PDA

View Full Version : Every other frame is completely black..



undershirt
02-02-2011, 10:37 AM
I am using a barebones OpenGL app without a display. I am just using glReadPixels to get the rendered image.

I am dumping the result of glReadPixels after each frame is drawn, but the problem is that every other frame is completely black. This is fixed if I call glClear twice before drawing anything. Can anyone tell me what's causing this problem? Thanks.

Source [runs in linux]:


#include <stdio.h>
#include <stdlib.h>

#include<X11/X.h>
#include<X11/Xlib.h>
#include<GL/gl.h>
#include<GL/glx.h>
#include<GL/glu.h>

Display *dpy;
Window root;
GLint att[] = { GLX_RGBA, true, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None };
XVisualInfo *vi;
GLXContext glc;

GLsizei width = 24;
GLsizei height =24;
GLfloat aspect = (float)width/height;
GLubyte *pixels;

void setup()
{
dpy = XOpenDisplay(NULL);

if ( !dpy ) {
printf("\n\tcannot connect to X server\n\n");
exit(0);
}

root = DefaultRootWindow(dpy);
vi = glXChooseVisual(dpy, 0, att);

if (!vi) {
printf("\n\tno appropriate visual found\n\n");
exit(0);
}

glc = glXCreateContext(dpy, vi, NULL, GL_TRUE);
glXMakeCurrent(dpy, root, glc);

printf("vendor: %s\n", (const char*)glGetString(GL_VENDOR));

pixels = new GLubyte[3*(width+1)*(height+1)+3];

glViewport(0,0,width,height);
}

void draw()
{
float degrees = 0;

// Render some frames
for (int i=0; i<4; i++)
{
glClear(GL_COLOR_BUFFER_BIT);
//glClear(GL_COLOR_BUFFER_BIT); // uncommenting this fixes the problem...

// Set Projection
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, aspect, 0.1,1000);

// Set ModelView
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glTranslatef(0,0,-3);
glRotatef(degrees,0,0,1);

// draw Square
glBegin(GL_QUADS);
glVertex3d(0,1,0);
glVertex3d(1,0,0);
glVertex3d(0,-1,0);
glVertex3d(-1,0,0);
glEnd();

// get pixels
glReadPixels(0,0,width,height,GL_RGB,GL_UNSIGNED_B YTE,(void*)pixels);

// print buffer to terminal using ascii characters
int count = 0;
for(int y=0;y<height;y++)
{
for(int x=0;x<width;x++)
printf("%02x", pixels[count+=3] & 0xFF);
puts("");
}
puts("");

// increase rotation
degrees += 10;
}
}

int main(int argc, const char* argv[]){
setup();
draw();
return 0;
}

Output:
Notice that every other frame is completely black.


vendor: NVIDIA Corporation
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000

000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
0000000000000000000000ffff0000000000000000000000
00000000000000000000ffffffff00000000000000000000
0000000000000000ffffffffffffff000000000000000000
00000000000000ffffffffffffffff000000000000000000
000000000000ffffffffffffffffffff0000000000000000
00000000ffffffffffffffffffffffffff00000000000000
000000ffffffffffffffffffffffffffffff000000000000
0000ffffffffffffffffffffffffffffffff000000000000
0000ffffffffffffffffffffffffffffffffff0000000000
000000ffffffffffffffffffffffffffffffffff00000000
00000000ffffffffffffffffffffffffffffffff00000000
00000000ffffffffffffffffffffffffffffff0000000000
0000000000ffffffffffffffffffffffffff000000000000
000000000000ffffffffffffffffffff0000000000000000
00000000000000ffffffffffffffff000000000000000000
00000000000000ffffffffffffff00000000000000000000
0000000000000000ffffffff000000000000000000000000
000000000000000000ffff00000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000

000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000

