我做了(翻译,旋转,翻译)的事情,但它仍然围绕原点旋转。我所做的就是当你按下r键时,技巧将开始,即翻译,旋转,翻译。结果是它仍然围绕原点旋转
#include <gl/glut.h>
void OnKeyPress(unsigned char key, int x, int y)
{
if (key == 27)
exit(0);
switch(key)
{
case 'r':
case 'R':
// trick start here *********************
glTranslatef(-60,-20,0);
glRotatef(10, 0, 0, 1);
glTranslatef(60, 20, 0);
glutPostRedisplay();
break;
};
}
void OnDisplay()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0f,0.5f,1.0f);
glBegin(GL_TRIANGLES);
glVertex2f(20, 20);
glVertex2f(60, 20);
glVertex2f(20, 100);
glEnd();
glFlush();
}
int main( int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA);
glutInitWindowPosition(100, 100);
glutInitWindowSize(800, 600);
glutCreateWindow("OpenGL Lab1" );
glutDisplayFunc(OnDisplay);
glutKeyboardFunc(OnKeyPress);
glClearColor(1.0, 1.0, 1.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-100, 100, -100, 100);
glutMainLoop();
return 0;
}
答案 0 :(得分:4)
您需要切换glTranslate
次调用的顺序,因为上次完成的转换是应用于顶点的第一次转换。看,每个变换都是一个矩阵,其当前矩阵乘以。然后将得到的矩阵乘以顶点,以确定其最终位置。
所以如果你有:
glTranslatef(-60,-20,0); (T1)
glRotatef(10, 0, 0, 1); (R)
glTranslatef(60, 20, 0); (T2)
并且还有一个从前一帧存储的旧矩阵Mo,您将拥有:
M = (((Mo * T1) * R) * T2)
最后,这个M乘以每个顶点Vo,以确定它的最终位置:
V = M * Vo
矩阵乘法是非交换的,但它们是关联的,因此括号顺序无关紧要,所有这些转换在数学上等同于:
V = Mo * T1 * R * (T2 * Vo)
请注意,(T2 * Vo)是由T2(您的上一次翻译)转换的顶点。如果我们称之为V1,我们有:
V = Mo * T1 * (R * V1)
看到V1,由T2转换的原始顶点现在又被(R * V1)中的旋转R转换,产生另一个顶点,现在被翻译然后旋转。继续从右到左解决表达式,你将把所有的变换应用于它们在OpenGL代码中被“调用”的相反顺序的顶点。
我假设您知道为什么必须翻译 - 旋转 - 未翻译才能围绕您想要的点进行旋转,但是当您说代码中的“东西”围绕原点旋转时,您就错了。事实上,如果你注意,你会注意到它在点(-60,-20)附近旋转。
最后,您没有使用模型视图矩阵,而是使用透视矩阵进行所有变换(顺便说一下,因为您不像大多数应用程序那样每帧都重置它)。您不应该这样做,而是使用GL_MODELVIEW进行这种转换。尝试使用以下方法完成初始化功能:
...
Set_Transformations();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glutMainLoop();
}
答案 1 :(得分:1)
翻转(+, rot, -)
而不是(-, rot, +)
:
#include <gl/glut.h>
int angle = 0;
void OnKeyPress(unsigned char key, int x, int y)
{
if (key == 27)
exit(0);
switch(key)
{
case 'r':
case 'R':
angle += 10;
glutPostRedisplay();
break;
};
}
void OnDisplay()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0f,0.5f,1.0f);
glClearColor(1.0, 1.0, 1.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-100, 100, -100, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// trick start here *********************
glTranslatef(60, 20, 0);
glRotatef( angle, 0, 0, 1);
glTranslatef(-60,-20,0);
glBegin(GL_TRIANGLES);
glColor3ub(0,0,255);
glVertex2f(20, 20);
glColor3ub(255,0,0);
glVertex2f(60, 20);
glColor3ub(0,0,255);
glVertex2f(20, 100);
glEnd();
glFlush();
}
int main( int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA);
glutInitWindowPosition(100, 100);
glutInitWindowSize(800, 600);
glutCreateWindow("OpenGL Lab1" );
glutDisplayFunc(OnDisplay);
glutKeyboardFunc(OnKeyPress);
glutMainLoop();
return 0;
}