2017-12-21 4 views
1

Ich habe ein Programm, in dem ein farbiger Würfel mit OpenGL angezeigt wird. Ich verwende Freeglut, um die OpenGL-Instanz anzuzeigen. Das Programm soll es dem Benutzer ermöglichen, den Würfel mit der Maus zu drehen, während er die linke Maustaste gedrückt hält. Nach jeder Mausbewegung soll der Cursor im Fenster zentriert sein. GlossPostRedisplay(); soll nur angerufen werden, wird nur einige Male aufgerufen und dann nicht mehr aufgerufen, bis Sie die linke Maustaste loslassen.glutPostRedisplay() wird nicht immer aufgerufen?

my_cube.c

#include <stdio.h> 
#include <stdarg.h> 
#include <math.h> 
#include <string.h> 
#define GL_GLEXT_PROTOTYPES 
#include <GL/glew.h> 
#include <GL/freeglut.h> 

// ---------------------------------------------------------- 
// Function Prototypes 
// ---------------------------------------------------------- 
void display(); 
void specialKeys(); 

// ---------------------------------------------------------- 
// Global Variables 
// ---------------------------------------------------------- 
double rotate_y=0; 
double rotate_x=0; 
float deltaAngleX = 0.0f; 
float deltaAngleY = 0.0f; 
int xOrigin = -1; 
int yOrigin = -1; 
int MSAA; 
int MouseState = 0; 
void enableMultisample(int msaa){ 
    if(msaa) 
    { 
     glEnable(GL_MULTISAMPLE); 
     glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST); 

     //detect current settings 
     GLint iMultiSample = 0; 
     GLint iNumSamples = 0; 
     glGetIntegerv(GL_SAMPLE_BUFFERS, &iMultiSample); 
     glGetIntegerv(GL_SAMPLES, &iNumSamples); 
     //printf("MSAA on, GL_SAMPLE_BUFFERS = %d, GL_SAMPLES = %d\n", iMultiSample, iNumSamples); 
    } 
    else 
    { 
     glDisable(GL_MULTISAMPLE); 
     //printf("MSAA off\n"); 
    } 
} 


void mouseButton(int button, int state, int x, int y) { 

    // only start motion if the left button is pressed 
    if (button == GLUT_LEFT_BUTTON) { 

     // when the button is released 
     if (state == GLUT_UP) { 
      //rotate_x += deltaAngleX; 
      //rotate_y += deltaAngleY; 
      xOrigin = -1; 
      yOrigin = -1; 
      MouseState = 0; 
     } 
     else {// state = GLUT_DOWN 
      xOrigin = x; 
      yOrigin = y; 
      MouseState = 1; 
     } 
    } 
} 
void mouseMove(int x, int y) { 
    // this will only be true when the left button is down 
    if (xOrigin >= 0) { 
     int midWindowX = 1280/2; 
     int midWindowY = 720/2; 

     rotate_y -= (x - midWindowX)/10.0f; 
     rotate_x += (y - midWindowY)/10.0f; 
     glutWarpPointer(midWindowX, midWindowY); 

     //glutPostRedisplay(); 

     printf("Rotate_X = %lf : Rotate_Y = %lf : Mouse_X = %d : Mouse_Y = %d\n", rotate_x, rotate_y, x, y); 
     glutPostRedisplay(); 
    } 
} 

