Rotating square & changing its color

Hello! I’m new to openGL, I need help with rotating a square about its center and changing the color of its square as it rotates.

The code that I’ve worked on so far: (Note: I’m using XCode on Mac, so there might be some differences when initializing the libraries at the beginning)



#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#include <GLUT/glut.h>

//#include <GL/glut.h>   /* GLUT header also calls OpenGL header */
#include <stdlib.h>

/* predefine function names */
void initgl();
void display(void);
void mouse(int button, int state, int x, int y);
void spinDisplay(void);


static GLfloat spin =0.0;

/* main program - setup window using GLUT */ 
int
main(int argc, char **argv)
{
    /* Initialise GLUT window manger */
    glutInit(&argc, argv);       
    //glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB ); 
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB );
    glutInitWindowSize(500, 500);
    glutCreateWindow("Square");

    glutDisplayFunc(display);   /* Register a drawing function with GLUT */
    glutMouseFunc(mouse);

    initgl();                   /* initialise the opengl */

    glutMainLoop();             /* loop forever & start displaying */
    return  0;
}

/* Initialisation of OpenGL */
void initgl()
{
	
	glMatrixMode(GL_PROJECTION); //hello
	
    glLoadIdentity();
    
    glMatrixMode(GL_MODELVIEW);
	gluOrtho2D(0.0, 1.0, 0.0,1.0);
    glClearColor (1.0, 1.0, 1.0,1.0); /* background colour */
    glColor3f(1.0,0.0,0.0);       /* foreground colour */
}

/* draw a square */
void display(void)
{
   glClear(GL_COLOR_BUFFER_BIT);


   glPushMatrix(); /* save current transformation state on stack */
   
	glRotatef(spin,1.5,1.5,0.0);/* rotate about z-axis */

	
   glBegin(GL_POLYGON);             /* POLYGON with 4 Verticies */
      glVertex3f (0.25, 0.25, 0.0);
      glVertex3f (0.75, 0.25, 0.0);
      glVertex3f (0.75, 0.75, 0.0);
      glVertex3f (0.25, 0.75, 0.0);
   glEnd();

   glPopMatrix(); /* reset to previous transformation state */
 
   //glFlush();
   glutSwapBuffers();
}


void mouse(int button, int state, int x, int y) 
{
       switch (button) {
          case GLUT_LEFT_BUTTON:
             if (state == GLUT_DOWN)
				glutIdleFunc(spinDisplay); /* start spin */
				
			   break;
         case GLUT_RIGHT_BUTTON:
               if (state == GLUT_DOWN)
		 glutIdleFunc(NULL);    /* stop spin */
         break;
             default:
         break;
       }
}

/* update angle of display */
void spinDisplay(void)
{
  spin = spin + 2.0;
	if (spin > 360.0)
		spin = spin - 360.0;
  
  glutPostRedisplay();
  
}

if its the rotation thats the problem then change glrotate to (spin, 0 ,0, 1)

the colour you aren’t changing so you would need to store that in a varible and change them in your spinDisplay method. blending the colour will give a nicer effect to i.e

glEnable(GL_BLEND);

Earlier, I did try (spin,0,0,1) but that only rotated the square at the z-axis (as I have commented in the code). I need to find a way to make the square rotate at its center. Thank you for trying, though :slight_smile:

The rotation should be a matter of


Gl.glMatrixMode(Gl.GL_MODELVIEW);
            Gl.glLoadIdentity();
            //do any camera stuff you want 

            Gl.glPushMatrix();
            //update spin
            spin += 2.0f;
            if (spin > 360.0)
                spin = 0;
// rotate
            Gl.glRotatef(spin, 0, 0, 1);

            //now draw our square

            Gl.glBegin(Gl.GL_QUADS);
            Gl.glColor3f(1, 1, 0);
            Gl.glVertex3f(-25.0f, -25.0f, 25.0f);	// Bottom Left  Quad

            Gl.glVertex3f(25.0f, -25.0f, 25.0f);	// Bottom Right  Quad

            Gl.glVertex3f(25.0f, 25.0f, 25.0f);	// Top Right  Quad

            Gl.glVertex3f(-25.0f, 25.0f, 25.0f);	// Top Left  Quad
            Gl.glEnd();
            Gl.glPopMatrix();
            
            Gl.glFlush();

It works now thank you very much!
I see, I should’ve drawn the square at the center of its origin. Could you explain more on how to use GL_BLEND?

Thats my mistake i ment glShadeModel(GL_SMOOTH);

This will make the quad look nicer as you can colour each vert and they will make a nice effect. So the colours will actually blend from point to point and changing them might look nicer.

Yes GL_SMOOTH does give the pretty blending effect :slight_smile: However, that’s not really what I meant when I said changing the color. I have to change the color of the square while it rotates (ex: from red>green>red>…until it stops rotating). Any suggestions as to how I do that?

But anyway, thank you for the tip on glShadeModel!

Well I use visual studio and the tao framework so i’m not sure how the glut function works exactly but the basics of it is this.

Create a colour varible (this can be a float array or three seperate floats)

lets say you went individual floats:

ie red = 1, green = 0 and blue = 0

set a timer you may want to use this instead of glutIdleFunc use glutTimerFunc(40,spinDisplay,0);

basically from what I can tell (again i would use VS and TAO) the glutIdleFunc will be called when ever it can, this is not good for animation or the recolor as it will happen at different speeds depending on the comp its ran on.

by using the timer we make the animation a set frame rate in this case 25fps

Now in your spinDisplay change your colour varible if you just want green to red and back then:

if(red == 1)
{
red = 0;
green = 1;
blue = 0;
}
else if(green == 1)
{
red = 0;
green = 1;
blue = 0;
}

Finally in the code change the colour3f to
Gl.glColor3f(red, green, blue);

In my example you can see the GL.function this is because i am using the tao framework and c#.

I can’t seem to get it right. All I got was a black square rotating. I created individual color floats:

float red,green,blue;

and the function spinDisplay was modified to be:

void spinDisplay(void)
{
	spin += 2.0;
	
	if(red == 1.0)
	{
		red = 0.0;
		green = 1.0;
		blue = 0.0;
	}
	else if(green == 1.0)
	{
		red = 0.0;
		green = 1.0;
		blue = 0.0;
	}
	glutPostRedisplay();

}

I placed glColor3f(red, green, blue); in the display function, before glBegin().

I tried using glutTimerFunc(40,spinDisplay,0); but got a warning saying
‘warning: passing argument 2 of ‘glutTimerFunc’ from incompatible pointer type’

Yeah i’m not sure about the glut stuff unfortunatly I’m sure another member will be able to explain it but this might point out what is wrong:

http://www.opengl.org/resources/faq/technical/glut.htm

Sorry I couldn’t be more helpful for the glut issue but i us VS and TAO