From 38f4f6b7fc97cfe86007869c4fc9688c6797eb99 Mon Sep 17 00:00:00 2001 From: Vladislav Khorev Date: Sun, 7 Dec 2025 16:46:43 +0300 Subject: [PATCH] Working on web --- Game.cpp | 40 +++++------ Readme.md | 9 ++- TextureManager.cpp | 28 +++++--- TextureManager.h | 4 ++ Utils.cpp | 11 ++- main.cpp | 106 ++++++++++++++++------------- shaders/env_desktop.fragment | 8 +++ shaders/env_reverse.fragment | 21 ------ shaders/env_reverse.vertex | 14 ---- shaders/env_reverse_night.fragment | 21 ------ shaders/env_reverse_night.vertex | 14 ---- shaders/env_web.fragment | 7 ++ 12 files changed, 131 insertions(+), 152 deletions(-) create mode 100644 shaders/env_desktop.fragment delete mode 100644 shaders/env_reverse.fragment delete mode 100644 shaders/env_reverse.vertex delete mode 100644 shaders/env_reverse_night.fragment delete mode 100644 shaders/env_reverse_night.vertex create mode 100644 shaders/env_web.fragment diff --git a/Game.cpp b/Game.cpp index f451428..cd98935 100755 --- a/Game.cpp +++ b/Game.cpp @@ -9,8 +9,11 @@ namespace ZL { +#ifdef EMSCRIPTEN + const char* CONST_ZIP_FILE = "space-game001.zip"; +#else const char* CONST_ZIP_FILE = ""; - +#endif Game::Game() : window(nullptr) , glContext(nullptr) @@ -40,24 +43,23 @@ void Game::setup() { #ifdef EMSCRIPTEN renderer.shaderManager.AddShaderFromFiles("default", "./shaders/default.vertex", "./shaders/default_web.fragment", CONST_ZIP_FILE); renderer.shaderManager.AddShaderFromFiles("defaultColor", "./shaders/defaultColor.vertex", "./shaders/defaultColor_web.fragment", CONST_ZIP_FILE); + renderer.shaderManager.AddShaderFromFiles("env", "./shaders/env.vertex", "./shaders/env_web.fragment", CONST_ZIP_FILE); + #else renderer.shaderManager.AddShaderFromFiles("default", "./shaders/default.vertex", "./shaders/default_desktop.fragment", CONST_ZIP_FILE); renderer.shaderManager.AddShaderFromFiles("defaultColor", "./shaders/defaultColor.vertex", "./shaders/defaultColor_desktop.fragment", CONST_ZIP_FILE); + renderer.shaderManager.AddShaderFromFiles("env", "./shaders/env.vertex", "./shaders/env_desktop.fragment", CONST_ZIP_FILE); + #endif - renderer.shaderManager.AddShaderFromFiles("env", "./shaders/env.vertex", "./shaders/env.fragment", CONST_ZIP_FILE); - - - // std::array cubemapTextureNightStr = { -//"../resources/sky/space_rt.bmp", "../resources/sky/space_lf.bmp", "../resources/sky/space_up.bmp", "../resources/sky/space_dn.bmp", "../resources/sky/space_bk.bmp", "../resources/sky/space_ft.bmp" -// }; + cubemapTexture = std::make_shared( std::array{ - CreateTextureDataFromBmp24("./resources/sky/space_rt.bmp"), - CreateTextureDataFromBmp24("./resources/sky/space_lf.bmp"), - CreateTextureDataFromBmp24("./resources/sky/space_up.bmp"), - CreateTextureDataFromBmp24("./resources/sky/space_dn.bmp"), - CreateTextureDataFromBmp24("./resources/sky/space_bk.bmp"), - CreateTextureDataFromBmp24("./resources/sky/space_ft.bmp") + CreateTextureDataFromBmp24("./resources/sky/space_rt.bmp", CONST_ZIP_FILE), + CreateTextureDataFromBmp24("./resources/sky/space_lf.bmp", CONST_ZIP_FILE), + CreateTextureDataFromBmp24("./resources/sky/space_up.bmp", CONST_ZIP_FILE), + CreateTextureDataFromBmp24("./resources/sky/space_dn.bmp", CONST_ZIP_FILE), + CreateTextureDataFromBmp24("./resources/sky/space_bk.bmp", CONST_ZIP_FILE), + CreateTextureDataFromBmp24("./resources/sky/space_ft.bmp", CONST_ZIP_FILE) }); @@ -65,15 +67,15 @@ void Game::setup() { cubemap.RefreshVBO(); //Load texture - spaceshipTexture = std::make_unique(CreateTextureDataFromPng("./resources/DefaultMaterial_BaseColor.png")); - spaceshipBase = LoadFromTextFile02("./resources/spaceship005.txt"); + spaceshipTexture = std::make_unique(CreateTextureDataFromBmp24("./resources/DefaultMaterial_BaseColor.bmp", CONST_ZIP_FILE)); + spaceshipBase = LoadFromTextFile02("./resources/spaceship005.txt", CONST_ZIP_FILE); spaceshipBase.RotateByMatrix(QuatToMatrix(QuatFromRotateAroundY(M_PI / 2.0))); spaceshipBase.Move(Vector3f{ -0.52998, -13, 0 }); spaceship.AssignFrom(spaceshipBase); spaceship.RefreshVBO(); - + renderer.InitOpenGL(); } @@ -88,7 +90,7 @@ void Game::drawScene() { glClearColor(0.0f, 0.5f, 1.0f, 1.0f); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - + glViewport(0, 0, Environment::width, Environment::height); CheckGlError(); @@ -118,7 +120,7 @@ void Game::drawScene() { renderer.shaderManager.PopShader(); CheckGlError(); - + renderer.shaderManager.PushShader(defaultShaderName); renderer.RenderUniform1i(textureUniformName, 0); renderer.EnableVertexAttribArray(vPositionName); @@ -143,7 +145,7 @@ void Game::drawScene() { renderer.DisableVertexAttribArray(vTexCoordName); renderer.shaderManager.PopShader(); - + CheckGlError(); } diff --git a/Readme.md b/Readme.md index 2d5180a..a4b3b98 100644 --- a/Readme.md +++ b/Readme.md @@ -3,7 +3,7 @@ ``` C:\Work\Projects\emsdk\emsdk.bat activate latest C:\Work\Projects\emsdk\emsdk_env.bat -emcc main.cpp Game.cpp Math.cpp Physics.cpp Renderer.cpp ShaderManager.cpp TextureManager.cpp Utils.cpp OpenGlExtensions.cpp -O2 -std=c++14 -sTOTAL_MEMORY=33554432 -sUSE_SDL_IMAGE=2 -sSDL2_IMAGE_FORMATS="[""png""]" -sUSE_SDL=2 --preload-file background.bmp --preload-file bird.bmp32 --preload-file default.fragment --preload-file default.vertex --preload-file game_over.bmp32 --preload-file pipe.bmp32 -o jumpingbird.html +emcc main.cpp Game.cpp Math.cpp Physics.cpp Renderer.cpp ShaderManager.cpp TextureManager.cpp Utils.cpp OpenGlExtensions.cpp -O2 -std=c++14 -sTOTAL_MEMORY=33554432 -sUSE_SDL_IMAGE=2 -sSDL2_IMAGE_FORMATS="[""png""]" -sUSE_SDL=2 --preload-file background.bmp --preload-file bird.bmp32 --preload-file default.fragment --preload-file default.vertex --preload-file game_over.bmp32 --preload-file pipe.bmp32 -o space-game001.html ``` ``` @@ -63,7 +63,12 @@ emcc main.cpp Game.cpp Environment.cpp GameObjectManager.cpp BoneAnimatedModel.c # Windows: -emcc main.cpp Game.cpp Environment.cpp GameObjectManager.cpp BoneAnimatedModel.cpp GameWorld.cpp InputManager.cpp Inventory.cpp ObjLoader.cpp QuestScripts.cpp RenderSystem.cpp Math.cpp Physics.cpp Renderer.cpp TextModel.cpp ShaderManager.cpp TextureManager.cpp Utils.cpp OpenGlExtensions.cpp -O2 -std=c++14 -pthread -sUSE_PTHREADS=1 -sPTHREAD_POOL_SIZE=4 -sTOTAL_MEMORY=4294967296 -sINITIAL_MEMORY=3221225472 -sMAXIMUM_MEMORY=4294967296 -sALLOW_MEMORY_GROWTH=1 -I./thirdparty/libzip-1.11.3/build-emcmake/install/include -L./thirdparty/libzip-1.11.3/build-emcmake/install/lib -lzip -lz -sUSE_SDL_IMAGE=2 -sUSE_SDL=2 -sUSE_LIBPNG=1 --preload-file data.zip -o viola.html +emcc --clear-cache +embuilder build sdl2 sdl2_ttf sdl2_image sdl2_image_jpg sdl2_image_png + + + +emcc main.cpp Game.cpp Environment.cpp BoneAnimatedModel.cpp Math.cpp Renderer.cpp TextModel.cpp ShaderManager.cpp TextureManager.cpp Utils.cpp OpenGlExtensions.cpp -O2 -std=c++14 -pthread -sUSE_PTHREADS=1 -sPTHREAD_POOL_SIZE=4 -sTOTAL_MEMORY=4294967296 -sINITIAL_MEMORY=3221225472 -sMAXIMUM_MEMORY=4294967296 -sALLOW_MEMORY_GROWTH=1 -I./thirdparty/libzip-1.11.3/build-emcmake/install/include -L./thirdparty/libzip-1.11.3/build-emcmake/install/lib -lzip -lz -sUSE_SDL_IMAGE=2 -sUSE_SDL=2 -sUSE_LIBPNG=1 --preload-file space-game001.zip -o space-game001.html emrun --no_browser --port 8080 . ``` diff --git a/TextureManager.cpp b/TextureManager.cpp index fb4f012..8fd8745 100755 --- a/TextureManager.cpp +++ b/TextureManager.cpp @@ -71,42 +71,50 @@ namespace ZL // Настройка параметров для Cubemap glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + // Используем GL_LINEAR для MIN_FILTER, так как мипмапы здесь не генерируются + // Если бы использовались мипмапы (e.g., GL_LINEAR_MIPMAP_LINEAR), нужно было бы вызвать glGenerateMipmap. glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Обязательные параметры обертки для Cubemap glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - CheckGlError(); + // GL_TEXTURE_WRAP_R не поддерживается в WebGL 1.0/OpenGL ES 2.0 и вызывает ошибку. + // Ограничиваем его вызов только для настольных платформ. +#ifndef EMSCRIPTEN + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); +#endif + + CheckGlError(); // Проверка после установки параметров // Загрузка данных для каждой из 6 граней - // GL_TEXTURE_CUBE_MAP_POSITIVE_X + i дает грани: - // +X (0), -X (1), +Y (2), -Y (3), +Z (4), -Z (5) + // GL_TEXTURE_CUBE_MAP_POSITIVE_X + i дает грани: +X (0), -X (1), +Y (2), -Y (3), +Z (4), -Z (5) for (int i = 0; i < 6; ++i) { GLint internalFormat; GLenum format; + // В WebGL 1.0/OpenGL ES 2.0 внутренний формат (internalFormat) + // должен строго соответствовать формату данных (format). if (texDataArray[i].bitSize == TextureDataStruct::BS_24BIT) { - internalFormat = GL_RGB; - format = GL_RGB; + internalFormat = GL_RGB; // internalFormat + format = GL_RGB; // format } else // BS_32BIT { - internalFormat = GL_RGBA; - format = GL_RGBA; + internalFormat = GL_RGBA; // internalFormat + format = GL_RGBA; // format } glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, // Целевая грань 0, // Уровень MIP-текстуры - internalFormat, // Внутренний формат (например, GL_RGB) + internalFormat, // Внутренний формат (должен совпадать с форматом) static_cast(width), static_cast(height), 0, // Граница (всегда 0) - format, // Формат исходных данных (например, GL_RGB) + format, // Формат исходных данных GL_UNSIGNED_BYTE, // Тип данных texDataArray[i].data.data() // Указатель на данные ); diff --git a/TextureManager.h b/TextureManager.h index 86b124d..6663cc0 100755 --- a/TextureManager.h +++ b/TextureManager.h @@ -3,6 +3,10 @@ #include "OpenGlExtensions.h" #include "Utils.h" +#ifdef EMSCRIPTEN +#define PNG_ENABLED +#endif + namespace ZL { diff --git a/Utils.cpp b/Utils.cpp index 51a8bb1..a7adef2 100755 --- a/Utils.cpp +++ b/Utils.cpp @@ -5,7 +5,9 @@ #include #include #include -//#include +#ifdef EMSCRIPTEN +#include +#endif namespace ZL { @@ -42,7 +44,8 @@ namespace ZL } std::vector readFileFromZIP(const std::string& filename, const std::string& zipfilename) { - /*const std::string zipPath = zipfilename; +#ifdef EMSCRIPTEN + const std::string zipPath = zipfilename; int zipErr; zip_t* archive = zip_open(zipPath.c_str(), ZIP_RDONLY, &zipErr); if (!archive) { @@ -77,8 +80,10 @@ namespace ZL zip_fclose(zipFile); zip_close(archive); - return fileData;*/ + return fileData; +#else return {}; +#endif } bool findString(const char* in, char* list) diff --git a/main.cpp b/main.cpp index bfa1a05..a636b19 100755 --- a/main.cpp +++ b/main.cpp @@ -1,78 +1,88 @@ #include "Game.h" #include "Environment.h" +#include + ZL::Game game; void MainLoop() { game.update(); } int main(int argc, char* argv[]) { - constexpr int CONST_WIDTH = 1280; - constexpr int CONST_HEIGHT = 720; + try + { + constexpr int CONST_WIDTH = 1280; + constexpr int CONST_HEIGHT = 720; - ZL::Environment::width = CONST_WIDTH; - ZL::Environment::height = CONST_HEIGHT; + ZL::Environment::width = CONST_WIDTH; + ZL::Environment::height = CONST_HEIGHT; #ifdef EMSCRIPTEN - if (SDL_Init(SDL_INIT_VIDEO) != 0) { - std::cerr << "SDL_Init failed: " << SDL_GetError() << std::endl; - return 1; - } + if (SDL_Init(SDL_INIT_VIDEO) != 0) { + std::cerr << "SDL_Init failed: " << SDL_GetError() << std::endl; + return 1; + } - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); - SDL_Window* win = SDL_CreateWindow("Space Ship Game", - SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, - CONST_WIDTH, CONST_HEIGHT, - SDL_WINDOW_OPENGL); + SDL_Window* win = SDL_CreateWindow("Space Ship Game", + SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + CONST_WIDTH, CONST_HEIGHT, + SDL_WINDOW_OPENGL); - if (!win) { - std::cerr << "SDL_CreateWindow failed: " << SDL_GetError() << std::endl; - return 1; - } + if (!win) { + std::cerr << "SDL_CreateWindow failed: " << SDL_GetError() << std::endl; + return 1; + } - SDL_GLContext glContext = SDL_GL_CreateContext(win); - if (!glContext) { - std::cerr << "SDL_GL_CreateContext failed: " << SDL_GetError() << std::endl; - return 1; - } + SDL_GLContext glContext = SDL_GL_CreateContext(win); + if (!glContext) { + std::cerr << "SDL_GL_CreateContext failed: " << SDL_GetError() << std::endl; + return 1; + } - // РџСЂРёРІСЏР·РєР° контекста Рє РѕРєРЅСѓ — важно! - SDL_GL_MakeCurrent(win, glContext); + // РџСЂРёРІСЏР·РєР° контекста Рє РѕРєРЅСѓ — важно! + SDL_GL_MakeCurrent(win, glContext); - ZL::Environment::window = win; + ZL::Environment::window = win; #else - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) != 0) { - SDL_Log("SDL init failed: %s", SDL_GetError()); - return 1; - } + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) != 0) { + SDL_Log("SDL init failed: %s", SDL_GetError()); + return 1; + } - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - ZL::Environment::window = SDL_CreateWindow( - "Space Ship Game", - SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, - CONST_WIDTH, CONST_HEIGHT, - SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN - ); + ZL::Environment::window = SDL_CreateWindow( + "Space Ship Game", + SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + CONST_WIDTH, CONST_HEIGHT, + SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN + ); - SDL_GLContext ctx = SDL_GL_CreateContext(ZL::Environment::window); - SDL_GL_MakeCurrent(ZL::Environment::window, ctx); + SDL_GLContext ctx = SDL_GL_CreateContext(ZL::Environment::window); + SDL_GL_MakeCurrent(ZL::Environment::window, ctx); #endif - game.setup(); + game.setup(); #ifdef EMSCRIPTEN - emscripten_set_main_loop(MainLoop, 0, 1); + emscripten_set_main_loop(MainLoop, 0, 1); #else - while (!game.shouldExit()) { - game.update(); - SDL_Delay(2); - } + while (!game.shouldExit()) { + game.update(); + SDL_Delay(2); + } #endif + } + catch (const std::exception& e) + { + std::cout << e.what() << std::endl; + } + return 0; } diff --git a/shaders/env_desktop.fragment b/shaders/env_desktop.fragment new file mode 100644 index 0000000..e033049 --- /dev/null +++ b/shaders/env_desktop.fragment @@ -0,0 +1,8 @@ +uniform samplerCube Texture; + +varying vec3 dir; + +void main(){ + gl_FragColor = textureCube(Texture, normalize(dir)); + +} \ No newline at end of file diff --git a/shaders/env_reverse.fragment b/shaders/env_reverse.fragment deleted file mode 100644 index 3a81eba..0000000 --- a/shaders/env_reverse.fragment +++ /dev/null @@ -1,21 +0,0 @@ -uniform samplerCube Env; - -varying vec3 dir; - -void main(){ - gl_FragColor = textureCube(Env, normalize(dir)); - - vec4 fogColor = vec4(0.25, 0.55, 1.0, 1.0); - - float coef = dir.y+1.0; - coef = clamp(coef, 0.0, 1.0); - - gl_FragColor = mix(gl_FragColor,fogColor, coef); - - //if (dir.z < 0) - //{ - // gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); - //} - //gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); - -} \ No newline at end of file diff --git a/shaders/env_reverse.vertex b/shaders/env_reverse.vertex deleted file mode 100644 index d4a4d03..0000000 --- a/shaders/env_reverse.vertex +++ /dev/null @@ -1,14 +0,0 @@ -attribute vec3 vPosition; - -uniform mat4 ProjectionMatrix; -uniform mat3 ModelRotateMatrix; -uniform vec3 ModelTranslateVector; - -varying vec3 dir; - -void main(){ - vec4 realVertexPos = vec4(ModelRotateMatrix * vPosition.xyz + ModelTranslateVector, 1.0); - gl_Position = ProjectionMatrix * realVertexPos; - - dir = -vPosition; -} \ No newline at end of file diff --git a/shaders/env_reverse_night.fragment b/shaders/env_reverse_night.fragment deleted file mode 100644 index 0703ce6..0000000 --- a/shaders/env_reverse_night.fragment +++ /dev/null @@ -1,21 +0,0 @@ -uniform samplerCube Env; - -varying vec3 dir; - -void main(){ - gl_FragColor = textureCube(Env, normalize(dir)); - - vec4 fogColor = vec4(0.05, 0.05, 0.1, 1.0); - - float coef = dir.y+1.0; - coef = clamp(coef, 0.0, 1.0); - - gl_FragColor = mix(gl_FragColor,fogColor, coef); - - //if (dir.z < 0) - //{ - // gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); - //} - //gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); - -} \ No newline at end of file diff --git a/shaders/env_reverse_night.vertex b/shaders/env_reverse_night.vertex deleted file mode 100644 index d4a4d03..0000000 --- a/shaders/env_reverse_night.vertex +++ /dev/null @@ -1,14 +0,0 @@ -attribute vec3 vPosition; - -uniform mat4 ProjectionMatrix; -uniform mat3 ModelRotateMatrix; -uniform vec3 ModelTranslateVector; - -varying vec3 dir; - -void main(){ - vec4 realVertexPos = vec4(ModelRotateMatrix * vPosition.xyz + ModelTranslateVector, 1.0); - gl_Position = ProjectionMatrix * realVertexPos; - - dir = -vPosition; -} \ No newline at end of file diff --git a/shaders/env_web.fragment b/shaders/env_web.fragment new file mode 100644 index 0000000..63ad205 --- /dev/null +++ b/shaders/env_web.fragment @@ -0,0 +1,7 @@ +precision mediump float; +uniform samplerCube Texture; +varying vec3 dir; + +void main(){ + gl_FragColor = textureCube(Texture, normalize(dir)); +} \ No newline at end of file