2016-04-02 10 views
0

Nach dem größten Teil des Lehrplans beginnen sie C++ für das letzte Jahr. Seufzer. Also versuche ich es unter Wasser zu lernen und OpenGL, wobei letzteres das eigentliche Thema der Klasse ist.Warum wird dieses C++/OpenGL-Programm zweimal ausgeführt?

Bitte, warum läuft dieses Ding zweimal? Diese Aufgabe wurde bereits eingereicht und benotet, aber ich kann einfach keinen guten Online-Guide zu OpenGL finden. Danke für irgendwelche Gedanken.

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

Antwort

4

Die GLUT-Anzeigefunktion displayFunction wird jedesmal, wenn die Grafiken müssen genannt wieder gerendert werden. In einer echten OpenGL-App würde es kontinuierlich aufgerufen werden, gesteuert von einem Timer. Hier wird es einmal aufgerufen wenn das Fenster geöffnet wird. Je nach Betriebssystem kann es jedoch mehrmals aufgerufen werden, z. B. wenn das Fenster aktualisiert werden muss, weil es aktiviert wurde.

Im Code wird die Animation während der Ausführung von displayFunction() von Sleep(150) und glutSwapBuffers() gesteuert. So blockiert die Anwendung während der Animation, aber die Grafik wird immer noch wegen der glutSwapBuffers() Aufrufe angezeigt.

Normalerweise sollte eine Anzeigefunktion schnell ausgeführt werden (und niemals blockieren/warten), und glFlush() und glutSwapBuffers() nur einmal am Ende aufrufen. Eine bessere Implementierung wäre: Der Status der Animation (d. H. Die Anzahl der Uhrensymbole) wird in einer globalen Variablen int state = 0 gespeichert. displayFunction() zeichnet immer die Anzahl der Uhren, ohne zu warten, und wird dann beendet. Vor dem Start der Hauptschleife wird ein Timer mit glutTimerFunc registriert, mit einer Funktion, die state inkrementiert, und ruft dann glutPostRedisplay() auf. Dies veranlaßt GLUT, die Anzeigefunktion aufzurufen. Dann reagiert die App auch während der Animation und kann durch Schließen des Fensters beendet werden.

+0

Ich ging voran und zählte das als gelöst, obwohl ich noch lerne und es nicht vollständig verstehe. Wenn ich jedoch lerne, dass displayFunction komplizierter ist als ich dachte, habe ich entdeckt, dass das Verschieben aller Berechnungen das Problem löst. Ich wünschte, alle OpenGL-How-To- und Funktionskatalog-Sites wären nicht schrecklich ... trotzdem, danke! – failure

Verwandte Themen