1

I would like to perform some 3D rendering on my Debian machine and bring the result into client-side memory.

I've created a C++, GLX, and GLEW based application that does not require a window. I get a display with glXOpenDisplay, use it to find a proper framebuffer with glXChooseFBConfig (passing the DefaultScreen of the display), obtain visual info with glXGetVisualFromFBConfig, and pass the relevant information to glXCreateContext. I make that context current & initialize GLEW.

As a starting test, I'm simply clearing the default framebuffer with a variety of colors; I would like to now query the result pixel-by-pixel, presumably with glReadPixels.

But this is where I seem to be fundamentally misunderstanding something: What are the dimensions of the default framebuffer? I never define an initial height or a width for it, and I'm not seeing a way to do so.

Answers such as this one imply the window "defines" the dimensions. In my application, is the DefaultScreen defining the dimensions? If that's the case, what can I do to make the default framebuffer larger than a particularly small screen?

Community
  • 1
  • 1
Litty
  • 1,856
  • 1
  • 16
  • 35

2 Answers2

3

and pass the relevant information to glXCreateContext. I then initialize GLEW.

Just because you have a context does not mean, that you can immediately use it. Consider what happens if you have more than one context. Before you can make OpenGL calls, you have to make active a context on the current thread, using glXMakeCurrent or glXMakeContextCurrent. If you look at those functios' signatures you'll see that they take a Drawable as parameter in addition to the OpenGL context. So you need that, too.

For windowless operation GLX offers PBuffers, which offer windowless drawables. Or you could use a window that you don't map to the screen. PBuffers allow to do offscreen rendering without the use of framebuffer objects, but the use of their main framebuffer is a bit finicky. My recommendation is the use of a 0×0 sized PBuffer and a framebuffer object.

datenwolf
  • 159,371
  • 13
  • 185
  • 298
  • I was making the context current, but that was omitted it from my description. Updated to reflect. PBuffers are exactly what I'm looking for, thank you! – Litty Apr 17 '17 at 21:21
  • 1
    As it so happens, since OpenGL 3.0 it seems, you may pass `None` as the drawable to `glXMakeCurrent` to perform "offscreen rendering" to a user-specified framebuffer. No PBuffer nor window is required. – Litty May 23 '17 at 08:17
1

You need to use framebuffer objects. These use textures whose dimensions you have specified. For example:

// Generate framebuffer ID
GLuint fb;
glGenFramebuffers(1, &fb);

// Make framebuffer active
glBindFramebuffer(GL_FRAMEBUFFER, fb);

// Attach color and depth textures (must have same dimensions)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color_tex, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_tex, 0);

// Check framebuffer is valid
assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
Joseph Thomson
  • 9,888
  • 1
  • 34
  • 38
  • What if I initialized a pixel buffer before creating the context instead? After some further research, that seems to be more of what I'm looking for. This way I can still use the default framebuffer. – Litty Apr 17 '17 at 07:04
  • @Litty You can use pixel buffer objects as a more efficient way to transfer pixel data from the framebuffer to your application, but you will still need a framebuffer. – Joseph Thomson Apr 17 '17 at 11:04
  • I believe these are different than OpenGL's PBOs. Am I incorrect? https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glXCreatePbuffer.xml – Litty Apr 17 '17 at 19:01
  • @Litty Pbuffers are an old platform-specific way to render to an off-screen target. So no, they are not the same as PBOs. Pbuffers have been largely superseded by FBOs. – Joseph Thomson Apr 17 '17 at 23:56
  • I've also read that. Although I'm going with pbuffers for my needs, for the sake of knowledge, are you recommending I just ditch the default framebuffer altogether? It seems weird to have it initialized and unused. – Litty Apr 18 '17 at 06:06
  • 1
    @Litty As datenwolf described, you can use a 0x0 pbuffer as a means to make use of your context, or create a hidden window. Really, you shouldn't have to create a render target in order to use a context, but OpenGL is old and quirky. I would recommend using framebuffers over pbuffers simply because they are cross-platform, likely to be more flexible, and less likely to be buggy. Obviously if you are targeting really old hardware that may not support OpenGL 3 or the framebuffer extension, you will have to use pbuffers. – Joseph Thomson Apr 18 '17 at 08:02
  • 1
    I'm coming to these same conclusions at hindsight; Good recommendation, thank you. – Litty Apr 22 '17 at 05:14