added camera class
This commit is contained in:
parent
e8e2408b9d
commit
60f01db034
|
@ -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" />
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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);
|
||||
|
|
1
src/Engine/util/camera/camera.cpp
Normal file
1
src/Engine/util/camera/camera.cpp
Normal file
|
@ -0,0 +1 @@
|
|||
#include "camera.h"
|
111
src/Engine/util/camera/camera.h
Normal file
111
src/Engine/util/camera/camera.h
Normal 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));
|
||||
}
|
||||
};
|
||||
|
|
@ -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)?
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user