From 784d355906ebefa4ff6ea7207f5f61c854b20a85 Mon Sep 17 00:00:00 2001 From: Andre Popovitch Date: Thu, 10 Oct 2024 23:28:34 -0500 Subject: [PATCH] Store objects with World --- OpenGL/CMakeLists.txt | 4 +- OpenGL/src/Application.cpp | 66 +++++------------------- OpenGL/src/Renderer.cpp | 28 ---------- OpenGL/src/World.cpp | 51 +++++++++--------- OpenGL/src/World.h | 8 +-- OpenGL/src/game_objects/Camera.cpp | 4 +- OpenGL/src/game_objects/GameObject.cpp | 4 +- OpenGL/src/game_objects/SquareObject.cpp | 2 +- OpenGL/src/game_objects/Tile.cpp | 7 ++- OpenGL/src/rendering/Buffer.h | 2 +- OpenGL/src/rendering/RenderPass.cpp | 27 ---------- OpenGL/src/rendering/Renderer.cpp | 30 +++++++++++ OpenGL/src/rendering/Texture.h | 4 ++ 13 files changed, 93 insertions(+), 144 deletions(-) diff --git a/OpenGL/CMakeLists.txt b/OpenGL/CMakeLists.txt index 88bfadae..d2de1029 100644 --- a/OpenGL/CMakeLists.txt +++ b/OpenGL/CMakeLists.txt @@ -7,8 +7,8 @@ set(CMAKE_CXX_STANDARD 23) set(VENDOR_DIR ${CMAKE_CURRENT_SOURCE_DIR}/vendor) # Add application code -file(GLOB cpp_files "src/Application.cpp" "src/rendering/*.cpp" "src/game_objects/GameObject.cpp" "src/game_objects/Background.cpp" "src/game_objects/SquareObject.cpp", "src/Input.cpp", "src/game_objects/Tile.cpp") -file(GLOB header_files "src/Application.h" "src/rendering/*.h" "src/game_objects/GameObject.h" "src/game_objects/Background.h" "src/game_objects/SquareObject.h" "src/Input.h" "src/game_objects/Tile.h") +file(GLOB cpp_files "src/Application.cpp" "src/rendering/*.cpp" "src/game_objects/GameObject.cpp" "src/game_objects/Background.cpp" "src/game_objects/SquareObject.cpp" "src/Input.cpp" "src/game_objects/Tile.cpp" "src/World.cpp" "src/game_objects/Camera.cpp" "src/WeakMemoizeConstructor.hpp") +file(GLOB header_files "src/Application.h" "src/rendering/*.h" "src/game_objects/GameObject.h" "src/game_objects/Background.h" "src/game_objects/SquareObject.h" "src/Input.h" "src/game_objects/Tile.h" "src/World.h" "src/game_objects/Camera.h") # Add resource files file(GLOB_RECURSE res_files "res/*") diff --git a/OpenGL/src/Application.cpp b/OpenGL/src/Application.cpp index 66643748..0f710f34 100644 --- a/OpenGL/src/Application.cpp +++ b/OpenGL/src/Application.cpp @@ -42,6 +42,7 @@ #include "game_objects/Background.h" #include "game_objects/SquareObject.h" #include "game_objects/Tile.h" +#include "World.h" #define GL_SILENCE_DEPRECATION @@ -50,6 +51,9 @@ #endif #include // Will drag system OpenGL headers + +const float TICKS_PER_SECOND = 3.0f; + void setWindowIcon(GLFWwindow* window, const char* iconPath) { int width, height, channels; unsigned char* pixels = stbi_load(iconPath, &width, &height, &channels, 4); @@ -291,6 +295,8 @@ Application::Application() , uncapturedErrorCallbackHandle(getUncapturedErrorCallbackHandle(device)) , queue(device.getQueue()) , surfaceFormat(preferredFormat(surface, adapter)) { + glfwSetKeyCallback(window, key_callback); + glfwSetWindowUserPointer(window, this); // Use a non-capturing lambda as resize callback glfwSetFramebufferSizeCallback(window, [](GLFWwindow* window, int, int) { @@ -302,6 +308,9 @@ Application::Application() InitializeResPath(); + std::string icon_path = res_path / "images" / "Logo2.png"; + setWindowIcon(window, icon_path.c_str()); + initialized = true; } @@ -374,12 +383,12 @@ wgpu::TextureView Application::GetNextSurfaceTextureView() { } // Draw a frame and handle events -void mainLoop(Application& application, Renderer& renderer, std::vector>& gameobjects) { +void mainLoop(Application& application, Renderer& renderer) { glfwPollEvents(); auto device = application.getDevice(); - for (auto& gameobject : gameobjects) { + for (auto& gameobject : World::gameobjects) { gameobject->update(); } @@ -391,9 +400,7 @@ void mainLoop(Application& application, Renderer& renderer, std::vectorrender(renderer); - } + World::RenderObjects(renderer); // The render pass and command encoder will be ended and submitted in their destructors } @@ -415,11 +422,7 @@ int main(void) { Application& application = Application::get(); Renderer renderer = Renderer(); - std::vector> gameobjects; - gameobjects.push_back(std::make_unique("Stars")); - gameobjects.push_back(std::make_unique("Floor", DrawPriority::Floor, 0, 0, "floor.png")); - gameobjects.push_back(std::make_unique("Tile", true, true, 1, 0)); - gameobjects.push_back(std::make_unique("Tile", false, true, 0, 1)); + World::LoadMap("SpaceShip.txt"); // Not Emscripten-friendly if (!application.initialized) { @@ -428,7 +431,7 @@ int main(void) { // Not emscripten-friendly while (application.IsRunning()) { - mainLoop(application, renderer, gameobjects); + mainLoop(application, renderer); } application.Terminate(); @@ -437,47 +440,6 @@ int main(void) { /* - const float TICKS_PER_SECOND = 3.0f; - - /* Initialize the library * / - if (!glfwInit()) - return -1; - - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - - // Get the primary monitor - GLFWmonitor* primaryMonitor = glfwGetPrimaryMonitor(); - const GLFWvidmode* mode = glfwGetVideoMode(primaryMonitor); - - // Create a fullscreen window - GLFWwindow* window = glfwCreateWindow(mode->width, mode->height, "SpaceBoom", NULL, NULL); - if (!window) { - std::cerr << "Failed to create GLFW window" << std::endl; - glfwTerminate(); - return -1; - } - - glfwSetKeyCallback(window, key_callback); - - // Set the window icon - std::string icon_path = Renderer::ResPath() + "images/Logo2.png"; - setWindowIcon(window, icon_path.c_str()); - - /* Make the window's context current * / - glfwMakeContextCurrent(window); - - glfwSwapInterval(1); - - if (glewInit() != GLEW_OK) - std::cout << "Error!" << std::endl; - - std::cout << "current version of GL: " << glGetString(GL_VERSION) << std::endl; - - GLCall(glEnable(GL_BLEND)); - GLCall(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); - // Initialize ImGui IMGUI_CHECKVERSION(); ImGui::CreateContext(); diff --git a/OpenGL/src/Renderer.cpp b/OpenGL/src/Renderer.cpp index 40250937..6175b0f2 100644 --- a/OpenGL/src/Renderer.cpp +++ b/OpenGL/src/Renderer.cpp @@ -13,34 +13,6 @@ ImFont* load_font(ImGuiIO* io, const std::string& font_name, int size) { return font; } -glm::mat4 CalculateMVP(std::tuple windowSize, const glm::vec2& objectPosition, float objectRotationDegrees, - float objectScale) { - // Retrieve window size from the renderer - auto [width, height] = windowSize; - - // Calculate aspect ratio - float aspectRatio = static_cast(width) / static_cast(height); - - // Create orthographic projection matrix - float orthoWidth = Camera::scale * aspectRatio; - glm::mat4 projection = - glm::ortho(-orthoWidth / 2.0f, orthoWidth / 2.0f, -Camera::scale / 2.0f, Camera::scale / 2.0f, -1.0f, 1.0f); - - // Create view matrix - glm::mat4 view = glm::translate(glm::mat4(1.0f), glm::vec3(-Camera::position, 0.0f)); - - // Create model matrix - glm::mat4 model = glm::translate(glm::mat4(1.0f), glm::vec3(objectPosition, 0.0f)); - float rotationRadians = glm::radians(objectRotationDegrees); - model = glm::rotate(model, rotationRadians, glm::vec3(0.0f, 0.0f, 1.0f)); - model = glm::scale(model, glm::vec3(objectScale, objectScale, 1.0f)); - - // Combine matrices to form MVP - glm::mat4 mvp = projection * view * model; - - return mvp; -} - glm::vec2 Renderer::ScreenToWorldPosition(const glm::vec2& screenPos) { // Retrieve window size from the renderer auto [width, height] = WindowSize(); diff --git a/OpenGL/src/World.cpp b/OpenGL/src/World.cpp index 37d04c33..274fd60b 100644 --- a/OpenGL/src/World.cpp +++ b/OpenGL/src/World.cpp @@ -1,16 +1,17 @@ +#include "World.h" + #include #include -#include "World.h" #include -#include "Renderer.h" -#include "game_objects/Player.h" +#include "rendering/Renderer.h" +// #include "game_objects/Player.h" #include "game_objects/Background.h" #include "game_objects/Camera.h" #include "game_objects/Tile.h" -#include "game_objects/enemies/Bomber.h" -#include "game_objects/enemies/Turret.h" -#include "game_objects/Mine.h" +// #include "game_objects/enemies/Bomber.h" +// #include "game_objects/enemies/Turret.h" +// #include "game_objects/Mine.h" std::vector> World::gameobjects = {}; std::vector> World::gameobjectstoadd = {}; @@ -18,13 +19,15 @@ float World::timeSpeed = 1.0f; bool World::settingTimeSpeed = false; bool World::shouldTick = false; -void World::LoadMap(const std::string& map_path) { +void World::LoadMap(const std::filesystem::path& map_path) { gameobjects.clear(); - std::ifstream file(Renderer::ResPath() + map_path); + std::filesystem::path map_path_full = Application::get().res_path / "maps" / map_path; + + std::ifstream file(map_path_full); if (!file.is_open()) { - std::cerr << "Error opening file: " << map_path << std::endl; + std::cerr << "Error opening file: " << map_path_full << std::endl; } std::vector lines; @@ -43,32 +46,32 @@ void World::LoadMap(const std::string& map_path) { size_t y = total_rows - row; if (c != '\n') { if (c == 'b') { // Background - gameobjects.push_back(std::make_shared(Background("Background"))); + gameobjects.push_back(std::make_shared("Background")); } if (c == 'p') { // player - gameobjects.push_back(std::make_shared(Player("Coolbox", (float)x, (float)y))); - gameobjects.push_back(std::make_shared(Tile("Floor", (float)x, (float)y))); + // gameobjects.push_back(std::make_shared(Player("Coolbox", (float)x, (float)y))); + gameobjects.push_back(std::make_shared("Floor", (float)x, (float)y)); } if (c == 'f') { // floor - gameobjects.push_back(std::make_shared(Tile("Floor", (float)x, (float)y))); + gameobjects.push_back(std::make_shared("Floor", (float)x, (float)y)); } if (c == 'w') { // wall - gameobjects.push_back(std::make_shared(Tile("Wall", true, false, (float)x, (float)y))); + gameobjects.push_back(std::make_shared("Wall", true, false, (float)x, (float)y)); } if (c == 'W') { // wall - gameobjects.push_back(std::make_shared(Tile("Wall", true, true, (float)x, (float)y))); + gameobjects.push_back(std::make_shared("Wall", true, true, (float)x, (float)y)); } if (c == 'e') { // enemy Bomber - gameobjects.push_back(std::make_shared(Bomber("bomber", (float)x, (float)y))); - gameobjects.push_back(std::make_shared(Tile("Floor", (float)x, (float)y))); + // gameobjects.push_back(std::make_shared(Bomber("bomber", (float)x, (float)y))); + gameobjects.push_back(std::make_shared("Floor", (float)x, (float)y)); } if (c == 't') { // Turret - gameobjects.push_back(std::make_shared(Turret("turret", (float)x, (float)y))); - gameobjects.push_back(std::make_shared(Tile("Floor", (float)x, (float)y))); + // gameobjects.push_back(std::make_shared(Turret("turret", (float)x, (float)y))); + gameobjects.push_back(std::make_shared("Floor", (float)x, (float)y)); } if (c == 'm') { // Mine - gameobjects.push_back(std::make_shared(Mine("mine", (float)x, (float)y))); - gameobjects.push_back(std::make_shared(Tile("Floor", (float)x, (float)y))); + // gameobjects.push_back(std::make_shared(Mine("mine", (float)x, (float)y))); + gameobjects.push_back(std::make_shared("Floor", (float)x, (float)y)); } } } @@ -126,6 +129,8 @@ void World::RenderObjects(Renderer& renderer) { } bool World::ticksPaused() { - auto player = getFirst(); - return player->pauseTicks(); + // TODO: uncomment + // auto player = getFirst(); + // return player->pauseTicks(); + return false; } diff --git a/OpenGL/src/World.h b/OpenGL/src/World.h index 1c325549..a436b46b 100644 --- a/OpenGL/src/World.h +++ b/OpenGL/src/World.h @@ -1,9 +1,11 @@ // World.h #pragma once +#include #include + #include "game_objects/GameObject.h" -#include "Renderer.h" +#include "rendering/Renderer.h" class World { public: @@ -14,7 +16,7 @@ class World { static bool ticksPaused(); - static std::vector get_gameobjects() { + static std::vector get_gameobjects() { // return a vector of all gameobjects and their gameobjects.children std::vector allGameObjects; for (auto& gameobject : gameobjects) { @@ -65,7 +67,7 @@ class World { return where([&](const T& obj) { return obj.tile_x == x && obj.tile_y == y; }); } - static void LoadMap(const std::string& map_path); + static void LoadMap(const std::filesystem::path& map_path); static void UpdateObjects(); static void TickObjects(); diff --git a/OpenGL/src/game_objects/Camera.cpp b/OpenGL/src/game_objects/Camera.cpp index 6ae18605..a79a764f 100644 --- a/OpenGL/src/game_objects/Camera.cpp +++ b/OpenGL/src/game_objects/Camera.cpp @@ -1,4 +1,4 @@ #include "Camera.h" -glm::vec2 Camera::position = {0.0, 0.0}; -float Camera::scale = 14.0f; +glm::vec2 Camera::position = {20.0, 30.0}; +float Camera::scale = 19.0f; diff --git a/OpenGL/src/game_objects/GameObject.cpp b/OpenGL/src/game_objects/GameObject.cpp index 611020c2..1ad319b4 100644 --- a/OpenGL/src/game_objects/GameObject.cpp +++ b/OpenGL/src/game_objects/GameObject.cpp @@ -16,4 +16,6 @@ void GameObject::update() {} void GameObject::tickUpdate() {} -void GameObject::render(Renderer& renderer) {} +void GameObject::render(Renderer& renderer) { + std::cout << "Rendering GameObject (you should not see this lol) " << name << std::endl; +} diff --git a/OpenGL/src/game_objects/SquareObject.cpp b/OpenGL/src/game_objects/SquareObject.cpp index f595e8a9..3eb893e4 100644 --- a/OpenGL/src/game_objects/SquareObject.cpp +++ b/OpenGL/src/game_objects/SquareObject.cpp @@ -28,7 +28,7 @@ SquareObject::SquareObject(const std::string& name, DrawPriority drawPriority, i SquareObjectVertexUniform{CalculateMVP(glm::vec2{tile_x, tile_y}, 0, 1)})), fragmentUniform( BufferView::create(SquareObjectFragmentUniform{glm::vec4(0.0f, 0.0f, 0.0f, 0.0f)})), - texture(std::make_shared(texturePath)) {} + texture(Texture::create(texturePath)) {} void SquareObject::render(Renderer& renderer) { this->vertexUniform.Update(SquareObjectVertexUniform{CalculateMVP(glm::vec2{tile_x, tile_y}, 0, 1)}); diff --git a/OpenGL/src/game_objects/Tile.cpp b/OpenGL/src/game_objects/Tile.cpp index 25e22a7c..4fa90ca6 100644 --- a/OpenGL/src/game_objects/Tile.cpp +++ b/OpenGL/src/game_objects/Tile.cpp @@ -4,10 +4,9 @@ Tile::Tile(const std::string& name, bool wall, bool unbreakable, float x, float : SquareObject(name, DrawPriority::Floor, x, y, "alt-wall-bright.png") , wall(wall) , unbreakable(unbreakable) - , wallTexture(std::make_shared("alt-wall-bright.png")) - , wallTextureUnbreakable(std::make_shared("alt-wall-unbreakable.png")) - , floorTexture( - std::make_shared(std::vector{"2-alt-floor.png", "2-alt-floor-2.png"}[rand() % 2])) { + , wallTexture(Texture::create("alt-wall-bright.png")) + , wallTextureUnbreakable(Texture::create("alt-wall-unbreakable.png")) + , floorTexture(Texture::create(std::vector{"2-alt-floor.png", "2-alt-floor-2.png"}[rand() % 2])) { setTexture(); } diff --git a/OpenGL/src/rendering/Buffer.h b/OpenGL/src/rendering/Buffer.h index 2896d11c..06e027b0 100644 --- a/OpenGL/src/rendering/Buffer.h +++ b/OpenGL/src/rendering/Buffer.h @@ -97,7 +97,7 @@ class Buffer : public std::enable_shared_from_this> { freeIndices_.pop_back(); } else { // Check if there's space in the current buffer - if (capacity_ < count_) { + if (count_ < capacity_) { allocatedIndex = count_; ++count_; } else { diff --git a/OpenGL/src/rendering/RenderPass.cpp b/OpenGL/src/rendering/RenderPass.cpp index 602edd11..65b9f3d6 100644 --- a/OpenGL/src/rendering/RenderPass.cpp +++ b/OpenGL/src/rendering/RenderPass.cpp @@ -2,7 +2,6 @@ #include "CommandEncoder.h" #include "Application.h" -#include "glm/gtc/matrix_transform.hpp" RenderPass::RenderPass(CommandEncoder& encoder) { auto& application = Application::get(); @@ -42,29 +41,3 @@ RenderPass::~RenderPass() { wgpu::RenderPassEncoder& RenderPass::get() { return renderPass_; } - - -glm::mat4 CalculateMVP(const glm::vec2& objectPosition, float objectRotationDegrees, float objectScale) { - glm::ivec2 windowSize = Application::get().windowSize(); - - // Calculate aspect ratio - float aspectRatio = static_cast(windowSize.x) / static_cast(windowSize.y); - - // Create orthographic projection matrix - float orthoWidth = 18 * aspectRatio; - glm::mat4 projection = glm::ortho(-orthoWidth / 2.0f, orthoWidth / 2.0f, -18 / 2.0f, 18 / 2.0f, -1.0f, 1.0f); - - // Create view matrix - glm::mat4 view = glm::translate(glm::mat4(1.0f), glm::vec3(-glm::vec2(1, 1), 0.0f)); - - // Create model matrix - glm::mat4 model = glm::translate(glm::mat4(1.0f), glm::vec3(objectPosition, 0.0f)); - float rotationRadians = glm::radians(objectRotationDegrees); - model = glm::rotate(model, rotationRadians, glm::vec3(0.0f, 0.0f, 1.0f)); - model = glm::scale(model, glm::vec3(objectScale, objectScale, 1.0f)); - - // Combine matrices to form MVP - glm::mat4 mvp = projection * view * model; - - return mvp; -} diff --git a/OpenGL/src/rendering/Renderer.cpp b/OpenGL/src/rendering/Renderer.cpp index ea2c607c..dc5d22b1 100644 --- a/OpenGL/src/rendering/Renderer.cpp +++ b/OpenGL/src/rendering/Renderer.cpp @@ -1,6 +1,9 @@ #include "Renderer.h" #include "Application.h" +#include "glm/gtc/matrix_transform.hpp" +#include "../game_objects/Camera.h" + RenderPipeline>, VertexBufferLayout> starPipeline() { auto& application = Application::get(); auto device = application.getDevice(); @@ -29,3 +32,30 @@ Renderer::Renderer() : stars(starPipeline()) , squareObject(squareObjectPipeline()) , device(Application::get().getDevice()) {} + + +glm::mat4 CalculateMVP(const glm::vec2& objectPosition, float objectRotationDegrees, float objectScale) { + glm::ivec2 windowSize = Application::get().windowSize(); + + // Calculate aspect ratio + float aspectRatio = static_cast(windowSize.x) / static_cast(windowSize.y); + + // Create orthographic projection matrix + float orthoWidth = Camera::scale * aspectRatio; + glm::mat4 projection = + glm::ortho(-orthoWidth / 2.0f, orthoWidth / 2.0f, -Camera::scale / 2.0f, Camera::scale / 2.0f, -1.0f, 1.0f); + + // Create view matrix + glm::mat4 view = glm::translate(glm::mat4(1.0f), glm::vec3(-Camera::position, 0.0f)); + + // Create model matrix + glm::mat4 model = glm::translate(glm::mat4(1.0f), glm::vec3(objectPosition, 0.0f)); + float rotationRadians = glm::radians(objectRotationDegrees); + model = glm::rotate(model, rotationRadians, glm::vec3(0.0f, 0.0f, 1.0f)); + model = glm::scale(model, glm::vec3(objectScale, objectScale, 1.0f)); + + // Combine matrices to form MVP + glm::mat4 mvp = projection * view * model; + + return mvp; +} diff --git a/OpenGL/src/rendering/Texture.h b/OpenGL/src/rendering/Texture.h index eeab1019..2c954079 100644 --- a/OpenGL/src/rendering/Texture.h +++ b/OpenGL/src/rendering/Texture.h @@ -8,6 +8,7 @@ #include // For std::memcpy #include // Ensure stb_image is included in your project #include "../Application.h" +#include "../WeakMemoizeConstructor.hpp" // Texture abstraction class class Texture { @@ -208,6 +209,9 @@ class Texture { uint32_t getHeight() const { return m_Height; } int32_t getBPP() const { return m_BPP; } + // Declare the global memoized constructor + DECLARE_GLOBAL_MEMOIZED_CONSTRUCTOR(Texture) + private: wgpu::Device& device_; wgpu::Queue& queue_;