c - 在 OpenGL 中调整窗口大小 : Garbage Output

标签 c opengl glut

我在 Mac OS X 上使用 GLUT 和 OpenGL。当我通过拖动窗口边缘来调整窗口大小时,窗口会充满垃圾值。代码附在下面。我发现删除垃圾的唯一方法是调用 glClear(),当然,我不想这样做。

问题是我不想要垃圾值。我不明白为什么我也得到这样的值。

#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();
}

编辑:我在 Ubuntu 14.04 上也有类似的问题。所以问题一定出在我的编码上(当然!)。

最佳答案

OpenGL 不是场景图(我已经停止计算我已经在 SO 上写过多少次了)。它只是将点、线和三角形一次绘制一个到像素帧缓冲区。一旦事情被绘制出来,就这样了。

当您调整窗口大小时,其帧缓冲区布局会发生变化。如果添加像素,则其初始值未定义。由您来用值填充这些像素。通常,当调整窗口大小时,操作系统会向您的程序发送消息,表明它需要重绘其窗口内容。 GLUT 为此使用 display 回调。您的程序的显示回调不执行任何操作(除了调用 glFlush ,如果在它之前没有绘图调用,则这是一个无操作)。

您唯一的绘图调用发生在输入事件处理程序中。这绝对是进行绘图调用的错误位置,至少不是主窗口帧缓冲区。就其值(value)而言,事件处理程序中甚至可能没有 OpenGL 上下文(在 GLUT 中是有的,但恕我直言,这是一个疏忽)。在事件处理程序中,您应该只处理事件并设置稍后控制绘图的变量。

所有绘图(这意味着对 glVertexglDraw... 的调用)应该仅(且仅)在 GLUT 显示回调中发生(或通过帧缓冲区对象转到屏幕外渲染缓冲区/纹理)。

如果您是新手并且正在使用 GLUT,那么有一个简单的规则可以防止您陷入大多数陷阱:不得调用以 gl... 开头的函数(这不会不是指 glut…glew…,只是 gl 然后大写)在除显示回调函数之外的任何函数中(我知道大多数,如果不是所有教程都违反了这条规则;不要让它们欺骗了你)。如果您遵循该规则,您会发现很大一部分 OpenGL 新手问题都消失了。

关于c - 在 OpenGL 中调整窗口大小 : Garbage Output,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34800056/

相关文章:

此 C 代码会导致段错误吗?

c - printf 在一定程度上跟随零

java - JOGL:从 GLJPanel 获取 GL()?

c++ - 如何刷新 GLUT 空闲函数内的窗口

c++ - DevIL 图像无法正确呈现

c++ - 如何在 OpenGL(使用 GLUT)上绘制像圆锥体一样的填充包络?

c++ - 独立关闭多个 GLUT 窗口

c - 该 C 程序出现段错误

c - 调用 CreateWindowEx 函数时出现访问冲突错误

c++ - 为什么我的 Flatten Shader(来自 Lighthouse3d 教程)不工作?