PDA

View Full Version : How increase speed?



ncn213
08-03-2009, 10:44 PM
Hi all,
I have a opengl program in mfc dialog. my dialog contain 20 cstatic that each one is one opengl window. In each window I draw a texture and then draw some polygon on it. my opengl display function located in onpaint function of cstatic and when I want to redisplay the window, call redrawwindow().

Every onpaint execution take about 15 milisecond time of my program. How can I decrease this time??

In OnPaint I call a list that draw texture and then compute some point and draw a polygon.

Thanks.

Nighthawk
08-04-2009, 05:28 AM
To locate the bottleneck: Just do a glClear in your onpaint(), comment out the other openGl code.

If it is still slow, it is overhead from the MFC. Otherwise the OpenGL code is causing the slowdown.

And try disabling V-Sync in your driver, see if that makes any difference.

ncn213
08-09-2009, 09:14 PM
Hi Nighthawk,
I do your suggestion, I found that wglMakeCurrent(dc.m_hdc,NULL)
at the end of OnPaint, after Swapbuffer(), take 15 milisecound time.
How can I decrease this time?

kowal
08-10-2009, 05:16 AM
If You are using multiple OpenGL-renderable surfaces in one dialog, don't use separate contexts for them (You used wglMake Current every frame, that suggests that You have multiple contexts), have one context and render to FBOs with attached textures for each window. In your main window draw series of textured quads(with textures You just rendered to).

This way You avoid context switching (replace context switching with binding FBOs). (On Linux it works fast: ~800 fps (~1.25ms/frame) with 4 windows (FBOs) and bumpmapped cube in each window), on Widows this also should be a lot faster than separate contexts)

If You somehow have only one context, don't call wglMakeCurrent more than once.

ps. Sorry about my poor english.

ncn213
08-10-2009, 06:48 AM
Hi kowal,

What is FBO?

and

How can I have one context and render to FBOs with attached textures for each window?

My windows redraw separately, maybe one windowredraw 10 times and another doesn't need to redraw.

kowal
08-10-2009, 09:37 AM
FBO is Framebuffer Object,

You create and setup it like that:



GLuint myFBOs[NUM_FBOS];
GLuint depthBuffers[NUM_FBOS];
GLuint textures[NUM_FBOS];

glGenFramebuffers( NUM_FBOS, myFBOs );
glGenRenderbuffers( NUM_FBOS, depthBuffers );
glGenTextures( NUM_FBOS, textures );

for(int i = 0;i < NUM_FBOS;i++)
{
glBindFramebuffer( GL_FRAMEBUFFER, myFBOs[i] );
glBindRenderbuffer( GL_RENDERBUFFER, depthBuffers[i] );
glBindTexture( GL_TEXTURE_2D, textures[i] );

/*setup texture format and parameters, eg:*/
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

/*setup depth buffer IT MUST HAVE THE SAME width and height as texture*/
glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height );

/*attach texture and depth buffer to FBO*/
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[i], 0 );
glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffers[i] );

/*check status*/
if( glCheckFramebufferStatus( GL_FRAMEBUFFER ) != GL_FRAMEBUFFER_COMPLETE)
printf( "Something is wrong with your FBO setup!\n" );
}



now your FBOs are ready to rendering, to render to FBO:
bind it:


glBindFramebuffer( GL_FRAMEBUFFER, myFBOs[whichever_you_want] );

(don't forget to set Your viewport to texture dimensions)

and everything that You render will go to texture attached to that fbo.

If You want to render to screen, unbind FBO:


glBindFramebuffer( GL_FRAMEBUFFER, 0 );


and You may now use textures attached to FBOs to draw your windows. (set orhographic projection and draw just textured quads (or apply some custom transformations to them, choice is yours :) ))

When any of your windows requests update, just bind it's FBO, redraw, unbind FBO and redraw main dialog (for me it works fast enough).

ncn213
08-11-2009, 03:23 AM
Hi kowal,
I use vc6, and my gl.h doesn't have glBindFramebuffer() and glBindRenderbuffer().
Are there this function opengl standard?

ZbuffeR
08-11-2009, 11:44 AM
http://www.opengl.org/wiki/Getting_started#OpenGL_2.0.2B_and_extensions

All modern GL functions have to be retrieved dynamically. If this sound complex for you, use GLEW or GLEE : these libraries make it very easy.