000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
00000000000000000000000000ffffff0000000000000000
000000000000000000ffffffffffffff0000000000000000
0000000000ffffffffffffffffffffffff00000000000000
000000ffffffffffffffffffffffffffff00000000000000
000000ffffffffffffffffffffffffffff00000000000000
000000ffffffffffffffffffffffffffff00000000000000
00000000ffffffffffffffffffffffffffff000000000000
00000000ffffffffffffffffffffffffffff000000000000
00000000ffffffffffffffffffffffffffff000000000000
00000000ffffffffffffffffffffffffffff000000000000
0000000000ffffffffffffffffffffffffffff0000000000
0000000000ffffffffffffffffffffffffffff0000000000
0000000000ffffffffffffffffffffffffffff0000000000
0000000000ffffffffffffffffffffffff00000000000000
000000000000ffffffffffffff0000000000000000000000
000000000000ffffff000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000

Output after adding two glClear calls before drawing:


vendor: NVIDIA Corporation
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
00000000000000000000ffff000000000000000000000000
000000000000000000ffffffff0000000000000000000000
0000000000000000ffffffffffff00000000000000000000
00000000000000ffffffffffffffff000000000000000000
000000000000ffffffffffffffffffff0000000000000000
0000000000ffffffffffffffffffffffff00000000000000
00000000ffffffffffffffffffffffffffff000000000000
000000ffffffffffffffffffffffffffffffff0000000000
0000ffffffffffffffffffffffffffffffffffff00000000
0000ffffffffffffffffffffffffffffffffffff00000000
000000ffffffffffffffffffffffffffffffff0000000000
00000000ffffffffffffffffffffffffffff000000000000
0000000000ffffffffffffffffffffffff00000000000000
000000000000ffffffffffffffffffff0000000000000000
00000000000000ffffffffffffffff000000000000000000
0000000000000000ffffffffffff00000000000000000000
000000000000000000ffffffff0000000000000000000000
00000000000000000000ffff000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000

000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
0000000000000000000000ffff0000000000000000000000
00000000000000000000ffffffff00000000000000000000
0000000000000000ffffffffffffff000000000000000000
00000000000000ffffffffffffffff000000000000000000
000000000000ffffffffffffffffffff0000000000000000
00000000ffffffffffffffffffffffffff00000000000000
000000ffffffffffffffffffffffffffffff000000000000
0000ffffffffffffffffffffffffffffffff000000000000
0000ffffffffffffffffffffffffffffffffff0000000000
000000ffffffffffffffffffffffffffffffffff00000000
00000000ffffffffffffffffffffffffffffffff00000000
00000000ffffffffffffffffffffffffffffff0000000000
0000000000ffffffffffffffffffffffffff000000000000
000000000000ffffffffffffffffffff0000000000000000
00000000000000ffffffffffffffff000000000000000000
00000000000000ffffffffffffff00000000000000000000
0000000000000000ffffffff000000000000000000000000
000000000000000000ffff00000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000

000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
00000000000000000000000000ffff000000000000000000
0000000000000000000000ffffffff000000000000000000
000000000000000000ffffffffffffff0000000000000000
00000000000000ffffffffffffffffff0000000000000000
00000000ffffffffffffffffffffffff0000000000000000
0000ffffffffffffffffffffffffffffff00000000000000
0000ffffffffffffffffffffffffffffff00000000000000
000000ffffffffffffffffffffffffffffff000000000000
000000ffffffffffffffffffffffffffffff000000000000
00000000ffffffffffffffffffffffffffffff0000000000
00000000ffffffffffffffffffffffffffffff0000000000
0000000000ffffffffffffffffffffffffffffff00000000
0000000000ffffffffffffffffffffffffffffff00000000
000000000000ffffffffffffffffffffffff000000000000
000000000000ffffffffffffffffff000000000000000000
000000000000ffffffffffffff0000000000000000000000
00000000000000ffffffff00000000000000000000000000
00000000000000ffff000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000

000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
00000000000000000000000000ffffff0000000000000000
000000000000000000ffffffffffffff0000000000000000
0000000000ffffffffffffffffffffffff00000000000000
000000ffffffffffffffffffffffffffff00000000000000
000000ffffffffffffffffffffffffffff00000000000000
000000ffffffffffffffffffffffffffff00000000000000
00000000ffffffffffffffffffffffffffff000000000000
00000000ffffffffffffffffffffffffffff000000000000
00000000ffffffffffffffffffffffffffff000000000000
00000000ffffffffffffffffffffffffffff000000000000
0000000000ffffffffffffffffffffffffffff0000000000
0000000000ffffffffffffffffffffffffffff0000000000
0000000000ffffffffffffffffffffffffffff0000000000
0000000000ffffffffffffffffffffffff00000000000000
000000000000ffffffffffffff0000000000000000000000
000000000000ffffff000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000

