From 88bc764f08c3919f5c4e1caec553fc0f6602d460 Mon Sep 17 00:00:00 2001 From: Vladislav Khorev Date: Sun, 7 Dec 2025 19:14:33 +0300 Subject: [PATCH] Working --- Environment.cpp | 6 +- Environment.h | 4 + Game.cpp | 207 ++++++++++++++++++++++++++++++++++++++---- Game.h | 18 ++++ Math.cpp | 12 +++ Math.h | 20 ++++ resources/box/box.png | 3 + resources/box/box.txt | 29 ++++++ 8 files changed, 281 insertions(+), 18 deletions(-) create mode 100644 resources/box/box.png create mode 100644 resources/box/box.txt diff --git a/Environment.cpp b/Environment.cpp index 1acc505..342edc6 100644 --- a/Environment.cpp +++ b/Environment.cpp @@ -24,12 +24,16 @@ bool Environment::showMouse = false; bool Environment::exitGameLoop = false; Matrix3f Environment::shipMatrix = Matrix3f::Identity(); - +Matrix3f Environment::inverseShipMatrix = Matrix3f::Identity(); bool Environment::tapDownHold = false; Vector2f Environment::tapDownStartPos = { 0, 0 }; Vector2f Environment::tapDownCurrentPos = { 0, 0 }; +Vector3f Environment::shipPosition = {0,0,0}; + +float Environment::shipVelocity = 0.f; + } // namespace ZL diff --git a/Environment.h b/Environment.h index df76590..32ae87c 100644 --- a/Environment.h +++ b/Environment.h @@ -22,6 +22,7 @@ public: static bool settings_inverseVertical; static Matrix3f shipMatrix; + static Matrix3f inverseShipMatrix; static SDL_Window* window; @@ -33,6 +34,9 @@ public: static Vector2f tapDownStartPos; static Vector2f tapDownCurrentPos; + static Vector3f shipPosition; + static float shipVelocity; + }; diff --git a/Game.cpp b/Game.cpp index 700fe85..666dc00 100755 --- a/Game.cpp +++ b/Game.cpp @@ -6,6 +6,8 @@ #include #include "TextureManager.h" #include "TextModel.h" +#include +#include namespace ZL { @@ -14,6 +16,84 @@ namespace ZL #else const char* CONST_ZIP_FILE = ""; #endif + + + // --- Основная функция генерации --- + 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; + boxCoordsArr.reserve(N); // Резервируем память + + // 1. Инициализация генератора псевдослучайных чисел + // Используем Mersenne Twister (mt19937) как высококачественный генератор + std::random_device rd; + std::mt19937 gen(rd()); + + // 2. Определение равномерного распределения для координат [MIN_COORD, MAX_COORD] + 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) + { + // Координаты подходят, добавляем объект + boxCoordsArr.emplace_back(BoxCoords{ newPos, Matrix3f::Identity() }); + generatedCount++; + } + attempts++; + } + + // Если превышено максимальное количество попыток, выходим из цикла, + // чтобы избежать зависания, если N слишком велико или диапазон слишком мал. + if (!accepted) { + std::cerr << "Предупреждение: Не удалось сгенерировать " << N << " объектов. Сгенерировано: " << generatedCount << std::endl; + break; + } + } + + return boxCoordsArr; + } + Game::Game() : window(nullptr) , glContext(nullptr) @@ -70,31 +150,38 @@ void Game::setup() { spaceshipTexture = std::make_unique(CreateTextureDataFromPng("./resources/DefaultMaterial_BaseColor.png", CONST_ZIP_FILE)); spaceshipBase = LoadFromTextFile02("./resources/spaceship005.txt", CONST_ZIP_FILE); spaceshipBase.RotateByMatrix(QuatToMatrix(QuatFromRotateAroundY(M_PI / 2.0))); - spaceshipBase.Move(Vector3f{ -0.52998, -13, 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].RefreshVBO(); + } + renderer.InitOpenGL(); } -void Game::drawScene() { +void Game::drawCubemap() +{ 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, 0.5f, 1.0f, 1.0f); - glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - - glViewport(0, 0, Environment::width, Environment::height); - - CheckGlError(); - renderer.shaderManager.PushShader(envShaderName); renderer.RenderUniform1i(textureUniformName, 0); renderer.EnableVertexAttribArray(vPositionName); @@ -103,7 +190,7 @@ void Game::drawScene() { 1, 1000); renderer.PushMatrix(); renderer.LoadIdentity(); - renderer.RotateMatrix(Environment::shipMatrix); + renderer.RotateMatrix(Environment::inverseShipMatrix); CheckGlError(); @@ -119,8 +206,15 @@ void Game::drawScene() { 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); @@ -132,7 +226,6 @@ void Game::drawScene() { renderer.PushMatrix(); renderer.LoadIdentity(); - //renderer.RotateMatrix(Environment::shipMatrix); renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom }); @@ -145,6 +238,66 @@ void Game::drawScene() { 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), + 1, 1000); + + 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(boxCoordsArr[i].pos); + + glBindTexture(GL_TEXTURE_2D, boxTexture->getTexID()); + renderer.DrawVertexRenderStruct(boxRenderArr[i]); + + renderer.PopMatrix(); + } + renderer.PopProjectionMatrix(); + renderer.DisableVertexAttribArray(vPositionName); + renderer.DisableVertexAttribArray(vTexCoordName); + + 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, 0.5f, 1.0f, 1.0f); + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + + glViewport(0, 0, Environment::width, Environment::height); + + CheckGlError(); + + drawCubemap(); + drawShip(); + drawBoxes(); CheckGlError(); } @@ -174,11 +327,11 @@ void Game::processTickCount() { float rotationPower = sqrtf(diffx * diffx + diffy * diffy); - std::cout << rotationPower << std::endl; + //std::cout << rotationPower << std::endl; float deltaAlpha = rotationPower * delta * M_PI / 500000.f; - Vector3f rotationDirection = { -diffy, -diffx, 0 }; + Vector3f rotationDirection = { diffy, diffx, 0 }; rotationDirection = rotationDirection.normalized(); @@ -190,11 +343,20 @@ void Game::processTickCount() { Matrix3f rotateMat = QuatToMatrix(rotateQuat); - Environment::shipMatrix = MultMatrixMatrix(rotateMat, Environment::shipMatrix); + 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; + } + lastTickCount = newTickCount; } } @@ -252,6 +414,17 @@ void Game::update() { Environment::zoom = zoomstep; } } + else if (event.type == SDL_KEYUP) + { + if (event.key.keysym.sym == SDLK_i) + { + Environment::shipVelocity += 1.f; + } + if (event.key.keysym.sym == SDLK_k) + { + Environment::shipVelocity -= 1.f; + } + } } render(); } diff --git a/Game.h b/Game.h index c157bbf..b97d62e 100755 --- a/Game.h +++ b/Game.h @@ -7,6 +7,14 @@ namespace ZL { + + struct BoxCoords + { + Vector3f pos; + Matrix3f m; + }; + + class Game { public: Game(); @@ -21,6 +29,9 @@ public: private: void processTickCount(); void drawScene(); + void drawCubemap(); + void drawShip(); + void drawBoxes(); SDL_Window* window; SDL_GLContext glContext; @@ -38,6 +49,13 @@ private: VertexRenderStruct spaceship; VertexRenderStruct cubemap; + + std::shared_ptr boxTexture; + VertexDataStruct boxBase; + + std::vector boxCoordsArr; + std::vector boxRenderArr; + }; } // namespace ZL \ No newline at end of file diff --git a/Math.cpp b/Math.cpp index 8bb5c31..ca7662e 100755 --- a/Math.cpp +++ b/Math.cpp @@ -45,6 +45,16 @@ namespace ZL { return result; } + Vector3f operator-(const Vector3f& x) + { + Vector3f result; + + result.v[0] = -x.v[0]; + result.v[1] = -x.v[1]; + result.v[2] = -x.v[2]; + return result; + } + Vector4f operator+(const Vector4f& x, const Vector4f& y) { Vector4f result; @@ -67,6 +77,8 @@ namespace ZL { return result; } + + Matrix3f Matrix3f::Identity() { Matrix3f r; diff --git a/Math.h b/Math.h index 182c4a3..750a113 100755 --- a/Math.h +++ b/Math.h @@ -32,6 +32,15 @@ namespace ZL { { 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]); Vector3f r; @@ -42,6 +51,15 @@ namespace ZL { return r; } + + float squaredNorm() const { + return v[0] * v[0] + v[1] * v[1] + v[2] * v[2]; + } + + // Оператор вычитания + /*Vector3f operator-(const Vector3f& other) const { + return Vector3f(v[0] - other.v[0], v[1] - other.v[1], v[2] - other.v[2]); + }*/ }; @@ -62,6 +80,8 @@ namespace ZL { Vector4f operator-(const Vector4f& x, const Vector4f& y); + Vector3f operator-(const Vector3f& x); + struct Matrix3f { diff --git a/resources/box/box.png b/resources/box/box.png new file mode 100644 index 0000000..bab8183 --- /dev/null +++ b/resources/box/box.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6d72908f468ba5f8247e22281bd8c698db8dbaec2decf6246bb34a2dab36b48c +size 598250 diff --git a/resources/box/box.txt b/resources/box/box.txt new file mode 100644 index 0000000..bb703eb --- /dev/null +++ b/resources/box/box.txt @@ -0,0 +1,29 @@ +===Vertices (Split by UV/Normal): 14 +V 0: Pos(1.0, 1.0, 1.0) Norm(0.57735, 0.57735, 0.57735) UV(0.5, 0.5) +V 1: Pos(-1.0, 1.0, 1.0) Norm(-0.57735, 0.57735, 0.57735) UV(0.75, 0.5) +V 2: Pos(-1.0, -1.0, 1.0) Norm(-0.57735, -0.57735, 0.57735) UV(0.75, 0.75) +V 3: Pos(1.0, -1.0, 1.0) Norm(0.57735, -0.57735, 0.57735) UV(0.5, 0.75) +V 4: Pos(1.0, -1.0, -1.0) Norm(0.57735, -0.57735, -0.57735) UV(0.25, 0.75) +V 5: Pos(-1.0, -1.0, 1.0) Norm(-0.57735, -0.57735, 0.57735) UV(0.5, 1.0) +V 6: Pos(-1.0, -1.0, -1.0) Norm(-0.57735, -0.57735, -0.57735) UV(0.25, 1.0) +V 7: Pos(-1.0, -1.0, -1.0) Norm(-0.57735, -0.57735, -0.57735) UV(0.25, 0.0) +V 8: Pos(-1.0, -1.0, 1.0) Norm(-0.57735, -0.57735, 0.57735) UV(0.5, 0.0) +V 9: Pos(-1.0, 1.0, 1.0) Norm(-0.57735, 0.57735, 0.57735) UV(0.5, 0.25) +V 10: Pos(-1.0, 1.0, -1.0) Norm(-0.57735, 0.57735, -0.57735) UV(0.25, 0.25) +V 11: Pos(-1.0, 1.0, -1.0) Norm(-0.57735, 0.57735, -0.57735) UV(0.0, 0.5) +V 12: Pos(1.0, 1.0, -1.0) Norm(0.57735, 0.57735, -0.57735) UV(0.25, 0.5) +V 13: Pos(-1.0, -1.0, -1.0) Norm(-0.57735, -0.57735, -0.57735) UV(0.0, 0.75) + +===Triangles (Indices): 12 +Tri: 0 1 2 +Tri: 0 2 3 +Tri: 4 3 5 +Tri: 4 5 6 +Tri: 7 8 9 +Tri: 7 9 10 +Tri: 11 12 4 +Tri: 11 4 13 +Tri: 12 0 3 +Tri: 12 3 4 +Tri: 10 9 0 +Tri: 10 0 12