PDA

View Full Version : Camera not rotation



tritZium
03-10-2015, 09:07 AM
Hello!

I'm following the tutorial at learnopengl.com but I can't get my camera to rotate. I did it slightly differenly to the tutorial so I'll drop the code here.
The pitch goes up like crazy here's the yaw and pitch values outputted from the console -90, 6.94683e+06. The meshes also dissapper whenever moving my mouse more then 10cm and then they come back when I move it back. I also can't translate the camera because it dissapers there as well. I have to be very close to the exact middle. Why?

Main

#define GLEW_STATIC
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <memory>

#include <SOIL/SOIL.h>

#define GLM_FORCE_RADIANS
#include <GL/glew.h>
#include <SDL2/SDL.h>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

bool keys[1024];
GLfloat deltaTime = 0.0f;
GLfloat lastFrame = 0.0f;
GLfloat lastX = 400;
GLfloat lastY = 300;
GLfloat pitch = 0, yaw = -90.0f;
bool firstMouse = true;
#include "../include/OGRenderer.h"
#include "../include/mesh.h"
#include "../include/Camera.h"

//Add the include var
#define PROGRAMNAME "OPENGL!!!!"

std::string readFile(std::string path){
std::string content;
std::ifstream fileStream(path, std::ios::in);
if(!fileStream.is_open()){
std::cout << "Shader failed to open\n";
return "";
}
std::string line;
while(!fileStream.eof()){
std::getline(fileStream, line);
content.append(line + "\n");
}
fileStream.close();
return content;
}


void loadImage(const char* path, GLint curTex, GLuint textureArray[]){
int width, height;
glBindTexture(GL_TEXTURE_2D, textureArray[curTex]);
unsigned char* image = SOIL_load_image(path, &width, &height, 0, SOIL_LOAD_RGB);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
SOIL_free_image_data(image);
}

void doMovement(Camera &camera);
bool handleInput(SDL_Event &windowEvent, Camera &camera);
GLuint createShaders(std::string vertexShaderPath, std::string fragmentShaderPath);
void setupShaderVariables(GLint shaderProgram);

int main() {

int screenHeight = 512, screenWidht = 512;
OGRenderer render(3,0,1,24);
glewExperimental = GL_TRUE;
glewInit();

/*std::vector<GLfloat> vertices = {
// Position Color Texcoords
-0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // Top-left
0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // Top-right
0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // Bottom-right
-0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f // Bottom-left
};*/

//SDL_SetRelativeMouseMode(SDL_TRUE);
glEnable(GL_DEPTH_TEST);

std::vector<GLfloat> vertices = {
// Position Texcoords
-1.0f, 1.0f, 0.5f, 0.0f, 0.0f, // Top-left
0.0f, 1.0f, 0.5f, 1.0f, 0.0f, // Top-right
0.0f, -0.0f, 0.5f, 1.0f, 1.0f, // Bottom-right
-1.0f, -0.0f, 0.5f, 0.0f, 1.0f, // Bottom-left

-1.0f, 1.0f, -0.5f, 1.0f, 0.0f, // Top-left
0.0f, 1.0f, -0.5f, 0.0f, 0.0f, // Top-right
0.0f, -0.0f, -0.5f, 0.0f, 1.0f, // Bottom-right
-1.0f, -0.0f, -0.5f, 1.0f, 1.0f // Bottom-left

};

std::vector<GLuint> elements = {
0, 1, 2, //Front
2, 3, 0, //Front
2, 3, 7, //Bottom
2, 7, 6, //Bottom
0, 3, 4, //Left
3, 4, 7, //Left
4, 7, 5, //Back
5, 7, 6, //Back
1, 5, 6, //Right
1, 2, 6, //Right
0, 1, 4, //Top
1, 4, 5//Top
};

std::vector<glm::vec3> cubePositions = {
glm::vec3( 0.0f, 0.0f, 0.0f),
glm::vec3( 2.0f, 5.0f, -15.0f),
glm::vec3(-1.5f, -2.2f, -2.5f),
glm::vec3(-3.8f, -2.0f, -12.3f),
glm::vec3( 2.4f, -0.4f, -3.5f),
glm::vec3(-1.7f, 3.0f, -7.5f),
glm::vec3( 1.3f, -2.0f, -2.5f),
glm::vec3( 1.5f, 2.0f, -2.5f),
glm::vec3( 1.5f, 0.2f, -1.5f),
glm::vec3(-1.3f, 1.0f, -1.5f)
};


//Load shaders
GLuint shaderProgram = createShaders("vertexShader.glsl", "fragmentShader.glsl");
//Shaders have been loaded


std::vector<std::shared_ptr<mesh>> cubes;

for(GLuint i = 0; i < 10; i++){
std::shared_ptr<mesh> newMesh = std::make_shared<mesh>();
newMesh->initMesh(vertices, elements, shaderProgram);
newMesh->Translate(cubePositions[i]);
newMesh->Rotate(glm::vec3(1.0f, 0.3f, 0.5f), 300.0f * i);
cubes.push_back(newMesh);
}
//For stroing textures
GLuint textures[2];
glGenTextures(2, textures);
glActiveTexture(GL_TEXTURE0);
loadImage("CAT.jpg", 0, textures);
glUniform1i(glGetUniformLocation(shaderProgram, "tex"), 0);
glActiveTexture(GL_TEXTURE1);
loadImage("TW.png", 1, textures);
glUniform1i(glGetUniformLocation(shaderProgram, "tex2"), 1);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

std::cout << glGetString(GL_VERSION) << std::endl;

Camera camera(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f));


