Link to home
Start Free TrialLog in
Avatar of Valleriani
VallerianiFlag for Sweden

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->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);




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(D3DPT_LINESTRIP);
      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(D3DPT_TRIANGLEFAN);
      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(D3DPT_TRIANGLELIST);
      GLDraw::beginPrimitive(D3DPT_LINESTRIP);
      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).
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;
}

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of ambience
ambience
Flag of Pakistan image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Valleriani

ASKER

Ended up using a basic bitmap for it and it sped up almost 6x :)