我试图让我的对象根据想要的轴旋转(通过按x,y,z),然后用相同的键启动/停止旋转。这是我的代码:
#include <glut.h>
#include <stdio.h>
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合并到它中。即使我能够澄清一下如何/为什么我的键盘调用不正确也会很棒!
答案 0 :(得分:4)
您希望将当前旋转状态写入某个变量。因此,当您想要绘制场景时,它将会被人知道。
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;
}
这应该让你开始。
请记住,这会强制在特定轴上旋转对象的局部轴。如果你想对旋转有更多的控制,你可以看看一些四元数 - &gt;矩阵旋转。有一篇关于Wiki的文章以及关于互联网的更多文章。
此外,动画方案已放入空闲功能,您无法直接控制动画的速度。它完全取决于应用程序的帧速率。还有很多关于如何实现主循环的精彩文章,以便您可以精确地处理逻辑/时间。