Valleriani
asked on
C++ & DirectX 9: Quickest way to draw triangles/circles/etc.. How to optimize this coding?
I will attach the coding below. Basically, what it does is Draws an object depending on where it is, and what it is.
The main concern where it draws and partially the dx drawing. But this part is the larger blow to framerate:
if(isPlanet)
map->buffer->drawFilledCir cle(x0 + addx,y0 + addy,cy/2,color);
else if(isShip)
map->buffer->drawTriangle( x0-5+addx, y0+5+addy, x0+5+addx, y0+5+addy, x0+addx,y0 -5+addy,sc olor);
else if(isColony && !colonizedPlanet)
map->buffer->drawRect(x0-3 +addx,y0-3 +addy,x0+4 +addx,y0+4 +addy,colo r);
The coding for the drawing is:
void DxCanvas::drawCircle(int x, int y, int rad, D3DCOLOR color, int numSegments){
if (numSegments <= 0){
numSegments = rad*2;
if (numSegments < 2)
numSegments = 4;
if (numSegments > 2000)
numSegments = 2000;
}
GLDraw::setColor(color);
Render::setTexture(0);
GLDraw::beginPrimitive(D3D PT_LINESTR IP);
float xCenter = (float)x, yCenter = (float)y, radius = (float)rad;
GLDraw::vertex2f(xCenter + radius, yCenter);
float add = pi*2.0f/(float)numSegments ;
float angle = add;
for (int i = 1; i < numSegments; i++, angle+= add)
GLDraw::vertex2f(xCenter + cos(angle)*radius, yCenter + sin(angle)*radius);
GLDraw::vertex2f(xCenter + radius, yCenter);
GLDraw::endPrimitive();
}
void DxCanvas::drawFilledCircle (int x, int y, int rad, D3DCOLOR color, int numSegments){
if (numSegments <= 0){
numSegments = rad*2;
if (numSegments < 2)
numSegments = 4;
if (numSegments > 2000)
numSegments = 2000;
}
GLDraw::setColor(color);
Render::setTexture(0);
GLDraw::beginPrimitive(D3D PT_TRIANGL EFAN);
float xCenter = (float)x - 0.5f, yCenter = (float)y - 0.5f, radius = (float)rad;
GLDraw::vertex2f(xCenter, yCenter);
GLDraw::vertex2f(xCenter + radius, yCenter);
float add = pi*2.0f/(float)numSegments ;
float angle = add;
for (int i = 1; i < numSegments; i++, angle+= add)
GLDraw::vertex2f(xCenter + cos(angle)*radius, yCenter + sin(angle)*radius);
GLDraw::vertex2f(xCenter + radius, yCenter);
GLDraw::endPrimitive();
}
void DxCanvas::drawTriangle(int x0,int y0,int x1,int y1,int x2,int y2, D3DCOLOR color){
GLDraw::setColor(color);
Render::setTexture(0);
//GLDraw::beginPrimitive(D 3DPT_TRIAN GLELIST);
GLDraw::beginPrimitive(D3D PT_LINESTR IP);
GLDraw::vertex2f((float)x0 , (float)y0);
GLDraw::vertex2f((float)x1 , (float)y1);
GLDraw::vertex2f((float)x2 , (float)y2);
GLDraw::vertex2f((float)x0 , (float)y0);
GLDraw::endPrimitive();
}
Which I would guess is basic DX9 rendering. But it sems to be taking a heavy blow on FPS like stated. Does anyone have any ideas how to optimize this above coding with DX or the below coding (printText/DrawString etc is basic DX output as well for text can attach if needed). Any suggestions to make the coding a bit more happy.
Right now there are several objects in one area, so it can take a very large hit to draw these! I was thinking of trying to split rendering each frame, but thats a last option (Aka if I give 8 frames to loop, and theres 200 objects, I want it too render 25 each frame and keep looping etc. Kinda to 'even' the load).
The main concern where it draws and partially the dx drawing. But this part is the larger blow to framerate:
if(isPlanet)
map->buffer->drawFilledCir
else if(isShip)
map->buffer->drawTriangle(
else if(isColony && !colonizedPlanet)
map->buffer->drawRect(x0-3
The coding for the drawing is:
void DxCanvas::drawCircle(int x, int y, int rad, D3DCOLOR color, int numSegments){
if (numSegments <= 0){
numSegments = rad*2;
if (numSegments < 2)
numSegments = 4;
if (numSegments > 2000)
numSegments = 2000;
}
GLDraw::setColor(color);
Render::setTexture(0);
GLDraw::beginPrimitive(D3D
float xCenter = (float)x, yCenter = (float)y, radius = (float)rad;
GLDraw::vertex2f(xCenter + radius, yCenter);
float add = pi*2.0f/(float)numSegments
float angle = add;
for (int i = 1; i < numSegments; i++, angle+= add)
GLDraw::vertex2f(xCenter + cos(angle)*radius, yCenter + sin(angle)*radius);
GLDraw::vertex2f(xCenter + radius, yCenter);
GLDraw::endPrimitive();
}
void DxCanvas::drawFilledCircle
if (numSegments <= 0){
numSegments = rad*2;
if (numSegments < 2)
numSegments = 4;
if (numSegments > 2000)
numSegments = 2000;
}
GLDraw::setColor(color);
Render::setTexture(0);
GLDraw::beginPrimitive(D3D
float xCenter = (float)x - 0.5f, yCenter = (float)y - 0.5f, radius = (float)rad;
GLDraw::vertex2f(xCenter, yCenter);
GLDraw::vertex2f(xCenter + radius, yCenter);
float add = pi*2.0f/(float)numSegments
float angle = add;
for (int i = 1; i < numSegments; i++, angle+= add)
GLDraw::vertex2f(xCenter + cos(angle)*radius, yCenter + sin(angle)*radius);
GLDraw::vertex2f(xCenter + radius, yCenter);
GLDraw::endPrimitive();
}
void DxCanvas::drawTriangle(int
GLDraw::setColor(color);
Render::setTexture(0);
//GLDraw::beginPrimitive(D
GLDraw::beginPrimitive(D3D
GLDraw::vertex2f((float)x0
GLDraw::vertex2f((float)x1
GLDraw::vertex2f((float)x2
GLDraw::vertex2f((float)x0
GLDraw::endPrimitive();
}
Which I would guess is basic DX9 rendering. But it sems to be taking a heavy blow on FPS like stated. Does anyone have any ideas how to optimize this above coding with DX or the below coding (printText/DrawString etc is basic DX output as well for text can attach if needed). Any suggestions to make the coding a bit more happy.
Right now there are several objects in one area, so it can take a very large hit to draw these! I was thinking of trying to split rendering each frame, but thats a last option (Aka if I give 8 frames to loop, and theres 200 objects, I want it too render 25 each frame and keep looping etc. Kinda to 'even' the load).
int SF_DisplayEngine::DrawMapConsoleObject(int i){
if(!map)
return 0;
if(!isShip && !isPlanet && !isColony)
return 0;
if(!visible /*&& !isAWarpingShip*/)
return 0;
int zoom = strategicZoom;
int scale = strategicScale;
int addx = map->buffer->x;
int addy = map->buffer->y;
int cx = sprite->cx/scale;
int cy = sprite->cy/scale;
if(cx < 1) cx = 1;
if(cy < 1) cy = 1;
if(isPlanet){
cx *= 2;
cy *= 2;
}
if(isShip){
cx = 9;
cy = 9;
}
if(isColony){
cx = 7;
cy = 7;
}
long x = map->buffer->width/2 +(gx - x0)/zoom - cx/2;
long y = map->buffer->height/2 -(gy - y0)/zoom - cy/2;
long x0 = x + cx/2;
long y0 = y + cy/2;
long nx = map->buffer->width/2 +(ngx - x0)/zoom - cx/2;
long ny = map->buffer->height/2 -(ngy - y0)/zoom - cy/2;
int onScr =(x > -cx) &&(x < map->buffer->width) &&
(y > -cy) &&(y < map->buffer->height);
bool dontDrawObject = false;
if(zoom >= 64 &&(isShip || isColony) && i != ge->localSlot)
dontDrawObject = true;
dxbb->setClipRect(map->buffer->x + 10, map->buffer->y + 10, map->buffer->x + map->buffer->width - 10, map->buffer->y + map->buffer->height - 10);
char *text = 0;
if(onScr && !dontDrawObject){
ulong scolor = color|0xFF000000;
if(i == ge->localSlot)
scolor = 0xFFFFFFFF;
if(isPlanet)
map->buffer->drawFilledCircle(x0 + addx,y0 + addy,cy/2,color);
else if(isShip)
map->buffer->drawTriangle(x0-5+addx,y0+5+addy,x0+5+addx,y0+5+addy,x0+addx,y0-5+addy,scolor);
else if(isColony && !colonizedPlanet)
map->buffer->drawRect(x0-3+addx,y0-3+addy,x0+4+addx,y0+4+addy,color);
if(isSun)
text =((PlanetClass *)(game->objectList[i]))->name;
if(isPlanet && !isMinor && zoom < 128)
text =((PlanetClass *)(game->objectList[i]))->name;
if(isMinor && zoom < 32)
text =((PlanetClass *)(game->objectList[i]))->name;
if(isShip && zoom < 32)
text = game->player[game->ship[i].playerIndex].shipName;
if(visible && isTargetted && ge->itime % (10*SF_MULTIPLIER) < (5*SF_MULTIPLIER))
map->buffer->drawRect(x-2+addx,y-2+addy,x+cx+2+addx,y+cy+2+addy,0xFFFF0000);
if(mainFont && mainFont->spr){
if(text)
mainFont->DrawString(map->buffer,text,x+addx,y+cy+mainFont->cy+addy,race);
}
else{
if(text)
map->font->printText(text,x+addx,y+cy+addy,color);
}
}/* onScreen */
dxbb->resetClipRect();
return 0;
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER