added camera class

This commit is contained in:
Daniel 2023-08-03 20:03:56 +02:00
parent e8e2408b9d
commit 60f01db034
6 changed files with 156 additions and 47 deletions

View File

@ -138,6 +138,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\..\libraries\glad\src\glad.c" />
<ClCompile Include="util\camera\camera.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="Shaders\Shader.cpp" />
<ClCompile Include="util\stb_image.cpp" />
@ -151,6 +152,7 @@
</CopyFileToFolders>
</ItemGroup>
<ItemGroup>
<ClInclude Include="util\camera\camera.h" />
<ClInclude Include="Exceptions\IOException.h" />
<ClInclude Include="Exceptions\Shaders\CreateProgramException.h" />
<ClInclude Include="Exceptions\Shaders\ShaderCompileException.h" />

View File

@ -27,6 +27,9 @@
<ClCompile Include="util\stb_image.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="util\camera\camera.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Shaders\Shader.h">
@ -56,6 +59,9 @@
<ClInclude Include="util\property.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="util\camera\camera.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CopyFileToFolders Include="Shaders\default\default.frag" />

View File

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

View File

@ -0,0 +1 @@
#include "camera.h"

View File

@ -0,0 +1,111 @@
#pragma once
#include <glad/glad.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#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));
}
};

View File

@ -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<T> 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<T>& 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<typename T>
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<T>& 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)?
};