试图实现相机

时间:2014-12-27 23:54:14

标签: c++ opengl camera glsl shader

我正在尝试实施一个Camera课程,以便我可以按照以下步骤查看世界:

#ifndef _CAMERA_H_
#define _CAMERA_H_

#include <glm\glm.hpp>

class Camera
{
public:
    Camera();
    ~Camera();

    void Update(const glm::vec2& newXY);
    //if by = 0.0 it means, it will use the const Class speed to scale it
    void MoveForward(const float by = 0.0f);
    void MoveBackword(const float by = 0.0f);
    void MoveLef(const float by = 0.0f);
    void MoveRight(const float by = 0.0f);
    void MoveUp(const float by = 0.0f);
    void MoveDown(const float by = 0.0f);
    void Speed(const float speed = 0.0f);

    glm::vec3& GetCurrentPosition();
    glm::vec3& GetCurrentDirection();
    glm::mat4 GetWorldToView() const;
private:
    glm::vec3 position, viewDirection, strafeDir;
    glm::vec2 oldYX;

    float speed;
    const glm::vec3 up;
};

#endif

#include "Camera.h"
#include <glm\gtx\transform.hpp>

Camera::Camera()
    :up(0.0f, 1.0f, 0.0), viewDirection(0.0f, 0.0f, -1.0f),
    speed(0.1f)
{
}


Camera::~Camera()
{
}


void Camera::Update(const glm::vec2& newXY)
{
    glm::vec2 delta = newXY - oldYX;
    auto length = glm::length(delta);
    if (glm::length(delta) < 50.f)
    {
        strafeDir = glm::cross(viewDirection, up);
        glm::mat4 rotation = glm::rotate(-delta.x * speed, up) *
            glm::rotate(-delta.y * speed, strafeDir);

        viewDirection = glm::mat3(rotation) * viewDirection;
    }

    oldYX = newXY;
}

void Camera::Speed(const float speed)
{
    this->speed = speed;
}

void Camera::MoveForward(const float by)
{
    float s = by == 0.0f ? speed : by;

    position += s * viewDirection;
}
void Camera::MoveBackword(const float by)
{
    float s = by == 0.0f ? speed : by;

    position += -s * viewDirection;
}
void Camera::MoveLef(const float by )
{
    float s = by == 0.0f ? speed : by;
    position += -s * strafeDir;
}
void Camera::MoveRight(const float by )
{
    float s = by == 0.0f ? speed : by;
    position += -s * strafeDir;
}
void Camera::MoveUp(const float by )
{
    float s = by == 0.0f ? speed : by;
    position += s * up;
}
void Camera::MoveDown(const float by )
{
    float s = by == 0.0f ? speed : by;
    position += -s * up;
}

glm::vec3& Camera::GetCurrentPosition()
{
    return position;
}
glm::vec3& Camera::GetCurrentDirection()
{
    return viewDirection;
}

glm::mat4 Camera::GetWorldToView() const
{
    return glm::lookAt(position, position + viewDirection, up);
}

我更新并呈现如下:

void Game::OnUpdate()
{
    glLoadIdentity();
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


    glUniformMatrix4fv(program->GetUniformLocation("modelToViewWorld"), 1, GL_FALSE, &cam.GetWorldToView()[0][0]);

}

void Game::OnRender()
{

    model->Draw();

}

顶点着色器的外观如下:

#version 410

layout (location = 0) in vec3 inVertex;
layout (location = 1) in vec2 inTexture;
layout (location = 2) in vec3 inNormal;

uniform mat4 modelToViewWorld;


void main()
{
        gl_Position    = vec4(mat3(modelToViewWorld) * inVertex, 1);

}

但我正在移动/旋转模型本身,而不是围绕它的相机。我在这里做错了什么?

2 个答案:

答案 0 :(得分:0)

我认为问题在于你没有反转视图矩阵。模型 - 视图矩阵仅是模型 - >世界坐标矩阵变换和世界 - >视图坐标矩阵变换的乘积。第一个采用局部模型空间中的坐标并将它们转换为世界空间,因此不需要反转。然而,第二个采用相机在世界空间中的坐标并将它们转换为相机的局部坐标系,因为它与第一个相反,需要反转。

答案 1 :(得分:0)

您正在旋转模型,而不是旋转视图方向。

viewDirection = glm::mat3(rotation) * viewDirection;

您要做的是围绕物体旋转相机的中心,然后将相机的方向设置为物体。

例如:

position = vec3( radius * cos(t), radius * sin(t), 0);
direction = normalize(-position);