Advertisement

Trying to implement Camera

Started by December 27, 2014 09:43 PM
2 comments, last by Satharis 10 years ago

what am trying to do is implementing Camera calss so I can walk and look on the world as follow:


#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);
}

and I update and render as follow :


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();

}

where the Vertix shader:


#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);
    
}

but what is happening is am moving/rotating the Model it's self not the camrea around it . what am doing wrong here?

Hello Mr_PoP,

This article explains the subject very well:

http://nehe.gamedev.net/article/camera_class_tutorial/18010/

Also have a look at the camera code in your favorite fps.

Regards

Henry

Advertisement

Just the things that looked odd:

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

Thats not how that works, you should convert the inVertex to a vec4 with 1.0 in its 'w' component, then multiply it by the full mat4 modelToViewWorld. Otherwise you're just throwing away translation.

glLoadIdentity();

glLoadIdentity, while using OpenGL 4 and GLM? Why? Leave that cruft away.

From an "aesthetic" point of view, maybe someone will disagree with me in this but this is how I see it: You're mixing two things here, the camera and movement.

As far as I see it, Camera class shouldn't move at all, Camera should able to fetch the facing direction + of the entity its attached to and compute a view matrix out of that, but thats it. Whatever moves the entity is something else, an input controller with movement action mappings probably, point being, in another class (or classes).

Mainly because it doesn't makes sense to implement movement behavior for entities that don't have a camera and reimplement the same behavior again for entities that do have a camera. Those two aspects should be separated. Movement could pretty much be handled the same way across different entities (or game objects, or whatever you use).

"I AM ZE EMPRAH OPENGL 3.3 THE CORE, I DEMAND FROM THEE ZE SHADERZ AND MATRIXEZ"

My journals: dustArtemis ECS framework and Making a Terrain Generator

TheChubu has the right idea IMO, even taking 'aesthetics' into consideration, you're talking about the fact that in a 3D game the camera will have to say, react with the terrain. Reacting with terrain or other objects means the camera then has to have knowledge about things like collision, or gravity, or what things are affecting the character and their jump height. Even if the camera isn't connected to an "entity" per se, the camera likely shouldn't be making any decisions about -where- it moves, it should simply be in charge of repositioning itself to where it is asked to. Its mostly a problem of code logic, the camera has to be 'aware' either directly or indirectly of where it can be moved to. Otherwise we'll just go right through walls and the ground!

This topic is closed to new replies.

Advertisement