buffer reads when window not in focus

in reading back the stencil buffer, i’m running into problems when my app is not the foremost window on the screen. wherever the screen is covered by another app’s window, the stencil buffer appears empty as if nothing is being drawn there. i assume this is some optimization made to reduce unnecessary drawing, however, i want it to draw to the whole window, as changes made in blocked portions of the screen affect the whole image. i’m currently using glut for window management (and its cross platform nature). has anyone else run into this before, or found some form of work around?

The content of the portions of the window under another window are undefined, as per the OpenGL specification. In order to guarentee that all the pixels you’re looking for are drawn, you will need to render to a p-buffer.

alright, thanks – i’ll def look into them. does anybody happen to know of any good tutorials/sites/articles that explain how to use p-buffers. i just did a (very preliminary) search on the web, and didn’t see much of value turn up. i’ve never used them before – any resource links would be a help!

http://oss.sgi.com/projects/ogl-sample/registry/ARB/wgl_pbuffer.txt

The extension registry should have a description of WGL_ARB_pbuffer extension. (Or is that just EXT? I forget). You also need to support the WGL_ARB_pixel_format extension to be able to specify contexts compatible with pbuffers.

Then make sure to use ShareLists() with the new pbuffer context to avoid duplicating texture objects. However, state is still separate, so if you change, say, TexEnv in one context, it won’t be applied in the second context (you have to manually keep them in sync if you need that).

hey, thanks for all the info guys. i see they also have an extension: GLX_SGIX_pbuffer. since i’m trying to keep this cross platform (actually, it’s more necessity than desire), across both windows and linux, does it seem feasible to just use:
#ifdef WIN32
WGL_ARB_pbuffer initialization code
#else
GLX_SGIX_pbuffer intitialization code
#endif
… has anyone does this before and found it easy/hard?

hey, i have another quick question. upon querying for “WGL_ARB_pbuffer”, it seems i don’t have that extension. is that a function of my openGL driver, or of the graphics board itself? my vid card is an Nvidia Quadro4 750XGL. do i just need new drivers for it?

When querying WGL extensions you need to use the WGL_ARB_extensions_string extension. Just get a pointer to wglGetExtensionsStringARB usign wglGetProcAddress and if its not null, this extension is supported by your video card.

Then you can call wglGetExtensionsStringARB to get a list of supported WGL extensions.

in NVSDK sources exist a nice class, which help to work with PBuffer under Win32/X-Window(all #ifdef win32 is inside).

hey, thanks jra – that was my problem… once i followed your instructions, i was able to find the extension w/o any trouble now time to mess around a bit! and thx for the lead on that nvidia class – it sounds like it might be just the thing i need.

Yes, that pbuffer class should do what you want and it works under Windows, Linux, and FreeBSD.

well, i found the pbuffer class in the source code for nvidia’s “infinite shadow volumes” tutorial. however, when i include the files:
pbuffer.h
pbuffer.cpp
i also have to add:
glh_extensions.h
gl_genext.h
gl_nveb.h
NVEBGlutAPI.h & NVEBGlutAPI.c
then when i compile, i get linking errors saying that in pbuffer.obj there are unresolved external symbols for all the wglCreatePbufferARB, wglDestroyPbufferARB etc calls. i don’t get any of these linking problems when i just have my code that involves the same function calls. is there something else i should include for the nvidia code?

The only thing you should need to include is glh_extensions.h. You must also define GLH_EXT_SINGLE_FILE in a single .cpp file ONLY.

that took care of it. i can’t imagine how long it would’ve taken me to find that comment at the top of the gl_extensions.h header file! much thanks

[This message has been edited by lost hope (edited 09-24-2003).]

alright, so after getting everything to compile with the nvidia pbuffer class, i tried to create an instance of it. however, the program always crashes on:
wglChoosePixelFormatARB( hdc, iattributes, fattributes, MAX_PFORMATS, pformat, &nformats )
so my code goes something like this: after i create the main window (using glut), but before i enter the glutMainLoop, i run:
int mode = (GLUT_RGBA | GLUT_STENCIL);
PBuffer* pbuffer = new PBuffer(800, 600, mode);
pbuffer->Initialize(true, true);
and it crashes in the initialize routine on the line i mentioned above. any ideas?

ah, i found what i was doing wrong – i wasn’t calling the routines:
glh_init_extensions(“WGL_ARB_pbuffer”);
glh_init_extensions(“WGL_ARB_pixel_format”);
in the gl_extensions header file. it looks like at least this one bit of code will still have to be system dependent – i guess i thought they would’ve abstracted those initialization routines away in the pbuffer’s constructor or something. oh well.

Yes, you’ll need to call

glh_init_extensions(“WGL_ARB_pbuffer WGL_ARB_pixel_format”)

under Windows and call

glh_init_extensions(“GLX_SGIX_pbuffer GLX_SGIX_fbconfig”)

under Linux/FreeBSD.

so i think i have everything set up correctly. however, when i render into my pbuffer, and then read back the stencil buffer, there is never anything in it. my pbuffer is an 800x600 window with a 24 bit depth buffer and an 8 bit stencil buffer. i call:
pbuffer->MakeCurrent(); //make pbuffer active
glClear(GL_DEPTH_BUFFER_BIT |GL_STENCIL_BUFFER_BIT);
glLoadIdentity();
gluLookAt(…);
glEnable(GL_STENCIL_TEST);
…set stencil test params…
renderMyScene();
glDisable(GL_STENCIL_TEST);
glReadPixels(0, 0, 800, 600, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, pixelBuffer);
glutSetWindow(windowID);
when i run the above, the pixelBuffer always returns empty as if nothing were drawn. also, i’m not sure exactly what is shared between the pbuffer and the glut DC. i told it not to share contexts or lists, but i don’t use any display lists, but rather just use glVertex, etc right there. for example, do they share the same modelview/projection matrix?

so i answered my own question – yes, it seems they do have their own projection/modelview matrices. i hadn’t called glViewport(0, 0, width, height) – once i did that, i was able read back my image! thanks for the help everyone, especially jra =)

If you tell it to share display lists, that basically means that display lists, vertex programs, texture objects, etc… are shared between the rendering contexts.