Rosario Leonardi
02-02-2011, 11:58 AM
It work correctly on my computer with a single glClear.

Are you getting a single buffer or a double buffer?

GLint att[] = {
GLX_RGBA, true,
GLX_DEPTH_SIZE, 24,
GLX_DOUBLEBUFFER, None };

This part is wrong, if you want a double buffer you must write GLX_DOUBLEBUFFER, True,
None };

Also you are sure that create the context using the root window it's safe? Probably that's why you are getting an undefined behaviour. Try to use a pixel buffer.


#include <stdio.h>
#include <stdlib.h>

#include<X11/X.h>
#include<X11/Xlib.h>
#include<GL/gl.h>
#include<GL/glx.h>
#include<GL/glu.h>

Display *dpy;
Window root;
XVisualInfo *vi;
GLXContext glc;
GLXPbuffer pBuffer;
const GLsizei width = 32;
const GLsizei height = 32;
const GLfloat aspect = (float)width/height;
GLubyte pixels[width*height];

void setup()
{
dpy = XOpenDisplay(NULL);

if ( !dpy ) {
printf("\n\tcannot connect to X server\n\n");
exit(1);
}
root = DefaultRootWindow(dpy);
int numFbCfg;
GLint att[] = {
GLX_DRAWABLE_TYPE, GLX_PBUFFER,
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_DEPTH_SIZE, 24, // why you need the depth?
GLX_DOUBLEBUFFER, True,
None
};
GLXFBConfig *fbConfig = glXChooseFBConfig(dpy, XDefaultScreen(dpy), att, &amp;numFbCfg);
if(numFbCfg == 0)
{
printf("Error FbConfig");
exit(1);
}
vi = glXGetVisualFromFBConfig(dpy, fbConfig[0]);

if (!vi) {
printf("\n\tno appropriate visual found\n\n");
exit(1);
}

GLint pBuffAttrib [] = {
GLX_PBUFFER_WIDTH, width,
GLX_PBUFFER_HEIGHT, height,
None
};
pBuffer = glXCreatePbuffer(dpy, fbConfig[0], pBuffAttrib);

glc = glXCreateContext(dpy, vi, NULL, GL_TRUE);
glXMakeCurrent(dpy, pBuffer, glc);

printf("vendor: %s\n", (const char*)glGetString(GL_VENDOR));

glViewport(0,0,width,height);
XFree(vi);
XFree(fbConfig);
}

void draw()
{
float degrees = 0;

// Render some frames
for (int i=0; i<4; i++)
{
glClear(GL_COLOR_BUFFER_BIT);
//glClear(GL_COLOR_BUFFER_BIT); // uncommenting this fixes the problem...

// Set Projection
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, aspect, 0.1,1000);

// Set ModelView
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.f, 0.f, -3.f);
glRotatef(degrees,0,0,1);

// draw Square
glBegin(GL_QUADS);
glVertex3d(0,1,0);
glVertex3d(1,0,0);
glVertex3d(0,-1,0);
glVertex3d(-1,0,0);
glEnd();

// get pixels
glReadPixels(0,0,width,height,GL_RED,GL_UNSIGNED_B YTE,(void*)pixels);

// print buffer to terminal using ascii characters
for(int y=0;y<height;y++)
{
for(int x=0;x<width;x++)
printf("%02x", pixels[x+width*y] & 0xFF);
puts("");
}
puts("");
glXSwapBuffers(dpy, pBuffer);
// increase rotation
degrees += 10;
}
}

int main(int argc, const char* argv[]){
setup();
draw();
return 0;
}

undershirt
02-02-2011, 04:55 PM
Rosario,

Your code worked for me. Thanks for the improvements and corrections. Some pieces were taken from different examples online, so I appreciate the clean up.

Is it important to use glXSwapBuffers if I'm only reading from the back buffer? I noticed it ran fine without it. On second thought, I guess I don't really need double buffering either for something like this.