Page 1 of 1

CPU issues[OPENGL][SDL]

Posted: Fri Sep 23, 2011 2:35 am
by evilbunnie
Hey guys,

I've been playing around in OpenGL+SDL, but something is ticking me off. I get around 30-40 CPU whilst rendering 25x19 tiles at 60FPS. Is this normal? Is there a way to have the framerate at 60FPS and get the CPU down at the same time? Does Elysian Shadows get this? My current FPS limiter function is;

at the top of the loop I have

Code: Select all

tick = SDL_GetTicks();
and then at the bottom of the loop

Code: Select all

// cap the framerate
tick = SDL_GetTicks() - tick;
if(tick < (1000 / 60))
{
     // sleep for as long as it can
     SDL_Delay((1000 / 60) - tick);
}
Thanks in advanced, guys!

Re: CPU issues[OPENGL][SDL]

Posted: Fri Sep 23, 2011 5:15 pm
by TheBuzzSaw
Share your hardware specs.

In my own engine, I check to see if it is time to update; if not, I do SDL_Delay(1) and check again later.

Re: CPU issues[OPENGL][SDL]

Posted: Fri Sep 23, 2011 7:01 pm
by Live-Dimension
Just chucking out some alternative ideas that can show the same symptoms that you may not of thought of.

Have you tried a release build and ran the executable directly? ie, no debugger or anything like that getting in the way? It sounds like this might be the reason for such a high cpu useage. Maybe there is some kind of huge bottleneck in your code somewhere?

Re: CPU issues[OPENGL][SDL]

Posted: Fri Sep 23, 2011 10:50 pm
by evilbunnie
This is the rendering part, it's what is causing the CPU increase.

Code: Select all

void renderGraphics(){

	// render everything for the current frame
	glClear(GL_COLOR_BUFFER_BIT);

	// setup the view
	glLoadIdentity();

	// move off center so the quads is visible
	glTranslatef(0, 0, -500); 

	// draw quad as white
	glColor3f(1.0f, 1.0f, 1.0f);
	
	// smoothly shade
	glShadeModel(GL_SMOOTH);

	// render all the quads on-to screen
	glBegin(GL_QUADS);
	
		// render all the tiles 
		for(x=0; x<25; x++){
			for(y=0; y < 19; y++){
				if (Map.tile[x + Camera.x][y + Camera.y].tileSet > 0){
					drawSurface(gTileSet, (x) * 32, (y) * 32, 32, 32, 0, 0, 1.0, 1.0);
				}
			}
		}

	glEnd();

	// update display
	SDL_GL_SwapBuffers();
}

void drawSurface(GLuint source, Uint16 dX, Uint16 dY, Uint16 dH, Uint16 dW, Uint16 sX, Uint16 sY, Uint16 sH, Uint16 sW)
{
	// bind the texture to OPENGL
	glBindTexture(GL_TEXTURE_2D, source);

	// draws the quad to screen
	glTexCoord2i(sX, sY); glVertex2i(dX, dY);
	glTexCoord2i(sX, sY + sH); glVertex2i(dX, dY + dH);
	glTexCoord2i(sX + sW, sY + sH); glVertex2i(dX + dW, dY + dH);
	glTexCoord2i(sX + sW, sY); glVertex2i(dX + dW, dY);
}
Tried to comment as much as I can

Also my specs;

Re: CPU issues[OPENGL][SDL]

Posted: Sat Sep 24, 2011 4:47 am
by Live-Dimension
I'm pretty basic to OGL, so take this with a grain of salt. Maybe it'll help point you in the right direction.

Code: Select all

	glShadeModel(GL_SMOOTH);
I'm pretty sure that's meant to be in the initialisation of OGL.

Code: Select all

	// render all the quads on-to screen
	glBegin(GL_QUADS);
	
		// render all the tiles 
		for(x=0; x<25; x++){
			for(y=0; y < 19; y++){
				if (Map.tile[x + Camera.x][y + Camera.y].tileSet > 0){
					drawSurface(gTileSet, (x) * 32, (y) * 32, 32, 32, 0, 0, 1.0, 1.0);
				}
			}
		}

	glEnd();
