为什么这个C++/OpenGL程序运行两次

Why does this C++ / OpenGL program run twice?

本文关键字:两次 运行 程序 C++ OpenGL 为什么      更新时间:2023-10-16

大部分课程结束后,他们在高年级向我们推荐C++。叹气所以我在水下尝试学习它和OpenGL,后者是课程的实际主题。

拜托,为什么这个东西跑两次?这个作业已经交上来并进行了评分,所以我找不到任何好的OpenGL在线指南。谢谢你的想法。

#ifdef __APPLE__
#include <GLUT/glut.h>
#include <OpenGL/gl.h>
#else
#include <GL/glut.h>
#endif
#include <stdlib.h>
int width = 800, height = 600;
float xmin = -(width / 2), ymin = -(height / 2), xmax = width / 2, ymax = height / 2;
GLubyte bitmap[72] = { 0x00, 0x00, 0x00,
0x40, 0x00, 0x02,
0x20, 0x00, 0x04,
0x10, 0x38, 0x08,
0x09, 0x63, 0x10,
0x06, 0x00, 0xA0,
0x08, 0x00, 0x20,
0x10, 0x00, 0x10,
0x10, 0x00, 0x10,
0x10, 0x00, 0x08,
0x20, 0x00, 0x08,
0x20, 0x10, 0x08,
0x20, 0x18, 0x08,
0x10, 0x14, 0x08,
0x10, 0x12, 0x10,
0x10, 0x11, 0x10,
0x08, 0x10, 0x20,
0x04, 0x10, 0x40,
0x01, 0x87, 0x00,
0x00, 0x78, 0x00,
0x00, 0x00, 0x00,
0x00, 0x00, 0x00,
0x00, 0x00, 0x00,
0x00, 0x00, 0x00
};
void init(void) {
    // Set display-window color to white.
    glClearColor(0.0, 0.0, 1.0, 0.0);
    // Set projection parameters.
    glMatrixMode(GL_PROJECTION);
    gluOrtho2D(xmin,xmax,ymin,ymax);
    // Clear display window.
    glClear(GL_COLOR_BUFFER_BIT);
    glutSwapBuffers();
}
// Windows redraw function
void winReshapeFcn(GLint newWidth, GLint newHeight) {
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(-(GLdouble)width / 2, (GLdouble)width / 2, -(GLdouble)height / 2, (GLdouble)height / 2);
    glClear(GL_COLOR_BUFFER_BIT);
}
void drawText() {
    int x = (int) xmin + 20, y = (int) ymax - 20, count = 0;
    char what [] = { 'R', 'e', 'c', 't', 'a', 'n', 'g', 'l', 'e', 's' };
    float color = 1.0;
    glRasterPos2i(x, y);
    do {
        glColor3f(color,color,color);
        color = color - 0.1;
        glutBitmapCharacter(GLUT_BITMAP_9_BY_15, what[count]);
        y = y - 20;
        glRasterPos2i(x, y);
        count = count + 1;
    } while (count <= 9);
}
void drawRectangles() {
    int h = (int) ymax, x1 = -h, y1 = h, x2 = h, y2 = -h, count = 0, delta, factor = 5;
    do {
        glBegin(GL_LINES);
            glVertex2i(x1,h);
            glVertex2i(h,y1);
            glVertex2i(h,y1);
            glVertex2i(x2,-h);
            glVertex2i(x2,-h);
            glVertex2i(-h,y2);
            glVertex2i(-h,y2);
            glVertex2i(x1,h);
        glEnd();
        h = h - factor; delta = factor * count;
        x1 = -h + delta; y1 = h - delta; x2 = h - delta; y2 = -h + delta;
        count = count + 1;
    } while (x1 < h);
}
void drawBitmaps() {
    int count = 0;
    GLfloat xorigin = xmin + (xmax - ymax) / 2.0;
    // Needed for reading from memory. 1 indicates byte alignment
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    // Center the bitmap image
    glRasterPos2i(0, 0);
    do {
        glBitmap(24.0, 24.0, xorigin, ymax, 0.0, 24.0, bitmap);
        count = count + 24;
        Sleep(150);
        glutSwapBuffers();
    } while ((count < width) && (count < height));
}
void displayFunction(void) {
    // Clear display window.
    glClear(GL_COLOR_BUFFER_BIT);
    // Set  graphic objects color to Red or change for your choice
    drawText();
    glColor3f(1.0, 1.0, 0.0);
    drawRectangles();
    drawBitmaps();
    // Execute OpenGL functions
    glFlush();
}
void main(int argc, char** argv) {
    // Initialize GLUT.
    glutInit(&argc, argv);
    // Set display mode.
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    // Set top-left display-window position.
    glutInitWindowPosition((glutGet(GLUT_SCREEN_WIDTH) - width) / 2, (glutGet(GLUT_SCREEN_HEIGHT) - height) / 2);
    // Set display-window width and height.
    glutInitWindowSize(width, height);
    // Create display window.
    glutCreateWindow("Michael Powers - Homework 2");
    // Execute initialization procedure.
    init();
    // Send graphics to display window.
    glutDisplayFunc(displayFunction);
    // Window reshape call
    glutReshapeFunc(winReshapeFcn);
    // Display everything and wait.
    glutMainLoop();
}
每次需要再次渲染图形时,都会调用GLUT显示函数displayFunction。在一个真正的OpenGL应用程序上,它会被持续调用,由计时器控制。在这里,当它打开窗户时,它会被调用一次。但根据操作系统的不同,它可能会被调用多次,例如,如果窗口因为被激活而需要刷新。

在代码中,动画在执行displayFunction()期间由Sleep(150)glutSwapBuffers()控制。因此,应用程序在动画过程中会阻塞,但由于glutSwapBuffers()调用,图形仍会显示。

通常情况下,显示函数应该快速执行(从不阻塞/等待),并且最后只调用glFlush()glutSwapBuffers()一次。

更好的实现是:动画的状态(即时钟图标的数量)存储在全局变量int state = 0中。displayFunction()总是在不等待的情况下绘制该数量的时钟,然后退出。在开始主循环之前,计时器已注册到glutTimerFunc,该函数递增state,然后调用glutPostRedisplay()。这将安排GLUT调用显示功能。然后,该应用程序在动画过程中也保持响应,可以通过关闭窗口退出。