OpenGL triangle rotation using glut - need a simple correction

7k Views Asked by At

Here is my code :

#include <stdio.h>
#include "glut.h"

float width = 800.0;
float height = 600.0;

void changeSize(int w,int h){
    if(h==0)
        h=1;
    width = w;
    height = h;
    GLdouble ratio = 1.0f*w/h;

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    glViewport(0,0,w,h);

    gluPerspective(45,ratio,1,1000);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0,0,10,
              0,0,-1,
              0,1,0);
}

void renderScene(){
    glClearColor(0,0,255,1);
    glClearDepth(1.0f);
    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

    //glPushMatrix();


    glRotatef(0.09,0.0,0.0,0.09); 
    glColor3f(1.0,0.0,0.0);
        glBegin(GL_QUADS);
        glVertex3f(-1.0f,-1.0f,0.0f);
        glVertex3f(1.0f,-1.0f,0.0f);
        glVertex3f(1.0f,1.0f,0.0f);
        glVertex3f(-1.0f,1.0f,0.0f);
    glEnd();
    //glPopMatrix();


    glPushMatrix();
    glColor3f(0.0,1.0,0.0);
    glTranslatef(-3.0,0.0,0.0);

    glRotatef(0.09,0.0,0.0,-1.0);
    glBegin(GL_TRIANGLE_STRIP);
        glVertex2f(-1,-1);
        glVertex2f(0,1);
        glVertex2f(1,-1);
        glEnd();

    glPopMatrix();



    glutSwapBuffers();

}

int main(int argc, char **argv){

    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowPosition(100,200);
    glutInitWindowSize(width,height);
    glutCreateWindow("OpenGL");

    glutDisplayFunc(renderScene);
    glutIdleFunc(renderScene);

    glutReshapeFunc(changeSize);

    glutMainLoop();

    return(0);

}

I draw a rectangle and a triangle.

Both of them are rotating right now but I want the rectangle to stand still and rotate the triangle only. What am I doing wrong here? Do I need to change push pop lines or something else. I tried many combinations but I can't do it.

3

There are 3 best solutions below

1
On BEST ANSWER

what you should do is replace

glRotatef(0.09,0.0,0.0,0.09); 
glColor3f(1.0,0.0,0.0);
    glBegin(GL_QUADS);
    glVertex3f(-1.0f,-1.0f,0.0f);
    glVertex3f(1.0f,-1.0f,0.0f);
    glVertex3f(1.0f,1.0f,0.0f);
    glVertex3f(-1.0f,1.0f,0.0f);
glEnd();

with

glColor3f(1.0,0.0,0.0);
    glBegin(GL_QUADS);
    glVertex3f(-1.0f,-1.0f,0.0f);
    glVertex3f(1.0f,-1.0f,0.0f);
    glVertex3f(1.0f,1.0f,0.0f);
    glVertex3f(-1.0f,1.0f,0.0f);
glEnd();

Pushing/popping the matrix will not do any change to the rectangle's transformation, it will only prevent the rectangle's transformation from affecting the triangle's.

2
On

If you do not want to rotate the rectangle then remove the rotate call glRotatef(0.09,0.0,0.0,0.09); before drawing the rectangle. You need to push-pop matrix before-after drawing triangle, rectangle. To stop rotation you have to remove rotate call, not push-pop matrix.

EDIT: To rotate the triangle you need to change the angle. If you keep fixed angle 0.09 then there will be no animation. One simple way is to keep track of angle as a global variable. Something like this:

double ang = 0;  // global variable

void renderScene(){
    // other codes

    glRotatef(ang++,0.0,0.0,-1.0);  // use and change ang instead of using fixed 0.09
    glBegin(GL_TRIANGLE_STRIP);

    // remaining codes
}
0
On

Your problem is that the rotation around the square is the only one that's actually compounding every frame. Because you push/pop the rotation around the triangle, it's getting reset back to its default state every time you draw it.

Instead of making it rotate over time, you're just doing a small rotate, popping it (thus removing the rotation), and then when you draw next frame you do the exact same small rotation, so the triangle doesn't look like it ever moves, it just draws in the same rotated state every time.

Because you don't pop the rotation around the quad, it compounds over each frame. What you want to do is increment a variable each frame, and then rotate by the amount of the variable.

First define a float rotationAngle as a member variable of your class.

Then in the draw call, run something like this:

rotationAngle += rotationSpeed;
glPushMatrix();
  //do quad specific transformations
  //draw quad
glPopMatrix(); //remove quad specific transforms from stack

glPushMatrix();
   glRotatef(rotationAngle, 0, 0, 1);
   //do other triangle specific rotations
   //draw triangle
glPopMatrix(); //remove triangle's rotation and other transforms