I'm even more sure that you have to glBegin() and glEnd() each square you use, although if they are done in a special order you can avoid that.
Anyway, your cpu sucking issue will be here in this loop.

Re: CPU issues[OPENGL][SDL]

Posted: Sat Sep 24, 2011 10:55 am
by ibly31
glShadeModel doesn't initialize anything. It is also something that only needs to be set once, so in your OpenGL setup code, put it there, and take it out of the draw loop.

Also, I noticed you bind the current texture on EVERY quad you draw. This is not necessary, and causes huge performance drops in big projects. What you should do is something like this:

Code: Select all

void renderGraphics(){

   // render everything for the current frame
   glClear(GL_COLOR_BUFFER_BIT);

   // setup the view
   glLoadIdentity();

   // move off center so the quads is visible
   glTranslatef(0, 0, -500); 

   // draw quad as white
   glColor3f(1.0f, 1.0f, 1.0f);

 // bind the texture for all of the quads that will be drawn.
   glBindTexture(gTileSet, GL_TEXTURE_2D);
   // render all the quads on-to screen
   glBegin(GL_QUADS);
   
      // render all the tiles 
      for(x=0; x<25; x++){
         for(y=0; y < 19; y++){
            if (Map.tile[x + Camera.x][y + Camera.y].tileSet > 0){
               drawSurface((x) * 32, (y) * 32, 32, 32, 0, 0, 1.0, 1.0);// This doesn't have the gTileSet param anymore
            }
         }
      }

   glEnd();

   // update display
   SDL_GL_SwapBuffers();
}

// Notice new function params :
void drawSurface(Uint16 dX, Uint16 dY, Uint16 dH, Uint16 dW, Uint16 sX, Uint16 sY, Uint16 sH, Uint16 sW)
{
   // NO NEED TO BIND ANYTHING HERE, WE ALREADY DID IT BEFORE DRAWING.

   // draws the quad to screen
   glTexCoord2i(sX, sY); glVertex2i(dX, dY);
   glTexCoord2i(sX, sY + sH); glVertex2i(dX, dY + dH);
   glTexCoord2i(sX + sW, sY + sH); glVertex2i(dX + dW, dY + dH);
   glTexCoord2i(sX + sW, sY); glVertex2i(dX + dW, dY);
}
This code assumes that all of your tiles you are drawing use that texture as their tile set. If you want to switch tile sets or use different ones for each tile, you will have to structure this differently.

Re: CPU issues[OPENGL][SDL]

Posted: Sat Sep 24, 2011 3:13 pm
by TheBuzzSaw
Pentium D? That's pretty old, though 3.2 GHz is pretty good.

Your render loop doesn't look all too complex. I doubt your render loop is all that is causing the CPU usage. Your older CPU combined with the use of immediate mode could contribute to the increased CPU. I wonder how much CPU one of my programs would use on your system. My scenes are increasingly complex, and I still sit at around 20% CPU.

Re: CPU issues[OPENGL][SDL]

Posted: Sat Sep 24, 2011 4:29 pm
by evilbunnie
Well, after testing this on my other computer and getting 2-3 CPU avg all I can think is my CPU is dying. It's about 5 years old.

Oh and I forgot about that gl smooth code was put there to test something should be moved.

Also, I'm planning on using a different tile from tileset per tile, although I could probably have a check to see if it is already binded.

Thanks guys :)

Re: CPU issues[OPENGL][SDL]

Posted: Sat Sep 24, 2011 5:32 pm
by dandymcgee
evilbunnie wrote:Well, after testing this on my other computer and getting 2-3 CPU avg all I can think is my CPU is dying. It's about 5 years old.
Lol, CPUs don't have a "dying" state. They're either working, or they're not. ;)

