我试图使我的对象根据所需的轴旋转(通过按x,y,z),然后使用相同的键启动/停止旋转。这是我的代码:
#include#include static GLfloat spin = 0.0; void init(void){ glClearColor(0.0, 0.0, 0.0, 0.0); glShadeModel(GL_SMOOTH); } void action(void) { } void display(void) { glClear(GL_COLOR_BUFFER_BIT); glPushMatrix(); glBegin(GL_LINE_LOOP); glColor3f(1.00, 0.00, 0.00); glVertex3f(0.00, 0.00, 0.00); glVertex3f(0.00, 0.00, -1.00); glVertex3f(0.50, 0.00, -1.00); glVertex3f(0.75, 0.0, -0.75); glVertex3f(0.25, 0.25, -1.0); glVertex3f(0.50, 0.50, -0.50); glColor3f(0.00, 1.00, 0.00); glVertex3f(0.00, 0.00, 0.00); glVertex3f(0.00, 0.00, 1.00); glVertex3f(0.50, 0.00, 1.00); glVertex3f(0.75, 0.0, 0.75); glVertex3f(0.25, 0.25, 1.0); glVertex3f(0.50, 0.50, 0.50); glEnd(); glPopMatrix(); glutSwapBuffers(); glFlush(); } //spin function void spinDisplay(void){ spin = spin + 0.02; if (spin > 360.0) spin = spin - 360.0; glutPostRedisplay(); } void reshape(int w, int h) { glViewport(0, 0, (GLsizei)w, (GLsizei)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-1.0, 1.0, -1.0, 1.0, 0.5, 15.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(1.5, 1.5, 1.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); } //keyboard event handler void keyboard(unsigned char key, int x, int y) { switch (key) { case 27: // Escape key exit(0); break; case 'x': glRotatef(spin, 1.0, 0.0, 0.0); break; case 'y': glRotatef(spin, 0.0, 1.0, 0.0); break; case 'z': glRotatef(spin, 0.0, 0.0, 1.0); break; case 'r': glutIdleFunc(action); break; } glutPostRedisplay(); } void mouse(int button, int state, int x, int y){ switch (button){ case GLUT_LEFT_BUTTON: if (state == GLUT_DOWN) glutIdleFunc(spinDisplay); break; case GLUT_RIGHT_BUTTON: if (state == GLUT_DOWN) glutIdleFunc(NULL); break; default: break; } } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize(500, 500); glutInitWindowPosition(100, 100); glutCreateWindow(argv[0]); init(); glutReshapeFunc(reshape); glutDisplayFunc(display); glutMouseFunc(mouse); glutKeyboardFunc(keyboard); glutIdleFunc(action); glutMainLoop(); return 0; }
我在键盘功能中具有所需的每个键,但是我想知道glRotatef -即它是否属于该键。我创建了我打算用于调用glutIdleFunc()的函数操作,但是不确定如何将Rotate并入其中。即使我能就为什么/为什么我的键盘通话不正确做出一些澄清,也很棒!
您希望将当前旋转状态写入某个变量。这样,当您要绘制场景时就可以知道它。
struct rot_state { bool rotating; // animation/movement happening float x,y,z; // current rotation values int current_axis; // 0 for x, 1 for y, 2 for z }
状态保持当前旋转,程序可以对此进行操作。
glutIdleFunc
通过增加(设置动画)正确的轴来完成此示例中的所有工作app_state.x += increment;
Glut调用每次都无关紧要并处理循环时。因此,它用作动画逻辑的门,然后在帧上强制重画。
尽管可以做得更好,但我不想掩盖原始代码。
在显示框架时,您可以仅使用已有的信息并应用旋转。
glRotatef(app_state.x, 1, 0, 0); glRotatef(app_state.y, 0, 1, 0); glRotatef(app_state.z, 0, 0, 1);
#include <glut.h> #include <stdio.h> struct rot_state { bool rotating; // animation/movement happening float x,y,z; // current rotation values int current_axis; // 0 for x, 1 for y, 2 for z } app_state; void init(void){ // Setting up initial app state app_state.rotating = false; app_state.x = app_state.y = app_state.z = 0.0f; app_state.current_axis = 0; glClearColor(0.0, 0.0, 0.0, 0.0); glShadeModel(GL_SMOOTH); } void action(void) { // Animate the rotation float increment = 1.0f; switch (app_state.current_axis) { case 0: app_state.x += increment; break; case 1: app_state.y += increment; break; case 2: app_state.z += increment; break; default: break; } glutPostRedisplay(); } void display(void) { glClear(GL_COLOR_BUFFER_BIT); glPushMatrix(); // Apply the rotations glRotatef(app_state.x, 1, 0, 0); glRotatef(app_state.y, 0, 1, 0); glRotatef(app_state.z, 0, 0, 1); glBegin(GL_LINE_LOOP); glColor3f(1.00, 0.00, 0.00); glVertex3f(0.00, 0.00, 0.00); glVertex3f(0.00, 0.00, -1.00); glVertex3f(0.50, 0.00, -1.00); glVertex3f(0.75, 0.0, -0.75); glVertex3f(0.25, 0.25, -1.0); glVertex3f(0.50, 0.50, -0.50); glColor3f(0.00, 1.00, 0.00); glVertex3f(0.00, 0.00, 0.00); glVertex3f(0.00, 0.00, 1.00); glVertex3f(0.50, 0.00, 1.00); glVertex3f(0.75, 0.0, 0.75); glVertex3f(0.25, 0.25, 1.0); glVertex3f(0.50, 0.50, 0.50); glEnd(); glPopMatrix(); glutSwapBuffers(); glFlush(); } void reshape(int w, int h) { glViewport(0, 0, (GLsizei)w, (GLsizei)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-1.0, 1.0, -1.0, 1.0, 0.5, 15.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(1.5, 1.5, 1.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); } //keyboard event handler void keyboard(unsigned char key, int x, int y) { switch (key) { case 27: // Escape key exit(0); break; case 'x': app_state.current_axis = 0; break; case 'y': app_state.current_axis = 1; break; case 'z': app_state.current_axis = 2; break; case 'r': app_state.rotating ^= 1; glutIdleFunc(app_state.rotating ? action : NULL); break; } glutPostRedisplay(); } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize(500, 500); glutInitWindowPosition(100, 100); glutCreateWindow(argv[0]); init(); glutReshapeFunc(reshape); glutDisplayFunc(display); glutKeyboardFunc(keyboard); glutIdleFunc(action); glutMainLoop(); return 0; }
这应该使您入门。
请记住,这会强制在对象本地的特定轴上旋转。如果要对旋转进行更多控制,则需要查看一些四元数->矩阵旋转。在Wiki上有一篇文章,在互联网上还有更多文章。
动画方案也被置于空闲函数中,您无法直接控制动画的速度。它完全取决于应用程序的帧速率。关于如何实现主循环的文章也很多,因此您的逻辑/时间可以得到精确处理。