我试图在opengl中制作飞行模拟器,但我无法让我的相机正确地跟随飞机。我认为,如果我在相机和飞机上应用相同的变换集合它会起作用但它不会。当我说变换时,我正在谈论使用髓的旋转和偏航角(我暂时忽略了滚动角)以及移动飞机所需的平移。 这是我的Camera类:
namespace gps {
Camera::Camera(glm::vec3 cameraPosition, glm::vec3 cameraTarget)
{
this->cameraPosition = cameraPosition;
this->cameraTarget = cameraTarget;
this->cameraDirection = glm::normalize(cameraTarget - cameraPosition);
this->cameraRightDirection = glm::normalize(glm::cross(this->cameraDirection, glm::vec3(0.0f, 1.0f, 0.0f)));
}
glm::mat4 Camera::getViewMatrix()
{
return glm::lookAt(cameraPosition, cameraPosition + cameraDirection , glm::vec3(0.0f, 1.0f, 0.0f));
}
glm::vec3 Camera::getCameraPosition()
{
return cameraPosition;
}
void Camera::move(MOVE_DIRECTION direction, float speed)
{
switch (direction) {
case MOVE_FORWARD:
cameraPosition += cameraDirection * speed;
break;
case MOVE_BACKWARD:
cameraPosition -= cameraDirection * speed;
break;
case MOVE_RIGHT:
cameraPosition += glm::normalize(glm::cross(cameraDirection, glm::vec3(0.0f, 1.0f, 0.0f))) * speed;
break;
case MOVE_LEFT:
cameraPosition -= glm::normalize(glm::cross(cameraDirection, glm::vec3(0.0f, 1.0f, 0.0f))) * speed;
break;
}
}
void Camera::rotate(float pitch, float yaw)
{
glm::vec3 front;
front.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch));
front.y = sin(glm::radians(pitch));
front.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch));
cameraDirection = glm::normalize(front);
}
}
我创建了2个摄像头:一个应该跟随飞机,另一个应该在飞机上应用这组变换。
gps::Camera myCamera(glm::vec3(0.0f, 0.0f, 2.5f), glm::vec3(0.0f, 0.0f, -10.0f));
gps::Camera planeCamera(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -10.0f));
这是我的renderScene函数:
void renderScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
processMovement();
//initialize the view matrix
view = myCamera.getViewMatrix();
//send view matrix data to shader
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
//plane
model = glm::mat4(1.0f);
model = planeCamera.getViewMatrix();
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
normalMatrix = glm::mat3(glm::inverseTranspose(view*model));
//send normal matrix data to shader
glUniformMatrix3fv(normalMatrixLoc, 1, GL_FALSE, glm::value_ptr(normalMatrix));
planeModel.Draw(myCustomShader);
}
processMovement是这样的:
void processMovement()
{
if (pressedKeys[GLFW_KEY_W]) {
myCamera.move(gps::MOVE_FORWARD, cameraSpeed);
planeCamera.move(gps::MOVE_BACKWARD, cameraSpeed);
}
if (pressedKeys[GLFW_KEY_S]) {
myCamera.move(gps::MOVE_BACKWARD, cameraSpeed);
planeCamera.move(gps::MOVE_FORWARD, cameraSpeed);
}
...
}
这些是我的模型,视图,投影矩阵:
model = glm::mat4(1.0f);
modelLoc = glGetUniformLocation(myCustomShader.shaderProgram, "model");
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
view = myCamera.getViewMatrix();
viewLoc = glGetUniformLocation(myCustomShader.shaderProgram, "view");
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
normalMatrix = glm::mat3(glm::inverseTranspose(view*model));
normalMatrixLoc = glGetUniformLocation(myCustomShader.shaderProgram, "normalMatrix");
glUniformMatrix3fv(normalMatrixLoc, 1, GL_FALSE, glm::value_ptr(normalMatrix));
projection = glm::perspective(glm::radians(45.0f), (float)retina_width / (float)retina_height, 0.1f, 1000.0f);
projectionLoc = glGetUniformLocation(myCustomShader.shaderProgram, "projection");
glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection));