float carX = 0.0;
float carY = 0.0;
float carSpeed = 1.0;
float direction = 0.0;
bool exhaust;
void reshape(void)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 10.0, 0, 10.0, 0.0, 10.0);
glMatrixMode(GL_MODELVIEW);
}
void keys(int key, int x, int y){
if(key == GLUT_KEY_UP){
carY = carY + carSpeed;
direction = 0.0;
glutPostRedisplay();
}
if(key == GLUT_KEY_DOWN){
carY = carY - carSpeed;
direction = 90.0;
glutPostRedisplay();
}
if(key == GLUT_KEY_LEFT){
carX = carX - carSpeed;
direction = -90.0;
glutPostRedisplay();
}
if(key == GLUT_KEY_RIGHT){
carX = carX + carSpeed;
direction = 180.0;
glutPostRedisplay();
}}
void renderScene(void){
glClear (GL_COLOR_BUFFER_BIT);
glLoadIdentity();
drawPlayground();
glPushMatrix();
glRotatef(direction, 0.0, 0.0, 1.0);
glTranslatef(carX, carY,0.0);
drawcar();
glPopMatrix();
glFlush();}
int main(int argc, char** argv){
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (400, 400);
glutInitWindowPosition (100, 100);
glutCreateWindow("courseWork_2DGame");
reshape();
glutDisplayFunc(renderScene);
glutSpecialFunc(keys);
glutMainLoop();
return 0;}
这是我的openGL代码,我画了汽车移动的操场。汽车将被移动但是箭头,并且当它移动方向时,按照箭头键按下汽车的旋转。然而,当按下按键时,汽车转换得很好,但旋转不正确,我认为因为它不是在它的中心而是在不同的点上旋转。
答案 0 :(得分:2)
我记得有一篇文章详细解释了这一点here。这个人在解释整个矩阵层次结构方面做了惊人的工作。
如果要围绕其中心旋转对象,首先必须将其转换为原点,然后旋转并将其平移。由于转换矩阵会从右到左影响矢量,因此必须按相反的顺序对这些步骤进行编码。
这是一些伪代码,因为我不了解OpenGL例程:
PushMatrix();
LoadIdentity(); // Start with a fresh matrix
Translate(); // Move your object to its final destination
Rotate(); // Apply rotations
Draw(); // Draw your object using coordinates relative to the object center
PopMatrix();
这些矩阵得到应用:
v_t = (I * T * R) * v = (I * (T * (R * v)))
顺序是:轮换,翻译。
编辑:对上述等式的解释。
转换旋转,缩放和平移会影响模型 - 视图 - 矩阵。模型的每个3D点(矢量)乘以此矩阵以获得其在3D空间中的最终点,然后将其乘以投影矩阵以接收2D点(在2D屏幕上)。
忽略投影内容,由模型 - 视图矩阵转换的点是:
v_t = MV * v
表示原点v,乘以模型 - 视图 - 矩阵MV。
在上面的代码中,我们通过单位矩阵I,平移T和旋转R构建MV:
MV = I * T * R
将所有内容组合在一起,您会看到您的点v首先受到旋转R的影响,然后是翻译T,这样您的点在翻译之前就会被旋转,就像我们希望的那样:
v_t = MV * v = (I * T * R) * v = T * (R * v)
在Translate()之前调用Rotate()将导致:
v_t = (I * R * T) * v = R * (T * v)
这很糟糕:转换到3D中的某个点,然后围绕原点旋转,导致模型中出现一些奇怪的失真。