How increase speed?

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.


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.

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?

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.

Hi kowal,

What is FBO?


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.

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 );
	/*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!
" );

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 :slight_smile: ))

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

Hi kowal,
I use vc6, and my gl.h doesn’t have glBindFramebuffer() and glBindRenderbuffer().
Are there this function opengl standard?

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.