Added camera controller class

pull/4/head
E. Almqvist 2 years ago
parent a2cc45117d
commit 1e66e3e6ac
  1. 21
      headers/controller.hpp
  2. 27
      headers/renderer.hpp
  3. 70
      src/controller.cpp
  4. 112
      src/main.cpp
  5. 30
      src/renderer.cpp

@ -1,12 +1,23 @@
#pragma once #pragma once
#include "glm/fwd.hpp"
#include "renderer.hpp" #include "renderer.hpp"
#include "GLFW/glfw3.h" #include "GLFW/glfw3.h"
class Controller { #define CAM_MAX_ANGLE 89.99f
Controller(GLFWwindow* win);
Controller(GLFWwindow* win, Renderer::Camera cam);
protected: class Controller : public Renderer::Camera {
Renderer::Camera cam; public:
using Renderer::Camera::Camera;
float sensitivity = 0.04f;
void processInput(float deltaTime);
private:
float pitch, yaw;
double lastX, lastY;
bool firstMouseInput = true;
void processMouseInput(float deltaTime);
}; };

@ -18,8 +18,6 @@
#define NEAR_PLANE 0.1f #define NEAR_PLANE 0.1f
#define FAR_PLANE 100.0f #define FAR_PLANE 100.0f
#define CAM_SPEED 0.05f
namespace Renderer { namespace Renderer {
class Object { class Object {
public: public:
@ -35,6 +33,7 @@ namespace Renderer {
void setRotation(glm::vec3 angle); void setRotation(glm::vec3 angle);
void rotate(glm::vec3 dangle); void rotate(glm::vec3 dangle);
protected: protected:
void updatePositionTransform(); void updatePositionTransform();
void updateRotationTransform(); void updateRotationTransform();
@ -42,25 +41,26 @@ namespace Renderer {
glm::mat4 positionTransform = glm::mat4(1.0f); glm::mat4 positionTransform = glm::mat4(1.0f);
glm::mat4 rotationTransform = glm::mat4(1.0f); glm::mat4 rotationTransform = glm::mat4(1.0f);
glm::mat4 modelTransform = glm::mat4(1.0f); glm::mat4 modelTransform = glm::mat4(1.0f);
glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f); glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f);
glm::vec3 angle = glm::vec3(0.0f, 0.0f, 0.0f); glm::vec3 angle = glm::vec3(0.0f, 0.0f, 0.0f);
}; };
class Camera : public Object { class Camera : public Object {
public:
glm::mat4 projection = glm::mat4(1.0f);
glm::mat4 view = glm::mat4(1.0f);
Camera(GLFWwindow* win); Camera(GLFWwindow* win);
Camera(GLFWwindow* win, glm::vec3 pos); Camera(GLFWwindow* win, glm::vec3 pos);
Camera(GLFWwindow* win, glm::vec3 pos, glm::vec3 angle); Camera(GLFWwindow* win, glm::vec3 pos, glm::vec3 angle);
public:
void setFOV(float deg); void setFOV(float deg);
void pointAt(glm::vec3 target); protected:
glm::mat4 projection = glm::mat4(1.0f);
glm::mat4 view = glm::mat4(1.0f);
private:
GLFWwindow* window; GLFWwindow* window;
// glm::vec3 front = glm::vec3(0.0f, 0.0f, -1.0f); glm::vec3 front = glm::vec3(0.0f, 0.0f, 1.0f);
glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f);
void updateCameraTransforms();
}; };
@ -80,17 +80,20 @@ namespace Renderer {
class Scene { class Scene {
public: public:
Camera camera; float deltaTime = 0.0f;
Scene(GLFWwindow* win); Scene(GLFWwindow* win);
Scene(GLFWwindow* win, std::vector<RenderObject*> ROs); Scene(GLFWwindow* win, std::vector<RenderObject*> ROs);
void setCamera(Camera cam); void setCamera(Camera *cam);
void spawnObject(RenderObject *ro); void spawnObject(RenderObject *ro);
void render(); void render();
protected:
Camera *camera;
private: private:
std::vector<RenderObject*> renderObjects = std::vector<RenderObject*>(); std::vector<RenderObject*> renderObjects = std::vector<RenderObject*>();
GLFWwindow* window; GLFWwindow* window;
float lastFrame = 0.0f;
}; };
class TexturedObject : public RenderObject { class TexturedObject : public RenderObject {

@ -0,0 +1,70 @@
#include "controller.hpp"
#include "GLFW/glfw3.h"
#include "glm/fwd.hpp"
#include "glm/trigonometric.hpp"
#include "renderer.hpp"
#include <cmath>
#include <cstdio>
void Controller::processMouseInput(float deltaTime) {
double x, y;
glfwGetCursorPos(window, &x, &y);
if (firstMouseInput) {
lastX = x;
lastY = y;
firstMouseInput = false;
}
float xOffset = x - lastX;
float yOffset = y - lastY;
lastX = x;
lastY = y;
xOffset *= sensitivity;
yOffset *= sensitivity;
yaw += xOffset;
pitch += yOffset;
// Clamp camera values
pitch = glm::clamp(pitch, -CAM_MAX_ANGLE, CAM_MAX_ANGLE);
// yaw = glm::clamp(yaw, -CAM_MAX_ANGLE, CAM_MAX_ANGLE);
yaw = std::fmod(yaw, 360.0f);
// Update the front vector
glm::vec3 dir;
dir.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch));
dir.y = sin(glm::radians(-pitch));
dir.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch));
front = glm::normalize(dir);
updateCameraTransforms();
printf("%f %f %f (pitch: %f yaw: %f)\n", position.x, position.y, position.z, pitch, yaw);
}
void Controller::processInput(float deltaTime) {
processMouseInput(deltaTime);
float cameraSpeed = deltaTime * 2.5f;
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
translate(cameraSpeed * front);
}
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {
translate(-cameraSpeed * front);
}
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) {
translate(-glm::normalize(glm::cross(front, up)) * cameraSpeed);
}
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {
translate(glm::normalize(glm::cross(front, up)) * cameraSpeed);
}
if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) {
translate(cameraSpeed * up);
}
if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) {
translate(cameraSpeed * -up);
}
}

@ -7,6 +7,7 @@
#include <vector> #include <vector>
#include <math.h> #include <math.h>
#include "controller.hpp"
#include "renderer.hpp" #include "renderer.hpp"
#define WINDOW_WIDTH 640 #define WINDOW_WIDTH 640
@ -14,45 +15,7 @@
#define RUSTY_METAL_TEXTURE "assets/textures/rusty_metal.jpg" #define RUSTY_METAL_TEXTURE "assets/textures/rusty_metal.jpg"
void framebuffer_size_callback(GLFWwindow* win, int w, int h) { std::vector<float> verts({
glViewport(0, 0, w, h);
}
void processInput(GLFWwindow *win) {
int action = glfwGetKey(win, GLFW_KEY_ESCAPE);
if (action == GLFW_PRESS) {
glfwSetWindowShouldClose(win, true);
}
}
void renderCallback() {
// Make background
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
// glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
// glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
int main() {
glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* win = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Hohmann", NULL, NULL);
if (win == NULL) {
printf("Failed to create a window.\n");
glfwTerminate();
return 1;
}
glfwMakeContextCurrent(win);
if ( !gladLoadGLLoader((GLADloadproc)glfwGetProcAddress) ) {
printf("Failed to init GLAD.\n");
return 1;
}
std::vector<float> verts({
-0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
@ -105,10 +68,10 @@ int main() {
0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f
}); });
// Vert struc: x y z r g b tx ty // Vert struc: x y z r g b tx ty
std::vector<unsigned int> indices({ std::vector<unsigned int> indices({
0, 1, 3, 0, 1, 3,
1, 2, 3, 1, 2, 3,
5, 6, 7, 5, 6, 7,
@ -139,12 +102,49 @@ int main() {
7, 8, 9, 7, 8, 9,
9, 10, 11, 9, 10, 11,
11, 12, 13, 11, 12, 13,
}); });
void framebuffer_size_callback(GLFWwindow* win, int w, int h) {
glViewport(0, 0, w, h);
}
void mouse_callback(GLFWwindow* win, double x, double y) {}
void processInput(GLFWwindow *win) {
int action = glfwGetKey(win, GLFW_KEY_ESCAPE);
if (action == GLFW_PRESS) {
glfwSetWindowShouldClose(win, true);
}
}
int main() {
glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* win = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Hohmann", NULL, NULL);
if (win == NULL) {
printf("Failed to create a window.\n");
glfwTerminate();
return 1;
}
glfwMakeContextCurrent(win);
if ( !gladLoadGLLoader((GLADloadproc)glfwGetProcAddress) ) {
printf("Failed to init GLAD.\n");
return 1;
}
glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
glfwSetFramebufferSizeCallback(win, framebuffer_size_callback); glfwSetFramebufferSizeCallback(win, framebuffer_size_callback); // Framebuffer
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
// Input
glfwSetInputMode(win, GLFW_CURSOR, GLFW_CURSOR_DISABLED); // Disable cursor
glfwSetCursorPosCallback(win, mouse_callback); // Mouse capture callback
float borderColor[] = {1.0f, 1.0f, 1.0f, 1.0f}; float borderColor[] = {1.0f, 1.0f, 1.0f, 1.0f};
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor); glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
@ -163,27 +163,17 @@ int main() {
scene.spawnObject(&ro); scene.spawnObject(&ro);
scene.spawnObject(&ro2); scene.spawnObject(&ro2);
// Controller test
Controller player(win, glm::vec3(0.0f, 0.0f, -8.0f));
scene.setCamera(&player);
while (!glfwWindowShouldClose(win)) { while (!glfwWindowShouldClose(win)) {
// Handle input // Handle input
player.processInput(scene.deltaTime);
processInput(win); processInput(win);
// rendering ro.translate(glm::vec3(0.0f, 0.0f, 0.001f));
renderCallback(); // ro2.setPosition(glm::vec3(0.0f, 0.0f, -1000.0f));
float time = glfwGetTime();
float gVal = sin(time);
// Move the camera left and right
// scene.camera.setRotation(glm::vec3(gVal * 5, 5.0f * gVal, gVal * 20.0f));
// scene.camera.translate(glm::vec3(0.0f, 0.0f, 0.02f + gVal/100.0f));
scene.camera.pointAt(glm::vec3(0.0f, 0.0f, 0.0f));
float radius = 10.0f;
scene.camera.setPosition(glm::vec3(cos(time) * radius, 0.0f, sin(time) * radius));
// Move the objects & stuff
float rotang = time;
ro.rotate(glm::vec3(gVal, 0.0f, gVal));
ro2.setPosition(glm::vec3(0.0f, gVal * 2.0f, 1.0f + gVal*5.0f));
// Render new frame // Render new frame
scene.render(); scene.render();

@ -43,8 +43,7 @@ namespace Renderer {
} }
void Object::translate(glm::vec3 dpos) { void Object::translate(glm::vec3 dpos) {
position += dpos; setPosition(position + dpos);
updatePositionTransform();
} }
void Object::updateRotationTransform() { void Object::updateRotationTransform() {
@ -68,15 +67,12 @@ namespace Renderer {
} }
void Object::rotate(glm::vec3 dangle) { void Object::rotate(glm::vec3 dangle) {
angle += dangle; setRotation(angle + dangle);
updateRotationTransform();
} }
// Scene // Scene
Scene::Scene(GLFWwindow* win) : camera(win) { Scene::Scene(GLFWwindow* win) {
window = win; window = win;
camera.setFOV(DEFAULT_FOV);
} }
Scene::Scene(GLFWwindow* win, std::vector<RenderObject*> ROs) : Scene(win) { Scene::Scene(GLFWwindow* win, std::vector<RenderObject*> ROs) : Scene(win) {
@ -87,18 +83,29 @@ namespace Renderer {
renderObjects.push_back(ro); renderObjects.push_back(ro);
} }
void Scene::setCamera(Camera cam) { void Scene::setCamera(Camera *cam) {
camera = cam; camera = cam;
} }
void Scene::render() { void Scene::render() {
// Record deltaTime
float curFrame = glfwGetTime();
deltaTime = curFrame - lastFrame;
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
for ( RenderObject *ro: renderObjects ) for ( RenderObject *ro: renderObjects )
ro->render(window, camera); ro->render(window, *camera);
// Record the last frame
lastFrame = curFrame;
} }
// Camera // Camera
Camera::Camera(GLFWwindow* win) { Camera::Camera(GLFWwindow* win) {
window = win; window = win;
setFOV(DEFAULT_FOV);
} }
Camera::Camera(GLFWwindow* win, glm::vec3 pos) : Camera(win) { Camera::Camera(GLFWwindow* win, glm::vec3 pos) : Camera(win) {
@ -115,11 +122,10 @@ namespace Renderer {
projection = glm::perspective(glm::radians(fov), (float)width / (float)height, NEAR_PLANE, FAR_PLANE); projection = glm::perspective(glm::radians(fov), (float)width / (float)height, NEAR_PLANE, FAR_PLANE);
} }
void Camera::pointAt(glm::vec3 target) { void Camera::updateCameraTransforms() {
view = glm::lookAt(position, target, glm::vec3(0.0f, 1.0f, 0.0f)); view = glm::lookAt(position, position + front, up);
} }
// RenderObject // RenderObject
RenderObject::RenderObject(std::vector<float> verts, std::vector<unsigned int> indices) RenderObject::RenderObject(std::vector<float> verts, std::vector<unsigned int> indices)
: shader(VERT_SHADER_SRC_FILE, FRAG_SHADER_SRC_FILE) { : shader(VERT_SHADER_SRC_FILE, FRAG_SHADER_SRC_FILE) {

Loading…
Cancel
Save