GLint time = glGetUniformLocation(shaderProgram, "time");
SDL_Event windowEvent;
bool quit = false;
while(!quit){
GLfloat currentFrame = SDL_GetTicks();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;

quit = handleInput(windowEvent, camera);
doMovement(camera);

glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glUniform1f(time, (float)clock() / (float)CLOCKS_PER_SEC);

glm::mat4 trans;
glm::mat4 view;
glm::mat4 projection;
float radius = 10.0f;
//camera.Translate(glm::vec3(glm::sin(((float)clock( ) / (float)CLOCKS_PER_SEC) * 9.0f) * radius, 0.0f, glm::cos(((float)clock() / (float)CLOCKS_PER_SEC) * 9.0f) * radius));
view = camera.getViewVector();
projection = glm::perspective(45.0f, (GLfloat)screenWidht / (GLfloat)screenHeight, 0.1f, 100.0f);


glUniformMatrix4fv(glGetUniformLocation(shaderProg ram, "view"), 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(glGetUniformLocation(shaderProg ram, "projection"), 1, GL_FALSE, glm::value_ptr(projection));

for(GLuint i = 0; i < 10; i++){
cubes[i]->render();
}

render.update();
}
glDeleteTextures(2, textures);

glDeleteProgram(shaderProgram);
return 0;
}

GLuint createShaders(std::string vertexShaderPath, std::string fragmentShaderPath){
//Load the shader sources
std::string vertexSource = readFile(vertexShaderPath);
std::string fragmentSource = readFile(fragmentShaderPath);
//Convert them to a c-style string
const char *vertShaderSrc = vertexSource.c_str();
const char *fragShaderSrc = fragmentSource.c_str();

GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertShaderSrc, NULL);
glCompileShader(vertexShader);

//Check so the shader was compiled succesfully
GLint status;
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status);
char buffer[512];
glGetShaderInfoLog(vertexShader, 512, NULL, buffer);
std::cout << buffer << std::endl;
if(status != true){
std::cout << "The vertexShader was not compiled succesfully\n";
exit(-1);
}
//Check so the shader was compiled succesfully

GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragShaderSrc, NULL);
glCompileShader(fragmentShader);


glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &status);
glGetShaderInfoLog(fragmentShader, 512, NULL, buffer);
std::cout << buffer << std::endl;
if(status != true){
std::cout << "The fragmentShader was not compiled succesfully\n";
exit(-1);
}

GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);

glDeleteShader(fragmentShader);
glDeleteShader(vertexShader);

return shaderProgram;
}


bool handleInput(SDL_Event &windowEvent, Camera &camera){
while(SDL_PollEvent(&windowEvent)){
if(windowEvent.type == SDL_QUIT || (windowEvent.type == SDL_KEYUP && windowEvent.key.keysym.sym == SDLK_ESCAPE)){
return true;
break;
}
switch(windowEvent.type){
case SDL_KEYDOWN:
//std::cout << windowEvent.key.keysym.sym <<std::endl;
keys[windowEvent.key.keysym.sym] = true;
break;
case SDL_KEYUP:
keys[windowEvent.key.keysym.sym] = false;
break;
default:
break;
}
if(firstMouse){
lastX = windowEvent.motion.x;
lastY = windowEvent.motion.y;
firstMouse = false;
}
//std::cout << lastX << ", " << lastY << std::endl;
camera.processMouseMovement(windowEvent.motion.xre l, windowEvent.motion.yrel);
}
return false;
}

void doMovement(Camera &camera){
GLfloat cameraSpeed = 0.005f * deltaTime;
if(keys[SDLK_w]){
camera.Translate(glm::vec3(0.0f, 0.0f, -1.0f) * cameraSpeed);
}
if(keys[SDLK_s]){
camera.Translate(glm::vec3(0.0f, 0.0f, 1.0f) * cameraSpeed);
}
if(keys[SDLK_a]){
camera.Translate(glm::vec3(-1.0f, 0.0f, 0.0f) * cameraSpeed);
}
if(keys[SDLK_d]){
camera.Translate(glm::vec3(1.0f, 0.0f, 0.0f) * cameraSpeed);
}
/* if(keys[SDLK_LSHIFT]){
camera.Translate(glm::vec3(0.0f, 1.0f, 0.0f) * cameraSpeed);
}
if(keys[SDLK_SPACE]){
camera.Translate(glm::vec3(0.0f, -1.0f, 0.0f) * cameraSpeed);
}*/
}


Camera:

.cpp


#include "Camera.h"

