From 592e008914e996013f2ddd94ec8f64203338374f Mon Sep 17 00:00:00 2001 From: Vladislav Khorev Date: Tue, 30 Dec 2025 16:16:50 +0300 Subject: [PATCH] Minor refactoring --- CMakeLists.txt | 86 +- AnimatedModel.h => src/AnimatedModel.h | 4 +- .../AudioPlayerAsync.cpp | 0 AudioPlayerAsync.h => src/AudioPlayerAsync.h | 0 .../BoneAnimatedModel.cpp | 0 .../BoneAnimatedModel.h | 4 +- Environment.cpp => src/Environment.cpp | 2 +- Environment.h => src/Environment.h | 4 +- Game.cpp => src/Game.cpp | 1565 ++++++++-------- Game.h => src/Game.h | 217 ++- Projectile.cpp => src/Projectile.cpp | 0 Projectile.h => src/Projectile.h | 6 +- SparkEmitter.cpp => src/SparkEmitter.cpp | 2 +- SparkEmitter.h => src/SparkEmitter.h | 6 +- TextModel.cpp => src/TextModel.cpp | 0 TextModel.h => src/TextModel.h | 4 +- UiManager.cpp => src/UiManager.cpp | 2 +- UiManager.h => src/UiManager.h | 4 +- {external => src/external}/nlohmann/json.hpp | 0 {gl => src/gl}/glext.h | 0 main.cpp => src/main.cpp | 176 +- PlanetData.cpp => src/planet/PlanetData.cpp | 0 PlanetData.h => src/planet/PlanetData.h | 6 +- .../planet/PlanetObject.cpp | 2 +- PlanetObject.h => src/planet/PlanetObject.h | 10 +- StoneObject.cpp => src/planet/StoneObject.cpp | 4 +- StoneObject.h => src/planet/StoneObject.h | 4 +- FrameBuffer.cpp => src/render/FrameBuffer.cpp | 0 FrameBuffer.h => src/render/FrameBuffer.h | 0 .../render/OpenGlExtensions.cpp | 670 +++---- .../render/OpenGlExtensions.h | 318 ++-- Renderer.cpp => src/render/Renderer.cpp | 1666 ++++++++--------- Renderer.h => src/render/Renderer.h | 286 +-- .../render/ShaderManager.cpp | 428 ++--- ShaderManager.h => src/render/ShaderManager.h | 126 +- .../render/TextureManager.cpp | 859 ++++----- .../render/TextureManager.h | 112 +- Perlin.cpp => src/utils/Perlin.cpp | 0 Perlin.h => src/utils/Perlin.h | 2 +- Utils.cpp => src/utils/Utils.cpp | 210 +-- Utils.h => src/utils/Utils.h | 38 +- ZLMath.cpp => src/utils/ZLMath.cpp | 2 +- ZLMath.h => src/utils/ZLMath.h | 358 ++-- 43 files changed, 3589 insertions(+), 3594 deletions(-) rename AnimatedModel.h => src/AnimatedModel.h (90%) rename AudioPlayerAsync.cpp => src/AudioPlayerAsync.cpp (100%) rename AudioPlayerAsync.h => src/AudioPlayerAsync.h (100%) rename BoneAnimatedModel.cpp => src/BoneAnimatedModel.cpp (100%) rename BoneAnimatedModel.h => src/BoneAnimatedModel.h (94%) rename Environment.cpp => src/Environment.cpp (97%) rename Environment.h => src/Environment.h (92%) rename Game.cpp => src/Game.cpp (96%) mode change 100755 => 100644 rename Game.h => src/Game.h (90%) mode change 100755 => 100644 rename Projectile.cpp => src/Projectile.cpp (100%) rename Projectile.h => src/Projectile.h (85%) rename SparkEmitter.cpp => src/SparkEmitter.cpp (99%) rename SparkEmitter.h => src/SparkEmitter.h (95%) rename TextModel.cpp => src/TextModel.cpp (100%) rename TextModel.h => src/TextModel.h (82%) rename UiManager.cpp => src/UiManager.cpp (99%) rename UiManager.h => src/UiManager.h (97%) rename {external => src/external}/nlohmann/json.hpp (100%) rename {gl => src/gl}/glext.h (100%) mode change 100755 => 100644 rename main.cpp => src/main.cpp (96%) mode change 100755 => 100644 rename PlanetData.cpp => src/planet/PlanetData.cpp (100%) rename PlanetData.h => src/planet/PlanetData.h (97%) rename PlanetObject.cpp => src/planet/PlanetObject.cpp (99%) rename PlanetObject.h => src/planet/PlanetObject.h (90%) rename StoneObject.cpp => src/planet/StoneObject.cpp (99%) rename StoneObject.h => src/planet/StoneObject.h (96%) rename FrameBuffer.cpp => src/render/FrameBuffer.cpp (100%) rename FrameBuffer.h => src/render/FrameBuffer.h (100%) rename OpenGlExtensions.cpp => src/render/OpenGlExtensions.cpp (97%) mode change 100755 => 100644 rename OpenGlExtensions.h => src/render/OpenGlExtensions.h (97%) mode change 100755 => 100644 rename Renderer.cpp => src/render/Renderer.cpp (96%) mode change 100755 => 100644 rename Renderer.h => src/render/Renderer.h (95%) mode change 100755 => 100644 rename ShaderManager.cpp => src/render/ShaderManager.cpp (96%) mode change 100755 => 100644 rename ShaderManager.h => src/render/ShaderManager.h (93%) mode change 100755 => 100644 rename TextureManager.cpp => src/render/TextureManager.cpp (96%) mode change 100755 => 100644 rename TextureManager.h => src/render/TextureManager.h (92%) mode change 100755 => 100644 rename Perlin.cpp => src/utils/Perlin.cpp (100%) rename Perlin.h => src/utils/Perlin.h (91%) rename Utils.cpp => src/utils/Utils.cpp (94%) mode change 100755 => 100644 rename Utils.h => src/utils/Utils.h (95%) mode change 100755 => 100644 rename ZLMath.cpp => src/utils/ZLMath.cpp (99%) rename ZLMath.h => src/utils/ZLMath.h (95%) mode change 100755 => 100644 diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f2c2f0..2283149 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -413,45 +413,45 @@ set_target_properties(libzip_external_lib PROPERTIES # Основной проект space-game001 # =========================================== add_executable(space-game001 - main.cpp - Game.cpp - Game.h - Environment.cpp - Environment.h - Renderer.cpp - Renderer.h - ShaderManager.cpp - ShaderManager.h - TextureManager.cpp - TextureManager.h - TextModel.cpp - TextModel.h - AudioPlayerAsync.cpp - AudioPlayerAsync.h - BoneAnimatedModel.cpp - BoneAnimatedModel.h - ZLMath.cpp - ZLMath.h - OpenGlExtensions.cpp - OpenGlExtensions.h - Utils.cpp - Utils.h - SparkEmitter.cpp - SparkEmitter.h - PlanetObject.cpp - PlanetObject.h - PlanetData.cpp - PlanetData.h - Perlin.cpp - Perlin.h - StoneObject.cpp - StoneObject.h - FrameBuffer.cpp - FrameBuffer.h - UiManager.cpp - UiManager.h - Projectile.h - Projectile.cpp + src/main.cpp + src/Game.cpp + src/Game.h + src/Environment.cpp + src/Environment.h + src/render/Renderer.cpp + src/render/Renderer.h + src/render/ShaderManager.cpp + src/render/ShaderManager.h + src/render/TextureManager.cpp + src/render/TextureManager.h + src/TextModel.cpp + src/TextModel.h + src/AudioPlayerAsync.cpp + src/AudioPlayerAsync.h + src/BoneAnimatedModel.cpp + src/BoneAnimatedModel.h + src/utils/ZLMath.cpp + src/utils/ZLMath.h + src/render/OpenGlExtensions.cpp + src/render/OpenGlExtensions.h + src/utils/Utils.cpp + src/utils/Utils.h + src/SparkEmitter.cpp + src/SparkEmitter.h + src/planet/PlanetObject.cpp + src/planet/PlanetObject.h + src/planet/PlanetData.cpp + src/planet/PlanetData.h + src/utils/Perlin.cpp + src/utils/Perlin.h + src/planet/StoneObject.cpp + src/planet/StoneObject.h + src/render/FrameBuffer.cpp + src/render/FrameBuffer.h + src/UiManager.cpp + src/UiManager.h + src/Projectile.h + src/Projectile.cpp ) # Установка проекта по умолчанию для Visual Studio @@ -459,12 +459,8 @@ set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT s # include-пути проекта target_include_directories(space-game001 PRIVATE - "${CMAKE_CURRENT_SOURCE_DIR}" - #"${CMAKE_CURRENT_SOURCE_DIR}/gl" - #"${CMAKE_CURRENT_SOURCE_DIR}/cmakeaudioplayer/include" - #"${SDL2_INSTALL_DIR}/include" - #"${SDL2_INSTALL_DIR}/include/SDL2" - #"${LIBZIP_INSTALL_DIR}-Release/include" # Добавил include-путь для libzip + "${CMAKE_CURRENT_SOURCE_DIR}/src" + "${CMAKE_CURRENT_SOURCE_DIR}/external" ) set_target_properties(space-game001 PROPERTIES diff --git a/AnimatedModel.h b/src/AnimatedModel.h similarity index 90% rename from AnimatedModel.h rename to src/AnimatedModel.h index 64e57ac..895987d 100644 --- a/AnimatedModel.h +++ b/src/AnimatedModel.h @@ -1,8 +1,8 @@ #pragma once -#include "Renderer.h" -#include "TextureManager.h" +#include "render/Renderer.h" +#include "render/TextureManager.h" namespace ZL { diff --git a/AudioPlayerAsync.cpp b/src/AudioPlayerAsync.cpp similarity index 100% rename from AudioPlayerAsync.cpp rename to src/AudioPlayerAsync.cpp diff --git a/AudioPlayerAsync.h b/src/AudioPlayerAsync.h similarity index 100% rename from AudioPlayerAsync.h rename to src/AudioPlayerAsync.h diff --git a/BoneAnimatedModel.cpp b/src/BoneAnimatedModel.cpp similarity index 100% rename from BoneAnimatedModel.cpp rename to src/BoneAnimatedModel.cpp diff --git a/BoneAnimatedModel.h b/src/BoneAnimatedModel.h similarity index 94% rename from BoneAnimatedModel.h rename to src/BoneAnimatedModel.h index b59a9e9..9711ea9 100644 --- a/BoneAnimatedModel.h +++ b/src/BoneAnimatedModel.h @@ -1,6 +1,6 @@ #pragma once -#include "ZLMath.h" -#include "Renderer.h" +#include "utils/ZLMath.h" +#include "render/Renderer.h" #include diff --git a/Environment.cpp b/src/Environment.cpp similarity index 97% rename from Environment.cpp rename to src/Environment.cpp index 8d6479d..1c1afd4 100644 --- a/Environment.cpp +++ b/src/Environment.cpp @@ -1,6 +1,6 @@ #include "Environment.h" -#include "Utils.h" +#include "utils/Utils.h" #include namespace ZL { diff --git a/Environment.h b/src/Environment.h similarity index 92% rename from Environment.h rename to src/Environment.h index b68f123..870a5c1 100644 --- a/Environment.h +++ b/src/Environment.h @@ -1,9 +1,9 @@ #pragma once -#include "ZLMath.h" +#include "utils/ZLMath.h" #ifdef __linux__ #include #endif -#include "OpenGlExtensions.h" +#include "render/OpenGlExtensions.h" namespace ZL { diff --git a/Game.cpp b/src/Game.cpp old mode 100755 new mode 100644 similarity index 96% rename from Game.cpp rename to src/Game.cpp index e69c80c..d56afb4 --- a/Game.cpp +++ b/src/Game.cpp @@ -1,783 +1,782 @@ -#include "Game.h" -#include "AnimatedModel.h" -#include "BoneAnimatedModel.h" -#include "Utils.h" -#include "OpenGlExtensions.h" -#include -#include "TextureManager.h" -#include "TextModel.h" -#include "StoneObject.h" -#include -#include - -namespace ZL -{ -#ifdef EMSCRIPTEN - const char* CONST_ZIP_FILE = "space-game001.zip"; -#else - const char* CONST_ZIP_FILE = ""; -#endif - - - - Vector4f generateRandomQuaternion(std::mt19937& gen) - { - - std::normal_distribution<> distrib(0.0, 1.0); - - Vector4f randomQuat = { - (float)distrib(gen), - (float)distrib(gen), - (float)distrib(gen), - (float)distrib(gen) - }; - - return randomQuat.normalized(); - } - - - std::vector generateRandomBoxCoords(int N) - { - const float MIN_DISTANCE = 3.0f; - const float MIN_DISTANCE_SQUARED = MIN_DISTANCE * MIN_DISTANCE; - const float MIN_COORD = -100.0f; - const float MAX_COORD = 100.0f; - const int MAX_ATTEMPTS = 1000; - std::vector boxCoordsArr; - - std::random_device rd; - std::mt19937 gen(rd()); - - std::uniform_real_distribution<> distrib(MIN_COORD, MAX_COORD); - - int generatedCount = 0; - - while (generatedCount < N) - { - bool accepted = false; - int attempts = 0; - - while (!accepted && attempts < MAX_ATTEMPTS) - { - Vector3f newPos( - (float)distrib(gen), - (float)distrib(gen), - (float)distrib(gen) - ); - - accepted = true; - for (const auto& existingBox : boxCoordsArr) - { - - Vector3f diff = newPos - existingBox.pos; - - float distanceSquared = diff.squaredNorm(); - - if (distanceSquared < MIN_DISTANCE_SQUARED) - { - accepted = false; - break; - } - } - - if (accepted) - { - Vector4f randomQuat = generateRandomQuaternion(gen); - - Matrix3f randomMatrix = QuatToMatrix(randomQuat); - - boxCoordsArr.emplace_back(BoxCoords{ newPos, randomMatrix }); - generatedCount++; - } - attempts++; - } - - if (!accepted) { - std::cerr << "Ïðåäóïðåæäåíèå: Íå óäàëîñü ñãåíåðèðîâàòü " << N << " îáúåêòîâ. Ñãåíåðèðîâàíî: " << generatedCount << std::endl; - break; - } - } - - return boxCoordsArr; - } - - Game::Game() - : window(nullptr) - , glContext(nullptr) - , newTickCount(0) - , lastTickCount(0) - { - projectiles.reserve(maxProjectiles); - for (int i = 0; i < maxProjectiles; ++i) { - projectiles.emplace_back(std::make_unique()); - } - } - - Game::~Game() { - if (glContext) { - SDL_GL_DeleteContext(glContext); - } - if (window) { - SDL_DestroyWindow(window); - } - SDL_Quit(); - } - - void Game::setup() { - glContext = SDL_GL_CreateContext(ZL::Environment::window); - - ZL::BindOpenGlFunctions(); - ZL::CheckGlError(); - - // Initialize renderer - -#ifdef EMSCRIPTEN - renderer.shaderManager.AddShaderFromFiles("default", "./shaders/default.vertex", "./shaders/default_web.fragment", CONST_ZIP_FILE); - renderer.shaderManager.AddShaderFromFiles("defaultColor", "./shaders/defaultColor.vertex", "./shaders/defaultColor_web.fragment", CONST_ZIP_FILE); - renderer.shaderManager.AddShaderFromFiles("env", "./shaders/env.vertex", "./shaders/env_web.fragment", CONST_ZIP_FILE); - renderer.shaderManager.AddShaderFromFiles("defaultAtmosphere", "./shaders/defaultAtmosphere.vertex", "./shaders/defaultAtmosphere.fragment", CONST_ZIP_FILE); - renderer.shaderManager.AddShaderFromFiles("defaultColorPlanet", "./shaders/defaultColorPlanet.vertex", "./shaders/defaultColorPlanet_web.fragment", CONST_ZIP_FILE); - -#else - renderer.shaderManager.AddShaderFromFiles("default", "./shaders/default.vertex", "./shaders/default_desktop.fragment", CONST_ZIP_FILE); - renderer.shaderManager.AddShaderFromFiles("defaultColor", "./shaders/defaultColor_fog.vertex", "./shaders/defaultColor_fog_desktop.fragment", CONST_ZIP_FILE); - renderer.shaderManager.AddShaderFromFiles("env", "./shaders/env_sky.vertex", "./shaders/env_sky_desktop.fragment", CONST_ZIP_FILE); - renderer.shaderManager.AddShaderFromFiles("defaultAtmosphere", "./shaders/defaultAtmosphere.vertex", "./shaders/defaultAtmosphere.fragment", CONST_ZIP_FILE); - renderer.shaderManager.AddShaderFromFiles("defaultColor2", "./shaders/defaultColor_fog2.vertex", "./shaders/defaultColor_fog2_desktop.fragment", CONST_ZIP_FILE); - renderer.shaderManager.AddShaderFromFiles("defaultColorStones", "./shaders/defaultColor_fog_stones.vertex", "./shaders/defaultColor_fog_stones_desktop.fragment", CONST_ZIP_FILE); - renderer.shaderManager.AddShaderFromFiles("planetBake", "./shaders/planet_bake.vertex", "./shaders/planet_bake_desktop.fragment", CONST_ZIP_FILE); - renderer.shaderManager.AddShaderFromFiles("planetStone", "./shaders/planet_stone.vertex", "./shaders/planet_stone_desktop.fragment", CONST_ZIP_FILE); - renderer.shaderManager.AddShaderFromFiles("planetLand", "./shaders/planet_land.vertex", "./shaders/planet_land_desktop.fragment", CONST_ZIP_FILE); - -#endif - - bool cfgLoaded = sparkEmitter.loadFromJsonFile("../config/spark_config.json", renderer, CONST_ZIP_FILE); - bool projCfgLoaded = projectileEmitter.loadFromJsonFile("../config/spark_projectile_config.json", renderer, CONST_ZIP_FILE); - projectileEmitter.setEmissionPoints(std::vector()); - uiManager.loadFromFile("../config/ui.json", renderer, CONST_ZIP_FILE); - - uiManager.setButtonCallback("playButton", [this](const std::string& name) { - std::cerr << "Play button pressed: " << name << std::endl; - }); - - uiManager.setButtonCallback("exitButton", [](const std::string& name) { - Environment::exitGameLoop = true; - }); - - uiManager.setButtonCallback("settingsButton", [this](const std::string& name) { - if (uiManager.pushMenuFromFile("../config/settings.json", this->renderer, CONST_ZIP_FILE)) { - - uiManager.setButtonCallback("Opt1", [this](const std::string& n) { - std::cerr << "Opt1 pressed: " << n << std::endl; - }); - - uiManager.setButtonCallback("Opt2", [this](const std::string& n) { - std::cerr << "Opt2 pressed: " << n << std::endl; - }); - - uiManager.setButtonCallback("backButton", [this](const std::string& n) { - uiManager.popMenu(); - }); - } - else { - std::cerr << "Failed to open settings menu" << std::endl; - } - }); - - uiManager.setSliderCallback("musicVolumeSlider", [this](const std::string& name, float value) { - std::cerr << "Music volume slider changed to: " << value << std::endl; - musicVolume = value; - Environment::shipVelocity = musicVolume * 20.0f; - }); - - cubemapTexture = std::make_shared( - std::array{ - CreateTextureDataFromBmp24("./resources/sky/space_rt.bmp", CONST_ZIP_FILE), - CreateTextureDataFromBmp24("./resources/sky/space_lf.bmp", CONST_ZIP_FILE), - CreateTextureDataFromBmp24("./resources/sky/space_up.bmp", CONST_ZIP_FILE), - CreateTextureDataFromBmp24("./resources/sky/space_dn.bmp", CONST_ZIP_FILE), - CreateTextureDataFromBmp24("./resources/sky/space_bk.bmp", CONST_ZIP_FILE), - CreateTextureDataFromBmp24("./resources/sky/space_ft.bmp", CONST_ZIP_FILE) - }); - - - cubemap.data = ZL::CreateCubemap(500); - cubemap.RefreshVBO(); - - //Load texture - spaceshipTexture = std::make_unique(CreateTextureDataFromPng("./resources/DefaultMaterial_BaseColor_shine.png", CONST_ZIP_FILE)); - spaceshipBase = LoadFromTextFile02("./resources/spaceship006.txt", CONST_ZIP_FILE); - spaceshipBase.RotateByMatrix(QuatToMatrix(QuatFromRotateAroundY(M_PI / 2.0))); - //spaceshipBase.Move(Vector3f{ -0.52998, -13, 0 }); - //spaceshipBase.Move(Vector3f{ -0.52998, -10, 10 }); - - spaceship.AssignFrom(spaceshipBase); - spaceship.RefreshVBO(); - - - //Boxes - boxTexture = std::make_unique(CreateTextureDataFromPng("./resources/box/box.png", CONST_ZIP_FILE)); - boxBase = LoadFromTextFile02("./resources/box/box.txt", CONST_ZIP_FILE); - - boxCoordsArr = generateRandomBoxCoords(50); - - boxRenderArr.resize(boxCoordsArr.size()); - - for (int i = 0; i < boxCoordsArr.size(); i++) - { - boxRenderArr[i].AssignFrom(boxBase); - //boxRenderArr[i].data = CreateBaseConvexPolyhedron(1999); - boxRenderArr[i].RefreshVBO(); - } - - if (!cfgLoaded) - { - throw std::runtime_error("Failed to load spark emitter config file!"); - } - - - /* buttonTexture = std::make_unique(CreateTextureDataFromPng("./resources/button.png", CONST_ZIP_FILE)); - - button.data.PositionData.push_back({ 100, 100, 0 }); - button.data.PositionData.push_back({ 100, 150, 0 }); - button.data.PositionData.push_back({ 300, 150, 0 }); - button.data.PositionData.push_back({ 100, 100, 0 }); - button.data.PositionData.push_back({ 300, 150, 0 }); - button.data.PositionData.push_back({ 300, 100, 0 }); - - button.data.TexCoordData.push_back({ 0,0 }); - button.data.TexCoordData.push_back({ 0,1 }); - button.data.TexCoordData.push_back({ 1,1 }); - button.data.TexCoordData.push_back({ 0,0 }); - button.data.TexCoordData.push_back({ 1,1 }); - button.data.TexCoordData.push_back({ 1,0 }); - - button.RefreshVBO();*/ - /* - musicVolumeBarTexture = std::make_unique(CreateTextureDataFromPng("./resources/musicVolumeBarTexture.png", CONST_ZIP_FILE)); - - musicVolumeBar.data.PositionData.push_back({ 1190, 100, 0 }); - musicVolumeBar.data.PositionData.push_back({ 1190, 600, 0 }); - musicVolumeBar.data.PositionData.push_back({ 1200, 600, 0 }); - musicVolumeBar.data.PositionData.push_back({ 1190, 100, 0 }); - musicVolumeBar.data.PositionData.push_back({ 1200, 600, 0 }); - musicVolumeBar.data.PositionData.push_back({ 1200, 100, 0 }); - - musicVolumeBar.data.TexCoordData.push_back({ 0,0 }); - musicVolumeBar.data.TexCoordData.push_back({ 0,1 }); - musicVolumeBar.data.TexCoordData.push_back({ 1,1 }); - musicVolumeBar.data.TexCoordData.push_back({ 0,0 }); - musicVolumeBar.data.TexCoordData.push_back({ 1,1 }); - musicVolumeBar.data.TexCoordData.push_back({ 1,0 }); - - musicVolumeBar.RefreshVBO(); - - - musicVolumeBarButtonTexture = std::make_unique(CreateTextureDataFromPng("./resources/musicVolumeBarButton.png", CONST_ZIP_FILE)); - - float musicVolumeBarButtonButtonCenterY = 350.0f; - - musicVolumeBarButton.data.PositionData.push_back({ musicVolumeBarButtonButtonCenterX - musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY - musicVolumeBarButtonButtonRadius, 0 }); - musicVolumeBarButton.data.PositionData.push_back({ musicVolumeBarButtonButtonCenterX - musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY + musicVolumeBarButtonButtonRadius, 0 }); - musicVolumeBarButton.data.PositionData.push_back({ musicVolumeBarButtonButtonCenterX + musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY + musicVolumeBarButtonButtonRadius, 0 }); - musicVolumeBarButton.data.PositionData.push_back({ musicVolumeBarButtonButtonCenterX - musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY - musicVolumeBarButtonButtonRadius, 0 }); - musicVolumeBarButton.data.PositionData.push_back({ musicVolumeBarButtonButtonCenterX + musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY + musicVolumeBarButtonButtonRadius, 0 }); - musicVolumeBarButton.data.PositionData.push_back({ musicVolumeBarButtonButtonCenterX + musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY - musicVolumeBarButtonButtonRadius, 0 }); - - musicVolumeBarButton.data.TexCoordData.push_back({ 0,0 }); - musicVolumeBarButton.data.TexCoordData.push_back({ 0,1 }); - musicVolumeBarButton.data.TexCoordData.push_back({ 1,1 }); - musicVolumeBarButton.data.TexCoordData.push_back({ 0,0 }); - musicVolumeBarButton.data.TexCoordData.push_back({ 1,1 }); - musicVolumeBarButton.data.TexCoordData.push_back({ 1,0 }); - - musicVolumeBarButton.RefreshVBO();*/ - renderer.InitOpenGL(); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - planetObject.init(); - - rockTexture = std::make_unique(CreateTextureDataFromPng("./resources/rock.png", "")); - - } - - void Game::drawCubemap(float skyPercent) - { - static const std::string defaultShaderName = "default"; - static const std::string envShaderName = "env"; - static const std::string vPositionName = "vPosition"; - static const std::string vTexCoordName = "vTexCoord"; - static const std::string textureUniformName = "Texture"; - static const std::string skyPercentUniformName = "skyPercent"; - - renderer.shaderManager.PushShader(envShaderName); - renderer.RenderUniform1i(textureUniformName, 0); - renderer.RenderUniform1f(skyPercentUniformName, skyPercent); - renderer.EnableVertexAttribArray(vPositionName); - renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5, - static_cast(Environment::width) / static_cast(Environment::height), - Environment::CONST_Z_NEAR, Environment::CONST_Z_FAR); - renderer.PushMatrix(); - renderer.LoadIdentity(); - renderer.RotateMatrix(Environment::inverseShipMatrix); - - CheckGlError(); - - glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture->getTexID()); - renderer.DrawVertexRenderStruct(cubemap); - - CheckGlError(); - - - renderer.PopMatrix(); - renderer.PopProjectionMatrix(); - renderer.DisableVertexAttribArray(vPositionName); - - renderer.shaderManager.PopShader(); - CheckGlError(); - } - - void Game::drawShip() - { - static const std::string defaultShaderName = "default"; - static const std::string envShaderName = "env"; - static const std::string vPositionName = "vPosition"; - static const std::string vTexCoordName = "vTexCoord"; - static const std::string textureUniformName = "Texture"; - - renderer.shaderManager.PushShader(defaultShaderName); - renderer.RenderUniform1i(textureUniformName, 0); - renderer.EnableVertexAttribArray(vPositionName); - renderer.EnableVertexAttribArray(vTexCoordName); - - renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5, - static_cast(Environment::width) / static_cast(Environment::height), - Environment::CONST_Z_NEAR, Environment::CONST_Z_FAR); - renderer.PushMatrix(); - - renderer.LoadIdentity(); - renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom }); - - renderer.TranslateMatrix({ 0, -Environment::zoom * 0.03f, 0 }); - glBindTexture(GL_TEXTURE_2D, spaceshipTexture->getTexID()); - renderer.DrawVertexRenderStruct(spaceship); - - for (const auto& p : projectiles) { - if (p && p->isActive()) { - p->draw(renderer); - } - } - - sparkEmitter.draw(renderer, Environment::zoom, Environment::width, Environment::height); - projectileEmitter.draw(renderer, Environment::zoom, Environment::width, Environment::height); - - renderer.PopMatrix(); - renderer.PopProjectionMatrix(); - renderer.DisableVertexAttribArray(vPositionName); - renderer.DisableVertexAttribArray(vTexCoordName); - - renderer.shaderManager.PopShader(); - CheckGlError(); - } - - void Game::drawBoxes() - { - static const std::string defaultShaderName = "default"; - static const std::string envShaderName = "env"; - static const std::string vPositionName = "vPosition"; - static const std::string vTexCoordName = "vTexCoord"; - static const std::string textureUniformName = "Texture"; - - renderer.shaderManager.PushShader(defaultShaderName); - renderer.RenderUniform1i(textureUniformName, 0); - renderer.EnableVertexAttribArray(vPositionName); - renderer.EnableVertexAttribArray(vTexCoordName); - - renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5, - static_cast(Environment::width) / static_cast(Environment::height), - Environment::CONST_Z_NEAR, Environment::CONST_Z_FAR); - - for (int i = 0; i < boxCoordsArr.size(); i++) - { - renderer.PushMatrix(); - - renderer.LoadIdentity(); - renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom }); - renderer.RotateMatrix(Environment::inverseShipMatrix); - renderer.TranslateMatrix(-Environment::shipPosition); - renderer.TranslateMatrix({ 0.f, 0.f, 45000.f }); - renderer.TranslateMatrix(boxCoordsArr[i].pos); - renderer.RotateMatrix(boxCoordsArr[i].m); - - glBindTexture(GL_TEXTURE_2D, boxTexture->getTexID()); - //glBindTexture(GL_TEXTURE_2D, rockTexture->getTexID()); - renderer.DrawVertexRenderStruct(boxRenderArr[i]); - - renderer.PopMatrix(); - } - renderer.PopProjectionMatrix(); - renderer.DisableVertexAttribArray(vPositionName); - renderer.DisableVertexAttribArray(vTexCoordName); - - renderer.shaderManager.PopShader(); - CheckGlError(); - } - /*void Game::UpdateVolumeKnob() { - float musicVolumeBarButtonButtonCenterY = volumeBarMinY + musicVolume * (volumeBarMaxY - volumeBarMinY); - - auto& pos = musicVolumeBarButton.data.PositionData; - - pos[0] = { musicVolumeBarButtonButtonCenterX - musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY - musicVolumeBarButtonButtonRadius, 0 }; - pos[1] = { musicVolumeBarButtonButtonCenterX - musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY + musicVolumeBarButtonButtonRadius, 0 }; - pos[2] = { musicVolumeBarButtonButtonCenterX + musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY + musicVolumeBarButtonButtonRadius, 0 }; - pos[3] = { musicVolumeBarButtonButtonCenterX - musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY - musicVolumeBarButtonButtonRadius, 0 }; - pos[4] = { musicVolumeBarButtonButtonCenterX + musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY + musicVolumeBarButtonButtonRadius, 0 }; - pos[5] = { musicVolumeBarButtonButtonCenterX + musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY - musicVolumeBarButtonButtonRadius, 0 }; - - musicVolumeBarButton.RefreshVBO(); - - } - void Game::UpdateVolumeFromMouse(int mouseX, int mouseY) { - - int uiX = mouseX; - int uiY = Environment::height - mouseY; - Environment::shipVelocity = (musicVolume) * (20.0); - if (uiY < volumeBarMinY || uiY > volumeBarMaxY) - { - return; - } - - float t = (uiY - volumeBarMinY) / (volumeBarMaxY - volumeBarMinY); - if (t < 0.0f) t = 0.0f; - if (t > 1.0f) t = 1.0f; - musicVolume = t; - UpdateVolumeKnob(); - }*/ - - void Game::drawUI() - { - static const std::string defaultShaderName = "default"; - static const std::string envShaderName = "env"; - static const std::string vPositionName = "vPosition"; - static const std::string vTexCoordName = "vTexCoord"; - static const std::string textureUniformName = "Texture"; - - glClear(GL_DEPTH_BUFFER_BIT); - - renderer.shaderManager.PushShader(defaultShaderName); - renderer.RenderUniform1i(textureUniformName, 0); - renderer.EnableVertexAttribArray(vPositionName); - renderer.EnableVertexAttribArray(vTexCoordName); - - //renderer.PushProjectionMatrix(Environment::width, Environment::height, -1, 1); - //renderer.PushMatrix(); - - //renderer.LoadIdentity(); - - //glBindTexture(GL_TEXTURE_2D, buttonTexture->getTexID()); - //renderer.DrawVertexRenderStruct(button); - - - //glBindTexture(GL_TEXTURE_2D, musicVolumeBarTexture->getTexID()); - //renderer.DrawVertexRenderStruct(musicVolumeBar); - - //glBindTexture(GL_TEXTURE_2D, musicVolumeBarButtonTexture->getTexID()); - //renderer.DrawVertexRenderStruct(musicVolumeBarButton); - - //renderer.PopMatrix(); - //renderer.PopProjectionMatrix(); - - renderer.DisableVertexAttribArray(vPositionName); - renderer.DisableVertexAttribArray(vTexCoordName); - uiManager.draw(renderer); - renderer.shaderManager.PopShader(); - CheckGlError(); - } - - void Game::drawScene() { - static const std::string defaultShaderName = "default"; - static const std::string envShaderName = "env"; - static const std::string vPositionName = "vPosition"; - static const std::string vTexCoordName = "vTexCoord"; - static const std::string textureUniformName = "Texture"; - - glClearColor(0.0f, 1.0f, 0.0f, 1.0f); - glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - - glViewport(0, 0, Environment::width, Environment::height); - - CheckGlError(); - - float skyPercent = 0.0; - float distance = planetObject.distanceToPlanetSurface(Environment::shipPosition); - if (distance > 1900.f) - { - skyPercent = 0.0f; - } - else if (distance < 1000.f) - { - skyPercent = 1.0f; - } - else - { - skyPercent = (1900.f - distance) / 900.f; - } - - - drawCubemap(skyPercent); - planetObject.draw(renderer); - if (planetObject.distanceToPlanetSurface(Environment::shipPosition) > 100.f) - { - glClear(GL_DEPTH_BUFFER_BIT); - } - drawShip(); - drawBoxes(); - - drawUI(); - - CheckGlError(); - } - - void Game::processTickCount() { - - if (lastTickCount == 0) { - lastTickCount = SDL_GetTicks64(); - return; - } - - newTickCount = SDL_GetTicks64(); - if (newTickCount - lastTickCount > CONST_TIMER_INTERVAL) { - size_t delta = (newTickCount - lastTickCount > CONST_MAX_TIME_INTERVAL) ? - CONST_MAX_TIME_INTERVAL : newTickCount - lastTickCount; - - //gameObjects.updateScene(delta); - sparkEmitter.update(static_cast(delta)); - planetObject.update(static_cast(delta)); - - if (Environment::tapDownHold) { - - float diffx = Environment::tapDownCurrentPos.v[0] - Environment::tapDownStartPos.v[0]; - float diffy = Environment::tapDownCurrentPos.v[1] - Environment::tapDownStartPos.v[1]; - - if (abs(diffy) > 5.0 || abs(diffx) > 5.0) //threshold - { - - float rotationPower = sqrtf(diffx * diffx + diffy * diffy); - - //std::cout << rotationPower << std::endl; - - float deltaAlpha = rotationPower * delta * M_PI / 500000.f; - - Vector3f rotationDirection = { diffy, diffx, 0 }; - - rotationDirection = rotationDirection.normalized(); - - Vector4f rotateQuat = { - rotationDirection.v[0] * sin(deltaAlpha * 0.5f), - rotationDirection.v[1] * sin(deltaAlpha * 0.5f), - rotationDirection.v[2] * sin(deltaAlpha * 0.5f), - cos(deltaAlpha * 0.5f) }; - - Matrix3f rotateMat = QuatToMatrix(rotateQuat); - - Environment::shipMatrix = MultMatrixMatrix(Environment::shipMatrix, rotateMat); - Environment::inverseShipMatrix = InverseMatrix(Environment::shipMatrix); - - } - } - - if (fabs(Environment::shipVelocity) > 0.01f) - { - Vector3f velocityDirection = { 0,0, -Environment::shipVelocity * delta / 1000.f }; - Vector3f velocityDirectionAdjusted = MultMatrixVector(Environment::shipMatrix, velocityDirection); - Environment::shipPosition = Environment::shipPosition + velocityDirectionAdjusted; - } - - for (auto& p : projectiles) { - if (p && p->isActive()) { - p->update(static_cast(delta), renderer); - } - } - - std::vector projCameraPoints; - for (const auto& p : projectiles) { - if (p && p->isActive()) { - Vector3f worldPos = p->getPosition(); - Vector3f rel = worldPos - Environment::shipPosition; - Vector3f camPos = MultMatrixVector(Environment::inverseShipMatrix, rel); - projCameraPoints.push_back(camPos); - } - } - if (!projCameraPoints.empty()) { - projectileEmitter.setEmissionPoints(projCameraPoints); - projectileEmitter.emit(); - } - else { - projectileEmitter.setEmissionPoints(std::vector()); - } - - std::vector shipCameraPoints; - for (const auto& lp : shipLocalEmissionPoints) { - Vector3f adjusted = lp + Vector3f{ 0.0f, -Environment::zoom * 0.03f, 0.0f }; - shipCameraPoints.push_back(adjusted); - } - if (!shipCameraPoints.empty()) { - sparkEmitter.setEmissionPoints(shipCameraPoints); - } - - sparkEmitter.update(static_cast(delta)); - projectileEmitter.update(static_cast(delta)); - - lastTickCount = newTickCount; - } - } - - void Game::fireProjectiles() { - std::vector localOffsets = { - Vector3f{ -1.5f, 0.9f, 5.0f }, - Vector3f{ 1.5f, 0.9f, 5.0f } - }; - - const float projectileSpeed = 60.0f; - const float lifeMs = 5000.0f; - const float size = 0.5f; - - Vector3f localForward = { 0,0,-1 }; - Vector3f worldForward = MultMatrixVector(Environment::shipMatrix, localForward).normalized(); - - for (const auto& lo : localOffsets) { - Vector3f worldPos = Environment::shipPosition + MultMatrixVector(Environment::shipMatrix, lo); - Vector3f worldVel = worldForward * projectileSpeed; - - for (auto& p : projectiles) { - if (!p->isActive()) { - p->init(worldPos, worldVel, lifeMs, size, projectileTexture, renderer); - break; - } - } - } - } - - void Game::render() { - SDL_GL_MakeCurrent(ZL::Environment::window, glContext); - ZL::CheckGlError(); - - glClearColor(0.0f, 1.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - drawScene(); - processTickCount(); - - SDL_GL_SwapWindow(ZL::Environment::window); - } - void Game::update() { - SDL_Event event; - while (SDL_PollEvent(&event)) { - if (event.type == SDL_QUIT) { - Environment::exitGameLoop = true; - } - else if (event.type == SDL_MOUSEBUTTONDOWN) { - // 1. Îáðàáîòêà íàæàòèÿ êíîïêè ìûøè - - int mx = event.button.x; - int my = event.button.y; - int uiX = mx; - int uiY = Environment::height - my; - - uiManager.onMouseDown(uiX, uiY); - - bool uiHandled = false; - - if (event.button.button == SDL_BUTTON_LEFT && !uiManager.isUiInteraction()) { - uint64_t now = SDL_GetTicks64(); - if (now - lastProjectileFireTime >= static_cast(projectileCooldownMs)) { - lastProjectileFireTime = now; - fireProjectiles(); - } - } - - for (const auto& button : uiManager.findButton("") ? std::vector>{} : std::vector>{}) { - (void)button; - } - - auto pressedSlider = [&]() -> std::shared_ptr { - for (const auto& slider : uiManager.findSlider("") ? std::vector>{} : std::vector>{}) { - (void)slider; - } - return nullptr; - }(); - - if (!uiManager.isUiInteraction()) { - Environment::tapDownHold = true; - // Êîîðäèíàòû íà÷àëüíîãî íàæàòèÿ - Environment::tapDownStartPos.v[0] = mx; - Environment::tapDownStartPos.v[1] = my; - // Íà÷àëüíàÿ ïîçèöèÿ òàêæå ñòàíîâèòñÿ òåêóùåé - Environment::tapDownCurrentPos.v[0] = mx; - Environment::tapDownCurrentPos.v[1] = my; - } - } - else if (event.type == SDL_MOUSEBUTTONUP) { - // 2. Îáðàáîòêà îòïóñêàíèÿ êíîïêè ìûøè - int mx = event.button.x; - int my = event.button.y; - int uiX = mx; - int uiY = Environment::height - my; - - uiManager.onMouseUp(uiX, uiY); - - if (!uiManager.isUiInteraction()) { - Environment::tapDownHold = false; - } - } - else if (event.type == SDL_MOUSEMOTION) { - // 3. Îáðàáîòêà ïåðåìåùåíèÿ ìûøè - int mx = event.motion.x; - int my = event.motion.y; - int uiX = mx; - int uiY = Environment::height - my; - - uiManager.onMouseMove(uiX, uiY); - - if (Environment::tapDownHold && !uiManager.isUiInteraction()) { - Environment::tapDownCurrentPos.v[0] = mx; - Environment::tapDownCurrentPos.v[1] = my; - } - } - else if (event.type == SDL_MOUSEWHEEL) { - static const float zoomstep = 2.0f; - if (event.wheel.y > 0) { - Environment::zoom -= zoomstep; - } - else if (event.wheel.y < 0) { - Environment::zoom += zoomstep; - } - if (Environment::zoom < zoomstep) { - Environment::zoom = zoomstep; - } - } - else if (event.type == SDL_KEYUP) - { - if (event.key.keysym.sym == SDLK_i) - { - Environment::shipVelocity += 500.f; - } - if (event.key.keysym.sym == SDLK_k) - { - Environment::shipVelocity -= 500.f; - } - if (event.key.keysym.sym == SDLK_o) - { - Environment::shipVelocity += 50.f; - } - if (event.key.keysym.sym == SDLK_l) - { - Environment::shipVelocity -= 50.f; - } - } - } - render(); - } - -} // namespace ZL +#include "Game.h" +#include "AnimatedModel.h" +#include "BoneAnimatedModel.h" +#include "utils/Utils.h" +#include "render/OpenGlExtensions.h" +#include +#include "render/TextureManager.h" +#include "TextModel.h" +#include +#include + +namespace ZL +{ +#ifdef EMSCRIPTEN + const char* CONST_ZIP_FILE = "space-game001.zip"; +#else + const char* CONST_ZIP_FILE = ""; +#endif + + + + Vector4f generateRandomQuaternion(std::mt19937& gen) + { + + std::normal_distribution<> distrib(0.0, 1.0); + + Vector4f randomQuat = { + (float)distrib(gen), + (float)distrib(gen), + (float)distrib(gen), + (float)distrib(gen) + }; + + return randomQuat.normalized(); + } + + + std::vector generateRandomBoxCoords(int N) + { + const float MIN_DISTANCE = 3.0f; + const float MIN_DISTANCE_SQUARED = MIN_DISTANCE * MIN_DISTANCE; + const float MIN_COORD = -100.0f; + const float MAX_COORD = 100.0f; + const int MAX_ATTEMPTS = 1000; + std::vector boxCoordsArr; + + std::random_device rd; + std::mt19937 gen(rd()); + + std::uniform_real_distribution<> distrib(MIN_COORD, MAX_COORD); + + int generatedCount = 0; + + while (generatedCount < N) + { + bool accepted = false; + int attempts = 0; + + while (!accepted && attempts < MAX_ATTEMPTS) + { + Vector3f newPos( + (float)distrib(gen), + (float)distrib(gen), + (float)distrib(gen) + ); + + accepted = true; + for (const auto& existingBox : boxCoordsArr) + { + + Vector3f diff = newPos - existingBox.pos; + + float distanceSquared = diff.squaredNorm(); + + if (distanceSquared < MIN_DISTANCE_SQUARED) + { + accepted = false; + break; + } + } + + if (accepted) + { + Vector4f randomQuat = generateRandomQuaternion(gen); + + Matrix3f randomMatrix = QuatToMatrix(randomQuat); + + boxCoordsArr.emplace_back(BoxCoords{ newPos, randomMatrix }); + generatedCount++; + } + attempts++; + } + + if (!accepted) { + std::cerr << "Ïðåäóïðåæäåíèå: Íå óäàëîñü ñãåíåðèðîâàòü " << N << " îáúåêòîâ. Ñãåíåðèðîâàíî: " << generatedCount << std::endl; + break; + } + } + + return boxCoordsArr; + } + + Game::Game() + : window(nullptr) + , glContext(nullptr) + , newTickCount(0) + , lastTickCount(0) + { + projectiles.reserve(maxProjectiles); + for (int i = 0; i < maxProjectiles; ++i) { + projectiles.emplace_back(std::make_unique()); + } + } + + Game::~Game() { + if (glContext) { + SDL_GL_DeleteContext(glContext); + } + if (window) { + SDL_DestroyWindow(window); + } + SDL_Quit(); + } + + void Game::setup() { + glContext = SDL_GL_CreateContext(ZL::Environment::window); + + ZL::BindOpenGlFunctions(); + ZL::CheckGlError(); + + // Initialize renderer + +#ifdef EMSCRIPTEN + renderer.shaderManager.AddShaderFromFiles("default", "./shaders/default.vertex", "./shaders/default_web.fragment", CONST_ZIP_FILE); + renderer.shaderManager.AddShaderFromFiles("defaultColor", "./shaders/defaultColor.vertex", "./shaders/defaultColor_web.fragment", CONST_ZIP_FILE); + renderer.shaderManager.AddShaderFromFiles("env", "./shaders/env.vertex", "./shaders/env_web.fragment", CONST_ZIP_FILE); + renderer.shaderManager.AddShaderFromFiles("defaultAtmosphere", "./shaders/defaultAtmosphere.vertex", "./shaders/defaultAtmosphere.fragment", CONST_ZIP_FILE); + renderer.shaderManager.AddShaderFromFiles("defaultColorPlanet", "./shaders/defaultColorPlanet.vertex", "./shaders/defaultColorPlanet_web.fragment", CONST_ZIP_FILE); + +#else + renderer.shaderManager.AddShaderFromFiles("default", "./shaders/default.vertex", "./shaders/default_desktop.fragment", CONST_ZIP_FILE); + renderer.shaderManager.AddShaderFromFiles("defaultColor", "./shaders/defaultColor_fog.vertex", "./shaders/defaultColor_fog_desktop.fragment", CONST_ZIP_FILE); + renderer.shaderManager.AddShaderFromFiles("env", "./shaders/env_sky.vertex", "./shaders/env_sky_desktop.fragment", CONST_ZIP_FILE); + renderer.shaderManager.AddShaderFromFiles("defaultAtmosphere", "./shaders/defaultAtmosphere.vertex", "./shaders/defaultAtmosphere.fragment", CONST_ZIP_FILE); + renderer.shaderManager.AddShaderFromFiles("defaultColor2", "./shaders/defaultColor_fog2.vertex", "./shaders/defaultColor_fog2_desktop.fragment", CONST_ZIP_FILE); + renderer.shaderManager.AddShaderFromFiles("defaultColorStones", "./shaders/defaultColor_fog_stones.vertex", "./shaders/defaultColor_fog_stones_desktop.fragment", CONST_ZIP_FILE); + renderer.shaderManager.AddShaderFromFiles("planetBake", "./shaders/planet_bake.vertex", "./shaders/planet_bake_desktop.fragment", CONST_ZIP_FILE); + renderer.shaderManager.AddShaderFromFiles("planetStone", "./shaders/planet_stone.vertex", "./shaders/planet_stone_desktop.fragment", CONST_ZIP_FILE); + renderer.shaderManager.AddShaderFromFiles("planetLand", "./shaders/planet_land.vertex", "./shaders/planet_land_desktop.fragment", CONST_ZIP_FILE); + +#endif + + bool cfgLoaded = sparkEmitter.loadFromJsonFile("../config/spark_config.json", renderer, CONST_ZIP_FILE); + bool projCfgLoaded = projectileEmitter.loadFromJsonFile("../config/spark_projectile_config.json", renderer, CONST_ZIP_FILE); + projectileEmitter.setEmissionPoints(std::vector()); + uiManager.loadFromFile("../config/ui.json", renderer, CONST_ZIP_FILE); + + uiManager.setButtonCallback("playButton", [this](const std::string& name) { + std::cerr << "Play button pressed: " << name << std::endl; + }); + + uiManager.setButtonCallback("exitButton", [](const std::string& name) { + Environment::exitGameLoop = true; + }); + + uiManager.setButtonCallback("settingsButton", [this](const std::string& name) { + if (uiManager.pushMenuFromFile("../config/settings.json", this->renderer, CONST_ZIP_FILE)) { + + uiManager.setButtonCallback("Opt1", [this](const std::string& n) { + std::cerr << "Opt1 pressed: " << n << std::endl; + }); + + uiManager.setButtonCallback("Opt2", [this](const std::string& n) { + std::cerr << "Opt2 pressed: " << n << std::endl; + }); + + uiManager.setButtonCallback("backButton", [this](const std::string& n) { + uiManager.popMenu(); + }); + } + else { + std::cerr << "Failed to open settings menu" << std::endl; + } + }); + + uiManager.setSliderCallback("musicVolumeSlider", [this](const std::string& name, float value) { + std::cerr << "Music volume slider changed to: " << value << std::endl; + musicVolume = value; + Environment::shipVelocity = musicVolume * 20.0f; + }); + + cubemapTexture = std::make_shared( + std::array{ + CreateTextureDataFromBmp24("./resources/sky/space_rt.bmp", CONST_ZIP_FILE), + CreateTextureDataFromBmp24("./resources/sky/space_lf.bmp", CONST_ZIP_FILE), + CreateTextureDataFromBmp24("./resources/sky/space_up.bmp", CONST_ZIP_FILE), + CreateTextureDataFromBmp24("./resources/sky/space_dn.bmp", CONST_ZIP_FILE), + CreateTextureDataFromBmp24("./resources/sky/space_bk.bmp", CONST_ZIP_FILE), + CreateTextureDataFromBmp24("./resources/sky/space_ft.bmp", CONST_ZIP_FILE) + }); + + + cubemap.data = ZL::CreateCubemap(500); + cubemap.RefreshVBO(); + + //Load texture + spaceshipTexture = std::make_unique(CreateTextureDataFromPng("./resources/DefaultMaterial_BaseColor_shine.png", CONST_ZIP_FILE)); + spaceshipBase = LoadFromTextFile02("./resources/spaceship006.txt", CONST_ZIP_FILE); + spaceshipBase.RotateByMatrix(QuatToMatrix(QuatFromRotateAroundY(M_PI / 2.0))); + //spaceshipBase.Move(Vector3f{ -0.52998, -13, 0 }); + //spaceshipBase.Move(Vector3f{ -0.52998, -10, 10 }); + + spaceship.AssignFrom(spaceshipBase); + spaceship.RefreshVBO(); + + + //Boxes + boxTexture = std::make_unique(CreateTextureDataFromPng("./resources/box/box.png", CONST_ZIP_FILE)); + boxBase = LoadFromTextFile02("./resources/box/box.txt", CONST_ZIP_FILE); + + boxCoordsArr = generateRandomBoxCoords(50); + + boxRenderArr.resize(boxCoordsArr.size()); + + for (int i = 0; i < boxCoordsArr.size(); i++) + { + boxRenderArr[i].AssignFrom(boxBase); + //boxRenderArr[i].data = CreateBaseConvexPolyhedron(1999); + boxRenderArr[i].RefreshVBO(); + } + + if (!cfgLoaded) + { + throw std::runtime_error("Failed to load spark emitter config file!"); + } + + + /* buttonTexture = std::make_unique(CreateTextureDataFromPng("./resources/button.png", CONST_ZIP_FILE)); + + button.data.PositionData.push_back({ 100, 100, 0 }); + button.data.PositionData.push_back({ 100, 150, 0 }); + button.data.PositionData.push_back({ 300, 150, 0 }); + button.data.PositionData.push_back({ 100, 100, 0 }); + button.data.PositionData.push_back({ 300, 150, 0 }); + button.data.PositionData.push_back({ 300, 100, 0 }); + + button.data.TexCoordData.push_back({ 0,0 }); + button.data.TexCoordData.push_back({ 0,1 }); + button.data.TexCoordData.push_back({ 1,1 }); + button.data.TexCoordData.push_back({ 0,0 }); + button.data.TexCoordData.push_back({ 1,1 }); + button.data.TexCoordData.push_back({ 1,0 }); + + button.RefreshVBO();*/ + /* + musicVolumeBarTexture = std::make_unique(CreateTextureDataFromPng("./resources/musicVolumeBarTexture.png", CONST_ZIP_FILE)); + + musicVolumeBar.data.PositionData.push_back({ 1190, 100, 0 }); + musicVolumeBar.data.PositionData.push_back({ 1190, 600, 0 }); + musicVolumeBar.data.PositionData.push_back({ 1200, 600, 0 }); + musicVolumeBar.data.PositionData.push_back({ 1190, 100, 0 }); + musicVolumeBar.data.PositionData.push_back({ 1200, 600, 0 }); + musicVolumeBar.data.PositionData.push_back({ 1200, 100, 0 }); + + musicVolumeBar.data.TexCoordData.push_back({ 0,0 }); + musicVolumeBar.data.TexCoordData.push_back({ 0,1 }); + musicVolumeBar.data.TexCoordData.push_back({ 1,1 }); + musicVolumeBar.data.TexCoordData.push_back({ 0,0 }); + musicVolumeBar.data.TexCoordData.push_back({ 1,1 }); + musicVolumeBar.data.TexCoordData.push_back({ 1,0 }); + + musicVolumeBar.RefreshVBO(); + + + musicVolumeBarButtonTexture = std::make_unique(CreateTextureDataFromPng("./resources/musicVolumeBarButton.png", CONST_ZIP_FILE)); + + float musicVolumeBarButtonButtonCenterY = 350.0f; + + musicVolumeBarButton.data.PositionData.push_back({ musicVolumeBarButtonButtonCenterX - musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY - musicVolumeBarButtonButtonRadius, 0 }); + musicVolumeBarButton.data.PositionData.push_back({ musicVolumeBarButtonButtonCenterX - musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY + musicVolumeBarButtonButtonRadius, 0 }); + musicVolumeBarButton.data.PositionData.push_back({ musicVolumeBarButtonButtonCenterX + musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY + musicVolumeBarButtonButtonRadius, 0 }); + musicVolumeBarButton.data.PositionData.push_back({ musicVolumeBarButtonButtonCenterX - musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY - musicVolumeBarButtonButtonRadius, 0 }); + musicVolumeBarButton.data.PositionData.push_back({ musicVolumeBarButtonButtonCenterX + musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY + musicVolumeBarButtonButtonRadius, 0 }); + musicVolumeBarButton.data.PositionData.push_back({ musicVolumeBarButtonButtonCenterX + musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY - musicVolumeBarButtonButtonRadius, 0 }); + + musicVolumeBarButton.data.TexCoordData.push_back({ 0,0 }); + musicVolumeBarButton.data.TexCoordData.push_back({ 0,1 }); + musicVolumeBarButton.data.TexCoordData.push_back({ 1,1 }); + musicVolumeBarButton.data.TexCoordData.push_back({ 0,0 }); + musicVolumeBarButton.data.TexCoordData.push_back({ 1,1 }); + musicVolumeBarButton.data.TexCoordData.push_back({ 1,0 }); + + musicVolumeBarButton.RefreshVBO();*/ + renderer.InitOpenGL(); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + planetObject.init(); + + rockTexture = std::make_unique(CreateTextureDataFromPng("./resources/rock.png", "")); + + } + + void Game::drawCubemap(float skyPercent) + { + static const std::string defaultShaderName = "default"; + static const std::string envShaderName = "env"; + static const std::string vPositionName = "vPosition"; + static const std::string vTexCoordName = "vTexCoord"; + static const std::string textureUniformName = "Texture"; + static const std::string skyPercentUniformName = "skyPercent"; + + renderer.shaderManager.PushShader(envShaderName); + renderer.RenderUniform1i(textureUniformName, 0); + renderer.RenderUniform1f(skyPercentUniformName, skyPercent); + renderer.EnableVertexAttribArray(vPositionName); + renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5, + static_cast(Environment::width) / static_cast(Environment::height), + Environment::CONST_Z_NEAR, Environment::CONST_Z_FAR); + renderer.PushMatrix(); + renderer.LoadIdentity(); + renderer.RotateMatrix(Environment::inverseShipMatrix); + + CheckGlError(); + + glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture->getTexID()); + renderer.DrawVertexRenderStruct(cubemap); + + CheckGlError(); + + + renderer.PopMatrix(); + renderer.PopProjectionMatrix(); + renderer.DisableVertexAttribArray(vPositionName); + + renderer.shaderManager.PopShader(); + CheckGlError(); + } + + void Game::drawShip() + { + static const std::string defaultShaderName = "default"; + static const std::string envShaderName = "env"; + static const std::string vPositionName = "vPosition"; + static const std::string vTexCoordName = "vTexCoord"; + static const std::string textureUniformName = "Texture"; + + renderer.shaderManager.PushShader(defaultShaderName); + renderer.RenderUniform1i(textureUniformName, 0); + renderer.EnableVertexAttribArray(vPositionName); + renderer.EnableVertexAttribArray(vTexCoordName); + + renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5, + static_cast(Environment::width) / static_cast(Environment::height), + Environment::CONST_Z_NEAR, Environment::CONST_Z_FAR); + renderer.PushMatrix(); + + renderer.LoadIdentity(); + renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom }); + + renderer.TranslateMatrix({ 0, -Environment::zoom * 0.03f, 0 }); + glBindTexture(GL_TEXTURE_2D, spaceshipTexture->getTexID()); + renderer.DrawVertexRenderStruct(spaceship); + + for (const auto& p : projectiles) { + if (p && p->isActive()) { + p->draw(renderer); + } + } + + sparkEmitter.draw(renderer, Environment::zoom, Environment::width, Environment::height); + projectileEmitter.draw(renderer, Environment::zoom, Environment::width, Environment::height); + + renderer.PopMatrix(); + renderer.PopProjectionMatrix(); + renderer.DisableVertexAttribArray(vPositionName); + renderer.DisableVertexAttribArray(vTexCoordName); + + renderer.shaderManager.PopShader(); + CheckGlError(); + } + + void Game::drawBoxes() + { + static const std::string defaultShaderName = "default"; + static const std::string envShaderName = "env"; + static const std::string vPositionName = "vPosition"; + static const std::string vTexCoordName = "vTexCoord"; + static const std::string textureUniformName = "Texture"; + + renderer.shaderManager.PushShader(defaultShaderName); + renderer.RenderUniform1i(textureUniformName, 0); + renderer.EnableVertexAttribArray(vPositionName); + renderer.EnableVertexAttribArray(vTexCoordName); + + renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5, + static_cast(Environment::width) / static_cast(Environment::height), + Environment::CONST_Z_NEAR, Environment::CONST_Z_FAR); + + for (int i = 0; i < boxCoordsArr.size(); i++) + { + renderer.PushMatrix(); + + renderer.LoadIdentity(); + renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom }); + renderer.RotateMatrix(Environment::inverseShipMatrix); + renderer.TranslateMatrix(-Environment::shipPosition); + renderer.TranslateMatrix({ 0.f, 0.f, 45000.f }); + renderer.TranslateMatrix(boxCoordsArr[i].pos); + renderer.RotateMatrix(boxCoordsArr[i].m); + + glBindTexture(GL_TEXTURE_2D, boxTexture->getTexID()); + //glBindTexture(GL_TEXTURE_2D, rockTexture->getTexID()); + renderer.DrawVertexRenderStruct(boxRenderArr[i]); + + renderer.PopMatrix(); + } + renderer.PopProjectionMatrix(); + renderer.DisableVertexAttribArray(vPositionName); + renderer.DisableVertexAttribArray(vTexCoordName); + + renderer.shaderManager.PopShader(); + CheckGlError(); + } + /*void Game::UpdateVolumeKnob() { + float musicVolumeBarButtonButtonCenterY = volumeBarMinY + musicVolume * (volumeBarMaxY - volumeBarMinY); + + auto& pos = musicVolumeBarButton.data.PositionData; + + pos[0] = { musicVolumeBarButtonButtonCenterX - musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY - musicVolumeBarButtonButtonRadius, 0 }; + pos[1] = { musicVolumeBarButtonButtonCenterX - musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY + musicVolumeBarButtonButtonRadius, 0 }; + pos[2] = { musicVolumeBarButtonButtonCenterX + musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY + musicVolumeBarButtonButtonRadius, 0 }; + pos[3] = { musicVolumeBarButtonButtonCenterX - musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY - musicVolumeBarButtonButtonRadius, 0 }; + pos[4] = { musicVolumeBarButtonButtonCenterX + musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY + musicVolumeBarButtonButtonRadius, 0 }; + pos[5] = { musicVolumeBarButtonButtonCenterX + musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY - musicVolumeBarButtonButtonRadius, 0 }; + + musicVolumeBarButton.RefreshVBO(); + + } + void Game::UpdateVolumeFromMouse(int mouseX, int mouseY) { + + int uiX = mouseX; + int uiY = Environment::height - mouseY; + Environment::shipVelocity = (musicVolume) * (20.0); + if (uiY < volumeBarMinY || uiY > volumeBarMaxY) + { + return; + } + + float t = (uiY - volumeBarMinY) / (volumeBarMaxY - volumeBarMinY); + if (t < 0.0f) t = 0.0f; + if (t > 1.0f) t = 1.0f; + musicVolume = t; + UpdateVolumeKnob(); + }*/ + + void Game::drawUI() + { + static const std::string defaultShaderName = "default"; + static const std::string envShaderName = "env"; + static const std::string vPositionName = "vPosition"; + static const std::string vTexCoordName = "vTexCoord"; + static const std::string textureUniformName = "Texture"; + + glClear(GL_DEPTH_BUFFER_BIT); + + renderer.shaderManager.PushShader(defaultShaderName); + renderer.RenderUniform1i(textureUniformName, 0); + renderer.EnableVertexAttribArray(vPositionName); + renderer.EnableVertexAttribArray(vTexCoordName); + + //renderer.PushProjectionMatrix(Environment::width, Environment::height, -1, 1); + //renderer.PushMatrix(); + + //renderer.LoadIdentity(); + + //glBindTexture(GL_TEXTURE_2D, buttonTexture->getTexID()); + //renderer.DrawVertexRenderStruct(button); + + + //glBindTexture(GL_TEXTURE_2D, musicVolumeBarTexture->getTexID()); + //renderer.DrawVertexRenderStruct(musicVolumeBar); + + //glBindTexture(GL_TEXTURE_2D, musicVolumeBarButtonTexture->getTexID()); + //renderer.DrawVertexRenderStruct(musicVolumeBarButton); + + //renderer.PopMatrix(); + //renderer.PopProjectionMatrix(); + + renderer.DisableVertexAttribArray(vPositionName); + renderer.DisableVertexAttribArray(vTexCoordName); + uiManager.draw(renderer); + renderer.shaderManager.PopShader(); + CheckGlError(); + } + + void Game::drawScene() { + static const std::string defaultShaderName = "default"; + static const std::string envShaderName = "env"; + static const std::string vPositionName = "vPosition"; + static const std::string vTexCoordName = "vTexCoord"; + static const std::string textureUniformName = "Texture"; + + glClearColor(0.0f, 1.0f, 0.0f, 1.0f); + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + + glViewport(0, 0, Environment::width, Environment::height); + + CheckGlError(); + + float skyPercent = 0.0; + float distance = planetObject.distanceToPlanetSurface(Environment::shipPosition); + if (distance > 1900.f) + { + skyPercent = 0.0f; + } + else if (distance < 1000.f) + { + skyPercent = 1.0f; + } + else + { + skyPercent = (1900.f - distance) / 900.f; + } + + + drawCubemap(skyPercent); + planetObject.draw(renderer); + if (planetObject.distanceToPlanetSurface(Environment::shipPosition) > 100.f) + { + glClear(GL_DEPTH_BUFFER_BIT); + } + drawShip(); + drawBoxes(); + + drawUI(); + + CheckGlError(); + } + + void Game::processTickCount() { + + if (lastTickCount == 0) { + lastTickCount = SDL_GetTicks64(); + return; + } + + newTickCount = SDL_GetTicks64(); + if (newTickCount - lastTickCount > CONST_TIMER_INTERVAL) { + size_t delta = (newTickCount - lastTickCount > CONST_MAX_TIME_INTERVAL) ? + CONST_MAX_TIME_INTERVAL : newTickCount - lastTickCount; + + //gameObjects.updateScene(delta); + sparkEmitter.update(static_cast(delta)); + planetObject.update(static_cast(delta)); + + if (Environment::tapDownHold) { + + float diffx = Environment::tapDownCurrentPos.v[0] - Environment::tapDownStartPos.v[0]; + float diffy = Environment::tapDownCurrentPos.v[1] - Environment::tapDownStartPos.v[1]; + + if (abs(diffy) > 5.0 || abs(diffx) > 5.0) //threshold + { + + float rotationPower = sqrtf(diffx * diffx + diffy * diffy); + + //std::cout << rotationPower << std::endl; + + float deltaAlpha = rotationPower * delta * M_PI / 500000.f; + + Vector3f rotationDirection = { diffy, diffx, 0 }; + + rotationDirection = rotationDirection.normalized(); + + Vector4f rotateQuat = { + rotationDirection.v[0] * sin(deltaAlpha * 0.5f), + rotationDirection.v[1] * sin(deltaAlpha * 0.5f), + rotationDirection.v[2] * sin(deltaAlpha * 0.5f), + cos(deltaAlpha * 0.5f) }; + + Matrix3f rotateMat = QuatToMatrix(rotateQuat); + + Environment::shipMatrix = MultMatrixMatrix(Environment::shipMatrix, rotateMat); + Environment::inverseShipMatrix = InverseMatrix(Environment::shipMatrix); + + } + } + + if (fabs(Environment::shipVelocity) > 0.01f) + { + Vector3f velocityDirection = { 0,0, -Environment::shipVelocity * delta / 1000.f }; + Vector3f velocityDirectionAdjusted = MultMatrixVector(Environment::shipMatrix, velocityDirection); + Environment::shipPosition = Environment::shipPosition + velocityDirectionAdjusted; + } + + for (auto& p : projectiles) { + if (p && p->isActive()) { + p->update(static_cast(delta), renderer); + } + } + + std::vector projCameraPoints; + for (const auto& p : projectiles) { + if (p && p->isActive()) { + Vector3f worldPos = p->getPosition(); + Vector3f rel = worldPos - Environment::shipPosition; + Vector3f camPos = MultMatrixVector(Environment::inverseShipMatrix, rel); + projCameraPoints.push_back(camPos); + } + } + if (!projCameraPoints.empty()) { + projectileEmitter.setEmissionPoints(projCameraPoints); + projectileEmitter.emit(); + } + else { + projectileEmitter.setEmissionPoints(std::vector()); + } + + std::vector shipCameraPoints; + for (const auto& lp : shipLocalEmissionPoints) { + Vector3f adjusted = lp + Vector3f{ 0.0f, -Environment::zoom * 0.03f, 0.0f }; + shipCameraPoints.push_back(adjusted); + } + if (!shipCameraPoints.empty()) { + sparkEmitter.setEmissionPoints(shipCameraPoints); + } + + sparkEmitter.update(static_cast(delta)); + projectileEmitter.update(static_cast(delta)); + + lastTickCount = newTickCount; + } + } + + void Game::fireProjectiles() { + std::vector localOffsets = { + Vector3f{ -1.5f, 0.9f, 5.0f }, + Vector3f{ 1.5f, 0.9f, 5.0f } + }; + + const float projectileSpeed = 60.0f; + const float lifeMs = 5000.0f; + const float size = 0.5f; + + Vector3f localForward = { 0,0,-1 }; + Vector3f worldForward = MultMatrixVector(Environment::shipMatrix, localForward).normalized(); + + for (const auto& lo : localOffsets) { + Vector3f worldPos = Environment::shipPosition + MultMatrixVector(Environment::shipMatrix, lo); + Vector3f worldVel = worldForward * projectileSpeed; + + for (auto& p : projectiles) { + if (!p->isActive()) { + p->init(worldPos, worldVel, lifeMs, size, projectileTexture, renderer); + break; + } + } + } + } + + void Game::render() { + SDL_GL_MakeCurrent(ZL::Environment::window, glContext); + ZL::CheckGlError(); + + glClearColor(0.0f, 1.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + drawScene(); + processTickCount(); + + SDL_GL_SwapWindow(ZL::Environment::window); + } + void Game::update() { + SDL_Event event; + while (SDL_PollEvent(&event)) { + if (event.type == SDL_QUIT) { + Environment::exitGameLoop = true; + } + else if (event.type == SDL_MOUSEBUTTONDOWN) { + // 1. Îáðàáîòêà íàæàòèÿ êíîïêè ìûøè + + int mx = event.button.x; + int my = event.button.y; + int uiX = mx; + int uiY = Environment::height - my; + + uiManager.onMouseDown(uiX, uiY); + + bool uiHandled = false; + + if (event.button.button == SDL_BUTTON_LEFT && !uiManager.isUiInteraction()) { + uint64_t now = SDL_GetTicks64(); + if (now - lastProjectileFireTime >= static_cast(projectileCooldownMs)) { + lastProjectileFireTime = now; + fireProjectiles(); + } + } + + for (const auto& button : uiManager.findButton("") ? std::vector>{} : std::vector>{}) { + (void)button; + } + + auto pressedSlider = [&]() -> std::shared_ptr { + for (const auto& slider : uiManager.findSlider("") ? std::vector>{} : std::vector>{}) { + (void)slider; + } + return nullptr; + }(); + + if (!uiManager.isUiInteraction()) { + Environment::tapDownHold = true; + // Êîîðäèíàòû íà÷àëüíîãî íàæàòèÿ + Environment::tapDownStartPos.v[0] = mx; + Environment::tapDownStartPos.v[1] = my; + // Íà÷àëüíàÿ ïîçèöèÿ òàêæå ñòàíîâèòñÿ òåêóùåé + Environment::tapDownCurrentPos.v[0] = mx; + Environment::tapDownCurrentPos.v[1] = my; + } + } + else if (event.type == SDL_MOUSEBUTTONUP) { + // 2. Îáðàáîòêà îòïóñêàíèÿ êíîïêè ìûøè + int mx = event.button.x; + int my = event.button.y; + int uiX = mx; + int uiY = Environment::height - my; + + uiManager.onMouseUp(uiX, uiY); + + if (!uiManager.isUiInteraction()) { + Environment::tapDownHold = false; + } + } + else if (event.type == SDL_MOUSEMOTION) { + // 3. Îáðàáîòêà ïåðåìåùåíèÿ ìûøè + int mx = event.motion.x; + int my = event.motion.y; + int uiX = mx; + int uiY = Environment::height - my; + + uiManager.onMouseMove(uiX, uiY); + + if (Environment::tapDownHold && !uiManager.isUiInteraction()) { + Environment::tapDownCurrentPos.v[0] = mx; + Environment::tapDownCurrentPos.v[1] = my; + } + } + else if (event.type == SDL_MOUSEWHEEL) { + static const float zoomstep = 2.0f; + if (event.wheel.y > 0) { + Environment::zoom -= zoomstep; + } + else if (event.wheel.y < 0) { + Environment::zoom += zoomstep; + } + if (Environment::zoom < zoomstep) { + Environment::zoom = zoomstep; + } + } + else if (event.type == SDL_KEYUP) + { + if (event.key.keysym.sym == SDLK_i) + { + Environment::shipVelocity += 500.f; + } + if (event.key.keysym.sym == SDLK_k) + { + Environment::shipVelocity -= 500.f; + } + if (event.key.keysym.sym == SDLK_o) + { + Environment::shipVelocity += 50.f; + } + if (event.key.keysym.sym == SDLK_l) + { + Environment::shipVelocity -= 50.f; + } + } + } + render(); + } + +} // namespace ZL diff --git a/Game.h b/src/Game.h old mode 100755 new mode 100644 similarity index 90% rename from Game.h rename to src/Game.h index 4b7ebd9..e96e33c --- a/Game.h +++ b/src/Game.h @@ -1,110 +1,109 @@ -#pragma once - -#include "OpenGlExtensions.h" -#include "Renderer.h" -#include "Environment.h" -#include "TextureManager.h" -#include "SparkEmitter.h" -#include "PlanetObject.h" -#include "UiManager.h" -#include "Projectile.h" - -namespace ZL { - - - struct BoxCoords - { - Vector3f pos; - Matrix3f m; - }; - - - class Game { - public: - Game(); - ~Game(); - - void setup(); - void update(); - void render(); - - - bool shouldExit() const { return Environment::exitGameLoop; } - - private: - void processTickCount(); - void drawScene(); - void drawCubemap(float skyPercent); - void drawShip(); - void drawBoxes(); - void drawUI(); - - void fireProjectiles(); - - SDL_Window* window; - SDL_GLContext glContext; - Renderer renderer; - - size_t newTickCount; - size_t lastTickCount; - - std::shared_ptr rockTexture; - - - - std::vector boxCoordsArr; - std::vector boxRenderArr; - - - //std::shared_ptr buttonTexture; - //VertexRenderStruct button; - - //std::shared_ptr musicVolumeBarTexture; - //VertexRenderStruct musicVolumeBar; - - //std::shared_ptr musicVolumeBarButtonTexture; - //VertexRenderStruct musicVolumeBarButton; - - - //bool isDraggingVolume = false; - - float musicVolume = 0.0f; - float volumeBarMinX = 1190.0f; - float volumeBarMaxX = 1200.0f; - float volumeBarMinY = 100.0f; - float volumeBarMaxY = 600.0f; - //float musicVolumeBarButtonButtonCenterX = 1195.0f; - //float musicVolumeBarButtonButtonRadius = 25.0f; - //void UpdateVolumeFromMouse(int mouseX, int mouseY); - //void UpdateVolumeKnob(); - - - static const size_t CONST_TIMER_INTERVAL = 10; - static const size_t CONST_MAX_TIME_INTERVAL = 1000; - - std::shared_ptr sparkTexture; - std::shared_ptr spaceshipTexture; - std::shared_ptr cubemapTexture; - VertexDataStruct spaceshipBase; - VertexRenderStruct spaceship; - - VertexRenderStruct cubemap; - - std::shared_ptr boxTexture; - VertexDataStruct boxBase; - - SparkEmitter sparkEmitter; - SparkEmitter projectileEmitter; - PlanetObject planetObject; - UiManager uiManager; - - std::vector> projectiles; - std::shared_ptr projectileTexture; - float projectileCooldownMs = 500.0f; - uint64_t lastProjectileFireTime = 0; - int maxProjectiles = 32; - std::vector shipLocalEmissionPoints; - }; - - +#pragma once + +#include "render/Renderer.h" +#include "Environment.h" +#include "render/TextureManager.h" +#include "SparkEmitter.h" +#include "planet/PlanetObject.h" +#include "UiManager.h" +#include "Projectile.h" + +namespace ZL { + + + struct BoxCoords + { + Vector3f pos; + Matrix3f m; + }; + + + class Game { + public: + Game(); + ~Game(); + + void setup(); + void update(); + void render(); + + + bool shouldExit() const { return Environment::exitGameLoop; } + + private: + void processTickCount(); + void drawScene(); + void drawCubemap(float skyPercent); + void drawShip(); + void drawBoxes(); + void drawUI(); + + void fireProjectiles(); + + SDL_Window* window; + SDL_GLContext glContext; + Renderer renderer; + + size_t newTickCount; + size_t lastTickCount; + + std::shared_ptr rockTexture; + + + + std::vector boxCoordsArr; + std::vector boxRenderArr; + + + //std::shared_ptr buttonTexture; + //VertexRenderStruct button; + + //std::shared_ptr musicVolumeBarTexture; + //VertexRenderStruct musicVolumeBar; + + //std::shared_ptr musicVolumeBarButtonTexture; + //VertexRenderStruct musicVolumeBarButton; + + + //bool isDraggingVolume = false; + + float musicVolume = 0.0f; + float volumeBarMinX = 1190.0f; + float volumeBarMaxX = 1200.0f; + float volumeBarMinY = 100.0f; + float volumeBarMaxY = 600.0f; + //float musicVolumeBarButtonButtonCenterX = 1195.0f; + //float musicVolumeBarButtonButtonRadius = 25.0f; + //void UpdateVolumeFromMouse(int mouseX, int mouseY); + //void UpdateVolumeKnob(); + + + static const size_t CONST_TIMER_INTERVAL = 10; + static const size_t CONST_MAX_TIME_INTERVAL = 1000; + + std::shared_ptr sparkTexture; + std::shared_ptr spaceshipTexture; + std::shared_ptr cubemapTexture; + VertexDataStruct spaceshipBase; + VertexRenderStruct spaceship; + + VertexRenderStruct cubemap; + + std::shared_ptr boxTexture; + VertexDataStruct boxBase; + + SparkEmitter sparkEmitter; + SparkEmitter projectileEmitter; + PlanetObject planetObject; + UiManager uiManager; + + std::vector> projectiles; + std::shared_ptr projectileTexture; + float projectileCooldownMs = 500.0f; + uint64_t lastProjectileFireTime = 0; + int maxProjectiles = 32; + std::vector shipLocalEmissionPoints; + }; + + } // namespace ZL \ No newline at end of file diff --git a/Projectile.cpp b/src/Projectile.cpp similarity index 100% rename from Projectile.cpp rename to src/Projectile.cpp diff --git a/Projectile.h b/src/Projectile.h similarity index 85% rename from Projectile.h rename to src/Projectile.h index 627d472..7556cb8 100644 --- a/Projectile.h +++ b/src/Projectile.h @@ -1,8 +1,8 @@ #pragma once -#include "ZLMath.h" -#include "Renderer.h" -#include "TextureManager.h" +#include "utils/ZLMath.h" +#include "render/Renderer.h" +#include "render/TextureManager.h" #include namespace ZL { diff --git a/SparkEmitter.cpp b/src/SparkEmitter.cpp similarity index 99% rename from SparkEmitter.cpp rename to src/SparkEmitter.cpp index 1460c43..f9f07b6 100644 --- a/SparkEmitter.cpp +++ b/src/SparkEmitter.cpp @@ -1,7 +1,7 @@ #include "SparkEmitter.h" #include #include -#include "OpenGlExtensions.h" +//#include "renderer/OpenGlExtensions.h" #include #include "external/nlohmann/json.hpp" #include diff --git a/SparkEmitter.h b/src/SparkEmitter.h similarity index 95% rename from SparkEmitter.h rename to src/SparkEmitter.h index 953bd34..e70888a 100644 --- a/SparkEmitter.h +++ b/src/SparkEmitter.h @@ -1,8 +1,8 @@ #pragma once -#include "ZLMath.h" -#include "Renderer.h" -#include "TextureManager.h" +#include "utils/ZLMath.h" +#include "render/Renderer.h" +#include "render/TextureManager.h" #include #include #include diff --git a/TextModel.cpp b/src/TextModel.cpp similarity index 100% rename from TextModel.cpp rename to src/TextModel.cpp diff --git a/TextModel.h b/src/TextModel.h similarity index 82% rename from TextModel.h rename to src/TextModel.h index 8273b03..c1881af 100644 --- a/TextModel.h +++ b/src/TextModel.h @@ -1,7 +1,7 @@ #pragma once -#include "ZLMath.h" -#include "Renderer.h" +#include "utils/ZLMath.h" +#include "render/Renderer.h" #include diff --git a/UiManager.cpp b/src/UiManager.cpp similarity index 99% rename from UiManager.cpp rename to src/UiManager.cpp index 27fbb25..48c3c21 100644 --- a/UiManager.cpp +++ b/src/UiManager.cpp @@ -1,5 +1,5 @@ #include "UiManager.h" -#include "Utils.h" +#include "utils/Utils.h" #include #include #include diff --git a/UiManager.h b/src/UiManager.h similarity index 97% rename from UiManager.h rename to src/UiManager.h index cee34af..dfee5aa 100644 --- a/UiManager.h +++ b/src/UiManager.h @@ -1,7 +1,7 @@ #pragma once -#include "Renderer.h" -#include "TextureManager.h" +#include "render/Renderer.h" +#include "render/TextureManager.h" #include "Environment.h" #include "external/nlohmann/json.hpp" #include diff --git a/external/nlohmann/json.hpp b/src/external/nlohmann/json.hpp similarity index 100% rename from external/nlohmann/json.hpp rename to src/external/nlohmann/json.hpp diff --git a/gl/glext.h b/src/gl/glext.h old mode 100755 new mode 100644 similarity index 100% rename from gl/glext.h rename to src/gl/glext.h diff --git a/main.cpp b/src/main.cpp old mode 100755 new mode 100644 similarity index 96% rename from main.cpp rename to src/main.cpp index a636b19..fc00dd4 --- a/main.cpp +++ b/src/main.cpp @@ -1,88 +1,88 @@ -#include "Game.h" -#include "Environment.h" -#include - -ZL::Game game; -void MainLoop() { - game.update(); -} -int main(int argc, char* argv[]) { - try - { - constexpr int CONST_WIDTH = 1280; - constexpr int CONST_HEIGHT = 720; - - ZL::Environment::width = CONST_WIDTH; - ZL::Environment::height = CONST_HEIGHT; - - -#ifdef EMSCRIPTEN - if (SDL_Init(SDL_INIT_VIDEO) != 0) { - std::cerr << "SDL_Init failed: " << SDL_GetError() << std::endl; - return 1; - } - - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); - - SDL_Window* win = SDL_CreateWindow("Space Ship Game", - SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, - CONST_WIDTH, CONST_HEIGHT, - SDL_WINDOW_OPENGL); - - if (!win) { - std::cerr << "SDL_CreateWindow failed: " << SDL_GetError() << std::endl; - return 1; - } - - SDL_GLContext glContext = SDL_GL_CreateContext(win); - if (!glContext) { - std::cerr << "SDL_GL_CreateContext failed: " << SDL_GetError() << std::endl; - return 1; - } - - // Привязка контекста к окну — важно! - SDL_GL_MakeCurrent(win, glContext); - - ZL::Environment::window = win; -#else - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) != 0) { - SDL_Log("SDL init failed: %s", SDL_GetError()); - return 1; - } - - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - - ZL::Environment::window = SDL_CreateWindow( - "Space Ship Game", - SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, - CONST_WIDTH, CONST_HEIGHT, - SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN - ); - - SDL_GLContext ctx = SDL_GL_CreateContext(ZL::Environment::window); - SDL_GL_MakeCurrent(ZL::Environment::window, ctx); -#endif - - game.setup(); - -#ifdef EMSCRIPTEN - emscripten_set_main_loop(MainLoop, 0, 1); -#else - while (!game.shouldExit()) { - game.update(); - SDL_Delay(2); - } -#endif - - } - catch (const std::exception& e) - { - std::cout << e.what() << std::endl; - } - - return 0; -} +#include "Game.h" +#include "Environment.h" +#include + +ZL::Game game; +void MainLoop() { + game.update(); +} +int main(int argc, char* argv[]) { + try + { + constexpr int CONST_WIDTH = 1280; + constexpr int CONST_HEIGHT = 720; + + ZL::Environment::width = CONST_WIDTH; + ZL::Environment::height = CONST_HEIGHT; + + +#ifdef EMSCRIPTEN + if (SDL_Init(SDL_INIT_VIDEO) != 0) { + std::cerr << "SDL_Init failed: " << SDL_GetError() << std::endl; + return 1; + } + + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); + + SDL_Window* win = SDL_CreateWindow("Space Ship Game", + SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + CONST_WIDTH, CONST_HEIGHT, + SDL_WINDOW_OPENGL); + + if (!win) { + std::cerr << "SDL_CreateWindow failed: " << SDL_GetError() << std::endl; + return 1; + } + + SDL_GLContext glContext = SDL_GL_CreateContext(win); + if (!glContext) { + std::cerr << "SDL_GL_CreateContext failed: " << SDL_GetError() << std::endl; + return 1; + } + + // Привязка контекста к окну — важно! + SDL_GL_MakeCurrent(win, glContext); + + ZL::Environment::window = win; +#else + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) != 0) { + SDL_Log("SDL init failed: %s", SDL_GetError()); + return 1; + } + + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + + ZL::Environment::window = SDL_CreateWindow( + "Space Ship Game", + SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + CONST_WIDTH, CONST_HEIGHT, + SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN + ); + + SDL_GLContext ctx = SDL_GL_CreateContext(ZL::Environment::window); + SDL_GL_MakeCurrent(ZL::Environment::window, ctx); +#endif + + game.setup(); + +#ifdef EMSCRIPTEN + emscripten_set_main_loop(MainLoop, 0, 1); +#else + while (!game.shouldExit()) { + game.update(); + SDL_Delay(2); + } +#endif + + } + catch (const std::exception& e) + { + std::cout << e.what() << std::endl; + } + + return 0; +} diff --git a/PlanetData.cpp b/src/planet/PlanetData.cpp similarity index 100% rename from PlanetData.cpp rename to src/planet/PlanetData.cpp diff --git a/PlanetData.h b/src/planet/PlanetData.h similarity index 97% rename from PlanetData.h rename to src/planet/PlanetData.h index 6578eeb..26aa8b5 100644 --- a/PlanetData.h +++ b/src/planet/PlanetData.h @@ -1,8 +1,8 @@ #pragma once -#include "ZLMath.h" -#include "Perlin.h" -#include "Renderer.h" // VertexDataStruct +#include "utils/ZLMath.h" +#include "utils/Perlin.h" +#include "render/Renderer.h" #include #include #include diff --git a/PlanetObject.cpp b/src/planet/PlanetObject.cpp similarity index 99% rename from PlanetObject.cpp rename to src/planet/PlanetObject.cpp index 1566ab9..847ab59 100644 --- a/PlanetObject.cpp +++ b/src/planet/PlanetObject.cpp @@ -1,7 +1,7 @@ #include "PlanetObject.h" #include #include -#include "OpenGlExtensions.h" +#include "render/OpenGlExtensions.h" #include "Environment.h" #include "StoneObject.h" diff --git a/PlanetObject.h b/src/planet/PlanetObject.h similarity index 90% rename from PlanetObject.h rename to src/planet/PlanetObject.h index c45875f..0c3ad6c 100644 --- a/PlanetObject.h +++ b/src/planet/PlanetObject.h @@ -1,8 +1,8 @@ #pragma once -#include "ZLMath.h" -#include "Renderer.h" -#include "TextureManager.h" +#include "utils/ZLMath.h" +#include "render/Renderer.h" +#include "render/TextureManager.h" #include #include #include @@ -13,10 +13,10 @@ #include #include #include -#include "Perlin.h" +#include "utils/Perlin.h" #include "PlanetData.h" #include "StoneObject.h" -#include "FrameBuffer.h" +#include "render/FrameBuffer.h" namespace ZL { diff --git a/StoneObject.cpp b/src/planet/StoneObject.cpp similarity index 99% rename from StoneObject.cpp rename to src/planet/StoneObject.cpp index 4b226b8..e336e94 100644 --- a/StoneObject.cpp +++ b/src/planet/StoneObject.cpp @@ -1,10 +1,10 @@ #include "StoneObject.h" -#include "Utils.h" +#include "utils/Utils.h" #include #include #include -#include "Renderer.h" +#include "render/Renderer.h" #include "PlanetData.h" namespace ZL { diff --git a/StoneObject.h b/src/planet/StoneObject.h similarity index 96% rename from StoneObject.h rename to src/planet/StoneObject.h index 0fd4db3..5a1664c 100644 --- a/StoneObject.h +++ b/src/planet/StoneObject.h @@ -1,6 +1,6 @@ #pragma once -#include "ZLMath.h" -#include "Renderer.h" +#include "utils/ZLMath.h" +#include "render/Renderer.h" #include "PlanetData.h" namespace ZL { diff --git a/FrameBuffer.cpp b/src/render/FrameBuffer.cpp similarity index 100% rename from FrameBuffer.cpp rename to src/render/FrameBuffer.cpp diff --git a/FrameBuffer.h b/src/render/FrameBuffer.h similarity index 100% rename from FrameBuffer.h rename to src/render/FrameBuffer.h diff --git a/OpenGlExtensions.cpp b/src/render/OpenGlExtensions.cpp old mode 100755 new mode 100644 similarity index 97% rename from OpenGlExtensions.cpp rename to src/render/OpenGlExtensions.cpp index 45f0936..e4b3677 --- a/OpenGlExtensions.cpp +++ b/src/render/OpenGlExtensions.cpp @@ -1,335 +1,335 @@ -#include "OpenGlExtensions.h" - -#include "Utils.h" -#include - -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) - -//==================================================== -//===================== GLSL Shaders ================= -//==================================================== - -//Requires GL_VERSION_2_0 -PFNGLCREATEPROGRAMPROC glCreateProgram = NULL; -PFNGLDELETEPROGRAMPROC glDeleteProgram = NULL; -PFNGLLINKPROGRAMPROC glLinkProgram = NULL; -PFNGLVALIDATEPROGRAMPROC glValidateProgram = NULL; -PFNGLUSEPROGRAMPROC glUseProgram = NULL; -PFNGLGETPROGRAMIVPROC glGetProgramiv = NULL; -PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog = NULL; -PFNGLCREATESHADERPROC glCreateShader = NULL; -PFNGLDELETESHADERPROC glDeleteShader = NULL; -PFNGLSHADERSOURCEPROC glShaderSource = NULL; -PFNGLCOMPILESHADERPROC glCompileShader = NULL; -PFNGLATTACHSHADERPROC glAttachShader = NULL; -PFNGLDETACHSHADERPROC glDetachShader = NULL; -PFNGLGETSHADERIVPROC glGetShaderiv = NULL; -PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog = NULL; -PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation = NULL; -PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer = NULL; -PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray = NULL; -PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray = NULL; -PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation = NULL; -PFNGLUNIFORMMATRIX3FVPROC glUniformMatrix3fv = NULL; -PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv = NULL; -PFNGLUNIFORM1IPROC glUniform1i = NULL; -PFNGLUNIFORM1FVPROC glUniform1fv = NULL; -PFNGLUNIFORM3FVPROC glUniform2fv = NULL; -PFNGLUNIFORM3FVPROC glUniform3fv = NULL; -PFNGLUNIFORM4FVPROC glUniform4fv = NULL; -PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f = NULL; -PFNGLVERTEXATTRIB2FPROC glVertexAttrib2f = NULL; -PFNGLVERTEXATTRIB3FPROC glVertexAttrib3f = NULL; -PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f = NULL; -PFNGLVERTEXATTRIB2FVPROC glVertexAttrib2fv = NULL; -PFNGLVERTEXATTRIB3FVPROC glVertexAttrib3fv = NULL; -PFNGLVERTEXATTRIB4FVPROC glVertexAttrib4fv = NULL; -PFNGLGETACTIVEATTRIBPROC glGetActiveAttrib = NULL; -PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform = NULL; - - -//======================================= -//=========== Multitexture ============== -//======================================= - -//Requires GL version 1.3 -PFNGLACTIVETEXTUREPROC glActiveTexture = NULL; - -//======================================= -//========== Vertex buffer ============== -//======================================= - -//Requires GL_VERSION_1_5 -PFNGLGENBUFFERSPROC glGenBuffers = NULL; -PFNGLDELETEBUFFERSPROC glDeleteBuffers = NULL; -PFNGLBINDBUFFERPROC glBindBuffer = NULL; -PFNGLBUFFERDATAPROC glBufferData = NULL; -PFNGLBUFFERSUBDATAPROC glBufferSubData = NULL; -PFNGLMAPBUFFERPROC glMapBuffer = NULL; -PFNGLUNMAPBUFFERPROC glUnmapBuffer = NULL; - -//========================================= -//============ Frame buffer =============== -//========================================= - -//Requires GL_ARB_framebuffer_object -PFNGLISRENDERBUFFERPROC glIsRenderbuffer = NULL; -PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer = NULL; -PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers = NULL; -PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers = NULL; -PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage = NULL; -PFNGLGETRENDERBUFFERPARAMETERIVPROC glGetRenderbufferParameteriv = NULL; -PFNGLISFRAMEBUFFERPROC glIsFramebuffer = NULL; -PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer = NULL; -PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers = NULL; -PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers = NULL; -PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus = NULL; -PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D = NULL; -PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D = NULL; -PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D = NULL; -PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer = NULL; -PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetFramebufferAttachmentParameteriv = NULL; -PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer = NULL; -PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample = NULL; -PFNGLGENERATEMIPMAPPROC glGenerateMipmap = NULL; -PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer = NULL; - - - -//=========================================== -//============ Uniform buffer =============== -//=========================================== - -//Requires GL_ARB_uniform_buffer_object -PFNGLGETUNIFORMINDICESPROC glGetUniformIndices = NULL; -PFNGLGETACTIVEUNIFORMSIVPROC glGetActiveUniformsiv = NULL; -PFNGLGETACTIVEUNIFORMNAMEPROC glGetActiveUniformName = NULL; -PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex = NULL; -PFNGLGETACTIVEUNIFORMBLOCKIVPROC glGetActiveUniformBlockiv = NULL; -PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glGetActiveUniformBlockName = NULL; -PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding = NULL; -PFNGLBINDBUFFERBASEPROC glBindBufferBase = NULL; - - -PFNGLGENVERTEXARRAYSPROC glGenVertexArrays = NULL; -PFNGLBINDVERTEXARRAYPROC glBindVertexArray = NULL; -PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArray = NULL; - -#endif - -namespace ZL { - - bool BindOpenGlFunctions() - { -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) - //char* extensionList = (char*)glGetString(GL_EXTENSIONS); - char* glVersion = (char*)glGetString(GL_VERSION); - bool ok = true; - - //Requires OpenGL 2.0 or above - if (glVersion[0] >= '2') - { - - glActiveTexture = (PFNGLACTIVETEXTUREPROC)wglGetProcAddress("glActiveTexture"); - - glGenBuffers = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glGenBuffers"); - glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)wglGetProcAddress("glDeleteBuffers"); - glBindBuffer = (PFNGLBINDBUFFERPROC)wglGetProcAddress("glBindBuffer"); - glBufferData = (PFNGLBUFFERDATAPROC)wglGetProcAddress("glBufferData"); - glBufferSubData = (PFNGLBUFFERSUBDATAPROC)wglGetProcAddress("glBufferSubData"); - glMapBuffer = (PFNGLMAPBUFFERPROC)wglGetProcAddress("glMapBuffer"); - glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)wglGetProcAddress("glUnmapBuffer"); - - glCreateProgram = (PFNGLCREATEPROGRAMPROC)wglGetProcAddress("glCreateProgram"); - glDeleteProgram = (PFNGLDELETEPROGRAMPROC)wglGetProcAddress("glDeleteProgram"); - glLinkProgram = (PFNGLLINKPROGRAMPROC)wglGetProcAddress("glLinkProgram"); - glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)wglGetProcAddress("glValidateProgram"); - glUseProgram = (PFNGLUSEPROGRAMPROC)wglGetProcAddress("glUseProgram"); - glGetProgramiv = (PFNGLGETPROGRAMIVPROC)wglGetProcAddress("glGetProgramiv"); - glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)wglGetProcAddress("glGetProgramInfoLog"); - glCreateShader = (PFNGLCREATESHADERPROC)wglGetProcAddress("glCreateShader"); - - - glDeleteShader = (PFNGLDELETESHADERPROC)wglGetProcAddress("glDeleteShader"); - glShaderSource = (PFNGLSHADERSOURCEPROC)wglGetProcAddress("glShaderSource"); - glCompileShader = (PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader"); - glAttachShader = (PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader"); - glDetachShader = (PFNGLDETACHSHADERPROC)wglGetProcAddress("glDetachShader"); - glGetShaderiv = (PFNGLGETSHADERIVPROC)wglGetProcAddress("glGetShaderiv"); - glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)wglGetProcAddress("glGetShaderInfoLog"); - glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)wglGetProcAddress("glGetAttribLocation"); - glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)wglGetProcAddress("glVertexAttribPointer"); - glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)wglGetProcAddress("glEnableVertexAttribArray"); - - glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)wglGetProcAddress("glDisableVertexAttribArray"); - glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)wglGetProcAddress("glGetUniformLocation"); - glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)wglGetProcAddress("glUniformMatrix3fv"); - glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)wglGetProcAddress("glUniformMatrix4fv"); - glUniform1i = (PFNGLUNIFORM1IPROC)wglGetProcAddress("glUniform1i"); - glUniform1fv = (PFNGLUNIFORM1FVPROC)wglGetProcAddress("glUniform1fv"); - glUniform2fv = (PFNGLUNIFORM2FVPROC)wglGetProcAddress("glUniform2fv"); - glUniform3fv = (PFNGLUNIFORM3FVPROC)wglGetProcAddress("glUniform3fv"); - glUniform4fv = (PFNGLUNIFORM4FVPROC)wglGetProcAddress("glUniform4fv"); - - glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC)wglGetProcAddress("glVertexAttrib1f"); - glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC)wglGetProcAddress("glVertexAttrib2f"); - glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC)wglGetProcAddress("glVertexAttrib3f"); - glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC)wglGetProcAddress("glVertexAttrib4f"); - glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC)wglGetProcAddress("glVertexAttrib2fv"); - glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC)wglGetProcAddress("glVertexAttrib3fv"); - glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)wglGetProcAddress("glVertexAttrib4fv"); - glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC)wglGetProcAddress("glGetActiveAttrib"); - glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)wglGetProcAddress("glGetActiveUniform"); - - - if (glActiveTexture == NULL || - glGenBuffers == NULL || - glDeleteBuffers == NULL || - glBindBuffer == NULL || - glBufferData == NULL || - glBufferSubData == NULL || - glMapBuffer == NULL || - glCreateProgram == NULL || - glDeleteProgram == NULL || - glLinkProgram == NULL || - glValidateProgram == NULL || - glUseProgram == NULL || - glGetProgramiv == NULL || - glGetProgramInfoLog == NULL || - glCreateShader == NULL || - glDeleteShader == NULL || - glShaderSource == NULL || - glCompileShader == NULL || - glAttachShader == NULL || - glDetachShader == NULL || - glGetShaderiv == NULL || - glGetShaderInfoLog == NULL || - glGetAttribLocation == NULL || - glVertexAttribPointer == NULL || - glEnableVertexAttribArray == NULL || - glDisableVertexAttribArray == NULL || - glGetUniformLocation == NULL || - glUniformMatrix3fv == NULL || - glUniformMatrix4fv == NULL || - glUniform1i == NULL || - glUniform1fv == NULL || - glUniform2fv == NULL || - glUniform3fv == NULL || - glUniform4fv == NULL || - glEnableVertexAttribArray == NULL || - glVertexAttrib1f == NULL || - glVertexAttrib2f == NULL || - glVertexAttrib3f == NULL || - glVertexAttrib4f == NULL || - glVertexAttrib2fv == NULL || - glVertexAttrib3fv == NULL || - glVertexAttrib4fv == NULL || - glGetActiveAttrib == NULL || - glGetActiveUniform == NULL) - { - ok = false; - } - - - } - else - { - ok = false; - } - - - glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)wglGetProcAddress("glIsRenderbuffer"); - glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)wglGetProcAddress("glBindRenderbuffer"); - glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)wglGetProcAddress("glDeleteRenderbuffers"); - glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)wglGetProcAddress("glGenRenderbuffers"); - glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)wglGetProcAddress("glRenderbufferStorage"); - glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)wglGetProcAddress("glGetRenderbufferParameteriv"); - glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC)wglGetProcAddress("glIsFramebuffer"); - glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)wglGetProcAddress("glBindFramebuffer"); - glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)wglGetProcAddress("glDeleteFramebuffers"); - glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)wglGetProcAddress("glGenFramebuffers"); - glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)wglGetProcAddress("glCheckFramebufferStatus"); - glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC)wglGetProcAddress("glFramebufferTexture1D"); - glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)wglGetProcAddress("glFramebufferTexture2D"); - glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)wglGetProcAddress("glFramebufferTexture3D"); - glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)wglGetProcAddress("glFramebufferRenderbuffer"); - glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)wglGetProcAddress("glGetFramebufferAttachmentParameteriv"); - glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)wglGetProcAddress("glBlitFramebuffer"); - glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)wglGetProcAddress("glRenderbufferStorageMultisample"); - glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)wglGetProcAddress("glGenerateMipmap"); - glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)wglGetProcAddress("glFramebufferTextureLayer"); - - if (glIsRenderbuffer == NULL || - glBindRenderbuffer == NULL || - glDeleteRenderbuffers == NULL || - glGenRenderbuffers == NULL || - glRenderbufferStorage == NULL || - glGetRenderbufferParameteriv == NULL || - glIsFramebuffer == NULL || - glBindFramebuffer == NULL || - glDeleteFramebuffers == NULL || - glGenFramebuffers == NULL || - glCheckFramebufferStatus == NULL || - glFramebufferTexture1D == NULL || - glFramebufferTexture2D == NULL || - glFramebufferTexture3D == NULL || - glFramebufferRenderbuffer == NULL || - glGetFramebufferAttachmentParameteriv == NULL || - glBlitFramebuffer == NULL || - glRenderbufferStorageMultisample == NULL || - glGenerateMipmap == NULL || - glFramebufferTextureLayer == NULL) - { - ok = false; - } - - - glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC)wglGetProcAddress("glGetUniformIndices"); - glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC)wglGetProcAddress("glGetActiveUniformsiv"); - glGetActiveUniformName = (PFNGLGETACTIVEUNIFORMNAMEPROC)wglGetProcAddress("glGetActiveUniformName"); - glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC)wglGetProcAddress("glGetUniformBlockIndex"); - glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC)wglGetProcAddress("glGetActiveUniformBlockiv"); - glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)wglGetProcAddress("glGetActiveUniformBlockName"); - glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC)wglGetProcAddress("glUniformBlockBinding"); - glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)wglGetProcAddress("glBindBufferBase"); - - if (glGetUniformIndices == NULL || - glGetActiveUniformsiv == NULL || - glGetActiveUniformName == NULL || - glGetUniformBlockIndex == NULL || - glGetActiveUniformBlockiv == NULL || - glGetActiveUniformBlockName == NULL || - glUniformBlockBinding == NULL || - glBindBufferBase == NULL) - { - ok = false; - } - - - glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)wglGetProcAddress("glGenVertexArrays"); - glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)wglGetProcAddress("glBindVertexArray"); - glDeleteVertexArray = (PFNGLDELETEVERTEXARRAYSPROC)wglGetProcAddress("glBindVertexArray"); - - if (glGenVertexArrays == NULL || - glBindVertexArray == NULL || - glDeleteVertexArray == NULL) - { - ok = false; - } - - - return ok; -#else - return true; -#endif - } - - void CheckGlError() - { - size_t error = glGetError(); - if (error != GL_NO_ERROR) - { - throw std::runtime_error("Gl error"); - } - } -} +#include "OpenGlExtensions.h" + +#include "utils/Utils.h" +#include + +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) + +//==================================================== +//===================== GLSL Shaders ================= +//==================================================== + +//Requires GL_VERSION_2_0 +PFNGLCREATEPROGRAMPROC glCreateProgram = NULL; +PFNGLDELETEPROGRAMPROC glDeleteProgram = NULL; +PFNGLLINKPROGRAMPROC glLinkProgram = NULL; +PFNGLVALIDATEPROGRAMPROC glValidateProgram = NULL; +PFNGLUSEPROGRAMPROC glUseProgram = NULL; +PFNGLGETPROGRAMIVPROC glGetProgramiv = NULL; +PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog = NULL; +PFNGLCREATESHADERPROC glCreateShader = NULL; +PFNGLDELETESHADERPROC glDeleteShader = NULL; +PFNGLSHADERSOURCEPROC glShaderSource = NULL; +PFNGLCOMPILESHADERPROC glCompileShader = NULL; +PFNGLATTACHSHADERPROC glAttachShader = NULL; +PFNGLDETACHSHADERPROC glDetachShader = NULL; +PFNGLGETSHADERIVPROC glGetShaderiv = NULL; +PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog = NULL; +PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation = NULL; +PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer = NULL; +PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray = NULL; +PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray = NULL; +PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation = NULL; +PFNGLUNIFORMMATRIX3FVPROC glUniformMatrix3fv = NULL; +PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv = NULL; +PFNGLUNIFORM1IPROC glUniform1i = NULL; +PFNGLUNIFORM1FVPROC glUniform1fv = NULL; +PFNGLUNIFORM3FVPROC glUniform2fv = NULL; +PFNGLUNIFORM3FVPROC glUniform3fv = NULL; +PFNGLUNIFORM4FVPROC glUniform4fv = NULL; +PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f = NULL; +PFNGLVERTEXATTRIB2FPROC glVertexAttrib2f = NULL; +PFNGLVERTEXATTRIB3FPROC glVertexAttrib3f = NULL; +PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f = NULL; +PFNGLVERTEXATTRIB2FVPROC glVertexAttrib2fv = NULL; +PFNGLVERTEXATTRIB3FVPROC glVertexAttrib3fv = NULL; +PFNGLVERTEXATTRIB4FVPROC glVertexAttrib4fv = NULL; +PFNGLGETACTIVEATTRIBPROC glGetActiveAttrib = NULL; +PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform = NULL; + + +//======================================= +//=========== Multitexture ============== +//======================================= + +//Requires GL version 1.3 +PFNGLACTIVETEXTUREPROC glActiveTexture = NULL; + +//======================================= +//========== Vertex buffer ============== +//======================================= + +//Requires GL_VERSION_1_5 +PFNGLGENBUFFERSPROC glGenBuffers = NULL; +PFNGLDELETEBUFFERSPROC glDeleteBuffers = NULL; +PFNGLBINDBUFFERPROC glBindBuffer = NULL; +PFNGLBUFFERDATAPROC glBufferData = NULL; +PFNGLBUFFERSUBDATAPROC glBufferSubData = NULL; +PFNGLMAPBUFFERPROC glMapBuffer = NULL; +PFNGLUNMAPBUFFERPROC glUnmapBuffer = NULL; + +//========================================= +//============ Frame buffer =============== +//========================================= + +//Requires GL_ARB_framebuffer_object +PFNGLISRENDERBUFFERPROC glIsRenderbuffer = NULL; +PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer = NULL; +PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers = NULL; +PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers = NULL; +PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage = NULL; +PFNGLGETRENDERBUFFERPARAMETERIVPROC glGetRenderbufferParameteriv = NULL; +PFNGLISFRAMEBUFFERPROC glIsFramebuffer = NULL; +PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer = NULL; +PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers = NULL; +PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers = NULL; +PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus = NULL; +PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D = NULL; +PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D = NULL; +PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D = NULL; +PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer = NULL; +PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetFramebufferAttachmentParameteriv = NULL; +PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer = NULL; +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample = NULL; +PFNGLGENERATEMIPMAPPROC glGenerateMipmap = NULL; +PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer = NULL; + + + +//=========================================== +//============ Uniform buffer =============== +//=========================================== + +//Requires GL_ARB_uniform_buffer_object +PFNGLGETUNIFORMINDICESPROC glGetUniformIndices = NULL; +PFNGLGETACTIVEUNIFORMSIVPROC glGetActiveUniformsiv = NULL; +PFNGLGETACTIVEUNIFORMNAMEPROC glGetActiveUniformName = NULL; +PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex = NULL; +PFNGLGETACTIVEUNIFORMBLOCKIVPROC glGetActiveUniformBlockiv = NULL; +PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glGetActiveUniformBlockName = NULL; +PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding = NULL; +PFNGLBINDBUFFERBASEPROC glBindBufferBase = NULL; + + +PFNGLGENVERTEXARRAYSPROC glGenVertexArrays = NULL; +PFNGLBINDVERTEXARRAYPROC glBindVertexArray = NULL; +PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArray = NULL; + +#endif + +namespace ZL { + + bool BindOpenGlFunctions() + { +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) + //char* extensionList = (char*)glGetString(GL_EXTENSIONS); + char* glVersion = (char*)glGetString(GL_VERSION); + bool ok = true; + + //Requires OpenGL 2.0 or above + if (glVersion[0] >= '2') + { + + glActiveTexture = (PFNGLACTIVETEXTUREPROC)wglGetProcAddress("glActiveTexture"); + + glGenBuffers = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glGenBuffers"); + glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)wglGetProcAddress("glDeleteBuffers"); + glBindBuffer = (PFNGLBINDBUFFERPROC)wglGetProcAddress("glBindBuffer"); + glBufferData = (PFNGLBUFFERDATAPROC)wglGetProcAddress("glBufferData"); + glBufferSubData = (PFNGLBUFFERSUBDATAPROC)wglGetProcAddress("glBufferSubData"); + glMapBuffer = (PFNGLMAPBUFFERPROC)wglGetProcAddress("glMapBuffer"); + glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)wglGetProcAddress("glUnmapBuffer"); + + glCreateProgram = (PFNGLCREATEPROGRAMPROC)wglGetProcAddress("glCreateProgram"); + glDeleteProgram = (PFNGLDELETEPROGRAMPROC)wglGetProcAddress("glDeleteProgram"); + glLinkProgram = (PFNGLLINKPROGRAMPROC)wglGetProcAddress("glLinkProgram"); + glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)wglGetProcAddress("glValidateProgram"); + glUseProgram = (PFNGLUSEPROGRAMPROC)wglGetProcAddress("glUseProgram"); + glGetProgramiv = (PFNGLGETPROGRAMIVPROC)wglGetProcAddress("glGetProgramiv"); + glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)wglGetProcAddress("glGetProgramInfoLog"); + glCreateShader = (PFNGLCREATESHADERPROC)wglGetProcAddress("glCreateShader"); + + + glDeleteShader = (PFNGLDELETESHADERPROC)wglGetProcAddress("glDeleteShader"); + glShaderSource = (PFNGLSHADERSOURCEPROC)wglGetProcAddress("glShaderSource"); + glCompileShader = (PFNGLCOMPILESHADERPROC)wglGetProcAddress("glCompileShader"); + glAttachShader = (PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader"); + glDetachShader = (PFNGLDETACHSHADERPROC)wglGetProcAddress("glDetachShader"); + glGetShaderiv = (PFNGLGETSHADERIVPROC)wglGetProcAddress("glGetShaderiv"); + glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)wglGetProcAddress("glGetShaderInfoLog"); + glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)wglGetProcAddress("glGetAttribLocation"); + glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)wglGetProcAddress("glVertexAttribPointer"); + glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)wglGetProcAddress("glEnableVertexAttribArray"); + + glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)wglGetProcAddress("glDisableVertexAttribArray"); + glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)wglGetProcAddress("glGetUniformLocation"); + glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)wglGetProcAddress("glUniformMatrix3fv"); + glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)wglGetProcAddress("glUniformMatrix4fv"); + glUniform1i = (PFNGLUNIFORM1IPROC)wglGetProcAddress("glUniform1i"); + glUniform1fv = (PFNGLUNIFORM1FVPROC)wglGetProcAddress("glUniform1fv"); + glUniform2fv = (PFNGLUNIFORM2FVPROC)wglGetProcAddress("glUniform2fv"); + glUniform3fv = (PFNGLUNIFORM3FVPROC)wglGetProcAddress("glUniform3fv"); + glUniform4fv = (PFNGLUNIFORM4FVPROC)wglGetProcAddress("glUniform4fv"); + + glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC)wglGetProcAddress("glVertexAttrib1f"); + glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC)wglGetProcAddress("glVertexAttrib2f"); + glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC)wglGetProcAddress("glVertexAttrib3f"); + glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC)wglGetProcAddress("glVertexAttrib4f"); + glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC)wglGetProcAddress("glVertexAttrib2fv"); + glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC)wglGetProcAddress("glVertexAttrib3fv"); + glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)wglGetProcAddress("glVertexAttrib4fv"); + glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC)wglGetProcAddress("glGetActiveAttrib"); + glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)wglGetProcAddress("glGetActiveUniform"); + + + if (glActiveTexture == NULL || + glGenBuffers == NULL || + glDeleteBuffers == NULL || + glBindBuffer == NULL || + glBufferData == NULL || + glBufferSubData == NULL || + glMapBuffer == NULL || + glCreateProgram == NULL || + glDeleteProgram == NULL || + glLinkProgram == NULL || + glValidateProgram == NULL || + glUseProgram == NULL || + glGetProgramiv == NULL || + glGetProgramInfoLog == NULL || + glCreateShader == NULL || + glDeleteShader == NULL || + glShaderSource == NULL || + glCompileShader == NULL || + glAttachShader == NULL || + glDetachShader == NULL || + glGetShaderiv == NULL || + glGetShaderInfoLog == NULL || + glGetAttribLocation == NULL || + glVertexAttribPointer == NULL || + glEnableVertexAttribArray == NULL || + glDisableVertexAttribArray == NULL || + glGetUniformLocation == NULL || + glUniformMatrix3fv == NULL || + glUniformMatrix4fv == NULL || + glUniform1i == NULL || + glUniform1fv == NULL || + glUniform2fv == NULL || + glUniform3fv == NULL || + glUniform4fv == NULL || + glEnableVertexAttribArray == NULL || + glVertexAttrib1f == NULL || + glVertexAttrib2f == NULL || + glVertexAttrib3f == NULL || + glVertexAttrib4f == NULL || + glVertexAttrib2fv == NULL || + glVertexAttrib3fv == NULL || + glVertexAttrib4fv == NULL || + glGetActiveAttrib == NULL || + glGetActiveUniform == NULL) + { + ok = false; + } + + + } + else + { + ok = false; + } + + + glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)wglGetProcAddress("glIsRenderbuffer"); + glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)wglGetProcAddress("glBindRenderbuffer"); + glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)wglGetProcAddress("glDeleteRenderbuffers"); + glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)wglGetProcAddress("glGenRenderbuffers"); + glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)wglGetProcAddress("glRenderbufferStorage"); + glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)wglGetProcAddress("glGetRenderbufferParameteriv"); + glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC)wglGetProcAddress("glIsFramebuffer"); + glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)wglGetProcAddress("glBindFramebuffer"); + glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)wglGetProcAddress("glDeleteFramebuffers"); + glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)wglGetProcAddress("glGenFramebuffers"); + glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)wglGetProcAddress("glCheckFramebufferStatus"); + glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC)wglGetProcAddress("glFramebufferTexture1D"); + glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)wglGetProcAddress("glFramebufferTexture2D"); + glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)wglGetProcAddress("glFramebufferTexture3D"); + glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)wglGetProcAddress("glFramebufferRenderbuffer"); + glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)wglGetProcAddress("glGetFramebufferAttachmentParameteriv"); + glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)wglGetProcAddress("glBlitFramebuffer"); + glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)wglGetProcAddress("glRenderbufferStorageMultisample"); + glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)wglGetProcAddress("glGenerateMipmap"); + glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)wglGetProcAddress("glFramebufferTextureLayer"); + + if (glIsRenderbuffer == NULL || + glBindRenderbuffer == NULL || + glDeleteRenderbuffers == NULL || + glGenRenderbuffers == NULL || + glRenderbufferStorage == NULL || + glGetRenderbufferParameteriv == NULL || + glIsFramebuffer == NULL || + glBindFramebuffer == NULL || + glDeleteFramebuffers == NULL || + glGenFramebuffers == NULL || + glCheckFramebufferStatus == NULL || + glFramebufferTexture1D == NULL || + glFramebufferTexture2D == NULL || + glFramebufferTexture3D == NULL || + glFramebufferRenderbuffer == NULL || + glGetFramebufferAttachmentParameteriv == NULL || + glBlitFramebuffer == NULL || + glRenderbufferStorageMultisample == NULL || + glGenerateMipmap == NULL || + glFramebufferTextureLayer == NULL) + { + ok = false; + } + + + glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC)wglGetProcAddress("glGetUniformIndices"); + glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC)wglGetProcAddress("glGetActiveUniformsiv"); + glGetActiveUniformName = (PFNGLGETACTIVEUNIFORMNAMEPROC)wglGetProcAddress("glGetActiveUniformName"); + glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC)wglGetProcAddress("glGetUniformBlockIndex"); + glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC)wglGetProcAddress("glGetActiveUniformBlockiv"); + glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)wglGetProcAddress("glGetActiveUniformBlockName"); + glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC)wglGetProcAddress("glUniformBlockBinding"); + glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)wglGetProcAddress("glBindBufferBase"); + + if (glGetUniformIndices == NULL || + glGetActiveUniformsiv == NULL || + glGetActiveUniformName == NULL || + glGetUniformBlockIndex == NULL || + glGetActiveUniformBlockiv == NULL || + glGetActiveUniformBlockName == NULL || + glUniformBlockBinding == NULL || + glBindBufferBase == NULL) + { + ok = false; + } + + + glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)wglGetProcAddress("glGenVertexArrays"); + glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)wglGetProcAddress("glBindVertexArray"); + glDeleteVertexArray = (PFNGLDELETEVERTEXARRAYSPROC)wglGetProcAddress("glBindVertexArray"); + + if (glGenVertexArrays == NULL || + glBindVertexArray == NULL || + glDeleteVertexArray == NULL) + { + ok = false; + } + + + return ok; +#else + return true; +#endif + } + + void CheckGlError() + { + size_t error = glGetError(); + if (error != GL_NO_ERROR) + { + throw std::runtime_error("Gl error"); + } + } +} diff --git a/OpenGlExtensions.h b/src/render/OpenGlExtensions.h old mode 100755 new mode 100644 similarity index 97% rename from OpenGlExtensions.h rename to src/render/OpenGlExtensions.h index a2347b2..35a202f --- a/OpenGlExtensions.h +++ b/src/render/OpenGlExtensions.h @@ -1,160 +1,160 @@ -#pragma once - - -#include "SDL.h" -#ifdef EMSCRIPTEN -//#define GL_GLEXT_PROTOTYPES 1 -//#define EGL_EGLEXT_PROTOTYPES 1 -//#include -#include -#include "emscripten.h" -#endif - -#ifdef __linux__ -#include -#include -#include - -#endif - -#include -#include -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) - -#include "windows.h" - -#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp)) -#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp)) - -//#define GL_GLEXT_PROTOTYPES - -#include "gl/gl.h" -#include "gl/glu.h" -#include "gl/glext.h" - - -#include -#include -#include -#include -#include -#include -#define _USE_MATH_DEFINES -#include - -//Requires GL_VERSION_2_0 -extern PFNGLCREATEPROGRAMPROC glCreateProgram; -extern PFNGLDELETEPROGRAMPROC glDeleteProgram; -extern PFNGLLINKPROGRAMPROC glLinkProgram; -extern PFNGLVALIDATEPROGRAMPROC glValidateProgram; -extern PFNGLUSEPROGRAMPROC glUseProgram; -extern PFNGLGETPROGRAMIVPROC glGetProgramiv; -extern PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; -extern PFNGLCREATESHADERPROC glCreateShader; -extern PFNGLDELETESHADERPROC glDeleteShader; -extern PFNGLSHADERSOURCEPROC glShaderSource; -extern PFNGLCOMPILESHADERPROC glCompileShader; -extern PFNGLATTACHSHADERPROC glAttachShader; -extern PFNGLDETACHSHADERPROC glDetachShader; -extern PFNGLGETSHADERIVPROC glGetShaderiv; -extern PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; -extern PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation; -extern PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; -extern PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; -extern PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; -extern PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; -extern PFNGLUNIFORMMATRIX3FVPROC glUniformMatrix3fv; -extern PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; -extern PFNGLUNIFORM1IPROC glUniform1i; -extern PFNGLUNIFORM1FVPROC glUniform1fv; -extern PFNGLUNIFORM3FVPROC glUniform2fv; -extern PFNGLUNIFORM3FVPROC glUniform3fv; -extern PFNGLUNIFORM4FVPROC glUniform4fv; -extern PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f; -extern PFNGLVERTEXATTRIB2FPROC glVertexAttrib2f; -extern PFNGLVERTEXATTRIB3FPROC glVertexAttrib3f; -extern PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f; -extern PFNGLVERTEXATTRIB2FVPROC glVertexAttrib2fv; -extern PFNGLVERTEXATTRIB3FVPROC glVertexAttrib3fv; -extern PFNGLVERTEXATTRIB4FVPROC glVertexAttrib4fv; -extern PFNGLGETACTIVEATTRIBPROC glGetActiveAttrib; -extern PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform; - - -//======================================= -//=========== Multitexture ============== -//======================================= - -//Requires GL version 1.3 -extern PFNGLACTIVETEXTUREPROC glActiveTexture; - -//======================================= -//========== Vertex buffer ============== -//======================================= - -//Requires GL_VERSION_1_5 -extern PFNGLGENBUFFERSPROC glGenBuffers; -extern PFNGLDELETEBUFFERSPROC glDeleteBuffers; -extern PFNGLBINDBUFFERPROC glBindBuffer; -extern PFNGLBUFFERDATAPROC glBufferData; -extern PFNGLBUFFERSUBDATAPROC glBufferSubData; -extern PFNGLMAPBUFFERPROC glMapBuffer; -extern PFNGLUNMAPBUFFERPROC glUnmapBuffer; - -//========================================= -//============ Frame buffer =============== -//========================================= - -//Requires GL_ARB_framebuffer_object -extern PFNGLISRENDERBUFFERPROC glIsRenderbuffer; -extern PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer; -extern PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers; -extern PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers; -extern PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage; -extern PFNGLGETRENDERBUFFERPARAMETERIVPROC glGetRenderbufferParameteriv; -extern PFNGLISFRAMEBUFFERPROC glIsFramebuffer; -extern PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; -extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers; -extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; -extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus; -extern PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D; -extern PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D; -extern PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D; -extern PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer; -extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetFramebufferAttachmentParameteriv; -extern PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer; -extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample; -extern PFNGLGENERATEMIPMAPPROC glGenerateMipmap; -extern PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer; - - - -//=========================================== -//============ Uniform buffer =============== -//=========================================== - -//Requires GL_ARB_uniform_buffer_object -extern PFNGLGETUNIFORMINDICESPROC glGetUniformIndices; -extern PFNGLGETACTIVEUNIFORMSIVPROC glGetActiveUniformsiv; -extern PFNGLGETACTIVEUNIFORMNAMEPROC glGetActiveUniformName; -extern PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex; -extern PFNGLGETACTIVEUNIFORMBLOCKIVPROC glGetActiveUniformBlockiv; -extern PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glGetActiveUniformBlockName; -extern PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding; -extern PFNGLBINDBUFFERBASEPROC glBindBufferBase; - - -extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays; -extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray; -extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArray; -#else - -#endif -namespace ZL { - - - - bool BindOpenGlFunctions(); - - void CheckGlError(); +#pragma once + + +#include "SDL.h" +#ifdef EMSCRIPTEN +//#define GL_GLEXT_PROTOTYPES 1 +//#define EGL_EGLEXT_PROTOTYPES 1 +//#include +#include +#include "emscripten.h" +#endif + +#ifdef __linux__ +#include +#include +#include + +#endif + +#include +#include +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) + +#include "windows.h" + +#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp)) +#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp)) + +//#define GL_GLEXT_PROTOTYPES + +#include "gl/gl.h" +#include "gl/glu.h" +#include "gl/glext.h" + + +#include +#include +#include +#include +#include +#include +#define _USE_MATH_DEFINES +#include + +//Requires GL_VERSION_2_0 +extern PFNGLCREATEPROGRAMPROC glCreateProgram; +extern PFNGLDELETEPROGRAMPROC glDeleteProgram; +extern PFNGLLINKPROGRAMPROC glLinkProgram; +extern PFNGLVALIDATEPROGRAMPROC glValidateProgram; +extern PFNGLUSEPROGRAMPROC glUseProgram; +extern PFNGLGETPROGRAMIVPROC glGetProgramiv; +extern PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; +extern PFNGLCREATESHADERPROC glCreateShader; +extern PFNGLDELETESHADERPROC glDeleteShader; +extern PFNGLSHADERSOURCEPROC glShaderSource; +extern PFNGLCOMPILESHADERPROC glCompileShader; +extern PFNGLATTACHSHADERPROC glAttachShader; +extern PFNGLDETACHSHADERPROC glDetachShader; +extern PFNGLGETSHADERIVPROC glGetShaderiv; +extern PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; +extern PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation; +extern PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; +extern PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; +extern PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; +extern PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; +extern PFNGLUNIFORMMATRIX3FVPROC glUniformMatrix3fv; +extern PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; +extern PFNGLUNIFORM1IPROC glUniform1i; +extern PFNGLUNIFORM1FVPROC glUniform1fv; +extern PFNGLUNIFORM3FVPROC glUniform2fv; +extern PFNGLUNIFORM3FVPROC glUniform3fv; +extern PFNGLUNIFORM4FVPROC glUniform4fv; +extern PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f; +extern PFNGLVERTEXATTRIB2FPROC glVertexAttrib2f; +extern PFNGLVERTEXATTRIB3FPROC glVertexAttrib3f; +extern PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f; +extern PFNGLVERTEXATTRIB2FVPROC glVertexAttrib2fv; +extern PFNGLVERTEXATTRIB3FVPROC glVertexAttrib3fv; +extern PFNGLVERTEXATTRIB4FVPROC glVertexAttrib4fv; +extern PFNGLGETACTIVEATTRIBPROC glGetActiveAttrib; +extern PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform; + + +//======================================= +//=========== Multitexture ============== +//======================================= + +//Requires GL version 1.3 +extern PFNGLACTIVETEXTUREPROC glActiveTexture; + +//======================================= +//========== Vertex buffer ============== +//======================================= + +//Requires GL_VERSION_1_5 +extern PFNGLGENBUFFERSPROC glGenBuffers; +extern PFNGLDELETEBUFFERSPROC glDeleteBuffers; +extern PFNGLBINDBUFFERPROC glBindBuffer; +extern PFNGLBUFFERDATAPROC glBufferData; +extern PFNGLBUFFERSUBDATAPROC glBufferSubData; +extern PFNGLMAPBUFFERPROC glMapBuffer; +extern PFNGLUNMAPBUFFERPROC glUnmapBuffer; + +//========================================= +//============ Frame buffer =============== +//========================================= + +//Requires GL_ARB_framebuffer_object +extern PFNGLISRENDERBUFFERPROC glIsRenderbuffer; +extern PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer; +extern PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers; +extern PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers; +extern PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage; +extern PFNGLGETRENDERBUFFERPARAMETERIVPROC glGetRenderbufferParameteriv; +extern PFNGLISFRAMEBUFFERPROC glIsFramebuffer; +extern PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; +extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers; +extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; +extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus; +extern PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D; +extern PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D; +extern PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D; +extern PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer; +extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetFramebufferAttachmentParameteriv; +extern PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer; +extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample; +extern PFNGLGENERATEMIPMAPPROC glGenerateMipmap; +extern PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer; + + + +//=========================================== +//============ Uniform buffer =============== +//=========================================== + +//Requires GL_ARB_uniform_buffer_object +extern PFNGLGETUNIFORMINDICESPROC glGetUniformIndices; +extern PFNGLGETACTIVEUNIFORMSIVPROC glGetActiveUniformsiv; +extern PFNGLGETACTIVEUNIFORMNAMEPROC glGetActiveUniformName; +extern PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex; +extern PFNGLGETACTIVEUNIFORMBLOCKIVPROC glGetActiveUniformBlockiv; +extern PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glGetActiveUniformBlockName; +extern PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding; +extern PFNGLBINDBUFFERBASEPROC glBindBufferBase; + + +extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays; +extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray; +extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArray; +#else + +#endif +namespace ZL { + + + + bool BindOpenGlFunctions(); + + void CheckGlError(); } \ No newline at end of file diff --git a/Renderer.cpp b/src/render/Renderer.cpp old mode 100755 new mode 100644 similarity index 96% rename from Renderer.cpp rename to src/render/Renderer.cpp index 1bfc118..c50c830 --- a/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -1,833 +1,833 @@ -#include "Renderer.h" -#include - -namespace ZL { - - VBOHolder::VBOHolder() - { - glGenBuffers(1, &Buffer); - } - - VBOHolder::~VBOHolder() - { - glDeleteBuffers(1, &Buffer); - } - - GLuint VBOHolder::getBuffer() - { - return Buffer; - } - - VAOHolder::VAOHolder() - { -#ifndef EMSCRIPTEN - glGenVertexArrays(1, &vao); -#endif - } - - VAOHolder::~VAOHolder() - { -#ifndef EMSCRIPTEN - -#ifdef __linux__ - glDeleteVertexArrays(1, &vao); -#else - //Windows - glDeleteVertexArray(1, &vao); -#endif -#endif - } - - GLuint VAOHolder::getBuffer() - { - return vao; - } - - - VertexDataStruct CreateRect2D(Vector2f center, Vector2f halfWidthHeight, float zLevel) - { - Vector2f posFrom = center - halfWidthHeight; - - Vector2f posTo = center + halfWidthHeight; - - Vector3f pos1 = { posFrom.v[0], posFrom.v[1], zLevel }; - Vector3f pos2 = { posFrom.v[0], posTo.v[1], zLevel }; - Vector3f pos3 = { posTo.v[0], posTo.v[1], zLevel }; - Vector3f pos4 = { posTo.v[0], posFrom.v[1], zLevel }; - - - Vector2f texCoordPos1 = { 0.0f, 0.0f }; - Vector2f texCoordPos2 = { 0.0f, 1.0f }; - Vector2f texCoordPos3 = { 1.0f, 1.0f }; - Vector2f texCoordPos4 = { 1.0f, 0.0f }; - - VertexDataStruct result; - - result.PositionData.push_back(pos1); - result.PositionData.push_back(pos2); - result.PositionData.push_back(pos3); - result.PositionData.push_back(pos3); - result.PositionData.push_back(pos4); - result.PositionData.push_back(pos1); - - result.TexCoordData.push_back(texCoordPos1); - result.TexCoordData.push_back(texCoordPos2); - result.TexCoordData.push_back(texCoordPos3); - result.TexCoordData.push_back(texCoordPos3); - result.TexCoordData.push_back(texCoordPos4); - result.TexCoordData.push_back(texCoordPos1); - - return result; - } - - VertexDataStruct CreateRectHorizontalSections2D(Vector2f center, Vector2f halfWidthHeight, float zLevel, size_t sectionCount) - { - Vector2f posFrom = center - halfWidthHeight; - - Vector2f posTo = center + halfWidthHeight; - - float sectionWidth = halfWidthHeight.v[0] * 2.f; - - VertexDataStruct result; - - for (size_t i = 0; i < sectionCount; i++) - { - Vector3f pos1 = { posFrom.v[0]+sectionWidth*i, posFrom.v[1], zLevel }; - Vector3f pos2 = { posFrom.v[0] + sectionWidth * i, posTo.v[1], zLevel }; - Vector3f pos3 = { posTo.v[0] + sectionWidth * i, posTo.v[1], zLevel }; - Vector3f pos4 = { posTo.v[0] + sectionWidth * i, posFrom.v[1], zLevel }; - - result.PositionData.push_back(pos1); - result.PositionData.push_back(pos2); - result.PositionData.push_back(pos3); - result.PositionData.push_back(pos3); - result.PositionData.push_back(pos4); - result.PositionData.push_back(pos1); - - Vector2f texCoordPos1 = { 0.0f, 0.0f }; - Vector2f texCoordPos2 = { 0.0f, 1.0f }; - Vector2f texCoordPos3 = { 1.0f, 1.0f }; - Vector2f texCoordPos4 = { 1.0f, 0.0f }; - - result.TexCoordData.push_back(texCoordPos1); - result.TexCoordData.push_back(texCoordPos2); - result.TexCoordData.push_back(texCoordPos3); - result.TexCoordData.push_back(texCoordPos3); - result.TexCoordData.push_back(texCoordPos4); - result.TexCoordData.push_back(texCoordPos1); - } - - - return result; - - } - - VertexDataStruct CreateCube3D(float scale) - { - - std::array, 6> cubeSides; - - std::array cubeColors; - - - cubeSides[0][0] = { -1, -1, -1 }; - cubeSides[0][1] = { -1, 1, -1 }; - cubeSides[0][2] = { 1, 1, -1 }; - cubeSides[0][3] = { 1, -1, -1 }; - - cubeSides[1][0] = { -1, -1, 1 }; - cubeSides[1][1] = { -1, 1, 1 }; - cubeSides[1][2] = { 1, 1, 1 }; - cubeSides[1][3] = { 1, -1, 1 }; - - //------------ - - cubeSides[2][0] = { -1, -1, -1 }; - cubeSides[2][1] = { -1, -1, 1 }; - cubeSides[2][2] = { 1, -1, 1 }; - cubeSides[2][3] = { 1, -1, -1 }; - - cubeSides[3][0] = { -1, 1, -1 }; - cubeSides[3][1] = { -1, 1, 1 }; - cubeSides[3][2] = { 1, 1, 1 }; - cubeSides[3][3] = { 1, 1, -1 }; - - //------------ - cubeSides[4][0] = { -1, -1, -1 }; - cubeSides[4][1] = { -1, -1, 1 }; - cubeSides[4][2] = { -1, 1, 1 }; - cubeSides[4][3] = { -1, 1, -1 }; - - cubeSides[5][0] = { 1, -1, -1 }; - cubeSides[5][1] = { 1, -1, 1 }; - cubeSides[5][2] = { 1, 1, 1 }; - cubeSides[5][3] = { 1, 1, -1 }; - - //----------- - - cubeColors[0] = Vector3f{ 1, 0, 0 }; - cubeColors[1] = Vector3f{ 0, 1, 0 }; - cubeColors[2] = Vector3f{ 0, 0, 1 }; - cubeColors[3] = Vector3f{ 1, 1, 0 }; - cubeColors[4] = Vector3f{ 0, 1, 1 }; - cubeColors[5] = Vector3f{ 1, 0, 1 }; - - //----------- - - VertexDataStruct result; - - for (int i = 0; i < 6; i++) - { - result.PositionData.push_back(cubeSides[i][0] * scale); - result.PositionData.push_back(cubeSides[i][1] * scale); - result.PositionData.push_back(cubeSides[i][2] * scale); - result.PositionData.push_back(cubeSides[i][2] * scale); - result.PositionData.push_back(cubeSides[i][3] * scale); - result.PositionData.push_back(cubeSides[i][0] * scale); - - result.ColorData.push_back(cubeColors[i]); - result.ColorData.push_back(cubeColors[i]); - result.ColorData.push_back(cubeColors[i]); - result.ColorData.push_back(cubeColors[i]); - result.ColorData.push_back(cubeColors[i]); - result.ColorData.push_back(cubeColors[i]); - } - - return result; - } - - VertexDataStruct CreateCubemap(float scale) - { - VertexDataStruct cubemapVertexDataStruct; - - // +x - cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, -scale }); - cubemapVertexDataStruct.PositionData.push_back({ scale, scale, -scale }); - cubemapVertexDataStruct.PositionData.push_back({ scale, scale, scale }); - - cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, -scale }); - cubemapVertexDataStruct.PositionData.push_back({ scale, scale, scale }); - cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, scale }); - - // -x - cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, -scale }); - cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, -scale }); - cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, scale }); - - cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, -scale }); - cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, scale }); - cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, scale }); - - - // +y - cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, -scale }); - cubemapVertexDataStruct.PositionData.push_back({ scale, scale, -scale }); - cubemapVertexDataStruct.PositionData.push_back({ scale, scale, scale }); - - cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, -scale }); - cubemapVertexDataStruct.PositionData.push_back({ scale, scale, scale }); - cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, scale }); - - - // -y - cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, -scale }); - cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, -scale }); - cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, scale }); - - cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, -scale }); - cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, scale }); - cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, scale }); - - - // +z - cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, scale }); - cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, scale }); - cubemapVertexDataStruct.PositionData.push_back({ scale, scale, scale }); - - cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, scale }); - cubemapVertexDataStruct.PositionData.push_back({ scale, scale, scale }); - cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, scale }); - - // -z - cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, -scale }); - cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, -scale }); - cubemapVertexDataStruct.PositionData.push_back({ scale, scale, -scale }); - - cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, -scale }); - cubemapVertexDataStruct.PositionData.push_back({ scale, scale, -scale }); - cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, -scale }); - - return cubemapVertexDataStruct; - - } - - void VertexRenderStruct::RefreshVBO() - { - //Check if main thread, check if data is not empty... - -#ifndef EMSCRIPTEN - if (!vao) - { - vao = std::make_shared(); - } - - glBindVertexArray(vao->getBuffer()); -#endif - if (!positionVBO) - { - positionVBO = std::make_shared(); - } - - glBindBuffer(GL_ARRAY_BUFFER, positionVBO->getBuffer()); - - glBufferData(GL_ARRAY_BUFFER, data.PositionData.size() * 12, &data.PositionData[0], GL_STATIC_DRAW); - - if (data.TexCoordData.size() > 0) - { - if (!texCoordVBO) - { - texCoordVBO = std::make_shared(); - } - - glBindBuffer(GL_ARRAY_BUFFER, texCoordVBO->getBuffer()); - - glBufferData(GL_ARRAY_BUFFER, data.TexCoordData.size() * 8, &data.TexCoordData[0], GL_STATIC_DRAW); - } - - if (data.NormalData.size() > 0) - { - if (!normalVBO) - { - normalVBO = std::make_shared(); - } - - glBindBuffer(GL_ARRAY_BUFFER, normalVBO->getBuffer()); - - glBufferData(GL_ARRAY_BUFFER, data.NormalData.size() * 12, &data.NormalData[0], GL_STATIC_DRAW); - } - - if (data.TangentData.size() > 0) - { - if (!tangentVBO) - { - tangentVBO = std::make_shared(); - } - - glBindBuffer(GL_ARRAY_BUFFER, tangentVBO->getBuffer()); - - glBufferData(GL_ARRAY_BUFFER, data.TangentData.size() * 12, &data.TangentData[0], GL_STATIC_DRAW); - } - - if (data.BinormalData.size() > 0) - { - if (!binormalVBO) - { - binormalVBO = std::make_shared(); - } - - glBindBuffer(GL_ARRAY_BUFFER, binormalVBO->getBuffer()); - - glBufferData(GL_ARRAY_BUFFER, data.BinormalData.size() * 12, &data.BinormalData[0], GL_STATIC_DRAW); - } - - if (data.ColorData.size() > 0) - { - if (!colorVBO) - { - colorVBO = std::make_shared(); - } - - glBindBuffer(GL_ARRAY_BUFFER, colorVBO->getBuffer()); - - glBufferData(GL_ARRAY_BUFFER, data.ColorData.size() * 12, &data.ColorData[0], GL_STATIC_DRAW); - } - } - - void VertexDataStruct::Scale(float scale) - { - for (int i = 0; i < PositionData.size(); i++) - { - PositionData[i] = PositionData[i] * scale; - } - } - void VertexDataStruct::Move(Vector3f diff) - { - for (int i = 0; i < PositionData.size(); i++) - { - PositionData[i] = PositionData[i] + diff; - } - } - - void VertexDataStruct::SwapZandY() - { - for (int i = 0; i < PositionData.size(); i++) - { - auto value = PositionData[i].v[1]; - PositionData[i].v[1] = PositionData[i].v[2]; - PositionData[i].v[2] = value; - } - } - - - void VertexDataStruct::RotateByMatrix(Matrix3f m) - { - - for (int i = 0; i < PositionData.size(); i++) - { - PositionData[i] = MultVectorMatrix(PositionData[i], m); - } - - for (int i = 0; i < NormalData.size(); i++) - { - NormalData[i] = MultVectorMatrix(NormalData[i], m); - } - - for (int i = 0; i < TangentData.size(); i++) - { - TangentData[i] = MultVectorMatrix(TangentData[i], m); - } - - for (int i = 0; i < BinormalData.size(); i++) - { - BinormalData[i] = MultVectorMatrix(BinormalData[i], m); - } - } - - void VertexRenderStruct::AssignFrom(const VertexDataStruct& v) - { - data = v; - RefreshVBO(); - } - - void Renderer::InitOpenGL() - { - ModelviewMatrixStack.push(Matrix4f::Identity()); - ProjectionMatrixStack.push(Matrix4f::Identity()); - - glEnable(GL_DEPTH_TEST); - glEnable(GL_BLEND); - - glActiveTexture(GL_TEXTURE0); - -#ifndef EMSCRIPTEN - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); -#endif - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDepthFunc(GL_LEQUAL); - - CheckGlError(); - } - - void Renderer::PushProjectionMatrix(float width, float height, float zNear, float zFar) - { - Matrix4f m = MakeOrthoMatrix(width, height, zNear, zFar); - ProjectionMatrixStack.push(m); - SetMatrix(); - - if (ProjectionMatrixStack.size() > CONST_MATRIX_STACK_SIZE) - { - throw std::runtime_error("Projection matrix stack overflow!!!!"); - } - } - - void Renderer::PushProjectionMatrix(float xmin, float xmax, float ymin, float ymax, float zNear, float zFar) - { - Matrix4f m = MakeOrthoMatrix(xmin, xmax, ymin, ymax, zNear, zFar); - ProjectionMatrixStack.push(m); - SetMatrix(); - - if (ProjectionMatrixStack.size() > CONST_MATRIX_STACK_SIZE) - { - throw std::runtime_error("Projection matrix stack overflow!!!!"); - } - } - - void Renderer::PushPerspectiveProjectionMatrix(float fovY, float aspectRatio, float zNear, float zFar) - { - Matrix4f m = MakePerspectiveMatrix(fovY, aspectRatio, zNear, zFar); - ProjectionMatrixStack.push(m); - SetMatrix(); - - if (ProjectionMatrixStack.size() > CONST_MATRIX_STACK_SIZE) - { - throw std::runtime_error("Projection matrix stack overflow!!!!"); - } - } - - - void Renderer::PopProjectionMatrix() - { - if (ProjectionMatrixStack.size() == 0) - { - throw std::runtime_error("Projection matrix stack underflow!!!!"); - } - ProjectionMatrixStack.pop(); - SetMatrix(); - } - - Matrix4f Renderer::GetProjectionModelViewMatrix() - { - return ProjectionModelViewMatrix; - } - - Matrix4f Renderer::GetCurrentModelViewMatrix() - { - return ModelviewMatrixStack.top(); - } - - - void Renderer::SetMatrix() - { - if (ProjectionMatrixStack.size() <= 0) - { - throw std::runtime_error("Projection matrix stack out!"); - } - - if (ModelviewMatrixStack.size() <= 0) - { - throw std::runtime_error("Modelview matrix stack out!"); - } - - Matrix4f& modelViewMatrix = ModelviewMatrixStack.top(); - ProjectionModelViewMatrix = ProjectionMatrixStack.top() * modelViewMatrix; - - static const std::string ProjectionModelViewMatrixName = "ProjectionModelViewMatrix"; - - RenderUniformMatrix4fv(ProjectionModelViewMatrixName, false, &ProjectionModelViewMatrix.m[0]); - - static const std::string ModelViewMatrixName = "ModelViewMatrix"; - - RenderUniformMatrix4fv(ModelViewMatrixName, false, &modelViewMatrix.m[0]); - - } - - void Renderer::PushMatrix() - { - if (ModelviewMatrixStack.size() == 0) - { - throw std::runtime_error("Modelview matrix stack underflow!!!!"); - } - - ModelviewMatrixStack.push(ModelviewMatrixStack.top()); - - if (ModelviewMatrixStack.size() > CONST_MATRIX_STACK_SIZE) - { - throw std::runtime_error("Modelview matrix stack overflow!!!!"); - } - } - - void Renderer::LoadIdentity() - { - if (ModelviewMatrixStack.size() == 0) - { - throw std::runtime_error("Modelview matrix stack underflow!!!!"); - } - - ModelviewMatrixStack.pop(); - ModelviewMatrixStack.push(Matrix4f::Identity()); - - SetMatrix(); - } - - void Renderer::TranslateMatrix(const Vector3f& p) - { - - Matrix4f m = Matrix4f::Identity(); - m.m[12] = p.v[0]; - m.m[13] = p.v[1]; - m.m[14] = p.v[2]; - - m = ModelviewMatrixStack.top() * m; - - if (ModelviewMatrixStack.size() == 0) - { - throw std::runtime_error("Modelview matrix stack underflow!!!!"); - } - - ModelviewMatrixStack.pop(); - ModelviewMatrixStack.push(m); - - SetMatrix(); - } - - void Renderer::ScaleMatrix(float scale) - { - Matrix4f m = Matrix4f::Identity(); - m.m[0] = scale; - m.m[5] = scale; - m.m[10] = scale; - - m = ModelviewMatrixStack.top() * m; - - if (ModelviewMatrixStack.size() == 0) - { - throw std::runtime_error("Modelview matrix stack underflow!!!!"); - } - - ModelviewMatrixStack.pop(); - ModelviewMatrixStack.push(m); - - SetMatrix(); - } - - void Renderer::ScaleMatrix(const Vector3f& scale) - { - Matrix4f m = Matrix4f::Identity(); - m.m[0] = scale.v[0]; - m.m[5] = scale.v[1]; - m.m[10] = scale.v[2]; - - m = ModelviewMatrixStack.top() * m; - - if (ModelviewMatrixStack.size() == 0) - { - throw std::runtime_error("Modelview matrix stack underflow!!!!"); - } - - ModelviewMatrixStack.pop(); - ModelviewMatrixStack.push(m); - - SetMatrix(); - } - - void Renderer::RotateMatrix(const Vector4f& q) - { - - Matrix3f m3 = QuatToMatrix(q); - Matrix4f m = Matrix4f::Identity(); - m.m[0] = m3.m[0]; - m.m[1] = m3.m[1]; - m.m[2] = m3.m[2]; - - m.m[4] = m3.m[3]; - m.m[5] = m3.m[4]; - m.m[6] = m3.m[5]; - - m.m[8] = m3.m[6]; - m.m[9] = m3.m[7]; - m.m[10] = m3.m[8]; - - m = ModelviewMatrixStack.top() * m; - - if (ModelviewMatrixStack.size() == 0) - { - throw std::runtime_error("Modelview matrix stack underflow!!!!"); - } - - ModelviewMatrixStack.pop(); - ModelviewMatrixStack.push(m); - - - SetMatrix(); - } - - void Renderer::RotateMatrix(const Matrix3f& m3) - { - Matrix4f m = Matrix4f::Identity(); - m.m[0] = m3.m[0]; - m.m[1] = m3.m[1]; - m.m[2] = m3.m[2]; - - m.m[4] = m3.m[3]; - m.m[5] = m3.m[4]; - m.m[6] = m3.m[5]; - - m.m[8] = m3.m[6]; - m.m[9] = m3.m[7]; - m.m[10] = m3.m[8]; - - m = ModelviewMatrixStack.top() * m; - - if (ModelviewMatrixStack.size() == 0) - { - throw std::runtime_error("Modelview matrix stack underflow!!!!"); - } - - ModelviewMatrixStack.pop(); - ModelviewMatrixStack.push(m); - - - SetMatrix(); - } - - void Renderer::PushSpecialMatrix(const Matrix4f& m) - { - if (ModelviewMatrixStack.size() > 64) - { - throw std::runtime_error("Modelview matrix stack overflow!!!!"); - } - ModelviewMatrixStack.push(m); - SetMatrix(); - } - - - void Renderer::PopMatrix() - { - if (ModelviewMatrixStack.size() == 0) - { - throw std::runtime_error("Modelview matrix stack underflow!!!!"); - } - ModelviewMatrixStack.pop(); - - SetMatrix(); - } - - - void Renderer::EnableVertexAttribArray(const std::string& attribName) - { - - auto shader = shaderManager.GetCurrentShader(); - if (shader->attribList.find(attribName) != shader->attribList.end()) - glEnableVertexAttribArray(shader->attribList[attribName]); - } - - void Renderer::DisableVertexAttribArray(const std::string& attribName) - { - auto shader = shaderManager.GetCurrentShader(); - if (shader->attribList.find(attribName) != shader->attribList.end()) - glDisableVertexAttribArray(shader->attribList[attribName]); - } - - void Renderer::RenderUniformMatrix3fv(const std::string& uniformName, bool transpose, const float* value) - { - auto shader = shaderManager.GetCurrentShader(); - - auto uniform = shader->uniformList.find(uniformName); - - if (uniform != shader->uniformList.end()) - { - glUniformMatrix3fv(uniform->second, 1, transpose, value); - } - } - - - void Renderer::RenderUniformMatrix4fv(const std::string& uniformName, bool transpose, const float* value) - { - auto shader = shaderManager.GetCurrentShader(); - - auto uniform = shader->uniformList.find(uniformName); - - if (uniform != shader->uniformList.end()) - { - glUniformMatrix4fv(uniform->second, 1, transpose, value); - } - } - - void Renderer::RenderUniform3fv(const std::string& uniformName, const float* value) - { - auto shader = shaderManager.GetCurrentShader(); - - auto uniform = shader->uniformList.find(uniformName); - - if (uniform != shader->uniformList.end()) - { - glUniform3fv(uniform->second, 1, value); - } - } - - void Renderer::RenderUniform1i(const std::string& uniformName, const int value) - { - auto shader = shaderManager.GetCurrentShader(); - - auto uniform = shader->uniformList.find(uniformName); - - if (uniform != shader->uniformList.end()) - { - glUniform1i(uniform->second, value); - } - - } - - void Renderer::RenderUniform1f(const std::string& uniformName, float value) - { - auto shader = shaderManager.GetCurrentShader(); - - auto uniform = shader->uniformList.find(uniformName); - - if (uniform != shader->uniformList.end()) - { - glUniform1fv(uniform->second, 1, &value); - } - - } - - - void Renderer::VertexAttribPointer2fv(const std::string& attribName, int stride, const char* pointer) - { - auto shader = shaderManager.GetCurrentShader(); - if (shader->attribList.find(attribName) != shader->attribList.end()) - glVertexAttribPointer(shader->attribList[attribName], 2, GL_FLOAT, GL_FALSE, stride, pointer); - - } - - void Renderer::VertexAttribPointer3fv(const std::string& attribName, int stride, const char* pointer) - { - - auto shader = shaderManager.GetCurrentShader(); - if (shader->attribList.find(attribName) != shader->attribList.end()) - glVertexAttribPointer(shader->attribList[attribName], 3, GL_FLOAT, GL_FALSE, stride, pointer); - } - - void Renderer::DrawVertexRenderStruct(const VertexRenderStruct& VertexRenderStruct) - { - static const std::string vNormal("vNormal"); - static const std::string vTangent("vTangent"); - static const std::string vBinormal("vBinormal"); - static const std::string vColor("vColor"); - static const std::string vTexCoord("vTexCoord"); - static const std::string vPosition("vPosition"); - - //glBindVertexArray(VertexRenderStruct.vao->getBuffer()); - - //Check if main thread, check if data is not empty... - if (VertexRenderStruct.data.NormalData.size() > 0) - { - glBindBuffer(GL_ARRAY_BUFFER, VertexRenderStruct.normalVBO->getBuffer()); - VertexAttribPointer3fv(vNormal, 0, NULL); - } - if (VertexRenderStruct.data.TangentData.size() > 0) - { - glBindBuffer(GL_ARRAY_BUFFER, VertexRenderStruct.tangentVBO->getBuffer()); - VertexAttribPointer3fv(vTangent, 0, NULL); - } - if (VertexRenderStruct.data.BinormalData.size() > 0) - { - glBindBuffer(GL_ARRAY_BUFFER, VertexRenderStruct.binormalVBO->getBuffer()); - VertexAttribPointer3fv(vBinormal, 0, NULL); - } - if (VertexRenderStruct.data.ColorData.size() > 0) - { - glBindBuffer(GL_ARRAY_BUFFER, VertexRenderStruct.colorVBO->getBuffer()); - VertexAttribPointer3fv(vColor, 0, NULL); - } - if (VertexRenderStruct.data.TexCoordData.size() > 0) - { - glBindBuffer(GL_ARRAY_BUFFER, VertexRenderStruct.texCoordVBO->getBuffer()); - VertexAttribPointer2fv(vTexCoord, 0, NULL); - } - - glBindBuffer(GL_ARRAY_BUFFER, VertexRenderStruct.positionVBO->getBuffer()); - VertexAttribPointer3fv(vPosition, 0, NULL); - - glDrawArrays(GL_TRIANGLES, 0, static_cast(VertexRenderStruct.data.PositionData.size())); - - } - - void 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); - } - - -} - +#include "render/Renderer.h" +#include + +namespace ZL { + + VBOHolder::VBOHolder() + { + glGenBuffers(1, &Buffer); + } + + VBOHolder::~VBOHolder() + { + glDeleteBuffers(1, &Buffer); + } + + GLuint VBOHolder::getBuffer() + { + return Buffer; + } + + VAOHolder::VAOHolder() + { +#ifndef EMSCRIPTEN + glGenVertexArrays(1, &vao); +#endif + } + + VAOHolder::~VAOHolder() + { +#ifndef EMSCRIPTEN + +#ifdef __linux__ + glDeleteVertexArrays(1, &vao); +#else + //Windows + glDeleteVertexArray(1, &vao); +#endif +#endif + } + + GLuint VAOHolder::getBuffer() + { + return vao; + } + + + VertexDataStruct CreateRect2D(Vector2f center, Vector2f halfWidthHeight, float zLevel) + { + Vector2f posFrom = center - halfWidthHeight; + + Vector2f posTo = center + halfWidthHeight; + + Vector3f pos1 = { posFrom.v[0], posFrom.v[1], zLevel }; + Vector3f pos2 = { posFrom.v[0], posTo.v[1], zLevel }; + Vector3f pos3 = { posTo.v[0], posTo.v[1], zLevel }; + Vector3f pos4 = { posTo.v[0], posFrom.v[1], zLevel }; + + + Vector2f texCoordPos1 = { 0.0f, 0.0f }; + Vector2f texCoordPos2 = { 0.0f, 1.0f }; + Vector2f texCoordPos3 = { 1.0f, 1.0f }; + Vector2f texCoordPos4 = { 1.0f, 0.0f }; + + VertexDataStruct result; + + result.PositionData.push_back(pos1); + result.PositionData.push_back(pos2); + result.PositionData.push_back(pos3); + result.PositionData.push_back(pos3); + result.PositionData.push_back(pos4); + result.PositionData.push_back(pos1); + + result.TexCoordData.push_back(texCoordPos1); + result.TexCoordData.push_back(texCoordPos2); + result.TexCoordData.push_back(texCoordPos3); + result.TexCoordData.push_back(texCoordPos3); + result.TexCoordData.push_back(texCoordPos4); + result.TexCoordData.push_back(texCoordPos1); + + return result; + } + + VertexDataStruct CreateRectHorizontalSections2D(Vector2f center, Vector2f halfWidthHeight, float zLevel, size_t sectionCount) + { + Vector2f posFrom = center - halfWidthHeight; + + Vector2f posTo = center + halfWidthHeight; + + float sectionWidth = halfWidthHeight.v[0] * 2.f; + + VertexDataStruct result; + + for (size_t i = 0; i < sectionCount; i++) + { + Vector3f pos1 = { posFrom.v[0]+sectionWidth*i, posFrom.v[1], zLevel }; + Vector3f pos2 = { posFrom.v[0] + sectionWidth * i, posTo.v[1], zLevel }; + Vector3f pos3 = { posTo.v[0] + sectionWidth * i, posTo.v[1], zLevel }; + Vector3f pos4 = { posTo.v[0] + sectionWidth * i, posFrom.v[1], zLevel }; + + result.PositionData.push_back(pos1); + result.PositionData.push_back(pos2); + result.PositionData.push_back(pos3); + result.PositionData.push_back(pos3); + result.PositionData.push_back(pos4); + result.PositionData.push_back(pos1); + + Vector2f texCoordPos1 = { 0.0f, 0.0f }; + Vector2f texCoordPos2 = { 0.0f, 1.0f }; + Vector2f texCoordPos3 = { 1.0f, 1.0f }; + Vector2f texCoordPos4 = { 1.0f, 0.0f }; + + result.TexCoordData.push_back(texCoordPos1); + result.TexCoordData.push_back(texCoordPos2); + result.TexCoordData.push_back(texCoordPos3); + result.TexCoordData.push_back(texCoordPos3); + result.TexCoordData.push_back(texCoordPos4); + result.TexCoordData.push_back(texCoordPos1); + } + + + return result; + + } + + VertexDataStruct CreateCube3D(float scale) + { + + std::array, 6> cubeSides; + + std::array cubeColors; + + + cubeSides[0][0] = { -1, -1, -1 }; + cubeSides[0][1] = { -1, 1, -1 }; + cubeSides[0][2] = { 1, 1, -1 }; + cubeSides[0][3] = { 1, -1, -1 }; + + cubeSides[1][0] = { -1, -1, 1 }; + cubeSides[1][1] = { -1, 1, 1 }; + cubeSides[1][2] = { 1, 1, 1 }; + cubeSides[1][3] = { 1, -1, 1 }; + + //------------ + + cubeSides[2][0] = { -1, -1, -1 }; + cubeSides[2][1] = { -1, -1, 1 }; + cubeSides[2][2] = { 1, -1, 1 }; + cubeSides[2][3] = { 1, -1, -1 }; + + cubeSides[3][0] = { -1, 1, -1 }; + cubeSides[3][1] = { -1, 1, 1 }; + cubeSides[3][2] = { 1, 1, 1 }; + cubeSides[3][3] = { 1, 1, -1 }; + + //------------ + cubeSides[4][0] = { -1, -1, -1 }; + cubeSides[4][1] = { -1, -1, 1 }; + cubeSides[4][2] = { -1, 1, 1 }; + cubeSides[4][3] = { -1, 1, -1 }; + + cubeSides[5][0] = { 1, -1, -1 }; + cubeSides[5][1] = { 1, -1, 1 }; + cubeSides[5][2] = { 1, 1, 1 }; + cubeSides[5][3] = { 1, 1, -1 }; + + //----------- + + cubeColors[0] = Vector3f{ 1, 0, 0 }; + cubeColors[1] = Vector3f{ 0, 1, 0 }; + cubeColors[2] = Vector3f{ 0, 0, 1 }; + cubeColors[3] = Vector3f{ 1, 1, 0 }; + cubeColors[4] = Vector3f{ 0, 1, 1 }; + cubeColors[5] = Vector3f{ 1, 0, 1 }; + + //----------- + + VertexDataStruct result; + + for (int i = 0; i < 6; i++) + { + result.PositionData.push_back(cubeSides[i][0] * scale); + result.PositionData.push_back(cubeSides[i][1] * scale); + result.PositionData.push_back(cubeSides[i][2] * scale); + result.PositionData.push_back(cubeSides[i][2] * scale); + result.PositionData.push_back(cubeSides[i][3] * scale); + result.PositionData.push_back(cubeSides[i][0] * scale); + + result.ColorData.push_back(cubeColors[i]); + result.ColorData.push_back(cubeColors[i]); + result.ColorData.push_back(cubeColors[i]); + result.ColorData.push_back(cubeColors[i]); + result.ColorData.push_back(cubeColors[i]); + result.ColorData.push_back(cubeColors[i]); + } + + return result; + } + + VertexDataStruct CreateCubemap(float scale) + { + VertexDataStruct cubemapVertexDataStruct; + + // +x + cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, scale, scale }); + + cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, scale, scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, scale }); + + // -x + cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, scale }); + + cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, scale }); + cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, scale }); + + + // +y + cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, scale, scale }); + + cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, scale, scale }); + cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, scale }); + + + // -y + cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, scale }); + + cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, scale }); + cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, scale }); + + + // +z + cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, scale, scale }); + + cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, scale, scale }); + cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, scale }); + + // -z + cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, scale, -scale }); + + cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, -scale }); + + return cubemapVertexDataStruct; + + } + + void VertexRenderStruct::RefreshVBO() + { + //Check if main thread, check if data is not empty... + +#ifndef EMSCRIPTEN + if (!vao) + { + vao = std::make_shared(); + } + + glBindVertexArray(vao->getBuffer()); +#endif + if (!positionVBO) + { + positionVBO = std::make_shared(); + } + + glBindBuffer(GL_ARRAY_BUFFER, positionVBO->getBuffer()); + + glBufferData(GL_ARRAY_BUFFER, data.PositionData.size() * 12, &data.PositionData[0], GL_STATIC_DRAW); + + if (data.TexCoordData.size() > 0) + { + if (!texCoordVBO) + { + texCoordVBO = std::make_shared(); + } + + glBindBuffer(GL_ARRAY_BUFFER, texCoordVBO->getBuffer()); + + glBufferData(GL_ARRAY_BUFFER, data.TexCoordData.size() * 8, &data.TexCoordData[0], GL_STATIC_DRAW); + } + + if (data.NormalData.size() > 0) + { + if (!normalVBO) + { + normalVBO = std::make_shared(); + } + + glBindBuffer(GL_ARRAY_BUFFER, normalVBO->getBuffer()); + + glBufferData(GL_ARRAY_BUFFER, data.NormalData.size() * 12, &data.NormalData[0], GL_STATIC_DRAW); + } + + if (data.TangentData.size() > 0) + { + if (!tangentVBO) + { + tangentVBO = std::make_shared(); + } + + glBindBuffer(GL_ARRAY_BUFFER, tangentVBO->getBuffer()); + + glBufferData(GL_ARRAY_BUFFER, data.TangentData.size() * 12, &data.TangentData[0], GL_STATIC_DRAW); + } + + if (data.BinormalData.size() > 0) + { + if (!binormalVBO) + { + binormalVBO = std::make_shared(); + } + + glBindBuffer(GL_ARRAY_BUFFER, binormalVBO->getBuffer()); + + glBufferData(GL_ARRAY_BUFFER, data.BinormalData.size() * 12, &data.BinormalData[0], GL_STATIC_DRAW); + } + + if (data.ColorData.size() > 0) + { + if (!colorVBO) + { + colorVBO = std::make_shared(); + } + + glBindBuffer(GL_ARRAY_BUFFER, colorVBO->getBuffer()); + + glBufferData(GL_ARRAY_BUFFER, data.ColorData.size() * 12, &data.ColorData[0], GL_STATIC_DRAW); + } + } + + void VertexDataStruct::Scale(float scale) + { + for (int i = 0; i < PositionData.size(); i++) + { + PositionData[i] = PositionData[i] * scale; + } + } + void VertexDataStruct::Move(Vector3f diff) + { + for (int i = 0; i < PositionData.size(); i++) + { + PositionData[i] = PositionData[i] + diff; + } + } + + void VertexDataStruct::SwapZandY() + { + for (int i = 0; i < PositionData.size(); i++) + { + auto value = PositionData[i].v[1]; + PositionData[i].v[1] = PositionData[i].v[2]; + PositionData[i].v[2] = value; + } + } + + + void VertexDataStruct::RotateByMatrix(Matrix3f m) + { + + for (int i = 0; i < PositionData.size(); i++) + { + PositionData[i] = MultVectorMatrix(PositionData[i], m); + } + + for (int i = 0; i < NormalData.size(); i++) + { + NormalData[i] = MultVectorMatrix(NormalData[i], m); + } + + for (int i = 0; i < TangentData.size(); i++) + { + TangentData[i] = MultVectorMatrix(TangentData[i], m); + } + + for (int i = 0; i < BinormalData.size(); i++) + { + BinormalData[i] = MultVectorMatrix(BinormalData[i], m); + } + } + + void VertexRenderStruct::AssignFrom(const VertexDataStruct& v) + { + data = v; + RefreshVBO(); + } + + void Renderer::InitOpenGL() + { + ModelviewMatrixStack.push(Matrix4f::Identity()); + ProjectionMatrixStack.push(Matrix4f::Identity()); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_BLEND); + + glActiveTexture(GL_TEXTURE0); + +#ifndef EMSCRIPTEN + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +#endif + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDepthFunc(GL_LEQUAL); + + CheckGlError(); + } + + void Renderer::PushProjectionMatrix(float width, float height, float zNear, float zFar) + { + Matrix4f m = MakeOrthoMatrix(width, height, zNear, zFar); + ProjectionMatrixStack.push(m); + SetMatrix(); + + if (ProjectionMatrixStack.size() > CONST_MATRIX_STACK_SIZE) + { + throw std::runtime_error("Projection matrix stack overflow!!!!"); + } + } + + void Renderer::PushProjectionMatrix(float xmin, float xmax, float ymin, float ymax, float zNear, float zFar) + { + Matrix4f m = MakeOrthoMatrix(xmin, xmax, ymin, ymax, zNear, zFar); + ProjectionMatrixStack.push(m); + SetMatrix(); + + if (ProjectionMatrixStack.size() > CONST_MATRIX_STACK_SIZE) + { + throw std::runtime_error("Projection matrix stack overflow!!!!"); + } + } + + void Renderer::PushPerspectiveProjectionMatrix(float fovY, float aspectRatio, float zNear, float zFar) + { + Matrix4f m = MakePerspectiveMatrix(fovY, aspectRatio, zNear, zFar); + ProjectionMatrixStack.push(m); + SetMatrix(); + + if (ProjectionMatrixStack.size() > CONST_MATRIX_STACK_SIZE) + { + throw std::runtime_error("Projection matrix stack overflow!!!!"); + } + } + + + void Renderer::PopProjectionMatrix() + { + if (ProjectionMatrixStack.size() == 0) + { + throw std::runtime_error("Projection matrix stack underflow!!!!"); + } + ProjectionMatrixStack.pop(); + SetMatrix(); + } + + Matrix4f Renderer::GetProjectionModelViewMatrix() + { + return ProjectionModelViewMatrix; + } + + Matrix4f Renderer::GetCurrentModelViewMatrix() + { + return ModelviewMatrixStack.top(); + } + + + void Renderer::SetMatrix() + { + if (ProjectionMatrixStack.size() <= 0) + { + throw std::runtime_error("Projection matrix stack out!"); + } + + if (ModelviewMatrixStack.size() <= 0) + { + throw std::runtime_error("Modelview matrix stack out!"); + } + + Matrix4f& modelViewMatrix = ModelviewMatrixStack.top(); + ProjectionModelViewMatrix = ProjectionMatrixStack.top() * modelViewMatrix; + + static const std::string ProjectionModelViewMatrixName = "ProjectionModelViewMatrix"; + + RenderUniformMatrix4fv(ProjectionModelViewMatrixName, false, &ProjectionModelViewMatrix.m[0]); + + static const std::string ModelViewMatrixName = "ModelViewMatrix"; + + RenderUniformMatrix4fv(ModelViewMatrixName, false, &modelViewMatrix.m[0]); + + } + + void Renderer::PushMatrix() + { + if (ModelviewMatrixStack.size() == 0) + { + throw std::runtime_error("Modelview matrix stack underflow!!!!"); + } + + ModelviewMatrixStack.push(ModelviewMatrixStack.top()); + + if (ModelviewMatrixStack.size() > CONST_MATRIX_STACK_SIZE) + { + throw std::runtime_error("Modelview matrix stack overflow!!!!"); + } + } + + void Renderer::LoadIdentity() + { + if (ModelviewMatrixStack.size() == 0) + { + throw std::runtime_error("Modelview matrix stack underflow!!!!"); + } + + ModelviewMatrixStack.pop(); + ModelviewMatrixStack.push(Matrix4f::Identity()); + + SetMatrix(); + } + + void Renderer::TranslateMatrix(const Vector3f& p) + { + + Matrix4f m = Matrix4f::Identity(); + m.m[12] = p.v[0]; + m.m[13] = p.v[1]; + m.m[14] = p.v[2]; + + m = ModelviewMatrixStack.top() * m; + + if (ModelviewMatrixStack.size() == 0) + { + throw std::runtime_error("Modelview matrix stack underflow!!!!"); + } + + ModelviewMatrixStack.pop(); + ModelviewMatrixStack.push(m); + + SetMatrix(); + } + + void Renderer::ScaleMatrix(float scale) + { + Matrix4f m = Matrix4f::Identity(); + m.m[0] = scale; + m.m[5] = scale; + m.m[10] = scale; + + m = ModelviewMatrixStack.top() * m; + + if (ModelviewMatrixStack.size() == 0) + { + throw std::runtime_error("Modelview matrix stack underflow!!!!"); + } + + ModelviewMatrixStack.pop(); + ModelviewMatrixStack.push(m); + + SetMatrix(); + } + + void Renderer::ScaleMatrix(const Vector3f& scale) + { + Matrix4f m = Matrix4f::Identity(); + m.m[0] = scale.v[0]; + m.m[5] = scale.v[1]; + m.m[10] = scale.v[2]; + + m = ModelviewMatrixStack.top() * m; + + if (ModelviewMatrixStack.size() == 0) + { + throw std::runtime_error("Modelview matrix stack underflow!!!!"); + } + + ModelviewMatrixStack.pop(); + ModelviewMatrixStack.push(m); + + SetMatrix(); + } + + void Renderer::RotateMatrix(const Vector4f& q) + { + + Matrix3f m3 = QuatToMatrix(q); + Matrix4f m = Matrix4f::Identity(); + m.m[0] = m3.m[0]; + m.m[1] = m3.m[1]; + m.m[2] = m3.m[2]; + + m.m[4] = m3.m[3]; + m.m[5] = m3.m[4]; + m.m[6] = m3.m[5]; + + m.m[8] = m3.m[6]; + m.m[9] = m3.m[7]; + m.m[10] = m3.m[8]; + + m = ModelviewMatrixStack.top() * m; + + if (ModelviewMatrixStack.size() == 0) + { + throw std::runtime_error("Modelview matrix stack underflow!!!!"); + } + + ModelviewMatrixStack.pop(); + ModelviewMatrixStack.push(m); + + + SetMatrix(); + } + + void Renderer::RotateMatrix(const Matrix3f& m3) + { + Matrix4f m = Matrix4f::Identity(); + m.m[0] = m3.m[0]; + m.m[1] = m3.m[1]; + m.m[2] = m3.m[2]; + + m.m[4] = m3.m[3]; + m.m[5] = m3.m[4]; + m.m[6] = m3.m[5]; + + m.m[8] = m3.m[6]; + m.m[9] = m3.m[7]; + m.m[10] = m3.m[8]; + + m = ModelviewMatrixStack.top() * m; + + if (ModelviewMatrixStack.size() == 0) + { + throw std::runtime_error("Modelview matrix stack underflow!!!!"); + } + + ModelviewMatrixStack.pop(); + ModelviewMatrixStack.push(m); + + + SetMatrix(); + } + + void Renderer::PushSpecialMatrix(const Matrix4f& m) + { + if (ModelviewMatrixStack.size() > 64) + { + throw std::runtime_error("Modelview matrix stack overflow!!!!"); + } + ModelviewMatrixStack.push(m); + SetMatrix(); + } + + + void Renderer::PopMatrix() + { + if (ModelviewMatrixStack.size() == 0) + { + throw std::runtime_error("Modelview matrix stack underflow!!!!"); + } + ModelviewMatrixStack.pop(); + + SetMatrix(); + } + + + void Renderer::EnableVertexAttribArray(const std::string& attribName) + { + + auto shader = shaderManager.GetCurrentShader(); + if (shader->attribList.find(attribName) != shader->attribList.end()) + glEnableVertexAttribArray(shader->attribList[attribName]); + } + + void Renderer::DisableVertexAttribArray(const std::string& attribName) + { + auto shader = shaderManager.GetCurrentShader(); + if (shader->attribList.find(attribName) != shader->attribList.end()) + glDisableVertexAttribArray(shader->attribList[attribName]); + } + + void Renderer::RenderUniformMatrix3fv(const std::string& uniformName, bool transpose, const float* value) + { + auto shader = shaderManager.GetCurrentShader(); + + auto uniform = shader->uniformList.find(uniformName); + + if (uniform != shader->uniformList.end()) + { + glUniformMatrix3fv(uniform->second, 1, transpose, value); + } + } + + + void Renderer::RenderUniformMatrix4fv(const std::string& uniformName, bool transpose, const float* value) + { + auto shader = shaderManager.GetCurrentShader(); + + auto uniform = shader->uniformList.find(uniformName); + + if (uniform != shader->uniformList.end()) + { + glUniformMatrix4fv(uniform->second, 1, transpose, value); + } + } + + void Renderer::RenderUniform3fv(const std::string& uniformName, const float* value) + { + auto shader = shaderManager.GetCurrentShader(); + + auto uniform = shader->uniformList.find(uniformName); + + if (uniform != shader->uniformList.end()) + { + glUniform3fv(uniform->second, 1, value); + } + } + + void Renderer::RenderUniform1i(const std::string& uniformName, const int value) + { + auto shader = shaderManager.GetCurrentShader(); + + auto uniform = shader->uniformList.find(uniformName); + + if (uniform != shader->uniformList.end()) + { + glUniform1i(uniform->second, value); + } + + } + + void Renderer::RenderUniform1f(const std::string& uniformName, float value) + { + auto shader = shaderManager.GetCurrentShader(); + + auto uniform = shader->uniformList.find(uniformName); + + if (uniform != shader->uniformList.end()) + { + glUniform1fv(uniform->second, 1, &value); + } + + } + + + void Renderer::VertexAttribPointer2fv(const std::string& attribName, int stride, const char* pointer) + { + auto shader = shaderManager.GetCurrentShader(); + if (shader->attribList.find(attribName) != shader->attribList.end()) + glVertexAttribPointer(shader->attribList[attribName], 2, GL_FLOAT, GL_FALSE, stride, pointer); + + } + + void Renderer::VertexAttribPointer3fv(const std::string& attribName, int stride, const char* pointer) + { + + auto shader = shaderManager.GetCurrentShader(); + if (shader->attribList.find(attribName) != shader->attribList.end()) + glVertexAttribPointer(shader->attribList[attribName], 3, GL_FLOAT, GL_FALSE, stride, pointer); + } + + void Renderer::DrawVertexRenderStruct(const VertexRenderStruct& VertexRenderStruct) + { + static const std::string vNormal("vNormal"); + static const std::string vTangent("vTangent"); + static const std::string vBinormal("vBinormal"); + static const std::string vColor("vColor"); + static const std::string vTexCoord("vTexCoord"); + static const std::string vPosition("vPosition"); + + //glBindVertexArray(VertexRenderStruct.vao->getBuffer()); + + //Check if main thread, check if data is not empty... + if (VertexRenderStruct.data.NormalData.size() > 0) + { + glBindBuffer(GL_ARRAY_BUFFER, VertexRenderStruct.normalVBO->getBuffer()); + VertexAttribPointer3fv(vNormal, 0, NULL); + } + if (VertexRenderStruct.data.TangentData.size() > 0) + { + glBindBuffer(GL_ARRAY_BUFFER, VertexRenderStruct.tangentVBO->getBuffer()); + VertexAttribPointer3fv(vTangent, 0, NULL); + } + if (VertexRenderStruct.data.BinormalData.size() > 0) + { + glBindBuffer(GL_ARRAY_BUFFER, VertexRenderStruct.binormalVBO->getBuffer()); + VertexAttribPointer3fv(vBinormal, 0, NULL); + } + if (VertexRenderStruct.data.ColorData.size() > 0) + { + glBindBuffer(GL_ARRAY_BUFFER, VertexRenderStruct.colorVBO->getBuffer()); + VertexAttribPointer3fv(vColor, 0, NULL); + } + if (VertexRenderStruct.data.TexCoordData.size() > 0) + { + glBindBuffer(GL_ARRAY_BUFFER, VertexRenderStruct.texCoordVBO->getBuffer()); + VertexAttribPointer2fv(vTexCoord, 0, NULL); + } + + glBindBuffer(GL_ARRAY_BUFFER, VertexRenderStruct.positionVBO->getBuffer()); + VertexAttribPointer3fv(vPosition, 0, NULL); + + glDrawArrays(GL_TRIANGLES, 0, static_cast(VertexRenderStruct.data.PositionData.size())); + + } + + void 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); + } + + +} + diff --git a/Renderer.h b/src/render/Renderer.h old mode 100755 new mode 100644 similarity index 95% rename from Renderer.h rename to src/render/Renderer.h index 08a0582..abeb240 --- a/Renderer.h +++ b/src/render/Renderer.h @@ -1,144 +1,144 @@ -#pragma once - -#include "OpenGlExtensions.h" -#include "ZLMath.h" -#include -#include -#include "ShaderManager.h" - -namespace ZL { - - constexpr size_t CONST_MATRIX_STACK_SIZE = 64; - - class VBOHolder { - GLuint Buffer; - - public: - VBOHolder(); - - VBOHolder(const VBOHolder& v) = delete; - - VBOHolder& operator=(const VBOHolder& v) = delete; - - ~VBOHolder(); - - GLuint getBuffer(); - }; - - class VAOHolder { - GLuint vao; - - public: - VAOHolder(); - - VAOHolder(const VAOHolder& v) = delete; - - VAOHolder& operator=(const VAOHolder& v) = delete; - - ~VAOHolder(); - - GLuint getBuffer(); - }; - - struct VertexDataStruct - { - std::vector PositionData; - std::vector TexCoordData; - std::vector NormalData; - std::vector TangentData; - std::vector BinormalData; - std::vector ColorData; - - void RotateByMatrix(Matrix3f m); - - void Scale(float scale); - void Move(Vector3f diff); - void SwapZandY(); - }; - - struct VertexRenderStruct - { - VertexDataStruct data; - - std::shared_ptr vao; - std::shared_ptr positionVBO; - std::shared_ptr texCoordVBO; - std::shared_ptr normalVBO; - std::shared_ptr tangentVBO; - std::shared_ptr binormalVBO; - std::shared_ptr colorVBO; - void RefreshVBO(); - - void AssignFrom(const VertexDataStruct& v); - }; - - VertexDataStruct CreateRect2D(Vector2f center, Vector2f halfWidthHeight, float zLevel); - VertexDataStruct CreateRectHorizontalSections2D(Vector2f center, Vector2f halfWidthHeight, float zLevel, size_t sectionCount); - VertexDataStruct CreateCube3D(float scale); - VertexDataStruct CreateCubemap(float scale = 1000.f); - - - class Renderer - { - protected: - std::stack ProjectionMatrixStack; - std::stack ModelviewMatrixStack; - - Matrix4f ProjectionModelViewMatrix; - - public: - - ShaderManager shaderManager; - - void InitOpenGL(); - - void PushProjectionMatrix(float width, float height, float zNear = 0.f, float zFar = 1.f); - void PushProjectionMatrix(float xmin, float xmax, float ymin, float ymax, float zNear, float zFar); - void PushPerspectiveProjectionMatrix(float fovY, float aspectRatio, float zNear, float zFar); - void PopProjectionMatrix(); - - void PushMatrix(); - void LoadIdentity(); - void TranslateMatrix(const Vector3f& p); - void ScaleMatrix(float scale); - void ScaleMatrix(const Vector3f& scale); - void RotateMatrix(const Vector4f& q); - void RotateMatrix(const Matrix3f& m3); - void PushSpecialMatrix(const Matrix4f& m); - void PopMatrix(); - - - Matrix4f GetProjectionModelViewMatrix(); - Matrix4f GetCurrentModelViewMatrix(); - - void SetMatrix(); - - - - void EnableVertexAttribArray(const std::string& attribName); - - void DisableVertexAttribArray(const std::string& attribName); - - - void RenderUniformMatrix3fv(const std::string& uniformName, bool transpose, const float* value); - void RenderUniformMatrix4fv(const std::string& uniformName, bool transpose, const float* value); - void RenderUniform1i(const std::string& uniformName, const int value); - void RenderUniform3fv(const std::string& uniformName, const float* value); - void RenderUniform1f(const std::string& uniformName, float value); - - void VertexAttribPointer2fv(const std::string& attribName, int stride, const char* pointer); - - void VertexAttribPointer3fv(const std::string& attribName, int stride, const char* pointer); - - void DrawVertexRenderStruct(const VertexRenderStruct& VertexRenderStruct); - }; - - - - - void worldToScreenCoordinates(Vector3f objectPos, - Matrix4f projectionModelView, - int screenWidth, int screenHeight, - int& screenX, int& screenY); - +#pragma once + +#include "OpenGlExtensions.h" +#include "utils/ZLMath.h" +#include +#include +#include "ShaderManager.h" + +namespace ZL { + + constexpr size_t CONST_MATRIX_STACK_SIZE = 64; + + class VBOHolder { + GLuint Buffer; + + public: + VBOHolder(); + + VBOHolder(const VBOHolder& v) = delete; + + VBOHolder& operator=(const VBOHolder& v) = delete; + + ~VBOHolder(); + + GLuint getBuffer(); + }; + + class VAOHolder { + GLuint vao; + + public: + VAOHolder(); + + VAOHolder(const VAOHolder& v) = delete; + + VAOHolder& operator=(const VAOHolder& v) = delete; + + ~VAOHolder(); + + GLuint getBuffer(); + }; + + struct VertexDataStruct + { + std::vector PositionData; + std::vector TexCoordData; + std::vector NormalData; + std::vector TangentData; + std::vector BinormalData; + std::vector ColorData; + + void RotateByMatrix(Matrix3f m); + + void Scale(float scale); + void Move(Vector3f diff); + void SwapZandY(); + }; + + struct VertexRenderStruct + { + VertexDataStruct data; + + std::shared_ptr vao; + std::shared_ptr positionVBO; + std::shared_ptr texCoordVBO; + std::shared_ptr normalVBO; + std::shared_ptr tangentVBO; + std::shared_ptr binormalVBO; + std::shared_ptr colorVBO; + void RefreshVBO(); + + void AssignFrom(const VertexDataStruct& v); + }; + + VertexDataStruct CreateRect2D(Vector2f center, Vector2f halfWidthHeight, float zLevel); + VertexDataStruct CreateRectHorizontalSections2D(Vector2f center, Vector2f halfWidthHeight, float zLevel, size_t sectionCount); + VertexDataStruct CreateCube3D(float scale); + VertexDataStruct CreateCubemap(float scale = 1000.f); + + + class Renderer + { + protected: + std::stack ProjectionMatrixStack; + std::stack ModelviewMatrixStack; + + Matrix4f ProjectionModelViewMatrix; + + public: + + ShaderManager shaderManager; + + void InitOpenGL(); + + void PushProjectionMatrix(float width, float height, float zNear = 0.f, float zFar = 1.f); + void PushProjectionMatrix(float xmin, float xmax, float ymin, float ymax, float zNear, float zFar); + void PushPerspectiveProjectionMatrix(float fovY, float aspectRatio, float zNear, float zFar); + void PopProjectionMatrix(); + + void PushMatrix(); + void LoadIdentity(); + void TranslateMatrix(const Vector3f& p); + void ScaleMatrix(float scale); + void ScaleMatrix(const Vector3f& scale); + void RotateMatrix(const Vector4f& q); + void RotateMatrix(const Matrix3f& m3); + void PushSpecialMatrix(const Matrix4f& m); + void PopMatrix(); + + + Matrix4f GetProjectionModelViewMatrix(); + Matrix4f GetCurrentModelViewMatrix(); + + void SetMatrix(); + + + + void EnableVertexAttribArray(const std::string& attribName); + + void DisableVertexAttribArray(const std::string& attribName); + + + void RenderUniformMatrix3fv(const std::string& uniformName, bool transpose, const float* value); + void RenderUniformMatrix4fv(const std::string& uniformName, bool transpose, const float* value); + void RenderUniform1i(const std::string& uniformName, const int value); + void RenderUniform3fv(const std::string& uniformName, const float* value); + void RenderUniform1f(const std::string& uniformName, float value); + + void VertexAttribPointer2fv(const std::string& attribName, int stride, const char* pointer); + + void VertexAttribPointer3fv(const std::string& attribName, int stride, const char* pointer); + + void DrawVertexRenderStruct(const VertexRenderStruct& VertexRenderStruct); + }; + + + + + void worldToScreenCoordinates(Vector3f objectPos, + Matrix4f projectionModelView, + int screenWidth, int screenHeight, + int& screenX, int& screenY); + }; \ No newline at end of file diff --git a/ShaderManager.cpp b/src/render/ShaderManager.cpp old mode 100755 new mode 100644 similarity index 96% rename from ShaderManager.cpp rename to src/render/ShaderManager.cpp index 33c37b8..62cdb53 --- a/ShaderManager.cpp +++ b/src/render/ShaderManager.cpp @@ -1,215 +1,215 @@ -#include "ShaderManager.h" -#include - - -namespace ZL { - - ShaderResource::ShaderResource(const std::string& vertexCode, const std::string& fragmentCode) - { - - const int CONST_INFOLOG_LENGTH = 256; - - char infoLog[CONST_INFOLOG_LENGTH]; - int infoLogLength; - char infoLog2[CONST_INFOLOG_LENGTH]; - int infoLogLength2; - - int vertexShaderCompiled; - int fragmentShaderCompiled; - int programLinked; - - GLuint vertexShader; - GLuint fragmentShader; - - int vertexCodeLength = static_cast(strlen(vertexCode.c_str())); - int fragmentCodeLength = static_cast(strlen(fragmentCode.c_str())); - - const char* vc = &vertexCode[0]; - const char* fc = &fragmentCode[0]; - - vertexShader = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(vertexShader, 1, &(vc), &vertexCodeLength); - - fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(fragmentShader, 1, &(fc), &fragmentCodeLength); - - glCompileShader(vertexShader); - glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &vertexShaderCompiled); - glGetShaderInfoLog(vertexShader, CONST_INFOLOG_LENGTH, &infoLogLength, infoLog); - - glCompileShader(fragmentShader); - glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &fragmentShaderCompiled); - glGetShaderInfoLog(fragmentShader, CONST_INFOLOG_LENGTH, &infoLogLength2, infoLog2); - - - if (!vertexShaderCompiled) - { - throw std::runtime_error("Failed to compile vertex shader code!"); - } - - if (!fragmentShaderCompiled) - { - throw std::runtime_error("Failed to compile fragment shader code!"); - } - - shaderProgram = glCreateProgram(); - - glAttachShader(shaderProgram, vertexShader); - glAttachShader(shaderProgram, fragmentShader); - - glLinkProgram(shaderProgram); - - glDeleteShader(vertexShader); - glDeleteShader(fragmentShader); - - glGetProgramiv(shaderProgram, GL_LINK_STATUS, &programLinked); - glGetProgramInfoLog(shaderProgram, CONST_INFOLOG_LENGTH, &infoLogLength, infoLog); - - if (!programLinked) - { - shaderProgram = 0; - throw std::runtime_error("Failed to link shader program!"); - } - - - int dummySize; //Dummy - int dummyLen; //Dummy - GLenum dummyEnum; - - - //================= Parsing all uniforms ================ - - int activeUniforms; - - const int CONST_UNIFORM_NAME_LENGTH = 256; - char uniformName[CONST_UNIFORM_NAME_LENGTH]; - - glGetProgramiv(shaderProgram, GL_ACTIVE_UNIFORMS, &activeUniforms); - - for (int i = 0; i < activeUniforms; i++) - { - glGetActiveUniform(shaderProgram, i, CONST_UNIFORM_NAME_LENGTH, &dummyLen, &dummySize, &dummyEnum, uniformName); - - uniformList[uniformName] = glGetUniformLocation(shaderProgram, uniformName); - } - - //================= Parsing all attributes ================ - int activeAttribs; - - const int CONST_ATTRIB_NAME_LENGTH = 256; - char attribName[CONST_ATTRIB_NAME_LENGTH]; - - glGetProgramiv(shaderProgram, GL_ACTIVE_ATTRIBUTES, &activeAttribs); - - for (int i = 0; i < activeAttribs; i++) - { - glGetActiveAttrib(shaderProgram, i, CONST_ATTRIB_NAME_LENGTH, &dummyLen, &dummySize, &dummyEnum, attribName); - attribList[attribName] = glGetAttribLocation(shaderProgram, attribName); - } - } - - ShaderResource::~ShaderResource() - { - if (shaderProgram != 0) - { - glDeleteProgram(shaderProgram); - - shaderProgram = 0; - } - } - - GLuint ShaderResource::getShaderProgram() - { - return shaderProgram; - } - - - void ShaderManager::AddShaderFromFiles(const std::string& shaderName, const std::string& vertexShaderFileName, const std::string& fragmentShaderFileName, const std::string& ZIPFileName) - { - - std::string vertexShader; - std::string fragmentShader; - - if (!ZIPFileName.empty()){ - - std::vector vertexShaderData; - std::vector fragmentShaderData; - - vertexShaderData = readFileFromZIP(vertexShaderFileName, ZIPFileName); - fragmentShaderData = readFileFromZIP(fragmentShaderFileName, ZIPFileName); - - vertexShader = std::string(vertexShaderData.begin(), vertexShaderData.end()); - fragmentShader = std::string(fragmentShaderData.begin(), fragmentShaderData.end()); - - }else{ - vertexShader = readTextFile(vertexShaderFileName); - fragmentShader = readTextFile(fragmentShaderFileName); - } - ///std::cout << "Shader: "<< vertexShader << std::endl; - shaderResourceMap[shaderName] = std::make_shared(vertexShader, fragmentShader); - } - - void ShaderManager::PushShader(const std::string& shaderName) - { - if (shaderStack.size() >= CONST_MAX_SHADER_STACK_SIZE) - { - throw std::runtime_error("Shader stack overflow!"); - } - - if (shaderResourceMap.find(shaderName) == shaderResourceMap.end()) - { - throw std::runtime_error("Shader does not exist!"); - } - - shaderStack.push(shaderName); - - glUseProgram(shaderResourceMap[shaderName]->getShaderProgram()); - } - - - void ShaderManager::PopShader() - { - if (shaderStack.size() == 0) - { - throw std::runtime_error("Shader stack underflow!"); - } - - shaderStack.pop(); - - if (shaderStack.size() == 0) - { - glUseProgram(0); - } - else - { - glUseProgram(shaderResourceMap[shaderStack.top()]->getShaderProgram()); - } - } - - std::shared_ptr ShaderManager::GetCurrentShader() - { - if (shaderStack.size() == 0) - { - throw std::runtime_error("Shader stack underflow!"); - } - - - return shaderResourceMap[shaderStack.top()]; - - } - - - - - ShaderSetter::ShaderSetter(ShaderManager& inShaderManager, const std::string& shaderName) - : shaderManager(shaderManager) - { - shaderManager.PushShader(shaderName); - } - - ShaderSetter::~ShaderSetter() - { - shaderManager.PopShader(); - } - +#include "ShaderManager.h" +#include + + +namespace ZL { + + ShaderResource::ShaderResource(const std::string& vertexCode, const std::string& fragmentCode) + { + + const int CONST_INFOLOG_LENGTH = 256; + + char infoLog[CONST_INFOLOG_LENGTH]; + int infoLogLength; + char infoLog2[CONST_INFOLOG_LENGTH]; + int infoLogLength2; + + int vertexShaderCompiled; + int fragmentShaderCompiled; + int programLinked; + + GLuint vertexShader; + GLuint fragmentShader; + + int vertexCodeLength = static_cast(strlen(vertexCode.c_str())); + int fragmentCodeLength = static_cast(strlen(fragmentCode.c_str())); + + const char* vc = &vertexCode[0]; + const char* fc = &fragmentCode[0]; + + vertexShader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertexShader, 1, &(vc), &vertexCodeLength); + + fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragmentShader, 1, &(fc), &fragmentCodeLength); + + glCompileShader(vertexShader); + glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &vertexShaderCompiled); + glGetShaderInfoLog(vertexShader, CONST_INFOLOG_LENGTH, &infoLogLength, infoLog); + + glCompileShader(fragmentShader); + glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &fragmentShaderCompiled); + glGetShaderInfoLog(fragmentShader, CONST_INFOLOG_LENGTH, &infoLogLength2, infoLog2); + + + if (!vertexShaderCompiled) + { + throw std::runtime_error("Failed to compile vertex shader code!"); + } + + if (!fragmentShaderCompiled) + { + throw std::runtime_error("Failed to compile fragment shader code!"); + } + + shaderProgram = glCreateProgram(); + + glAttachShader(shaderProgram, vertexShader); + glAttachShader(shaderProgram, fragmentShader); + + glLinkProgram(shaderProgram); + + glDeleteShader(vertexShader); + glDeleteShader(fragmentShader); + + glGetProgramiv(shaderProgram, GL_LINK_STATUS, &programLinked); + glGetProgramInfoLog(shaderProgram, CONST_INFOLOG_LENGTH, &infoLogLength, infoLog); + + if (!programLinked) + { + shaderProgram = 0; + throw std::runtime_error("Failed to link shader program!"); + } + + + int dummySize; //Dummy + int dummyLen; //Dummy + GLenum dummyEnum; + + + //================= Parsing all uniforms ================ + + int activeUniforms; + + const int CONST_UNIFORM_NAME_LENGTH = 256; + char uniformName[CONST_UNIFORM_NAME_LENGTH]; + + glGetProgramiv(shaderProgram, GL_ACTIVE_UNIFORMS, &activeUniforms); + + for (int i = 0; i < activeUniforms; i++) + { + glGetActiveUniform(shaderProgram, i, CONST_UNIFORM_NAME_LENGTH, &dummyLen, &dummySize, &dummyEnum, uniformName); + + uniformList[uniformName] = glGetUniformLocation(shaderProgram, uniformName); + } + + //================= Parsing all attributes ================ + int activeAttribs; + + const int CONST_ATTRIB_NAME_LENGTH = 256; + char attribName[CONST_ATTRIB_NAME_LENGTH]; + + glGetProgramiv(shaderProgram, GL_ACTIVE_ATTRIBUTES, &activeAttribs); + + for (int i = 0; i < activeAttribs; i++) + { + glGetActiveAttrib(shaderProgram, i, CONST_ATTRIB_NAME_LENGTH, &dummyLen, &dummySize, &dummyEnum, attribName); + attribList[attribName] = glGetAttribLocation(shaderProgram, attribName); + } + } + + ShaderResource::~ShaderResource() + { + if (shaderProgram != 0) + { + glDeleteProgram(shaderProgram); + + shaderProgram = 0; + } + } + + GLuint ShaderResource::getShaderProgram() + { + return shaderProgram; + } + + + void ShaderManager::AddShaderFromFiles(const std::string& shaderName, const std::string& vertexShaderFileName, const std::string& fragmentShaderFileName, const std::string& ZIPFileName) + { + + std::string vertexShader; + std::string fragmentShader; + + if (!ZIPFileName.empty()){ + + std::vector vertexShaderData; + std::vector fragmentShaderData; + + vertexShaderData = readFileFromZIP(vertexShaderFileName, ZIPFileName); + fragmentShaderData = readFileFromZIP(fragmentShaderFileName, ZIPFileName); + + vertexShader = std::string(vertexShaderData.begin(), vertexShaderData.end()); + fragmentShader = std::string(fragmentShaderData.begin(), fragmentShaderData.end()); + + }else{ + vertexShader = readTextFile(vertexShaderFileName); + fragmentShader = readTextFile(fragmentShaderFileName); + } + ///std::cout << "Shader: "<< vertexShader << std::endl; + shaderResourceMap[shaderName] = std::make_shared(vertexShader, fragmentShader); + } + + void ShaderManager::PushShader(const std::string& shaderName) + { + if (shaderStack.size() >= CONST_MAX_SHADER_STACK_SIZE) + { + throw std::runtime_error("Shader stack overflow!"); + } + + if (shaderResourceMap.find(shaderName) == shaderResourceMap.end()) + { + throw std::runtime_error("Shader does not exist!"); + } + + shaderStack.push(shaderName); + + glUseProgram(shaderResourceMap[shaderName]->getShaderProgram()); + } + + + void ShaderManager::PopShader() + { + if (shaderStack.size() == 0) + { + throw std::runtime_error("Shader stack underflow!"); + } + + shaderStack.pop(); + + if (shaderStack.size() == 0) + { + glUseProgram(0); + } + else + { + glUseProgram(shaderResourceMap[shaderStack.top()]->getShaderProgram()); + } + } + + std::shared_ptr ShaderManager::GetCurrentShader() + { + if (shaderStack.size() == 0) + { + throw std::runtime_error("Shader stack underflow!"); + } + + + return shaderResourceMap[shaderStack.top()]; + + } + + + + + ShaderSetter::ShaderSetter(ShaderManager& inShaderManager, const std::string& shaderName) + : shaderManager(shaderManager) + { + shaderManager.PushShader(shaderName); + } + + ShaderSetter::~ShaderSetter() + { + shaderManager.PopShader(); + } + } \ No newline at end of file diff --git a/ShaderManager.h b/src/render/ShaderManager.h old mode 100755 new mode 100644 similarity index 93% rename from ShaderManager.h rename to src/render/ShaderManager.h index da911f1..d22b567 --- a/ShaderManager.h +++ b/src/render/ShaderManager.h @@ -1,64 +1,64 @@ -#pragma once -#include "OpenGlExtensions.h" -#include "Utils.h" - -namespace ZL { - - - constexpr size_t CONST_MAX_SHADER_STACK_SIZE = 16; - - class ShaderResource - { - protected: - GLuint shaderProgram; - - std::unordered_map uniformList; - - //std::unordered_map> UniformList; - std::map attribList; - - - public: - - GLuint getShaderProgram(); - - ShaderResource(const std::string& vertexCode, const std::string& fragmentCode); - ~ShaderResource(); - - public: - friend class ShaderManager; - friend class Renderer; - }; - - class ShaderManager { - protected: - std::unordered_map> shaderResourceMap; - - std::stack shaderStack; - - public: - void AddShaderFromFiles(const std::string& shaderName, const std::string& vertexShaderFileName, const std::string& fragmentShaderFileName, const std::string& ZIPFileName = ""); - - void PushShader(const std::string& shaderName); - void PopShader(); - - std::shared_ptr GetCurrentShader(); - }; - - - class ShaderSetter - { - protected: - - ShaderManager& shaderManager; - - public: - ShaderSetter(ShaderManager& inShaderManager, const std::string& shaderName); - - ~ShaderSetter(); - - - }; - - +#pragma once +#include "OpenGlExtensions.h" +#include "utils/Utils.h" + +namespace ZL { + + + constexpr size_t CONST_MAX_SHADER_STACK_SIZE = 16; + + class ShaderResource + { + protected: + GLuint shaderProgram; + + std::unordered_map uniformList; + + //std::unordered_map> UniformList; + std::map attribList; + + + public: + + GLuint getShaderProgram(); + + ShaderResource(const std::string& vertexCode, const std::string& fragmentCode); + ~ShaderResource(); + + public: + friend class ShaderManager; + friend class Renderer; + }; + + class ShaderManager { + protected: + std::unordered_map> shaderResourceMap; + + std::stack shaderStack; + + public: + void AddShaderFromFiles(const std::string& shaderName, const std::string& vertexShaderFileName, const std::string& fragmentShaderFileName, const std::string& ZIPFileName = ""); + + void PushShader(const std::string& shaderName); + void PopShader(); + + std::shared_ptr GetCurrentShader(); + }; + + + class ShaderSetter + { + protected: + + ShaderManager& shaderManager; + + public: + ShaderSetter(ShaderManager& inShaderManager, const std::string& shaderName); + + ~ShaderSetter(); + + + }; + + } \ No newline at end of file diff --git a/TextureManager.cpp b/src/render/TextureManager.cpp old mode 100755 new mode 100644 similarity index 96% rename from TextureManager.cpp rename to src/render/TextureManager.cpp index 3db8f65..1805953 --- a/TextureManager.cpp +++ b/src/render/TextureManager.cpp @@ -1,430 +1,431 @@ -#include "TextureManager.h" -#ifdef PNG_ENABLED -#include "png.h" -#endif -#include - -namespace ZL -{ - - Texture::Texture(const TextureDataStruct& texData) - { - - width = texData.width; - height = texData.height; - - glGenTextures(1, &texID); - - if (texID == 0) - { - throw std::runtime_error("glGenTextures did not work"); - } - - glBindTexture(GL_TEXTURE_2D, texID); - - CheckGlError(); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - - CheckGlError(); - - //This should be only for Windows - //glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); - - CheckGlError(); - - if (texData.bitSize == TextureDataStruct::BS_24BIT) - { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, static_cast(texData.width), static_cast(texData.height), 0, GL_RGB, GL_UNSIGNED_BYTE, &texData.data[0]); - } - else - { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, static_cast(texData.width), static_cast(texData.height), 0, GL_RGBA, GL_UNSIGNED_BYTE, &texData.data[0]); - } - - CheckGlError(); - - } - - Texture::Texture(const std::array& texDataArray) - { - // , - width = texDataArray[0].width; - height = texDataArray[0].height; - - for (size_t i = 1; i < 6; ++i) { - if (texDataArray[i].width != width || texDataArray[i].height != height) { - throw std::runtime_error("Cubemap faces must have the same dimensions"); - } - } - - glGenTextures(1, &texID); - - if (texID == 0) - { - throw std::runtime_error("glGenTextures did not work for cubemap"); - } - - glBindTexture(GL_TEXTURE_CUBE_MAP, texID); - - CheckGlError(); - - // Cubemap - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - // GL_LINEAR MIN_FILTER, - // (e.g., GL_LINEAR_MIPMAP_LINEAR), glGenerateMipmap. - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - - // Cubemap - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - // GL_TEXTURE_WRAP_R WebGL 1.0/OpenGL ES 2.0 . - // . -#ifndef EMSCRIPTEN - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); -#endif - - CheckGlError(); // - - // 6 - // GL_TEXTURE_CUBE_MAP_POSITIVE_X + i : +X (0), -X (1), +Y (2), -Y (3), +Z (4), -Z (5) - for (int i = 0; i < 6; ++i) - { - GLint internalFormat; - GLenum format; - - // WebGL 1.0/OpenGL ES 2.0 (internalFormat) - // (format). - if (texDataArray[i].bitSize == TextureDataStruct::BS_24BIT) - { - internalFormat = GL_RGB; // internalFormat - format = GL_RGB; // format - } - else // BS_32BIT - { - internalFormat = GL_RGBA; // internalFormat - format = GL_RGBA; // format - } - - glTexImage2D( - GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, // - 0, // MIP- - internalFormat, // ( ) - static_cast(width), - static_cast(height), - 0, // ( 0) - format, // - GL_UNSIGNED_BYTE, // - texDataArray[i].data.data() // - ); - CheckGlError(); - } - - // - glBindTexture(GL_TEXTURE_CUBE_MAP, 0); - } - - Texture::~Texture() - { - glDeleteTextures(1, &texID); - texID = 0; - } - - GLuint Texture::getTexID() - { - return texID; - } - - size_t Texture::getWidth() - { - return width; - } - - size_t Texture::getHeight() - { - return height; - } - - - - TextureDataStruct CreateTextureDataFromBmp24(const std::string& fullFileName, const std::string& ZIPFileName) - { - - TextureDataStruct texData; - std::vector fileArr; - - fileArr = !ZIPFileName.empty() ? readFileFromZIP(fullFileName, ZIPFileName) : readFile(fullFileName); - - size_t fileSize = fileArr.size(); - - if (fileSize < 22) - { - throw std::runtime_error("File is too short or not correct!"); - } - - //This refers to BITMAPV5HEADER - texData.width = *reinterpret_cast(&fileArr[18]); - texData.height = *reinterpret_cast(&fileArr[22]); - - texData.bitSize = TextureDataStruct::BS_24BIT; - - size_t dataSize = texData.width * texData.height * 3; - - texData.data.resize(dataSize); - - size_t pos = *reinterpret_cast(&fileArr[10]); - size_t x = 0; - - for (size_t i = 0; i < texData.width; i++) - for (size_t j = 0; j < texData.height; j++) - { - - if (pos + 3 > fileSize) - { - throw std::runtime_error("File is too short!"); - } - - - x = (i * texData.height + j) + (i * texData.height + j) + (i * texData.height + j); - - texData.data[x + 2] = fileArr[pos++]; - texData.data[x + 1] = fileArr[pos++]; - texData.data[x + 0] = fileArr[pos++]; - - } - - return texData; - } - - TextureDataStruct CreateTextureDataFromBmp32(const std::string& fullFileName, const std::string& ZIPFileName) - { - - TextureDataStruct texData; - std::vector fileArr; - - fileArr = !ZIPFileName.empty() ? readFileFromZIP(fullFileName, ZIPFileName) : readFile(fullFileName); - - size_t fileSize = fileArr.size(); - - if (fileSize < 22) - { - throw std::runtime_error("File is too short or not correct!"); - } - - //This refers to BITMAPV5HEADER - texData.width = *reinterpret_cast(&fileArr[18]); - texData.height = *reinterpret_cast(&fileArr[22]); - - texData.bitSize = TextureDataStruct::BS_32BIT; - - size_t dataSize = texData.width * texData.height * 4; - - texData.data.resize(dataSize); - - size_t pos = *reinterpret_cast(&fileArr[10]); - size_t x = 0; - - for (size_t i = 0; i < texData.width; i++) - for (size_t j = 0; j < texData.height; j++) - { - - if (pos + 4 > fileSize) - { - throw std::runtime_error("File is too short!"); - } - - - x = (i * texData.height + j) + (i * texData.height + j) + (i * texData.height + j) + (i * texData.height + j); - - texData.data[x + 2] = fileArr[pos++]; - texData.data[x + 1] = fileArr[pos++]; - texData.data[x + 0] = fileArr[pos++]; - texData.data[x + 3] = fileArr[pos++]; - - } - - return texData; - } - -#ifdef PNG_ENABLED - - // / - struct png_data_t { - const char* data; - size_t size; - size_t offset; - }; - - // libpng - // 'png_ptr' - png - // 'out_ptr' - - // 'bytes_to_read' - - void user_read_data(png_structp png_ptr, png_bytep out_ptr, png_size_t bytes_to_read) { - // png_data_t, png_set_read_fn - png_data_t* data = (png_data_t*)png_get_io_ptr(png_ptr); - - if (data->offset + bytes_to_read > data->size) { - // , . - // , . - // libpng. - png_error(png_ptr, "PNG Read Error: Attempted to read past end of data buffer."); - bytes_to_read = data->size - data->offset; // , - } - - // libpng - std::memcpy(out_ptr, data->data + data->offset, bytes_to_read); - - // - data->offset += bytes_to_read; - } - - // ( , nullptr) - void user_warning_fn(png_structp png_ptr, png_const_charp warning_msg) { - // - //throw std::runtime_error(); - std::cout << "PNG Warning: " << warning_msg << std::endl; - } - - // ( setjmp) - void user_error_fn(png_structp png_ptr, png_const_charp error_msg) { - // - std::cout << "PNG Error: " << error_msg << std::endl; - // longjmp / PNG - longjmp(png_jmpbuf(png_ptr), 1); - } - - TextureDataStruct CreateTextureDataFromPng(const std::vector& fileArr) - { - TextureDataStruct texData; - - // - png_data_t png_data = { fileArr.data(), fileArr.size(), 0 }; - - png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); - if (!png) { - throw std::runtime_error("Could not create PNG read structure"); - } - - png_infop info = png_create_info_struct(png); - if (!info) { - png_destroy_read_struct(&png, nullptr, nullptr); - throw std::runtime_error("Could not create PNG info structure"); - } - - // === === - // 1. longjmp - if (setjmp(png_jmpbuf(png))) { - png_destroy_read_struct(&png, &info, nullptr); - throw std::runtime_error("Error during PNG read (longjmp was executed)"); - } - - // 2. - // nullptr error_ptr warning_ptr , - png_set_error_fn(png, nullptr, user_error_fn, user_warning_fn); - - // 3. png_data - png_set_read_fn(png, &png_data, user_read_data); - // =================================================================== - - png_read_info(png, info); - - texData.width = png_get_image_width(png, info); - texData.height = png_get_image_height(png, info); - png_byte color_type = png_get_color_type(png, info); - png_byte bit_depth = png_get_bit_depth(png, info); - - // === ( ) === - if (bit_depth == 16) - png_set_strip_16(png); - - if (color_type == PNG_COLOR_TYPE_PALETTE) - png_set_palette_to_rgb(png); - - if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) - png_set_expand_gray_1_2_4_to_8(png); - - if (png_get_valid(png, info, PNG_INFO_tRNS)) - png_set_tRNS_to_alpha(png); - - if (color_type == PNG_COLOR_TYPE_RGB || - color_type == PNG_COLOR_TYPE_GRAY || - color_type == PNG_COLOR_TYPE_PALETTE) - png_set_filler(png, 0xFF, PNG_FILLER_AFTER); - - if (color_type == PNG_COLOR_TYPE_GRAY || - color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - png_set_gray_to_rgb(png); - - png_read_update_info(png, info); - // ==================================================== - - // === ( ) === - png_bytep* row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * texData.height); - for (int y = 0; y < texData.height; y++) { - row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(png, info)); - } - - png_read_image(png, row_pointers); - - bool has_alpha = (color_type & PNG_COLOR_MASK_ALPHA) || (png_get_valid(png, info, PNG_INFO_tRNS)); - - size_t dataSize; - - if (has_alpha) - { - texData.bitSize = TextureDataStruct::BS_32BIT; - } - else - { - texData.bitSize = TextureDataStruct::BS_24BIT; - } - - int channels = has_alpha ? 4 : 3; - - dataSize = texData.width * texData.height * channels; - texData.data.resize(dataSize); - - - for (int y = texData.height - 1; y >= 0; y--) { - png_bytep row = row_pointers[texData.height - 1 - y]; - for (int x = 0; x < texData.width; x++) { - png_bytep px = &(row[x * 4]); - texData.data[(y * texData.width + x) * channels + 0] = px[0]; // R - texData.data[(y * texData.width + x) * channels + 1] = px[1]; // G - texData.data[(y * texData.width + x) * channels + 2] = px[2]; // B - if (has_alpha) { - texData.data[(y * texData.width + x) * channels + 3] = px[3]; // A - } - } - free(row_pointers[texData.height - 1 - y]); - } - free(row_pointers); - // ================================================== - - png_destroy_read_struct(&png, &info, nullptr); - - return texData; - } - - - TextureDataStruct CreateTextureDataFromPng(const std::string& fullFileName, const std::string& ZIPFileName) - { - std::vector fileArr; - - fileArr = !ZIPFileName.empty() ? readFileFromZIP(fullFileName, ZIPFileName) : readFile(fullFileName); - - if (fileArr.empty()) { - throw std::runtime_error("Could not read file data into memory"); - } - - // , - return CreateTextureDataFromPng(fileArr); - } - - -#endif - - +#include "render/TextureManager.h" +#include "render/OpenGlExtensions.h" +#ifdef PNG_ENABLED +#include "png.h" +#endif +#include + +namespace ZL +{ + + Texture::Texture(const TextureDataStruct& texData) + { + + width = texData.width; + height = texData.height; + + glGenTextures(1, &texID); + + if (texID == 0) + { + throw std::runtime_error("glGenTextures did not work"); + } + + glBindTexture(GL_TEXTURE_2D, texID); + + CheckGlError(); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + CheckGlError(); + + //This should be only for Windows + //glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); + + CheckGlError(); + + if (texData.bitSize == TextureDataStruct::BS_24BIT) + { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, static_cast(texData.width), static_cast(texData.height), 0, GL_RGB, GL_UNSIGNED_BYTE, &texData.data[0]); + } + else + { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, static_cast(texData.width), static_cast(texData.height), 0, GL_RGBA, GL_UNSIGNED_BYTE, &texData.data[0]); + } + + CheckGlError(); + + } + + Texture::Texture(const std::array& texDataArray) + { + // , + width = texDataArray[0].width; + height = texDataArray[0].height; + + for (size_t i = 1; i < 6; ++i) { + if (texDataArray[i].width != width || texDataArray[i].height != height) { + throw std::runtime_error("Cubemap faces must have the same dimensions"); + } + } + + glGenTextures(1, &texID); + + if (texID == 0) + { + throw std::runtime_error("glGenTextures did not work for cubemap"); + } + + glBindTexture(GL_TEXTURE_CUBE_MAP, texID); + + CheckGlError(); + + // Cubemap + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + // GL_LINEAR MIN_FILTER, + // (e.g., GL_LINEAR_MIPMAP_LINEAR), glGenerateMipmap. + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + // Cubemap + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + // GL_TEXTURE_WRAP_R WebGL 1.0/OpenGL ES 2.0 . + // . +#ifndef EMSCRIPTEN + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); +#endif + + CheckGlError(); // + + // 6 + // GL_TEXTURE_CUBE_MAP_POSITIVE_X + i : +X (0), -X (1), +Y (2), -Y (3), +Z (4), -Z (5) + for (int i = 0; i < 6; ++i) + { + GLint internalFormat; + GLenum format; + + // WebGL 1.0/OpenGL ES 2.0 (internalFormat) + // (format). + if (texDataArray[i].bitSize == TextureDataStruct::BS_24BIT) + { + internalFormat = GL_RGB; // internalFormat + format = GL_RGB; // format + } + else // BS_32BIT + { + internalFormat = GL_RGBA; // internalFormat + format = GL_RGBA; // format + } + + glTexImage2D( + GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, // + 0, // MIP- + internalFormat, // ( ) + static_cast(width), + static_cast(height), + 0, // ( 0) + format, // + GL_UNSIGNED_BYTE, // + texDataArray[i].data.data() // + ); + CheckGlError(); + } + + // + glBindTexture(GL_TEXTURE_CUBE_MAP, 0); + } + + Texture::~Texture() + { + glDeleteTextures(1, &texID); + texID = 0; + } + + GLuint Texture::getTexID() + { + return texID; + } + + size_t Texture::getWidth() + { + return width; + } + + size_t Texture::getHeight() + { + return height; + } + + + + TextureDataStruct CreateTextureDataFromBmp24(const std::string& fullFileName, const std::string& ZIPFileName) + { + + TextureDataStruct texData; + std::vector fileArr; + + fileArr = !ZIPFileName.empty() ? readFileFromZIP(fullFileName, ZIPFileName) : readFile(fullFileName); + + size_t fileSize = fileArr.size(); + + if (fileSize < 22) + { + throw std::runtime_error("File is too short or not correct!"); + } + + //This refers to BITMAPV5HEADER + texData.width = *reinterpret_cast(&fileArr[18]); + texData.height = *reinterpret_cast(&fileArr[22]); + + texData.bitSize = TextureDataStruct::BS_24BIT; + + size_t dataSize = texData.width * texData.height * 3; + + texData.data.resize(dataSize); + + size_t pos = *reinterpret_cast(&fileArr[10]); + size_t x = 0; + + for (size_t i = 0; i < texData.width; i++) + for (size_t j = 0; j < texData.height; j++) + { + + if (pos + 3 > fileSize) + { + throw std::runtime_error("File is too short!"); + } + + + x = (i * texData.height + j) + (i * texData.height + j) + (i * texData.height + j); + + texData.data[x + 2] = fileArr[pos++]; + texData.data[x + 1] = fileArr[pos++]; + texData.data[x + 0] = fileArr[pos++]; + + } + + return texData; + } + + TextureDataStruct CreateTextureDataFromBmp32(const std::string& fullFileName, const std::string& ZIPFileName) + { + + TextureDataStruct texData; + std::vector fileArr; + + fileArr = !ZIPFileName.empty() ? readFileFromZIP(fullFileName, ZIPFileName) : readFile(fullFileName); + + size_t fileSize = fileArr.size(); + + if (fileSize < 22) + { + throw std::runtime_error("File is too short or not correct!"); + } + + //This refers to BITMAPV5HEADER + texData.width = *reinterpret_cast(&fileArr[18]); + texData.height = *reinterpret_cast(&fileArr[22]); + + texData.bitSize = TextureDataStruct::BS_32BIT; + + size_t dataSize = texData.width * texData.height * 4; + + texData.data.resize(dataSize); + + size_t pos = *reinterpret_cast(&fileArr[10]); + size_t x = 0; + + for (size_t i = 0; i < texData.width; i++) + for (size_t j = 0; j < texData.height; j++) + { + + if (pos + 4 > fileSize) + { + throw std::runtime_error("File is too short!"); + } + + + x = (i * texData.height + j) + (i * texData.height + j) + (i * texData.height + j) + (i * texData.height + j); + + texData.data[x + 2] = fileArr[pos++]; + texData.data[x + 1] = fileArr[pos++]; + texData.data[x + 0] = fileArr[pos++]; + texData.data[x + 3] = fileArr[pos++]; + + } + + return texData; + } + +#ifdef PNG_ENABLED + + // / + struct png_data_t { + const char* data; + size_t size; + size_t offset; + }; + + // libpng + // 'png_ptr' - png + // 'out_ptr' - + // 'bytes_to_read' - + void user_read_data(png_structp png_ptr, png_bytep out_ptr, png_size_t bytes_to_read) { + // png_data_t, png_set_read_fn + png_data_t* data = (png_data_t*)png_get_io_ptr(png_ptr); + + if (data->offset + bytes_to_read > data->size) { + // , . + // , . + // libpng. + png_error(png_ptr, "PNG Read Error: Attempted to read past end of data buffer."); + bytes_to_read = data->size - data->offset; // , + } + + // libpng + std::memcpy(out_ptr, data->data + data->offset, bytes_to_read); + + // + data->offset += bytes_to_read; + } + + // ( , nullptr) + void user_warning_fn(png_structp png_ptr, png_const_charp warning_msg) { + // + //throw std::runtime_error(); + std::cout << "PNG Warning: " << warning_msg << std::endl; + } + + // ( setjmp) + void user_error_fn(png_structp png_ptr, png_const_charp error_msg) { + // + std::cout << "PNG Error: " << error_msg << std::endl; + // longjmp / PNG + longjmp(png_jmpbuf(png_ptr), 1); + } + + TextureDataStruct CreateTextureDataFromPng(const std::vector& fileArr) + { + TextureDataStruct texData; + + // + png_data_t png_data = { fileArr.data(), fileArr.size(), 0 }; + + png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); + if (!png) { + throw std::runtime_error("Could not create PNG read structure"); + } + + png_infop info = png_create_info_struct(png); + if (!info) { + png_destroy_read_struct(&png, nullptr, nullptr); + throw std::runtime_error("Could not create PNG info structure"); + } + + // === === + // 1. longjmp + if (setjmp(png_jmpbuf(png))) { + png_destroy_read_struct(&png, &info, nullptr); + throw std::runtime_error("Error during PNG read (longjmp was executed)"); + } + + // 2. + // nullptr error_ptr warning_ptr , + png_set_error_fn(png, nullptr, user_error_fn, user_warning_fn); + + // 3. png_data + png_set_read_fn(png, &png_data, user_read_data); + // =================================================================== + + png_read_info(png, info); + + texData.width = png_get_image_width(png, info); + texData.height = png_get_image_height(png, info); + png_byte color_type = png_get_color_type(png, info); + png_byte bit_depth = png_get_bit_depth(png, info); + + // === ( ) === + if (bit_depth == 16) + png_set_strip_16(png); + + if (color_type == PNG_COLOR_TYPE_PALETTE) + png_set_palette_to_rgb(png); + + if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) + png_set_expand_gray_1_2_4_to_8(png); + + if (png_get_valid(png, info, PNG_INFO_tRNS)) + png_set_tRNS_to_alpha(png); + + if (color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_GRAY || + color_type == PNG_COLOR_TYPE_PALETTE) + png_set_filler(png, 0xFF, PNG_FILLER_AFTER); + + if (color_type == PNG_COLOR_TYPE_GRAY || + color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_gray_to_rgb(png); + + png_read_update_info(png, info); + // ==================================================== + + // === ( ) === + png_bytep* row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * texData.height); + for (int y = 0; y < texData.height; y++) { + row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(png, info)); + } + + png_read_image(png, row_pointers); + + bool has_alpha = (color_type & PNG_COLOR_MASK_ALPHA) || (png_get_valid(png, info, PNG_INFO_tRNS)); + + size_t dataSize; + + if (has_alpha) + { + texData.bitSize = TextureDataStruct::BS_32BIT; + } + else + { + texData.bitSize = TextureDataStruct::BS_24BIT; + } + + int channels = has_alpha ? 4 : 3; + + dataSize = texData.width * texData.height * channels; + texData.data.resize(dataSize); + + + for (int y = texData.height - 1; y >= 0; y--) { + png_bytep row = row_pointers[texData.height - 1 - y]; + for (int x = 0; x < texData.width; x++) { + png_bytep px = &(row[x * 4]); + texData.data[(y * texData.width + x) * channels + 0] = px[0]; // R + texData.data[(y * texData.width + x) * channels + 1] = px[1]; // G + texData.data[(y * texData.width + x) * channels + 2] = px[2]; // B + if (has_alpha) { + texData.data[(y * texData.width + x) * channels + 3] = px[3]; // A + } + } + free(row_pointers[texData.height - 1 - y]); + } + free(row_pointers); + // ================================================== + + png_destroy_read_struct(&png, &info, nullptr); + + return texData; + } + + + TextureDataStruct CreateTextureDataFromPng(const std::string& fullFileName, const std::string& ZIPFileName) + { + std::vector fileArr; + + fileArr = !ZIPFileName.empty() ? readFileFromZIP(fullFileName, ZIPFileName) : readFile(fullFileName); + + if (fileArr.empty()) { + throw std::runtime_error("Could not read file data into memory"); + } + + // , + return CreateTextureDataFromPng(fileArr); + } + + +#endif + + } \ No newline at end of file diff --git a/TextureManager.h b/src/render/TextureManager.h old mode 100755 new mode 100644 similarity index 92% rename from TextureManager.h rename to src/render/TextureManager.h index be3c7e1..2386b2e --- a/TextureManager.h +++ b/src/render/TextureManager.h @@ -1,56 +1,56 @@ -#pragma once - -#include "OpenGlExtensions.h" -#include "Utils.h" - -#ifdef EMSCRIPTEN -#define PNG_ENABLED -#endif - -namespace ZL -{ - - struct TextureDataStruct - { - size_t width; - size_t height; - std::vector data; - enum BitSize { - BS_24BIT, - BS_32BIT - }; - - BitSize bitSize; - }; - - class Texture - { - size_t width = 0; - size_t height = 0; - GLuint texID = 0; - - public: - - Texture(const TextureDataStruct& texData); - - //Cubemap texture: - Texture(const std::array& texDataArray); - - ~Texture(); - - GLuint getTexID(); - - size_t getWidth(); - size_t getHeight(); - - - }; - - TextureDataStruct CreateTextureDataFromBmp24(const std::string& fullFileName, const std::string& ZIPFileName=""); - TextureDataStruct CreateTextureDataFromBmp32(const std::string& fullFileName, const std::string& ZIPFileName=""); -#ifdef PNG_ENABLED - TextureDataStruct CreateTextureDataFromPng(const std::string& fullFileName, const std::string& ZIPFileName = ""); -#endif - - -} +#pragma once + +#include "OpenGlExtensions.h" +#include "utils/Utils.h" + +#ifdef EMSCRIPTEN +#define PNG_ENABLED +#endif + +namespace ZL +{ + + struct TextureDataStruct + { + size_t width; + size_t height; + std::vector data; + enum BitSize { + BS_24BIT, + BS_32BIT + }; + + BitSize bitSize; + }; + + class Texture + { + size_t width = 0; + size_t height = 0; + GLuint texID = 0; + + public: + + Texture(const TextureDataStruct& texData); + + //Cubemap texture: + Texture(const std::array& texDataArray); + + ~Texture(); + + GLuint getTexID(); + + size_t getWidth(); + size_t getHeight(); + + + }; + + TextureDataStruct CreateTextureDataFromBmp24(const std::string& fullFileName, const std::string& ZIPFileName=""); + TextureDataStruct CreateTextureDataFromBmp32(const std::string& fullFileName, const std::string& ZIPFileName=""); +#ifdef PNG_ENABLED + TextureDataStruct CreateTextureDataFromPng(const std::string& fullFileName, const std::string& ZIPFileName = ""); +#endif + + +} diff --git a/Perlin.cpp b/src/utils/Perlin.cpp similarity index 100% rename from Perlin.cpp rename to src/utils/Perlin.cpp diff --git a/Perlin.h b/src/utils/Perlin.h similarity index 91% rename from Perlin.h rename to src/utils/Perlin.h index cc07273..dbd76e6 100644 --- a/Perlin.h +++ b/src/utils/Perlin.h @@ -2,7 +2,7 @@ #include #include -#include "ZLMath.h" +#include "utils/ZLMath.h" namespace ZL { diff --git a/Utils.cpp b/src/utils/Utils.cpp old mode 100755 new mode 100644 similarity index 94% rename from Utils.cpp rename to src/utils/Utils.cpp index a7adef2..bfc09c2 --- a/Utils.cpp +++ b/src/utils/Utils.cpp @@ -1,105 +1,105 @@ -#include "Utils.h" -#include -#include -#include -#include -#include -#include -#ifdef EMSCRIPTEN -#include -#endif - -namespace ZL -{ - - std::string readTextFile(const std::string& filename) - { - std::ifstream f(filename); - - std::string str((std::istreambuf_iterator(f)), std::istreambuf_iterator()); - - return str; - } - - std::vector readFile(const std::string& filename) - { - std::ifstream file(filename, std::ios::binary); - - file.unsetf(std::ios::skipws); - - std::streampos fileSize; - - file.seekg(0, std::ios::end); - fileSize = file.tellg(); - file.seekg(0, std::ios::beg); - - std::vector vec; - vec.reserve(fileSize); - - vec.insert(vec.begin(), - std::istream_iterator(file), - std::istream_iterator()); - - return vec; - } - - std::vector readFileFromZIP(const std::string& filename, const std::string& zipfilename) { -#ifdef EMSCRIPTEN - const std::string zipPath = zipfilename; - int zipErr; - zip_t* archive = zip_open(zipPath.c_str(), ZIP_RDONLY, &zipErr); - if (!archive) { - throw std::runtime_error("Ошибка открытия ZIP: " + zipPath); - } - - std::string cleanFilename = filename; - if (cleanFilename.rfind("./", 0) == 0) { - cleanFilename = cleanFilename.substr(2); - } - - std::cout << "Ищем в ZIP: " << cleanFilename << std::endl; - - zip_file_t* zipFile = zip_fopen(archive, cleanFilename.c_str(), 0); - if (!zipFile) { - zip_close(archive); - throw std::runtime_error("Файл не найден в ZIP: " + cleanFilename); - } - - zip_stat_t fileStat; - if (zip_stat(archive, cleanFilename.c_str(), 0, &fileStat) != 0) { - zip_fclose(zipFile); - zip_close(archive); - throw std::runtime_error("Ошибка чтения ZIP-статистики."); - } - - std::vector fileData; - fileData.resize(fileStat.size); - - zip_fread(zipFile, fileData.data(), fileData.size()); - - zip_fclose(zipFile); - zip_close(archive); - - return fileData; -#else - return {}; -#endif - } - - bool findString(const char* in, char* list) - { - size_t thisLength = strlen(in); - while (*list != 0) - { - size_t length = strcspn(list, " "); - - if (thisLength == length) - if (!strncmp(in, list, length)) - return true; - - list += length; - list += 1; - } - return false; - } -}; +#include "utils/Utils.h" +#include +#include +#include +#include +#include +#include +#ifdef EMSCRIPTEN +#include +#endif + +namespace ZL +{ + + std::string readTextFile(const std::string& filename) + { + std::ifstream f(filename); + + std::string str((std::istreambuf_iterator(f)), std::istreambuf_iterator()); + + return str; + } + + std::vector readFile(const std::string& filename) + { + std::ifstream file(filename, std::ios::binary); + + file.unsetf(std::ios::skipws); + + std::streampos fileSize; + + file.seekg(0, std::ios::end); + fileSize = file.tellg(); + file.seekg(0, std::ios::beg); + + std::vector vec; + vec.reserve(fileSize); + + vec.insert(vec.begin(), + std::istream_iterator(file), + std::istream_iterator()); + + return vec; + } + + std::vector readFileFromZIP(const std::string& filename, const std::string& zipfilename) { +#ifdef EMSCRIPTEN + const std::string zipPath = zipfilename; + int zipErr; + zip_t* archive = zip_open(zipPath.c_str(), ZIP_RDONLY, &zipErr); + if (!archive) { + throw std::runtime_error("Ошибка открытия ZIP: " + zipPath); + } + + std::string cleanFilename = filename; + if (cleanFilename.rfind("./", 0) == 0) { + cleanFilename = cleanFilename.substr(2); + } + + std::cout << "Ищем в ZIP: " << cleanFilename << std::endl; + + zip_file_t* zipFile = zip_fopen(archive, cleanFilename.c_str(), 0); + if (!zipFile) { + zip_close(archive); + throw std::runtime_error("Файл не найден в ZIP: " + cleanFilename); + } + + zip_stat_t fileStat; + if (zip_stat(archive, cleanFilename.c_str(), 0, &fileStat) != 0) { + zip_fclose(zipFile); + zip_close(archive); + throw std::runtime_error("Ошибка чтения ZIP-статистики."); + } + + std::vector fileData; + fileData.resize(fileStat.size); + + zip_fread(zipFile, fileData.data(), fileData.size()); + + zip_fclose(zipFile); + zip_close(archive); + + return fileData; +#else + return {}; +#endif + } + + bool findString(const char* in, char* list) + { + size_t thisLength = strlen(in); + while (*list != 0) + { + size_t length = strcspn(list, " "); + + if (thisLength == length) + if (!strncmp(in, list, length)) + return true; + + list += length; + list += 1; + } + return false; + } +}; diff --git a/Utils.h b/src/utils/Utils.h old mode 100755 new mode 100644 similarity index 95% rename from Utils.h rename to src/utils/Utils.h index 89960a7..ced39aa --- a/Utils.h +++ b/src/utils/Utils.h @@ -1,20 +1,20 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -namespace ZL -{ - std::string readTextFile(const std::string& filename); - - std::vector readFile(const std::string& filename); - - std::vector readFileFromZIP(const std::string& filename, const std::string& zipfilename); - - bool findString(const char* in, char* list); - +#pragma once + +#include +#include +#include +#include +#include +#include +#include +namespace ZL +{ + std::string readTextFile(const std::string& filename); + + std::vector readFile(const std::string& filename); + + std::vector readFileFromZIP(const std::string& filename, const std::string& zipfilename); + + bool findString(const char* in, char* list); + } \ No newline at end of file diff --git a/ZLMath.cpp b/src/utils/ZLMath.cpp similarity index 99% rename from ZLMath.cpp rename to src/utils/ZLMath.cpp index 954b783..01bf58d 100644 --- a/ZLMath.cpp +++ b/src/utils/ZLMath.cpp @@ -1,4 +1,4 @@ -#include "ZLMath.h" +#include "utils/ZLMath.h" #include #include diff --git a/ZLMath.h b/src/utils/ZLMath.h old mode 100755 new mode 100644 similarity index 95% rename from ZLMath.h rename to src/utils/ZLMath.h index 07caa84..b065087 --- a/ZLMath.h +++ b/src/utils/ZLMath.h @@ -1,179 +1,179 @@ -#pragma once - -#include -#include -#include -#include - -namespace ZL { - - struct Vector4f - { - std::array v = { 0.f, 0.f, 0.f, 0.f }; - - Vector4f normalized() const { - double norm = std::sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3]); - if (norm <= 0.000001f) { - return { 0,0, 0, 0}; - } - Vector4f r; - - r.v[0] = v[0] / norm; - r.v[1] = v[1] / norm; - r.v[2] = v[2] / norm; - r.v[3] = v[3] / norm; - - return r; - } - - double dot(const Vector4f& other) const { - return v[0] * other.v[0] + v[1] * other.v[1] + v[2] * other.v[2] + v[3] * other.v[3]; - } - }; - - struct Vector3f - { - std::array v = { 0.f, 0.f, 0.f }; - - Vector3f() - { - } - - Vector3f(float x, float y, float z) - : v{x,y,z} - { - } - - Vector3f normalized() const { - double norm = std::sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); - if (norm <= 0.000001f) { - return { 0,0,0 }; - } - Vector3f r; - - r.v[0] = v[0] / norm; - r.v[1] = v[1] / norm; - r.v[2] = v[2] / norm; - - return r; - } - - float squaredNorm() const { - return v[0] * v[0] + v[1] * v[1] + v[2] * v[2]; - } - - float length() const - { - return sqrt(squaredNorm()); - } - - float dot(const Vector3f& other) const { - return v[0] * other.v[0] + v[1] * other.v[1] + v[2] * other.v[2]; - } - - Vector3f cross(const Vector3f& other) const { - return Vector3f( - v[1] * other.v[2] - v[2] * other.v[1], - v[2] * other.v[0] - v[0] * other.v[2], - v[0] * other.v[1] - v[1] * other.v[0] - ); - } - - bool operator<(const Vector3f& other) const { - if (v[0] != other.v[0]) return v[0] < other.v[0]; - if (v[1] != other.v[1]) return v[1] < other.v[1]; - return v[2] < other.v[2]; - } - }; - - - - struct Vector2f - { - std::array v = {0.f, 0.f}; - - Vector2f() - { - } - - Vector2f(float x, float y) - : v{ x,y } - { - } - }; - - Vector2f operator+(const Vector2f& x, const Vector2f& y); - - Vector2f operator-(const Vector2f& x, const Vector2f& y); - - Vector3f operator+(const Vector3f& x, const Vector3f& y); - - Vector3f operator-(const Vector3f& x, const Vector3f& y); - Vector4f operator+(const Vector4f& x, const Vector4f& y); - - Vector4f operator-(const Vector4f& x, const Vector4f& y); - - Vector3f operator-(const Vector3f& x); - - - struct Matrix3f - { - std::array m = { 0.f, 0.f, 0.f, - 0.f, 0.f, 0.f, - 0.f, 0.f, 0.f, }; - - static Matrix3f Identity(); - }; - - struct Matrix4f - { - std::array m = { 0.f, 0.f, 0.f, 0.f, - 0.f, 0.f, 0.f, 0.f, - 0.f, 0.f, 0.f, 0.f, - 0.f, 0.f, 0.f, 0.f }; - - static Matrix4f Identity(); - - float& operator()(int row, int col) { - //return m[row * 4 + col]; //OpenGL specific - return m[col * 4 + row]; - } - - const float& operator()(int row, int col) const { - //return m[row * 4 + col]; - return m[col * 4 + row]; - } - }; - - Matrix4f operator*(const Matrix4f& m1, const Matrix4f& m2); - - Matrix4f MakeOrthoMatrix(float width, float height, float zNear, float zFar); - Matrix4f MakeOrthoMatrix(float xmin, float xmax, float ymin, float ymax, float zNear, float zFar); - - Matrix4f MakePerspectiveMatrix(float fovY, float aspectRatio, float zNear, float zFar); - - Matrix3f QuatToMatrix(const Vector4f& q); - - Vector4f MatrixToQuat(const Matrix3f& m); - - Vector4f QuatFromRotateAroundX(float angle); - Vector4f QuatFromRotateAroundY(float angle); - Vector4f QuatFromRotateAroundZ(float angle); - - Vector2f operator*(Vector2f v, float scale); - Vector3f operator*(Vector3f v, float scale); - Vector4f operator*(Vector4f v, float scale); - - Vector3f MultVectorMatrix(Vector3f v, Matrix3f mt); - Vector4f MultVectorMatrix(Vector4f v, Matrix4f mt); - Vector4f MultMatrixVector(Matrix4f mt, Vector4f v); - Vector3f MultMatrixVector(Matrix3f mt, Vector3f v); - - Vector4f slerp(const Vector4f& q1, const Vector4f& q2, float t); - Matrix3f InverseMatrix(const Matrix3f& m); - Matrix4f InverseMatrix(const Matrix4f& m); - Matrix3f MultMatrixMatrix(const Matrix3f& m1, const Matrix3f& m2); - Matrix4f MultMatrixMatrix(const Matrix4f& m1, const Matrix4f& m2); - Matrix4f MakeMatrix4x4(const Matrix3f& m, const Vector3f pos); - -}; +#pragma once + +#include +#include +#include +#include + +namespace ZL { + + struct Vector4f + { + std::array v = { 0.f, 0.f, 0.f, 0.f }; + + Vector4f normalized() const { + double norm = std::sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3]); + if (norm <= 0.000001f) { + return { 0,0, 0, 0}; + } + Vector4f r; + + r.v[0] = v[0] / norm; + r.v[1] = v[1] / norm; + r.v[2] = v[2] / norm; + r.v[3] = v[3] / norm; + + return r; + } + + double dot(const Vector4f& other) const { + return v[0] * other.v[0] + v[1] * other.v[1] + v[2] * other.v[2] + v[3] * other.v[3]; + } + }; + + struct Vector3f + { + std::array v = { 0.f, 0.f, 0.f }; + + Vector3f() + { + } + + Vector3f(float x, float y, float z) + : v{x,y,z} + { + } + + Vector3f normalized() const { + double norm = std::sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); + if (norm <= 0.000001f) { + return { 0,0,0 }; + } + Vector3f r; + + r.v[0] = v[0] / norm; + r.v[1] = v[1] / norm; + r.v[2] = v[2] / norm; + + return r; + } + + float squaredNorm() const { + return v[0] * v[0] + v[1] * v[1] + v[2] * v[2]; + } + + float length() const + { + return sqrt(squaredNorm()); + } + + float dot(const Vector3f& other) const { + return v[0] * other.v[0] + v[1] * other.v[1] + v[2] * other.v[2]; + } + + Vector3f cross(const Vector3f& other) const { + return Vector3f( + v[1] * other.v[2] - v[2] * other.v[1], + v[2] * other.v[0] - v[0] * other.v[2], + v[0] * other.v[1] - v[1] * other.v[0] + ); + } + + bool operator<(const Vector3f& other) const { + if (v[0] != other.v[0]) return v[0] < other.v[0]; + if (v[1] != other.v[1]) return v[1] < other.v[1]; + return v[2] < other.v[2]; + } + }; + + + + struct Vector2f + { + std::array v = {0.f, 0.f}; + + Vector2f() + { + } + + Vector2f(float x, float y) + : v{ x,y } + { + } + }; + + Vector2f operator+(const Vector2f& x, const Vector2f& y); + + Vector2f operator-(const Vector2f& x, const Vector2f& y); + + Vector3f operator+(const Vector3f& x, const Vector3f& y); + + Vector3f operator-(const Vector3f& x, const Vector3f& y); + Vector4f operator+(const Vector4f& x, const Vector4f& y); + + Vector4f operator-(const Vector4f& x, const Vector4f& y); + + Vector3f operator-(const Vector3f& x); + + + struct Matrix3f + { + std::array m = { 0.f, 0.f, 0.f, + 0.f, 0.f, 0.f, + 0.f, 0.f, 0.f, }; + + static Matrix3f Identity(); + }; + + struct Matrix4f + { + std::array m = { 0.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 0.f }; + + static Matrix4f Identity(); + + float& operator()(int row, int col) { + //return m[row * 4 + col]; //OpenGL specific + return m[col * 4 + row]; + } + + const float& operator()(int row, int col) const { + //return m[row * 4 + col]; + return m[col * 4 + row]; + } + }; + + Matrix4f operator*(const Matrix4f& m1, const Matrix4f& m2); + + Matrix4f MakeOrthoMatrix(float width, float height, float zNear, float zFar); + Matrix4f MakeOrthoMatrix(float xmin, float xmax, float ymin, float ymax, float zNear, float zFar); + + Matrix4f MakePerspectiveMatrix(float fovY, float aspectRatio, float zNear, float zFar); + + Matrix3f QuatToMatrix(const Vector4f& q); + + Vector4f MatrixToQuat(const Matrix3f& m); + + Vector4f QuatFromRotateAroundX(float angle); + Vector4f QuatFromRotateAroundY(float angle); + Vector4f QuatFromRotateAroundZ(float angle); + + Vector2f operator*(Vector2f v, float scale); + Vector3f operator*(Vector3f v, float scale); + Vector4f operator*(Vector4f v, float scale); + + Vector3f MultVectorMatrix(Vector3f v, Matrix3f mt); + Vector4f MultVectorMatrix(Vector4f v, Matrix4f mt); + Vector4f MultMatrixVector(Matrix4f mt, Vector4f v); + Vector3f MultMatrixVector(Matrix3f mt, Vector3f v); + + Vector4f slerp(const Vector4f& q1, const Vector4f& q2, float t); + Matrix3f InverseMatrix(const Matrix3f& m); + Matrix4f InverseMatrix(const Matrix4f& m); + Matrix3f MultMatrixMatrix(const Matrix3f& m1, const Matrix3f& m2); + Matrix4f MultMatrixMatrix(const Matrix4f& m1, const Matrix4f& m2); + Matrix4f MakeMatrix4x4(const Matrix3f& m, const Vector3f pos); + +};