简体   繁体   English

为什么此C ++ / OpenGL程序运行两次?

[英]Why does this C++ / OpenGL program run twice?

After most of the curriculum, they spring C++ on us for the senior year. 在完成大部分课程后,他们将在大四学习C ++。 Sigh. 叹。 So I'm underwater trying to learn it and OpenGL, the latter being the actual subject of the class. 因此,我在水下尝试学习OpenGL和OpenGL,后者是该课程的实际主题。

Please, why does this thing run twice? 拜托,为什么这个东西运行两次? This assignment has already been turned in and graded, so but I just can't find any good online guide to OpenGL. 该作业已经上交并评分了,所以我只是找不到关于OpenGL的任何好的在线指南。 Thanks for any thoughts. 感谢您的任何想法。

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

The GLUT display function displayFunction gets called every time the graphics need to be rendered again. 每次需要重新渲染图形时,都会调用GLUT显示函数displayFunction On a real OpenGL app it would be called continuously, controlled by a timer. 在真正的OpenGL应用程序上,它会被计时器连续调用。 Here it gets called once when the window it opened. 在这里,当窗口打开时,它将被调用一次。 But depending on the OS, it may be called multiple times, for example if the window needs to be refreshed because it got activated. 但是根据操作系统的不同,它可能会被多次调用,例如,是否由于激活窗口而需要刷新窗口。

In the code the animation is controlled by Sleep(150) and glutSwapBuffers() during the execution of displayFunction() . 在代码中,在执行displayFunction() ,动画由Sleep(150)glutSwapBuffers() displayFunction() So the application blocks during the animation, but the graphics are still shown because of the glutSwapBuffers() calls. 因此,应用程序在动画期间会阻塞,但是由于发生了glutSwapBuffers()调用,因此仍显示了图形。

Normally a display function should execute quickly (and never block/wait), and call glFlush() and glutSwapBuffers() only once at the end. 通常,显示函数应该快速执行(并且永远不会阻塞/等待),并且最后只调用glFlush()glutSwapBuffers()

A better implementation would be: The state of the animation (ie the number of clock icons) is stored in a global variable int state = 0 . 更好的实现是:动画的状态(即时钟图标的数量)存储在全局变量int state = 0 displayFunction() always draws that number of clocks without waiting, and then exits. displayFunction()总是不等待而绘制该数量的时钟,然后退出。 Before starting the main loop a timer is registered with glutTimerFunc , with a function that increments state , and then calls glutPostRedisplay() . 在开始主循环之前,使用glutTimerFunc注册了一个计时器 ,该计时器具有一个递增state的函数,然后调用glutPostRedisplay() This schedules GLUT to recall the display function. 这样可以安排GLUT重新调用显示功能。 Then the app also remains responsive during the animation, and can be quit by closing the window. 然后,该应用在动画过程中也保持响应,并且可以通过关闭窗口来退出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM