- you do not need the flush/finish combo, the draw buffer call or the
texture bind. once you build the pbuffer its context, just like any
other context retains state. Set your draw buffer once, the pbuffer is
the pixels that you will texture from but has nothing to do with the
texture command itself and if you are single buffered a flush will be
fine, otherwise a swap.
I believe the issue you have is not understanding which context is
which in regards to texturing from the pbuffer...
- when drawing to your window, or texturing from the pbuffer in general
your context should be your window context NOT the pbuffer context.
E.G., teximagepbuffer's context is the window context NOT the pbuffer
context.
- When drawing to the pbuffer, obviously the context should be the
pbuffer context and it should act like a normal context. Though I
expect you do not want this context current when doing any texturing
from the pbuffer as the pbuffer cannot be drawn to and textured from at
the same time.
here are my notes on pbuffer use. Since I am having a tough time
getting them up on the developer web site, I will build a page on my
site in the next day or two to host them from folks who want to grab
them from somewhere other than this list (as the list has message
length restrictions).
---
Concepts and Usage:
Note: This document discusses PBuffers specifically using the CGL API
as an example. The same concepts, capabilities and limitations apply to
the AGL and NSOpenGL API unless otherwise noted.
Using PBuffers is similar to using a normal window or view as an OpenGL
drawable, the capabilities and restrictions are very much the same.
Clients should create a pixel format as usual with the specific
capabilities as determine by their application. Once a valid pixel
format is found the application create a context like it would for any
other rendering.
Note: While it is not required to specify the kCGLPFAPBuffer pixel
format attribute, failure to do will not guarantee a pixel format which
is compatible with pbuffers. In all likelihood the returned pixel
format will be compatible with pixel buffers, it is just not
guaranteed.
The actual pixel buffer is created with the CGLCreatePBuffer which is
very similar to creating a window or a view. Conceptually this pixel
buffer owns the actual pixel data associated with the PBuffer while the
OpenGL context owns the rendering state used to draw to or from the
PBuffer. The CGLCreatePBuffer requires the client to specify width,
height, and the texture target, all of which must be compatible (e.g.,
GL_TEXTURE_2D requires power of two width and height). Furthermore,
clients will need to specify either GL_RGB or GL_RGBA as the internal
format to indicate whether texturing will use the buffer's alpha
channel. Lastly, the maximum mipmap level should be specified, if
multiple mipmap levels are desired and are supported by the PBuffer's
texture target. Note: The actual bit depth and pixel format (such as
RGB or floating point) of a PBuffer is determined by the pixel format
of the context(s) that attach to the PBuffer for rendering, and not by
the internal format argument to CGLCreatePBuffer.
Once the pixel buffer is created the client can set it as the rendering
target with the CGLSetPBuffer command, which is similar to
CGLSetFullscreen, aglSetDrawable or NOpenGLContext's setView: method.
This call provides additional capability to target the specific drawing
destination buffer and renderer used for drawing with the face, level
and screen parameters. For PBuffers created with a GL_TEXTURE_CUBE_MAP
target, the face parameter must be one of the standard six face
enumerated values. For all other PBuffer targets face should be zero.
The destination mipmap level is set with the level parameter and must
be less than or equal to the maximum mipmap level specified at PBuffer
creation. Finally the renderer used can be specified by setting the
virtual screen parameter. It is recommended that the same renderer used
for the context that is the target of PBuffer texturing be used. This
can be achieved by querying the target context's virtual screen with
CGLGetVirtualScreen and passing this in as the screen parameter of the
source PBuffer.
Note: CGLSetPBuffer should always be called at least once prior to
attempting to set up texturing with a PBuffer to ensure needed buffers
have been created.
Now that the PBuffer is the rendering target the client can draw using
the PBuffer's context with the result going to the PBuffer. Any legal
OpenGL drawing commands can be used (which maybe limited by those
allowed by the PBuffer's pixel format) to render to the pixel buffer.
To complete the drawing a flush or swap command should be issued,
depending on whether the PBuffer's pixel format requested single or
double buffering.
Texturing from a pixel buffer is done from the "target" context and
follows normal OpenGL texturing rules. The "target" context is the
OpenGL context in which the actual drawing WITH the PBuffer texture
will take place (which is not normally the same context as was used to
draw into the PBuffer). Texturing from PBuffers cannot use the default
texture object, thus applications must generate a texture object (name)
and bind to it before texturing with a PBuffer. As a convenience to
developers, textures created from PBuffers with CGLTexImagePBuffer that
only have a single mipmap level defined automatically have their
filtering modes set up to disable mipmap filtering. This was done
because it is possible for OpenGL to know up front that there will
never be more than one mipmap level.
Setup for texturing can occur anytime after CGLSetPBuffer is called and
prior to actually drawing with the PBuffer texture. To texture from a
PBuffer clients should generate a texture object, bind to this object,
set appropriate texturing parameters (state) and then call
CGLTexImageBuffer to use the contents of the pixel buffer as a texture.
CGLTexImageBuffer is equivalent to glTexImage2D with the source
parameter representing the specific OpenGL buffer buffer to use to
texture from (GL_FRONT, GL_BACK, etc.). Of course, the buffer used must
actually be defined by the the pixel buffer's pixel format.
Note: If a texture name has been used with a normal (non-PBuffer)
texturing command, such as glTexImage1D, glTexImage2D, etc.,
glDeleteTextures must be called on that particular texture object (and
thus glGenTextures and glBindTexture would need to be re-issued) prior
to using glTexImagePBuffer to set a PBuffer as the texture source.
Note: No OpenGL texturing commands which modify a PBuffer texture
content are permitted, such as glTexSubImage2D, glCopyTexImage2D, with
the PBuffer texture as the destination. It IS permitted to use
texturing commands to read data from a PBuffer texture, such as
glCopyTexImage2D, with the PBuffer texture as the source. It is also
legal to use OpenGL commands to directly read the contents of a PBuffer
via the PBuffer context, such as glReadPixels.
Note: When using a single base level PBuffer all changes to the PBuffer
content are picked up (synchronized) by the client re-binding to the
texture object created for the PBuffer. If mipmaps are in use the
client must re-issue the CGLTexImagePBuffer command to pick up changes
in the mipmap levels.
Note: Context resource sharing is not required for texturing from a
PBuffer. A client can have independent pixel formats and OpenGL
Contexts for both the PBuffer and the target drawable without sharing
resources and still texture using a PBuffer in the target context.
Note: Clients should ensure the texture target used for creation of the
PBuffer is enabled prior to texturing with the PBuffer texture.
Additionally, all requirements for the particular texture target in use
must be met, including renderer support, size requirements, and texture
parameters appropriate for PBuffer setup.
Once the client is finished with the PBuffer it can be destroyed as one
would destroy any other OpenGL rendering environments. It is
recommended that clients delete texture objects associated with
PBuffers prior to destroying the associated PBuffer. This will ensure
these textures are not used once the PBuffer is destroyed. This ensures
problem free behavior on all versions of the PBuffer API. To destory
the PBuffer, first set the PBuffer context as the current context then
destroy the PBuffer with CGLDestroyPBuffer, followed by destruction of
the OpenGL context and pixel format in the normal manner. It matters
not whether the PBuffer was used recently for texturing as the OpenGL
engine will ensure the texturing is completed as expected.
Usage Outline:
The following is a simple outline of creating and using a pbuffer that
has its own pixel format and context.
--- Setup PBuffer Drawable ---
Create PBuffer (CGLCreatePBuffer)
Set pbuffer as drawing target for the context (CGLSetPBuffer)
--- Draw into pbuffer ---
Set current context as the PBuffer's context (CGLSetCurrentContext)
Draw with OpenGL (glBegin/glEnd, etc.)
Set current context as the PBuffer's context (CGLSetCurrentContext)
Draw with OpenGL (glBegin/glEnd, etc.)
--- Draw into target context ---
Set current context as the target's context (CGLSetCurrentContext)
(note: this is NOT the pbuffer's context)
--- Set up texturing ---
Create texture object (glGenTextures)
Bind the texture object (glBindTexture)
Set texture parameters (glTexEnvParameter)
Create PBuffer texture (CGLTexImagePBuffer)
(note: the context parameter here should be the target context not the
pbuffer context)
-- Destruction ---
Delete texture object (glDeleteTextures)
Set current context (CGLSetCurrentContext)
Destroy pbuffer (CGLDestroyPBuffer)
Destroy context (CGLDestroyContext)
Destroy pixel format (CGLDestroyPixelFormat)
Set current context to NULL (CGLSetCurrentContext)
On Dec 5, 2004, at 11:18 PM, Simon Goldrei wrote:
Hi Gordon,
Thanks for this. I had a solid look and I think I've learnt a few
things from it.
I was unable to compile your project though. I couldn't figure out how
to install glew and I didn't know where to get CG libs from.
I can grab my full framebuffer to a full-sized texture, thanks to
glCopyTexSubImage2D() but scaling it and copying to system memory is
still a no-go.
This CGLPBuffer stuff still gives me grief. Is it properly supported
in Panther? Or only Tiger? From your code it seems you know something
I don't...
I can't tell if it is that I can't draw to it, or can't read from. I'm
thinking it's the former, I don't know how to draw a texture to the
pBuffer. The way I think I should do it is:
<snip>
Geoff Stahl
3D Software Engineer
Apple
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Mac-opengl mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden