Search code examples
copenglglut

Resizing window in OpenGL: Garbage Output


I am using GLUT with the OpenGL on Mac OS X. When I resize my window by dragging the window edges, the window gets filled with garbage values. The code is attached below. The only way to remove garbage I've found is by calling glClear(), which of course, I do not want to do.

The question is that I do not want the garbage values. I cannot figure out why I get such values as well.

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

#ifdef __APPLE__
#include <GLUT/glut.h>
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#else
#include <GL/glut.h>
#endif

void myInit();
void display();
void reshape(int x, int y);
void keyboard(unsigned char c, int x, int y);
void mouse(int b, int s, int x, int y);


int width;
int height;

int main(int argc, char* argv[]) {

    glutInit(&argc, argv);
    myInit();
    glutMainLoop();
    return 0;
}


void myInit(){
    glutInitDisplayMode(GLUT_MULTISAMPLE);
    glutInitWindowSize(500,500);
    glutInitWindowPosition(100,100);
    glutCreateWindow("Hello World!");

    glClearColor(0.2,0.2,0.2,1);
    glutDisplayFunc(display);

    glutKeyboardFunc(keyboard);
    glutMouseFunc(mouse);

    glutReshapeFunc(reshape);
    glClear(GL_COLOR_BUFFER_BIT);
    glLoadIdentity();
    gluLookAt(0.0, 0.0, 0.5,\
        0.0,0.0,0.0,\
        0.0,1.0,0.0);
    glClear(GL_COLOR_BUFFER_BIT);
}

void display(){
    printf ("))display\n");
    glFlush();
}

void keyboard(unsigned char c, int x, int y){
    if (c == 27 || c == 81 || c == 113) exit(0);
    else if (c == 67 || c == 99){
        printf("CLEAR!\n");
        glClear(GL_COLOR_BUFFER_BIT);
        glutPostRedisplay();
    }
}

void putDot(int x, int y){
    glBegin(GL_POINTS);
        glVertex3f(x,height-y,0);
    glEnd();
    glutPostRedisplay();
}

void mouse(int b, int s, int x, int y){
    if (b == GLUT_LEFT_BUTTON && s == GLUT_DOWN){
        printf("MouseD\n");
        putDot(x,y);
    }
}

void reshape(int x, int y){
    printf ("))reshape\n");
    width = x;
    height = y;
    glViewport(0,0,width,height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0,width, 0,height, -10,10);
    glMatrixMode(GL_MODELVIEW);
    glutPostRedisplay();
}

EDIT: I have a similar problem on Ubuntu 14.04. So the trouble must be my coding (of course!).


Solution

  • OpenGL is not a scene graph (I stopped counting how many times I've written this on SO already). It merely draws points, lines and triangles, one at a time, to a pixel framebuffer. Once things have been drawn that's it.

    When you resize a window its framebuffer layout changes. If pixels are added their initial values are undefined. It's upon you, to fill those pixels with values. Normally when resizing a window the operating system will message your program, that it needs to redraw its window contents. GLUT uses the display callback for this. Your program's display callback does nothing (except calling glFlush which is a no-op if no drawing calls precede it).

    Your only drawing calls happen in input event handlers. This is definitely the wrong place to do drawing calls, at least not to the main window framebuffer. For what it's worth there might not even be a OpenGL context around in a event handler (in GLUT there is, but IMHO that's an oversight). In a event handler you should only process the event and set variables which later control the drawing.

    All drawing (that means calls to glVertex or glDraw…) should happen only (and only) in the GLUT display callback (or go to a off-screen renderbuffer/texture through a framebuffer object).

    If you're a newbie and you're using GLUT there's a simple rule that will keep you from falling into most pitfalls: There must be no calls to function starting with gl… (that doesn't mean glut… or glew…, just gl and then uppercase) in any function other than the display callback function (I know that most, if not all tutorials out there violate this rule; don't let them fool you). If you follow that rule you'll find that a surprisingly large fraction of OpenGL newbie problems vanish.