Re: CPU issues[OPENGL][SDL]

Posted: Sat Sep 24, 2011 6:18 pm
by Live-Dimension
They do, however, have an overheating state. Does the fan sound loud? is there 10 years worth of dust on the heatsink/fan?

Re: CPU issues[OPENGL][SDL]

Posted: Sun Sep 25, 2011 9:06 am
by dandymcgee
Live-Dimension wrote:They do, however, have an overheating state. Does the fan sound loud? is there 10 years worth of dust on the heatsink/fan?
Ah, yes. Definitely be sure to thoroughly blow out the inside with compressed air every so often. When you do, be sure to hold any fans you're cleaning still or you may damage the bearings. All too often I see people shooting air at their fans and causing them to spin up because it "it sounds cool".. then wondering why only one of three works anymore. Don't be that guy, haha.

Re: CPU issues[OPENGL][SDL]

Posted: Sun Sep 25, 2011 1:11 pm
by Falco Girgis
Live-Dimension wrote:I

Code: Select all

	// render all the quads on-to screen
	glBegin(GL_QUADS);
	
		// render all the tiles 
		for(x=0; x<25; x++){
			for(y=0; y < 19; y++){
				if (Map.tile[x + Camera.x][y + Camera.y].tileSet > 0){
					drawSurface(gTileSet, (x) * 32, (y) * 32, 32, 32, 0, 0, 1.0, 1.0);
				}
			}
		}

	glEnd();
I'm even more sure that you have to glBegin() and glEnd() each square you use, although if they are done in a special order you can avoid that.
Anyway, your cpu sucking issue will be here in this loop.
Actually, that's legit. And it's probably more efficient, because you aren't having to resubmit a polygon/vertex header to GPU for every primitive.
evilbunnie wrote:Also, I'm planning on using a different tile from tileset per tile, although I could probably have a check to see if it is already binded.
Honestly, you'll be MUCH better off rendering everything from a single sheet together. Even with this method, if you are blindly rendering things off of different sheets, it'll only save you a few extra glBinds(). And even if you DO render sheets together, you still have an unnecessary check in there.

The preferred method is to render everything from one texture, change textures, render everything from the new one, change textures, etc.
evilbunnie wrote:

Code: Select all

   glTexCoord2i(sX, sY); glVertex2i(dX, dY);
   glTexCoord2i(sX, sY + sH); glVertex2i(dX, dY + dH);
   glTexCoord2i(sX + sW, sY + sH); glVertex2i(dX + dW, dY + dH);
   glTexCoord2i(sX + sW, sY); glVertex2i(dX + dW, dY);
Might I recommend you use floats? I'm sure it looks perfectly fine now, but the minute you start using glRotate() and glScale() on integer vertices, you're going to see a lot of bounciness going on. The Sega Saturn and PSOne had this problem, because they didn't have FPUs. The N64 did, and look how much smoother it looked. Also, the chances are that those are being converted to floats in some form or another before they wind up on your GPU. Also, many OpenGL drivers can use SSE instructions to hardware accelerate matrix/vector multiplications that only operate on floating point numbers...

You may be fine now, but later down the road, if you wan to start adding some OpenGL fanciness to your engine, you may regret using integers.

Anyway, back on topic... I honestly don't see anything that should be slowing you down based on the code that you've given. Do other applications tend to use proportionally more CPU when compared to your other computers? I have no experience with that processor, but I think the chances of it sucking/dying are looking pretty high...

Re: CPU issues[OPENGL][SDL]

Posted: Tue Sep 27, 2011 4:58 pm
by CowboyX86
Hi,

May this help increase speed:

1) Use vertex array instead of using glBegin(type); list_of_vertex; and glEnd();

2) Load and set your tileset texture before and not inside your drawtile loop;

Well, this has nothing to do with speed, but if you thinking about porting your code to Android or iPhone someday, you should draw triangles instead os quads, you just need do a little change in your code, but will work fine later on these two platforms.