PDA

View Full Version : copy pixels from visible buffer to pbuffer?



codemonkey76
12-15-2004, 11:33 AM
i have the latest (windows) drivers on an nv28.

i can do this:
wglMakeContextCurrent(visible, pbuffer, visibleContext);

and glCopyPixels() copies the data fine from the pbuffer to the visible buffer.

but this:
wglMakeContextCurrent(pbuffer, visible, pbufferContext);

(and a few other combinations i've tried) doesn't work to copy from the visible buffer to the pbuffer. anyone have any ideas? is it not possible, or is there possibly something wrong with my glReadBuffer or glDrawBuffer, or the fact that the visible buffer is double buffered but not the pixel buffer? any ideas?
thanks!

SirKnight
12-15-2004, 02:08 PM
Do you mean framebuffer when you say "visible buffer?" To render to a pbuffer do the following:

1) wglMakeCurrent( dc, rc );
2) RenderStuff...
3) Bind Render Texture id...
4) glCopyTexSubImage2D( blah blah );
5) wglMakeCurrent( olddc, oldrc );

And you're all done. Now your rendered stuff is in a texture for you to love and enjoy. :D

-SirKnight

codemonkey76
12-15-2004, 03:02 PM
yes, frame buffer = visible buffer

however, i am not interested in getting the stuff in the framebuffer or pbuffer into a texture.

i am interested in getting pixels (a NPOT rectangle) from the framebuffer to a pbuffer for the purposes of later coping back to the framebuffer.

i want behavior similar to the wgl buffer_region extension, but more flexible. as i said before, the copy of pixels using glCopyPixels works fine from pbuffer->framebuffer, but not framebuffer->pbuffer.

i don't know if i am running into a driver bug or am just not doing things properly...

rgpc
12-15-2004, 07:31 PM
Originally posted by codemonkey76:
however, i am not interested in getting the stuff in the framebuffer or pbuffer into a texture.So you are not interested in speed...


Originally posted by codemonkey76:
i am interested in getting pixels (a NPOT rectangle) from the framebuffer to a pbuffer for the purposes of later coping back to the framebuffer.
So you are going to drag your data back across the AGP bus, then push it through the AGP bus back onto the card, THEN your going to do it again, purely because you have no interest in doing it the easy (and fast) way...

Also I presume you would at least be doing something with that data, other than just storing it in a pbuffer? Like some post processing or adding to the pbuffer? Because it'd be extremely inefficient to go through all this, just to store it in a pbuffer rather than just keep it in memory (which'd just be plain old inefficient, as opposed to using a texture).

codemonkey76
12-16-2004, 02:35 AM
arrrrghhh!

it is NOT going through AGP to main memory. it is a direct buffer-to-buffer copy with glCopyPixels(), setting the appropriate read and draw buffers using wglMakeContextCurrent() (check the spec!).

the pixel rectangles are NOT powers of two, so i can't use a texture intermediary unless the card supports one of the NPOT extensions (which it doesn't).

WGL_ARB_buffer_region is what i need but is not flexible enough to handle copying pixels from one region to another or doing incremental updates.

the whole reason for all of this is so i can
periodically save a region from the visible buffer to a temporary location, then later restore it, possibly to a different location. this is to accomplish incremental updates of a medical simulator using volume rendering, when it is too expensive to render the entire screen. i have been doing this with straight glReadPixels/glDrawPixels but think i should be able to use pbuffers for more performance.

i have glCopyPixels working with a direct buffer-to-buffer video memory copy (no AGP) FROM a pixel buffer TO the visible frame back buffer, but not the other way around. THAT'S what i need help with!

:)

codemonkey76
12-16-2004, 09:44 AM
ok, after more testing, it looks like the copy itself is working, but the pixels are being read/drawn to the wrong place. i'm trying to work out what's going on. it could be a driver bug. the image only shows up correctly if the pbuffer size and window size are the same.

i wish there was more documentation about how glCopyPixels works with wglMakeContextCurrent. it is not clear where the coordinates used by the copy are with respect to the active context, read buffer or draw buffer.

Aeluned
12-16-2004, 10:39 AM
So, You set your read buffer as the frame buffer and have your pbuffer as the current context?

In addition to that be sure you're setting your raster position. glCopyPixels copies pixels from the read buffer to the active region starting at the current raster position.

Also, glCopyPixels is undefined for areas where the window is obscured or for pixels outside the window area. Since a pbuffer is an offscreen context you don't run into this problem. However, for the typical frame buffer you could end up reading garbage if any of those pixels lie outside the window or in an obscured area of the window.

codemonkey76
12-16-2004, 11:31 AM
i think the raster position is part of the problem. as i resize the window, the copied part is moving around and sometimes it overlaps where it is supposed to be going, and sometimes not.

so here's the problem: the raster position is set in one context (either the visible context or the pbuffer context), but is used by the draw buffer set by wglMakeContextCurrent. this has to be synchronized with which buffers are the read and draw buffers, and which context is receiving the glCopyPixels().

i think it is probably working, but everything is obfuscated by the lack of clear documentation on how to do things. i'll keep hacking and hopefully stumble upon the correct solution...

Aeluned
12-16-2004, 12:45 PM
Hmmm...

Well, the raster position is set for each context.
Reset the raster position in your pbuffer context when you're about to do your pixel copy. Since your pbuffer resolution and frame buffer resolution don't necessarily match, you may or may not want to perform a pixel zoom...that's up to you.

rgpc
12-16-2004, 02:03 PM
Originally posted by codemonkey76:
arrrrghhh!

it is NOT going through AGP to main memory. it is a direct buffer-to-buffer copy with glCopyPixels(), setting the appropriate read and draw buffers using wglMakeContextCurrent() (check the spec!).

Right you are, I misread your post. :rolleyes:

From the Red book...



The data is copied to a new position whose lower left corner is given by the current raster position.