我正在尝试在OpenGL中实现基本的自由移动相机。
我想了解操作,所以我不使用gluLookAt。
我尝试了一些事情,但它没有按预期工作。
这是我的渲染
UICollectionView
我的输入处理
// Every frame
glViewport(0, 0, windowWidth, windowHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, windowWidth, 0, windowHeight, 0, 40);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// camera transforms:
glTranslatef(eye_x, eye_y, eye_z);
glRotatef(x_angular, 0, 1, 0);
// foreach object:
glPushMatrix();
{
glTranslatef( (*obj_i)->anchor[0] , (*obj_i)->anchor[1], (*obj_i)->anchor[2]);
glutWireSphere((*obj_i)->r, 15, 15);
}
glPopMatrix();
我想做什么: 在z = 0时有3个球体,我想进入(传递它们)然后VK_LEFT(向左转)做180,然后我应该能够看到球体。
不太确定错误,可能是我的输入处理错误,或操作已关闭?
使用glOrtho(0,windowWidth,0,windowHeight,0,40)
z_near是0而z_far = 40对吗?
如果我在z = 0和glTranslate(0,0,-10)绘制,我会接近z_far?并传递在z = 0处绘制的内容?
我已经阅读了大量的q / a和教程,但我无法将解释与我的代码相关联。
编辑
这看起来更接近我想要的。将需要运行更多测试,我认为可能仍然存在一两个故障。
// VK_UP
else if ( (*event_it)->key == 129 ) {
buffer << " Key press: VK_UP \n";
eye_z += 1;
}
// VK_DOWN
else if ( (*event_it)->key == 131 ) {
buffer << " Key press: VK_DOWN \n";
eye_z -= 1;
}
// VK_LEFT
else if ( (*event_it)->key == 128 ) {
//eye_x += 10;
buffer << " Key press: VK_LEFT \n";
x_angular -= 2;
//glRotatef(x_angular, 0, 0, 1);
}
// VK_RIGHT
else if ( (*event_it)->key == 130 ) {
//eye_x -= 10;
buffer << " Key press: VK_RIGHT \n";
x_angular += 2;
}
else if ( (*event_it)->key == 'i' ) {
}
else if ( (*event_it)->key == 'j' ) {
eye_x += 10;
}
else if ( (*event_it)->key == 'k' ) {
eye_x -= 10;
}
答案 0 :(得分:0)
使用矩阵乘法执行OpenGL中的平移和旋转。在您使用的固定功能管道中,这些操作不是可交换的,即[T] x [R]不等于[R] x [T]。在您的代码中,您首先进行翻译,这会改变下一轮旋转的原点。
如果仔细观察gluLookAt()的实现方式。需要反转相机转换。记住翻译和旋转将应用于对象。 OpenGL中没有相机这样的东西。我们只是通过将相机变换的逆应用于场景来模拟它。
了解这一点的唯一方法是学习OpenGL背后的数学知识。我建议找一本书。
尝试以下代码。请记住,我们正在模拟相机,因此请使用glTranslate和glRotate进行相反的操作。
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// camera transforms:
glTranslatef(-eye_x, -eye_y, -eye_z);
glRotatef(-x_angular, 0, 1, 0);
// foreach object:
glPushMatrix();
{
glTranslatef( (*obj_i)->anchor[0] , (*obj_i)->anchor[1], (*obj_i)- >anchor[2]);
glutWireSphere((*obj_i)->r, 15, 15);
}
glPopMatrix();