【发布时间】:2012-08-27 08:40:43
【问题描述】:
我有一个相机类,它是这样初始化的:
CameraFP::CameraFP() {
this->aspect_ratio = 800.0f / 600.0f;
this->fov = 45.0f;
this->near_plane = 0.1f;
this->far_plane = 1000.0f;
this->position = glm::vec3(0, 0, 0);
this->target = position + glm::vec3(0, 0, -1);
this->up = glm::vec3(0, 1, 0);
this->m_rotation = glm::mat4(1.0);
m_view = glm::lookAt(position, target, up);
m_projection = glm::perspective(fov, aspect_ratio, near_plane, far_plane);
}
还有其他导入功能:
void CameraFP::update(sf::Window *app) {
process_keyboard(app);
process_mouse(app);
calculate_view();
}
void CameraFP::process_keyboard(sf::Window *app) {
const sf::Input *input = &app->GetInput();
up = m_rotation * glm::vec3(0, 1, 0);
glm::vec3 forward = glm::vec3(0, 0, -1);
glm::vec3 forward_rotated = m_rotation * forward;
glm::vec3 right = glm::vec3(1, 0, 0);
glm::vec3 right_rotated = m_rotation * right;
if (input->IsKeyDown(sf::Key::W)) {
position += forward_rotated;
}
if (input->IsKeyDown(sf::Key::S)) {
position -= forward_rotated;
}
if (input->IsKeyDown(sf::Key::A)) {
position -= right_rotated;
}
if (input->IsKeyDown(sf::Key::D)) {
position += right_rotated;
}
}
void CameraFP::process_mouse(sf::Window *app) {
// TODO: Make the below constants, and take framerate into account
GLfloat SPEED_X = 0.000001f;
GLfloat SPEED_Y = 0.000001f;
GLfloat mouse_x = app->GetInput().GetMouseX();
GLfloat mouse_y = app->GetInput().GetMouseY();
GLfloat mouse_x_delta = old_mouse_x - mouse_x;
GLfloat mouse_y_delta = old_mouse_y - mouse_y;
if (mouse_x_delta != 0 ||
mouse_y_delta != 0) {
if (mouse_x_delta != 0) {
y_rot += mouse_x_delta * SPEED_X;
m_rotation = glm::rotate(m_rotation, y_rot, glm::vec3(0, 1, 0));
}
if (mouse_y_delta != 0) {
x_rot += mouse_y_delta * SPEED_Y;
m_rotation = glm::rotate(m_rotation, x_rot, glm::vec3(1, 0, 0));;
}
}
this->old_mouse_x = mouse_x;
this->old_mouse_y = mouse_y;
app->SetCursorPosition(app->GetWidth() / 2, app->GetHeight() / 2);
}
void CameraFP::calculate_view() {
glm::vec3 forward = glm::vec3(0, 0, -1);
glm::vec3 forward_rotated = m_rotation * forward;
target = position += glm::normalize(forward_rotated);
m_view = glm::lookAt(position, target, up);
}
我的问题是,当我编译项目时,编译器输出一个错误说:
\CameraFP.cpp|59|error: no match for 'operator*' in '((CameraFP*)this)->CameraFP::m_rotation * glm::detail::tvec3<float>(((const int&)((const int*)(&0))), ((const int&)((const int*)(&1))), ((const int&)((const int*)(&0))))'|
据我了解 vec = mat4 * vec 应该产生一个旋转向量?由于无法测试这段代码,不知道功能是否正常。
编辑
根据 cmets 和 awnsers 更新了代码。我现在的问题是我在渲染函数的某个地方得到了一个 BSOD...
void CameraFP::process_keyboard(sf::Window *app) {
const sf::Input *input = &app->GetInput();
up = m_rotation * glm::vec4(0.0f, 1.0f, 0.0f, 0.0f);
glm::vec4 forward = glm::vec4(0.0f, 0.0f, -1.0f, 0.0f);
glm::vec4 forward_rotated = m_rotation * forward;
glm::vec4 right = glm::vec4(1.0f, 0.0f, 0.0f, 0.0f);
glm::vec4 right_rotated = m_rotation * right;
if (input->IsKeyDown(sf::Key::W)) {
position += forward_rotated;
}
if (input->IsKeyDown(sf::Key::S)) {
position -= forward_rotated;
}
if (input->IsKeyDown(sf::Key::A)) {
position -= right_rotated;
}
if (input->IsKeyDown(sf::Key::D)) {
position += right_rotated;
}
}
void CameraFP::process_mouse(sf::Window *app) {
// TODO: Make the below constants, and take framerate into account
GLfloat SPEED_X = 0.000001f;
GLfloat SPEED_Y = 0.000001f;
GLfloat mouse_x = app->GetInput().GetMouseX();
GLfloat mouse_y = app->GetInput().GetMouseY();
GLfloat mouse_x_delta = old_mouse_x - mouse_x;
GLfloat mouse_y_delta = old_mouse_y - mouse_y;
if (mouse_x_delta != 0 ||
mouse_y_delta != 0) {
if (mouse_x_delta != 0) {
y_rot += mouse_x_delta * SPEED_X;
m_rotation = glm::rotate(m_rotation, y_rot, glm::vec3(0.0f, 1.0f, 0.0f));
}
if (mouse_y_delta != 0) {
x_rot += mouse_y_delta * SPEED_Y;
m_rotation = glm::rotate(m_rotation, x_rot, glm::vec3(1.0f, 0.0f, 0.0f));;
}
}
this->old_mouse_x = mouse_x;
this->old_mouse_y = mouse_y;
app->SetCursorPosition(app->GetWidth() / 2, app->GetHeight() / 2);
}
void CameraFP::calculate_view() {
glm::vec4 forward = glm::vec4(0.0f, 0.0f, -1.0f, 0.0f);
glm::vec4 forward_rotated = m_rotation * forward;
target = position += forward_rotated;
m_view = glm::lookAt(v4tov3(position), v4tov3(target), v4tov3(up));
}
glm::vec3 v4tov3(glm::vec4 v1) {
return glm::vec3(v1.x, v1.y, v1.z);
}
编辑 2
现在的问题是用鼠标旋转相机,它只是不起作用,由于某种原因,x 轴上的变化经常影响 y 轴上的变化,反之亦然。此外,如果我在 x 轴(y 旋转)上向右或向左移动鼠标,相机将向左旋转...
void CameraFP::process_mouse(sf::Clock *clock, sf::Window *app) {
// TODO: Make the below constants, and take framerate into account
GLfloat SPEED_X = 0.25f;
GLfloat SPEED_Y = 0.25f;
GLfloat screen_x = app->GetWidth();
GLfloat screen_y = app->GetHeight();
GLfloat mouse_x = float(screen_x / 2 - app->GetInput().GetMouseX());
GLfloat mouse_y = float(screen_y / 2 - app->GetInput().GetMouseY());
GLfloat mouse_x_delta = old_mouse_x - mouse_x;
GLfloat mouse_y_delta = old_mouse_y - mouse_y;
GLfloat current_time = clock->GetElapsedTime();
GLfloat delta_time = current_time - last_time;
this->last_time = current_time;
if (mouse_x_delta != 0 ||
mouse_y_delta != 0) {
if (mouse_x_delta != 0) {
y_rot += glm::radians(delta_time * SPEED_X * mouse_x);
m_rotation = glm::rotate(m_rotation, y_rot, glm::vec3(0.0f, 1.0f, 0.0f));
std::cout << "Y Rotation: " << y_rot << "\n";
}
if (mouse_y_delta != 0) {
x_rot += glm::radians(delta_time * SPEED_Y * mouse_y);
m_rotation = glm::rotate(m_rotation, x_rot, glm::vec3(1.0f, 0.0f, 0.0f));
std::cout << "X rotation: " << x_rot << "\n";
}
}
app->SetCursorPosition(screen_x / 2, screen_y / 2);
this->old_mouse_x = float(screen_x / 2 - app->GetInput().GetMouseX());
this->old_mouse_y = float(screen_y / 2 - app->GetInput().GetMouseY());
}
【问题讨论】:
-
未找到 mat4*vec3 的运算符 *。
m_rotation是mat4,forward是vec3。我认为应该是vec4。 -
@AquilaRapax 但是,我不是打算将位置表示为 vec3s 吗?我认为我不应该一直在 glm::vec3 和 glm::vec4 之间进行转换。我应该使用 glm::mat3 来表示我的旋转吗?
-
通常使用齐次坐标,因此所有向量和矩阵的维度都是 4。对于向量,最后一个坐标称为
w-coordinate 并且必须为 1。所以你不需要将 vec3 转换为 vec4。只需使用 vec4 并将第 4 个坐标设置为 1。有关更多信息,请查看 en.wikipedia.org/wiki/Homogeneous_coordinates
标签: c++ opengl matrix camera glm-math