Jump to content
  • Advertisement
Sign in to follow this  
aevanthony

OpenGL Efficient Rendering

This topic is 3713 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hmm, This application I tested with has a 128x128 texture, and the shader I'm using just does a glFragColor = texture2d...etc, a simple color assignment. Now when I scale the window up very large, my entire system suffers performance problems, mostly... actually more specifically, audio playback gets very bad and CPU shoots up. So I was wondering... what does OpenGL in place of when no shader programs are created? What's the default behavior? Maybe even... would it be a good idea to disable the shader program entirely when OpenGL is rendering a texture to the window, and just have it active while the FBO is rendering to the texture?

Share this post


Link to post
Share on other sites
Advertisement
I created a new Shader program, assigned it NO shader. I used glUseProgram(textureProgram); before the FBO rendered to a texture, I used; glUseProgram(DoNothing) after.

On my current PC, CPU usage while scaling my applications window during run time. With a 256x256 texture rendered to a window scaled up to 1680x1050; CPU from ~30% to ~8%

Mmmm... that's like what, 60-75% less cpu usage? Much better, can't wait to see how this runs on a slower gpu/system.

That'll go a long way to broaden the range of GPU's that will smoothly run this program I'm sure. Mmmmm.

:) I'll have to test it all out more and all that mess, but so far happy.

Share this post


Link to post
Share on other sites
Are you rendering with an infinite loop? In that case, with a single core CPU, it should use 100% CPU if vsync is off. If on, it will be like 1 to 5%.
With dual core, instead of 100%, it would be somewhere around 50%.
With dual core and if you have vsync on, it would be 1 to 5%.

Share this post


Link to post
Share on other sites
Hmm, is there another way to achieve this which won't use 100% CPU for those cases? Is there some other recommended approach to this?

Share this post


Link to post
Share on other sites
The other way is to render when the OS sends a notification because you window has been exposed or needs a refresh for some reason. On Windows, it sends a WM_PAINT message.
If you are using GLUT, then get rid of glutIdleFunc. Your render functions gets called when GLUT received a notification from the OS.

Share this post


Link to post
Share on other sites
When removing that idle function nothing redraws to the screen.

Just to add, I made sure vsync was forced... on both machines, but based on some reading in to Vista there's problems with vsync overall. In any case, I haven't seen anything near 50% usage on either machine. Well, except on this FX5200... but that's before and after glUseProgram.

When I swap the programs and set glUseProgram to use the program with no shader attached on this machine with a FX5200 it doesn't seem to take effect. The visual display doesn't render as if the texture is scaled, it still looks like the fragment shader is executing per pixel... using a program where no shader is attached!! Ironically the card I don't even need for did as I expected... (x1950pro) /ultra-sigh.

That's perplexing, I can't seem to figure out why that is, every thing's the same as the machine I ran this on last night on my ATI box.

Is it possible this FX card is ignoring glUseProgram calls I'm using per frame? Any other ideas? Can you think of something else?

I mean the only thing I did was akin to;

1. glUseProgram(p) // fun stuff
2. FBO render to texture. // receives fun stuff
3. glUseProgram(p2) // do no more fun stuff
4. Render texture to window. // texture rendered without extra fun stuff

*Kicks a bucket*

Share this post


Link to post
Share on other sites
The CPU rises only really* when I scale up, *only on this machine (of the two I tested). It's as if the glUseProgram(p2) doesn't do what it should. (Use a program which has no shader associated with it, to prevent a fragment shader from doing anything to every pixel. Hence more efficient, the goal is to force only* the texture to be processed with my fragment shader.)

This is the significant portion of the rendering loop.



static float da = 1.0;

glUseProgram(p); // ENABLE SHADER PROGRAM

glBindTexture(GL_TEXTURE_2D, FBOTex[TexRenderWrite]);
GLint TexLoc = glGetUniformLocation(p, "tex"); glUniform1i(TexLoc, 0);
vLoc = glGetUniformLocation(p, "aL"); glUniform1f(vLoc, u0);
vLoc = glGetUniformLocation(p, "aR"); glUniform1f(vLoc, u1);

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBO);
glPushAttrib(GL_VIEWPORT_BIT | GL_COLOR_BUFFER_BIT);
glViewport(0, 0, SD, SD);
glDrawBuffer(AttchPoint[TexRenderRead]);
glActiveTexture(GL_TEXTURE0 + TexRenderRead);
glPushMatrix();
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(-da, -da, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(-da, da, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f( da, da, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f( da, -da, 0.0);
glEnd();
glPopMatrix();
glPopAttrib();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
TexRenderRead = (TexRenderRead + 1)%2;
TexRenderWrite = (TexRenderWrite + 1)%2;

glUseProgram(p2); // DISABLE SHADER PROGRAM

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glPushMatrix();
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(-da, -da, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(-da, da, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f( da, da, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f( da, -da, 0.0);
glEnd();
glPopMatrix();
glutSwapBuffers();
Sleep(1);



Share this post


Link to post
Share on other sites
I fixed it, after researching I came across the fact that I should have done this instead to disable my fragment shader for rendering to the window;

Reference the above code and do this instead;

glUseProgram(p2) -> glUseProgram(0)




I can scale my window without a dramatic performance hit! it's a lot better. I need to do better still, it still uses too much(maybe) CPU. ~35% when scaled to over 800x600... maybe it's the best I can get though, even WinAmp has a comparable CPU usage on this machine, so maybe this is what I've been looking for.

Vista apparently has problems with vsync. Is there a way through OpenGL I can force vsync?

[Edited by - aevanthony on April 24, 2008 3:51:09 PM]

Share this post


Link to post
Share on other sites
If your driver offers http://www.opengl.org/registry/specs/EXT/wgl_swap_control.txt
then wglGetSwapIntervalEXT(0) disables and wglGetSwapIntervalEXT(1) enables it.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!