Added android version too
This commit is contained in:
1 parent
8089bcc0f3
commit
a08ee412a6
54 files changed
+7146
-488
No files matched your search
+6
-1
@@ -1,8 +1,13 @@
|
||||
#include "Environment.h"
|
||||
|
||||
#include "utils/Utils.h"
|
||||
#include <GL/gl.h>
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
namespace ZL {
|
||||
|
||||
int Environment::windowHeaderHeight = 0;
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
#ifdef __linux__
|
||||
#include <SDL2/SDL.h>
|
||||
#endif
|
||||
#ifndef __ANDROID__
|
||||
#include "render/OpenGlExtensions.h"
|
||||
#endif
|
||||
#include <Eigen/Dense>
|
||||
|
||||
namespace ZL {
|
||||
|
||||
+176
-172
@@ -9,6 +9,9 @@
|
||||
#include <random>
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#ifdef __ANDROID__
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
|
||||
namespace ZL
|
||||
{
|
||||
@@ -125,31 +128,81 @@ namespace ZL
|
||||
ZL::BindOpenGlFunctions();
|
||||
ZL::CheckGlError();
|
||||
|
||||
#ifdef __ANDROID__
|
||||
__android_log_print(ANDROID_LOG_INFO, "Game", "Start for Android");
|
||||
|
||||
const char* testFiles[] = {
|
||||
"resources/shaders/default.vertex",
|
||||
"resources/shaders/default_web.fragment",
|
||||
nullptr
|
||||
};
|
||||
|
||||
for (int i = 0; testFiles[i] != nullptr; i++) {
|
||||
SDL_RWops* file = SDL_RWFromFile(testFiles[i], "rb");
|
||||
if (file) {
|
||||
Sint64 size = SDL_RWsize(file);
|
||||
__android_log_print(ANDROID_LOG_INFO, "Game", "Found: %s (size: %lld)", testFiles[i], size);
|
||||
SDL_RWclose(file);
|
||||
} else {
|
||||
__android_log_print(ANDROID_LOG_WARN, "Game", "Not found: %s (SDL error: %s)",
|
||||
testFiles[i], SDL_GetError());
|
||||
}
|
||||
}
|
||||
|
||||
__android_log_print(ANDROID_LOG_ERROR, "ShaderManager",
|
||||
"Step 1xxxxxxx");
|
||||
#endif
|
||||
// Initialize renderer
|
||||
|
||||
|
||||
#ifndef SIMPLIFIED
|
||||
renderer.shaderManager.AddShaderFromFiles("defaultColor", "./resources/shaders/defaultColor.vertex", "./resources/shaders/defaultColor_web.fragment", CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("default", "./resources/shaders/default.vertex", "./resources/shaders/default_web.fragment", CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("env_sky", "./resources/shaders/env_sky.vertex", "./resources/shaders/env_sky_web.fragment", CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("defaultAtmosphere", "./resources/shaders/defaultAtmosphere.vertex", "./resources/shaders/defaultAtmosphere_web.fragment", CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("planetBake", "./resources/shaders/planet_bake.vertex", "./resources/shaders/planet_bake_web.fragment", CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("planetStone", "./resources/shaders/planet_stone.vertex", "./resources/shaders/planet_stone_web.fragment", CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("planetLand", "./resources/shaders/planet_land.vertex", "./resources/shaders/planet_land_web.fragment", CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("defaultColor", "resources/shaders/defaultColor.vertex", "resources/shaders/defaultColor_web.fragment", CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("default", "resources/shaders/default.vertex", "resources/shaders/default_web.fragment", CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("env_sky", "resources/shaders/env_sky.vertex", "resources/shaders/env_sky_web.fragment", CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("defaultAtmosphere", "resources/shaders/defaultAtmosphere.vertex", "resources/shaders/defaultAtmosphere_web.fragment", CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("planetBake", "resources/shaders/planet_bake.vertex", "resources/shaders/planet_bake_web.fragment", CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("planetStone", "resources/shaders/planet_stone.vertex", "resources/shaders/planet_stone_web.fragment", CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("planetLand", "resources/shaders/planet_land.vertex", "resources/shaders/planet_land_web.fragment", CONST_ZIP_FILE);
|
||||
|
||||
#else
|
||||
renderer.shaderManager.AddShaderFromFiles("default", "./resources/shaders/default.vertex", "./resources/shaders/default_web.fragment", CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("env_sky", "./resources/shaders/default_env.vertex", "./resources/shaders/default_env_web.fragment", CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("defaultAtmosphere", "./resources/shaders/default_texture.vertex", "./resources/shaders/default_texture_web.fragment", CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("planetBake", "./resources/shaders/default_texture.vertex", "./resources/shaders/default_texture_web.fragment", CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("planetStone", "./resources/shaders/default_texture.vertex", "./resources/shaders/default_texture_web.fragment", CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("planetLand", "./resources/shaders/default_texture.vertex", "./resources/shaders/default_texture_web.fragment", CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("default", "resources/shaders/default.vertex", "resources/shaders/default_web.fragment", CONST_ZIP_FILE);
|
||||
#ifdef __ANDROID__
|
||||
__android_log_print(ANDROID_LOG_ERROR, "ShaderManager",
|
||||
"Step 2xxxxxxx");
|
||||
#endif
|
||||
renderer.shaderManager.AddShaderFromFiles("env_sky", "resources/shaders/default_env.vertex", "resources/shaders/default_env_web.fragment", CONST_ZIP_FILE);
|
||||
#ifdef __ANDROID__
|
||||
__android_log_print(ANDROID_LOG_INFO, "ShaderManager",
|
||||
"Step 2");
|
||||
#endif
|
||||
renderer.shaderManager.AddShaderFromFiles("defaultAtmosphere", "resources/shaders/default_texture.vertex", "resources/shaders/default_texture_web.fragment", CONST_ZIP_FILE);
|
||||
#ifdef __ANDROID__
|
||||
__android_log_print(ANDROID_LOG_INFO, "ShaderManager",
|
||||
"Step 3");
|
||||
#endif
|
||||
|
||||
bool cfgLoaded = sparkEmitter.loadFromJsonFile("./resources/config/spark_config.json", renderer, CONST_ZIP_FILE);
|
||||
bool projCfgLoaded = projectileEmitter.loadFromJsonFile("./resources/config/spark_projectile_config.json", renderer, CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("planetBake", "resources/shaders/default_texture.vertex", "resources/shaders/default_texture_web.fragment", CONST_ZIP_FILE);
|
||||
#ifdef __ANDROID__
|
||||
__android_log_print(ANDROID_LOG_INFO, "ShaderManager",
|
||||
"Step 4");
|
||||
#endif
|
||||
renderer.shaderManager.AddShaderFromFiles("planetStone", "resources/shaders/default_texture.vertex", "resources/shaders/default_texture_web.fragment", CONST_ZIP_FILE);
|
||||
#ifdef __ANDROID__
|
||||
__android_log_print(ANDROID_LOG_INFO, "ShaderManager",
|
||||
"Step 5");
|
||||
#endif
|
||||
renderer.shaderManager.AddShaderFromFiles("planetLand", "resources/shaders/default_texture.vertex", "resources/shaders/default_texture_web.fragment", CONST_ZIP_FILE);
|
||||
#ifdef __ANDROID__
|
||||
__android_log_print(ANDROID_LOG_INFO, "ShaderManager",
|
||||
"Step 1");
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
bool cfgLoaded = sparkEmitter.loadFromJsonFile("resources/config/spark_config.json", renderer, CONST_ZIP_FILE);
|
||||
bool projCfgLoaded = projectileEmitter.loadFromJsonFile("resources/config/spark_projectile_config.json", renderer, CONST_ZIP_FILE);
|
||||
projectileEmitter.setEmissionPoints(std::vector<Vector3f>());
|
||||
uiManager.loadFromFile("./resources/config/ui.json", renderer, CONST_ZIP_FILE);
|
||||
uiManager.loadFromFile("resources/config/ui.json", renderer, CONST_ZIP_FILE);
|
||||
|
||||
uiManager.setButtonCallback("shootButton", [this](const std::string& name) {
|
||||
uint64_t now = SDL_GetTicks64();
|
||||
@@ -158,35 +211,7 @@ namespace ZL
|
||||
fireProjectiles();
|
||||
}
|
||||
});
|
||||
/*
|
||||
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("velocitySlider", [this](const std::string& name, float value) {
|
||||
Environment::shipVelocity = value * 1000.f;
|
||||
});
|
||||
@@ -194,21 +219,23 @@ namespace ZL
|
||||
|
||||
cubemapTexture = std::make_shared<Texture>(
|
||||
std::array<TextureDataStruct, 6>{
|
||||
CreateTextureDataFromPng("./resources/sky/space1.png", CONST_ZIP_FILE),
|
||||
CreateTextureDataFromPng("./resources/sky/space1.png", CONST_ZIP_FILE),
|
||||
CreateTextureDataFromPng("./resources/sky/space1.png", CONST_ZIP_FILE),
|
||||
CreateTextureDataFromPng("./resources/sky/space1.png", CONST_ZIP_FILE),
|
||||
CreateTextureDataFromPng("./resources/sky/space1.png", CONST_ZIP_FILE),
|
||||
CreateTextureDataFromPng("./resources/sky/space1.png", CONST_ZIP_FILE)
|
||||
CreateTextureDataFromPng("resources/sky/space1.png", CONST_ZIP_FILE),
|
||||
CreateTextureDataFromPng("resources/sky/space1.png", CONST_ZIP_FILE),
|
||||
CreateTextureDataFromPng("resources/sky/space1.png", CONST_ZIP_FILE),
|
||||
CreateTextureDataFromPng("resources/sky/space1.png", CONST_ZIP_FILE),
|
||||
CreateTextureDataFromPng("resources/sky/space1.png", CONST_ZIP_FILE),
|
||||
CreateTextureDataFromPng("resources/sky/space1.png", CONST_ZIP_FILE)
|
||||
});
|
||||
|
||||
|
||||
cubemap.data = ZL::CreateCubemap(500);
|
||||
cubemap.RefreshVBO();
|
||||
|
||||
|
||||
|
||||
//Load texture
|
||||
spaceshipTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/DefaultMaterial_BaseColor_shine.png", CONST_ZIP_FILE));
|
||||
spaceshipBase = LoadFromTextFile02("./resources/spaceship006.txt", CONST_ZIP_FILE);
|
||||
spaceshipTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/DefaultMaterial_BaseColor_shine.png", CONST_ZIP_FILE));
|
||||
spaceshipBase = LoadFromTextFile02("resources/spaceship006.txt", CONST_ZIP_FILE);
|
||||
spaceshipBase.RotateByMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(M_PI / 2.0, Eigen::Vector3f::UnitY())).toRotationMatrix());// QuatFromRotateAroundY(M_PI / 2.0).toRotationMatrix());
|
||||
|
||||
//spaceshipTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/cap_D.png", CONST_ZIP_FILE));
|
||||
@@ -224,8 +251,8 @@ namespace ZL
|
||||
|
||||
|
||||
//Boxes
|
||||
boxTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/box/box.png", CONST_ZIP_FILE));
|
||||
boxBase = LoadFromTextFile02("./resources/box/box.txt", CONST_ZIP_FILE);
|
||||
boxTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/box/box.png", CONST_ZIP_FILE));
|
||||
boxBase = LoadFromTextFile02("resources/box/box.txt", CONST_ZIP_FILE);
|
||||
|
||||
std::cout << "Init step 1 " << std::endl;
|
||||
|
||||
@@ -244,73 +271,15 @@ namespace ZL
|
||||
boxRenderArr[i].RefreshVBO();
|
||||
}
|
||||
|
||||
|
||||
std::cout << "Init step 4 " << std::endl;
|
||||
|
||||
if (!cfgLoaded)
|
||||
{
|
||||
throw std::runtime_error("Failed to load spark emitter config 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 });
|
||||
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<Texture>(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<Texture>(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();*/
|
||||
|
||||
std::cout << "Init step 5 " << std::endl;
|
||||
|
||||
renderer.InitOpenGL();
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
@@ -318,7 +287,7 @@ namespace ZL
|
||||
std::cout << "Init step 6 " << std::endl;
|
||||
planetObject.init();
|
||||
|
||||
planetObject.taskManager = &taskManager;
|
||||
planetObject.taskManager = &taskManager;
|
||||
|
||||
std::cout << "Init step 7 " << std::endl;
|
||||
//rockTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/rock.png", CONST_ZIP_FILE));
|
||||
@@ -671,80 +640,58 @@ namespace ZL
|
||||
|
||||
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) {
|
||||
#ifdef __ANDROID__
|
||||
if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_AC_BACK) {
|
||||
Environment::exitGameLoop = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __ANDROID__
|
||||
if (event.type == SDL_FINGERDOWN) {
|
||||
// Координаты Finger в SDL нормализованы от 0.0 до 1.0
|
||||
int mx = static_cast<int>(event.tfinger.x * Environment::width);
|
||||
int my = static_cast<int>(event.tfinger.y * Environment::height);
|
||||
handleDown(mx, my);
|
||||
}
|
||||
else if (event.type == SDL_FINGERUP) {
|
||||
int mx = static_cast<int>(event.tfinger.x * Environment::width);
|
||||
int my = static_cast<int>(event.tfinger.y * Environment::height);
|
||||
handleUp(mx, my);
|
||||
}
|
||||
else if (event.type == SDL_FINGERMOTION) {
|
||||
int mx = static_cast<int>(event.tfinger.x * Environment::width);
|
||||
int my = static_cast<int>(event.tfinger.y * Environment::height);
|
||||
handleMotion(mx, my);
|
||||
}
|
||||
#else
|
||||
|
||||
if (event.type == SDL_MOUSEBUTTONDOWN) {
|
||||
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<uint64_t>(projectileCooldownMs)) {
|
||||
lastProjectileFireTime = now;
|
||||
fireProjectiles();
|
||||
}
|
||||
}*/
|
||||
|
||||
for (const auto& button : uiManager.findButton("") ? std::vector<std::shared_ptr<UiButton>>{} : std::vector<std::shared_ptr<UiButton>>{}) {
|
||||
(void)button;
|
||||
}
|
||||
|
||||
auto pressedSlider = [&]() -> std::shared_ptr<UiSlider> {
|
||||
for (const auto& slider : uiManager.findSlider("") ? std::vector<std::shared_ptr<UiSlider>>{} : std::vector<std::shared_ptr<UiSlider>>{}) {
|
||||
(void)slider;
|
||||
}
|
||||
return nullptr;
|
||||
}();
|
||||
|
||||
if (!uiManager.isUiInteraction()) {
|
||||
Environment::tapDownHold = true;
|
||||
|
||||
Environment::tapDownStartPos(0) = mx;
|
||||
Environment::tapDownStartPos(1) = my;
|
||||
|
||||
Environment::tapDownCurrentPos(0) = mx;
|
||||
Environment::tapDownCurrentPos(1) = my;
|
||||
}
|
||||
handleDown(mx, my);
|
||||
}
|
||||
else if (event.type == SDL_MOUSEBUTTONUP) {
|
||||
if (event.type == SDL_MOUSEBUTTONUP) {
|
||||
|
||||
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;
|
||||
}
|
||||
handleUp(mx, my);
|
||||
}
|
||||
else if (event.type == SDL_MOUSEMOTION) {
|
||||
if (event.type == SDL_MOUSEMOTION) {
|
||||
|
||||
int mx = event.motion.x;
|
||||
int my = event.motion.y;
|
||||
int uiX = mx;
|
||||
int uiY = Environment::height - my;
|
||||
handleMotion(mx, my);
|
||||
|
||||
uiManager.onMouseMove(uiX, uiY);
|
||||
|
||||
if (Environment::tapDownHold && !uiManager.isUiInteraction()) {
|
||||
Environment::tapDownCurrentPos(0) = mx;
|
||||
Environment::tapDownCurrentPos(1) = my;
|
||||
}
|
||||
}
|
||||
else if (event.type == SDL_MOUSEWHEEL) {
|
||||
if (event.type == SDL_MOUSEWHEEL) {
|
||||
static const float zoomstep = 2.0f;
|
||||
if (event.wheel.y > 0) {
|
||||
Environment::zoom -= zoomstep;
|
||||
@@ -756,7 +703,7 @@ namespace ZL
|
||||
Environment::zoom = zoomstep;
|
||||
}
|
||||
}
|
||||
else if (event.type == SDL_KEYUP)
|
||||
if (event.type == SDL_KEYUP)
|
||||
{
|
||||
if (event.key.keysym.sym == SDLK_i)
|
||||
{
|
||||
@@ -775,8 +722,65 @@ namespace ZL
|
||||
Environment::shipVelocity -= 50.f;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
render();
|
||||
}
|
||||
|
||||
void Game::handleDown(int mx, int my)
|
||||
{
|
||||
int uiX = mx;
|
||||
int uiY = Environment::height - my;
|
||||
|
||||
uiManager.onMouseDown(uiX, uiY);
|
||||
|
||||
bool uiHandled = false;
|
||||
|
||||
for (const auto& button : uiManager.findButton("") ? std::vector<std::shared_ptr<UiButton>>{} : std::vector<std::shared_ptr<UiButton>>{}) {
|
||||
(void)button;
|
||||
}
|
||||
|
||||
auto pressedSlider = [&]() -> std::shared_ptr<UiSlider> {
|
||||
for (const auto& slider : uiManager.findSlider("") ? std::vector<std::shared_ptr<UiSlider>>{} : std::vector<std::shared_ptr<UiSlider>>{}) {
|
||||
(void)slider;
|
||||
}
|
||||
return nullptr;
|
||||
}();
|
||||
|
||||
if (!uiManager.isUiInteraction()) {
|
||||
Environment::tapDownHold = true;
|
||||
|
||||
Environment::tapDownStartPos(0) = mx;
|
||||
Environment::tapDownStartPos(1) = my;
|
||||
|
||||
Environment::tapDownCurrentPos(0) = mx;
|
||||
Environment::tapDownCurrentPos(1) = my;
|
||||
}
|
||||
}
|
||||
void Game::handleUp(int mx, int my)
|
||||
{
|
||||
int uiX = mx;
|
||||
int uiY = Environment::height - my;
|
||||
|
||||
uiManager.onMouseUp(uiX, uiY);
|
||||
|
||||
if (!uiManager.isUiInteraction()) {
|
||||
Environment::tapDownHold = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Game::handleMotion(int mx, int my)
|
||||
{
|
||||
int uiX = mx;
|
||||
int uiY = Environment::height - my;
|
||||
|
||||
uiManager.onMouseMove(uiX, uiY);
|
||||
|
||||
if (Environment::tapDownHold && !uiManager.isUiInteraction()) {
|
||||
Environment::tapDownCurrentPos(0) = mx;
|
||||
Environment::tapDownCurrentPos(1) = my;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace ZL
|
||||
@@ -42,6 +42,10 @@ namespace ZL {
|
||||
|
||||
void fireProjectiles();
|
||||
|
||||
void handleDown(int mx, int my);
|
||||
void handleUp(int mx, int my);
|
||||
void handleMotion(int mx, int my);
|
||||
|
||||
SDL_Window* window;
|
||||
SDL_GLContext glContext;
|
||||
Renderer renderer;
|
||||
|
||||
+25
-10
@@ -4,7 +4,9 @@
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
namespace ZL
|
||||
{
|
||||
|
||||
@@ -224,25 +226,38 @@ namespace ZL
|
||||
VertexDataStruct LoadFromTextFile02(const std::string& fileName, const std::string& ZIPFileName)
|
||||
{
|
||||
VertexDataStruct result;
|
||||
std::ifstream filestream;
|
||||
std::istringstream zipStream;
|
||||
std::istringstream f;
|
||||
|
||||
// --- 1. Открытие потока (без изменений) ---
|
||||
if (!ZIPFileName.empty())
|
||||
{
|
||||
std::vector<char> fileData = readFileFromZIP(fileName, ZIPFileName);
|
||||
std::string fileContents(fileData.begin(), fileData.end());
|
||||
zipStream.str(fileContents);
|
||||
f.str(fileContents);
|
||||
}
|
||||
else
|
||||
{
|
||||
filestream.open(fileName);
|
||||
if (!filestream.is_open()) {
|
||||
throw std::runtime_error("Failed to open file: " + fileName);
|
||||
}
|
||||
}
|
||||
#ifdef __ANDROID__
|
||||
// Для Android используем SDL_RWops для чтения файлов
|
||||
__android_log_print(ANDROID_LOG_INFO, "TextModel",
|
||||
"LoadFromTextFile02 called for Android: %s", fileName.c_str());
|
||||
#endif
|
||||
// Читаем файл с помощью readTextFile
|
||||
std::string fileContent = readTextFile(fileName);
|
||||
if (fileContent.empty()) {
|
||||
#ifdef __ANDROID__
|
||||
__android_log_print(ANDROID_LOG_ERROR, "TextModel",
|
||||
"Failed to read file: %s", fileName.c_str());
|
||||
#endif
|
||||
throw std::runtime_error("Failed to read file: " + fileName);
|
||||
}
|
||||
|
||||
std::istream& f = (!ZIPFileName.empty()) ? static_cast<std::istream&>(zipStream) : static_cast<std::istream&>(filestream);
|
||||
#ifdef __ANDROID__
|
||||
__android_log_print(ANDROID_LOG_INFO, "TextModel",
|
||||
"File read successfully, size: %zu", fileContent.size());
|
||||
#endif
|
||||
f.str(fileContent);
|
||||
}
|
||||
|
||||
std::string tempLine;
|
||||
std::smatch match;
|
||||
|
||||
+98
-1
@@ -1,14 +1,110 @@
|
||||
#include "Game.h"
|
||||
#include "Environment.h"
|
||||
#include <iostream>
|
||||
#ifdef __ANDROID__
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
|
||||
|
||||
ZL::Game game;
|
||||
|
||||
|
||||
void MainLoop() {
|
||||
game.update();
|
||||
}
|
||||
int main(int argc, char* argv[]) {
|
||||
|
||||
|
||||
#ifdef __ANDROID__
|
||||
|
||||
extern "C" int SDL_main(int argc, char* argv[]) {
|
||||
// Инициализация SDL перед получением информации о дисплее
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) != 0) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "Game", "SDL init failed: %s", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
SDL_DisplayMode displayMode;
|
||||
if (SDL_GetCurrentDisplayMode(0, &displayMode) != 0) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "Game", "SDL_GetCurrentDisplayMode failed: %s", SDL_GetError());
|
||||
SDL_Quit();
|
||||
return 1;
|
||||
}
|
||||
ZL::Environment::width = displayMode.w;
|
||||
ZL::Environment::height = displayMode.h;
|
||||
|
||||
__android_log_print(ANDROID_LOG_INFO, "Game", "Display resolution: %dx%d",
|
||||
ZL::Environment::width, ZL::Environment::height);
|
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
|
||||
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);
|
||||
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
|
||||
|
||||
ZL::Environment::window = SDL_CreateWindow(
|
||||
"Space Ship Game",
|
||||
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
||||
ZL::Environment::width, ZL::Environment::height,
|
||||
SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN
|
||||
);
|
||||
|
||||
if (!ZL::Environment::window) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "Game", "Failed to create window: %s", SDL_GetError());
|
||||
SDL_Quit();
|
||||
return 1;
|
||||
}
|
||||
|
||||
SDL_GLContext ctx = SDL_GL_CreateContext(ZL::Environment::window);
|
||||
if (!ctx) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "Game", "SDL_GL_CreateContext failed: %s", SDL_GetError());
|
||||
SDL_DestroyWindow(ZL::Environment::window);
|
||||
SDL_Quit();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (SDL_GL_MakeCurrent(ZL::Environment::window, ctx) != 0) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "Game", "SDL_GL_MakeCurrent failed: %s", SDL_GetError());
|
||||
SDL_GL_DeleteContext(ctx);
|
||||
SDL_DestroyWindow(ZL::Environment::window);
|
||||
SDL_Quit();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Настройка VSync
|
||||
if (SDL_GL_SetSwapInterval(1) < 0) {
|
||||
__android_log_print(ANDROID_LOG_WARN, "Game", "Unable to set VSync: %s", SDL_GetError());
|
||||
}
|
||||
|
||||
// Настройка игры
|
||||
try {
|
||||
game.setup();
|
||||
} catch (const std::exception &e) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "Game", "Game setup failed: %s", e.what());
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (!game.shouldExit()) {
|
||||
game.update();
|
||||
SDL_Delay(16);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
try
|
||||
{
|
||||
|
||||
|
||||
constexpr int CONST_WIDTH = 1280;
|
||||
constexpr int CONST_HEIGHT = 720;
|
||||
|
||||
@@ -86,3 +182,4 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
namespace ZL {
|
||||
|
||||
#ifdef EMSCRIPTEN
|
||||
#if defined EMSCRIPTEN || defined __ANDROID__
|
||||
using std::min;
|
||||
using std::max;
|
||||
#endif
|
||||
@@ -75,8 +75,8 @@ namespace ZL {
|
||||
planetRenderStruct.RefreshVBO();
|
||||
|
||||
|
||||
sandTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/sand2.png", CONST_ZIP_FILE));
|
||||
stoneTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/rockdark3.png", CONST_ZIP_FILE));
|
||||
sandTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/sand2.png", CONST_ZIP_FILE));
|
||||
stoneTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/rockdark3.png", CONST_ZIP_FILE));
|
||||
|
||||
// Атмосфера
|
||||
planetAtmosphereRenderStruct.data = planetData.getAtmosphereLod().vertexData;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "StoneObject.h"
|
||||
|
||||
#include "utils/Utils.h"
|
||||
#include <GL/gl.h>
|
||||
#include <random>
|
||||
#include <cmath>
|
||||
#include "render/Renderer.h"
|
||||
@@ -9,7 +8,7 @@
|
||||
|
||||
namespace ZL {
|
||||
|
||||
#ifdef EMSCRIPTEN
|
||||
#if defined EMSCRIPTEN || defined __ANDROID__
|
||||
using std::min;
|
||||
using std::max;
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "OpenGlExtensions.h"
|
||||
#include "render/OpenGlExtensions.h"
|
||||
#include <memory>
|
||||
|
||||
namespace ZL {
|
||||
@@ -9,10 +9,10 @@ namespace ZL {
|
||||
GLuint fbo = 0;
|
||||
GLuint textureID = 0;
|
||||
int width, height;
|
||||
bool useMipmaps; // Флаг использования мип-мапов
|
||||
bool useMipmaps; // ���� ������������� ���-�����
|
||||
|
||||
public:
|
||||
// Добавляем параметр в конструктор по умолчанию false
|
||||
// ��������� �������� � ����������� �� ��������� false
|
||||
FrameBuffer(int w, int h, bool useMipmaps = false);
|
||||
~FrameBuffer();
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace ZL {
|
||||
void Bind();
|
||||
void Unbind();
|
||||
|
||||
// Метод для принудительной генерации мип-мапов после рендера
|
||||
// ����� ��� �������������� ��������� ���-����� ����� �������
|
||||
void GenerateMipmaps();
|
||||
|
||||
GLuint getTextureID() const { return textureID; }
|
||||
|
||||
@@ -10,13 +10,17 @@
|
||||
#include "emscripten.h"
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include <GLES3/gl3.h>
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
#else
|
||||
#ifdef __linux__
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include <GLES3/gl3.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
|
||||
|
||||
+11
-4
@@ -50,17 +50,17 @@ namespace ZL {
|
||||
|
||||
Matrix4f r;
|
||||
|
||||
// Масштабирование
|
||||
// ���������������
|
||||
r.data()[0] = 2.f / width;
|
||||
r.data()[5] = 2.f / height;
|
||||
r.data()[10] = -1.f / depthRange;
|
||||
|
||||
// Обнуление неиспользуемых компонентов
|
||||
// ��������� �������������� �����������
|
||||
r.data()[1] = r.data()[2] = r.data()[3] = 0;
|
||||
r.data()[4] = r.data()[6] = r.data()[7] = 0;
|
||||
r.data()[8] = r.data()[9] = r.data()[11] = 0;
|
||||
|
||||
// Трансляция (смещение)
|
||||
// ���������� (��������)
|
||||
r.data()[12] = -(xmax + xmin) / width;
|
||||
r.data()[13] = -(ymax + ymin) / height;
|
||||
r.data()[14] = zNear / depthRange;
|
||||
@@ -120,20 +120,23 @@ namespace ZL {
|
||||
VAOHolder::VAOHolder()
|
||||
{
|
||||
#ifndef EMSCRIPTEN
|
||||
#ifndef ANDROID
|
||||
glGenVertexArrays(1, &vao);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
VAOHolder::~VAOHolder()
|
||||
{
|
||||
#ifndef EMSCRIPTEN
|
||||
|
||||
#ifndef ANDROID
|
||||
#ifdef __linux__
|
||||
glDeleteVertexArrays(1, &vao);
|
||||
#else
|
||||
//Windows
|
||||
glDeleteVertexArray(1, &vao);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -365,12 +368,14 @@ namespace ZL {
|
||||
//Check if main thread, check if data is not empty...
|
||||
|
||||
#ifndef EMSCRIPTEN
|
||||
#ifndef __ANDROID__
|
||||
if (!vao)
|
||||
{
|
||||
vao = std::make_shared<VAOHolder>();
|
||||
}
|
||||
|
||||
glBindVertexArray(vao->getBuffer());
|
||||
#endif
|
||||
#endif
|
||||
if (!positionVBO)
|
||||
{
|
||||
@@ -509,7 +514,9 @@ namespace ZL {
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
#ifndef EMSCRIPTEN
|
||||
#ifndef __ANDROID__
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
#endif
|
||||
#endif
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "OpenGlExtensions.h"
|
||||
#include "render/OpenGlExtensions.h"
|
||||
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
#include "ShaderManager.h"
|
||||
|
||||
+182
-187
@@ -1,227 +1,222 @@
|
||||
#include "ShaderManager.h"
|
||||
#include <iostream>
|
||||
#include <SDL.h>
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
|
||||
namespace ZL {
|
||||
|
||||
ShaderResource::ShaderResource(const std::string& vertexCode, const std::string& fragmentCode)
|
||||
{
|
||||
ShaderResource::ShaderResource(const std::string &vertexCode, const std::string &fragmentCode) {
|
||||
|
||||
const int CONST_INFOLOG_LENGTH = 256;
|
||||
const int CONST_INFOLOG_LENGTH = 256;
|
||||
|
||||
char infoLog[CONST_INFOLOG_LENGTH];
|
||||
int infoLogLength;
|
||||
char infoLog2[CONST_INFOLOG_LENGTH];
|
||||
int infoLogLength2;
|
||||
char infoLog[CONST_INFOLOG_LENGTH];
|
||||
int infoLogLength;
|
||||
|
||||
int vertexShaderCompiled;
|
||||
int fragmentShaderCompiled;
|
||||
int programLinked;
|
||||
int vertexShaderCompiled;
|
||||
int fragmentShaderCompiled;
|
||||
int programLinked;
|
||||
|
||||
GLuint vertexShader;
|
||||
GLuint fragmentShader;
|
||||
GLuint vertexShader;
|
||||
GLuint fragmentShader;
|
||||
|
||||
int vertexCodeLength = static_cast<int>(strlen(vertexCode.c_str()));
|
||||
int fragmentCodeLength = static_cast<int>(strlen(fragmentCode.c_str()));
|
||||
int vertexCodeLength = static_cast<int>(strlen(vertexCode.c_str()));
|
||||
int fragmentCodeLength = static_cast<int>(strlen(fragmentCode.c_str()));
|
||||
|
||||
const char* vc = &vertexCode[0];
|
||||
const char* fc = &fragmentCode[0];
|
||||
const char *vc = &vertexCode[0];
|
||||
const char *fc = &fragmentCode[0];
|
||||
|
||||
vertexShader = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vertexShader, 1, &(vc), &vertexCodeLength);
|
||||
vertexShader = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vertexShader, 1, &(vc), &vertexCodeLength);
|
||||
|
||||
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fragmentShader, 1, &(fc), &fragmentCodeLength);
|
||||
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(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);
|
||||
glCompileShader(fragmentShader);
|
||||
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &fragmentShaderCompiled);
|
||||
glGetShaderInfoLog(fragmentShader, CONST_INFOLOG_LENGTH, &infoLogLength, infoLog);
|
||||
|
||||
|
||||
if (!vertexShaderCompiled)
|
||||
{
|
||||
#ifdef EMSCRIPTEN
|
||||
std::cout << "Failed to compile vertex shader code!" << std::endl;
|
||||
std::cout << infoLog << std::endl;
|
||||
if (!vertexShaderCompiled) {
|
||||
#ifdef __ANDROID__
|
||||
__android_log_print(ANDROID_LOG_ERROR, "ShaderManager",
|
||||
"Failed to compile vertex shader: %s", infoLog);
|
||||
#endif
|
||||
throw std::runtime_error("Failed to compile vertex shader code!");
|
||||
}
|
||||
|
||||
if (!fragmentShaderCompiled)
|
||||
{
|
||||
#ifdef EMSCRIPTEN
|
||||
std::cout << "Failed to compile fragment shader code!" << std::endl;
|
||||
std::cout << infoLog2 << std::endl;
|
||||
throw std::runtime_error("Failed to compile vertex shader code!");
|
||||
}
|
||||
|
||||
if (!fragmentShaderCompiled) {
|
||||
#ifdef __ANDROID__
|
||||
__android_log_print(ANDROID_LOG_ERROR, "ShaderManager",
|
||||
"Failed to compile fragment shader: %s", infoLog);
|
||||
#endif
|
||||
throw std::runtime_error("Failed to compile fragment shader code!");
|
||||
}
|
||||
throw std::runtime_error("Failed to compile fragment shader code!");
|
||||
}
|
||||
|
||||
shaderProgram = glCreateProgram();
|
||||
shaderProgram = glCreateProgram();
|
||||
|
||||
glAttachShader(shaderProgram, vertexShader);
|
||||
glAttachShader(shaderProgram, fragmentShader);
|
||||
glAttachShader(shaderProgram, vertexShader);
|
||||
glAttachShader(shaderProgram, fragmentShader);
|
||||
|
||||
glLinkProgram(shaderProgram);
|
||||
glLinkProgram(shaderProgram);
|
||||
|
||||
glDeleteShader(vertexShader);
|
||||
glDeleteShader(fragmentShader);
|
||||
glDeleteShader(vertexShader);
|
||||
glDeleteShader(fragmentShader);
|
||||
|
||||
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &programLinked);
|
||||
glGetProgramInfoLog(shaderProgram, CONST_INFOLOG_LENGTH, &infoLogLength, infoLog);
|
||||
|
||||
if (!programLinked)
|
||||
{
|
||||
#ifdef EMSCRIPTEN
|
||||
std::cout << "Failed to link shader program!" << std::endl;
|
||||
std::cout << infoLog << std::endl;
|
||||
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &programLinked);
|
||||
glGetProgramInfoLog(shaderProgram, CONST_INFOLOG_LENGTH, &infoLogLength, infoLog);
|
||||
|
||||
if (!programLinked) {
|
||||
shaderProgram = 0;
|
||||
#ifdef __ANDROID__
|
||||
__android_log_print(ANDROID_LOG_ERROR, "ShaderManager",
|
||||
"Failed to link shader program: %s", infoLog);
|
||||
#endif
|
||||
shaderProgram = 0;
|
||||
throw std::runtime_error("Failed to link shader program!");
|
||||
}
|
||||
throw std::runtime_error("Failed to link shader program!");
|
||||
}
|
||||
|
||||
//================= Parsing all uniforms ================
|
||||
|
||||
int dummySize; //Dummy
|
||||
int dummyLen; //Dummy
|
||||
GLenum dummyEnum;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
#ifdef __ANDROID__
|
||||
__android_log_print(ANDROID_LOG_INFO, "ShaderManager",
|
||||
"Shader created successfully, program ID: %u", shaderProgram);
|
||||
#endif
|
||||
}
|
||||
|
||||
ShaderResource::~ShaderResource() {
|
||||
if (shaderProgram != 0) {
|
||||
glDeleteProgram(shaderProgram);
|
||||
|
||||
shaderProgram = 0;
|
||||
}
|
||||
}
|
||||
|
||||
GLuint ShaderResource::getShaderProgram() {
|
||||
return shaderProgram;
|
||||
}
|
||||
|
||||
|
||||
int dummySize; //Dummy
|
||||
int dummyLen; //Dummy
|
||||
GLenum dummyEnum;
|
||||
void ShaderManager::AddShaderFromFiles(const std::string &shaderName,
|
||||
const std::string &vertexShaderFileName,
|
||||
const std::string &fragmentShaderFileName,
|
||||
const std::string &ZIPFileName) {
|
||||
#ifdef __ANDROID__
|
||||
__android_log_print(ANDROID_LOG_INFO, "ShaderManager",
|
||||
"Loading shader: %s", shaderName.c_str());
|
||||
__android_log_print(ANDROID_LOG_INFO, "ShaderManager",
|
||||
"Vertex shader: %s", vertexShaderFileName.c_str());
|
||||
__android_log_print(ANDROID_LOG_INFO, "ShaderManager",
|
||||
"Fragment shader: %s", fragmentShaderFileName.c_str());
|
||||
#endif
|
||||
|
||||
std::string vertexShader;
|
||||
std::string fragmentShader;
|
||||
|
||||
if (!ZIPFileName.empty()) {
|
||||
|
||||
std::vector<char> vertexShaderData;
|
||||
std::vector<char> 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<ShaderResource>(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());
|
||||
}
|
||||
|
||||
|
||||
//================= Parsing all uniforms ================
|
||||
void ShaderManager::PopShader() {
|
||||
if (shaderStack.size() == 0) {
|
||||
throw std::runtime_error("Shader stack underflow!");
|
||||
}
|
||||
|
||||
int activeUniforms;
|
||||
shaderStack.pop();
|
||||
|
||||
const int CONST_UNIFORM_NAME_LENGTH = 256;
|
||||
char uniformName[CONST_UNIFORM_NAME_LENGTH];
|
||||
if (shaderStack.size() == 0) {
|
||||
glUseProgram(0);
|
||||
} else {
|
||||
glUseProgram(shaderResourceMap[shaderStack.top()]->getShaderProgram());
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
std::shared_ptr <ShaderResource> ShaderManager::GetCurrentShader() {
|
||||
if (shaderStack.size() == 0) {
|
||||
throw std::runtime_error("Shader stack underflow!");
|
||||
}
|
||||
|
||||
|
||||
void ShaderManager::AddShaderFromFiles(const std::string& shaderName, const std::string& vertexShaderFileName, const std::string& fragmentShaderFileName, const std::string& ZIPFileName)
|
||||
{
|
||||
return shaderResourceMap[shaderStack.top()];
|
||||
|
||||
std::string vertexShader;
|
||||
std::string fragmentShader;
|
||||
|
||||
if (!ZIPFileName.empty()){
|
||||
|
||||
std::vector<char> vertexShaderData;
|
||||
std::vector<char> 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<ShaderResource>(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!");
|
||||
}
|
||||
ShaderSetter::ShaderSetter(ShaderManager &inShaderManager, const std::string &shaderName)
|
||||
: shaderManager(inShaderManager) {
|
||||
shaderManager.PushShader(shaderName);
|
||||
}
|
||||
|
||||
shaderStack.pop();
|
||||
|
||||
if (shaderStack.size() == 0)
|
||||
{
|
||||
glUseProgram(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
glUseProgram(shaderResourceMap[shaderStack.top()]->getShaderProgram());
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<ShaderResource> 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(inShaderManager)
|
||||
{
|
||||
shaderManager.PushShader(shaderName);
|
||||
}
|
||||
|
||||
ShaderSetter::~ShaderSetter()
|
||||
{
|
||||
shaderManager.PopShader();
|
||||
}
|
||||
ShaderSetter::~ShaderSetter() {
|
||||
shaderManager.PopShader();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "OpenGlExtensions.h"
|
||||
|
||||
#include "render/OpenGlExtensions.h"
|
||||
#include "utils/Utils.h"
|
||||
|
||||
namespace ZL {
|
||||
|
||||
@@ -20,20 +20,20 @@ namespace ZL
|
||||
glBindTexture(GL_TEXTURE_2D, texID);
|
||||
CheckGlError();
|
||||
|
||||
// Настройка фильтрации в зависимости от выбранного типа
|
||||
// ��������� ���������� � ����������� �� ���������� ����
|
||||
if (texData.mipmap == TextureDataStruct::GENERATE) {
|
||||
// Используем трилинейную фильтрацию для устранения мерцания
|
||||
// ���������� ����������� ���������� ��� ���������� ��������
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
}
|
||||
else {
|
||||
// Обычная линейная фильтрация (будет мерцать на удалении)
|
||||
// ������� �������� ���������� (����� ������� �� ��������)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
CheckGlError();
|
||||
|
||||
// Загрузка данных базового уровня (Level 0)
|
||||
// �������� ������ �������� ������ (Level 0)
|
||||
GLint format = (texData.bitSize == TextureDataStruct::BS_24BIT) ? GL_RGB : GL_RGBA;
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format,
|
||||
@@ -43,7 +43,7 @@ namespace ZL
|
||||
|
||||
CheckGlError();
|
||||
|
||||
// Генерация мип-мапов, если это необходимо
|
||||
// ��������� ���-�����, ���� ��� ����������
|
||||
if (texData.mipmap == TextureDataStruct::GENERATE) {
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
CheckGlError();
|
||||
@@ -52,7 +52,7 @@ namespace ZL
|
||||
|
||||
Texture::Texture(const std::array<TextureDataStruct, 6>& texDataArray)
|
||||
{
|
||||
// Проверка, что все грани имеют одинаковые размеры
|
||||
// ��������, ��� ��� ����� ����� ���������� �������
|
||||
width = texDataArray[0].width;
|
||||
height = texDataArray[0].height;
|
||||
|
||||
@@ -73,33 +73,35 @@ namespace ZL
|
||||
|
||||
CheckGlError();
|
||||
|
||||
// Настройка параметров для Cubemap
|
||||
// ��������� ���������� ��� Cubemap
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
// Используем GL_LINEAR для MIN_FILTER, так как мипмапы здесь не генерируются
|
||||
// Если бы использовались мипмапы (e.g., GL_LINEAR_MIPMAP_LINEAR), нужно было бы вызвать glGenerateMipmap.
|
||||
// ���������� GL_LINEAR ��� MIN_FILTER, ��� ��� ������� ����� �� ������������
|
||||
// ���� �� �������������� ������� (e.g., GL_LINEAR_MIPMAP_LINEAR), ����� ���� �� ������� glGenerateMipmap.
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
// Обязательные параметры обертки для Cubemap
|
||||
// ������������ ��������� ������� ��� 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 и вызывает ошибку.
|
||||
// Ограничиваем его вызов только для настольных платформ.
|
||||
// GL_TEXTURE_WRAP_R �� �������������� � WebGL 1.0/OpenGL ES 2.0 � �������� ������.
|
||||
// ������������ ��� ����� ������ ��� ���������� ��������.
|
||||
#ifndef EMSCRIPTEN
|
||||
#ifndef __ANDROID__
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
CheckGlError(); // Проверка после установки параметров
|
||||
CheckGlError(); // �������� ����� ��������� ����������
|
||||
|
||||
// Загрузка данных для каждой из 6 граней
|
||||
// GL_TEXTURE_CUBE_MAP_POSITIVE_X + i дает грани: +X (0), -X (1), +Y (2), -Y (3), +Z (4), -Z (5)
|
||||
// �������� ������ ��� ������ �� 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).
|
||||
// � WebGL 1.0/OpenGL ES 2.0 ���������� ������ (internalFormat)
|
||||
// ������ ������ ��������������� ������� ������ (format).
|
||||
if (texDataArray[i].bitSize == TextureDataStruct::BS_24BIT)
|
||||
{
|
||||
internalFormat = GL_RGB; // internalFormat
|
||||
@@ -112,20 +114,20 @@ namespace ZL
|
||||
}
|
||||
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, // Целевая грань
|
||||
0, // Уровень MIP-текстуры
|
||||
internalFormat, // Внутренний формат (должен совпадать с форматом)
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, // ������� �����
|
||||
0, // ������� MIP-��������
|
||||
internalFormat, // ���������� ������ (������ ��������� � ��������)
|
||||
static_cast<GLsizei>(width),
|
||||
static_cast<GLsizei>(height),
|
||||
0, // Граница (всегда 0)
|
||||
format, // Формат исходных данных
|
||||
GL_UNSIGNED_BYTE, // Тип данных
|
||||
texDataArray[i].data.data() // Указатель на данные
|
||||
0, // ������� (������ 0)
|
||||
format, // ������ �������� ������
|
||||
GL_UNSIGNED_BYTE, // ��� ������
|
||||
texDataArray[i].data.data() // ��������� �� ������
|
||||
);
|
||||
CheckGlError();
|
||||
}
|
||||
|
||||
// Снимаем привязку для чистоты
|
||||
// ������� �������� ��� �������
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||
}
|
||||
|
||||
@@ -253,48 +255,48 @@ namespace ZL
|
||||
|
||||
#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' - сколько байт нужно прочитать
|
||||
// ���������������� ������� ������ ��� 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, ������� �� ���������� � ������� 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.
|
||||
// ������� ��������� ������, ��� ���� � �������.
|
||||
// ������ ������ ����������� ������, �� ����� ������ ��������� ������� ��� ������� ������.
|
||||
// � ���� ������ �� ������� ������ libpng.
|
||||
png_error(png_ptr, "PNG Read Error: Attempted to read past end of data buffer.");
|
||||
bytes_to_read = data->size - data->offset; // Устанавливаем, чтобы прочитать оставшееся
|
||||
bytes_to_read = data->size - data->offset; // �������������, ����� ��������� ����������
|
||||
}
|
||||
|
||||
// Копируем данные из нашего массива в буфер libpng
|
||||
// �������� ������ �� ������ ������� � ����� libpng
|
||||
std::memcpy(out_ptr, data->data + data->offset, bytes_to_read);
|
||||
|
||||
// Обновляем смещение
|
||||
// ��������� ��������
|
||||
data->offset += bytes_to_read;
|
||||
}
|
||||
|
||||
// Пользовательская функция предупреждений (по желанию, можно использовать nullptr)
|
||||
// ���������������� ������� �������������� (�� �������, ����� ������������ 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)
|
||||
// ���������������� ������� ������ (����������� ��� 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
|
||||
longjmp(png_jmpbuf(png_ptr), 1);
|
||||
}
|
||||
|
||||
@@ -302,7 +304,7 @@ namespace ZL
|
||||
{
|
||||
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);
|
||||
@@ -316,18 +318,18 @@ namespace ZL
|
||||
throw std::runtime_error("Could not create PNG info structure");
|
||||
}
|
||||
|
||||
// === Установка пользовательских функций чтения и обработки ошибок ===
|
||||
// 1. Установка обработчика ошибок и longjmp
|
||||
// === ��������� ���������������� ������� ������ � ��������� ������ ===
|
||||
// 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 можно передать указатель на свою структуру данных, если необходимо
|
||||
// 2. ��������� ���������������� ������� ��� ��������� ������ � ��������������
|
||||
// ������ nullptr � error_ptr � warning_ptr ����� �������� ��������� �� ���� ��������� ������, ���� ����������
|
||||
png_set_error_fn(png, nullptr, user_error_fn, user_warning_fn);
|
||||
|
||||
// 3. Установка пользовательской функции чтения и передача ей нашей структуры png_data
|
||||
// 3. ��������� ���������������� ������� ������ � �������� �� ����� ��������� png_data
|
||||
png_set_read_fn(png, &png_data, user_read_data);
|
||||
// ===================================================================
|
||||
|
||||
@@ -338,7 +340,7 @@ namespace ZL
|
||||
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);
|
||||
|
||||
@@ -363,7 +365,7 @@ namespace ZL
|
||||
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));
|
||||
@@ -422,7 +424,7 @@ namespace ZL
|
||||
throw std::runtime_error("Could not read file data into memory");
|
||||
}
|
||||
|
||||
// Вызываем новую функцию, которая работает с массивом байт
|
||||
// �������� ����� �������, ������� �������� � �������� ����
|
||||
return CreateTextureDataFromPng(fileArr);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "OpenGlExtensions.h"
|
||||
#include "render/OpenGlExtensions.h"
|
||||
#include "utils/Utils.h"
|
||||
|
||||
#ifdef EMSCRIPTEN
|
||||
#if defined EMSCRIPTEN || defined __ANDROID__
|
||||
#define PNG_ENABLED
|
||||
#endif
|
||||
|
||||
@@ -20,17 +20,17 @@ namespace ZL
|
||||
BS_32BIT
|
||||
};
|
||||
|
||||
// Íîâîå ïåðå÷èñëåíèå äëÿ óïðàâëåíèÿ ìèï-ìàïïèíãîì
|
||||
// ����� ������������ ��� ���������� ���-���������
|
||||
enum MipmapType {
|
||||
NONE, // Áåç ìèï-ìàïîâ (GL_LINEAR)
|
||||
GENERATE // Àâòîìàòè÷åñêàÿ ãåíåðàöèÿ (GL_LINEAR_MIPMAP_LINEAR)
|
||||
NONE, // ��� ���-����� (GL_LINEAR)
|
||||
GENERATE // �������������� ��������� (GL_LINEAR_MIPMAP_LINEAR)
|
||||
};
|
||||
|
||||
BitSize bitSize;
|
||||
/*#ifdef SIMPLIFIED
|
||||
MipmapType mipmap = NONE; // Ïî óìîë÷àíèþ âêëþ÷åíî
|
||||
MipmapType mipmap = NONE; // �� ��������� ��������
|
||||
#else*/
|
||||
MipmapType mipmap = GENERATE; // Ïî óìîë÷àíèþ âêëþ÷åíî
|
||||
MipmapType mipmap = GENERATE; // �� ��������� ��������
|
||||
//#endif
|
||||
};
|
||||
class Texture
|
||||
|
||||
+72
-21
@@ -10,40 +10,91 @@
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <cctype>
|
||||
#include <SDL.h>
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
|
||||
namespace ZL
|
||||
{
|
||||
std::string readTextFile(const std::string &filename) {
|
||||
#ifdef __ANDROID__
|
||||
SDL_RWops* file = SDL_RWFromFile(filename.c_str(), "rb");
|
||||
if (!file) {
|
||||
#ifdef DEBUG
|
||||
__android_log_print(ANDROID_LOG_ERROR, "Utils",
|
||||
"Failed to open: %s", filename.c_str());
|
||||
#endif
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string readTextFile(const std::string& filename)
|
||||
{
|
||||
std::ifstream f(filename);
|
||||
Sint64 size = SDL_RWsize(file);
|
||||
if (size <= 0) {
|
||||
SDL_RWclose(file);
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string str((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());
|
||||
std::string content(size, '\0');
|
||||
if (SDL_RWread(file, &content[0], size, 1) != 1) {
|
||||
SDL_RWclose(file);
|
||||
return "";
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
SDL_RWclose(file);
|
||||
return content;
|
||||
#else
|
||||
std::ifstream f(filename);
|
||||
if (!f.is_open()) {
|
||||
return "";
|
||||
}
|
||||
return std::string((std::istreambuf_iterator<char>(f)),
|
||||
std::istreambuf_iterator<char>());
|
||||
#endif
|
||||
}
|
||||
|
||||
std::vector<char> readFile(const std::string& filename)
|
||||
{
|
||||
std::ifstream file(filename, std::ios::binary);
|
||||
std::vector<char> readFile(const std::string &filename) {
|
||||
#ifdef __ANDROID__
|
||||
SDL_RWops* file = SDL_RWFromFile(filename.c_str(), "rb");
|
||||
if (!file) {
|
||||
return {};
|
||||
}
|
||||
|
||||
file.unsetf(std::ios::skipws);
|
||||
Sint64 size = SDL_RWsize(file);
|
||||
if (size <= 0) {
|
||||
SDL_RWclose(file);
|
||||
return {};
|
||||
}
|
||||
|
||||
std::streampos fileSize;
|
||||
std::vector<char> data(size);
|
||||
if (SDL_RWread(file, data.data(), size, 1) != 1) {
|
||||
SDL_RWclose(file);
|
||||
return {};
|
||||
}
|
||||
|
||||
file.seekg(0, std::ios::end);
|
||||
fileSize = file.tellg();
|
||||
file.seekg(0, std::ios::beg);
|
||||
SDL_RWclose(file);
|
||||
return data;
|
||||
#else
|
||||
std::ifstream file(filename, std::ios::binary | std::ios::ate);
|
||||
if (!file) {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<char> vec;
|
||||
vec.reserve(static_cast<size_t>(fileSize));
|
||||
std::streamsize size = file.tellg();
|
||||
if (size <= 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
vec.insert(vec.begin(),
|
||||
std::istream_iterator<char>(file),
|
||||
std::istream_iterator<char>());
|
||||
file.seekg(0, std::ios::beg);
|
||||
std::vector<char> buffer(size);
|
||||
|
||||
return vec;
|
||||
}
|
||||
if (!file.read(buffer.data(), size)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return buffer;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::vector<char> readFileFromZIP(const std::string& filename, const std::string& zipfilename) {
|
||||
#ifdef EMSCRIPTEN
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#include <stack>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <array>
|
||||
|
||||
namespace ZL
|
||||
{
|
||||
std::string readTextFile(const std::string& filename);
|
||||
|
||||
Reference in new issue
Block a user