// ---------------------------------------------------------- 
// display() Callback function 
// ---------------------------------------------------------- 
void display(){ 

    // Clear screen and Z-buffer 
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 

    // Reset transformations 
    // 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    gluPerspective(60.0f, (1280.0f/720.0f), 0.1f, 100.0f); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 

    enableMultisample(MSAA); 

    glTranslatef(0, 0, -4); 
    glRotatef(180, 1.0, 0.0, 0.0); 

    // Rotate when user changes rotate_x and rotate_y 
    glRotatef(rotate_x, 1.0, 0.0, 0.0); 
    glRotatef(rotate_y, 0.0, 1.0, 0.0); 

    // Reset rotations 
    if(rotate_x == 360.0f || rotate_x > 360.0f || rotate_x == -360 || rotate_x < -360) rotate_x = 0.0f; 
    if(rotate_y == 360.0f || rotate_y > 360.0f || rotate_y == -360 || rotate_y < -360) rotate_y = 0.0f; 

    //Multi-colored side - FRONT 
    glBegin(GL_POLYGON); 

    glColor3f(0.0, 1.0, 0.0);  glVertex3f(-0.5, -0.5, -0.5);  // P4 is green 
    glColor3f(0.0, 0.0, 1.0);  glVertex3f(-0.5, 0.5, -0.5);  // P3 is blue 
    glColor3f(1.0, 0.0, 1.0);  glVertex3f( 0.5, 0.5, -0.5);  // P2 is purple 
    glColor3f(1.0, 0.0, 0.0);  glVertex3f( 0.5, -0.5, -0.5);  // P1 is red 

    glEnd(); 

    // White side - BACK 
    glBegin(GL_POLYGON); 
    glColor3f( 1.0, 1.0, 1.0); 
    glVertex3f( 0.5, -0.5, 0.5); 
    glVertex3f( 0.5, 0.5, 0.5); 
    glVertex3f(-0.5, 0.5, 0.5); 
    glVertex3f(-0.5, -0.5, 0.5); 
    glEnd(); 

    // Purple side - RIGHT 
    glBegin(GL_POLYGON); 
    glColor3f( 1.0, 0.0, 1.0); 
    glVertex3f(0.5, -0.5, -0.5); 
    glVertex3f(0.5, 0.5, -0.5); 
    glVertex3f(0.5, 0.5, 0.5); 
    glVertex3f(0.5, -0.5, 0.5); 
    glEnd(); 

    // Green side - LEFT 
    glBegin(GL_POLYGON); 
    glColor3f( 0.0, 1.0, 0.0); 
    glVertex3f(-0.5, -0.5, 0.5); 
    glVertex3f(-0.5, 0.5, 0.5); 
    glVertex3f(-0.5, 0.5, -0.5); 
    glVertex3f(-0.5, -0.5, -0.5); 
    glEnd(); 

    // Blue side - TOP 
    glBegin(GL_POLYGON); 
    glColor3f( 0.0, 0.0, 1.0); 
    glVertex3f( 0.5, 0.5, 0.5); 
    glVertex3f( 0.5, 0.5, -0.5); 
    glVertex3f(-0.5, 0.5, -0.5); 
    glVertex3f(-0.5, 0.5, 0.5); 
    glEnd(); 

    // Red side - BOTTOM 
    glBegin(GL_POLYGON); 
    glColor3f( 1.0, 0.0, 0.0); 
    glVertex3f( 0.5, -0.5, -0.5); 
    glVertex3f( 0.5, -0.5, 0.5); 
    glVertex3f(-0.5, -0.5, 0.5); 
    glVertex3f(-0.5, -0.5, -0.5); 
    glEnd(); 

    glFlush(); 
    glutSwapBuffers(); 

} 

// ---------------------------------------------------------- 
// specialKeys() Callback Function 
// ---------------------------------------------------------- 
void specialKeys(int key, int x, int y) { 
    if(!MouseState){ 
     // Right arrow - increase rotation by 5 degree 
     if (key == GLUT_KEY_RIGHT) 
      rotate_y -= 5; 

     // Left arrow - decrease rotation by 5 degree 
     else if (key == GLUT_KEY_LEFT) 
      rotate_y += 5; 

     else if (key == GLUT_KEY_UP) 
      rotate_x -= 5; 

     else if (key == GLUT_KEY_DOWN) 
      rotate_x += 5; 

     // Request display update 
     glutPostRedisplay(); 
    } 
} 

// ---------------------------------------------------------- 
// main() function 
// ---------------------------------------------------------- 
int main(int argc, char* argv[]){ 
    for(int i; i<argc; i++){ 
     char *arg; 
     arg = argv[i]; 
     const char msaaArg[4] = "MSAA"; 
     char *ret; 

     ret = strstr(arg, msaaArg); 

     if(ret != NULL){ 
      MSAA = (intptr_t)argv[i+1]; 
     } 
    } 

    // Initialize GLUT and process user parameters 
    glutInit(&argc,argv); 

    // Set Initial Size of window 
    glutInitWindowSize(1280, 720); 

    // Enable Multisampling 
    glutSetOption(GLUT_MULTISAMPLE, 8); 

    // Request double buffered true color window with Z-buffer 
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_MULTISAMPLE); 

    // Create window 
    glewInit(); 
    glutCreateWindow(""); 

    // Get OpenGL Version 
    printf("Using OpenGL Version: %s\n", glGetString(GL_VERSION)); 
    char title[150]; 
    const char* temp; 
    strcpy(title, "Awesome Cube [OpenGL Version "); 
    strcat(title, glGetString(GL_VERSION)); 
    temp = glGetString(GL_VERSION); 
    strcat(title, "]"); 
    glutSetWindowTitle(title); 

    // Enable Z-buffer depth test 
    glEnable(GL_DEPTH_TEST); 

    // Enable Backface Culling 
    glEnable(GL_CULL_FACE); 

    // Move mouse to the middle of the screen 
    glutWarpPointer(1280/2, 720/2); 

    // Callback functions 
    glutDisplayFunc(display); 
    glutSpecialFunc(specialKeys); 
    glutMouseFunc(mouseButton); 
    glutMotionFunc(mouseMove); 
    // Pass control to GLUT for events 
    glutMainLoop(); 

    return 0; 
} 
+0

