Reputation: 331
I have some code written for Linux which I need to re-implement so it can work on Windows and Linux. It's currently X-Windows, GLX and OpenGL 2.1 and I'm using SDL2 and compatible OpenGL extensions using GLEW (it's still running on an old (Centos 5.3) Linux platform as well as recent Windows with 6 year old graphics cards).
I'm stuck on how to replace glXMakeContextCurrent. This is currently used to select Read and Draw Pixel Buffers (GLXPbuffer) and associate with a context. I've been looking at using Pixel Buffer Objects to replace the GLXPbuffers but don't know how to replicate the functionality of glXMakeContextCurrent using such techniques, or if there's a better way to do it.
The existing code sets it up so that it renders into a GLXPbuffer and then uses glCopyPixels to copy from one drawable (a GLXPbuffer) to another (another GLXPbuffer) using the specified context, with the Draw and Read Drawables and Context specified in the glXMakeContextCurrent call. This is a mostly 2D OpenGL application.
How can this be achieved without using GLX, i.e. so it works on Windows (as well as Linux)?
Here's a code segment showing what the current code does:
Display *dpy;
GLXContext osr_ctx;
GLXPbuffer pbuf2, osr_pbuf;
void sel_drc( GLXDrawable dst, GLXDrawable src, SDL_GLContext ctx )
{
if ( !src )
{
if ( !glXMakeCurrent( dpy, dst, ctx ) )
{
Error( "glXMakeCurrent" );
}
}
else
{
if ( !glXMakeContextCurrent( dpy, dst, src, ctx ) )
{
Error( "glXMakeContextCurrent" );
}
}
}
// Display dpy is set up elsewhere.
// GLXContext and GLXPbuffers get created elsewhere and stored in osr_ctx, pbuf2, osr_pbuf
// The Display and GLXContexts are to be replaced by their SDL2 equivalents.
// GLXPbuffers are currently planned to be Pixel Buffer Objects:
// GLuint pboIds[2];
// glGenBuffers(2, pboIds);
// glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboIds[0]);
// glBufferData(GL_PIXEL_UNPACK_BUFFER, DATA_SIZE, 0, GL_STREAM_DRAW);
// etc.
//
sel_drc( osr_pbuf, pbuf2, osr_ctx );
glRasterPos2f( 0.1, 0.1 );
glCopyPixels ( 0, 0, 576, 576, GL_COLOR );
Upvotes: 1
Views: 571
Reputation: 331
It would appear that a simplistic, albeit potentially low performance solution is to use Framebuffer Objects and blit between them using glBlitFramebuffer:
GLuint fboId; // ID of FBO
glBindFramebuffer(GL_READ_FRAMEBUFFER, fboId);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBlitFramebuffer(0, 0, TEXTURE_WIDTH, TEXTURE_HEIGHT,
0, 0, screenWidth, screenHeight,
GL_COLOR_BUFFER_BIT,
GL_LINEAR);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
This is equivalent of copying between two Framebuffer Objects. In this instance, the code copies from the FBO (fboId) to the default Framebuffer (0).
This code is from: http://www.songho.ca/opengl/gl_fbo.html
It would seem that it is quicker to render to a texture and then render a quad into the destination Framebuffer with that texture bound. However, this glBlitFramebuffer approach is close to the existing code structure and probably won't be any worse than the glCopyPixels currently employed.
Upvotes: 1