(OpenGL) 旋转对象
(OpenGL) Rotate object
我正在制作一个程序,当我单击鼠标按钮时,它会旋转两个三角形重叠的六点星。
- 点击鼠标右键:星星旋转
- 点击鼠标中键:星星颜色变化(白→蓝)
我已经应用了代码来旋转一个矩形,但是当我点击鼠标右键时,它不旋转而是跳来跳去。
并且点击鼠标中键时,变色成功,但是是通过旋转星星来初始化的。我想通过在旋转时单击中间按钮来旋转颜色改变的星星。
请告诉我问题是什么。
/////////////////////////// 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;
}
when I click right mouse button, it doesn't rotate and makes a jump around
它实际上不是跳来跳去,而是围绕原点(显示屏的左下角)旋转。
发生这种情况的原因是因为你在旋转然后平移。由于您已将星星的 x = 400
和 y = 442.5
位置硬编码到您的顶点中。如果你使星星的中心位于 0x0
(减去 400x442.5
),那么你会看到星星在显示屏的左下角绕着自己旋转。
float v1[3] = { -35.0f, 22.5f, 0.0f };
float v2[3] = { -35.0f, -22.5f, 0.0f };
float v3[3] = { 0.0f, 42.5f, 0.0f };
float v4[3] = { 0.0f, -42.5f, 0.0f };
float v5[3] = { 35.0f, 22.5f, 0.0f };
float v6[3] = { 35.0f, -22.5f, 0.0f };
现在在 display()
中,然后在旋转之前进行翻译:
glTranslatef(x, y, 0.0f);
glRotatef(spin, 0.0, 0.0, 1.0);
考虑在别处定义 float x = 400.0f, y = 442.5f;
。
现在你会看到星星回到原处,但绕着自己旋转。
I would like to rotate the star with the color changed by clicking the middle button while rotating.
您可以将颜色保留为变量,而不是为每种模式复制所有代码。
float color1[3] = { 1.0f, 1.0f, 1.0f };
float color2[3] = { 1.0f, 1.0f, 1.0f };
int mode = 1;
现在 mouse()
在 GLUT_MIDDLE_BUTTON
然后你切换颜色。
case GLUT_MIDDLE_BUTTON:
if (state == GLUT_DOWN) {
if (mode == 1) {
color1[0] = 0.0f, color1[1] = 0.0f, color1[2] = 1.0f;
color2[0] = 0.0f, color2[1] = 1.0f, color2[2] = 0.0f;
mode = 2;
}
else if (mode == 2) {
color1[0] = 1.0f, color1[1] = 1.0f, color1[2] = 1.0f;
color2[0] = 1.0f, color2[1] = 1.0f, color2[2] = 1.0f;
mode = 1;
}
}
然后在triangle_1
和triangle_2
记得把glColor3f()
换成glColor3fv(color1)
和glColor3fv(color2)
.
除此之外,您还可以在 mouse
中设置 mode
并在 triangle_1
中执行类似的操作(在 triangle_2
中也这样做):
if (mode == 2)
glColor3f(0.0, 0.0, 1.0);
else
glColor3f(1.0, 1.0, 1.0);
当然是你的选择
总而言之,现在您应该能够看到星星围绕自身旋转,并在单击鼠标中键时切换颜色。
现在这也意味着您可以删除 display_p
、triangle_1p
和 triangle_2p
。
我正在制作一个程序,当我单击鼠标按钮时,它会旋转两个三角形重叠的六点星。
- 点击鼠标右键:星星旋转
- 点击鼠标中键:星星颜色变化(白→蓝)
我已经应用了代码来旋转一个矩形,但是当我点击鼠标右键时,它不旋转而是跳来跳去。
并且点击鼠标中键时,变色成功,但是是通过旋转星星来初始化的。我想通过在旋转时单击中间按钮来旋转颜色改变的星星。
请告诉我问题是什么。
/////////////////////////// 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;
}
when I click right mouse button, it doesn't rotate and makes a jump around
它实际上不是跳来跳去,而是围绕原点(显示屏的左下角)旋转。
发生这种情况的原因是因为你在旋转然后平移。由于您已将星星的 x = 400
和 y = 442.5
位置硬编码到您的顶点中。如果你使星星的中心位于 0x0
(减去 400x442.5
),那么你会看到星星在显示屏的左下角绕着自己旋转。
float v1[3] = { -35.0f, 22.5f, 0.0f };
float v2[3] = { -35.0f, -22.5f, 0.0f };
float v3[3] = { 0.0f, 42.5f, 0.0f };
float v4[3] = { 0.0f, -42.5f, 0.0f };
float v5[3] = { 35.0f, 22.5f, 0.0f };
float v6[3] = { 35.0f, -22.5f, 0.0f };
现在在 display()
中,然后在旋转之前进行翻译:
glTranslatef(x, y, 0.0f);
glRotatef(spin, 0.0, 0.0, 1.0);
考虑在别处定义 float x = 400.0f, y = 442.5f;
。
现在你会看到星星回到原处,但绕着自己旋转。
I would like to rotate the star with the color changed by clicking the middle button while rotating.
您可以将颜色保留为变量,而不是为每种模式复制所有代码。
float color1[3] = { 1.0f, 1.0f, 1.0f };
float color2[3] = { 1.0f, 1.0f, 1.0f };
int mode = 1;
现在 mouse()
在 GLUT_MIDDLE_BUTTON
然后你切换颜色。
case GLUT_MIDDLE_BUTTON:
if (state == GLUT_DOWN) {
if (mode == 1) {
color1[0] = 0.0f, color1[1] = 0.0f, color1[2] = 1.0f;
color2[0] = 0.0f, color2[1] = 1.0f, color2[2] = 0.0f;
mode = 2;
}
else if (mode == 2) {
color1[0] = 1.0f, color1[1] = 1.0f, color1[2] = 1.0f;
color2[0] = 1.0f, color2[1] = 1.0f, color2[2] = 1.0f;
mode = 1;
}
}
然后在triangle_1
和triangle_2
记得把glColor3f()
换成glColor3fv(color1)
和glColor3fv(color2)
.
除此之外,您还可以在 mouse
中设置 mode
并在 triangle_1
中执行类似的操作(在 triangle_2
中也这样做):
if (mode == 2)
glColor3f(0.0, 0.0, 1.0);
else
glColor3f(1.0, 1.0, 1.0);
当然是你的选择
总而言之,现在您应该能够看到星星围绕自身旋转,并在单击鼠标中键时切换颜色。
现在这也意味着您可以删除 display_p
、triangle_1p
和 triangle_2p
。