Warum setzen Sie nicht 'glutPostRedisplay()' am Ende des 'display()'? – Rabbid76

+1

Ich hielt es nicht für notwendig, die Computer-Ressourcen die ganze Zeit zu verwenden. Ich wollte das Bild nur rendern, wenn es nötig war. –

Antwort

1

glutWarpPointer() erzeugt einen neuen Mausbewegungs Rückruf; ein Flag und ignorieren verzugs erzeugten Bewegungs Rückrufe:

bool warped = false; 
void mouseMove(int x, int y) 
{ 
    if(warped) 
    { 
     warped = false; 
     return; 
    } 

    // this will only be true when the left button is down 
    if(xOrigin >= 0) 
    { 
     int midWindowX = 1280/2; 
     int midWindowY = 720/2; 

     rotate_y -= (x - midWindowX)/10.0f; 
     rotate_x += (y - midWindowY)/10.0f; 

     warped = true; 
     glutWarpPointer(midWindowX, midWindowY); 

     printf("Rotate_X = %lf : Rotate_Y = %lf : Mouse_X = %d : Mouse_Y = %d\n", rotate_x, rotate_y, x, y); 
     glutPostRedisplay(); 
    } 
} 

Alle zusammen:

#include <stdio.h> 
#include <stdarg.h> 
#include <math.h> 
#include <string.h> 
#include <GL/glew.h> 
#include <GL/freeglut.h> 

// ---------------------------------------------------------- 
// Function Prototypes 
// ---------------------------------------------------------- 
void display(); 
void specialKeys(); 

// ---------------------------------------------------------- 
// Global Variables 
// ---------------------------------------------------------- 
double rotate_y = 0; 
double rotate_x = 0; 
float deltaAngleX = 0.0f; 
float deltaAngleY = 0.0f; 
int xOrigin = -1; 
int yOrigin = -1; 
int MouseState = 0; 

void mouseButton(int button, int state, int x, int y) 
{ 
    // only start motion if the left button is pressed 
    if(button == GLUT_LEFT_BUTTON) 
    { 
     // when the button is released 
     if(state == GLUT_UP) 
     { 
      //rotate_x += deltaAngleX; 
      //rotate_y += deltaAngleY; 
      xOrigin = -1; 
      yOrigin = -1; 
      MouseState = 0; 
     } 
     else 
     { 
      // state = GLUT_DOWN 
      xOrigin = x; 
      yOrigin = y; 
      MouseState = 1; 
     } 
    } 
} 

bool warped = false; 
void mouseMove(int x, int y) 
{ 
    if(warped) 
    { 
     warped = false; 
     return; 
    } 

    // this will only be true when the left button is down 
    if(xOrigin >= 0) 
    { 
     int midWindowX = 1280/2; 
     int midWindowY = 720/2; 

     rotate_y -= (x - midWindowX)/10.0f; 
     rotate_x += (y - midWindowY)/10.0f; 

     warped = true; 
     glutWarpPointer(midWindowX, midWindowY); 

     printf("Rotate_X = %lf : Rotate_Y = %lf : Mouse_X = %d : Mouse_Y = %d\n", rotate_x, rotate_y, x, y); 
     glutPostRedisplay(); 
    } 
} 

