OpenGL - 每次单击菜单时移动的对象

时间:2018-05-24 14:43:20

标签: c++ visual-studio opengl glut

我正在开发一个项目,在我添加了用于更改颜色的菜单后,窗口中的对象或形状会改变颜色,但每次选择菜单中的项目(如颜色)时,都会继续移动或超出范围。我也尝试将GLUT_DOUBLE改为GLUT_SINGLE,但仍然没有运气。

#include "stdafx.h"
#include <windows.h>
#include <GL/glut.h>
#include <stdlib.h>
#define RED 1
#define GREEN 2
#define BLUE 3
#define WHITE 4 //white colour for sphere


float red =1.0,green =1.0,blue=0.0,white = 0.0;

void init(void) {   
    glClearColor (0.0, 0.0, 0.0, 0.0);   
    glShadeModel (GL_FLAT);
}

void display(void){
    // Sphere   
    glClear (GL_COLOR_BUFFER_BIT);   
    glColor3f(red,green,blue);   
    glPushMatrix();   
    glTranslatef (-3.5, -1.5, 0.0);   
    glTranslatef (1.0, 0.0, 0.0);   
    glPushMatrix();   
    glScalef (3.0, 3.0, 0.0);   
    glutSolidSphere(0.4,40,40);   
    glPopMatrix();    
    //Cone   
    glColor3f(0.0,0.0,0.0);   
    glTranslatef (0.95,-0.2, 0.0);   
    glPushMatrix();   
    glRotated(300,1.0,4.0,1.0);   
    glutSolidCone(0.6, 0.9, 30, 30);   
    glPopMatrix();   
    //Sphere(eye)   
    glColor3f(0.0,0.0,0.0);   
    glTranslatef (-0.75,0.8, 0.0);   
    glPushMatrix();   
    glScalef(0.6,0.6,0.0);   
    glutSolidSphere(0.2,40,40);   
    glPopMatrix();    
    glFlush();
}

void reshape (int w, int h){   
    glViewport (0, 0, (GLsizei) w, (GLsizei) h);    
    glMatrixMode (GL_PROJECTION);   
    glLoadIdentity ();   
    gluPerspective(65.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);   
    glMatrixMode(GL_MODELVIEW);   
    glLoadIdentity();   
    glTranslatef (0.0, 0.0, -5.0);
}

void mouse(int option){
    switch(option){
    case RED:
        red = 1.0,green = 0.0,blue = 0.0;
        break;
    case GREEN:
        red = 0.0,green = 1.0,blue = 0.0;
        break;
    case BLUE:
        red = 0.0,green = 0.0,blue = 1.0;
        break;
    case WHITE:
        red = 1.0,green = 1.0,blue = 1.0;
        break;
    }
    glutPostRedisplay();
}

int main(int argc, char** argv){   
    glutInit(&argc, argv);
    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);   
    glutInitWindowSize (700, 500);    
    glutInitWindowPosition (100, 100);   
    glutCreateWindow ("Testing");
    glutDisplayFunc(display);    
    glutReshapeFunc(reshape);
    int sphere =  glutCreateMenu(mouse); //change colour of pacman 
    glutAddMenuEntry("Red",RED);
    glutAddMenuEntry("Green",GREEN);
    glutAddMenuEntry("Blue",BLUE);
    glutAddMenuEntry("White",WHITE);
    glutCreateMenu(mouse);
    glutAddSubMenu("Pacman",sphere);
    glutAttachMenu(GLUT_RIGHT_BUTTON);
    init ();  
    glutMainLoop(); 
    return 0;
}

1 个答案:

答案 0 :(得分:0)

您必须为每个glPopMatrix执行一次glPushMatrix。函数glPopMatrix中缺少1 display

void display(void){
    // Sphere   
    glClear (GL_COLOR_BUFFER_BIT);   
    glColor3f(red,green,blue);   
    glPushMatrix();   
        glTranslatef (-3.5, -1.5, 0.0);   
        glTranslatef (1.0, 0.0, 0.0);   
        glPushMatrix();   
            glScalef (3.0, 3.0, 0.0);   
            glutSolidSphere(0.4,40,40);   
        glPopMatrix();    
        //Cone   
        glColor3f(0.0,0.0,0.0);   
        glTranslatef (0.95,-0.2, 0.0);   
        glPushMatrix();   
            glRotated(300,1.0,4.0,1.0);   
            glutSolidCone(0.6, 0.9, 30, 30);   
        glPopMatrix();   
        //Sphere(eye)   
        glColor3f(0.0,0.0,0.0);   
        glTranslatef (-0.75,0.8, 0.0);   
        glPushMatrix();   
            glScalef(0.6,0.6,0.0);   
            glutSolidSphere(0.2,40,40);   
        glPopMatrix();    
    glPopMatrix(); // <--------------------- this is missing
    glFlush();
}

由于缺少pop,第一次渲染的转换保留在矩阵堆栈的顶部。使用新颜色第二次完成渲染时,将再次应用平移。这导致位置的逐渐改变。