I'm making a program that rotates six-point stars with two triangles overlapping when I click the mouse button.
- Click right mouse button: star spins
- Click middle mouse button: star's color changes(white → blue)
I've applied the codes to rotate a rectangle, but when I click right mouse button, it doesn't rotate and makes a jump around.
And when the middle mouse button is clicked, the color changing is successful but it is initialized by rotating the star. I would like to rotate the star with the color changed by clicking the middle button while rotating.
Please let me know what is the problem.
/////////////////////////// Header /////////////////////////////
#include <stdlib.h>
#include <GL/glut.h>
float v1[3] = { 365.0, 465.0, 0.0 };
float v2[3] = { 365.0, 420.0, 0.0 };
float v3[3] = { 400.0, 485.0, 0.0 };
float v4[3] = { 400.0, 400.0, 0.0 };
float v5[3] = { 435.0, 465.0, 0.0 };
float v6[3] = { 435.0, 420.0, 0.0 };
static GLfloat spin = 0.0;
//////////////////////// Functions ////////////////////////////
void init(void) {
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
}
void reshape(int w, int h) {
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 500.0, 0.0, 500.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void spinDisplay(void) {
spin = spin + 2.0;
if (spin > 360.0) {
spin = spin - 360.0;
}
glutPostRedisplay();
}
void triangle_1(void) { /////////// first triangle ///////////
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_TRIANGLE_FAN);
glVertex3fv(v1);
glVertex3fv(v4);
glVertex3fv(v5);
glEnd();
}
void triangle_2(void) { ///////// second triangle /////////
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_TRIANGLE_FAN);
glVertex3fv(v2);
glVertex3fv(v3);
glVertex3fv(v6);
glEnd();
}
void triangle_1p(void) { ///// first triangle (color changed) /////
glColor3f(0.0, 0.0, 1.0);
glBegin(GL_TRIANGLE_FAN);
glVertex3fv(v1);
glVertex3fv(v4);
glVertex3fv(v5);
glEnd();
}
void triangle_2p(void) { ///// second triangle (color changed) /////
glColor3f(0.0, 1.0, 0.0);
glBegin(GL_TRIANGLE_FAN);
glVertex3fv(v2);
glVertex3fv(v3);
glVertex3fv(v6);
glEnd();
}
void display(void) { ///////// star display /////////
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glRotatef(spin, 0.0, 0.0, 1.0);
triangle_1();
triangle_2();
glPopMatrix();
glutSwapBuffers();
}
void display_p(void) { ///// star display (color changed) /////
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glRotatef(spin, 0.0, 0.0, 1.0);
triangle_1p();
triangle_2p();
glPopMatrix();
glutSwapBuffers();
}
/////////////////////// Mouse Click ///////////////////////
void mouse(int button, int state, int x, int y) {
switch (button) {
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN)
glutIdleFunc(NULL);
break;
case GLUT_MIDDLE_BUTTON:
if (state == GLUT_DOWN)
glutIdleFunc(display_p);
break;
case GLUT_RIGHT_BUTTON:
if (state == GLUT_DOWN)
glutIdleFunc(spinDisplay);
break;
default:
break;
}
}
//////////////////////////// Main /////////////////////////////
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(300, 300);
glutCreateWindow("6-Point Star");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutMainLoop();
return 0;
}
It actually isn't jumping around, it's rotating around the origin (bottom left corner of the display).
The reason this happens if because you're rotating then translating. Since you have hardcoded the star's position of
x = 400
andy = 442.5
into your vertices. If you make so that the the center of the star is at0x0
(subtracting400x442.5
) then you'll see the star is rotating around itself in the bottom left corner of the display.Now in
display()
you then translate before rotating:Considering
float x = 400.0f, y = 442.5f;
to be defined elsewhere.Now you'll see the star back at the same place, but rotating around itself.
Instead of duplicating all your code for each mode, you could keep the colors as variables.
Now in
mouse()
onGLUT_MIDDLE_BUTTON
then you switch around the colors.Then in
triangle_1
andtriangle_2
remember to replaceglColor3f()
withglColor3fv(color1)
andglColor3fv(color2)
.Instead of all that, you could also just set
mode
inmouse
and do something like this intriangle_1
(also doing likewise intriangle_2
):The choice is of course up to you.
All in all, now you should be able to see the star rotating around itself, and toggle the colors when middle mouse button is clicked.
This now also means that you can delete
display_p
,triangle_1p
andtriangle_2p
.