// ---------------------------------------------------------- 
// display() Callback function 
// ---------------------------------------------------------- 
void display() 
{ 
    // Clear screen and Z-buffer 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    // Reset transformations 
    // 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    gluPerspective(60.0f, (1280.0f/720.0f), 0.1f, 100.0f); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 

    glTranslatef(0, 0, -4); 
    glRotatef(180, 1.0, 0.0, 0.0); 

    // Rotate when user changes rotate_x and rotate_y 
    glRotatef(rotate_x, 1.0, 0.0, 0.0); 
    glRotatef(rotate_y, 0.0, 1.0, 0.0); 

    // Reset rotations 
    if(rotate_x == 360.0f || rotate_x > 360.0f || rotate_x == -360 || rotate_x < -360) rotate_x = 0.0f; 
    if(rotate_y == 360.0f || rotate_y > 360.0f || rotate_y == -360 || rotate_y < -360) rotate_y = 0.0f; 

    //Multi-colored side - FRONT 
    glBegin(GL_POLYGON); 

    glColor3f(0.0, 1.0, 0.0);  glVertex3f(-0.5, -0.5, -0.5);  // P4 is green 
    glColor3f(0.0, 0.0, 1.0);  glVertex3f(-0.5, 0.5, -0.5);  // P3 is blue 
    glColor3f(1.0, 0.0, 1.0);  glVertex3f(0.5, 0.5, -0.5);  // P2 is purple 
    glColor3f(1.0, 0.0, 0.0);  glVertex3f(0.5, -0.5, -0.5);  // P1 is red 

    glEnd(); 

    // White side - BACK 
    glBegin(GL_POLYGON); 
    glColor3f(1.0, 1.0, 1.0); 
    glVertex3f(0.5, -0.5, 0.5); 
    glVertex3f(0.5, 0.5, 0.5); 
    glVertex3f(-0.5, 0.5, 0.5); 
    glVertex3f(-0.5, -0.5, 0.5); 
    glEnd(); 

    // Purple side - RIGHT 
    glBegin(GL_POLYGON); 
    glColor3f(1.0, 0.0, 1.0); 
    glVertex3f(0.5, -0.5, -0.5); 
    glVertex3f(0.5, 0.5, -0.5); 
    glVertex3f(0.5, 0.5, 0.5); 
    glVertex3f(0.5, -0.5, 0.5); 
    glEnd(); 

    // Green side - LEFT 
    glBegin(GL_POLYGON); 
    glColor3f(0.0, 1.0, 0.0); 
    glVertex3f(-0.5, -0.5, 0.5); 
    glVertex3f(-0.5, 0.5, 0.5); 
    glVertex3f(-0.5, 0.5, -0.5); 
    glVertex3f(-0.5, -0.5, -0.5); 
    glEnd(); 

    // Blue side - TOP 
    glBegin(GL_POLYGON); 
    glColor3f(0.0, 0.0, 1.0); 
    glVertex3f(0.5, 0.5, 0.5); 
    glVertex3f(0.5, 0.5, -0.5); 
    glVertex3f(-0.5, 0.5, -0.5); 
    glVertex3f(-0.5, 0.5, 0.5); 
    glEnd(); 

    // Red side - BOTTOM 
    glBegin(GL_POLYGON); 
    glColor3f(1.0, 0.0, 0.0); 
    glVertex3f(0.5, -0.5, -0.5); 
    glVertex3f(0.5, -0.5, 0.5); 
    glVertex3f(-0.5, -0.5, 0.5); 
    glVertex3f(-0.5, -0.5, -0.5); 
    glEnd(); 

    glFlush(); 
    glutSwapBuffers(); 
} 

// ---------------------------------------------------------- 
// specialKeys() Callback Function 
// ---------------------------------------------------------- 
void specialKeys(int key, int x, int y) 
{ 
    if(!MouseState) 
    { 
     // Right arrow - increase rotation by 5 degree 
     if(key == GLUT_KEY_RIGHT) 
      rotate_y -= 5; 

     // Left arrow - decrease rotation by 5 degree 
     else if(key == GLUT_KEY_LEFT) 
      rotate_y += 5; 

     else if(key == GLUT_KEY_UP) 
      rotate_x -= 5; 

     else if(key == GLUT_KEY_DOWN) 
      rotate_x += 5; 

     // Request display update 
     glutPostRedisplay(); 
    } 
} 

// ---------------------------------------------------------- 
// main() function 
// ---------------------------------------------------------- 
int main(int argc, char* argv[]) 
{ 
    // Initialize GLUT and process user parameters 
    glutInit(&argc, argv); 

    // Set Initial Size of window 
    glutInitWindowSize(1280, 720); 

    // Request double buffered true color window with Z-buffer 
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); 

    // Create window 
    glewInit(); 
    glutCreateWindow(""); 

    // Enable Z-buffer depth test 
    glEnable(GL_DEPTH_TEST); 

    // Enable Backface Culling 
    glEnable(GL_CULL_FACE); 

    // Move mouse to the middle of the screen 
    glutWarpPointer(1280/2, 720/2); 

    // Callback functions 
    glutDisplayFunc(display); 
    glutSpecialFunc(specialKeys); 
    glutMouseFunc(mouseButton); 
    glutMotionFunc(mouseMove); 
    // Pass control to GLUT for events 
    glutMainLoop(); 

    return 0; 
} 
Verwandte Themen