From 170e2288e88354cd8f1341097fc9cfe310c06a8d Mon Sep 17 00:00:00 2001 From: Notiooo Date: Fri, 1 Dec 2023 23:58:43 +0100 Subject: [PATCH] Work --- .../resources/Shaders/Graphics/Physics/Ray.fs | 8 ++++ .../resources/Shaders/Graphics/Physics/Ray.vs | 9 ++++ AimGL/src/CMakeLists_Sources.txt | 3 +- AimGL/src/Game.cpp | 2 +- AimGL/src/Player/Player.cpp | 3 -- AimGL/src/Player/Player.h | 2 +- AimGL/src/Renderer/Core/Shader.cpp | 17 ++++++- AimGL/src/Renderer/Core/Shader.h | 4 +- AimGL/src/Renderer/Renderer.cpp | 19 ++++++++ AimGL/src/Renderer/Renderer.h | 33 ++++++++++++- AimGL/src/States/CustomStates/GameState.h | 1 + AimGL/src/World/Physics/Collider.cpp | 2 + AimGL/src/World/Physics/Collider.h | 13 +++++ AimGL/src/World/Physics/Collisions.h | 8 ++++ AimGL/src/World/Physics/Ray.cpp | 27 +++++++++++ AimGL/src/World/Physics/Ray.h | 47 +++++++++++++++++++ AimGL/src/World/Physics/RectangleCollider.cpp | 2 + AimGL/src/World/Physics/RectangleCollider.h | 31 ++++++++++++ AimGL/src/World/Physics/SphereCollider.cpp | 2 + AimGL/src/World/Physics/SphereCollider.h | 31 ++++++++++++ .../World/{ => Scene}/GameObjects/Rifle.cpp | 9 +++- .../src/World/{ => Scene}/GameObjects/Rifle.h | 4 ++ AimGL/src/World/Scene/GameObjects/Target.cpp | 2 + AimGL/src/World/Scene/GameObjects/Target.h | 5 ++ AimGL/src/main.cpp | 5 +- 25 files changed, 276 insertions(+), 13 deletions(-) create mode 100644 AimGL/resources/Shaders/Graphics/Physics/Ray.fs create mode 100644 AimGL/resources/Shaders/Graphics/Physics/Ray.vs create mode 100644 AimGL/src/World/Physics/Collider.cpp create mode 100644 AimGL/src/World/Physics/Collider.h create mode 100644 AimGL/src/World/Physics/Collisions.h create mode 100644 AimGL/src/World/Physics/Ray.cpp create mode 100644 AimGL/src/World/Physics/Ray.h create mode 100644 AimGL/src/World/Physics/RectangleCollider.cpp create mode 100644 AimGL/src/World/Physics/RectangleCollider.h create mode 100644 AimGL/src/World/Physics/SphereCollider.cpp create mode 100644 AimGL/src/World/Physics/SphereCollider.h rename AimGL/src/World/{ => Scene}/GameObjects/Rifle.cpp (89%) rename AimGL/src/World/{ => Scene}/GameObjects/Rifle.h (91%) create mode 100644 AimGL/src/World/Scene/GameObjects/Target.cpp create mode 100644 AimGL/src/World/Scene/GameObjects/Target.h diff --git a/AimGL/resources/Shaders/Graphics/Physics/Ray.fs b/AimGL/resources/Shaders/Graphics/Physics/Ray.fs new file mode 100644 index 0000000..36b19dc --- /dev/null +++ b/AimGL/resources/Shaders/Graphics/Physics/Ray.fs @@ -0,0 +1,8 @@ +#version 330 core +out vec4 FragColor; + +uniform vec3 rayColor = vec3(0,1,0); + +void main() { + FragColor = vec4(rayColor, 1.0); +} diff --git a/AimGL/resources/Shaders/Graphics/Physics/Ray.vs b/AimGL/resources/Shaders/Graphics/Physics/Ray.vs new file mode 100644 index 0000000..0706816 --- /dev/null +++ b/AimGL/resources/Shaders/Graphics/Physics/Ray.vs @@ -0,0 +1,9 @@ +#version 330 core +layout (location = 0) in vec3 aPos; + +uniform mat4 view; +uniform mat4 projection; + +void main() { + gl_Position = projection * view * vec4(aPos, 1.0); +} diff --git a/AimGL/src/CMakeLists_Sources.txt b/AimGL/src/CMakeLists_Sources.txt index beea8d9..aa47153 100644 --- a/AimGL/src/CMakeLists_Sources.txt +++ b/AimGL/src/CMakeLists_Sources.txt @@ -26,6 +26,7 @@ set(PROJECT_SOURCES Player/Player.cpp World/Camera.cpp World/InfiniteGridFloor.cpp - World/GameObjects/Rifle.cpp + World/Scene/GameObjects/Rifle.cpp + World/Physics/Ray.cpp Utils/Mouse.cpp ) \ No newline at end of file diff --git a/AimGL/src/Game.cpp b/AimGL/src/Game.cpp index b5dd81c..9edd9e4 100644 --- a/AimGL/src/Game.cpp +++ b/AimGL/src/Game.cpp @@ -72,7 +72,7 @@ Game::Game() mAppStack.saveState(State_ID::GameState, *mGameWindow); // Initial state of the statestack is TitleState - mAppStack.push(State_ID::LogoState); + mAppStack.push(State_ID::GameState); } void Game::run() diff --git a/AimGL/src/Player/Player.cpp b/AimGL/src/Player/Player.cpp index 14fab89..52a8e46 100644 --- a/AimGL/src/Player/Player.cpp +++ b/AimGL/src/Player/Player.cpp @@ -20,10 +20,7 @@ Player::Player(WindowToRender& window) void Player::draw(const Renderer& target) const { - glDepthRange(0.0, 0.01); mRifle.draw(target); - glDepthRange(0.0, 1.0); - mCrosshair.draw(target); } diff --git a/AimGL/src/Player/Player.h b/AimGL/src/Player/Player.h index b2d34ff..1edb636 100644 --- a/AimGL/src/Player/Player.h +++ b/AimGL/src/Player/Player.h @@ -1,7 +1,7 @@ #pragma once #include #include -#include +#include class Renderer; class Camera; diff --git a/AimGL/src/Renderer/Core/Shader.cpp b/AimGL/src/Renderer/Core/Shader.cpp index 5caf613..bc61e9b 100644 --- a/AimGL/src/Renderer/Core/Shader.cpp +++ b/AimGL/src/Renderer/Core/Shader.cpp @@ -13,6 +13,21 @@ Shader::Shader(std::initializer_list shaders) GLCall(glUseProgram(mRendererId)); } +Shader::Shader(Shader&& rhs) noexcept + : mRendererId(rhs.mRendererId) + , mUniformLocationCache(std::move(rhs.mUniformLocationCache)) +{ + rhs.mRendererId = 0; +} + +Shader& Shader::operator=(Shader&& rhs) noexcept +{ + mRendererId = rhs.mRendererId; + mUniformLocationCache = std::move(rhs.mUniformLocationCache); + rhs.mRendererId = 0; + return *this; +} + Shader::~Shader() { GLCall(glDeleteProgram(mRendererId)); @@ -93,7 +108,7 @@ unsigned Shader::getUniformLocation(const std::string& name) const GLCall(auto location = glGetUniformLocation(mRendererId, name.c_str())); if (location == -1) { - spdlog::warn("No uniform with name {} exist", name); + spdlog::debug("No uniform with name {} exist", name); } mUniformLocationCache[name] = location; diff --git a/AimGL/src/Renderer/Core/Shader.h b/AimGL/src/Renderer/Core/Shader.h index dbe6834..e6fb669 100644 --- a/AimGL/src/Renderer/Core/Shader.h +++ b/AimGL/src/Renderer/Core/Shader.h @@ -48,9 +48,9 @@ class Shader Shader(std::initializer_list shaders); Shader(const Shader&) = delete; - Shader(Shader&&) noexcept = default; + Shader(Shader&&) noexcept; Shader& operator=(const Shader&) = delete; - Shader& operator=(Shader&&) noexcept = default; + Shader& operator=(Shader&&) noexcept; ~Shader(); /** diff --git a/AimGL/src/Renderer/Renderer.cpp b/AimGL/src/Renderer/Renderer.cpp index 1ec58c4..cf25aed 100644 --- a/AimGL/src/Renderer/Renderer.cpp +++ b/AimGL/src/Renderer/Renderer.cpp @@ -50,6 +50,25 @@ void Renderer::draw3D(const VertexArray& va, const IndexBuffer& ib, const Shader #endif } +void Renderer::draw3D(const VertexArray& va, int numberOfVertices, const Shader& shader, + const Camera& camera, const DrawMode& drawMode) const +{ + shader.bind(); + va.bind(); + + const auto view = camera.view(); + const auto projection = camera.projection(); + shader.setUniform("view", view); + shader.setUniform("projection", projection); + shader.setUniform("cameraPosition", camera.cameraPosition()); + GLCall(glDrawArrays(toOpenGl(drawMode), 0, numberOfVertices)); + +#ifdef _DEBUG + shader.unbind(); + va.unbind(); +#endif +} + unsigned Renderer::toOpenGl(const Renderer::DrawMode& drawMode) const { switch (drawMode) diff --git a/AimGL/src/Renderer/Renderer.h b/AimGL/src/Renderer/Renderer.h index 2915b13..425b14a 100644 --- a/AimGL/src/Renderer/Renderer.h +++ b/AimGL/src/Renderer/Renderer.h @@ -22,8 +22,8 @@ class Renderer explicit Renderer(sf::Window& window); /** - * Draws the data given in VertexArray, IndexBuffer to the screen using the interpretation given - * in Shader. + * \brief Draws the data given in VertexArray, IndexBuffer to the screen using + * the interpretation given in Shader. * @param va Stores all Vertex Data. * @param ib Specifies the drawing order of the VertexArray. * @param shader Shader telling how to draw data. @@ -31,10 +31,39 @@ class Renderer void draw2D(const VertexArray& va, const IndexBuffer& ib, const Shader& shader, const DrawMode& drawMode = DrawMode::Triangles) const; + /** + * \brief Draws the data given in VertexArray, IndexBuffer to the screen using + * the interpretation given in Shader. In additon information about view, projection + * and position are passed to the shader from camera. + * \param va Vertex array containing the object's vertices. + * \param ib Index buffer defining the order to draw the vertices. + * \param shader Shader program to apply during rendering. + * \param camera Camera object defining the view and projection matrices. + * \param drawMode (Optional) Specifies the mode of drawing (e.g., triangles, lines). + */ void draw3D(const VertexArray& va, const IndexBuffer& ib, const Shader& shader, const Camera& camera, const DrawMode& drawMode = DrawMode::Triangles) const; + /** + * \brief Draws the data given in VertexArray with specified number of vertices to + * the screen using the interpretation given in Shader. In additon information about + * view, projection and position are passed to the shader from camera. + * \param va Vertex array containing the object's vertices. + * \param numberOfVertices Number of vertices to draw. + * \param shader Shader program to use during rendering. + * \param camera Camera object for view and projection. + * \param drawMode Specifies the drawing mode (e.g., points, lines). + */ + void draw3D(const VertexArray& vb, int numberOfVertices, const Shader& shader, + const Camera& camera, const DrawMode& drawMode) const; + private: + /** + * \brief Convert a DrawMode enum value to the corresponding OpenGL mode. + * \param drawMode DrawMode enum value. + * \return Corresponding OpenGL drawing mode (e.g., GL_TRIANGLES). + */ unsigned toOpenGl(const DrawMode& drawMode) const; + sf::Window& mWindow; }; \ No newline at end of file diff --git a/AimGL/src/States/CustomStates/GameState.h b/AimGL/src/States/CustomStates/GameState.h index dd21974..3f510eb 100644 --- a/AimGL/src/States/CustomStates/GameState.h +++ b/AimGL/src/States/CustomStates/GameState.h @@ -9,6 +9,7 @@ #include #include +#include class StateStack; diff --git a/AimGL/src/World/Physics/Collider.cpp b/AimGL/src/World/Physics/Collider.cpp new file mode 100644 index 0000000..fcf16d8 --- /dev/null +++ b/AimGL/src/World/Physics/Collider.cpp @@ -0,0 +1,2 @@ +#include "Collider.h" +#include "pch.h" \ No newline at end of file diff --git a/AimGL/src/World/Physics/Collider.h b/AimGL/src/World/Physics/Collider.h new file mode 100644 index 0000000..98247ab --- /dev/null +++ b/AimGL/src/World/Physics/Collider.h @@ -0,0 +1,13 @@ +#pragma once + +class SphereCollider; +class RectangleCollider; + +class Collider +{ +public: + virtual ~Collider() = default; + virtual bool checkCollision(const Collider& other) const = 0; + virtual bool checkCollisionWith(const SphereCollider& other) const = 0; + virtual bool checkCollisionWith(const RectangleCollider& other) const = 0; +}; \ No newline at end of file diff --git a/AimGL/src/World/Physics/Collisions.h b/AimGL/src/World/Physics/Collisions.h new file mode 100644 index 0000000..86a5909 --- /dev/null +++ b/AimGL/src/World/Physics/Collisions.h @@ -0,0 +1,8 @@ +#pragma once + +bool checkSphereRectangleCollision(const SphereCollider& sphere, const RectangleCollider& rectangle) +{ + glm::vec3 closestPoint = glm::clamp(sphere.center, aabb.min, aabb.max); + float distanceSquared = glm::distance2(sphere.center, closestPoint); + return distanceSquared < (sphere.radius * sphere.radius); +} \ No newline at end of file diff --git a/AimGL/src/World/Physics/Ray.cpp b/AimGL/src/World/Physics/Ray.cpp new file mode 100644 index 0000000..945c31e --- /dev/null +++ b/AimGL/src/World/Physics/Ray.cpp @@ -0,0 +1,27 @@ +#include "Ray.h" +#include "pch.h" + +#include + +Ray::Ray(const glm::vec3& origin, const glm::vec3& direction, float length) + : mOrigin(origin) + , mDirection(glm::normalize(direction)) + , mLength(length) + , mShader{{ShaderType::VertexShader, "resources/Shaders/Graphics/Physics/Ray.vs"}, + {ShaderType::FragmentShader, "resources/Shaders/Graphics/Physics/Ray.fs"}} +{ + glm::vec3 endPoint = mOrigin + mDirection * mLength; + + std::vector vertices = {mOrigin.x, mOrigin.y, mOrigin.z, + endPoint.x, endPoint.y, endPoint.z}; + mBufferLayout.push(3); + + mVBO.setBuffer(vertices); + mVAO.setBuffer(mVBO, mBufferLayout); +} + +void Ray::draw(const Renderer& target, const Camera& camera) const +{ + constexpr auto numberOfVertices = 6; + target.draw3D(mVAO, numberOfVertices, mShader, camera, Renderer::DrawMode::Lines); +} diff --git a/AimGL/src/World/Physics/Ray.h b/AimGL/src/World/Physics/Ray.h new file mode 100644 index 0000000..193bb05 --- /dev/null +++ b/AimGL/src/World/Physics/Ray.h @@ -0,0 +1,47 @@ +#pragma once +#include "Renderer/Core/Buffers/BufferLayout.h" +#include "Renderer/Core/Buffers/VertexBuffer.h" +#include "Renderer/Core/VertexArray.h" + +#include + +class Camera; +class Renderer; + +/** + * \brief Represents a ray in 3D space, defined by an origin point, direction vector, and length. + */ +class Ray +{ +public: + /** + * \brief Constructs a Ray object. + * \param origin The starting point of the ray in 3D space. + * \param direction The direction vector of the ray. This vector should be normalized. + * \param length (Optional) The length of the ray. Default is 100 units. + */ + Ray(const glm::vec3& origin, const glm::vec3& direction, float length = 100); + Ray(Ray&&) noexcept = default; + + /** + * \brief Draws a Ray for a given target + * \param target The target to which the model is drawn + * \param camera A camera in 3D space that looks at this object + */ + void draw(const Renderer& target, const Camera& camera) const; + + /** + * Updates the Ray logic dependent, or independent of time, every rendered frame. + * \param deltaTime the time that has passed since the game was last updated. + */ + void update(const float& deltaTime); + +private: + VertexArray mVAO; + VertexBuffer mVBO; + BufferLayout mBufferLayout; + glm::vec3 mOrigin; + glm::vec3 mDirection; + float mLength; + Shader mShader; +}; diff --git a/AimGL/src/World/Physics/RectangleCollider.cpp b/AimGL/src/World/Physics/RectangleCollider.cpp new file mode 100644 index 0000000..e931b82 --- /dev/null +++ b/AimGL/src/World/Physics/RectangleCollider.cpp @@ -0,0 +1,2 @@ +#include "RectangleCollider.h" +#include "pch.h" \ No newline at end of file diff --git a/AimGL/src/World/Physics/RectangleCollider.h b/AimGL/src/World/Physics/RectangleCollider.h new file mode 100644 index 0000000..0ef7a45 --- /dev/null +++ b/AimGL/src/World/Physics/RectangleCollider.h @@ -0,0 +1,31 @@ +#pragma once + +class RectangleCollider : public Collider +{ +public: + glm::vec3 min;// Minimum point + glm::vec3 max;// Maximum point + + RectangleCollider(const glm::vec3& min, const glm::vec3& max) + : min(min) + , max(max) + { + } + + bool checkCollision(const Collider& other) const override + { + return other.checkCollisionWith(*this); + } + + bool checkCollisionWith(const SphereCollider& other) const override + { + return checkSphereRectangleCollision(other, *this); + } + + bool checkCollisionWith(const RectangleCollider& other) const override + { + return (min.x <= other.max.x && max.x >= other.min.x) && + (min.y <= other.max.y && max.y >= other.min.y) && + (min.z <= other.max.z && max.z >= other.min.z); + } +}; \ No newline at end of file diff --git a/AimGL/src/World/Physics/SphereCollider.cpp b/AimGL/src/World/Physics/SphereCollider.cpp new file mode 100644 index 0000000..dd26357 --- /dev/null +++ b/AimGL/src/World/Physics/SphereCollider.cpp @@ -0,0 +1,2 @@ +#include "SphereCollider.h" +#include "pch.h" diff --git a/AimGL/src/World/Physics/SphereCollider.h b/AimGL/src/World/Physics/SphereCollider.h new file mode 100644 index 0000000..842c24e --- /dev/null +++ b/AimGL/src/World/Physics/SphereCollider.h @@ -0,0 +1,31 @@ +#pragma once + +class SphereCollider : public Collider +{ +public: + glm::vec3 center; + float radius; + + SphereCollider(const glm::vec3& center, float radius) + : center(center) + , radius(radius) + { + } + + bool checkCollision(const Collider& other) const override + { + return other.checkCollisionWith(*this); + } + + bool checkCollisionWith(const SphereCollider& other) const override + { + float distanceSquared = glm::distance2(center, other.center); + float radiusSum = radius + other.radius; + return distanceSquared < (radiusSum * radiusSum); + } + + bool checkCollisionWith(const RectangleCollider& other) const override + { + return checkSphereRectangleCollision(*this, other); + } +}; diff --git a/AimGL/src/World/GameObjects/Rifle.cpp b/AimGL/src/World/Scene/GameObjects/Rifle.cpp similarity index 89% rename from AimGL/src/World/GameObjects/Rifle.cpp rename to AimGL/src/World/Scene/GameObjects/Rifle.cpp index fc93405..ffa3e3a 100644 --- a/AimGL/src/World/GameObjects/Rifle.cpp +++ b/AimGL/src/World/Scene/GameObjects/Rifle.cpp @@ -16,7 +16,13 @@ Rifle::Rifle(Camera& camera) void Rifle::draw(const Renderer& target) const { + glDepthRange(0.0, 0.01); mGun.draw(target, mCamera); + glDepthRange(0.0, 1.0); + if (mLatelyShotRay.has_value()) + { + mLatelyShotRay.value().draw(target, mCamera); + } } void Rifle::update(const float& deltaTime) @@ -58,5 +64,6 @@ void Rifle::handleEvent(const sf::Event& event) mCurrentRecoil = std::min(mCurrentRecoil, RECOIL_OFFSET_MAX); mCamera.shake(); mGunShotSound.play(); + mLatelyShotRay.emplace(mCamera.cameraPosition(), mCamera.direction()); } -} +} \ No newline at end of file diff --git a/AimGL/src/World/GameObjects/Rifle.h b/AimGL/src/World/Scene/GameObjects/Rifle.h similarity index 91% rename from AimGL/src/World/GameObjects/Rifle.h rename to AimGL/src/World/Scene/GameObjects/Rifle.h index da01923..d5e6e37 100644 --- a/AimGL/src/World/GameObjects/Rifle.h +++ b/AimGL/src/World/Scene/GameObjects/Rifle.h @@ -1,4 +1,5 @@ #pragma once +#include "World/Physics/Ray.h" #include #include #include @@ -36,6 +37,7 @@ class Rifle */ void handleEvent(const sf::Event& event); + private: /** * \brief Updates logic related to attaching rifle to camera @@ -51,4 +53,6 @@ class Rifle float mCurrentRecoil{0}; sf::SoundBuffer mSoundBuffer; sf::Sound mGunShotSound; + std::optional mLatelyShotRay; + std::vector> mRaySubscribers; }; \ No newline at end of file diff --git a/AimGL/src/World/Scene/GameObjects/Target.cpp b/AimGL/src/World/Scene/GameObjects/Target.cpp new file mode 100644 index 0000000..c561b60 --- /dev/null +++ b/AimGL/src/World/Scene/GameObjects/Target.cpp @@ -0,0 +1,2 @@ +#include "Target.h" +#include "pch.h" \ No newline at end of file diff --git a/AimGL/src/World/Scene/GameObjects/Target.h b/AimGL/src/World/Scene/GameObjects/Target.h new file mode 100644 index 0000000..6084655 --- /dev/null +++ b/AimGL/src/World/Scene/GameObjects/Target.h @@ -0,0 +1,5 @@ +#pragma once + +class Target +{ +}; diff --git a/AimGL/src/main.cpp b/AimGL/src/main.cpp index f0434d5..bf7eef7 100644 --- a/AimGL/src/main.cpp +++ b/AimGL/src/main.cpp @@ -8,8 +8,11 @@ int main() _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); #endif -#ifdef MTR_ENABLED&& defined(_DEBUG) +#if defined(_DEBUG) + spdlog::set_level(spdlog::level::debug); + #ifdef MTR_ENABLED spdlog::warn("MiniTrace is enabled!"); + #endif #endif try