diff --git a/resources/shaders/phong.frag b/resources/shaders/phong.frag index 4eaed19..1d65e41 100644 --- a/resources/shaders/phong.frag +++ b/resources/shaders/phong.frag @@ -5,10 +5,10 @@ in vec3 FragPos; // in vec4 FragPosLightSpace; uniform vec3 lightPos; +uniform vec3 viewPos; out vec4 outColour; -vec3 viewPos = vec3(0.0, 0.0, 0.0); vec3 objectColour = vec3(1.0, 1.0, 1.0); vec3 lightColour = vec3(0.7, 0.3, 0.65); // vec3 lightColour = vec3(0.3, 0.85, 1.0); diff --git a/resources/shaders/phong.vert b/resources/shaders/phong.vert index 87e4784..b29ee92 100644 --- a/resources/shaders/phong.vert +++ b/resources/shaders/phong.vert @@ -1,7 +1,7 @@ #version 330 layout (location = 0) in vec3 position; -layout (location = 1)in vec3 normal; +layout (location = 1) in vec3 normal; layout (location = 2) in vec3 texCoord; out vec3 Normal; diff --git a/src/camera.cpp b/src/camera.cpp new file mode 100644 index 0000000..a97e3cd --- /dev/null +++ b/src/camera.cpp @@ -0,0 +1,88 @@ +#include "camera.h" + +Camera::Camera() { + +} + +void Camera::updateView() { + //roll can be removed from here. because is not actually used in FPS camera + glm::mat4 matRoll = glm::mat4(1.0f);//identity matrix; + glm::mat4 matPitch = glm::mat4(1.0f);//identity matrix + glm::mat4 matYaw = glm::mat4(1.0f);//identity matrix + + //roll, pitch and yaw are used to store our angles in our class + matRoll = glm::rotate(matRoll, roll, glm::vec3(0.0f, 0.0f, 1.0f)); + matPitch = glm::rotate(matPitch, pitch, glm::vec3(1.0f, 0.0f, 0.0f)); + matYaw = glm::rotate(matYaw, yaw, glm::vec3(0.0f, 1.0f, 0.0f)); + + //order matters + glm::mat4 rotate = matRoll * matPitch * matYaw; + + glm::mat4 translate = glm::mat4(1.0f); + translate = glm::translate(translate, -eyeVector); + + viewMatrix = rotate * translate; +} + +glm::mat4 Camera::getViewMatrix() { + return viewMatrix; +} + +glm::vec3 Camera::getPos() { + return eyeVector; +} + +void Camera::handleMouse(SDL_Event e) { + if (e.type != SDL_MOUSEMOTION) + return; + + + float mouseDX = e.motion.xrel; + float mouseDY = e.motion.yrel; + + glm::vec2 mouseDelta {mouseDX, mouseDY}; + + mouseMoved(mouseDelta); +} + +void Camera::moveCamera() { + float dx = 0; //how much we strafe on x + float dz = 0; //how much we walk on z + + const Uint8* state = SDL_GetKeyboardState(NULL); + + if (state[SDL_SCANCODE_W]) + dz += 2; + if (state[SDL_SCANCODE_S]) + dz += -2; + if (state[SDL_SCANCODE_A]) + dx += -2; + if (state[SDL_SCANCODE_D]) + dx += 2; + // if (state[SDL_SCANCODE_Z]) + + // if (state[SDL_SCANCODE_LSHIFT]) + + + //get current view matrix + glm::mat4 mat = getViewMatrix(); + //row major + glm::vec3 forward(mat[0][2], mat[1][2], mat[2][2]); + glm::vec3 strafe( mat[0][0], mat[1][0], mat[2][0]); + + //forward vector must be negative to look forward. + //read :http://in2gpu.com/2015/05/17/view-matrix/ + eyeVector += (-dz * forward + dx * strafe) * cameraSpeed; + + //update the view matrix + updateView(); +} + +void Camera::mouseMoved(glm::vec2 mouseDelta) { + //note that yaw and pitch must be converted to radians. + //this is done in UpdateView() by glm::rotate + yaw += mouseSensitivity * mouseDelta.x; + pitch += mouseSensitivity * mouseDelta.y; + + updateView(); +} diff --git a/src/camera.h b/src/camera.h new file mode 100644 index 0000000..e372c80 --- /dev/null +++ b/src/camera.h @@ -0,0 +1,31 @@ +#ifndef SMHENGINE_SRC_CAMERA_H_ +#define SMHENGINE_SRC_CAMERA_H_ + +#include + +#include +#include +#include + +class Camera { +public: + Camera(); + + void updateView(); + glm::mat4 getViewMatrix(); + glm::vec3 getPos(); + + void handleMouse(SDL_Event e); + void moveCamera(); + void mouseMoved(glm::vec2 mouseDelta); + + float mouseSensitivity = 0.0025f; + float cameraSpeed = 1.12f; + +private: + float roll, pitch, yaw; + glm::vec3 eyeVector; + glm::mat4 viewMatrix; +}; + +#endif diff --git a/src/display.cpp b/src/display.cpp index e837760..bb76368 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -68,6 +68,9 @@ Display::Display(std::string name, Logger& logger, int w, int h, logger << LOGGER_INFO << "Creating OpenGL context" << LOGGER_ENDL; glContext = SDL_GL_CreateContext(window); + SDL_WarpMouseInWindow(window, w / 2, h / 2); + SDL_SetRelativeMouseMode(SDL_TRUE); + // Set VSYNC swap interval if (vsyncMode == VSYNC_DEFAULT || vsyncMode == VSYNC_ENABLED) { SDL_GL_SetSwapInterval(1); @@ -84,6 +87,8 @@ Display::Display(std::string name, Logger& logger, int w, int h, gladLoadGLLoader(SDL_GL_GetProcAddress); glEnable(GL_MULTISAMPLE); glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); logger << LOGGER_INFO << "Loaded OpenGL" << LOGGER_ENDL; logger << LOGGER_ENDL; isClosed = false; @@ -161,6 +166,9 @@ Display::Display(std::string name, Logger& logger, int w, int h, logger << LOGGER_INFO << "Creating OpenGL context" << LOGGER_ENDL; glContext = SDL_GL_CreateContext(window); + SDL_WarpMouseInWindow(window, w / 2, h / 2); + SDL_SetRelativeMouseMode(SDL_TRUE); + // Set VSYNC swap interval if (vsyncMode == VSYNC_DEFAULT || vsyncMode == VSYNC_ENABLED) { SDL_GL_SetSwapInterval(1); @@ -177,6 +185,8 @@ Display::Display(std::string name, Logger& logger, int w, int h, gladLoadGLLoader(SDL_GL_GetProcAddress); glEnable(GL_MULTISAMPLE); glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); logger << LOGGER_INFO << "Loaded OpenGL" << LOGGER_ENDL; logger << LOGGER_ENDL; isClosed = false; diff --git a/src/main.cpp b/src/main.cpp index 43e2f25..620d114 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -26,6 +26,10 @@ int main (int argc, char** argv) { Display display{"SMH Engine", logger, 1280, 720, MXAA_16X, VSYNC_ENABLED}; + Camera camera; + camera.mouseSensitivity = 0.0012f; + camera.cameraSpeed = 1.0f; + Shader shader; shader.load("./resources/shaders/phong").attatch().link().use(); @@ -34,7 +38,10 @@ int main (int argc, char** argv) { SDL_Event e; while (!display.isClosed) { + + camera.moveCamera(); while (SDL_PollEvent(&e)) { + camera.handleMouse(e); if (e.type == SDL_QUIT || e.key.keysym.sym == SDLK_ESCAPE) display.isClosed = true; } @@ -50,7 +57,7 @@ int main (int argc, char** argv) { } mesh.bind(); - mesh.render(shader); + mesh.render(shader, camera);` mesh.unbind(); display.update(); diff --git a/src/mesh.cpp b/src/mesh.cpp index 8ccc7ae..accdbb1 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -87,26 +87,25 @@ void Mesh::bind() { glBindVertexArray(VAOid); } -void Mesh::render(Shader& shader) { +void Mesh::render(Shader& shader, Camera& camera) { // Model matrice glm::mat4 model = glm::mat4(1.0f); model = glm::translate(model, { -170.0f, -170.0f, -170.0f }); model = glm::rotate(model, glm::radians(-160.0f + this->rotation), glm::vec3(0.0f, 1.0f, 0.0f)); - // Gets uniform for model matrice, to be used later GLint uniTrans = glGetUniformLocation(shader.getProgram(), "model"); glUniformMatrix4fv(uniTrans, 1, GL_FALSE, glm::value_ptr(model)); - // View matrice - glm::mat4 view = glm::lookAt( - glm::vec3(1.0f, 1.0f, 1.0f), - glm::vec3(0.0f, 0.4f, 0.0f), - glm::vec3(0.0f, 1.0f, 0.0f) - ); + // // View matrice + // glm::mat4 view = glm::lookAt( + // glm::vec3(1.0f, 1.0f, 1.0f), + // glm::vec3(0.0f, 0.4f, 0.0f), + // glm::vec3(0.0f, 1.0f, 0.0f) + // ); // Get uniform and send it to the GPU GLint uniView = glGetUniformLocation(shader.getProgram(), "view"); - glUniformMatrix4fv(uniView, 1, GL_FALSE, glm::value_ptr(view)); + glUniformMatrix4fv(uniView, 1, GL_FALSE, glm::value_ptr(camera.getViewMatrix())); // Projection matrice glm::mat4 proj = glm::perspective(glm::radians(45.0f), 1280.0f / 720.0f, 1.0f, 1000.0f);//camera.perspective; @@ -115,11 +114,14 @@ void Mesh::render(Shader& shader) { glUniformMatrix4fv(uniProj, 1, GL_FALSE, glm::value_ptr(proj)); - glm::vec3 lightPos = { -2.0f, 4.0f, -1.0f }; + glm::vec3 lightPos = { -270.0f, -270.0f, -1.0f }; - GLint uniLight = glGetUniformLocation(shader.getProgram(), "lightpos"); + GLint uniLight = glGetUniformLocation(shader.getProgram(), "lightPos"); glUniformMatrix3fv(uniLight, 1, GL_FALSE, glm::value_ptr(lightPos)); + GLint uniCamPos = glGetUniformLocation(shader.getProgram(), "viewPos"); + glUniformMatrix3fv(uniLight, 1, GL_FALSE, glm::value_ptr(camera.getPos())); + glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0); } diff --git a/src/mesh.h b/src/mesh.h index 5530aec..47c4dff 100644 --- a/src/mesh.h +++ b/src/mesh.h @@ -13,6 +13,7 @@ #include #include +#include "camera.h" #include "shader.h" #include "./util/util.h" @@ -44,7 +45,7 @@ public: void setup(); void bind(); - void render(Shader& shader); + void render(Shader& shader, Camera& camera); static void unbind(); GLuint VAOid;