PDA

View Full Version : Double Buffer makes things disappear



shadowayex
09-21-2010, 07:06 PM
Edit: I solved this problem on my own =)

Hello,

I'm new at OpenGL and 3D programming in general, so I don't really know how to figure out a lot of things on my own yet.

I'm learning from the Red Book 7th edition, and I got my stuff to work with single buffering, but when I tried to change to double buffering, I ran into an issue.

First, I'm using freeglut for windowing. Second, I'm working in Vista at the moment. And third, the issue I'm hitting is that after maybe a second, my drawing disappears. I'm coding in C++, trying to make things Object Oriented. Once again, I don't really know anything about OpenGL yet, so if you see anything that looks wrong, it might be wrong. Here's the code:

Main.cpp

#include <GL/freeglut.h>
#include "Lego.h"

static GLfloat spin = 0.0;
Lego lego1(1.0, 0.0, 0.0, 4.0, 2.0, 1.0);

//Initialize the program
void init() {
glClearColor(0.0, 0.0, 0.0, 0.0); // Set default background color

glShadeModel(GL_FLAT); // Dunno yet <--
}

// The magic
void display() {
glClear(GL_COLOR_BUFFER_BIT); // Clear Pixels
glPushMatrix(); // Dunno Yet <--

spin += 2.0;

glRotatef(spin, 0.0, 0.0, 1.0);
lego1.draw();

glPopMatrix(); // Dunno yet <--
glutSwapBuffers(); // Switch to drawing next buffer when time is up
}

// Command what happens when window is resized
void reshape(int w, int h) {
glViewport(0, 0, (GLsizei)w, (GLsizei)h); // Change viewing area to continue to be the whole window
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-w/2, w/2, -h/2, h/2, -100.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

// Function for mouse input
void mouse(int button, int state, int x, int y) {
switch(button) {
case GLUT_LEFT_BUTTON:
if(state == GLUT_DOWN) {
//glutIdleFunc(spinDisplay);
}
break;

case GLUT_RIGHT_BUTTON:
if(state == GLUT_DOWN) {
//glutIdleFunc(NULL);
}
break;

default:
break;
}
}

int main(int argc, char** argv) {
glutInit(&amp;argc, argv); // Any commad line related stuff
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); // Sets display properties
glutInitWindowSize(250, 250); // Initial window size
glutInitWindowPosition(100, 100); // Initial window position
glutInitContextVersion(3, 0); // Use version 3.0
glutInitContextFlags(GLUT_FORWARD_COMPATIBLE); // Make forward compatible
glutCreateWindow("Hello World"); // Create (but not display) window

init(); // Launch initializing function
glutDisplayFunc(display); // Set the display function
glutReshapeFunc(reshape); // Sets what happens when reshaped
glutMouseFunc(mouse); // Sets what happens with mouse input
glutMainLoop(); // Start the program
return 0;
}


Lego.h

#ifndef _LEGO_H

#define _LEGO_H_

class Lego {
float r, g, b;
float l, w, h; // Each 1 unit = ?
float x, y, z;
float xRot, yRot, zRot;

public:
Lego(float, float, float, float, float, float);
void draw();
bool isMouseDown();
};

#endif


Lego.cpp

#include <GL/freeglut.h>

#include "Lego.h"

Lego::Lego(float r, float g, float b, float l, float w, float h) {
this->r = r;
this->g = g;
this->b = b;
this->l = l;
this->w = w;
this->h = h;

this->xRot = 0.0;
this->yRot = 0.0;
this->zRot = 0.0;

// Temporary
this->x = 0.0;
this->y = 0.0;
this->z = 0.0;
}

void Lego::draw() {
glTranslatef(x, y, z);

GLfloat vertices[] = {-80, -80, 30, 1.0, 0.0, 0.0,
40, -80, 30, 1.0, 0.0, 0.0,
40, 40, 30, 1.0, 0.0, 0.0,
-80, 40, 30, 1.0, 0.0, 0.0,
-60, -60, -30, 0.0, 1.0, 0.0,
60, -60, -30, 0.0, 1.0, 0.0,
60, 60, -30, 0.0, 1.0, 0.0,
-60, 60, -30, 0.0, 1.0, 0.0,
};

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);

glVertexPointer(3, GL_FLOAT, 6*sizeof(GL_FLOAT), &amp;vertices[0]);
glColorPointer(3, GL_FLOAT, 6*sizeof(GL_FLOAT), &amp;vertices[3]);

glDrawArrays(GL_QUADS, 0, 8);

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);

glTranslatef(0, 0, 0);

glutSwapBuffers();
}


As I said, after like a second, maybe less, the boxes disappear. My question is why does it do this?

ZbuffeR
09-22-2010, 05:42 AM
Glad you solved it alone :)
Next time please explain in a few words what was the mistake and how you solved it, to help others.

shadowayex
09-22-2010, 06:19 AM
Well,

The display function isn't continuously called, like I thought. Instead, you apparently refresh the display with glutPostRedisplay() (given I remember the function name correctly).

Well, the disappearing issue happened when the Lego.draw() function switched buffers, then the display() function switched buffers after that. Since nothing was is the other buffer (as nothing was told to be drawn), it resulted in an empty screen.

What I did was take the buffer swapping out of the draw() function, and left the buffer swap up to the display function. Every time I want it to be updated (due to mouse events or whatever), I have to have glutPostRedisplay() at the end of the function that updates things (like an angle, or position of the object, etc.) for the updates to actually be made.

There might be more technical things happening that I don't know about yet, but that's what I figured out and it works now.