Camera::Camera(glm::vec3 cameraPos, glm::vec3 cameraFront, glm::vec3 worldUp, GLfloat sensitivity, GLfloat yaw, GLfloat pitch)
{
this->sensitivity = sensitivity;
this->yaw = yaw;
this->pitch = pitch;
this->cameraPos = cameraPos;
//this-> cameraFront = cameraFront;
this->worldUp = worldUp;

updateCameraViewVector();
//ctor
}

Camera::~Camera()
{
//dtor
}

glm::mat4x4 Camera::getViewVector(){
return view;
}

void Camera::Translate(glm::vec3 addVector){
cameraPos += addVector;
updateCameraViewVector();
}

void Camera::Rotate(glm::vec3 rotVector){
cameraFront = glm::normalize(rotVector);
//std::cout << cameraFront.x << ", " << cameraFront.y << ", " << cameraFront.z << std::endl;
updateCameraViewVector();
}

void Camera::processMouseMovement(GLfloat xoffset, GLfloat yoffset, GLboolean constrainPitch){
xoffset *= sensitivity;
yoffset *= sensitivity;

yaw += xoffset;
pitch += yoffset;
std::cout << yaw << ", " << pitch << std::endl;
updateCameraViewVector();
}
void Camera::updateCameraViewVector(){
glm::vec3 front;

front.x = glm::cos(glm::radians(yaw)) * glm::cos(glm::radians(pitch));
front.y = glm::sin(glm::radians(pitch));
front.z = glm::sin(glm::radians(yaw)) * glm::radians(glm::radians(pitch));

cameraFront = glm::normalize(front);
cameraRight = glm::normalize(glm::cross(cameraFront, worldUp));
cameraUp = glm::normalize(glm::cross(cameraRight, cameraFront));
//std::cout << cameraFront.x << ", " << cameraFront.y << ", " << cameraFront.z << std::endl;
view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp);

}


.h


#ifndef CAMERA_H
#define CAMERA_H

#include <iostream>

#include <SDL2/SDL.h>
#include <GL/glew.h>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

class Camera
{
public:
Camera(glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3 worldUp = glm::vec3(0.0f, 1.0f, 0.0f), GLfloat sensitivity = 0.5f, GLfloat yaw = -90.0f, GLfloat pitch = 0.0f);
~Camera();
glm::mat4x4 getViewVector();
void Translate(glm::vec3 addVector);
void Rotate(glm::vec3 rotVector);
void processMouseMovement(GLfloat xoffset, GLfloat yoffset, GLboolean constrainPitch = true);
protected:
private:
GLfloat pitch;
GLfloat yaw;
GLfloat sensitivity;

glm::vec3 cameraPos;
glm::vec3 cameraFront;
glm::vec3 cameraUp;
glm::vec3 cameraRight;
glm::vec3 worldUp;

glm::vec3 up;
glm::mat4x4 view;
glm::mat4x4 transform;

void updateCameraViewVector();

};

#endif // CAMERA_H


I have no idea what could be causing this, so thank you for your help! :)

EDIT: just saw my title is all wrong xD.
Sorry about that :/

TheGLJ
03-13-2015, 09:47 AM
Hi,

in my projects, I don't use glm::lookAt anymore, instead I rotate the view matrix around the x- and y-axis:


void Camera::processMouseMovement(GLfloat xoffset, GLfloat yoffset, GLboolean constrainPitch)
{
yaw -= sensitivity * xoffset;
pitch -= sensitivity * yoffset;
if(yaw < 0.0f)
yaw += 360.0f;
else if(yaw > 360.0f)
yaw -= 360.0f;
if(pitch > 90.0f)
pitch = 90.0f;
else if(pitch < -90.0f)
pitch = -90.0f;
updateCameraViewVector();
}

void Camera::updateCameraViewVector() //shouldn't it be called "updateCameraViewMatrix()"? (it updates the glm::mat4 view)
{
view = glm::mat4(1.0f);
view = glm::rotate(view, (float)-(pitch*(M_PI/180.0)), glm::vec3(1, 0, 0));
view = glm::rotate(view, (float)-(yaw*(M_PI/180.0)), glm::vec3(0, 1, 0));
view = glm::translate(view, -cameraPos);
}


I hope, this helps :)

cod999
03-19-2015, 08:21 PM
void Camera::updateCameraViewVector() //shouldn't it be called "updateCameraViewMatrix()"? (it updates the glm::mat4 view)
{
view = glm::mat4(1.0f);
view = glm::rotate(view, (float)-(pitch*(M_PI/180.0)), glm::vec3(1, 0, 0));
view = glm::rotate(view, (float)-(yaw*(M_PI/180.0)), glm::vec3(0, 1, 0));
view = glm::translate(view, -cameraPos);
}



I have a question which is why you convert the pitch and yaw into radian because i thought glm uses degrees as argument? and does this method remain smooth transition when the user rotates mouse very quickly?

TheGLJ
03-24-2015, 09:59 AM
I am quite used to radians, so I defined GLM_FORCE_RADIANS at the beginning of my code, but of course you don't have to use it (just delete the (M_PI/180.0)'s). And it should remain smooth when you have enough frames per second in your main program (in my programs, where I use this code, the camera works quite well).