From 48821afd7663ef3a214312d66411922867e8b95e Mon Sep 17 00:00:00 2001 From: "Grayson Riffe (Laptop)" Date: Wed, 1 Sep 2021 02:04:28 -0500 Subject: [PATCH] Added Camera and first-person and UI camera types; Added mouse tracking to aid this --- NothinFancy/NothinFancy.vcxproj | 10 +- NothinFancy/NothinFancy.vcxproj.filters | 6 ++ NothinFancy/res/defaultShader/vertex.shader | 5 +- NothinFancy/src/Application.cpp | 60 ++++++++++- NothinFancy/src/Gamestate.cpp | 8 +- NothinFancy/src/Renderer/Camera.cpp | 106 +++++++++++++++++++ NothinFancy/src/Renderer/Drawable/Entity.cpp | 14 ++- NothinFancy/src/Renderer/Drawable/Model.cpp | 4 + NothinFancy/src/Renderer/Renderer.cpp | 8 +- NothinFancy/src/include/Application.h | 7 ++ NothinFancy/src/include/Camera.h | 38 +++++++ NothinFancy/src/include/Entity.h | 9 +- NothinFancy/src/include/Gamestate.h | 4 +- NothinFancy/src/include/Model.h | 8 +- NothinFancy/src/include/NothinFancy.h | 27 +++-- NothinFancy/src/include/Renderer.h | 6 +- NothinFancy/src/include/Shader.h | 2 - NothinFancy/src/include/Utility.h | 11 ++ 18 files changed, 291 insertions(+), 42 deletions(-) create mode 100644 NothinFancy/src/Renderer/Camera.cpp create mode 100644 NothinFancy/src/include/Camera.h diff --git a/NothinFancy/NothinFancy.vcxproj b/NothinFancy/NothinFancy.vcxproj index 64cbbf2..9b88053 100644 --- a/NothinFancy/NothinFancy.vcxproj +++ b/NothinFancy/NothinFancy.vcxproj @@ -94,7 +94,7 @@ Level3 true - NFENGINE;GLEW_STATIC;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + GLEW_STATIC;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true $(ProjectDir)src\include\;$(ProjectDir)dep\include\ $(IntDir)obj\ @@ -123,7 +123,7 @@ true true true - NFENGINE;GLEW_STATIC;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + GLEW_STATIC;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true $(ProjectDir)src\include\;$(ProjectDir)dep\include\ $(IntDir)obj\ @@ -152,7 +152,7 @@ Level3 true - NFENGINE;GLEW_STATIC;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + GLEW_STATIC;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true $(ProjectDir)src\include\;$(ProjectDir)dep\include\ $(IntDir)obj\ @@ -181,7 +181,7 @@ true true true - NFENGINE;GLEW_STATIC;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + GLEW_STATIC;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true $(ProjectDir)src\include\;$(ProjectDir)dep\include\ $(IntDir)obj\ @@ -211,6 +211,7 @@ + @@ -224,6 +225,7 @@ + diff --git a/NothinFancy/NothinFancy.vcxproj.filters b/NothinFancy/NothinFancy.vcxproj.filters index 9998290..d05e54a 100644 --- a/NothinFancy/NothinFancy.vcxproj.filters +++ b/NothinFancy/NothinFancy.vcxproj.filters @@ -57,6 +57,9 @@ Source Files + + Source Files + @@ -113,6 +116,9 @@ Header Files + + Header Files + diff --git a/NothinFancy/res/defaultShader/vertex.shader b/NothinFancy/res/defaultShader/vertex.shader index 194f98b..ddac06c 100644 --- a/NothinFancy/res/defaultShader/vertex.shader +++ b/NothinFancy/res/defaultShader/vertex.shader @@ -10,7 +10,6 @@ uniform mat4 proj; out vec2 texCoord; void main() { - //gl_Position = proj * view * model * vec4(pos, 1.0); - gl_Position = proj * model * vec4(pos, 1.0); + gl_Position = proj * view * model * vec4(pos, 1.0); texCoord = texCoords; -} +} \ No newline at end of file diff --git a/NothinFancy/src/Application.cpp b/NothinFancy/src/Application.cpp index 7e0c437..91f6d1f 100644 --- a/NothinFancy/src/Application.cpp +++ b/NothinFancy/src/Application.cpp @@ -70,6 +70,8 @@ namespace nf { MSG msg = { }; std::thread mainThread(&Application::runMainGameThread, this); while (m_running) { + if (m_quit) + PostMessage(m_window, WM_CLOSE, NULL, NULL); while (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); @@ -133,6 +135,18 @@ namespace nf { } } + void Application::trackMouse(bool track) { + m_trackingMouse = track; + } + + void Application::getMouseDiff(int& x, int& y) { + x = m_mouseDiffX; + y = m_mouseDiffY; + m_mouseDiffX = 0; + m_mouseDiffY = 0; + //TODO: Replace with atomic? + } + void Application::registerWindowClass() { if (!FindWindow(L"NFClass", NULL)) { m_wclassName = L"NFClass"; @@ -193,6 +207,41 @@ namespace nf { else m_input[i] = false; } + POINT mouse; + GetCursorPos(&mouse); + ScreenToClient(m_window, &mouse); + if (GetFocus() == m_window) { + m_mouseX = mouse.x; + m_mouseY = mouse.y; + if (m_mouseX > m_currentConfig.width) + m_mouseX = m_currentConfig.width; + if (m_mouseX < 0) + m_mouseX = 0; + if (m_mouseY > m_currentConfig.height) + m_mouseY = m_currentConfig.height; + if (m_mouseY < 0) + m_mouseY = 0; + + if (m_trackingMouse) { + static bool first = true; + int middleX = m_currentConfig.width / 2; + int middleY = m_currentConfig.height / 2; + m_mouseDiffX += m_mouseX - middleX; + m_mouseDiffY += middleY - m_mouseY; + if (first) { + m_mouseDiffX = 0; + m_mouseDiffY = 0; + first = false; + } + POINT middle = { middleX, middleY }; + ClientToScreen(m_window, &middle); + SetCursorPos(middle.x, middle.y); + } + } + } + + void Application::quit() { + m_quit = true; } void Application::runMainGameThread() { @@ -207,7 +256,7 @@ namespace nf { lastFrame = std::chrono::steady_clock::now(); m_currentState->update(m_deltaTime); m_currentState->render(*m_renderer); - m_renderer->doFrame(); + m_renderer->doFrame(m_currentState->getCamera()); m_frames++; if (m_stateChange) doStateChange(); @@ -263,6 +312,15 @@ namespace nf { case WM_MENUCHAR: { return MNC_CLOSE << 16; } + case WM_SETCURSOR: { + if (LOWORD(lParam) != HTCLIENT) + break; + if (app->m_trackingMouse && LOWORD(lParam) == HTCLIENT && GetFocus() == hWnd) { + SetCursor(NULL); + return 0; + } + break; + } case WM_CLOSE: { DestroyWindow(hWnd); return 0; diff --git a/NothinFancy/src/Gamestate.cpp b/NothinFancy/src/Gamestate.cpp index 1c5c4bd..1f8d46d 100644 --- a/NothinFancy/src/Gamestate.cpp +++ b/NothinFancy/src/Gamestate.cpp @@ -4,7 +4,9 @@ #include "Utility.h" namespace nf { - Gamestate::Gamestate(Application* app) { + Gamestate::Gamestate(Application* app) : + m_camera(app) + { m_app = app; } @@ -16,6 +18,10 @@ namespace nf { } + Camera* Gamestate::getCamera() { + return &m_camera; + } + void Gamestate::render(Renderer& renderer) { } diff --git a/NothinFancy/src/Renderer/Camera.cpp b/NothinFancy/src/Renderer/Camera.cpp new file mode 100644 index 0000000..d9a61e8 --- /dev/null +++ b/NothinFancy/src/Renderer/Camera.cpp @@ -0,0 +1,106 @@ +#include "Camera.h" + +#include "glm/glm.hpp" + +#include "Application.h" +#include "Shader.h" + +namespace nf { + Camera::Camera(Application* app) : + m_app(app) + { + m_type = Type::NF_CAMERA_UI; + } + + void Camera::setType(Type cameraType) { + m_type = cameraType; + if (m_type == Type::NF_CAMERA_FIRST_PERSON || m_type == Type::NF_CAMERA_ORBIT) + m_app->trackMouse(true); + else + m_app->trackMouse(false); + } + + Camera::Type Camera::getType() const { + return m_type; + } + + void Camera::moveForward(double speed) { + Vec3 temp = m_front * speed; + m_position = { m_position.x + temp.x, m_position.y + temp.y, m_position.z + temp.z }; + } + + void Camera::moveBackward(double speed) { + Vec3 temp = m_front * speed; + m_position = { m_position.x - temp.x, m_position.y - temp.y, m_position.z - temp.z }; + } + + void Camera::moveRight(double speed) { + glm::vec3 front = { m_front.x, m_front.y, m_front.z }; + glm::vec3 temp = glm::normalize(glm::cross(front, glm::vec3(0.0, 1.0, 0.0))) * (float)speed; + m_position = { m_position.x + temp.x, m_position.y + temp.y, m_position.z + temp.z }; + } + + void Camera::moveLeft(double speed) { + glm::vec3 front = { m_front.x, m_front.y, m_front.z }; + glm::vec3 temp = glm::normalize(glm::cross(front, glm::vec3(0.0, 1.0, 0.0))) * (float)speed; + m_position = { m_position.x - temp.x, m_position.y - temp.y, m_position.z - temp.z }; + } + + void Camera::setPosition(double x, double y, double z) { + m_position = { x, y, z }; + } + + void Camera::setPosition(const Vec3& position) { + m_position = position; + } + + void Camera::bind(Shader* shader) { + glm::mat4 view; + + switch (m_type) { + case Type::NF_CAMERA_UI: { + view = glm::mat4(1.0); + break; + } + case Type::NF_CAMERA_FIRST_PERSON: { + int mouseDiffx = 0; + int mouseDiffy = 0; + m_app->getMouseDiff(mouseDiffx, mouseDiffy); + float mouseX = (float)mouseDiffx * 0.1f; + float mouseY = (float)mouseDiffy * 0.1f; + static float yaw = -90.0f; + static float pitch = 0.0f; + yaw += mouseX; + pitch += mouseY; + if (pitch > 89.0f) + pitch = 89.0f; + if (pitch < -89.0f) + pitch = -89.0f; + glm::vec3 rotation; + rotation.x = std::cos(glm::radians(yaw)) * std::cos(glm::radians(pitch)); + rotation.y = std::sin(glm::radians(pitch)); + rotation.z = std::sin(glm::radians(yaw)) * std::cos(glm::radians(pitch)); + rotation = glm::normalize(rotation); + m_front = { rotation.x, rotation.y, rotation.z }; + glm::vec3 position(m_position.x, m_position.y, m_position.z); + glm::vec3 up(0.0, 1.0, 0.0); + view = glm::lookAt(position, position + rotation, up); + break; + } + case Type::NF_CAMERA_ORBIT: { + + break; + } + case Type::NF_CAMERA_FIXED: { + + break; + } + } + + shader->setUniform("view", view); + } + + Camera::~Camera() { + + } +} \ No newline at end of file diff --git a/NothinFancy/src/Renderer/Drawable/Entity.cpp b/NothinFancy/src/Renderer/Drawable/Entity.cpp index 083aaf9..f377b68 100644 --- a/NothinFancy/src/Renderer/Drawable/Entity.cpp +++ b/NothinFancy/src/Renderer/Drawable/Entity.cpp @@ -2,8 +2,6 @@ #include -#include "Utility.h" - namespace nf { Entity::Entity() : m_model(nullptr), @@ -39,10 +37,18 @@ namespace nf { m_position = { x, y, z }; } + void Entity::setPosition(const Vec3& position) { + m_position = position; + } + void Entity::setRotation(double x, double y, double z) { m_rotation = { x, y, z }; } + void Entity::setRotation(const Vec3& rotation) { + m_rotation = rotation; + } + void Entity::setScale(double x) { m_rotation = { x, x, x }; } @@ -51,6 +57,10 @@ namespace nf { m_scale = { x, y, z }; } + void Entity::setScale(const Vec3& scale) { + m_scale = scale; + } + void Entity::bind(Shader* shader) { m_model->bind(); shader->bind(); diff --git a/NothinFancy/src/Renderer/Drawable/Model.cpp b/NothinFancy/src/Renderer/Drawable/Model.cpp index e20b67a..85baee0 100644 --- a/NothinFancy/src/Renderer/Drawable/Model.cpp +++ b/NothinFancy/src/Renderer/Drawable/Model.cpp @@ -1,6 +1,10 @@ #include "Model.h" +#include "glm/glm.hpp" +#include "glm/gtc/matrix_transform.hpp" + #include "Utility.h" +#include "Texture.h" namespace nf { Model::Model() { diff --git a/NothinFancy/src/Renderer/Renderer.cpp b/NothinFancy/src/Renderer/Renderer.cpp index 55d8b1c..c1bd168 100644 --- a/NothinFancy/src/Renderer/Renderer.cpp +++ b/NothinFancy/src/Renderer/Renderer.cpp @@ -2,6 +2,7 @@ #include "GL/glew.h" #include "GL\wglew.h" +#include "glm/glm.hpp" #include "Application.h" #include "Utility.h" @@ -51,6 +52,7 @@ namespace nf { glDepthFunc(GL_LESS); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_CULL_FACE); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); Win32Res vs(IDR_DEFAULTVERTEX); @@ -68,15 +70,17 @@ namespace nf { m_lGame.push_back(&in); } - void Renderer::doFrame() { + void Renderer::doFrame(Camera* camera) { glViewport(0, 0, m_app->getConfig().width, m_app->getConfig().height); - proj = glm::perspective(glm::radians(45.0f), (float)m_app->getConfig().width / (float)m_app->getConfig().height, 0.1f, 100000.0f); + glm::mat4 proj = glm::perspective(glm::radians(45.0f), (float)m_app->getConfig().width / (float)m_app->getConfig().height, 0.1f, 100000.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); for (Entity* draw : m_lGame) { Entity& curr = *draw; curr.bind(m_defaultShader); m_defaultShader->setUniform("proj", proj); + camera->bind(m_defaultShader); + //TODO: Clean this up a bit glDrawElements(GL_TRIANGLES, curr.getModel()->getIndexCount(), GL_UNSIGNED_INT, nullptr); } m_lGame.clear(); diff --git a/NothinFancy/src/include/Application.h b/NothinFancy/src/include/Application.h index d99c7e1..8d4ca54 100644 --- a/NothinFancy/src/include/Application.h +++ b/NothinFancy/src/include/Application.h @@ -28,7 +28,10 @@ namespace nf { const Config& getConfig() const; int getFPS() const; bool isInput(unsigned int code); + void trackMouse(bool track); + void getMouseDiff(int& x, int& y); + void quit(); ~Application(); private: void registerWindowClass(); @@ -44,6 +47,7 @@ namespace nf { Config m_currentConfig; bool m_running; + bool m_quit; HINSTANCE m_hInst; LPCWSTR m_wclassName; HWND m_window; @@ -71,6 +75,9 @@ namespace nf { //Array of booleans that represent keyboard and mouse input minus the scrollwheel bool m_input[164]; + int m_mouseX, m_mouseY; + bool m_trackingMouse; + int m_mouseDiffX, m_mouseDiffY; //Renderer object to use OpenGL to render the current state Renderer* m_renderer; diff --git a/NothinFancy/src/include/Camera.h b/NothinFancy/src/include/Camera.h new file mode 100644 index 0000000..94ca7c0 --- /dev/null +++ b/NothinFancy/src/include/Camera.h @@ -0,0 +1,38 @@ +#pragma once +#include"Utility.h" + +namespace nf { + class Application; + class Shader; + //TODO: Make sure there are always newlines here; + class Camera { + public: + enum class Type { + NF_CAMERA_UI, + NF_CAMERA_FIRST_PERSON, + NF_CAMERA_ORBIT, + NF_CAMERA_FIXED + }; + Camera(Application* app); + + void setType(Type cameraType); + Type getType() const; + + void moveForward(double speed); + void moveBackward(double speed); + void moveRight(double speed); + void moveLeft(double speed); + void setPosition(double x, double y, double z); + void setPosition(const Vec3& position); + + void bind(Shader* shader); + + ~Camera(); + private: + Application* m_app; + Type m_type; + + Vec3 m_position; + Vec3 m_front; + }; +} \ No newline at end of file diff --git a/NothinFancy/src/include/Entity.h b/NothinFancy/src/include/Entity.h index 68aede4..ea54c21 100644 --- a/NothinFancy/src/include/Entity.h +++ b/NothinFancy/src/include/Entity.h @@ -1,23 +1,22 @@ #pragma once #include "Model.h" #include "Assets.h" +#include "Utility.h" namespace nf { class Entity { - struct Vec3 { - Vec3(double x1) : x(x1), y(x1), z(x1) {} - Vec3(double x1, double y1, double z1) : x(x1), y(y1), z(z1) {} - double x, y, z; - }; public: Entity(); void create(Asset* modelAsset, Asset* textureAsset = nullptr); void setPosition(double x, double y, double z); + void setPosition(const Vec3& position); void setRotation(double x, double y, double z); + void setRotation(const Vec3& rotation); void setScale(double x); void setScale(double x, double y, double z); + void setScale(const Vec3& scale); void bind(Shader* shader); Model* getModel() const; diff --git a/NothinFancy/src/include/Gamestate.h b/NothinFancy/src/include/Gamestate.h index 6e14fa7..6ba41b1 100644 --- a/NothinFancy/src/include/Gamestate.h +++ b/NothinFancy/src/include/Gamestate.h @@ -1,4 +1,5 @@ #pragma once +#include "Camera.h" namespace nf { class Application; @@ -13,11 +14,12 @@ namespace nf { virtual void onEnter(); virtual void update(double deltaTime); + Camera* getCamera(); virtual void render(Renderer& renderer); virtual void onExit(); protected: Application* m_app; - //Resource identifier? + Camera m_camera; }; } \ No newline at end of file diff --git a/NothinFancy/src/include/Model.h b/NothinFancy/src/include/Model.h index 2c05e1e..d66bacc 100644 --- a/NothinFancy/src/include/Model.h +++ b/NothinFancy/src/include/Model.h @@ -1,13 +1,9 @@ #pragma once -#ifdef NFENGINE -#include "glm/glm.hpp" -#include "glm/gtc/matrix_transform.hpp" -#endif - #include "Drawable.h" -#include "Texture.h" namespace nf { + class Drawable; + class Texture; class Model : public Drawable { public: Model(); diff --git a/NothinFancy/src/include/NothinFancy.h b/NothinFancy/src/include/NothinFancy.h index 502070d..ba76d7e 100644 --- a/NothinFancy/src/include/NothinFancy.h +++ b/NothinFancy/src/include/NothinFancy.h @@ -6,6 +6,7 @@ #include #include "Config.h" +#include "Utility.h" #include "IntroGamestate.h" #include "Assets.h" @@ -15,20 +16,18 @@ namespace nf { class Model; class Entity { - struct Vec3 { - Vec3(double x1) : x(x1), y(x1), z(x1) {} - Vec3(double x1, double y1, double z1) : x(x1), y(y1), z(z1) {} - double x, y, z; - }; public: Entity(); void create(Asset* modelAsset, Asset* textureAsset = nullptr); void setPosition(double x, double y, double z); + void setPosition(const Vec3& position); void setRotation(double x, double y, double z); + void setRotation(const Vec3& rotation); void setScale(double x); void setScale(double x, double y, double z); + void setScale(const Vec3& scale); void bind(Shader* shader); Model* getModel() const; @@ -49,8 +48,9 @@ namespace nf { Renderer(Application* app); void render(Entity& in); + //TODO: Create second render function for UIElements - void doFrame(); + void doFrame(Camera* camera); ~Renderer(); private: @@ -59,10 +59,8 @@ namespace nf { HDC m_hdc; HGLRC m_hglrc; - std::vector m_lGame; + std::vector m_lGame; std::vector m_lUI; - const char* m_defaultVertex; - const char* m_defaultFragment; Shader* m_defaultShader; }; @@ -85,13 +83,17 @@ namespace nf { const Config& getConfig() const; int getFPS() const; bool isInput(unsigned int code); + void trackMouse(bool track); + void getMouseDiff(int& x, int& y); + void quit(); ~Application(); private: void registerWindowClass(); RECT getWindowRect() const; void calculateNewWindowPos(int& x, int& y); void toggleFullscreen(); + void updateInput(); void runMainGameThread(); void startIntroState(); void doStateChange(); @@ -100,6 +102,7 @@ namespace nf { Config m_currentConfig; bool m_running; + bool m_quit; HINSTANCE m_hInst; LPCWSTR m_wclassName; HWND m_window; @@ -127,10 +130,12 @@ namespace nf { //Array of booleans that represent keyboard and mouse input minus the scrollwheel bool m_input[164]; + int m_mouseX, m_mouseY; + bool m_trackingMouse; + int m_mouseDiffX, m_mouseDiffY; //Renderer object to use OpenGL to render the current state Renderer* m_renderer; }; } -#include "Input.h" -#include "Utility.h" \ No newline at end of file +#include "Input.h" \ No newline at end of file diff --git a/NothinFancy/src/include/Renderer.h b/NothinFancy/src/include/Renderer.h index 28f5f3f..13e85ea 100644 --- a/NothinFancy/src/include/Renderer.h +++ b/NothinFancy/src/include/Renderer.h @@ -1,9 +1,9 @@ #pragma once #include #include -#include "glm/glm.hpp" #include "Entity.h" +#include "Camera.h" namespace nf { class Application; @@ -15,7 +15,7 @@ namespace nf { void render(Entity& in); //TODO: Create second render function for UIElements - void doFrame(); + void doFrame(Camera* camera); ~Renderer(); private: @@ -27,7 +27,5 @@ namespace nf { std::vector m_lGame; std::vector m_lUI; Shader* m_defaultShader; - - glm::mat4 proj; }; } \ No newline at end of file diff --git a/NothinFancy/src/include/Shader.h b/NothinFancy/src/include/Shader.h index fd3522d..abb93b4 100644 --- a/NothinFancy/src/include/Shader.h +++ b/NothinFancy/src/include/Shader.h @@ -1,9 +1,7 @@ #pragma once #include -#ifdef NFENGINE #include "glm/glm.hpp" #include "glm/gtc/type_ptr.hpp" -#endif namespace nf { class Shader { diff --git a/NothinFancy/src/include/Utility.h b/NothinFancy/src/include/Utility.h index a251e46..c4283c3 100644 --- a/NothinFancy/src/include/Utility.h +++ b/NothinFancy/src/include/Utility.h @@ -39,12 +39,23 @@ __debugbreak();} std::exit(-1);} #endif + //TODO: Delete this after moving everything to base.nfpack struct Win32Res { Win32Res(int id); void* ptr; size_t size; }; + struct Vec3 { + Vec3() {} + Vec3(double x1) : x(x1), y(x1), z(x1) {} + Vec3(double x1, double y1, double z1) : x(x1), y(y1), z(z1) {} + Vec3 operator*(const double scalar) { + return Vec3(x * scalar, y * scalar, z * scalar); + } + double x, y, z; + }; + const wchar_t* toWide(const char* in); const wchar_t* toWide(const std::string& in); void writeFile(const std::string& filename, const std::string& in, bool encrypted = false);