add ui.json and del default values from SparkEmitter

This commit is contained in:
Vlad 2025-12-19 17:35:34 +06:00
parent 53ea1f768c
commit 068c319890
11 changed files with 540 additions and 50 deletions

View File

@ -440,6 +440,8 @@ add_executable(space-game001
SparkEmitter.h
PlanetObject.cpp
PlanetObject.h
UiManager.cpp
UiManager.h
)
# Установка проекта по умолчанию для Visual Studio

View File

@ -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<Texture>(
std::array<TextureDataStruct, 6>{
@ -208,7 +209,7 @@ namespace ZL
}
buttonTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/button.png", CONST_ZIP_FILE));
/* buttonTexture = std::make_unique<Texture>(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<Texture>(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);

2
Game.h
View File

@ -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;
};

View File

@ -6,6 +6,7 @@
#include "external/nlohmann/json.hpp"
#include <iostream>
#include "Environment.h"
#include <stdexcept>
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<Vector3f>& 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<std::chrono::milliseconds>(
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<float> angleDist(0.0f, 2.0f * static_cast<float>(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<float>();
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!");
}
};
requireKey("emissionPoints");
requireKey("texture");
requireKey("speedRange");
requireKey("zSpeedRange");
requireKey("scaleRange");
requireKey("lifeTimeRange");
requireKey("emissionRate");
requireKey("maxParticles");
requireKey("particleSize");
requireKey("biasX");
requireKey("shaderProgramName");
emissionRate = j["emissionRate"].get<float>();
if (j.contains("maxParticles")) {
maxParticles = j["maxParticles"].get<int>();
particles.resize(maxParticles);
drawPositions.reserve(maxParticles * 6);
drawTexCoords.reserve(maxParticles * 6);
std::cout << "Max particles: " << maxParticles << std::endl;
}
if (j.contains("particleSize")) {
particleSize = j["particleSize"].get<float>();
std::cout << "Particle size: " << particleSize << std::endl;
}
if (j.contains("biasX")) {
biasX = j["biasX"].get<float>();
std::cout << "Bias X: " << biasX << std::endl;
}
// emissionPoints
std::vector<Vector3f> 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<float>();
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<float>();
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<float>();
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<float>();
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::string>();
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;
}

View File

@ -50,6 +50,7 @@ namespace ZL {
std::string shaderProgramName;
bool configured;
void prepareDrawData();
public:

249
UiManager.cpp Normal file
View File

@ -0,0 +1,249 @@
#include "UiManager.h"
#include "Utils.h"
#include <fstream>
#include <iostream>
#include <algorithm>
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<Texture>* 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<UiNode> UiManager::parseNode(const json& j, Renderer& renderer, const std::string& zipFile) {
auto node = std::make_shared<UiNode>();
if (j.contains("type") && j["type"].is_string()) node->type = j["type"].get<std::string>();
if (j.contains("name") && j["name"].is_string()) node->name = j["name"].get<std::string>();
if (j.contains("x")) node->rect.x = j["x"].get<float>();
if (j.contains("y")) node->rect.y = j["y"].get<float>();
if (j.contains("width")) node->rect.w = j["width"].get<float>();
if (j.contains("height")) node->rect.h = j["height"].get<float>();
if (j.contains("orientation") && j["orientation"].is_string()) node->orientation = j["orientation"].get<std::string>();
if (j.contains("spacing")) node->spacing = j["spacing"].get<float>();
if (node->type == "Button") {
auto btn = std::make_shared<UiButton>();
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<Texture> {
if (!t.contains(key) || !t[key].is_string()) return nullptr;
std::string path = t[key].get<std::string>();
try {
auto data = CreateTextureDataFromPng(path.c_str(), zipFile.c_str());
return std::make_shared<Texture>(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<UiNode>& 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<UiNode>& 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<UiButton> UiManager::findButton(const std::string& name) {
for (auto& b : buttons) if (b->name == name) return b;
return nullptr;
}
} // namespace ZL

83
UiManager.h Normal file
View File

@ -0,0 +1,83 @@
#pragma once
#include "Renderer.h"
#include "TextureManager.h"
#include "Environment.h"
#include "external/nlohmann/json.hpp"
#include <string>
#include <vector>
#include <memory>
#include <functional>
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<Texture> texNormal;
std::shared_ptr<Texture> texHover;
std::shared_ptr<Texture> texPressed;
ButtonState state = ButtonState::Normal;
VertexRenderStruct mesh;
std::function<void(const std::string&)> onClick;
void buildMesh();
void draw(Renderer& renderer) const;
};
struct UiNode {
std::string type;
UiRect rect;
std::string name;
std::vector<std::shared_ptr<UiNode>> children;
std::shared_ptr<UiButton> 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<UiButton> findButton(const std::string& name);
private:
std::shared_ptr<UiNode> parseNode(const json& j, Renderer& renderer, const std::string& zipFile);
void layoutNode(const std::shared_ptr<UiNode>& node);
void collectButtons(const std::shared_ptr<UiNode>& node);
std::shared_ptr<UiNode> root;
std::vector<std::shared_ptr<UiButton>> buttons;
std::shared_ptr<UiButton> pressedButton;
};
} // namespace ZL

View File

@ -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"
}

72
config/ui.json Normal file
View File

@ -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"
}
}
]
}
]
}
]
}
}

View File

@ -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;
}

View File

@ -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;
}