WIN32 Question / Advice

First let me preface the question by describing my application. I have a “main” application that spawns an openGL rendering window. Everything regarding this window is contained in a class I defined - call it COGLwin. It has its own message handler (and of course its own rendering context). The ultimate purpose of COGLwin is to use openGL as a means to do volume rendering via raycasting. Nevermind the details of volume rendering. The only thing is that it operates very similar to raytracing. As such I would like, as other raytracers do, render the scene scanline by scanline. My question is this: Say during the raycasting (raytracing) procedure I get a WM_PAINT message (e.g. minimize then maximize again) and a portion of what I have already rendered gets invalidated. Since volume rendering can be computationally intensive, I clearly do not want to render the entire scene again. An option is to store my progress (i.e. the pixels I’ve rendered already) in some buffer and, when I need to repaint, simply dump that buffer to the window. I’d prefer not to do this though because: (a) the datasets that need to be rendered can be huge and minimizing memory-usage is vital (must avoid paging the dataset if possible) ; (b) writing to the buffer is just more overhead.

Can anyone offer a better suggestion? Or does Windoze somehow “implicitly” perform this refresh for us?

Thanks. Sorry for the length of the post…
ks

Hm, you may be able to hack something by using double buffering, then using readpixel/writepixel to copy the backbuffer to the front buffer, instead of doing a swap. I’m not 100% sure but I think that the backbuffer is guaranteed to be valid no matter what as long as you don’t swap (at which point the content becomes undefined). Alternatively render to texture and simply draw a 1:1 quad using that texture to the frontbuffer in your wm_paint ?
Just some ideas, I didn’t try this

All buffers have undefined contents of occluded areas.

Eh ? So… suppose a dialog box is occluding the upperleft of a window. I’m rendering to the backbuffer. Before I do the swap, the user drags the dialog to the lowerright. Now I swap. Are you saying the upperleft is undefined, and I will need to start all over anyhow ? That’s very interesting indeed !

First off - how would I write to the back - buffer: doesn’t glWritePixel( ), write to the frame-buffer. Or when using double-buffering (which I don’t really need), does glWritePixel() write to the back-buffer? (Excuse my ignorance, I haven’t had the occasion to use openGL to write pixels)

So what you guys are saying is that even if I write directly to the back buffer a portion of it will get invalidated if something like a dialog invalidates a portion of the window. In other words, even if I write directly to the back buffer and a portion of my window gets invalidated, I have to start all over again - or “fill in” the portion of the back buffer that was invalidated. If this is the case would it be better just to have another buffer - call it the “progress buffer”? In this case, the progress buffer contains all the pixels that have been determined by the ray-casting procedure. These will be dumped to the screen at some regular interval - say once per line - or when some portion of the window gets invalidated. This seems like a sloppy albeit easy way to handle the problem. I would have preferred to use the buffers that are provided to us by openGL.
ks

[This message has been edited by loopguru (edited 11-07-2002).]

[This message has been edited by loopguru (edited 11-07-2002).]

Eh ? So… suppose a dialog box is occluding the upperleft of a window. I’m rendering to the backbuffer. Before I do the swap, the user drags the dialog to the lowerright. Now I swap. Are you saying the upperleft is undefined, and I will need to start all over anyhow ? That’s very interesting indeed !

And what if the driver is using a unified back buffer and the dialog contains another OpenGL viewport?

First off - how would I write to the back - buffer: doesn’t glWritePixel( ), write to the frame-buffer. Or when using double-buffering (which I don’t really need), does glWritePixel() write to the back-buffer?

glDrawPixels (which I suppose you mean) draws pixels to the buffer sepcified by glDrawBuffer. Default is the back buffer for a double buffered application.

So what you guys are saying is that even if I write directly to the back buffer a portion of it will get invalidated if something like a dialog invalidates a portion of the window

Not will, may.

If this is the case would it be better just to have another buffer - call it the “progress buffer”?

Yes, that would be better. Have a look at p-buffers.

I would have preferred to use the buffers that are provided to us by openGL.

But it would certainly be easier to render to your own buffer in system memory, and copy it (or parts of it) into the front buffer when needed. It’s not that difficult to allocate an buffer and draw it to the front buffer.

And what if the driver is using a unified back buffer and the dialog contains another OpenGL viewport?

Well I’d say the driver can do whatever it wants, as long as it adheres to the spec. Now, it’s not that I don’t believe you but just for completeness, can you point to the part of the spec where this behavior is discussed (and the above driver behavior allowed) ? This kind of trickery has come up a few times, I’d like to check it out in depth. Thanks

I don’t think there’s anything in the spec about unified buffers. At least there’s nothing in there that prevents unified buffers.

Not forcing correct contents of occluded pixels in the back buffer can be an enormous benefit in some applications. Concider a huge modelling software, with lots of large views overlapping each other (like a few scene and material previews, modelling areas, for example). Since a pixel can belong to one, and only one, rendering context at a time, having separate back, depth and stencil buffers for each separate window is a waste of memory. Unified buffers can reduce the memory requirements.

Also, if the front buffer is occluded, the content of the back buffer won’t be visible anyways on a buffer swap. Since OpenGL is intended for realtime graphics, the problem with long rendering times should not be handled by OpenGL.

Anyways, check out the section on per-fragment operations and the framebuffer in the spec, chapter 4 in the 1.4 spec at least. Maybe you find some usefull information there.

Thanks for the input, I see what you mean. I was kindof assuming the spec wouldn’t allow such unification, because there isn’t any guarantee that those different RCs would be compatible anyway; ie even though the pixel is only in one RC at a time, it maybe in a 16bpp now and in a 32bpp the next moment, kindof nuking unification efforts (unless you have very leet hardware). I’ll check out the reference, I was mostly bouncing around in 1.1. Thanks.

It seems to me that “loopguru” isn’t really using OpenGL. Sure, there are calls to create a GL window, but it doesn’t seem like he’s using anything more than glDrawPixels or something like it and SwapBuffers. In that case, why even use OpenGL at all?

You can just as easily create a Win32 bitmap object, write to the pixels of it, and then blit it to the window’s device context. Sure, it won’t be accelerated drawing, but it’ll be much easier than dealing with OpenGL for simply displaying an image.

Eh ? So… suppose a dialog box is occluding the upperleft of a window. I’m rendering to the backbuffer. Before I do the swap, the user drags the dialog to the lowerright. Now I swap. Are you saying the upperleft is undefined, and I will need to start all over anyhow ? That’s very interesting indeed !

Note that, under Windows, the window regions don’t (usually) change until all applications involved have had a chance to call into the Windows message pump. So it’s very unlikely that the user can drag the window from one place to another WHILE you’re rendering (unless you’re multi-threaded).

Multitasking seems sufficient, the occluder doesn’t need to be from the application doing the rendering ? Or am I missing something