Search code examples
c++visual-studioopenglglut

OpenGL - The object moving everytime the menu clicked


I am developing a project and after I added menu for changing color,the object or shape in window changes color but keep moving other way or out of range every time an item in menu selected such as color. I also tried changing GLUT_DOUBLE to GLUT_SINGLE but still no luck.

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

Solution

  • You have to do one glPopMatrix for each glPushMatrix. Ther is missing 1 glPopMatrix in the function 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();
    }
    

    Since the pop is missing, the translation of the first rendering is kept on the top of the matrix stack. When the rendering is done a 2nd time with the new color, translation is applied again. This causes a progressive change of position.