Mailing Lists: Apple Mailing Lists
Image of Mac OS face in stamp
Re: CGLPBufferObj , glReadPixels & drawing to pBuffers?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: CGLPBufferObj , glReadPixels & drawing to pBuffers?



A few observations...

- 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)


--- Drawing with PBuffer texture ---
Bind PBuffer texture object (CGLSetPBuffer)
Enable appropriate texture target (glEnable)
Draw primitives with appropriate texture coordinates (glBegin/glEnd, etc.)


-- 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


References: 
 >Re: CGLPBufferObj , glReadPixels & drawing to pBuffers? (From: Simon Goldrei <email@hidden>)
 >Re: CGLPBufferObj , glReadPixels & drawing to pBuffers? (From: Simon Goldrei <email@hidden>)



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2011 Apple Inc. All rights reserved.