diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..540a927 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +*.bmp filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.jpg filter=lfs diff=lfs merge=lfs -text diff --git a/Game.cpp b/Game.cpp index 11bb330..7d67025 100755 --- a/Game.cpp +++ b/Game.cpp @@ -44,6 +44,25 @@ void Game::setup() { 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); #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") + }); + + + cubemap.data = ZL::CreateCubemap(1000); + cubemap.RefreshVBO(); //Load texture spaceshipTexture = std::make_unique(CreateTextureDataFromPng("./resources/sship001x.png")); @@ -59,6 +78,8 @@ void Game::setup() { void Game::drawScene() { static const std::string defaultShaderName = "default"; + static const std::string envShaderName = "env"; + static const std::string vPositionName = "vPosition"; static const std::string vTexCoordName = "vTexCoord"; static const std::string textureUniformName = "Texture"; @@ -70,6 +91,31 @@ void Game::drawScene() { CheckGlError(); + renderer.shaderManager.PushShader(envShaderName); + renderer.RenderUniform1i(textureUniformName, 0); + renderer.EnableVertexAttribArray(vPositionName); + renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5, + static_cast(Environment::width) / static_cast(Environment::height), + 1, 1000); + renderer.PushMatrix(); + renderer.LoadIdentity(); + + CheckGlError(); + + glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture->getTexID()); + renderer.DrawVertexRenderStruct(cubemap); + + CheckGlError(); + + + renderer.PopMatrix(); + renderer.PopProjectionMatrix(); + renderer.DisableVertexAttribArray(vPositionName); + + renderer.shaderManager.PopShader(); + CheckGlError(); + + renderer.shaderManager.PushShader(defaultShaderName); renderer.RenderUniform1i(textureUniformName, 0); renderer.EnableVertexAttribArray(vPositionName); diff --git a/Game.h b/Game.h index 9e97688..c157bbf 100755 --- a/Game.h +++ b/Game.h @@ -33,8 +33,11 @@ private: static const size_t CONST_MAX_TIME_INTERVAL = 1000; std::shared_ptr spaceshipTexture; + std::shared_ptr cubemapTexture; VertexDataStruct spaceshipBase; VertexRenderStruct spaceship; + + VertexRenderStruct cubemap; }; } // namespace ZL \ No newline at end of file diff --git a/Renderer.cpp b/Renderer.cpp index 868818a..9fe2f40 100755 --- a/Renderer.cpp +++ b/Renderer.cpp @@ -196,6 +196,71 @@ namespace ZL { return result; } + VertexDataStruct CreateCubemap(float scale) + { + VertexDataStruct cubemapVertexDataStruct; + + // +x + cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, scale, scale }); + + cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, scale, scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, scale }); + + // -x + cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, scale }); + + cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, scale }); + cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, scale }); + + + // +y + cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, scale, scale }); + + cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, scale, scale }); + cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, scale }); + + + // -y + cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, scale }); + + cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, scale }); + cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, scale }); + + + // +z + cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, scale, scale }); + + cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, scale, scale }); + cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, scale }); + + // -z + cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, scale, -scale }); + + cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ scale, scale, -scale }); + cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, -scale }); + + return cubemapVertexDataStruct; + + } + void VertexRenderStruct::RefreshVBO() { //Check if main thread, check if data is not empty... diff --git a/Renderer.h b/Renderer.h index 55bbc4d..8b8736c 100755 --- a/Renderer.h +++ b/Renderer.h @@ -75,6 +75,7 @@ namespace ZL { VertexDataStruct CreateRect2D(Vector2f center, Vector2f halfWidthHeight, float zLevel); VertexDataStruct CreateRectHorizontalSections2D(Vector2f center, Vector2f halfWidthHeight, float zLevel, size_t sectionCount); VertexDataStruct CreateCube3D(float scale); + VertexDataStruct CreateCubemap(float scale = 1000.f); class Renderer diff --git a/TextureManager.cpp b/TextureManager.cpp index 00f2e55..fb4f012 100755 --- a/TextureManager.cpp +++ b/TextureManager.cpp @@ -46,6 +46,77 @@ namespace ZL } + Texture::Texture(const std::array& texDataArray) + { + // Проверка, что все грани имеют одинаковые размеры + width = texDataArray[0].width; + height = texDataArray[0].height; + + for (size_t i = 1; i < 6; ++i) { + if (texDataArray[i].width != width || texDataArray[i].height != height) { + throw std::runtime_error("Cubemap faces must have the same dimensions"); + } + } + + glGenTextures(1, &texID); + + if (texID == 0) + { + throw std::runtime_error("glGenTextures did not work for cubemap"); + } + + glBindTexture(GL_TEXTURE_CUBE_MAP, texID); + + CheckGlError(); + + // Настройка параметров для Cubemap + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + 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(); + + // Загрузка данных для каждой из 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; + + if (texDataArray[i].bitSize == TextureDataStruct::BS_24BIT) + { + internalFormat = GL_RGB; + format = GL_RGB; + } + else // BS_32BIT + { + internalFormat = GL_RGBA; + format = GL_RGBA; + } + + glTexImage2D( + GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, // Целевая грань + 0, // Уровень MIP-текстуры + internalFormat, // Внутренний формат (например, GL_RGB) + static_cast(width), + static_cast(height), + 0, // Граница (всегда 0) + format, // Формат исходных данных (например, GL_RGB) + GL_UNSIGNED_BYTE, // Тип данных + texDataArray[i].data.data() // Указатель на данные + ); + CheckGlError(); + } + + // Снимаем привязку для чистоты + glBindTexture(GL_TEXTURE_CUBE_MAP, 0); + } + Texture::~Texture() { glDeleteTextures(1, &texID); @@ -282,4 +353,6 @@ namespace ZL return texData; } #endif + + } \ No newline at end of file diff --git a/TextureManager.h b/TextureManager.h index 0d4e504..86b124d 100755 --- a/TextureManager.h +++ b/TextureManager.h @@ -29,6 +29,9 @@ namespace ZL Texture(const TextureDataStruct& texData); + //Cubemap texture: + Texture(const std::array& texDataArray); + ~Texture(); GLuint getTexID(); @@ -44,4 +47,6 @@ namespace ZL #ifdef PNG_ENABLED TextureDataStruct CreateTextureDataFromPng(const std::string& fullFileName); #endif + + } diff --git a/resources/sky/space_bk.bmp b/resources/sky/space_bk.bmp new file mode 100644 index 0000000..b37e96f --- /dev/null +++ b/resources/sky/space_bk.bmp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:42e0dc0dfa1902efac68c7ae4028545a13d1c1fa85d6e359a04cb625b6396079 +size 3145782 diff --git a/resources/sky/space_dn.bmp b/resources/sky/space_dn.bmp new file mode 100644 index 0000000..41ea30d --- /dev/null +++ b/resources/sky/space_dn.bmp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:84353c826f100f121866febcebfd1aec977a8c8862382aaa2a35c073fec56291 +size 3145782 diff --git a/resources/sky/space_ft.bmp b/resources/sky/space_ft.bmp new file mode 100644 index 0000000..c0c6fcc --- /dev/null +++ b/resources/sky/space_ft.bmp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6b9b11c45b2e5b8fa9f6757232b96c28233a7808f6da09340563782d5d5d5d9a +size 3145782 diff --git a/resources/sky/space_lf.bmp b/resources/sky/space_lf.bmp new file mode 100644 index 0000000..e90c3fb --- /dev/null +++ b/resources/sky/space_lf.bmp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a6176946fbdc557ba453382a9fc4208aec323072f9292ae8032172a00886557f +size 3145782 diff --git a/resources/sky/space_rt.bmp b/resources/sky/space_rt.bmp new file mode 100644 index 0000000..2cc5121 --- /dev/null +++ b/resources/sky/space_rt.bmp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:48278772f14f40b22d9d50fb64ceda8ef0fc1adeae2372bc4365e30fb3f8b813 +size 3145782 diff --git a/resources/sky/space_up.bmp b/resources/sky/space_up.bmp new file mode 100644 index 0000000..a20369b --- /dev/null +++ b/resources/sky/space_up.bmp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5e3d869700062ddab52c6eb8fc33d953e12c3204b0cf75f0ef8476ab8ee2573a +size 3145782 diff --git a/resources/sship001.png b/resources/sship001.png deleted file mode 100644 index beaab8c..0000000 Binary files a/resources/sship001.png and /dev/null differ diff --git a/resources/sship001x.png b/resources/sship001x.png deleted file mode 100644 index 06e2340..0000000 Binary files a/resources/sship001x.png and /dev/null differ diff --git a/shaders/env.fragment b/shaders/env.fragment new file mode 100644 index 0000000..ce047fb --- /dev/null +++ b/shaders/env.fragment @@ -0,0 +1,13 @@ +uniform samplerCube Texture; + +varying vec3 dir; + +void main(){ + gl_FragColor = textureCube(Texture, normalize(dir)); + //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.vertex b/shaders/env.vertex new file mode 100644 index 0000000..5903df6 --- /dev/null +++ b/shaders/env.vertex @@ -0,0 +1,12 @@ +attribute vec3 vPosition; + +uniform mat4 ProjectionModelViewMatrix; + +varying vec3 dir; + +void main(){ + vec4 realVertexPos = vec4(vPosition.xyz, 1.0); + gl_Position = ProjectionModelViewMatrix * realVertexPos; + + dir = vPosition; +} \ No newline at end of file diff --git a/shaders/env_reverse.fragment b/shaders/env_reverse.fragment new file mode 100644 index 0000000..3a81eba --- /dev/null +++ b/shaders/env_reverse.fragment @@ -0,0 +1,21 @@ +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 new file mode 100644 index 0000000..d4a4d03 --- /dev/null +++ b/shaders/env_reverse.vertex @@ -0,0 +1,14 @@ +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 new file mode 100644 index 0000000..0703ce6 --- /dev/null +++ b/shaders/env_reverse_night.fragment @@ -0,0 +1,21 @@ +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 new file mode 100644 index 0000000..d4a4d03 --- /dev/null +++ b/shaders/env_reverse_night.vertex @@ -0,0 +1,14 @@ +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