From 068c319890c2b9aa08ccd268d274adcbdd023b82 Mon Sep 17 00:00:00 2001 From: Vlad Date: Fri, 19 Dec 2025 17:35:34 +0600 Subject: [PATCH] add ui.json and del default values from SparkEmitter --- CMakeLists.txt | 2 + Game.cpp | 29 +++-- Game.h | 2 + SparkEmitter.cpp | 119 ++++++++++++++----- SparkEmitter.h | 1 + UiManager.cpp | 249 +++++++++++++++++++++++++++++++++++++++ UiManager.h | 83 +++++++++++++ config/spark_config.json | 4 +- config/ui.json | 72 +++++++++++ shaders/spark.fragment | 16 ++- shaders/spark.vertex | 13 +- 11 files changed, 540 insertions(+), 50 deletions(-) create mode 100644 UiManager.cpp create mode 100644 UiManager.h create mode 100644 config/ui.json diff --git a/CMakeLists.txt b/CMakeLists.txt index 819c8b6..f44b693 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -440,6 +440,8 @@ add_executable(space-game001 SparkEmitter.h PlanetObject.cpp PlanetObject.h + UiManager.cpp + UiManager.h ) # Установка проекта по умолчанию для Visual Studio diff --git a/Game.cpp b/Game.cpp index 08330e8..cb53b47 100755 --- a/Game.cpp +++ b/Game.cpp @@ -163,6 +163,7 @@ namespace ZL #endif bool cfgLoaded = sparkEmitter.loadFromJsonFile("../config/spark_config.json", renderer, CONST_ZIP_FILE); + uiManager.loadFromFile("../config/ui.json", renderer, CONST_ZIP_FILE); cubemapTexture = std::make_shared( std::array{ @@ -208,7 +209,7 @@ namespace ZL } - buttonTexture = std::make_unique(CreateTextureDataFromPng("./resources/button.png", CONST_ZIP_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 }); @@ -224,7 +225,7 @@ namespace ZL button.data.TexCoordData.push_back({ 1,1 }); button.data.TexCoordData.push_back({ 1,0 }); - button.RefreshVBO(); + button.RefreshVBO();*/ musicVolumeBarTexture = std::make_unique(CreateTextureDataFromPng("./resources/musicVolumeBarTexture.png", CONST_ZIP_FILE)); @@ -436,9 +437,8 @@ namespace ZL renderer.LoadIdentity(); - - glBindTexture(GL_TEXTURE_2D, buttonTexture->getTexID()); - renderer.DrawVertexRenderStruct(button); + //glBindTexture(GL_TEXTURE_2D, buttonTexture->getTexID()); + //renderer.DrawVertexRenderStruct(button); glBindTexture(GL_TEXTURE_2D, musicVolumeBarTexture->getTexID()); renderer.DrawVertexRenderStruct(musicVolumeBar); @@ -450,7 +450,7 @@ namespace ZL renderer.PopProjectionMatrix(); renderer.DisableVertexAttribArray(vPositionName); renderer.DisableVertexAttribArray(vTexCoordName); - + uiManager.draw(renderer); renderer.shaderManager.PopShader(); CheckGlError(); } @@ -518,7 +518,6 @@ namespace ZL 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 { @@ -586,6 +585,10 @@ namespace ZL std::cout << mx << " " << my << '\n'; int uiX = mx; int uiY = Environment::height - my; + + uiManager.onMouseMove(uiX, uiY); + uiManager.onMouseDown(uiX, uiY); + if (uiX >= volumeBarMinX - 40 && uiX <= volumeBarMaxX + 40 && uiY >= volumeBarMinY - 40 && uiY <= volumeBarMaxY + 40) { isDraggingVolume = true; @@ -604,6 +607,13 @@ namespace ZL } 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); + isDraggingVolume = false; Environment::tapDownHold = false; } @@ -612,6 +622,11 @@ namespace ZL int mx = event.motion.x; int my = event.motion.y; + int uiX = mx; + int uiY = Environment::height - my; + + uiManager.onMouseMove(uiX, uiY); + if (isDraggingVolume) { // Äâèãàåì ìûøü ïî ñëàéäåðó — ìåíÿåì ãðîìêîñòü è ïîçèöèþ êðóæêà UpdateVolumeFromMouse(mx, my); diff --git a/Game.h b/Game.h index 987e3e1..5308799 100755 --- a/Game.h +++ b/Game.h @@ -6,6 +6,7 @@ #include "TextureManager.h" #include "SparkEmitter.h" #include "PlanetObject.h" +#include "UiManager.h" namespace ZL { @@ -86,6 +87,7 @@ namespace ZL { SparkEmitter sparkEmitter; PlanetObject planetObject; + UiManager uiManager; }; diff --git a/SparkEmitter.cpp b/SparkEmitter.cpp index ef5ed3e..1460c43 100644 --- a/SparkEmitter.cpp +++ b/SparkEmitter.cpp @@ -6,6 +6,7 @@ #include "external/nlohmann/json.hpp" #include #include "Environment.h" +#include namespace ZL { @@ -13,7 +14,7 @@ namespace ZL { SparkEmitter::SparkEmitter() : emissionRate(100.0f), isActive(true), drawDataDirty(true), maxParticles(200), - shaderProgramName("default"), particleSize(0.04f), biasX(0.3f) { + shaderProgramName("default"), particleSize(0.04f), biasX(0.3f), configured(false) { particles.resize(maxParticles); drawPositions.reserve(maxParticles * 6); drawTexCoords.reserve(maxParticles * 6); @@ -25,7 +26,7 @@ namespace ZL { SparkEmitter::SparkEmitter(const std::vector& positions, float rate) : emissionPoints(positions), emissionRate(rate), isActive(true), drawDataDirty(true), maxParticles(positions.size() * 100), - shaderProgramName("default"), particleSize(0.04f), biasX(0.3f) { + shaderProgramName("default"), particleSize(0.04f), biasX(0.3f), configured(false) { particles.resize(maxParticles); drawPositions.reserve(maxParticles * 6); drawTexCoords.reserve(maxParticles * 6); @@ -39,7 +40,7 @@ namespace ZL { float rate) : emissionPoints(positions), texture(tex), emissionRate(rate), isActive(true), drawDataDirty(true), maxParticles(positions.size() * 100), - shaderProgramName("default"), particleSize(0.04f), biasX(0.3f) { + shaderProgramName("default"), particleSize(0.04f), biasX(0.3f), configured(false) { particles.resize(maxParticles); drawPositions.reserve(maxParticles * 6); drawTexCoords.reserve(maxParticles * 6); @@ -105,12 +106,16 @@ namespace ZL { } void SparkEmitter::draw(Renderer& renderer, float zoom, int screenWidth, int screenHeight) { + if (!configured) { + throw std::runtime_error("Failed to load spark emitter config file!"); + } + if (getActiveParticleCount() == 0) { return; } if (!texture) { - return; + throw std::runtime_error("Failed to load spark emitter config file!"); } prepareDrawData(); @@ -157,6 +162,10 @@ namespace ZL { } void SparkEmitter::update(float deltaTimeMs) { + if (!configured) { + throw std::runtime_error("Failed to load spark emitter config file!"); + } + auto currentTime = std::chrono::steady_clock::now(); auto elapsed = std::chrono::duration_cast( currentTime - lastEmissionTime).count(); @@ -203,6 +212,10 @@ namespace ZL { } void SparkEmitter::emit() { + if (!configured) { + throw std::runtime_error("Failed to load spark emitter config file!"); + } + if (emissionPoints.empty()) return; bool emitted = false; @@ -253,6 +266,10 @@ namespace ZL { } void SparkEmitter::initParticle(SparkParticle& particle, int emitterIndex) { + if (!configured) { + throw std::runtime_error("Failed to load spark emitter config file!"); + } + particle.velocity = getRandomVelocity(emitterIndex); static std::random_device rd; static std::mt19937 gen(rd()); @@ -265,6 +282,10 @@ namespace ZL { } Vector3f SparkEmitter::getRandomVelocity(int emitterIndex) { + if (!configured) { + throw std::runtime_error("Failed to load spark emitter config file!"); + } + static std::random_device rd; static std::mt19937 gen(rd()); std::uniform_real_distribution angleDist(0.0f, 2.0f * static_cast(M_PI)); @@ -311,7 +332,7 @@ namespace ZL { std::ifstream in(path); if (!in.is_open()) { std::cerr << "Failed to open JSON file: " << path << std::endl; - return false; + throw std::runtime_error("Failed to load spark emitter config file!"); } json j; @@ -321,32 +342,42 @@ namespace ZL { } catch (const std::exception& e) { std::cerr << "JSON parse error: " << e.what() << std::endl; - return false; + throw std::runtime_error("Failed to load spark emitter config file!"); } std::cout << "JSON content: " << j.dump(2) << std::endl; - // Основные параметры - if (j.contains("emissionRate")) { - emissionRate = j["emissionRate"].get(); - } + auto requireKey = [&](const std::string& key) { + if (!j.contains(key)) { + std::cerr << "Missing required key in spark JSON: " << key << std::endl; + throw std::runtime_error("Failed to load spark emitter config file!"); + } + }; - if (j.contains("maxParticles")) { - maxParticles = j["maxParticles"].get(); - particles.resize(maxParticles); - drawPositions.reserve(maxParticles * 6); - drawTexCoords.reserve(maxParticles * 6); - std::cout << "Max particles: " << maxParticles << std::endl; - } + requireKey("emissionPoints"); + requireKey("texture"); + requireKey("speedRange"); + requireKey("zSpeedRange"); + requireKey("scaleRange"); + requireKey("lifeTimeRange"); + requireKey("emissionRate"); + requireKey("maxParticles"); + requireKey("particleSize"); + requireKey("biasX"); + requireKey("shaderProgramName"); - if (j.contains("particleSize")) { - particleSize = j["particleSize"].get(); - std::cout << "Particle size: " << particleSize << std::endl; - } + emissionRate = j["emissionRate"].get(); - if (j.contains("biasX")) { - biasX = j["biasX"].get(); - std::cout << "Bias X: " << biasX << std::endl; - } + maxParticles = j["maxParticles"].get(); + particles.resize(maxParticles); + drawPositions.reserve(maxParticles * 6); + drawTexCoords.reserve(maxParticles * 6); + std::cout << "Max particles: " << maxParticles << std::endl; + + particleSize = j["particleSize"].get(); + std::cout << "Particle size: " << particleSize << std::endl; + + biasX = j["biasX"].get(); + std::cout << "Bias X: " << biasX << std::endl; // emissionPoints std::vector points; @@ -382,6 +413,14 @@ namespace ZL { setEmissionPoints(points); std::cout << "Total emission points: " << emissionPoints.size() << std::endl; } + else { + std::cerr << "Emission points parsed but empty" << std::endl; + throw std::runtime_error("Failed to load spark emitter config file!"); + } + } + else { + std::cerr << "emissionPoints is not array" << std::endl; + throw std::runtime_error("Failed to load spark emitter config file!"); } // Ranges @@ -391,6 +430,10 @@ namespace ZL { speedRange.max = a[1].get(); std::cout << "Speed range: [" << speedRange.min << ", " << speedRange.max << "]" << std::endl; } + else { + std::cerr << "speedRange missing or invalid" << std::endl; + throw std::runtime_error("Failed to load spark emitter config file!"); + } if (j.contains("zSpeedRange") && j["zSpeedRange"].is_array()) { auto a = j["zSpeedRange"]; @@ -398,6 +441,10 @@ namespace ZL { zSpeedRange.max = a[1].get(); std::cout << "Z speed range: [" << zSpeedRange.min << ", " << zSpeedRange.max << "]" << std::endl; } + else { + std::cerr << "zSpeedRange missing or invalid" << std::endl; + throw std::runtime_error("Failed to load spark emitter config file!"); + } if (j.contains("scaleRange") && j["scaleRange"].is_array()) { auto a = j["scaleRange"]; @@ -405,6 +452,10 @@ namespace ZL { scaleRange.max = a[1].get(); std::cout << "Scale range: [" << scaleRange.min << ", " << scaleRange.max << "]" << std::endl; } + else { + std::cerr << "scaleRange missing or invalid" << std::endl; + throw std::runtime_error("Failed to load spark emitter config file!"); + } if (j.contains("lifeTimeRange") && j["lifeTimeRange"].is_array()) { auto a = j["lifeTimeRange"]; @@ -412,6 +463,10 @@ namespace ZL { lifeTimeRange.max = a[1].get(); std::cout << "Life time range: [" << lifeTimeRange.min << ", " << lifeTimeRange.max << "]" << std::endl; } + else { + std::cerr << "lifeTimeRange missing or invalid" << std::endl; + throw std::runtime_error("Failed to load spark emitter config file!"); + } // texture if (j.contains("texture") && j["texture"].is_string()) { @@ -425,12 +480,12 @@ namespace ZL { } catch (const std::exception& e) { std::cerr << "Texture load error: " << e.what() << std::endl; - return false; + throw std::runtime_error("Failed to load spark emitter config file!"); } } else { - std::cout << "No texture specified in JSON" << std::endl; - return false; + std::cerr << "No texture specified or invalid type in JSON" << std::endl; + throw std::runtime_error("Failed to load spark emitter config file!"); } // shaders @@ -438,6 +493,10 @@ namespace ZL { shaderProgramName = j["shaderProgramName"].get(); std::cout << "Shader program name: " << shaderProgramName << std::endl; } + else { + std::cerr << "shaderProgramName missing or invalid" << std::endl; + throw std::runtime_error("Failed to load spark emitter config file!"); + } if (j.contains("vertexShader") && j.contains("fragmentShader") && j["vertexShader"].is_string() && j["fragmentShader"].is_string()) { @@ -451,12 +510,12 @@ namespace ZL { } catch (const std::exception& e) { std::cerr << "Shader load error: " << e.what() << std::endl; - std::cerr << "Using default shader" << std::endl; - shaderProgramName = "default"; + throw std::runtime_error("Failed to load spark emitter config file!"); } } drawDataDirty = true; + configured = true; std::cout << "SparkEmitter configuration loaded successfully!" << std::endl; return true; } diff --git a/SparkEmitter.h b/SparkEmitter.h index 1cd2cae..953bd34 100644 --- a/SparkEmitter.h +++ b/SparkEmitter.h @@ -50,6 +50,7 @@ namespace ZL { std::string shaderProgramName; + bool configured; void prepareDrawData(); public: diff --git a/UiManager.cpp b/UiManager.cpp new file mode 100644 index 0000000..2e09b75 --- /dev/null +++ b/UiManager.cpp @@ -0,0 +1,249 @@ +#include "UiManager.h" +#include "Utils.h" +#include +#include +#include + +namespace ZL { + + using json = nlohmann::json; + + void UiButton::buildMesh() { + mesh.data.PositionData.clear(); + mesh.data.TexCoordData.clear(); + + float x0 = rect.x; + float y0 = rect.y; + float x1 = rect.x + rect.w; + float y1 = rect.y + rect.h; + + mesh.data.PositionData.push_back({ x0, y0, 0 }); + mesh.data.TexCoordData.push_back({ 0, 0 }); + + mesh.data.PositionData.push_back({ x0, y1, 0 }); + mesh.data.TexCoordData.push_back({ 0, 1 }); + + mesh.data.PositionData.push_back({ x1, y1, 0 }); + mesh.data.TexCoordData.push_back({ 1, 1 }); + + mesh.data.PositionData.push_back({ x0, y0, 0 }); + mesh.data.TexCoordData.push_back({ 0, 0 }); + + mesh.data.PositionData.push_back({ x1, y1, 0 }); + mesh.data.TexCoordData.push_back({ 1, 1 }); + + mesh.data.PositionData.push_back({ x1, y0, 0 }); + mesh.data.TexCoordData.push_back({ 1, 0 }); + + mesh.RefreshVBO(); + } + + void UiButton::draw(Renderer& renderer) const { + if (!texNormal) return; + const std::shared_ptr* tex = &texNormal; + switch (state) { + case ButtonState::Normal: tex = &texNormal; break; + case ButtonState::Hover: tex = &texHover; break; + case ButtonState::Pressed: tex = &texPressed; break; + } + if (!(*tex)) return; + + static const std::string vPositionName = "vPosition"; + static const std::string vTexCoordName = "vTexCoord"; + static const std::string textureUniformName = "Texture"; + + renderer.RenderUniform1i(textureUniformName, 0); + renderer.EnableVertexAttribArray(vPositionName); + renderer.EnableVertexAttribArray(vTexCoordName); + + glBindTexture(GL_TEXTURE_2D, (*tex)->getTexID()); + renderer.DrawVertexRenderStruct(mesh); + + renderer.DisableVertexAttribArray(vPositionName); + renderer.DisableVertexAttribArray(vTexCoordName); + } + + // UiManager implementation + void UiManager::loadFromFile(const std::string& path, Renderer& renderer, const std::string& zipFile) { + std::ifstream in(path); + if (!in.is_open()) { + std::cerr << "UiManager: failed to open " << path << std::endl; + throw std::runtime_error("Failed to load UI file: " + path); + } + + json j; + try { + in >> j; + } + catch (const std::exception& e) { + std::cerr << "UiManager: json parse error: " << e.what() << std::endl; + throw std::runtime_error("Failed to load UI file: " + path); + } + + if (!j.contains("root") || !j["root"].is_object()) { + std::cerr << "UiManager: root node missing or invalid" << std::endl; + throw std::runtime_error("Failed to load UI file: " + path); + } + + root = parseNode(j["root"], renderer, zipFile); + layoutNode(root); + buttons.clear(); + collectButtons(root); + + for (auto& b : buttons) { + b->buildMesh(); + } + } + + std::shared_ptr UiManager::parseNode(const json& j, Renderer& renderer, const std::string& zipFile) { + auto node = std::make_shared(); + if (j.contains("type") && j["type"].is_string()) node->type = j["type"].get(); + if (j.contains("name") && j["name"].is_string()) node->name = j["name"].get(); + + if (j.contains("x")) node->rect.x = j["x"].get(); + if (j.contains("y")) node->rect.y = j["y"].get(); + if (j.contains("width")) node->rect.w = j["width"].get(); + if (j.contains("height")) node->rect.h = j["height"].get(); + + if (j.contains("orientation") && j["orientation"].is_string()) node->orientation = j["orientation"].get(); + if (j.contains("spacing")) node->spacing = j["spacing"].get(); + + if (node->type == "Button") { + auto btn = std::make_shared(); + btn->name = node->name; + btn->rect = node->rect; + + if (!j.contains("textures") || !j["textures"].is_object()) { + std::cerr << "UiManager: Button '" << btn->name << "' missing textures" << std::endl; + throw std::runtime_error("UI button textures missing"); + } + auto t = j["textures"]; + auto loadTex = [&](const std::string& key)->std::shared_ptr { + if (!t.contains(key) || !t[key].is_string()) return nullptr; + std::string path = t[key].get(); + try { + auto data = CreateTextureDataFromPng(path.c_str(), zipFile.c_str()); + return std::make_shared(data); + } + catch (const std::exception& e) { + std::cerr << "UiManager: failed load texture " << path << " : " << e.what() << std::endl; + throw std::runtime_error("UI texture load failed: " + path); + } + }; + + btn->texNormal = loadTex("normal"); + btn->texHover = loadTex("hover"); + btn->texPressed = loadTex("pressed"); + + node->button = btn; + } + + // parse children + if (j.contains("children") && j["children"].is_array()) { + for (const auto& ch : j["children"]) { + node->children.push_back(parseNode(ch, renderer, zipFile)); + } + } + + return node; + } + + void UiManager::layoutNode(const std::shared_ptr& node) { + for (auto& child : node->children) { + child->rect.x += node->rect.x; + child->rect.y += node->rect.y; + } + + if (node->type == "LinearLayout") { + std::string orient = node->orientation; + std::transform(orient.begin(), orient.end(), orient.begin(), ::tolower); + + float cursorX = node->rect.x; + float cursorY = node->rect.y; + for (auto& child : node->children) { + if (orient == "horizontal") { + child->rect.x = cursorX; + child->rect.y = node->rect.y; + cursorX += child->rect.w + node->spacing; + } + else { + child->rect.x = node->rect.x; + child->rect.y = cursorY; + cursorY += child->rect.h + node->spacing; + } + layoutNode(child); + } + } + else { + for (auto& child : node->children) { + layoutNode(child); + } + } + } + + void UiManager::collectButtons(const std::shared_ptr& node) { + if (node->button) { + buttons.push_back(node->button); + } + for (auto& c : node->children) collectButtons(c); + } + + void UiManager::draw(Renderer& renderer) { + if (!root) return; + + renderer.PushProjectionMatrix(Environment::width, Environment::height, -1, 1); + renderer.PushMatrix(); + renderer.LoadIdentity(); + + for (const auto& b : buttons) { + b->draw(renderer); + } + + renderer.PopMatrix(); + renderer.PopProjectionMatrix(); + } + + void UiManager::onMouseMove(int x, int y) { + for (auto& b : buttons) { + if (b->rect.contains((float)x, (float)y)) { + if (b->state != ButtonState::Pressed) b->state = ButtonState::Hover; + } + else { + if (b->state != ButtonState::Pressed) b->state = ButtonState::Normal; + } + } + } + + void UiManager::onMouseDown(int x, int y) { + for (auto& b : buttons) { + if (b->rect.contains((float)x, (float)y)) { + b->state = ButtonState::Pressed; + pressedButton = b; + } + else { + // leave others + } + } + } + + void UiManager::onMouseUp(int x, int y) { + for (auto& b : buttons) { + bool contains = b->rect.contains((float)x, (float)y); + if (b->state == ButtonState::Pressed) { + if (contains && pressedButton == b) { + if (b->onClick) { + b->onClick(b->name); + } + } + b->state = contains ? ButtonState::Hover : ButtonState::Normal; + } + } + pressedButton.reset(); + } + + std::shared_ptr UiManager::findButton(const std::string& name) { + for (auto& b : buttons) if (b->name == name) return b; + return nullptr; + } + +} // namespace ZL \ No newline at end of file diff --git a/UiManager.h b/UiManager.h new file mode 100644 index 0000000..87bbbe1 --- /dev/null +++ b/UiManager.h @@ -0,0 +1,83 @@ +#pragma once + +#include "Renderer.h" +#include "TextureManager.h" +#include "Environment.h" +#include "external/nlohmann/json.hpp" +#include +#include +#include +#include + +namespace ZL { + + using json = nlohmann::json; + + struct UiRect { + float x = 0; + float y = 0; + float w = 0; + float h = 0; + bool contains(float px, float py) const { + return px >= x && px <= x + w && py >= y && py <= y + h; + } + }; + + enum class ButtonState { + Normal, + Hover, + Pressed + }; + + struct UiButton { + std::string name; + UiRect rect; + std::shared_ptr texNormal; + std::shared_ptr texHover; + std::shared_ptr texPressed; + ButtonState state = ButtonState::Normal; + + VertexRenderStruct mesh; + + std::function onClick; + + void buildMesh(); + void draw(Renderer& renderer) const; + }; + + struct UiNode { + std::string type; + UiRect rect; + std::string name; + std::vector> children; + std::shared_ptr button; + std::string orientation = "vertical"; + float spacing = 0.0f; + }; + + class UiManager { + public: + UiManager() = default; + + void loadFromFile(const std::string& path, Renderer& renderer, const std::string& zipFile = ""); + + void draw(Renderer& renderer); + + void onMouseMove(int x, int y); + void onMouseDown(int x, int y); + void onMouseUp(int x, int y); + + std::shared_ptr findButton(const std::string& name); + + private: + std::shared_ptr parseNode(const json& j, Renderer& renderer, const std::string& zipFile); + void layoutNode(const std::shared_ptr& node); + void collectButtons(const std::shared_ptr& node); + + std::shared_ptr root; + std::vector> buttons; + + std::shared_ptr pressedButton; + }; + +} // namespace ZL \ No newline at end of file diff --git a/config/spark_config.json b/config/spark_config.json index d3d040e..b043f60 100644 --- a/config/spark_config.json +++ b/config/spark_config.json @@ -17,6 +17,6 @@ "lifeTimeRange": [600.0, 1400.0], "texture": "./resources/spark.png", "shaderProgramName": "default", - "vertexShader": "./shaders/default.vertex", - "fragmentShader": "./shaders/default.fragment" + "vertexShader": "./shaders/spark.vertex", + "fragmentShader": "./shaders/spark.fragment" } \ No newline at end of file diff --git a/config/ui.json b/config/ui.json new file mode 100644 index 0000000..e21e113 --- /dev/null +++ b/config/ui.json @@ -0,0 +1,72 @@ +{ + "root": { + "type": "FrameLayout", + "x": 0, + "y": 0, + "width": 1280, + "height": 720, + "children": [ + { + "type": "FrameLayout", + "name": "leftPanel", + "x": 100, + "y": 100, + "width": 320, + "height": 400, + "children": [ + { + "type": "LinearLayout", + "name": "mainButtons", + "orientation": "vertical", + "spacing": 10, + "x": 0, + "y": 0, + "width": 300, + "height": 300, + "children": [ + { + "type": "Button", + "name": "playButton", + "x": 100, + "y": 100, + "width": 200, + "height": 50, + "textures": { + "normal": "./resources/button.png", + "hover": "./resources/rock.png", + "pressed": "./resources/sand.png" + } + }, + { + "type": "Button", + "name": "settingsButton", + "x": 100, + "y": 200, + "width": 200, + "height": 50, + "textures": { + "normal": "./resources/button.png", + "hover": "./resources/rock.png", + "pressed": "./resources/sand.png" + } + }, + { + "type": "Button", + "name": "exitButton", + "x": 150, + "y": 300, + "width": 200, + "height": 50, + "textures": { + "normal": "./resources/button.png", + "hover": "./resources/rock.png", + "pressed": "./resources/sand.png" + } + } + ] + } + ] + } + ] + } +} \ No newline at end of file diff --git a/shaders/spark.fragment b/shaders/spark.fragment index 759e1d7..ae06b6a 100644 --- a/shaders/spark.fragment +++ b/shaders/spark.fragment @@ -1,8 +1,12 @@ -#version 120 -varying vec2 fTexCoord; +//precision mediump float; uniform sampler2D Texture; -void main() { - vec4 col = texture2D(Texture, fTexCoord); - // простой аддитивный блёк - gl_FragColor = col; +varying vec2 texCoord; + +void main() +{ + vec4 color = texture2D(Texture,texCoord).rgba; + //gl_FragColor = vec4(color.rgb*0.9 + vec3(0.1, 0.1, 0.1), 1.0); + + gl_FragColor = color; + } \ No newline at end of file diff --git a/shaders/spark.vertex b/shaders/spark.vertex index 470451a..b385eb9 100644 --- a/shaders/spark.vertex +++ b/shaders/spark.vertex @@ -1,8 +1,11 @@ -#version 120 attribute vec3 vPosition; attribute vec2 vTexCoord; -varying vec2 fTexCoord; -void main() { - fTexCoord = vTexCoord; - gl_Position = gl_ModelViewProjectionMatrix * vec4(vPosition, 1.0); +varying vec2 texCoord; + +uniform mat4 ProjectionModelViewMatrix; + +void main() +{ + gl_Position = ProjectionModelViewMatrix * vec4(vPosition.xyz, 1.0); + texCoord = vTexCoord; } \ No newline at end of file