render window not updated - why?
Hi,
I am rendering with OpenGL into an MFC window. When I start the program, rendering works, but if I alt-tab out of the program and back in, the OpenGL view doesn't get updated (not even cleared), although the drawing function is called. I am using double buffering. If I turn off double buffering, the OpenGL render windows gets updated properly (but ofc flickers real bad).
[edited by - karx11erx on May 14, 2004 7:11:26 PM]
_________karx11erxVisit my Descent site or see my case mod.
I know why: The device context gets bogus somewhere ... but I have no clue why. Dammit.
_________karx11erxVisit my Descent site or see my case mod.
do you call SwapBuffers when your done rendering the frame?
---------------------------------
For an overdose of l33tness, flashbang.nu
---------------------------------
For an overdose of l33tness, flashbang.nu
www.flashbang.se | www.thegeekstate.com | nehe.gamedev.net | glAux fix for lesson 6 | [twitter]thegeekstate[/twitter]
Yes I do. The problem must be hidden somewhere in MFC.
I am using a document/view architecture and render to a view that is one of the panes of a split window. The setup function gets the device context with GetDC() and sets up everything for rendering.
But when I e.g. try to load another file, and the file open dialog is above the render view, the device context I had gotten is bogus (looks like MFC releases it somewhere). Calling SwapBuffers() returns an error code #6 (invalid device context), and the DC handle is NULL or some trash value (like 0xFEFEFEFE).
Here''s the setup code:
I am using a document/view architecture and render to a view that is one of the panes of a split window. The setup function gets the device context with GetDC() and sets up everything for rendering.
But when I e.g. try to load another file, and the file open dialog is above the render view, the device context I had gotten is bogus (looks like MFC releases it somewhere). Calling SwapBuffers() returns an error code #6 (invalid device context), and the DC handle is NULL or some trash value (like 0xFEFEFEFE).
Here''s the setup code:
BOOL GLCreateWindow (GLvoid){if (m_glDC) return TRUE; GLuint PixelFormat;static PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0 };if (!(m_glDC = GetDC ())) { GLKillWindow (); ErrorMsg ("OpenGL: Can''t create device context."); return FALSE; }glHDC = m_glDC->m_hDC;if (!(PixelFormat = ChoosePixelFormat (glHDC, &pfd))) { GLKillWindow (); sprintf (message, "OpenGL: Can''t find a suitable pixel format. (%d)", GetLastError ()); ErrorMsg (message); return FALSE; }if(!SetPixelFormat(glHDC, PixelFormat, &pfd)) { GLKillWindow(); sprintf (message, "OpenGL: Can''t set the pixel format (%d).", GetLastError ()); ErrorMsg (message); return FALSE; }if (!(m_glRC = wglCreateContext (glHDC))) { GLKillWindow (); sprintf (message, "OpenGL: Can''t create a rendering context (%d).", GetLastError ()); ErrorMsg (message); return FALSE; }if(!wglMakeCurrent (glHDC, m_glRC)) { GLKillWindow (); sprintf (message, "OpenGL: Can''t activate the rendering context (%d).", GetLastError ()); ErrorMsg (message); return FALSE; }if (!GLInit()) { GLKillWindow (); ErrorMsg ("OpenGL: Initialization failed."); return FALSE; }return TRUE;}
_________karx11erxVisit my Descent site or see my case mod.
Try this pfd:
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER,
32,
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
32,
0,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0
};
This one should work as it works in my mfc app, if it still doesn't work the problem isn't the pfd.
[edited by - Tree Penguin on May 15, 2004 7:01:24 AM]
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER,
32,
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
32,
0,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0
};
This one should work as it works in my mfc app, if it still doesn't work the problem isn't the pfd.
[edited by - Tree Penguin on May 15, 2004 7:01:24 AM]
It's not the pfd, i tried it and it works fine, i think you do something wrong in activating the rendering and/or device context as i wouldn't know any other reason for that error and i had the same problem and i think i fixed it changing something in that area. Post the context activating code you call each frame.
[edited by - Tree Penguin on May 15, 2004 7:07:57 AM]
[edited by - Tree Penguin on May 15, 2004 7:07:57 AM]
Context activation? Errrm ...
I am not calling wglMakeCurrent() each I time I start to render though, only on initialization of the rendering context.
It's not the rendering context though that gets lost, it's the (Windows) device context.
When I set up the OpenGL rendering, I get a device context from the window I render in and store a pointer to that DC in glDC. When I Alt+Tab out of the program (or open a file browse dialog), *glDC gets invalidated somehow (glDC->m_hDC is NULL then or some trash value, like 0xFEFEFEFE).
Setting up OpenGL rendering is done in GLCreateWindow(). The call sequence is GLRenderScene () -> GLResizeScene() -> GLCreateWindow().
GLRenderScene() renders the actual scene.
GLResizeScene() fits the viewport to the render windows client area and is called by GLRenderScene() before the actual rendering is done.
GLCreateWindow() creates the OpenGL rendering context and is called by GLResizeScene() to make sure there is a rendering context.
The other stuff is just the rendering code:
GLRenderScene () -> GLRenderFace() -> GLRenderTexture() -> GLCreateTexture () -> GLInitPalette ()
GLRenderScene () walks through all sides of all six sided segments that are to be rendered.
GLRenderFace() renders a single side, which can have up to two textures (base texture and overlay).
GLCreateTexture() loads the texture bitmap, gets an OpenGL name for it (which is kept in glHandles), creates an RGBA texture from it and binds it to OpenGL.
GLLoadPalette() loads the palette required to create RGBA textures from the basic bitmaps.
here's the complete rendering code:
I am not calling wglMakeCurrent() each I time I start to render though, only on initialization of the rendering context.
It's not the rendering context though that gets lost, it's the (Windows) device context.
When I set up the OpenGL rendering, I get a device context from the window I render in and store a pointer to that DC in glDC. When I Alt+Tab out of the program (or open a file browse dialog), *glDC gets invalidated somehow (glDC->m_hDC is NULL then or some trash value, like 0xFEFEFEFE).
Setting up OpenGL rendering is done in GLCreateWindow(). The call sequence is GLRenderScene () -> GLResizeScene() -> GLCreateWindow().
GLRenderScene() renders the actual scene.
GLResizeScene() fits the viewport to the render windows client area and is called by GLRenderScene() before the actual rendering is done.
GLCreateWindow() creates the OpenGL rendering context and is called by GLResizeScene() to make sure there is a rendering context.
The other stuff is just the rendering code:
GLRenderScene () -> GLRenderFace() -> GLRenderTexture() -> GLCreateTexture () -> GLInitPalette ()
GLRenderScene () walks through all sides of all six sided segments that are to be rendered.
GLRenderFace() renders a single side, which can have up to two textures (base texture and overlay).
GLCreateTexture() loads the texture bitmap, gets an OpenGL name for it (which is kept in glHandles), creates an RGBA texture from it and binds it to OpenGL.
GLLoadPalette() loads the palette required to create RGBA textures from the basic bitmaps.
here's the complete rendering code:
static UINT8 rgbBuf [64*64*4];static GLuint glHandles [910];static UINT8 *glPalette = NULL;static HGLRC glRC;static CDC *glDC;typedef struct { long x, y, z; } APOINT; typedef struct { float x, y, z; } vms_vector; #define MAX_SEGMENTS 900 APOINT Vertices [4 * MAX_SEGMENTS]; /*--------------------------*/BOOL CMineView::GLInit (GLvoid){glShadeModel (GL_SMOOTH);glClearColor (0.0f, 0.0f, 0.0f, 0.0f);glClearDepth (1.0f);glEnable (GL_DEPTH_TEST);glDepthFunc (GL_LEQUAL);glEnable (GL_ALPHA_TEST);glAlphaFunc (GL_GEQUAL, 0.5); glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);memset (glHandles, 0, sizeof (glHandles)); return TRUE;} /*--------------------------*/BOOL GLInitPalette (GLvoid){if (!glPalette) { HINSTANCE hInst = AfxGetInstanceHandle (); HRSRC hFind = FindResource (hInst, PaletteResource (), "RC_DATA"); if (hFind) { HGLOBAL hGlobal = LoadResource (hInst, hFind); if (hGlobal) glPalette = (UINT8 *) LockResource (hGlobal); } }return (glPalette != NULL);} /*--------------------------*/BOOL GLResizeScene (GLvoid) {if (!GLCreateWindow ()) //make soure there is a rendering DC and RC return FALSE;CRect rc; GetClientRect (rc);if (!(rc.Width () && rc.Height ())) return FALSE;glViewport (rc.left, rc.top, rc.Width (), rc.Height ());glMatrixMode (GL_PROJECTION);glLoadIdentity ();glOrtho (0.0, 1.0, 0.0, 1.0, -1.0, 1.0);glMatrixMode (GL_MODELVIEW);glLoadIdentity ();glMatrixMode (GL_PROJECTION);glLoadIdentity ();gluPerspective (90.0f, (GLfloat) rc.Width () / (GLfloat) rc.Height (), 0.1f, 1000000.0f);glMatrixMode (GL_MODELVIEW);glLoadIdentity ();glTranslated (0, 0, 0, - 500); //move out far enough to see somethingreturn TRUE;} /*--------------------------*/void GLCreateTexture (INT16 nTexture) //load a texture and create an RGBA texture from it{if (!GLInitPalette ()) return;INT16 iTexture = nTexture & ~0xC000; if (!glHandles [iTexture]) { DefineTexture (nTexture, 0, bmBuf, 0, 0); DrawAnimDirArrows (nTexture, (UINT8 *) bmBuf); // create RGBA bitmap from source bitmap int h, i, j; for (h = i = 0; i < 64*64; i++) { j = bmBuf ;<br> j *= 3;<br> rgbBuf [h++] = glPalette [j++] << 2;<br> rgbBuf [h++] = glPalette [j++] << 2;<br> rgbBuf [h++] = glPalette [j++] << 2;<br><br> rgbBuf [h++] = (bmBuf >= 254) ? 0 : 255; // transparent if >= 254<br> }<br> glGenTextures (1, glHandles + iTexture); <br> glEnable (GL_TEXTURE_2D);<br> glBindTexture (GL_TEXTURE_2D, glHandles [iTexture]); <br> glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbBuf);<br> glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);<br> glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);<br> }<br>}<br><br> /*βββββββββ*/<br><br>void GLRenderTexture (INT16 segnum, INT16 sidenum, INT16 nTexture)<br>{<br> CDSegment *seg = Segments (segnum);<br> CDSide *side = seg->sides + sidenum;<br> uvl *uvls;<br> double l;<br> APOINT *a;<br> static int rotOffs [4] = {0,3,2,1};<br> int j = rotOffs [(nTexture & 0xC000) >> 14]; //take care of rotated 2ndary texture<br><br>GLCreateTexture (nTexture);<br>glEnable (GL_TEXTURE_2D);<br>glBindTexture (GL_TEXTURE_2D, glHandles [nTexture & ~0xC000]); <br>glBegin (GL_TRIANGLE_FAN);<br>for (int i = 0; i < 4; i++) {<br> uvls = side->uvls + j;<br> l = uvls->l / UV_FACTOR;<br> glColor3d (l,l,l);<br> //glTexCoord2f (uvMap [j][0], uvMap [j][1]); <br> glTexCoord2d (uvls->u / 2048.0, uvls->v / 2048.0); <br> a = Vertices + seg->verts [side_vert [sidenum]];<br> glVertex3f ((float) a->x, (float) a->y, (float) a->z);<br> j = (j + 1) % 4;<br> }<br>glEnd ();<br>}<br><br> /*βββββββββ*/<br><br>void GLRenderFace (INT16 segnum, INT16 sidenum)<br>{<br> CDSegment *seg = Segments (segnum);<br> CDSide *side = seg->sides + sidenum;<br> UINT8 wallnum = seg->sides [sidenum].wall_num;<br><br>if (side->tmap_num < 0)<br> return;<br>CDWall *pWall = (wallnum == 255) ? NULL : Walls (wallnum); //non-static textured faces (i.e. can disappear or be moved through)<br>if ((seg->children [sidenum] > -1) &&<br> (!pWall || (pWall->type == WALL_OPEN) || ((pWall->type == WALL_CLOAKED) && !pWall->cloak_value)))<br> return;<br>APOINT& p0 = Vertices [seg->verts [side_vert [sidenum] [0]]];<br>APOINT& p1 = Vertices [seg->verts [side_vert [sidenum] [1]]];<br>APOINT& p3 = Vertices [seg->verts [side_vert [sidenum] [3]]];<br><br>vms_vector a,b;<br>a.x = p1.x - p0.x;<br>a.y = p1.y - p0.y;<br>b.x = p3.x - p0.x;<br>b.y = p3.y - p0.y;<br>if (a.x*b.y > a.y*b.x) //only render rearward cube faces<br> return;<br>GLRenderTexture (segnum, sidenum, side->tmap_num);<br>if (side->tmap_num2) //has a secondary (overlaid) texture<br> GLRenderTexture (segnum, sidenum, side->tmap_num2);<br>}<br><br> /*βββββββββ*/<br><br>BOOL GLRenderScene (GLvoid) <br>{<br>if (!GLResizeScene ()) // make sure the viewport covers the windows client area<br> return FALSE;<br>glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);<br>glLoadIdentity ();<br>for (INT16 segnum = SegCount (); segnumβ; )<br> for (INT16 sidenum = 0; sidenum < 6; sidenum++)<br> GLRenderFace (segnum, sidenum);<br>return TRUE;<br>}<br><br> /*βββββββββ*/<br><br>GLvoid GLReset (GLvoid)<br>{<br>glDeleteTextures (910, glHandles);<br>memset (glHandles, 0, sizeof (glHandles));<br>glPalette = NULL;<br>}<br><br> /*βββββββββ*/<br><br>GLvoid GLKillWindow (GLvoid)<br>{<br>GLReset ();<br>if (glRC) {<br> if (!wglMakeCurrent (NULL,NULL))<br> ErrorMsg ("OpenGL: Release of DC and RC failed.");<br> if (!wglDeleteContext (glRC))<br> ErrorMsg ("OpenGL: Release of rendering context failed.");<br> glRC = NULL;<br> }<br>if (glDC && !glDC->ReleaseDC ()) {<br> ErrorMsg ("OpenGL: Release of device context failed.");<br> glDC = NULL; <br> }<br>}<br><br> /*βββββββββ*/<br><br>BOOL GLCreateWindow (CDC * pDC)<br>{<br>if (glDC)<br> return TRUE;<br><br> GLuint PixelFormat;<br><br>static PIXELFORMATDESCRIPTOR pfd = {<br> sizeof(PIXELFORMATDESCRIPTOR),<br> 1, <br> PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,<br> PFD_TYPE_RGBA,<br> 8,<br> 0, 0, 0, 0, 0, 0,<br> 0, <br> 0,<br> 0,<br> 0, 0, 0, 0,<br> 16,<br> 0,<br> 0,<br> PFD_MAIN_PLANE,<br> 0,<br> 0, 0, 0<br> };<br><br>if (!(glDC = GetDC ())) { //grab a DC from the parent window<br> GLKillWindow ();<br> ErrorMsg ("OpenGL: Can't create device context.");<br> return FALSE;<br> }<br>glDC->m_hDC = glDC->hDC;<br>if (!(PixelFormat = ChoosePixelFormat (glDC->m_hDC, &pfd))) {<br> GLKillWindow ();<br> sprintf (message, "OpenGL: Can't find a suitable pixel format. (%d)", GetLastError ());<br> ErrorMsg (message);<br> return FALSE;<br> }<br>if(!SetPixelFormat(glDC->m_hDC, PixelFormat, &pfd)) {<br> GLKillWindow();<br> sprintf (message, "OpenGL: Can't set the pixel format (%d).", GetLastError ());<br> ErrorMsg (message);<br> return FALSE;<br> }<br>if (!(glRC = wglCreateContext (glDC->m_hDC))) {<br> GLKillWindow ();<br> sprintf (message, "OpenGL: Can't create a rendering context (%d).", GetLastError ());<br> ErrorMsg (message);<br> return FALSE;<br> }<br><br>if(!wglMakeCurrent (glDC->m_hDC, glRC)) {<br> GLKillWindow ();<br> sprintf (message, "OpenGL: Can't activate the rendering context (%d).", GetLastError ());<br> ErrorMsg (message);<br> return FALSE;<br> }<br>if (!GLInit()) {<br> GLKillWindow ();<br> ErrorMsg ("OpenGL: Initialization failed.");<br> return FALSE;<br> }<br>return TRUE;<br>}<br> </pre> <br><br><SPAN CLASS=editedby>[edited by - karx11erx on May 15, 2004 5:38:48 PM]</SPAN>
_________karx11erxVisit my Descent site or see my case mod.
What i did to fix a few problems (don''t remember which ones anymore) was activating the rendering context using wglMakeCurrent (which is nesseccery) and then resizing the view (which i think fixed the problem i had when using multiple ogl windows), anyway i do this to set up the window for rendering, each frame:
And this for swapping the buffers:
Any flickering, size or display problem i had was fixed changing the code to what it is now.
// If device and/or rendering contexts don''t exist: init opengl if((m_hRC==NULL||m_pDC==NULL)){ InitializeOpenGL(); }; // Activate the current window''s rendering and device contexts wglMakeCurrent(m_pDC->GetSafeHdc(),m_hRC); // Resize view CRect r; GetClientRect(&r); OnSize(0,r.Width(),r.Height());
And this for swapping the buffers:
if ( FALSE == ::SwapBuffers( m_pDC->GetSafeHdc()) )//dc { ::AfxMessageBox("SwapBuffers failed."); }
Any flickering, size or display problem i had was fixed changing the code to what it is now.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement