diff --git a/src/Engine/Engine.vcxproj b/src/Engine/Engine.vcxproj
index c62a1fd..d6d4c6e 100644
--- a/src/Engine/Engine.vcxproj
+++ b/src/Engine/Engine.vcxproj
@@ -138,6 +138,7 @@
+
@@ -151,6 +152,7 @@
+
diff --git a/src/Engine/Engine.vcxproj.filters b/src/Engine/Engine.vcxproj.filters
index aa346ca..4e69393 100644
--- a/src/Engine/Engine.vcxproj.filters
+++ b/src/Engine/Engine.vcxproj.filters
@@ -27,6 +27,9 @@
Source Files
+
+ Source Files
+
@@ -56,6 +59,9 @@
Header Files
+
+ Header Files
+
diff --git a/src/Engine/main.cpp b/src/Engine/main.cpp
index 10be1eb..09ef7c6 100644
--- a/src/Engine/main.cpp
+++ b/src/Engine/main.cpp
@@ -10,9 +10,10 @@
#include "shaders/Shader.h"
#include "textures/Texture2D.h"
#include "util/stb_image.h"
+#include "util/camera/camera.h"
-// Continue: https://learnopengl.com/Getting-started/Camera
-// Chapter: Camera class
+// Continue: https://learnopengl.com/Lighting/Colors
+// Chapter: Not yet started
//
// TODO: look at project->properties->VC++ Directories-> change everything to the Environment var
// For the "real" Nebulix Engine setup everything so it can be compiled/used with VSCode/CLion and not just VS
@@ -33,12 +34,9 @@ typedef glm::mat4 mat4;
typedef glm::vec3 vec3;
vec3 cameraPosition = vec3(0.0f, 0.0f, 3.0f);
-vec3 cameraFront = vec3(0.0f, 0.0f, -1.0f);
-vec3 cameraUp = vec3(0.0f, 1.0f, 0.0f);
+Camera cam(cameraPosition);
-float deltaTime = 0.0f;
-float lastFrameTime = 0.0f;
-float pitch = 0.0f, yaw = -90.0f, fov = 45.0f;
+float deltaTime = 0.0f, lastFrameTime = 0.0f;
float mouseLastX = WINDOW_WIDTH / 2, mouseLastY = WINDOW_HEIGHT / 2;
bool firstMouseMove = true;
@@ -50,24 +48,17 @@ void OnWindowResize(GLFWwindow* window, int width, int height)
void ProcessInput(GLFWwindow* window)
{
- const float cameraSpeed = 3.0f * deltaTime;
-
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
- if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
- cameraPosition += cameraSpeed * cameraFront;
- if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
- cameraPosition -= cameraSpeed * cameraFront;
- if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
- cameraPosition -= glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;
- if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
- cameraPosition += glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;
-
- if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS)
- cameraFront -= glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed * 0.25f;
- if (glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS)
- cameraFront += glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed * 0.25f;
+ if(glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
+ cam.ProcessKeyboard(MovementDirection::FORWARD, deltaTime);
+ if(glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
+ cam.ProcessKeyboard(MovementDirection::BACKWARD, deltaTime);
+ if(glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
+ cam.ProcessKeyboard(MovementDirection::LEFT, deltaTime);
+ if(glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
+ cam.ProcessKeyboard(MovementDirection::RIGHT, deltaTime);
}
void OnMouseMove(GLFWwindow* window, double xpos, double ypos)
@@ -85,32 +76,12 @@ void OnMouseMove(GLFWwindow* window, double xpos, double ypos)
mouseLastX = xpos;
mouseLastY = ypos;
- const float sensitivity = 0.1f;
- xoffset *= sensitivity;
- yoffset *= sensitivity;
-
- yaw += xoffset;
- pitch += yoffset;
-
- if (pitch > 89.0f)
- pitch = 89.0f;
- if (pitch < -89.0f)
- pitch = -89.0f;
-
- glm::vec3 direction;
- direction.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch));
- direction.y = sin(glm::radians(pitch));
- direction.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch));
- cameraFront = glm::normalize(direction);
+ cam.ProcessMouseMovement(xoffset, yoffset, true);
}
void OnScroll(GLFWwindow* window, double xoffset, double yoffset)
{
- fov -= (float)yoffset;
- if (fov < 1.0f)
- fov = 1.0f;
- if (fov > 90.0f)
- fov = 90.0f;
+ cam.ProcessMouseScroll(yoffset);
}
void Configure(GLFWwindow *window)
@@ -152,6 +123,7 @@ int main()
Configure(window);
+
float vertices[] = { // object coordinates, uv-coordinates
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
@@ -268,8 +240,8 @@ int main()
ProcessInput(window);
- mat4 viewMatrix = glm::lookAt(cameraPosition, cameraPosition + cameraFront, cameraUp);
- mat4 projectionMatrix = glm::perspective(glm::radians(fov), 800.0f / 600.0f, 0.1f, 100.0f);
+ mat4 viewMatrix = cam.GetViewMatrix();
+ mat4 projectionMatrix = glm::perspective(glm::radians(cam.Fov), 800.0f / 600.0f, 0.1f, 100.0f);
shader->Use();
shader->SetInt("ourTexture1", 0);
diff --git a/src/Engine/util/camera/camera.cpp b/src/Engine/util/camera/camera.cpp
new file mode 100644
index 0000000..729cfb7
--- /dev/null
+++ b/src/Engine/util/camera/camera.cpp
@@ -0,0 +1 @@
+#include "camera.h"
diff --git a/src/Engine/util/camera/camera.h b/src/Engine/util/camera/camera.h
new file mode 100644
index 0000000..d9c5109
--- /dev/null
+++ b/src/Engine/util/camera/camera.h
@@ -0,0 +1,111 @@
+#pragma once
+#include
+#include
+#include
+
+#include "../property.h"
+
+enum class MovementDirection
+{
+ FORWARD,
+ BACKWARD,
+ LEFT,
+ RIGHT
+};
+
+// Default values
+const float YAW = -90.0f;
+const float PITCH = 0.0f;
+const float SPEED = 2.5f;
+const float SENSITIVITY = 0.1f;
+const float FOV = 45.0f;
+
+class Camera
+{
+public:
+ glm::vec3 Position;
+ glm::vec3 Front;
+ glm::vec3 Up;
+ glm::vec3 Right;
+ glm::vec3 WorldUp;
+
+ float Yaw;
+ float Pitch;
+
+ float MovementSpeed;
+ float MouseSensitivity;
+ float Fov; // or zoom
+
+ Camera(glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f), float yaw = YAW, float pitch = PITCH) : Front(glm::vec3(0.0f, 0.0f, -1.0f)), MovementSpeed(SPEED), MouseSensitivity(SENSITIVITY), Fov(FOV)
+ {
+ Position = position;
+ WorldUp = up;
+ Yaw = yaw;
+ Pitch = pitch;
+ UpdateCameraVectors();
+ }
+
+ glm::mat4 GetViewMatrix() { return glm::lookAt(Position, Position + Front, Up); }
+
+ // processes input received from any keyboard-like input system. Accepts input parameter in the form of camera defined ENUM (to abstract it from windowing systems)
+ void ProcessKeyboard(MovementDirection direction, float deltaTime)
+ {
+ float velocity = MovementSpeed * deltaTime;
+ if (direction == MovementDirection::FORWARD)
+ Position += Front * velocity;
+ if (direction == MovementDirection::BACKWARD)
+ Position -= Front * velocity;
+ if (direction == MovementDirection::LEFT)
+ Position -= Right * velocity;
+ if (direction == MovementDirection::RIGHT)
+ Position += Right * velocity;
+ }
+
+ // processes input received from a mouse input system. Expects the offset value in both the x and y direction.
+ void ProcessMouseMovement(float xoffset, float yoffset, GLboolean constrainPitch = true)
+ {
+ xoffset *= MouseSensitivity;
+ yoffset *= MouseSensitivity;
+
+ Yaw += xoffset;
+ Pitch += yoffset;
+
+ // make sure that when pitch is out of bounds, screen doesn't get flipped
+ if (constrainPitch)
+ {
+ if (Pitch > 89.0f)
+ Pitch = 89.0f;
+ if (Pitch < -89.0f)
+ Pitch = -89.0f;
+ }
+
+ // update Front, Right and Up Vectors using the updated Euler angles
+ UpdateCameraVectors();
+ }
+
+ // processes input received from a mouse scroll-wheel event. Only requires input on the vertical wheel-axis
+ void ProcessMouseScroll(float yoffset)
+ {
+ Fov -= (float)yoffset;
+ if (Fov < 1.0f)
+ Fov = 1.0f;
+ if (Fov > 90.0f)
+ Fov = 90.0f;
+ }
+
+private:
+ // calculates the front vector from the Camera's (updated) Euler Angles
+ void UpdateCameraVectors()
+ {
+ glm::vec3 front;
+ front.x = cos(glm::radians(Yaw)) * cos(glm::radians(Pitch));
+ front.y = sin(glm::radians(Pitch));
+ front.z = sin(glm::radians(Yaw)) * cos(glm::radians(Pitch));
+ Front = glm::normalize(front);
+
+ // also re-calculate the Right and Up vector
+ Right = glm::normalize(glm::cross(Front, WorldUp)); // normalize the vectors, because their length gets closer to 0 the more you look up or down which results in slower movement.
+ Up = glm::normalize(glm::cross(Right, Front));
+ }
+};
+
diff --git a/src/Engine/util/property.h b/src/Engine/util/property.h
index 30f864c..8f23bd6 100644
--- a/src/Engine/util/property.h
+++ b/src/Engine/util/property.h
@@ -7,8 +7,25 @@ public:
Property(const T &data): data{data}{}
T operator()() { return data; }
- void operator()(const T &d) { data = d; }
+ void operator()(const T& d) { data = d; }
+ Property operator=(const T& d) { data = d; }
+ operator T() const { return data; } // to easily pass a property to a function which takes a var of type T for example: void func(float f) => func(property)
+
private:
T data;
void operator=(const Property& p); // so this property can not be overwritten, since this might lead to a memory leak. Maybe this operator can be used to assign only the data (C#-like)?
};
+
+template
+class ReadOnlyProperty
+{
+public:
+ ReadOnlyProperty(const T &data): data{data}{}
+
+ T operator()() { return data; }
+ operator T() const { return data; } // to easily pass a property to a function which takes a var of type T for example: void func(float f) => func(property)
+
+private:
+ T data;
+ void operator=(const ReadOnlyProperty& p); // so this property can not be overwritten, since this might lead to a memory leak. Maybe this operator can be used to assign only the data (C#-like)?
+};