Pbuffer support

I’m looking at adding Pbuffer support to SDL, so you can do render to texture.

On Windows it seems to be very well supported using wglBindTexImageARB()

I can’t find any information on using multiple pbuffers as read buffers
with GLX. As far as I can tell you switch to the pbuffer context, render,
then use glxMakeContextCurrent() to set the window drawable as the write
buffer and the pbuffer drawable as the read buffer and use glCopyTexImage2D
to copy to a texture. At that point does the texture point to the pbuffer
by reference? Can you make another pbuffer context current, and then do
the same thing with that so both buffers are available as textures? Can
you share display lists and other context resources between the main context
and the pbuffer context?

For MacOS X, it seems NSOpenGL is the way to go, but I know next to nothing
about it.

Comments are welcome. :slight_smile:

See ya!
-Sam Lantinga, Software Engineer, Blizzard Entertainment

I’m looking at adding Pbuffer support to SDL, so you can do render to texture.

On Windows it seems to be very well supported using wglBindTexImageARB()

I can’t find any information on using multiple pbuffers as read buffers
with GLX. As far as I can tell you switch to the pbuffer context, render,
then use glxMakeContextCurrent() to set the window drawable as the write
buffer and the pbuffer drawable as the read buffer and use glCopyTexImage2D
to copy to a texture. At that point does the texture point to the pbuffer
by reference?

No, it copies the pbuffer contents to the texture. The render_texture
extension eliminates this copy, but the GLX version is unfortunately not
available.

Can you make another pbuffer context current, and then do
the same thing with that so both buffers are available as textures?

After copying the first pbuffer to a texture, do the same thing with the
second pbuffer, and so on.

Can
you share display lists and other context resources between the main context
and the pbuffer context?

Display lists and texture objects are shared with the context specified
as the fourth parameter when calling glXCreateNewContext.

Alternatively, if the pbuffers and the main window are compatible
(same rendering type, color buffers are of the same depth, and created
with the same X screen), then you can get by with only one context.

Steven FullerOn Sun, 3 Aug 2003, Sam Lantinga wrote:

Well, I know next to nothing about pbuffers but I saw this at
developer.apple.com:

http://developer.apple.com/qa/qa2001/qa1269.html

It talks about the four basic OpenGL interfaces on OS X (CGL, AGL,
NSOpenGL, and GLUT) and has links to sample code. It looks like the
CGL and AGL have full pbuffer support. NSOpenGL has “a PBuffer
interface” but it doesn’t mention how complete it is.

Hope this was useful.

patOn Monday, August 4, 2003, at 01:00 AM, Sam Lantinga wrote:

For MacOS X, it seems NSOpenGL is the way to go, but I know next to
nothing
about it.

If found this sample code:
http://developer.apple.com/samplecode/Sample_Code/Graphics_3D/
AGLSurfaceTexture.htm

It seems a lot like what wgl does. You have to create an offscreen
window, bind a context to it, render, then bind the context to a
texture for the main context. So you’ll probably need a few function
calls (at least) to abstract that. For the Mac OS X implementation,
we’ll need a little voodoo to mix AGL with NSOpenGL, but besides that
it seems straightforward.

Here’s my take on the required API additions:

void* SDL_GL_CreatePBuffer(int size, )
- size must be power of 2
- more parameters for mipmapping, filters, rectangle_ext, etc
- lets platform choose optimal pixel format

SDL_GL_MakePBufferCurrent(void *pBuffer)
- also need a way to make main GL context current!

SDL_GL_BindPBufferTexture()
- just calls glBindTexture() on the (private) texture id

SDL_GL_FreePBuffer()On Monday, August 4, 2003, at 01:00 AM, Sam Lantinga wrote:

For MacOS X, it seems NSOpenGL is the way to go, but I know next to
nothing
about it.

Okay, here’s a proposed API for SDL 1.2.6 Pbuffer support:
/*

  • OpenGL render to texture support (pbuffers)
    /
    typedef struct SDL_Pbuffer {
    /
    Texture that holds the contents of the pbuffer after unlock */
    unsigned int texture;

    /* Implementation-specific context info */
    void *context;
    } SDL_Pbuffer;

/*

  • Create a pbuffer with the given size and format.
  • The format parameters are a zero terminated list of SDL_GL_* attibutes,
  • each followed by the associated value.
  • Currently this function does not create a new OpenGL context.*
  • This function returns NULL if a pbuffer couldn’t be created.
    */
    extern DECLSPEC SDL_Pbuffer * SDLCALL SDL_GL_CreatePbuffer(int *format, int width, int height);

/*

  • Set the pbuffer as the current OpenGL rendering context.
    */
    extern DECLSPEC void SDLCALL SDL_GL_LockPbuffer(SDL_Pbuffer *pbuffer);

/*

  • Update the texture with the contents of the pbuffer and make the
  • normal rendering context current.
    */
    extern DECLSPEC void SDLCALL SDL_GL_UnlockPbuffer(SDL_Pbuffer *pbuffer);

/*

  • Release any resources associated with the pbuffer, including its texture.
    */
    extern DECLSPEC void SDLCALL SDL_GL_DestroyPbuffer(SDL_Pbuffer *pbuffer);

Comments are welcome!
-Sam Lantinga, Software Engineer, Blizzard Entertainment

“Sam Lantinga” wrote in message
news:mailman.1060209422.28856.sdl at libsdl.org

Okay, here’s a proposed API for SDL 1.2.6 Pbuffer support:

<< Re: SDL_GL_CreatePbuffer >>

  • Currently this function does not create a new OpenGL context.
  • Set the pbuffer as the current OpenGL rendering context.
    extern DECLSPEC void SDLCALL SDL_GL_LockPbuffer(SDL_Pbuffer *pbuffer);

I’m a little confused - does it or does it not create a new context?

extern DECLSPEC void SDLCALL SDL_GL_DestroyPbuffer(SDL_Pbuffer *pbuffer);

We currently have FreeSurface, FreeCursor, FreeYUVOverlay, FreeWAV,
DestroyMutex and RemoveTimer. I’d prefer to use FreePbuffer in an attempt
at consistency.

I’m not sure about the Lock/Unlock setup. It sounds like, if I have two
pbuffers, there will be an unnecessary switch to the main rendering context
between unlocking one and locking the second. I’m also not sure about the
texture data update being forced on each unlock… I could see that as a
potential performance issue beyond the programmer’s control.

I’ve always seen Pbuffers as a potential expansion to the ‘surface’ concept.
It seems they could be neatly implemented using an additional flag or two
and the existing API with the addition of a call to make the surface the
current rendering target. You would lock a pbuffer prior to using it as a
texture, unlock afterwards, create and destroy as applicable… This would
also introduce the API call necessary to switch between multiple 'normal’
rendering contexts so multiple windows could be used easily.

Admittedly, I’m looking at SDL from the usage point of view, rather than an
under-the-hood implementation point of view. Perhaps tidying will have to
wait for 2.0…

If I had to settle for less, I’d like a separate call to make the context
current, allow me to switch directly to another pbuffer context instead of
hitting main, and only update texture data when locked.

If I had to settle for even less, I’d be happy with SDL just supporting the
things directly :slight_smile:

Thanks,
– Jeff