PDA

View Full Version : Double buffering



link19
04-16-2001, 06:34 AM
When i rotate an object, i get heavy flickering. I understand that double buffering will prevent this, however i do not know how to implement it.
I did a search in this forum and found that its quite simple using GLUT, but i am not. There was no help for implementing it for Win32/MFC. Im using VC++6.0 and would appreciate suggestions.
TIA

link19
04-16-2001, 06:45 AM
I realized i have to set the PFD_DOUBLEBUFFER flag in my SetWindowPixelFormat() method. Then i call SwapBuffers(dc.GetSafeHdc()); in my OnPaint()...but this has no effect on my view. Still have flickering when animating my object.
Ideas please??!

Warrior
04-16-2001, 07:27 AM
you on the right track.
you do need to specify PFD_DOUBLEBUFFER when filling in your PIXELFORMATDESCRIPTOR structure. then, to flip the buffers you call SwapBuffers(HDC).

if you need more info, your best bet is to read NeHe's tutorial on setting up a window in Windows. go to http://nehe.gamedev.net for this tutorial

- Dave

[This message has been edited by Warrior (edited 04-16-2001).]

danny1238
04-17-2001, 03:03 AM
I've just started learning how to program in OpenGL through a book called "OpenGL SuperBible". I came across the topics of double buffering and single buffering. To enable double buffering you should initialize it within the display mode before creating the window.

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);

Also, you should use

glutSwapBuffers();

at the end of the Rendering function instead of

glFlush();

link19
04-17-2001, 04:59 AM
Thx Danny...but if you had read my first post, im not using GLUT.
BTW, im still getting flickering and not sure why double buffering would not be enabled. Ive looked through NeHe's first tut and dont think im missing anything. Could there be something in my code that would prevent it?
Thx...

JoeMac
04-17-2001, 05:16 AM
You might actually be using double buffers correctly and still get flickering if you have some combination of:
software rendering, a lot of polygons, slow computer, vsync disabled.
Joe

Sanchis
04-17-2001, 05:16 AM
Maybe
glFinish();
SwapBuffers(wglGetCurrentDC()); ?

DaViper
04-17-2001, 05:29 AM
Are you sure that you are rendering to the backbuffer with using glDrawBuffer(GL_BACK)

Chris

link19
04-17-2001, 05:44 AM
My computer is fast, but i am drawing a lot of polygons...so possibly youre right. However, I commented out the SwapBuffer() call and my rendering is still visible. Does this mean that i am not drawing to the back buffer? I made the call glDrawBuffer(GL_BACK)right before i call my rendering function in OnPaint(). Is this the correct place for it?
Thx for your sugggestions...

Deiussum
04-17-2001, 08:11 AM
It sounds like you are using MFC. Try over-riding the OnEraseBkgnd() function and make it return TRUE.

link19
04-17-2001, 08:16 AM
Deiussum,
Yep, using MFC. Already implemented returning true in OnEraseBkgnd(). My call to glDrawBuffer(GL_BACK), is it in the correct place? as i mentioned in my earlier post...
TIA

[This message has been edited by link19 (edited 04-17-2001).]

Deiussum
04-17-2001, 10:15 AM
If your scene is still displaying even without the SwapBuffers, you are likely not getting a double-buffered context. Maybe you could try posting the function where you initialize the pixelformat.

link19
04-17-2001, 10:23 AM
Okay. But i think the only thing to notice wrt double buffering here is the flag PFD_DOUBLEBUFFER. So im posting more than that:



BOOL CMyMesh::SetWindowPixelFormat(HDC hDC)
{
PIXELFORMATDESCRIPTOR pixelDesc;

pixelDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pixelDesc.nVersion = 1;

pixelDesc.dwFlags = PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_SUPPORT_GDI |
PFD_DOUBLEBUFFER;

pixelDesc.iPixelType = PFD_TYPE_RGBA;
pixelDesc.cColorBits = 32;
pixelDesc.cRedBits = 8;
pixelDesc.cRedShift = 16;
pixelDesc.cGreenBits = 8;
pixelDesc.cGreenShift = 8;
pixelDesc.cBlueBits = 8;
pixelDesc.cBlueShift = 0;
pixelDesc.cAlphaBits = 0;
pixelDesc.cAlphaShift = 0;
pixelDesc.cAccumBits = 64;
pixelDesc.cAccumRedBits = 16;
pixelDesc.cAccumGreenBits = 16;
pixelDesc.cAccumBlueBits = 16;
pixelDesc.cAccumAlphaBits = 0;
pixelDesc.cDepthBits = 32;
pixelDesc.cStencilBits = 8;
pixelDesc.cAuxBuffers = 0;
pixelDesc.iLayerType = PFD_MAIN_PLANE;
pixelDesc.bReserved = 0;
pixelDesc.dwLayerMask = 0;
pixelDesc.dwVisibleMask = 0;
pixelDesc.dwDamageMask = 0;

m_GLPixelIndex = ChoosePixelFormat( hDC, &pixelDesc);
if (m_GLPixelIndex==0)
{
m_GLPixelIndex = 1;
if (DescribePixelFormat(hDC, m_GLPixelIndex,
sizeof(PIXELFORMATDESCRIPTOR), &pixelDesc)==0)
{
return FALSE;
}
}

if (SetPixelFormat(hDC, m_GLPixelIndex, &pixelDesc)==FALSE)
{
return FALSE;
}

return TRUE;

}

void CMyMesh::OnPaint()
{
CPaintDC dc(this);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawBuffer(GL_BACK);
RenderScene();

glPushMatrix();
..........
glCallList(m_meshList);
..........
glPopMatrix();

glFinish();
SwapBuffers(dc.GetSafeHdc());
}



[This message has been edited by link19 (edited 04-17-2001).]

JoeMac
04-17-2001, 10:41 AM
Out of curiosity, what does RenderScene() do since you are drawing outside of it? Does it also contain a call to swapbuffers()?

link19
04-17-2001, 10:47 AM
No i dont make a call to SwapBuffers in my RenderScene() function. It contains my display lists, m_meshList for instance being one of them.

10-26-2003, 09:14 PM
PFD_SUPPORT_GDI
and
PFD_DOUBLEBUFFER
are mutually exclusive

mikael_aronsson
10-27-2003, 12:22 AM
Yes, the PFD_SUPPORT_GDI allows you to use ordinary GDI calls to mix with OpenGL rendering, this prevents you from using doublebuffering (it would erase anything done with gdi calls), so just remove the PFD_SUPPORT_GDI and it should work fine.

Relic
10-28-2003, 02:14 AM
This is what the Microsoft implementation says, but other implementations can draw with GDI into OpenGL windows, but only into the front buffer, of course. (But you don't really want to do that!)

roffe
10-28-2003, 09:48 AM
Originally posted by link19:
My call to glDrawBuffer(GL_BACK), is it in the correct place? as i mentioned in my earlier post...


For single buffering, GL_FRONT is set as the default draw buffer. For double buffering GL_BACK is set. So unless you want to render to both back and front you should never have to call glDrawBuffer explicitly.Calling glDrawBuffer(GL_BACK) when using single buffering will result in an invalid operation error from glGetError(). If you requested double buffering and you're not sure you got it, this would be a simple(but primitive) way of checking it.