diff --git a/Game.cpp b/Game.cpp index 655150d..58d69ef 100755 --- a/Game.cpp +++ b/Game.cpp @@ -9,23 +9,14 @@ namespace ZL { -void Game::worldToScreenCoordinates(Vector3f objectPos, - Matrix4f projectionModelView, - int screenWidth, int screenHeight, - int& screenX, int& screenY) { - - Vector4f inx = { objectPos.v[0], objectPos.v[1], objectPos.v[2], 1.0f}; - Vector4f clipCoords = MultMatrixVector(projectionModelView, inx); - - float ndcX = clipCoords.v[0] / clipCoords.v[3]; - float ndcY = clipCoords.v[1] / clipCoords.v[3]; - - screenX = (int)((ndcX + 1.0f) * 0.5f * screenWidth); - screenY = (int)((1.0f + ndcY) * 0.5f * screenHeight); -} - -Game::Game() : window(nullptr), glContext(nullptr), exitGameLoop(false), - newTickCount(0), lastTickCount(0) { +Game::Game() + : window(nullptr) + , glContext(nullptr) + , exitGameLoop(false) + , newTickCount(0) + , lastTickCount(0) + , renderer(renderSystem.getRenderer()) // Инициализация ссылки на renderer +{ } Game::~Game() { @@ -66,100 +57,8 @@ void Game::setup() { } void Game::drawScene() { - static const std::string defaultShaderName = "default"; - static const std::string vPositionName = "vPosition"; - static const std::string vTexCoordName = "vTexCoord"; - static const std::string textureUniformName = "Texture"; - - glClearColor(0.3f, 0.3f, 0.3f, 1.0f); - glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - - glViewport(0, 0, Environment::width, Environment::height); - - renderer.shaderManager.PushShader(defaultShaderName); - renderer.RenderUniform1i(textureUniformName, 0); - - renderer.EnableVertexAttribArray(vPositionName); - renderer.EnableVertexAttribArray(vTexCoordName); - - // 3D Scene rendering - { - renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5, - static_cast(Environment::width) / static_cast(Environment::height), - 50, 10000); - renderer.PushMatrix(); - - renderer.LoadIdentity(); - renderer.TranslateMatrix({ 0,0, -100 * Environment::zoom }); - - float t = 0.3; - renderer.RotateMatrix(QuatFromRotateAroundX(t * M_PI / 2.0)); - - // Draw cone - glBindTexture(GL_TEXTURE_2D, gameObjects.coneTexturePtr->getTexID()); - renderer.DrawVertexRenderStruct(gameObjects.coneMeshMutable); - - renderer.TranslateMatrix(Environment::cameraShift); - - // Draw active objects - for (auto& ao : gameObjects.activeObjects) { - renderer.PushMatrix(); - renderer.TranslateMatrix(ao.objectPos); - glBindTexture(GL_TEXTURE_2D, ao.activeObjectTexturePtr->getTexID()); - renderer.DrawVertexRenderStruct(ao.activeObjectMeshMutable); - renderer.PopMatrix(); - } - - // Draw room - glBindTexture(GL_TEXTURE_2D, gameObjects.roomTexturePtr->getTexID()); - renderer.DrawVertexRenderStruct(gameObjects.textMeshMutable); - - auto latestProjectionModelView = renderer.GetProjectionModelViewMatrix(); - - renderer.PopMatrix(); - renderer.PopProjectionMatrix(); - - // 2D UI rendering - renderer.PushProjectionMatrix(static_cast(Environment::width), - static_cast(Environment::height)); - renderer.PushMatrix(); - renderer.LoadIdentity(); - - // Draw highlighted objects UI - for (auto& ao : gameObjects.activeObjects) { - if (ao.highlighted) { - int screenX, screenY; - worldToScreenCoordinates(ao.objectPos, latestProjectionModelView, - Environment::width, Environment::height, screenX, screenY); - renderer.PushMatrix(); - renderer.TranslateMatrix(Vector3f{screenX + 0.f, screenY + 0.f, 0.0f}); - glBindTexture(GL_TEXTURE_2D, ao.activeObjectScreenTexturePtr->getTexID()); - renderer.DrawVertexRenderStruct(ao.activeObjectScreenMeshMutable); - renderer.PopMatrix(); - } - } - - // Draw inventory - const auto& inventory = ZL::ReturnInventory(); - for (size_t i = 0; i < inventory.size(); ++i) { - renderer.PushMatrix(); - float xPos = Environment::width - gameObjects.INVENTORY_MARGIN - gameObjects.INVENTORY_ICON_SIZE; - float yPos = gameObjects.INVENTORY_MARGIN + i * (gameObjects.INVENTORY_ICON_SIZE + gameObjects.INVENTORY_MARGIN); - renderer.TranslateMatrix(Vector3f{xPos, yPos, 0.0f}); - glBindTexture(GL_TEXTURE_2D, inventory[i].texture->getTexID()); - renderer.DrawVertexRenderStruct(gameObjects.inventoryIconMeshMutable); - renderer.PopMatrix(); - } - - renderer.PopMatrix(); - renderer.PopProjectionMatrix(); - } - - renderer.DisableVertexAttribArray(vPositionName); - renderer.DisableVertexAttribArray(vTexCoordName); - renderer.shaderManager.PopShader(); - - CheckGlError(); + // Вместо прямого рисования используем RenderSystem + renderSystem.drawScene(gameObjects); } void Game::processTickCount() { diff --git a/Game.h b/Game.h index 73898d1..90f9567 100755 --- a/Game.h +++ b/Game.h @@ -2,7 +2,7 @@ #include #include "GameObjectManager.h" -#include "Renderer.h" +#include "RenderSystem.h" #include "Environment.h" namespace ZL { @@ -22,15 +22,12 @@ public: private: void processTickCount(); void drawScene(); - void worldToScreenCoordinates(Vector3f objectPos, - Matrix4f projectionModelView, - int screenWidth, int screenHeight, - int& screenX, int& screenY); SDL_Window* window; SDL_GLContext glContext; - Renderer renderer; + RenderSystem renderSystem; GameObjectManager gameObjects; + Renderer& renderer; // Ссылка на renderer из RenderSystem bool exitGameLoop; size_t newTickCount; @@ -40,4 +37,4 @@ private: static const size_t CONST_MAX_TIME_INTERVAL = 1000; }; -} // namespace ZL \ No newline at end of file +} // namespace ZL \ No newline at end of file diff --git a/RenderSystem.cpp b/RenderSystem.cpp new file mode 100644 index 0000000..8290d5b --- /dev/null +++ b/RenderSystem.cpp @@ -0,0 +1,133 @@ +#include "RenderSystem.h" +#include "Environment.h" +#include "Utils.h" +#include "Inventory.h" +#include + +namespace ZL { + +void RenderSystem::initialize() { + renderer.shaderManager.AddShaderFromFiles("default", "./default.vertex", "./default.fragment"); + renderer.shaderManager.AddShaderFromFiles("defaultColor", "./defaultColor.vertex", "./defaultColor.fragment"); + renderer.InitOpenGL(); +} + +void RenderSystem::drawScene(const GameObjectManager& gameObjects) { + static const std::string defaultShaderName = "default"; + static const std::string vPositionName = "vPosition"; + static const std::string vTexCoordName = "vTexCoord"; + static const std::string textureUniformName = "Texture"; + + glClearColor(0.3f, 0.3f, 0.3f, 1.0f); + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + + glViewport(0, 0, Environment::width, Environment::height); + + renderer.shaderManager.PushShader(defaultShaderName); + renderer.RenderUniform1i(textureUniformName, 0); + + renderer.EnableVertexAttribArray(vPositionName); + renderer.EnableVertexAttribArray(vTexCoordName); + + drawWorld(gameObjects); + drawUI(gameObjects); + + renderer.DisableVertexAttribArray(vPositionName); + renderer.DisableVertexAttribArray(vTexCoordName); + renderer.shaderManager.PopShader(); + + CheckGlError(); +} + +void RenderSystem::drawWorld(const GameObjectManager& gameObjects) { + renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5, + static_cast(Environment::width) / static_cast(Environment::height), + 50, 10000); + renderer.PushMatrix(); + + renderer.LoadIdentity(); + renderer.TranslateMatrix({ 0,0, -100 * Environment::zoom }); + + float t = 0.3; + renderer.RotateMatrix(QuatFromRotateAroundX(t * M_PI / 2.0)); + + // Draw cone + glBindTexture(GL_TEXTURE_2D, gameObjects.coneTexturePtr->getTexID()); + renderer.DrawVertexRenderStruct(gameObjects.coneMeshMutable); + + renderer.TranslateMatrix(Environment::cameraShift); + + // Draw active objects + for (const auto& ao : gameObjects.activeObjects) { + renderer.PushMatrix(); + renderer.TranslateMatrix(ao.objectPos); + glBindTexture(GL_TEXTURE_2D, ao.activeObjectTexturePtr->getTexID()); + renderer.DrawVertexRenderStruct(ao.activeObjectMeshMutable); + renderer.PopMatrix(); + } + + // Draw room + glBindTexture(GL_TEXTURE_2D, gameObjects.roomTexturePtr->getTexID()); + renderer.DrawVertexRenderStruct(gameObjects.textMeshMutable); + + Matrix4f latestProjectionModelView = renderer.GetProjectionModelViewMatrix(); + + renderer.PopMatrix(); + renderer.PopProjectionMatrix(); + + // Store matrix for UI rendering + currentProjectionModelView = latestProjectionModelView; +} + +void RenderSystem::drawUI(const GameObjectManager& gameObjects) { + renderer.PushProjectionMatrix(static_cast(Environment::width), + static_cast(Environment::height)); + renderer.PushMatrix(); + renderer.LoadIdentity(); + + // Draw highlighted objects UI + for (const auto& ao : gameObjects.activeObjects) { + if (ao.highlighted) { + int screenX, screenY; + worldToScreenCoordinates(ao.objectPos, currentProjectionModelView, + Environment::width, Environment::height, screenX, screenY); + renderer.PushMatrix(); + renderer.TranslateMatrix(Vector3f{screenX + 0.f, screenY + 0.f, 0.0f}); + glBindTexture(GL_TEXTURE_2D, ao.activeObjectScreenTexturePtr->getTexID()); + renderer.DrawVertexRenderStruct(ao.activeObjectScreenMeshMutable); + renderer.PopMatrix(); + } + } + + // Draw inventory + const auto& inventory = ZL::ReturnInventory(); + for (size_t i = 0; i < inventory.size(); ++i) { + renderer.PushMatrix(); + float xPos = Environment::width - gameObjects.INVENTORY_MARGIN - gameObjects.INVENTORY_ICON_SIZE; + float yPos = gameObjects.INVENTORY_MARGIN + i * (gameObjects.INVENTORY_ICON_SIZE + gameObjects.INVENTORY_MARGIN); + renderer.TranslateMatrix(Vector3f{xPos, yPos, 0.0f}); + glBindTexture(GL_TEXTURE_2D, inventory[i].texture->getTexID()); + renderer.DrawVertexRenderStruct(gameObjects.inventoryIconMeshMutable); + renderer.PopMatrix(); + } + + renderer.PopMatrix(); + renderer.PopProjectionMatrix(); +} + +void RenderSystem::worldToScreenCoordinates(Vector3f objectPos, + Matrix4f projectionModelView, + int screenWidth, int screenHeight, + int& screenX, int& screenY) { + + Vector4f inx = { objectPos.v[0], objectPos.v[1], objectPos.v[2], 1.0f}; + Vector4f clipCoords = MultMatrixVector(projectionModelView, inx); + + float ndcX = clipCoords.v[0] / clipCoords.v[3]; + float ndcY = clipCoords.v[1] / clipCoords.v[3]; + + screenX = (int)((ndcX + 1.0f) * 0.5f * screenWidth); + screenY = (int)((1.0f + ndcY) * 0.5f * screenHeight); +} + +} // namespace ZL diff --git a/RenderSystem.h b/RenderSystem.h new file mode 100644 index 0000000..951bcbd --- /dev/null +++ b/RenderSystem.h @@ -0,0 +1,29 @@ +#pragma once +#include "Renderer.h" +#include "GameObjectManager.h" +#include + +namespace ZL { + +class RenderSystem { +public: + RenderSystem() = default; + void initialize(); + void drawScene(const GameObjectManager& gameObjects); + Renderer& getRenderer() { return renderer; } + + void worldToScreenCoordinates(Vector3f objectPos, + Matrix4f projectionModelView, + int screenWidth, int screenHeight, + int& screenX, int& screenY); + +private: + void drawWorld(const GameObjectManager& gameObjects); + void drawUI(const GameObjectManager& gameObjects); + + Renderer renderer; + ShaderManager shaderManager; + Matrix4f currentProjectionModelView; // Добавлено для хранения матрицы между drawWorld и drawUI +}; + +} // namespace ZL diff --git a/start.sh b/start.sh index 65dd930..b3235c2 100755 --- a/start.sh +++ b/start.sh @@ -1,7 +1,7 @@ g++ Game.cpp main.cpp Math.cpp OpenGlExtensions.cpp Physics.cpp Renderer.cpp \ ShaderManager.cpp TextureManager.cpp Utils.cpp BoneAnimatedModel.cpp \ ObjLoader.cpp cmakeaudioplayer/src/AudioPlayer.cpp TextModel.cpp \ - Inventory.cpp Environment.cpp GameObjectManager.cpp \ + Inventory.cpp Environment.cpp GameObjectManager.cpp RenderSystem.cpp \ -o sdl_app -O2 -std=c++17 \ -I cmakeaudioplayer/include \ $(pkg-config --cflags --libs sdl2 gl) \