From 7450e354de08ee4336b6033d7c28980ab56f03ed Mon Sep 17 00:00:00 2001 From: Jupeyy Date: Wed, 19 Aug 2020 07:05:51 +0200 Subject: [PATCH] Add OpenGL 4.x support & cleanup --- CMakeLists.txt | 12 - data/shader/bordertile.frag | 10 - data/shader/bordertile.vert | 20 -- data/shader/bordertileline.frag | 9 - data/shader/bordertileline.vert | 17 - data/shader/bordertilelinetex.frag | 15 - data/shader/bordertilelinetex.vert | 27 -- data/shader/bordertiletex.frag | 15 - data/shader/bordertiletex.vert | 30 -- data/shader/prim.frag | 2 - data/shader/prim.vert | 2 - data/shader/quad.frag | 19 +- data/shader/quad.vert | 37 ++- data/shader/quadtex.frag | 15 - data/shader/quadtex.vert | 34 -- data/shader/sprite.frag | 2 - data/shader/sprite.vert | 2 - data/shader/spritemulti.frag | 2 - data/shader/spritemulti.vert | 2 - data/shader/text.frag | 2 - data/shader/text.vert | 2 - data/shader/tile.frag | 22 +- data/shader/tile.vert | 42 ++- data/shader/tiletex.frag | 15 - data/shader/tiletex.vert | 20 -- src/engine/client/backend_sdl.cpp | 403 +++++++++++++---------- src/engine/client/backend_sdl.h | 22 +- src/engine/client/graphics_threaded.cpp | 38 +-- src/engine/client/graphics_threaded.h | 9 +- src/engine/client/opengl_sl.cpp | 32 +- src/engine/client/opengl_sl.h | 35 +- src/engine/client/opengl_sl_program.cpp | 13 +- src/engine/client/opengl_sl_program.h | 30 +- src/engine/client/text.cpp | 25 +- src/engine/graphics.h | 5 + src/engine/textrender.h | 2 +- src/game/client/components/mapimages.cpp | 93 +++--- src/game/client/components/mapimages.h | 7 +- src/game/client/components/maplayers.cpp | 190 ++++------- 39 files changed, 580 insertions(+), 699 deletions(-) delete mode 100644 data/shader/bordertile.frag delete mode 100644 data/shader/bordertile.vert delete mode 100644 data/shader/bordertileline.frag delete mode 100644 data/shader/bordertileline.vert delete mode 100644 data/shader/bordertilelinetex.frag delete mode 100644 data/shader/bordertilelinetex.vert delete mode 100644 data/shader/bordertiletex.frag delete mode 100644 data/shader/bordertiletex.vert delete mode 100644 data/shader/quadtex.frag delete mode 100644 data/shader/quadtex.vert delete mode 100644 data/shader/tiletex.frag delete mode 100644 data/shader/tiletex.vert diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ced12f89..cbd081f0b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1107,20 +1107,10 @@ set(EXPECTED_DATA maps7/Gold\ Mine.map maps7/readme.txt particles.png - shader/bordertile.frag - shader/bordertile.vert - shader/bordertileline.frag - shader/bordertileline.vert - shader/bordertilelinetex.frag - shader/bordertilelinetex.vert - shader/bordertiletex.frag - shader/bordertiletex.vert shader/prim.frag shader/prim.vert shader/quad.frag shader/quad.vert - shader/quadtex.frag - shader/quadtex.vert shader/sprite.frag shader/sprite.vert shader/spritemulti.frag @@ -1129,8 +1119,6 @@ set(EXPECTED_DATA shader/text.vert shader/tile.frag shader/tile.vert - shader/tiletex.frag - shader/tiletex.vert "skins/Ablush NeoN.png" skins/Aoe4leg.png "skins/Apish Coke.png" diff --git a/data/shader/bordertile.frag b/data/shader/bordertile.frag deleted file mode 100644 index 3387d0281..000000000 --- a/data/shader/bordertile.frag +++ /dev/null @@ -1,10 +0,0 @@ -#version 330 - -uniform vec4 vertColor; - -out vec4 FragClr; - -void main() -{ - FragClr = vertColor; -} diff --git a/data/shader/bordertile.vert b/data/shader/bordertile.vert deleted file mode 100644 index 2c5e66962..000000000 --- a/data/shader/bordertile.vert +++ /dev/null @@ -1,20 +0,0 @@ -#version 330 - -layout (location = 0) in vec2 inVertex; - -uniform mat4x2 Pos; - -uniform vec2 Offset; -uniform vec2 Dir; -uniform int JumpIndex; - -void main() -{ - vec4 VertPos = vec4(inVertex, 0.0, 1.0); - int XCount = gl_InstanceID - (int(gl_InstanceID/JumpIndex) * JumpIndex); - int YCount = (int(gl_InstanceID/JumpIndex)); - VertPos.x += Offset.x + Dir.x * XCount; - VertPos.y += Offset.y + Dir.y * YCount; - - gl_Position = vec4(Pos * VertPos, 0.0, 1.0); -} diff --git a/data/shader/bordertileline.frag b/data/shader/bordertileline.frag deleted file mode 100644 index 17fc1ae8f..000000000 --- a/data/shader/bordertileline.frag +++ /dev/null @@ -1,9 +0,0 @@ -#version 330 - -uniform vec4 vertColor; - -out vec4 FragClr; -void main() -{ - FragClr = vertColor; -} diff --git a/data/shader/bordertileline.vert b/data/shader/bordertileline.vert deleted file mode 100644 index 017f83122..000000000 --- a/data/shader/bordertileline.vert +++ /dev/null @@ -1,17 +0,0 @@ -#version 330 - -layout (location = 0) in vec2 inVertex; - -uniform mat4x2 Pos; - -uniform vec2 Dir; -uniform vec2 Offset; - -void main() -{ - vec4 VertPos = vec4(inVertex.x + Offset.x, inVertex.y + Offset.y, 0.0, 1.0); - VertPos.x += Dir.x * gl_InstanceID; - VertPos.y += Dir.y * gl_InstanceID; - - gl_Position = vec4(Pos * VertPos, 0.0, 1.0); -} diff --git a/data/shader/bordertilelinetex.frag b/data/shader/bordertilelinetex.frag deleted file mode 100644 index 8bfb70294..000000000 --- a/data/shader/bordertilelinetex.frag +++ /dev/null @@ -1,15 +0,0 @@ -#version 330 - -uniform sampler2D textureSampler; - -uniform vec4 vertColor; -uniform float LOD; - -noperspective in vec2 texCoord; - -out vec4 FragClr; -void main() -{ - vec4 tex = textureLod(textureSampler, texCoord, LOD); - FragClr = tex * vertColor; -} diff --git a/data/shader/bordertilelinetex.vert b/data/shader/bordertilelinetex.vert deleted file mode 100644 index f4213cca9..000000000 --- a/data/shader/bordertilelinetex.vert +++ /dev/null @@ -1,27 +0,0 @@ -#version 330 - -layout (location = 0) in vec2 inVertex; -layout (location = 1) in vec2 inVertexTexCoord; -layout (location = 2) in ivec2 inVertexTexRightOrBottom; - -uniform mat4x2 Pos; -uniform float TexelOffset; - -uniform vec2 Dir; -uniform vec2 Offset; - -noperspective out vec2 texCoord; - -void main() -{ - vec4 VertPos = vec4(inVertex.x + Offset.x, inVertex.y + Offset.y, 0.0, 1.0); - VertPos.x += Dir.x * gl_InstanceID; - VertPos.y += Dir.y * gl_InstanceID; - - gl_Position = vec4(Pos * VertPos, 0.0, 1.0); - - float tx = (inVertexTexCoord.x/(16.0)); - float ty = (inVertexTexCoord.y/(16.0)); - - texCoord = vec2(tx + (inVertexTexRightOrBottom.x == 0 ? TexelOffset : -TexelOffset), ty + (inVertexTexRightOrBottom.y == 0 ? TexelOffset : -TexelOffset)); -} diff --git a/data/shader/bordertiletex.frag b/data/shader/bordertiletex.frag deleted file mode 100644 index 8bfb70294..000000000 --- a/data/shader/bordertiletex.frag +++ /dev/null @@ -1,15 +0,0 @@ -#version 330 - -uniform sampler2D textureSampler; - -uniform vec4 vertColor; -uniform float LOD; - -noperspective in vec2 texCoord; - -out vec4 FragClr; -void main() -{ - vec4 tex = textureLod(textureSampler, texCoord, LOD); - FragClr = tex * vertColor; -} diff --git a/data/shader/bordertiletex.vert b/data/shader/bordertiletex.vert deleted file mode 100644 index b02508e6e..000000000 --- a/data/shader/bordertiletex.vert +++ /dev/null @@ -1,30 +0,0 @@ -#version 330 - -layout (location = 0) in vec2 inVertex; -layout (location = 1) in vec2 inVertexTexCoord; -layout (location = 2) in ivec2 inVertexTexRightOrBottom; - -uniform mat4x2 Pos; -uniform float TexelOffset; - -uniform vec2 Offset; -uniform vec2 Dir; -uniform int JumpIndex; - -noperspective out vec2 texCoord; - -void main() -{ - vec4 VertPos = vec4(inVertex, 0.0, 1.0); - int XCount = gl_InstanceID - (int(gl_InstanceID/JumpIndex) * JumpIndex); - int YCount = (int(gl_InstanceID/JumpIndex)); - VertPos.x += Offset.x + Dir.x * XCount; - VertPos.y += Offset.y + Dir.y * YCount; - - gl_Position = vec4(Pos * VertPos, 0.0, 1.0); - - float tx = (inVertexTexCoord.x/(16.0)); - float ty = (inVertexTexCoord.y/(16.0)); - - texCoord = vec2(tx + (inVertexTexRightOrBottom.x == 0 ? TexelOffset : -TexelOffset), ty + (inVertexTexRightOrBottom.y == 0 ? TexelOffset : -TexelOffset)); -} diff --git a/data/shader/prim.frag b/data/shader/prim.frag index eb287be8f..aeb40cecd 100644 --- a/data/shader/prim.frag +++ b/data/shader/prim.frag @@ -1,5 +1,3 @@ -#version 330 - uniform int isTextured; uniform sampler2D textureSampler; diff --git a/data/shader/prim.vert b/data/shader/prim.vert index b1e530dd3..113cf0f7d 100644 --- a/data/shader/prim.vert +++ b/data/shader/prim.vert @@ -1,5 +1,3 @@ -#version 330 - layout (location = 0) in vec2 inVertex; layout (location = 1) in vec2 inVertexTexCoord; layout (location = 2) in vec4 inVertexColor; diff --git a/data/shader/quad.frag b/data/shader/quad.frag index 2c574a478..edbf160b8 100644 --- a/data/shader/quad.frag +++ b/data/shader/quad.frag @@ -1,11 +1,22 @@ -#version 330 +#ifdef TW_QUAD_TEXTURED +uniform sampler2D gTextureSampler; +#endif -uniform vec4 vertColor; +uniform vec4 gVertColors[TW_MAX_QUADS]; -noperspective in vec4 quadColor; +noperspective in vec4 QuadColor; +flat in int QuadIndex; +#ifdef TW_QUAD_TEXTURED +noperspective in vec2 TexCoord; +#endif out vec4 FragClr; void main() { - FragClr = quadColor * vertColor; +#ifdef TW_QUAD_TEXTURED + vec4 TexColor = texture(gTextureSampler, TexCoord); + FragClr = TexColor * QuadColor * gVertColors[QuadIndex]; +#else + FragClr = QuadColor * gVertColors[QuadIndex]; +#endif } diff --git a/data/shader/quad.vert b/data/shader/quad.vert index 6bd20e36f..953048866 100644 --- a/data/shader/quad.vert +++ b/data/shader/quad.vert @@ -1,31 +1,42 @@ -#version 330 - layout (location = 0) in vec4 inVertex; layout (location = 1) in vec4 inColor; +#ifdef TW_QUAD_TEXTURED +layout (location = 2) in vec2 inVertexTexCoord; +#endif -uniform mat4x2 Pos; +uniform mat4x2 gPos; -uniform vec2 Offset; -uniform float Rotation; +uniform vec2 gOffsets[TW_MAX_QUADS]; +uniform float gRotations[TW_MAX_QUADS]; -noperspective out vec4 quadColor; +noperspective out vec4 QuadColor; +flat out int QuadIndex; +#ifdef TW_QUAD_TEXTURED +noperspective out vec2 TexCoord; +#endif void main() { vec2 FinalPos = vec2(inVertex.xy); + + int TmpQuadIndex = int(gl_VertexID / 4); - if(Rotation != 0.0) + if(gRotations[TmpQuadIndex] != 0.0) { float X = FinalPos.x - inVertex.z; float Y = FinalPos.y - inVertex.w; - FinalPos.x = X * cos(Rotation) - Y * sin(Rotation) + inVertex.z; - FinalPos.y = X * sin(Rotation) + Y * cos(Rotation) + inVertex.w; + FinalPos.x = X * cos(gRotations[TmpQuadIndex]) - Y * sin(gRotations[TmpQuadIndex]) + inVertex.z; + FinalPos.y = X * sin(gRotations[TmpQuadIndex]) + Y * cos(gRotations[TmpQuadIndex]) + inVertex.w; } - FinalPos.x = FinalPos.x / 1024.0 + Offset.x; - FinalPos.y = FinalPos.y / 1024.0 + Offset.y; + FinalPos.x = FinalPos.x / 1024.0 + gOffsets[TmpQuadIndex].x; + FinalPos.y = FinalPos.y / 1024.0 + gOffsets[TmpQuadIndex].y; - gl_Position = vec4(Pos * vec4(FinalPos, 0.0, 1.0), 0.0, 1.0); - quadColor = inColor; + gl_Position = vec4(gPos * vec4(FinalPos, 0.0, 1.0), 0.0, 1.0); + QuadColor = inColor; + QuadIndex = TmpQuadIndex; +#ifdef TW_QUAD_TEXTURED + TexCoord = inVertexTexCoord; +#endif } diff --git a/data/shader/quadtex.frag b/data/shader/quadtex.frag deleted file mode 100644 index b4ba8727c..000000000 --- a/data/shader/quadtex.frag +++ /dev/null @@ -1,15 +0,0 @@ -#version 330 - -uniform sampler2D textureSampler; - -uniform vec4 vertColor; - -noperspective in vec2 texCoord; -noperspective in vec4 quadColor; - -out vec4 FragClr; -void main() -{ - vec4 tex = texture(textureSampler, texCoord); - FragClr = tex * quadColor * vertColor; -} diff --git a/data/shader/quadtex.vert b/data/shader/quadtex.vert deleted file mode 100644 index 60ef47d6f..000000000 --- a/data/shader/quadtex.vert +++ /dev/null @@ -1,34 +0,0 @@ -#version 330 - -layout (location = 0) in vec4 inVertex; -layout (location = 1) in vec2 inVertexTexCoord; -layout (location = 2) in vec4 inColor; - -uniform mat4x2 Pos; - -uniform vec2 Offset; -uniform float Rotation; - -noperspective out vec2 texCoord; -noperspective out vec4 quadColor; - -void main() -{ - vec2 FinalPos = vec2(inVertex.xy); - - if(Rotation != 0.0) - { - float X = FinalPos.x - inVertex.z; - float Y = FinalPos.y - inVertex.w; - - FinalPos.x = X * cos(Rotation) - Y * sin(Rotation) + inVertex.z; - FinalPos.y = X * sin(Rotation) + Y * cos(Rotation) + inVertex.w; - } - - FinalPos.x = FinalPos.x / 1024.0 + Offset.x; - FinalPos.y = FinalPos.y / 1024.0 + Offset.y; - - gl_Position = vec4(Pos * vec4(FinalPos, 0.0, 1.0), 0.0, 1.0); - texCoord = inVertexTexCoord; - quadColor = inColor; -} diff --git a/data/shader/sprite.frag b/data/shader/sprite.frag index 810e6cfdb..37a5a6433 100644 --- a/data/shader/sprite.frag +++ b/data/shader/sprite.frag @@ -1,5 +1,3 @@ -#version 330 - uniform sampler2D textureSampler; uniform vec4 VerticesColor; diff --git a/data/shader/sprite.vert b/data/shader/sprite.vert index cd70b600f..5c75cc8d5 100644 --- a/data/shader/sprite.vert +++ b/data/shader/sprite.vert @@ -1,5 +1,3 @@ -#version 330 - layout (location = 0) in vec2 inVertex; layout (location = 1) in vec2 inVertexTexCoord; layout (location = 2) in vec4 inVertexColor; diff --git a/data/shader/spritemulti.frag b/data/shader/spritemulti.frag index 810e6cfdb..37a5a6433 100644 --- a/data/shader/spritemulti.frag +++ b/data/shader/spritemulti.frag @@ -1,5 +1,3 @@ -#version 330 - uniform sampler2D textureSampler; uniform vec4 VerticesColor; diff --git a/data/shader/spritemulti.vert b/data/shader/spritemulti.vert index ae0de84d8..36bd10893 100644 --- a/data/shader/spritemulti.vert +++ b/data/shader/spritemulti.vert @@ -1,5 +1,3 @@ -#version 330 - layout (location = 0) in vec2 inVertex; layout (location = 1) in vec2 inVertexTexCoord; layout (location = 2) in vec4 inVertexColor; diff --git a/data/shader/text.frag b/data/shader/text.frag index 9356e71f1..dc8ba3ca3 100644 --- a/data/shader/text.frag +++ b/data/shader/text.frag @@ -1,5 +1,3 @@ -#version 330 - uniform sampler2D textSampler; uniform sampler2D textOutlineSampler; diff --git a/data/shader/text.vert b/data/shader/text.vert index 211d8de80..9e1d2b0a4 100644 --- a/data/shader/text.vert +++ b/data/shader/text.vert @@ -1,5 +1,3 @@ -#version 330 - layout (location = 0) in vec2 inVertex; layout (location = 1) in vec2 inVertexTexCoord; layout (location = 2) in vec4 inVertexColor; diff --git a/data/shader/tile.frag b/data/shader/tile.frag index 3387d0281..97a99cddc 100644 --- a/data/shader/tile.frag +++ b/data/shader/tile.frag @@ -1,10 +1,24 @@ -#version 330 +#ifdef TW_TILE_TEXTURED +#ifdef TW_TILE_3D_TEXTURED +uniform sampler3D gTextureSampler; +#else +uniform sampler2DArray gTextureSampler; +#endif +#endif -uniform vec4 vertColor; +uniform vec4 gVertColor; + +#ifdef TW_TILE_TEXTURED +noperspective in vec3 TexCoord; +#endif out vec4 FragClr; - void main() { - FragClr = vertColor; +#ifdef TW_TILE_TEXTURED + vec4 TexColor = texture(gTextureSampler, TexCoord); + FragClr = TexColor * gVertColor; +#else + FragClr = gVertColor; +#endif } diff --git a/data/shader/tile.vert b/data/shader/tile.vert index 5459c3d7a..ba6ed9a25 100644 --- a/data/shader/tile.vert +++ b/data/shader/tile.vert @@ -1,10 +1,44 @@ -#version 330 - layout (location = 0) in vec2 inVertex; +#ifdef TW_TILE_TEXTURED +layout (location = 1) in vec3 inVertexTexCoord; +#endif -uniform mat4x2 Pos; +uniform mat4x2 gPos; + +#if defined(TW_TILE_BORDER) || defined(TW_TILE_BORDER_LINE) +uniform vec2 gDir; +uniform vec2 gOffset; +#endif + +#if defined(TW_TILE_BORDER) +uniform int gJumpIndex; +#endif + +#ifdef TW_TILE_TEXTURED +noperspective out vec3 TexCoord; +#endif void main() { - gl_Position = vec4(Pos * vec4(inVertex, 0.0, 1.0), 0.0, 1.0); +#if defined(TW_TILE_BORDER) + vec4 VertPos = vec4(inVertex, 0.0, 1.0); + int XCount = gl_InstanceID - (int(gl_InstanceID/gJumpIndex) * gJumpIndex); + int YCount = (int(gl_InstanceID/gJumpIndex)); + VertPos.x += gOffset.x + gDir.x * XCount; + VertPos.y += gOffset.y + gDir.y * YCount; + + gl_Position = vec4(gPos * VertPos, 0.0, 1.0); +#elif defined(TW_TILE_BORDER_LINE) + vec4 VertPos = vec4(inVertex.x + gOffset.x, inVertex.y + gOffset.y, 0.0, 1.0); + VertPos.x += gDir.x * gl_InstanceID; + VertPos.y += gDir.y * gl_InstanceID; + + gl_Position = vec4(gPos * VertPos, 0.0, 1.0); +#else + gl_Position = vec4(gPos * vec4(inVertex, 0.0, 1.0), 0.0, 1.0); +#endif + +#ifdef TW_TILE_TEXTURED + TexCoord = inVertexTexCoord; +#endif } diff --git a/data/shader/tiletex.frag b/data/shader/tiletex.frag deleted file mode 100644 index e2f185fa3..000000000 --- a/data/shader/tiletex.frag +++ /dev/null @@ -1,15 +0,0 @@ -#version 330 - -uniform sampler2D textureSampler; - -uniform vec4 vertColor; -uniform float LOD; - -noperspective in vec2 texCoord; - -out vec4 FragClr; -void main() -{ - vec4 tex = textureLod(textureSampler, texCoord, LOD); - FragClr = tex * vertColor; -} diff --git a/data/shader/tiletex.vert b/data/shader/tiletex.vert deleted file mode 100644 index 5fcd6e75e..000000000 --- a/data/shader/tiletex.vert +++ /dev/null @@ -1,20 +0,0 @@ -#version 330 - -layout (location = 0) in vec2 inVertex; -layout (location = 1) in vec2 inVertexTexCoord; -layout (location = 2) in ivec2 inVertexTexRightOrBottom; - -uniform mat4x2 Pos; -uniform float TexelOffset; - -noperspective out vec2 texCoord; - -void main() -{ - gl_Position = vec4(Pos * vec4(inVertex, 0.0, 1.0), 0.0, 1.0); - - float tx = (inVertexTexCoord.x/(16.0)); - float ty = (inVertexTexCoord.y/(16.0)); - - texCoord = vec2(tx + (inVertexTexRightOrBottom.x == 0 ? TexelOffset : -TexelOffset), ty + (inVertexTexRightOrBottom.y == 0 ? TexelOffset : -TexelOffset)); -} diff --git a/src/engine/client/backend_sdl.cpp b/src/engine/client/backend_sdl.cpp index deb206c6e..5d565ef59 100644 --- a/src/engine/client/backend_sdl.cpp +++ b/src/engine/client/backend_sdl.cpp @@ -130,6 +130,32 @@ void CGraphicsBackend_Threaded::WaitForIdle() m_BufferDone.wait(); } +static bool Texture2DTo3D(void* pImageBuffer, int ImageWidth, int ImageHeight, int ImageColorChannelCount, int SplitCountWidth, int SplitCountHeight, void* pTarget3DImageData, int& Target3DImageWidth, int& Target3DImageHeight) +{ + Target3DImageWidth = ImageWidth / SplitCountWidth; + Target3DImageHeight = ImageHeight / SplitCountHeight; + + size_t FullImageWidth = (size_t)(ImageWidth * ImageColorChannelCount); + + for(int Y = 0; Y < SplitCountHeight; ++Y) + { + for(int X = 0; X < SplitCountWidth; ++X) + { + for(int Y3D = 0; Y3D < Target3DImageHeight; ++Y3D) + { + int DepthIndex = X + Y * SplitCountWidth; + + size_t TargetImageFullWidth = (size_t)(Target3DImageWidth * ImageColorChannelCount); + size_t TargetImageFullSize = (size_t)(TargetImageFullWidth * (size_t)Target3DImageHeight); + ptrdiff_t ImageOffset = (ptrdiff_t)(((size_t)Y * FullImageWidth * (size_t)Target3DImageHeight) + ((size_t)Y3D * FullImageWidth) + ((size_t)X * TargetImageFullWidth)); + ptrdiff_t TargetImageOffset = (ptrdiff_t)(TargetImageFullSize * (size_t)DepthIndex + ((size_t)Y3D * TargetImageFullWidth)); + mem_copy(((uint8_t*)pTarget3DImageData) + TargetImageOffset, ((uint8_t*)pImageBuffer) + (ptrdiff_t)(ImageOffset), TargetImageFullWidth); + } + } + } + + return true; +} // ------------ CCommandProcessorFragment_General @@ -485,6 +511,14 @@ int CCommandProcessorFragment_OpenGL3_3::TexFormatToOpenGLFormat(int TexFormat) return GL_RGBA; } +int CCommandProcessorFragment_OpenGL3_3::TexFormatToImageColorChannelCount(int TexFormat) +{ + if(TexFormat == CCommandBuffer::TEXFORMAT_RGB) return 3; + if(TexFormat == CCommandBuffer::TEXFORMAT_ALPHA) return 1; + if(TexFormat == CCommandBuffer::TEXFORMAT_RGBA) return 4; + return 4; +} + unsigned char CCommandProcessorFragment_OpenGL3_3::Sample(int w, int h, const unsigned char *pData, int u, int v, int Offset, int ScaleW, int ScaleH, int Bpp) { int Value = 0; @@ -520,7 +554,7 @@ void *CCommandProcessorFragment_OpenGL3_3::Rescale(int Width, int Height, int Ne return pTmpData; } -void CCommandProcessorFragment_OpenGL3_3::SetState(const CCommandBuffer::SState &State, CGLSLTWProgram *pProgram) +void CCommandProcessorFragment_OpenGL3_3::SetState(const CCommandBuffer::SState &State, CGLSLTWProgram *pProgram, bool Use2DArrayTextures) { if(State.m_BlendMode != m_LastBlendMode && State.m_BlendMode != CCommandBuffer::BLEND_NONE) { @@ -567,17 +601,33 @@ void CCommandProcessorFragment_OpenGL3_3::SetState(const CCommandBuffer::SState if(m_UseMultipleTextureUnits) { - if(!IsAndUpdateTextureSlotBound(Slot, State.m_Texture)) + if(!IsAndUpdateTextureSlotBound(Slot, State.m_Texture, Use2DArrayTextures)) { glActiveTexture(GL_TEXTURE0 + Slot); - glBindTexture(GL_TEXTURE_2D, m_aTextures[State.m_Texture].m_Tex); - glBindSampler(Slot, m_aTextures[State.m_Texture].m_Sampler); + if(!Use2DArrayTextures) + { + glBindTexture(GL_TEXTURE_2D, m_aTextures[State.m_Texture].m_Tex); + glBindSampler(Slot, m_aTextures[State.m_Texture].m_Sampler); + } + else + { + glBindTexture(GL_TEXTURE_2D_ARRAY, m_aTextures[State.m_Texture].m_Tex2DArray); + glBindSampler(Slot, m_aTextures[State.m_Texture].m_Sampler2DArray); + } } } else { Slot = 0; - glBindTexture(GL_TEXTURE_2D, m_aTextures[State.m_Texture].m_Tex); - glBindSampler(Slot, m_aTextures[State.m_Texture].m_Sampler); + if(!Use2DArrayTextures) + { + glBindTexture(GL_TEXTURE_2D, m_aTextures[State.m_Texture].m_Tex); + glBindSampler(Slot, m_aTextures[State.m_Texture].m_Sampler); + } + else + { + glBindTexture(GL_TEXTURE_2D_ARRAY, m_aTextures[State.m_Texture].m_Tex2DArray); + glBindSampler(Slot, m_aTextures[State.m_Texture].m_Sampler2DArray); + } } if(pProgram->m_LocIsTextured != -1) { @@ -594,7 +644,7 @@ void CCommandProcessorFragment_OpenGL3_3::SetState(const CCommandBuffer::SState pProgram->m_LastTextureSampler = Slot; } - if(m_aTextures[State.m_Texture].m_LastWrapMode != State.m_WrapMode) + if(m_aTextures[State.m_Texture].m_LastWrapMode != State.m_WrapMode && !Use2DArrayTextures) { switch (State.m_WrapMode) { @@ -667,10 +717,10 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand m_pPrimitiveProgram = new CGLSLPrimitiveProgram; m_pTileProgram = new CGLSLTileProgram; m_pTileProgramTextured = new CGLSLTileProgram; - m_pBorderTileProgram = new CGLSLBorderTileProgram; - m_pBorderTileProgramTextured = new CGLSLBorderTileProgram; - m_pBorderTileLineProgram = new CGLSLBorderTileLineProgram; - m_pBorderTileLineProgramTextured = new CGLSLBorderTileLineProgram; + m_pBorderTileProgram = new CGLSLTileProgram; + m_pBorderTileProgramTextured = new CGLSLTileProgram; + m_pBorderTileLineProgram = new CGLSLTileProgram; + m_pBorderTileLineProgramTextured = new CGLSLTileProgram; m_pQuadProgram = new CGLSLQuadProgram; m_pQuadProgramTextured = new CGLSLQuadProgram; m_pTextProgram = new CGLSLTextProgram; @@ -678,11 +728,17 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand m_pSpriteProgramMultiple = new CGLSLSpriteMultipleProgram; m_LastProgramID = 0; + CGLSLCompiler ShaderCompiler(g_Config.m_GfxOpenGLMajor, g_Config.m_GfxOpenGLMinor, g_Config.m_GfxOpenGLPatch); + + GLint CapVal; + glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, &CapVal);; + m_MaxQuadsAtOnce = minimum(((CapVal - 20) / (3 * 4)), m_MaxQuadsPossible); + { CGLSL PrimitiveVertexShader; CGLSL PrimitiveFragmentShader; - PrimitiveVertexShader.LoadShader(pCommand->m_pStorage, "shader/prim.vert", GL_VERTEX_SHADER); - PrimitiveFragmentShader.LoadShader(pCommand->m_pStorage, "shader/prim.frag", GL_FRAGMENT_SHADER); + PrimitiveVertexShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/prim.vert", GL_VERTEX_SHADER); + PrimitiveFragmentShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/prim.frag", GL_FRAGMENT_SHADER); m_pPrimitiveProgram->CreateProgram(); m_pPrimitiveProgram->AddShader(&PrimitiveVertexShader); @@ -698,8 +754,8 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand { CGLSL VertexShader; CGLSL FragmentShader; - VertexShader.LoadShader(pCommand->m_pStorage, "shader/tile.vert", GL_VERTEX_SHADER); - FragmentShader.LoadShader(pCommand->m_pStorage, "shader/tile.frag", GL_FRAGMENT_SHADER); + VertexShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/tile.vert", GL_VERTEX_SHADER); + FragmentShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/tile.frag", GL_FRAGMENT_SHADER); m_pTileProgram->CreateProgram(); m_pTileProgram->AddShader(&VertexShader); @@ -708,19 +764,16 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand UseProgram(m_pTileProgram); - m_pTileProgram->m_LocPos = m_pTileProgram->GetUniformLoc("Pos"); - m_pTileProgram->m_LocIsTextured = -1; - m_pTileProgram->m_LocTextureSampler = -1; - m_pTileProgram->m_LocColor = m_pTileProgram->GetUniformLoc("vertColor"); - m_pTileProgram->m_LocLOD = -1; - m_pTileProgram->m_LocTexelOffset = -1; - m_pTileProgram->m_LastLOD = -1; + m_pTileProgram->m_LocPos = m_pTileProgram->GetUniformLoc("gPos"); + m_pTileProgram->m_LocColor = m_pTileProgram->GetUniformLoc("gVertColor"); } { CGLSL VertexShader; CGLSL FragmentShader; - VertexShader.LoadShader(pCommand->m_pStorage, "shader/tiletex.vert", GL_VERTEX_SHADER); - FragmentShader.LoadShader(pCommand->m_pStorage, "shader/tiletex.frag", GL_FRAGMENT_SHADER); + ShaderCompiler.AddDefine("TW_TILE_TEXTURED", ""); + VertexShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/tile.vert", GL_VERTEX_SHADER); + FragmentShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/tile.frag", GL_FRAGMENT_SHADER); + ShaderCompiler.ClearDefines(); m_pTileProgramTextured->CreateProgram(); m_pTileProgramTextured->AddShader(&VertexShader); @@ -729,19 +782,17 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand UseProgram(m_pTileProgramTextured); - m_pTileProgramTextured->m_LocPos = m_pTileProgramTextured->GetUniformLoc("Pos"); - m_pTileProgramTextured->m_LocIsTextured = -1; - m_pTileProgramTextured->m_LocTextureSampler = m_pTileProgramTextured->GetUniformLoc("textureSampler"); - m_pTileProgramTextured->m_LocColor = m_pTileProgramTextured->GetUniformLoc("vertColor"); - m_pTileProgramTextured->m_LocLOD = m_pTileProgramTextured->GetUniformLoc("LOD"); - m_pTileProgramTextured->m_LocTexelOffset = m_pTileProgramTextured->GetUniformLoc("TexelOffset"); - m_pTileProgramTextured->m_LastLOD = -1; + m_pTileProgramTextured->m_LocPos = m_pTileProgramTextured->GetUniformLoc("gPos"); + m_pTileProgramTextured->m_LocTextureSampler = m_pTileProgramTextured->GetUniformLoc("gTextureSampler"); + m_pTileProgramTextured->m_LocColor = m_pTileProgramTextured->GetUniformLoc("gVertColor"); } { CGLSL VertexShader; CGLSL FragmentShader; - VertexShader.LoadShader(pCommand->m_pStorage, "shader/bordertile.vert", GL_VERTEX_SHADER); - FragmentShader.LoadShader(pCommand->m_pStorage, "shader/bordertile.frag", GL_FRAGMENT_SHADER); + ShaderCompiler.AddDefine("TW_TILE_BORDER", ""); + VertexShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/tile.vert", GL_VERTEX_SHADER); + FragmentShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/tile.frag", GL_FRAGMENT_SHADER); + ShaderCompiler.ClearDefines(); m_pBorderTileProgram->CreateProgram(); m_pBorderTileProgram->AddShader(&VertexShader); @@ -750,22 +801,20 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand UseProgram(m_pBorderTileProgram); - m_pBorderTileProgram->m_LocPos = m_pBorderTileProgram->GetUniformLoc("Pos"); - m_pBorderTileProgram->m_LocIsTextured = -1; - m_pBorderTileProgram->m_LocTextureSampler = -1; - m_pBorderTileProgram->m_LocColor = m_pBorderTileProgram->GetUniformLoc("vertColor"); - m_pBorderTileProgram->m_LocLOD = -1; - m_pBorderTileProgram->m_LocTexelOffset = -1; - m_pBorderTileProgram->m_LastLOD = -1; - m_pBorderTileProgram->m_LocOffset = m_pBorderTileProgram->GetUniformLoc("Offset"); - m_pBorderTileProgram->m_LocDir = m_pBorderTileProgram->GetUniformLoc("Dir"); - m_pBorderTileProgram->m_LocJumpIndex = m_pBorderTileProgram->GetUniformLoc("JumpIndex"); + m_pBorderTileProgram->m_LocPos = m_pBorderTileProgram->GetUniformLoc("gPos"); + m_pBorderTileProgram->m_LocColor = m_pBorderTileProgram->GetUniformLoc("gVertColor"); + m_pBorderTileProgram->m_LocOffset = m_pBorderTileProgram->GetUniformLoc("gOffset"); + m_pBorderTileProgram->m_LocDir = m_pBorderTileProgram->GetUniformLoc("gDir"); + m_pBorderTileProgram->m_LocJumpIndex = m_pBorderTileProgram->GetUniformLoc("gJumpIndex"); } { CGLSL VertexShader; CGLSL FragmentShader; - VertexShader.LoadShader(pCommand->m_pStorage, "shader/bordertiletex.vert", GL_VERTEX_SHADER); - FragmentShader.LoadShader(pCommand->m_pStorage, "shader/bordertiletex.frag", GL_FRAGMENT_SHADER); + ShaderCompiler.AddDefine("TW_TILE_BORDER", ""); + ShaderCompiler.AddDefine("TW_TILE_TEXTURED", ""); + VertexShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/tile.vert", GL_VERTEX_SHADER); + FragmentShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/tile.frag", GL_FRAGMENT_SHADER); + ShaderCompiler.ClearDefines(); m_pBorderTileProgramTextured->CreateProgram(); m_pBorderTileProgramTextured->AddShader(&VertexShader); @@ -774,22 +823,20 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand UseProgram(m_pBorderTileProgramTextured); - m_pBorderTileProgramTextured->m_LocPos = m_pBorderTileProgramTextured->GetUniformLoc("Pos"); - m_pBorderTileProgramTextured->m_LocIsTextured = -1; - m_pBorderTileProgramTextured->m_LocTextureSampler = m_pBorderTileProgramTextured->GetUniformLoc("textureSampler"); - m_pBorderTileProgramTextured->m_LocColor = m_pBorderTileProgramTextured->GetUniformLoc("vertColor"); - m_pBorderTileProgramTextured->m_LocLOD = m_pBorderTileProgramTextured->GetUniformLoc("LOD"); - m_pBorderTileProgramTextured->m_LocTexelOffset = m_pBorderTileProgramTextured->GetUniformLoc("TexelOffset"); - m_pBorderTileProgramTextured->m_LastLOD = -1; - m_pBorderTileProgramTextured->m_LocOffset = m_pBorderTileProgramTextured->GetUniformLoc("Offset"); - m_pBorderTileProgramTextured->m_LocDir = m_pBorderTileProgramTextured->GetUniformLoc("Dir"); - m_pBorderTileProgramTextured->m_LocJumpIndex = m_pBorderTileProgramTextured->GetUniformLoc("JumpIndex"); + m_pBorderTileProgramTextured->m_LocPos = m_pBorderTileProgramTextured->GetUniformLoc("gPos"); + m_pBorderTileProgramTextured->m_LocTextureSampler = m_pBorderTileProgramTextured->GetUniformLoc("gTextureSampler"); + m_pBorderTileProgramTextured->m_LocColor = m_pBorderTileProgramTextured->GetUniformLoc("gVertColor"); + m_pBorderTileProgramTextured->m_LocOffset = m_pBorderTileProgramTextured->GetUniformLoc("gOffset"); + m_pBorderTileProgramTextured->m_LocDir = m_pBorderTileProgramTextured->GetUniformLoc("gDir"); + m_pBorderTileProgramTextured->m_LocJumpIndex = m_pBorderTileProgramTextured->GetUniformLoc("gJumpIndex"); } { CGLSL VertexShader; CGLSL FragmentShader; - VertexShader.LoadShader(pCommand->m_pStorage, "shader/bordertileline.vert", GL_VERTEX_SHADER); - FragmentShader.LoadShader(pCommand->m_pStorage, "shader/bordertileline.frag", GL_FRAGMENT_SHADER); + ShaderCompiler.AddDefine("TW_TILE_BORDER_LINE", ""); + VertexShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/tile.vert", GL_VERTEX_SHADER); + FragmentShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/tile.frag", GL_FRAGMENT_SHADER); + ShaderCompiler.ClearDefines(); m_pBorderTileLineProgram->CreateProgram(); m_pBorderTileLineProgram->AddShader(&VertexShader); @@ -798,21 +845,19 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand UseProgram(m_pBorderTileLineProgram); - m_pBorderTileLineProgram->m_LocPos = m_pBorderTileLineProgram->GetUniformLoc("Pos"); - m_pBorderTileLineProgram->m_LocIsTextured = -1; - m_pBorderTileLineProgram->m_LocTextureSampler = -1; - m_pBorderTileLineProgram->m_LocColor = m_pBorderTileLineProgram->GetUniformLoc("vertColor"); - m_pBorderTileLineProgram->m_LocLOD = -1; - m_pBorderTileLineProgram->m_LocTexelOffset = -1; - m_pBorderTileLineProgram->m_LastLOD = -1; - m_pBorderTileLineProgram->m_LocOffset = m_pBorderTileLineProgram->GetUniformLoc("Offset"); - m_pBorderTileLineProgram->m_LocDir = m_pBorderTileLineProgram->GetUniformLoc("Dir"); + m_pBorderTileLineProgram->m_LocPos = m_pBorderTileLineProgram->GetUniformLoc("gPos"); + m_pBorderTileLineProgram->m_LocColor = m_pBorderTileLineProgram->GetUniformLoc("gVertColor"); + m_pBorderTileLineProgram->m_LocOffset = m_pBorderTileLineProgram->GetUniformLoc("gOffset"); + m_pBorderTileLineProgram->m_LocDir = m_pBorderTileLineProgram->GetUniformLoc("gDir"); } { CGLSL VertexShader; CGLSL FragmentShader; - VertexShader.LoadShader(pCommand->m_pStorage, "shader/bordertilelinetex.vert", GL_VERTEX_SHADER); - FragmentShader.LoadShader(pCommand->m_pStorage, "shader/bordertilelinetex.frag", GL_FRAGMENT_SHADER); + ShaderCompiler.AddDefine("TW_TILE_BORDER_LINE", ""); + ShaderCompiler.AddDefine("TW_TILE_TEXTURED", ""); + VertexShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/tile.vert", GL_VERTEX_SHADER); + FragmentShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/tile.frag", GL_FRAGMENT_SHADER); + ShaderCompiler.ClearDefines(); m_pBorderTileLineProgramTextured->CreateProgram(); m_pBorderTileLineProgramTextured->AddShader(&VertexShader); @@ -821,21 +866,19 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand UseProgram(m_pBorderTileLineProgramTextured); - m_pBorderTileLineProgramTextured->m_LocPos = m_pBorderTileLineProgramTextured->GetUniformLoc("Pos"); - m_pBorderTileLineProgramTextured->m_LocIsTextured = -1; - m_pBorderTileLineProgramTextured->m_LocTextureSampler = m_pBorderTileLineProgramTextured->GetUniformLoc("textureSampler"); - m_pBorderTileLineProgramTextured->m_LocColor = m_pBorderTileLineProgramTextured->GetUniformLoc("vertColor"); - m_pBorderTileLineProgramTextured->m_LocLOD = m_pBorderTileLineProgramTextured->GetUniformLoc("LOD"); - m_pBorderTileLineProgramTextured->m_LocTexelOffset = m_pBorderTileLineProgramTextured->GetUniformLoc("TexelOffset"); - m_pBorderTileLineProgramTextured->m_LastLOD = -1; - m_pBorderTileLineProgramTextured->m_LocOffset = m_pBorderTileLineProgramTextured->GetUniformLoc("Offset"); - m_pBorderTileLineProgramTextured->m_LocDir = m_pBorderTileLineProgramTextured->GetUniformLoc("Dir"); + m_pBorderTileLineProgramTextured->m_LocPos = m_pBorderTileLineProgramTextured->GetUniformLoc("gPos"); + m_pBorderTileLineProgramTextured->m_LocTextureSampler = m_pBorderTileLineProgramTextured->GetUniformLoc("gTextureSampler"); + m_pBorderTileLineProgramTextured->m_LocColor = m_pBorderTileLineProgramTextured->GetUniformLoc("gVertColor"); + m_pBorderTileLineProgramTextured->m_LocOffset = m_pBorderTileLineProgramTextured->GetUniformLoc("gOffset"); + m_pBorderTileLineProgramTextured->m_LocDir = m_pBorderTileLineProgramTextured->GetUniformLoc("gDir"); } { CGLSL VertexShader; CGLSL FragmentShader; - VertexShader.LoadShader(pCommand->m_pStorage, "shader/quad.vert", GL_VERTEX_SHADER); - FragmentShader.LoadShader(pCommand->m_pStorage, "shader/quad.frag", GL_FRAGMENT_SHADER); + ShaderCompiler.AddDefine("TW_MAX_QUADS", std::to_string(m_MaxQuadsAtOnce).c_str()); + VertexShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/quad.vert", GL_VERTEX_SHADER); + FragmentShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/quad.frag", GL_FRAGMENT_SHADER); + ShaderCompiler.ClearDefines(); m_pQuadProgram->CreateProgram(); m_pQuadProgram->AddShader(&VertexShader); @@ -844,18 +887,19 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand UseProgram(m_pQuadProgram); - m_pQuadProgram->m_LocPos = m_pQuadProgram->GetUniformLoc("Pos"); - m_pQuadProgram->m_LocIsTextured = -1; - m_pQuadProgram->m_LocTextureSampler = -1; - m_pQuadProgram->m_LocColor = m_pQuadProgram->GetUniformLoc("vertColor"); - m_pQuadProgram->m_LocRotation = m_pQuadProgram->GetUniformLoc("Rotation"); - m_pQuadProgram->m_LocOffset = m_pQuadProgram->GetUniformLoc("Offset"); + m_pQuadProgram->m_LocPos = m_pQuadProgram->GetUniformLoc("gPos"); + m_pQuadProgram->m_LocColors = m_pQuadProgram->GetUniformLoc("gVertColors"); + m_pQuadProgram->m_LocRotations = m_pQuadProgram->GetUniformLoc("gRotations"); + m_pQuadProgram->m_LocOffsets = m_pQuadProgram->GetUniformLoc("gOffsets"); } { CGLSL VertexShader; CGLSL FragmentShader; - VertexShader.LoadShader(pCommand->m_pStorage, "shader/quadtex.vert", GL_VERTEX_SHADER); - FragmentShader.LoadShader(pCommand->m_pStorage, "shader/quadtex.frag", GL_FRAGMENT_SHADER); + ShaderCompiler.AddDefine("TW_QUAD_TEXTURED", ""); + ShaderCompiler.AddDefine("TW_MAX_QUADS", std::to_string(m_MaxQuadsAtOnce).c_str()); + VertexShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/quad.vert", GL_VERTEX_SHADER); + FragmentShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/quad.frag", GL_FRAGMENT_SHADER); + ShaderCompiler.ClearDefines(); m_pQuadProgramTextured->CreateProgram(); m_pQuadProgramTextured->AddShader(&VertexShader); @@ -864,18 +908,17 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand UseProgram(m_pQuadProgramTextured); - m_pQuadProgramTextured->m_LocPos = m_pQuadProgramTextured->GetUniformLoc("Pos"); - m_pQuadProgramTextured->m_LocIsTextured = -1; - m_pQuadProgramTextured->m_LocTextureSampler = m_pQuadProgramTextured->GetUniformLoc("textureSampler"); - m_pQuadProgramTextured->m_LocColor = m_pQuadProgramTextured->GetUniformLoc("vertColor"); - m_pQuadProgramTextured->m_LocRotation = m_pQuadProgramTextured->GetUniformLoc("Rotation"); - m_pQuadProgramTextured->m_LocOffset = m_pQuadProgramTextured->GetUniformLoc("Offset"); + m_pQuadProgramTextured->m_LocPos = m_pQuadProgramTextured->GetUniformLoc("gPos"); + m_pQuadProgramTextured->m_LocTextureSampler = m_pQuadProgramTextured->GetUniformLoc("gTextureSampler"); + m_pQuadProgramTextured->m_LocColors = m_pQuadProgramTextured->GetUniformLoc("gVertColors"); + m_pQuadProgramTextured->m_LocRotations = m_pQuadProgramTextured->GetUniformLoc("gRotations"); + m_pQuadProgramTextured->m_LocOffsets = m_pQuadProgramTextured->GetUniformLoc("gOffsets"); } { CGLSL VertexShader; CGLSL FragmentShader; - VertexShader.LoadShader(pCommand->m_pStorage, "shader/text.vert", GL_VERTEX_SHADER); - FragmentShader.LoadShader(pCommand->m_pStorage, "shader/text.frag", GL_FRAGMENT_SHADER); + VertexShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/text.vert", GL_VERTEX_SHADER); + FragmentShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/text.frag", GL_FRAGMENT_SHADER); m_pTextProgram->CreateProgram(); m_pTextProgram->AddShader(&VertexShader); @@ -896,8 +939,8 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand { CGLSL PrimitiveVertexShader; CGLSL PrimitiveFragmentShader; - PrimitiveVertexShader.LoadShader(pCommand->m_pStorage, "shader/sprite.vert", GL_VERTEX_SHADER); - PrimitiveFragmentShader.LoadShader(pCommand->m_pStorage, "shader/sprite.frag", GL_FRAGMENT_SHADER); + PrimitiveVertexShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/sprite.vert", GL_VERTEX_SHADER); + PrimitiveFragmentShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/sprite.frag", GL_FRAGMENT_SHADER); m_pSpriteProgram->CreateProgram(); m_pSpriteProgram->AddShader(&PrimitiveVertexShader); @@ -920,8 +963,8 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand { CGLSL PrimitiveVertexShader; CGLSL PrimitiveFragmentShader; - PrimitiveVertexShader.LoadShader(pCommand->m_pStorage, "shader/spritemulti.vert", GL_VERTEX_SHADER); - PrimitiveFragmentShader.LoadShader(pCommand->m_pStorage, "shader/spritemulti.frag", GL_FRAGMENT_SHADER); + PrimitiveVertexShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/spritemulti.vert", GL_VERTEX_SHADER); + PrimitiveFragmentShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/spritemulti.frag", GL_FRAGMENT_SHADER); m_pSpriteProgramMultiple->CreateProgram(); m_pSpriteProgramMultiple->AddShader(&PrimitiveVertexShader); @@ -975,6 +1018,7 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand for(int i = 0; i < m_MaxTextureUnits; ++i) { m_TextureSlotBoundToUnit[i].m_TextureSlot = -1; + m_TextureSlotBoundToUnit[i].m_Is2DArray = false; } glBindVertexArray(0); @@ -1086,6 +1130,7 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Texture_Destroy(const CCommandBuff glBindTexture(GL_TEXTURE_2D, 0); glBindSampler(Slot, 0); m_TextureSlotBoundToUnit[Slot].m_TextureSlot = -1; + m_TextureSlotBoundToUnit[Slot].m_Is2DArray = false; DestroyTexture(pCommand->m_Slot); } @@ -1184,6 +1229,53 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Texture_Create(const CCommandBuffe } glTexImage2D(GL_TEXTURE_2D, 0, StoreOglformat, Width, Height, 0, Oglformat, GL_UNSIGNED_BYTE, pTexData); glGenerateMipmap(GL_TEXTURE_2D); + + if((pCommand->m_Flags&(CCommandBuffer::TEXFLAG_TO_2D_ARRAY_TEXTURE | CCommandBuffer::TEXFLAG_TO_2D_ARRAY_TEXTURE_SINGLE_LAYER)) != 0) + { + glGenTextures(1, &m_aTextures[pCommand->m_Slot].m_Tex2DArray); + glBindTexture(GL_TEXTURE_2D_ARRAY, m_aTextures[pCommand->m_Slot].m_Tex2DArray); + + glGenSamplers(1, &m_aTextures[pCommand->m_Slot].m_Sampler2DArray); + glBindSampler(Slot, m_aTextures[pCommand->m_Slot].m_Sampler2DArray); + glSamplerParameteri(m_aTextures[pCommand->m_Slot].m_Sampler2DArray, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glSamplerParameteri(m_aTextures[pCommand->m_Slot].m_Sampler2DArray, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glSamplerParameteri(m_aTextures[pCommand->m_Slot].m_Sampler2DArray, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glSamplerParameteri(m_aTextures[pCommand->m_Slot].m_Sampler2DArray, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glSamplerParameteri(m_aTextures[pCommand->m_Slot].m_Sampler2DArray, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + + int ImageColorChannels = TexFormatToImageColorChannelCount(pCommand->m_Format); + + uint8_t* p3DImageData = NULL; + + bool IsSingleLayer = (pCommand->m_Flags& CCommandBuffer::TEXFLAG_TO_2D_ARRAY_TEXTURE_SINGLE_LAYER) != 0; + + if(!IsSingleLayer) + p3DImageData = (uint8_t*)malloc(ImageColorChannels * Width * Height); + int Image3DWidth, Image3DHeight; + + if(IsSingleLayer || (Width != 0 && Width % 16 == 0 && Height != 0 && Height % 16 == 0 && Texture2DTo3D(pTexData, Width, Height, ImageColorChannels, 16, 16, p3DImageData, Image3DWidth, Image3DHeight))) + { + if(IsSingleLayer) + { + glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, StoreOglformat, Width, Height, 1, 0, Oglformat, GL_UNSIGNED_BYTE, pTexData); + } + else + { + glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, StoreOglformat, Image3DWidth, Image3DHeight, 256, 0, Oglformat, GL_UNSIGNED_BYTE, p3DImageData); + } + glGenerateMipmap(GL_TEXTURE_2D_ARRAY); + + if(StoreOglformat == GL_R8) + { + //Bind the texture 2D. + GLint swizzleMask[] = {GL_ONE, GL_ONE, GL_ONE, GL_RED}; + glTexParameteriv(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); + } + } + + if(!IsSingleLayer) + free(p3DImageData); + } } // This is the initial value for the wrap modes @@ -1352,13 +1444,15 @@ bool CCommandProcessorFragment_OpenGL3_3::RunCommand(const CCommandBuffer::SComm return true; } -bool CCommandProcessorFragment_OpenGL3_3::IsAndUpdateTextureSlotBound(int IDX, int Slot) +bool CCommandProcessorFragment_OpenGL3_3::IsAndUpdateTextureSlotBound(int IDX, int Slot, bool Is2DArray) { - if(m_TextureSlotBoundToUnit[IDX].m_TextureSlot == Slot) return true; + if(m_TextureSlotBoundToUnit[IDX].m_TextureSlot == Slot && m_TextureSlotBoundToUnit[IDX].m_Is2DArray == Is2DArray) + return true; else { //the texture slot uses this index now m_TextureSlotBoundToUnit[IDX].m_TextureSlot = Slot; + m_TextureSlotBoundToUnit[IDX].m_Is2DArray = Is2DArray; return false; } } @@ -1369,8 +1463,20 @@ void CCommandProcessorFragment_OpenGL3_3::DestroyTexture(int Slot) glDeleteSamplers(1, &m_aTextures[Slot].m_Sampler); *m_pTextureMemoryUsage -= m_aTextures[Slot].m_MemSize; + if(m_aTextures[Slot].m_Tex2DArray != 0) + { + glDeleteTextures(1, &m_aTextures[Slot].m_Tex2DArray); + } + + if(m_aTextures[Slot].m_Sampler2DArray != 0) + { + glDeleteSamplers(1, &m_aTextures[Slot].m_Sampler2DArray); + } + m_aTextures[Slot].m_Tex = 0; m_aTextures[Slot].m_Sampler = 0; + m_aTextures[Slot].m_Tex2DArray = 0; + m_aTextures[Slot].m_Sampler2DArray = 0; } void CCommandProcessorFragment_OpenGL3_3::DestroyBufferContainer(int Index, bool DeleteBOs) @@ -1588,28 +1694,15 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_RenderBorderTile(const CCommandBuf SBufferContainer& BufferContainer = m_BufferContainers[Index]; if(BufferContainer.m_VertArrayID == 0) return; - CGLSLBorderTileProgram *pProgram = NULL; + CGLSLTileProgram *pProgram = NULL; if(pCommand->m_State.m_Texture >= 0 && pCommand->m_State.m_Texture < CCommandBuffer::MAX_TEXTURES) { pProgram = m_pBorderTileProgramTextured; } else pProgram = m_pBorderTileProgram; UseProgram(pProgram); - if(pProgram->m_LocLOD != -1) - { - if(pCommand->m_LOD != pProgram->m_LastLOD) - { - pProgram->SetUniform(pProgram->m_LocLOD, (float)(pCommand->m_LOD)); - // calculate the texel offset for the current LOD - float TexelOffset = (0.5f / (1024.0f * powf(0.5f, (float)pCommand->m_LOD))); - pProgram->SetUniform(pProgram->m_LocTexelOffset, TexelOffset); - - pProgram->m_LastLOD = pCommand->m_LOD; - } - } - - SetState(pCommand->m_State, pProgram); + SetState(pCommand->m_State, pProgram, true); pProgram->SetUniformVec4(pProgram->m_LocColor, 1, (float*)&pCommand->m_Color); pProgram->SetUniformVec2(pProgram->m_LocOffset, 1, (float*)&pCommand->m_Offset); @@ -1636,28 +1729,15 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_RenderBorderTileLine(const CComman if(BufferContainer.m_VertArrayID == 0) return; - CGLSLBorderTileLineProgram *pProgram = NULL; + CGLSLTileProgram *pProgram = NULL; if(pCommand->m_State.m_Texture >= 0 && pCommand->m_State.m_Texture < CCommandBuffer::MAX_TEXTURES) { pProgram = m_pBorderTileLineProgramTextured; } else pProgram = m_pBorderTileLineProgram; UseProgram(pProgram); - if(pProgram->m_LocLOD != -1) - { - if(pCommand->m_LOD != pProgram->m_LastLOD) - { - pProgram->SetUniform(pProgram->m_LocLOD, (float)(pCommand->m_LOD)); - // calculate the texel offset for the current LOD - float TexelOffset = (0.5f / (1024.0f * powf(0.5f, (float)pCommand->m_LOD))); - pProgram->SetUniform(pProgram->m_LocTexelOffset, TexelOffset); - - pProgram->m_LastLOD = pCommand->m_LOD; - } - } - - SetState(pCommand->m_State, pProgram); + SetState(pCommand->m_State, pProgram, true); pProgram->SetUniformVec4(pProgram->m_LocColor, 1, (float*)&pCommand->m_Color); pProgram->SetUniformVec2(pProgram->m_LocOffset, 1, (float*)&pCommand->m_Offset); pProgram->SetUniformVec2(pProgram->m_LocDir, 1, (float*)&pCommand->m_Dir); @@ -1695,21 +1775,8 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_RenderTileLayer(const CCommandBuff else pProgram = m_pTileProgram; UseProgram(pProgram); - if(pProgram->m_LocLOD != -1) - { - if(pCommand->m_LOD != pProgram->m_LastLOD) - { - pProgram->SetUniform(pProgram->m_LocLOD, (float)(pCommand->m_LOD)); - // calculate the texel offset for the current LOD - float TexelOffset = (0.5f / (1024.0f * powf(0.5f, (float)pCommand->m_LOD))); - pProgram->SetUniform(pProgram->m_LocTexelOffset, TexelOffset); - - pProgram->m_LastLOD = pCommand->m_LOD; - } - } - - SetState(pCommand->m_State, pProgram); + SetState(pCommand->m_State, pProgram, true); pProgram->SetUniformVec4(pProgram->m_LocColor, 1, (float*)&pCommand->m_Color); glBindVertexArray(BufferContainer.m_VertArrayID); @@ -1758,34 +1825,30 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_RenderQuadLayer(const CCommandBuff BufferContainer.m_LastIndexBufferBound = m_QuadDrawIndexBufferID; } - // colors, offsets and rotation probably rarely change - float aColor[4]; - mem_copy(aColor, pCommand->m_pQuadInfo[0].m_aColor, sizeof(aColor)); - float aOffset[2]; - mem_copy(aOffset, pCommand->m_pQuadInfo[0].m_aOffsets, sizeof(aOffset)); - float Rotation = pCommand->m_pQuadInfo[0].m_Rotation; - pProgram->SetUniformVec4(pProgram->m_LocColor, 1, (float*)aColor); - pProgram->SetUniformVec2(pProgram->m_LocOffset, 1, (float*)aOffset); - pProgram->SetUniform(pProgram->m_LocRotation, Rotation); + int QuadsLeft = pCommand->m_QuadNum; + size_t QuadOffset = 0; - for(int i = 0; i < pCommand->m_QuadNum; ++i) + vec4 aColors[m_MaxQuadsPossible]; + vec2 aOffsets[m_MaxQuadsPossible]; + float aRotations[m_MaxQuadsPossible]; + + while(QuadsLeft > 0) { - if(aColor[0] != pCommand->m_pQuadInfo[i].m_aColor[0] || aColor[1] != pCommand->m_pQuadInfo[i].m_aColor[1] || aColor[2] != pCommand->m_pQuadInfo[i].m_aColor[2] || aColor[3] != pCommand->m_pQuadInfo[i].m_aColor[3]) - { - mem_copy(aColor, pCommand->m_pQuadInfo[i].m_aColor, sizeof(aColor)); - pProgram->SetUniformVec4(pProgram->m_LocColor, 1, (float*)aColor); + int ActualQuadCount = minimum(QuadsLeft, m_MaxQuadsAtOnce); + + for(size_t i = 0; i < (size_t)ActualQuadCount; ++i) { + mem_copy(&aColors[i], pCommand->m_pQuadInfo[i + QuadOffset].m_aColor, sizeof(vec4)); + mem_copy(&aOffsets[i], pCommand->m_pQuadInfo[i + QuadOffset].m_aOffsets, sizeof(vec2)); + mem_copy(&aRotations[i], &pCommand->m_pQuadInfo[i + QuadOffset].m_Rotation, sizeof(float)); } - if(aOffset[0] != pCommand->m_pQuadInfo[i].m_aOffsets[0] || aOffset[1] != pCommand->m_pQuadInfo[i].m_aOffsets[1]) - { - mem_copy(aOffset, pCommand->m_pQuadInfo[i].m_aOffsets, sizeof(aOffset)); - pProgram->SetUniformVec2(pProgram->m_LocOffset, 1, (float*)aOffset); - } - if(Rotation != pCommand->m_pQuadInfo[i].m_Rotation) - { - Rotation = pCommand->m_pQuadInfo[i].m_Rotation; - pProgram->SetUniform(pProgram->m_LocRotation, Rotation); - } - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void*)(i * 6 * sizeof(unsigned int))); + + pProgram->SetUniformVec4(pProgram->m_LocColors, ActualQuadCount, (float*)aColors); + pProgram->SetUniformVec2(pProgram->m_LocOffsets, ActualQuadCount, (float*)aOffsets); + pProgram->SetUniform(pProgram->m_LocRotations, ActualQuadCount, (float*)aRotations); + glDrawElements(GL_TRIANGLES, ActualQuadCount * 6, GL_UNSIGNED_INT, (void*)(QuadOffset * 6 * sizeof(unsigned int))); + + QuadsLeft -= ActualQuadCount; + QuadOffset += (size_t)ActualQuadCount; } } diff --git a/src/engine/client/backend_sdl.h b/src/engine/client/backend_sdl.h index f8d621bd1..6377d8859 100644 --- a/src/engine/client/backend_sdl.h +++ b/src/engine/client/backend_sdl.h @@ -130,8 +130,6 @@ class CGLSLTWProgram; class CGLSLPrimitiveProgram; class CGLSLQuadProgram; class CGLSLTileProgram; -class CGLSLBorderTileProgram; -class CGLSLBorderTileLineProgram; class CGLSLTextProgram; class CGLSLSpriteProgram; class CGLSLSpriteMultipleProgram; @@ -143,8 +141,11 @@ class CCommandProcessorFragment_OpenGL3_3 struct CTexture { + CTexture() : m_Tex2DArray(0), m_Sampler2DArray(0) {} GLuint m_Tex; + GLuint m_Tex2DArray; GLuint m_Sampler; + GLuint m_Sampler2DArray; int m_LastWrapMode; int m_MemSize; @@ -156,13 +157,16 @@ class CCommandProcessorFragment_OpenGL3_3 CTexture m_aTextures[CCommandBuffer::MAX_TEXTURES]; volatile int *m_pTextureMemoryUsage; + int m_MaxQuadsAtOnce; + static const int m_MaxQuadsPossible = 256; + CGLSLPrimitiveProgram *m_pPrimitiveProgram; CGLSLTileProgram *m_pTileProgram; CGLSLTileProgram *m_pTileProgramTextured; - CGLSLBorderTileProgram *m_pBorderTileProgram; - CGLSLBorderTileProgram *m_pBorderTileProgramTextured; - CGLSLBorderTileLineProgram *m_pBorderTileLineProgram; - CGLSLBorderTileLineProgram *m_pBorderTileLineProgramTextured; + CGLSLTileProgram *m_pBorderTileProgram; + CGLSLTileProgram *m_pBorderTileProgramTextured; + CGLSLTileProgram *m_pBorderTileLineProgram; + CGLSLTileProgram *m_pBorderTileLineProgramTextured; CGLSLQuadProgram *m_pQuadProgram; CGLSLQuadProgram *m_pQuadProgramTextured; CGLSLTextProgram *m_pTextProgram; @@ -189,10 +193,11 @@ class CCommandProcessorFragment_OpenGL3_3 struct STextureBound{ int m_TextureSlot; + bool m_Is2DArray; }; std::vector m_TextureSlotBoundToUnit; //the texture index generated by loadtextureraw is stored in an index calculated by max texture units - bool IsAndUpdateTextureSlotBound(int IDX, int Slot); + bool IsAndUpdateTextureSlotBound(int IDX, int Slot, bool Is2DArray = false); void DestroyTexture(int Slot); void DestroyBufferContainer(int Index, bool DeleteBOs = true); @@ -231,10 +236,11 @@ public: private: static int TexFormatToOpenGLFormat(int TexFormat); + static int TexFormatToImageColorChannelCount(int TexFormat); static unsigned char Sample(int w, int h, const unsigned char *pData, int u, int v, int Offset, int ScaleW, int ScaleH, int Bpp); static void *Rescale(int Width, int Height, int NewWidth, int NewHeight, int Format, const unsigned char *pData); - void SetState(const CCommandBuffer::SState &State, CGLSLTWProgram *pProgram); + void SetState(const CCommandBuffer::SState &State, CGLSLTWProgram *pProgram, bool Use2DArrayTextures = false); void UseProgram(CGLSLTWProgram *pProgram); void UploadStreamBufferData(unsigned int PrimitiveType, const void* pVertices, unsigned int PrimitiveCount); void RenderText(const CCommandBuffer::SState& State, int DrawNum, int TextTextureIndex, int TextOutlineTextureIndex, int TextureSize, const float* pTextColor, const float* pTextOutlineColor); diff --git a/src/engine/client/graphics_threaded.cpp b/src/engine/client/graphics_threaded.cpp index 225011a5b..ac3650f6e 100644 --- a/src/engine/client/graphics_threaded.cpp +++ b/src/engine/client/graphics_threaded.cpp @@ -437,6 +437,14 @@ IGraphics::CTextureHandle CGraphics_Threaded::LoadTextureRaw(int Width, int Heig Cmd.m_Flags |= CCommandBuffer::TEXFLAG_COMPRESSED; if(g_Config.m_GfxTextureQuality || Flags&TEXLOAD_NORESAMPLE) Cmd.m_Flags |= CCommandBuffer::TEXFLAG_QUALITY; + if((Flags&IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE) != 0) + Cmd.m_Flags |= CCommandBuffer::TEXFLAG_TO_2D_ARRAY_TEXTURE; + if((Flags&IGraphics::TEXLOAD_TO_3D_TEXTURE) != 0) + Cmd.m_Flags |= CCommandBuffer::TEXFLAG_TO_3D_TEXTURE; + if((Flags&IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE_SINGLE_LAYER) != 0) + Cmd.m_Flags |= CCommandBuffer::TEXFLAG_TO_2D_ARRAY_TEXTURE_SINGLE_LAYER; + if((Flags&IGraphics::TEXLOAD_TO_3D_TEXTURE_SINGLE_LAYER) != 0) + Cmd.m_Flags |= CCommandBuffer::TEXFLAG_TO_3D_TEXTURE_SINGLE_LAYER; // copy texture data int MemSize = Width*Height*Cmd.m_PixelSize; @@ -1000,15 +1008,6 @@ void CGraphics_Threaded::RenderTileLayer(int BufferContainerIndex, float *pColor Cmd.m_IndicesDrawNum = NumIndicesOffet; Cmd.m_BufferContainerIndex = BufferContainerIndex; mem_copy(&Cmd.m_Color, pColor, sizeof(Cmd.m_Color)); - float ScreenZoomRatio = ScreenWidth() / (m_State.m_ScreenBR.x - m_State.m_ScreenTL.x); - //the number of pixels we would skip in the fragment shader -- basically the LOD - float LODFactor = (64.f / (32.f * ScreenZoomRatio)); - //log2 gives us the amount of halving the texture for mipmapping - int LOD = (int)log2f(LODFactor); - //5 because log2(1024/(2^5)) is 5 -- 2^5 = 32 which would mean 2 pixels per tile index - if(LOD > 5) LOD = 5; - if(LOD < 0) LOD = 0; - Cmd.m_LOD = LOD; void *Data = m_pCommandBuffer->AllocData((sizeof(char*) + sizeof(unsigned int))*NumIndicesOffet); if(Data == 0x0) @@ -1065,16 +1064,6 @@ void CGraphics_Threaded::RenderBorderTiles(int BufferContainerIndex, float *pCol Cmd.m_DrawNum = DrawNum; Cmd.m_BufferContainerIndex = BufferContainerIndex; mem_copy(&Cmd.m_Color, pColor, sizeof(Cmd.m_Color)); - float ScreenZoomRatio = ScreenWidth() / (m_State.m_ScreenBR.x - m_State.m_ScreenTL.x); - //the number of pixels we would skip in the fragment shader -- basically the LOD - float LODFactor = (64.f / (32.f * ScreenZoomRatio)); - //log2 gives us the amount of halving the texture for mipmapping - int LOD = (int)log2f(LODFactor); - if(LOD > 5) - LOD = 5; - if(LOD < 0) - LOD = 0; - Cmd.m_LOD = LOD; Cmd.m_pIndicesOffset = pIndexBufferOffset; Cmd.m_JumpIndex = JumpIndex; @@ -1109,16 +1098,6 @@ void CGraphics_Threaded::RenderBorderTileLines(int BufferContainerIndex, float * Cmd.m_DrawNum = RedrawNum; Cmd.m_BufferContainerIndex = BufferContainerIndex; mem_copy(&Cmd.m_Color, pColor, sizeof(Cmd.m_Color)); - float ScreenZoomRatio = ScreenWidth() / (m_State.m_ScreenBR.x - m_State.m_ScreenTL.x); - //the number of pixels we would skip in the fragment shader -- basically the LOD - float LODFactor = (64.f / (32.f * ScreenZoomRatio)); - //log2 gives us the amount of halving the texture for mipmapping - int LOD = (int)log2f(LODFactor); - if(LOD > 5) - LOD = 5; - if(LOD < 0) - LOD = 0; - Cmd.m_LOD = LOD; Cmd.m_pIndicesOffset = pIndexBufferOffset; @@ -2059,6 +2038,7 @@ int CGraphics_Threaded::IssueInit() int r = m_pBackend->Init("DDNet Client", &g_Config.m_GfxScreen, &g_Config.m_GfxScreenWidth, &g_Config.m_GfxScreenHeight, g_Config.m_GfxFsaaSamples, Flags, &m_DesktopScreenWidth, &m_DesktopScreenHeight, &m_ScreenWidth, &m_ScreenHeight, m_pStorage); m_IsNewOpenGL = m_pBackend->IsNewOpenGL(); m_OpenGLBufferingEnabled = m_IsNewOpenGL; + m_OpenGLHasTextureArrays = m_IsNewOpenGL; return r; } diff --git a/src/engine/client/graphics_threaded.h b/src/engine/client/graphics_threaded.h index 229d6d256..45e83795a 100644 --- a/src/engine/client/graphics_threaded.h +++ b/src/engine/client/graphics_threaded.h @@ -130,6 +130,10 @@ public: TEXFLAG_NOMIPMAPS = 1, TEXFLAG_COMPRESSED = 2, TEXFLAG_QUALITY = 4, + TEXFLAG_TO_3D_TEXTURE = (1 << 3), + TEXFLAG_TO_2D_ARRAY_TEXTURE = (1 << 4), + TEXFLAG_TO_3D_TEXTURE_SINGLE_LAYER = (1 << 5), + TEXFLAG_TO_2D_ARRAY_TEXTURE_SINGLE_LAYER = (1 << 6), }; enum @@ -313,7 +317,6 @@ public: int m_IndicesDrawNum; int m_BufferContainerIndex; - int m_LOD; }; struct SCommand_RenderBorderTile : public SCommand @@ -324,7 +327,6 @@ public: char *m_pIndicesOffset; // you should use the command buffer data to allocate vertices for this command unsigned int m_DrawNum; int m_BufferContainerIndex; - int m_LOD; float m_Offset[2]; float m_Dir[2]; @@ -340,7 +342,6 @@ public: unsigned int m_IndexDrawNum; unsigned int m_DrawNum; int m_BufferContainerIndex; - int m_LOD; float m_Offset[2]; float m_Dir[2]; @@ -611,6 +612,7 @@ class CGraphics_Threaded : public IEngineGraphics CCommandBuffer::SState m_State; IGraphicsBackend *m_pBackend; bool m_OpenGLBufferingEnabled; + bool m_OpenGLHasTextureArrays; bool m_IsNewOpenGL; CCommandBuffer *m_apCommandBuffers[NUM_CMDBUFFERS]; @@ -829,6 +831,7 @@ public: virtual void WaitForIdle(); virtual bool IsBufferingEnabled() { return m_OpenGLBufferingEnabled; } + virtual bool HasTextureArrays() { return m_OpenGLHasTextureArrays; } }; extern IGraphicsBackend *CreateGraphicsBackend(); diff --git a/src/engine/client/opengl_sl.cpp b/src/engine/client/opengl_sl.cpp index 4b1328b1c..9e7b9e395 100644 --- a/src/engine/client/opengl_sl.cpp +++ b/src/engine/client/opengl_sl.cpp @@ -5,7 +5,7 @@ #include #include -bool CGLSL::LoadShader(IStorage *pStorage, const char *pFile, int Type) +bool CGLSL::LoadShader(CGLSLCompiler* pCompiler, IStorage *pStorage, const char *pFile, int Type) { if (m_IsLoaded) return true; @@ -14,6 +14,14 @@ bool CGLSL::LoadShader(IStorage *pStorage, const char *pFile, int Type) std::vector Lines; if (f) { + //add compiler specific values + Lines.push_back(std::string("#version ") + std::string(std::to_string(pCompiler->m_OpenGLVersionMajor)) + std::string(std::to_string(pCompiler->m_OpenGLVersionMinor)) + std::string(std::to_string(pCompiler->m_OpenGLVersionPatch)) + std::string(" core\r\n")); + + for(CGLSLCompiler::SGLSLCompilerDefine& Define : pCompiler->m_Defines) + { + Lines.push_back(std::string("#define ") + Define.m_DefineName + std::string(" ") + Define.m_DefineValue + std::string("\r\n")); + } + CLineReader LineReader; LineReader.Init(f); char* ReadLine = NULL; @@ -91,3 +99,25 @@ CGLSL::~CGLSL() { DeleteShader(); } + +CGLSLCompiler::CGLSLCompiler(int OpenGLVersionMajor, int OpenGLVersionMinor, int OpenGLVersionPatch) +{ + m_OpenGLVersionMajor = OpenGLVersionMajor; + m_OpenGLVersionMinor = OpenGLVersionMinor; + m_OpenGLVersionPatch = OpenGLVersionPatch; +} + +void CGLSLCompiler::AddDefine(const std::string& DefineName, const std::string& DefineValue) +{ + m_Defines.emplace_back(SGLSLCompilerDefine(DefineName, DefineValue)); +} + +void CGLSLCompiler::AddDefine(const char* pDefineName, const char* pDefineValue) +{ + AddDefine(std::string(pDefineName), std::string(pDefineValue)); +} + +void CGLSLCompiler::ClearDefines() +{ + m_Defines.clear(); +} diff --git a/src/engine/client/opengl_sl.h b/src/engine/client/opengl_sl.h index 4e83073f3..bab1bfe24 100644 --- a/src/engine/client/opengl_sl.h +++ b/src/engine/client/opengl_sl.h @@ -2,10 +2,14 @@ #define ENGINE_CLIENT_OPENGL_SL_H #include +#include +#include + +class CGLSLCompiler; class CGLSL { public: - bool LoadShader(class IStorage *pStorage, const char *pFile, int Type); + bool LoadShader(CGLSLCompiler* pCompiler, class IStorage *pStorage, const char *pFile, int Type); void DeleteShader(); bool IsLoaded(); @@ -19,4 +23,33 @@ private: bool m_IsLoaded; }; +class CGLSLCompiler +{ +private: + friend class CGLSL; + + struct SGLSLCompilerDefine + { + SGLSLCompilerDefine(const std::string& DefineName, const std::string& DefineValue) + { + m_DefineName = DefineName; + m_DefineValue = DefineValue; + } + std::string m_DefineName; + std::string m_DefineValue; + }; + + std::vector m_Defines; + + int m_OpenGLVersionMajor; + int m_OpenGLVersionMinor; + int m_OpenGLVersionPatch; +public: + CGLSLCompiler(int OpenGLVersionMajor, int OpenGLVersionMinor, int OpenGLVersionPatch); + + void AddDefine(const std::string& DefineName, const std::string& DefineValue); + void AddDefine(const char* pDefineName, const char* pDefineValue); + void ClearDefines(); +}; + #endif // ENGINE_CLIENT_OPENGL_SL_H diff --git a/src/engine/client/opengl_sl_program.cpp b/src/engine/client/opengl_sl_program.cpp index 367dcd4ed..e51598f77 100644 --- a/src/engine/client/opengl_sl_program.cpp +++ b/src/engine/client/opengl_sl_program.cpp @@ -77,14 +77,19 @@ void CGLSLProgram::DetachAllShaders() } } -void CGLSLProgram::SetUniformVec4(int Loc, int Count, const float* Value) +void CGLSLProgram::SetUniformVec4(int Loc, int Count, const float *pValues) { - glUniform4fv(Loc, Count, Value); + glUniform4fv(Loc, Count, pValues); } -void CGLSLProgram::SetUniformVec2(int Loc, int Count, const float* Value) +void CGLSLProgram::SetUniformVec2(int Loc, int Count, const float *pValues) { - glUniform2fv(Loc, Count, Value); + glUniform2fv(Loc, Count, pValues); +} + +void CGLSLProgram::SetUniform(int Loc, int Count, const float *pValues) +{ + glUniform1fv(Loc, Count, pValues); } void CGLSLProgram::SetUniform(int Loc, const int Value) diff --git a/src/engine/client/opengl_sl_program.h b/src/engine/client/opengl_sl_program.h index 8861cc374..b54332a54 100644 --- a/src/engine/client/opengl_sl_program.h +++ b/src/engine/client/opengl_sl_program.h @@ -21,12 +21,13 @@ public: void DetachAllShaders(); //Support various types - void SetUniformVec2(int Loc, int Count, const float* Value); - void SetUniformVec4(int Loc, int Count, const float* Value); + void SetUniformVec2(int Loc, int Count, const float *pValue); + void SetUniformVec4(int Loc, int Count, const float *pValue); void SetUniform(int Loc, const int Value); void SetUniform(int Loc, const unsigned int Value); void SetUniform(int Loc, const bool Value); void SetUniform(int Loc, const float Value); + void SetUniform(int Loc, int Count, const float *pValues); //for performance reason we do not use SetUniform with using strings... save the Locations of the variables instead int GetUniformLoc(const char* Name); @@ -41,7 +42,7 @@ protected: class CGLSLTWProgram : public CGLSLProgram { public: - CGLSLTWProgram() : m_LastTextureSampler(-1), m_LastIsTextured(-1) + CGLSLTWProgram() : m_LocPos(-1), m_LocIsTextured(-1), m_LocTextureSampler(-1), m_LastTextureSampler(-1), m_LastIsTextured(-1) { m_LastScreen[0] = m_LastScreen[1] = m_LastScreen[2] = m_LastScreen[3] = -1.f; } @@ -118,33 +119,20 @@ public: class CGLSLQuadProgram : public CGLSLTWProgram { public: - int m_LocColor; - int m_LocOffset; - int m_LocRotation; + int m_LocColors; + int m_LocOffsets; + int m_LocRotations; }; class CGLSLTileProgram : public CGLSLTWProgram { public: + CGLSLTileProgram() : m_LocColor(-1), m_LocOffset(-1), m_LocDir(-1), m_LocNum(-1), m_LocJumpIndex(-1) {} + int m_LocColor; - int m_LocLOD; - int m_LocTexelOffset; - - int m_LastLOD; -}; - -class CGLSLBorderTileProgram : public CGLSLTileProgram { -public: int m_LocOffset; int m_LocDir; int m_LocNum; int m_LocJumpIndex; }; -class CGLSLBorderTileLineProgram : public CGLSLTileProgram { -public: - int m_LocOffset; - int m_LocDir; - int m_LocNum; -}; - #endif // ENGINE_CLIENT_OPENGL_SL_PROGRAM_H diff --git a/src/engine/client/text.cpp b/src/engine/client/text.cpp index 80f8e7ad2..4a06cdb8b 100644 --- a/src/engine/client/text.cpp +++ b/src/engine/client/text.cpp @@ -1712,7 +1712,7 @@ public: Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1); } - virtual void UploadEntityLayerText(IGraphics::CTextureHandle Texture, const char *pText, int Length, float x, float y, int FontSize) + virtual void UploadEntityLayerText(void* pTexBuff, int TexWidth, int TexHeight, const char *pText, int Length, float x, float y, int FontSize) { if (FontSize < 1) return; @@ -1751,15 +1751,22 @@ public: mem_zero(ms_aGlyphData, SlotSize); if(pBitmap->pixel_mode == FT_PIXEL_MODE_GRAY) // ignore_convention - { - for(py = 0; py < (unsigned)SlotH; py++) // ignore_convention - for(px = 0; px < (unsigned)SlotW; px++) - { - ms_aGlyphData[(py)*SlotW + px] = pBitmap->buffer[py*pBitmap->width + px]; // ignore_convention - } - } + { + for(py = 0; py < (unsigned)SlotH; py++) // ignore_convention + for(px = 0; px < (unsigned)SlotW; px++) + { + ms_aGlyphData[(py)*SlotW + px] = pBitmap->buffer[py*pBitmap->width + px]; // ignore_convention + } + } + + uint8_t* pImageBuff = (uint8_t*)pTexBuff; + for(int OffY = 0; OffY < SlotH; ++OffY) + { + size_t ImageOffset = (y + OffY) * TexWidth + (x + WidthLastChars); + size_t GlyphOffset = (OffY) * SlotW; + mem_copy(pImageBuff + ImageOffset, ms_aGlyphData + GlyphOffset, sizeof(uint8_t) * SlotW); + } - Graphics()->LoadTextureRawSub(Texture, x + WidthLastChars, y, SlotW, SlotH, CImageInfo::FORMAT_ALPHA, ms_aGlyphData); WidthLastChars += (SlotW + 1); } diff --git a/src/engine/graphics.h b/src/engine/graphics.h index 3b45e691a..a9cb8ded5 100644 --- a/src/engine/graphics.h +++ b/src/engine/graphics.h @@ -111,6 +111,10 @@ public: TEXLOAD_NORESAMPLE = 1<<0, TEXLOAD_NOMIPMAPS = 1<<1, TEXLOAD_NO_COMPRESSION = 1<<2, + TEXLOAD_TO_3D_TEXTURE = (1 << 3), + TEXLOAD_TO_2D_ARRAY_TEXTURE = (1 << 4), + TEXLOAD_TO_3D_TEXTURE_SINGLE_LAYER = (1 << 5), + TEXLOAD_TO_2D_ARRAY_TEXTURE_SINGLE_LAYER = (1 << 6), }; @@ -187,6 +191,7 @@ public: virtual void IndicesNumRequiredNotify(unsigned int RequiredIndicesCount) = 0; virtual bool IsBufferingEnabled() = 0; + virtual bool HasTextureArrays() = 0; struct CLineItem { diff --git a/src/engine/textrender.h b/src/engine/textrender.h index 144de8697..409ecbc1e 100644 --- a/src/engine/textrender.h +++ b/src/engine/textrender.h @@ -99,7 +99,7 @@ public: virtual void RenderTextContainer(int TextContainerIndex, STextRenderColor *pTextColor, STextRenderColor *pTextOutlineColor) = 0; virtual void RenderTextContainer(int TextContainerIndex, STextRenderColor *pTextColor, STextRenderColor *pTextOutlineColor, float X, float Y) = 0; - virtual void UploadEntityLayerText(IGraphics::CTextureHandle Texture, const char *pText, int Length, float x, float y, int FontHeight) = 0; + virtual void UploadEntityLayerText(void* pTexBuff, int TexWidth, int TexHeight, const char *pText, int Length, float x, float y, int FontHeight) = 0; virtual int AdjustFontSize(const char *pText, int TextLength, int MaxSize = -1) = 0; virtual int CalculateTextWidth(const char *pText, int TextLength, int FontWidth, int FontHeight) = 0; diff --git a/src/game/client/components/mapimages.cpp b/src/game/client/components/mapimages.cpp index 7415b36f7..85831458e 100644 --- a/src/game/client/components/mapimages.cpp +++ b/src/game/client/components/mapimages.cpp @@ -19,6 +19,7 @@ CMapImages::CMapImages(int TextureSize) m_Count = 0; m_TextureScale = TextureSize; m_EntitiesIsLoaded = false; + m_SpeedupArrowIsLoaded = false; } void CMapImages::OnInit() @@ -35,12 +36,38 @@ void CMapImages::OnMapLoad() { Graphics()->UnloadTexture(m_aTextures[i]); m_aTextures[i] = IGraphics::CTextureHandle(); + m_aTextureUsedByLayer[i] = false; } m_Count = 0; int Start; pMap->GetType(MAPITEMTYPE_IMAGE, &Start, &m_Count); + CLayers *pLayers = m_pClient->Layers(); + for(int g = 0; g < pLayers->NumGroups(); g++) + { + CMapItemGroup *pGroup = pLayers->GetGroup(g); + if(!pGroup) + { + continue; + } + + for(int l = 0; l < pGroup->m_NumLayers; l++) + { + CMapItemLayer *pLayer = pLayers->GetLayer(pGroup->m_StartLayer+l); + if(pLayer->m_Type == LAYERTYPE_TILES) + { + CMapItemLayerTilemap *pTLayer = (CMapItemLayerTilemap *)pLayer; + if(pTLayer->m_Image != -1 && pTLayer->m_Image < (int)(sizeof(m_aTextures) / sizeof(m_aTextures[0]))) + { + m_aTextureUsedByLayer[(size_t)pTLayer->m_Image] = true; + } + } + } + } + + int TextureLoadFlag = Graphics()->HasTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE; + // load new textures for(int i = 0; i < m_Count; i++) { @@ -50,12 +77,12 @@ void CMapImages::OnMapLoad() char Buf[256]; char *pName = (char *)pMap->GetData(pImg->m_ImageName); str_format(Buf, sizeof(Buf), "mapres/%s.png", pName); - m_aTextures[i] = Graphics()->LoadTexture(Buf, IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0); + m_aTextures[i] = Graphics()->LoadTexture(Buf, IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, m_aTextureUsedByLayer[i] ? TextureLoadFlag : 0); } else { void *pData = pMap->GetData(pImg->m_ImageData); - m_aTextures[i] = Graphics()->LoadTextureRaw(pImg->m_Width, pImg->m_Height, CImageInfo::FORMAT_RGBA, pData, CImageInfo::FORMAT_RGBA, 0); + m_aTextures[i] = Graphics()->LoadTextureRaw(pImg->m_Width, pImg->m_Height, CImageInfo::FORMAT_RGBA, pData, CImageInfo::FORMAT_RGBA, m_aTextureUsedByLayer[i] ? TextureLoadFlag : 0); pMap->UnloadData(pImg->m_ImageData); } } @@ -63,35 +90,7 @@ void CMapImages::OnMapLoad() void CMapImages::LoadBackground(class IMap *pMap) { - // unload all textures - for(int i = 0; i < m_Count; i++) - { - Graphics()->UnloadTexture(m_aTextures[i]); - m_aTextures[i] = IGraphics::CTextureHandle(); - } - m_Count = 0; - - int Start; - pMap->GetType(MAPITEMTYPE_IMAGE, &Start, &m_Count); - - // load new textures - for(int i = 0; i < m_Count; i++) - { - CMapItemImage *pImg = (CMapItemImage *)pMap->GetItem(Start+i, 0, 0); - if(pImg->m_External) - { - char Buf[256]; - char *pName = (char *)pMap->GetData(pImg->m_ImageName); - str_format(Buf, sizeof(Buf), "mapres/%s.png", pName); - m_aTextures[i] = Graphics()->LoadTexture(Buf, IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0); - } - else - { - void *pData = pMap->GetData(pImg->m_ImageData); - m_aTextures[i] = Graphics()->LoadTextureRaw(pImg->m_Width, pImg->m_Height, CImageInfo::FORMAT_RGBA, pData, CImageInfo::FORMAT_RGBA, 0); - pMap->UnloadData(pImg->m_ImageData); - } - } + CMapImages::OnMapLoad(); } IGraphics::CTextureHandle CMapImages::GetEntities() @@ -118,13 +117,27 @@ IGraphics::CTextureHandle CMapImages::GetEntities() if(m_EntitiesTextures >= 0) Graphics()->UnloadTexture(m_EntitiesTextures); - m_EntitiesTextures = Graphics()->LoadTexture(aPath, IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0); + int TextureLoadFlag = Graphics()->HasTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE; + m_EntitiesTextures = Graphics()->LoadTexture(aPath, IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, TextureLoadFlag); m_EntitiesIsLoaded = true; m_pEntitiesGameType = pEntities; } return m_EntitiesTextures; } +IGraphics::CTextureHandle CMapImages::GetSpeedupArrow() +{ + if(!m_SpeedupArrowIsLoaded) + { + int TextureLoadFlag = Graphics()->HasTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE_SINGLE_LAYER : IGraphics::TEXLOAD_TO_3D_TEXTURE_SINGLE_LAYER; + m_SpeedupArrowTexture = Graphics()->LoadTexture(g_pData->m_aImages[IMAGE_SPEEDUP_ARROW].m_pFilename, IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, TextureLoadFlag); + + m_SpeedupArrowIsLoaded = true; + } + + return m_SpeedupArrowTexture; +} + IGraphics::CTextureHandle CMapImages::GetOverlayBottom() { return m_OverlayBottomTexture; @@ -166,17 +179,19 @@ int CMapImages::GetTextureScale() IGraphics::CTextureHandle CMapImages::UploadEntityLayerText(int TextureSize, int YOffset) { void *pMem = calloc(1024 * 1024, 1); - IGraphics::CTextureHandle Texture = Graphics()->LoadTextureRaw(1024, 1024, CImageInfo::FORMAT_ALPHA, pMem, CImageInfo::FORMAT_ALPHA, IGraphics::TEXLOAD_NOMIPMAPS); - free(pMem); - UpdateEntityLayerText(Texture, TextureSize, YOffset, 0); - UpdateEntityLayerText(Texture, TextureSize, YOffset, 1); - UpdateEntityLayerText(Texture, TextureSize, YOffset, 2, 255); + UpdateEntityLayerText(pMem, 1024, 1024, TextureSize, YOffset, 0); + UpdateEntityLayerText(pMem, 1024, 1024, TextureSize, YOffset, 1); + UpdateEntityLayerText(pMem, 1024, 1024, TextureSize, YOffset, 2, 255); + + int TextureLoadFlag = Graphics()->HasTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE; + IGraphics::CTextureHandle Texture = Graphics()->LoadTextureRaw(1024, 1024, CImageInfo::FORMAT_ALPHA, pMem, CImageInfo::FORMAT_ALPHA, TextureLoadFlag); + free(pMem); return Texture; } -void CMapImages::UpdateEntityLayerText(IGraphics::CTextureHandle Texture, int TextureSize, int YOffset, int NumbersPower, int MaxNumber) +void CMapImages::UpdateEntityLayerText(void* pTexBuffer, int TexWidth, int TexHeight, int TextureSize, int YOffset, int NumbersPower, int MaxNumber) { char aBuf[4]; int DigitsCount = NumbersPower+1; @@ -202,7 +217,7 @@ void CMapImages::UpdateEntityLayerText(IGraphics::CTextureHandle Texture, int Te float x = (CurrentNumber%16)*64; float y = (CurrentNumber/16)*64; - TextRender()->UploadEntityLayerText(Texture, aBuf, DigitsCount, x+XOffSet, y+YOffset, UniversalSuitableFontSize); + TextRender()->UploadEntityLayerText(pTexBuffer, TexWidth, TexHeight, aBuf, DigitsCount, x+XOffSet, y+YOffset, UniversalSuitableFontSize); } } diff --git a/src/game/client/components/mapimages.h b/src/game/client/components/mapimages.h index d398ff081..94591d027 100644 --- a/src/game/client/components/mapimages.h +++ b/src/game/client/components/mapimages.h @@ -9,6 +9,7 @@ class CMapImages : public CComponent friend class CBackground; IGraphics::CTextureHandle m_aTextures[64]; + bool m_aTextureUsedByLayer[64]; int m_Count; const char *m_pEntitiesGameType; @@ -25,6 +26,7 @@ public: // DDRace IGraphics::CTextureHandle GetEntities(); + IGraphics::CTextureHandle GetSpeedupArrow(); IGraphics::CTextureHandle GetOverlayBottom(); IGraphics::CTextureHandle GetOverlayTop(); @@ -34,9 +36,10 @@ public: int GetTextureScale(); private: - bool m_EntitiesIsLoaded; + bool m_SpeedupArrowIsLoaded; IGraphics::CTextureHandle m_EntitiesTextures; + IGraphics::CTextureHandle m_SpeedupArrowTexture; IGraphics::CTextureHandle m_OverlayBottomTexture; IGraphics::CTextureHandle m_OverlayTopTexture; IGraphics::CTextureHandle m_OverlayCenterTexture; @@ -44,7 +47,7 @@ private: void InitOverlayTextures(); IGraphics::CTextureHandle UploadEntityLayerText(int TextureSize, int YOffset); - void UpdateEntityLayerText(IGraphics::CTextureHandle Texture, int TextureSize, int YOffset, int NumbersPower, int MaxNumber = -1); + void UpdateEntityLayerText(void* pTexBuffer, int TexWidth, int TexHeight, int TextureSize, int YOffset, int NumbersPower, int MaxNumber = -1); }; #endif diff --git a/src/game/client/components/maplayers.cpp b/src/game/client/components/maplayers.cpp index 89d8f611f..75a1406d1 100644 --- a/src/game/client/components/maplayers.cpp +++ b/src/game/client/components/maplayers.cpp @@ -132,23 +132,13 @@ struct STmpTile vec2 m_BottomRight; vec2 m_BottomLeft; }; + struct STmpTileTexCoord { - STmpTileTexCoord() - { - m_TexCoordTopLeftRightOrBottom[0] = m_TexCoordTopLeftRightOrBottom[1] = 0; - m_TexCoordBottomLeftRightOrBottom[0] = 0; m_TexCoordBottomLeftRightOrBottom[1] = 1; - m_TexCoordTopRightRightOrBottom[0] = 1; m_TexCoordTopRightRightOrBottom[1] = 0; - m_TexCoordBottomRightRightOrBottom[0] = m_TexCoordBottomRightRightOrBottom[1] = 1; - } - unsigned char m_TexCoordTopLeft[2]; - unsigned char m_TexCoordTopLeftRightOrBottom[2]; - unsigned char m_TexCoordTopRight[2]; - unsigned char m_TexCoordTopRightRightOrBottom[2]; - unsigned char m_TexCoordBottomRight[2]; - unsigned char m_TexCoordBottomRightRightOrBottom[2]; - unsigned char m_TexCoordBottomLeft[2]; - unsigned char m_TexCoordBottomLeftRightOrBottom[2]; + vec3 m_TexCoordTopLeft; + vec3 m_TexCoordTopRight; + vec3 m_TexCoordBottomRight; + vec3 m_TexCoordBottomLeft; }; void FillTmpTileSpeedup(STmpTile* pTmpTile, STmpTileTexCoord* pTmpTex, unsigned char Flags, unsigned char Index, int x, int y, int Scale, CMapItemGroup* pGroup, short AngleRotate) @@ -157,39 +147,25 @@ void FillTmpTileSpeedup(STmpTile* pTmpTile, STmpTileTexCoord* pTmpTex, unsigned { unsigned char x0 = 0; unsigned char y0 = 0; - unsigned char x1 = 16; - unsigned char y1 = 0; - unsigned char x2 = 16; - unsigned char y2 = 16; - unsigned char x3 = 0; - unsigned char y3 = 16; + unsigned char x1 = x0 + 1; + unsigned char y1 = y0; + unsigned char x2 = x0 + 1; + unsigned char y2 = y0 + 1; + unsigned char x3 = x0; + unsigned char y3 = y0 + 1; - unsigned char bx0 = 0; - unsigned char by0 = 0; - unsigned char bx1 = 1; - unsigned char by1 = 0; - unsigned char bx2 = 1; - unsigned char by2 = 1; - unsigned char bx3 = 0; - unsigned char by3 = 1; - - pTmpTex->m_TexCoordTopLeft[0] = x0; - pTmpTex->m_TexCoordTopLeft[1] = y0; - pTmpTex->m_TexCoordBottomLeft[0] = x3; - pTmpTex->m_TexCoordBottomLeft[1] = y3; - pTmpTex->m_TexCoordTopRight[0] = x1; - pTmpTex->m_TexCoordTopRight[1] = y1; - pTmpTex->m_TexCoordBottomRight[0] = x2; - pTmpTex->m_TexCoordBottomRight[1] = y2; - - pTmpTex->m_TexCoordTopLeftRightOrBottom[0] = bx0; - pTmpTex->m_TexCoordTopLeftRightOrBottom[1] = by0; - pTmpTex->m_TexCoordBottomLeftRightOrBottom[0] = bx3; - pTmpTex->m_TexCoordBottomLeftRightOrBottom[1] = by3; - pTmpTex->m_TexCoordTopRightRightOrBottom[0] = bx1; - pTmpTex->m_TexCoordTopRightRightOrBottom[1] = by1; - pTmpTex->m_TexCoordBottomRightRightOrBottom[0] = bx2; - pTmpTex->m_TexCoordBottomRightRightOrBottom[1] = by2; + pTmpTex->m_TexCoordTopLeft.x = x0; + pTmpTex->m_TexCoordTopLeft.y = y0; + pTmpTex->m_TexCoordTopLeft.z = Index; + pTmpTex->m_TexCoordBottomLeft.x = x3; + pTmpTex->m_TexCoordBottomLeft.y = y3; + pTmpTex->m_TexCoordBottomLeft.z = Index; + pTmpTex->m_TexCoordTopRight.x = x1; + pTmpTex->m_TexCoordTopRight.y = y1; + pTmpTex->m_TexCoordTopRight.z = Index; + pTmpTex->m_TexCoordBottomRight.x = x2; + pTmpTex->m_TexCoordBottomRight.y = y2; + pTmpTex->m_TexCoordBottomRight.z = Index; } //same as in rotate from Graphics() @@ -228,27 +204,14 @@ void FillTmpTile(STmpTile* pTmpTile, STmpTileTexCoord* pTmpTex, unsigned char Fl { if(pTmpTex) { - unsigned char tx = Index%16; - unsigned char ty = Index/16; - unsigned char x0 = tx; - unsigned char y0 = ty; - unsigned char x1 = tx+1; - unsigned char y1 = ty; - unsigned char x2 = tx+1; - unsigned char y2 = ty+1; - unsigned char x3 = tx; - unsigned char y3 = ty+1; - - unsigned char bx0 = 0; - unsigned char by0 = 0; - unsigned char bx1 = 1; - unsigned char by1 = 0; - unsigned char bx2 = 1; - unsigned char by2 = 1; - unsigned char bx3 = 0; - unsigned char by3 = 1; - - + unsigned char x0 = 0; + unsigned char y0 = 0; + unsigned char x1 = x0 + 1; + unsigned char y1 = y0; + unsigned char x2 = x0 + 1; + unsigned char y2 = y0 + 1; + unsigned char x3 = x0; + unsigned char y3 = y0 + 1; if(Flags&TILEFLAG_VFLIP) { @@ -256,11 +219,6 @@ void FillTmpTile(STmpTile* pTmpTile, STmpTileTexCoord* pTmpTex, unsigned char Fl x1 = x3; x2 = x3; x3 = x0; - - bx0 = bx2; - bx1 = bx3; - bx2 = bx3; - bx3 = bx0; } if(Flags&TILEFLAG_HFLIP) @@ -269,11 +227,6 @@ void FillTmpTile(STmpTile* pTmpTile, STmpTileTexCoord* pTmpTex, unsigned char Fl y2 = y1; y3 = y1; y1 = y0; - - by0 = by3; - by2 = by1; - by3 = by1; - by1 = by0; } if(Flags&TILEFLAG_ROTATE) @@ -288,36 +241,20 @@ void FillTmpTile(STmpTile* pTmpTile, STmpTileTexCoord* pTmpTex, unsigned char Fl y3 = y2; y2 = y1; y1 = Tmp; - - Tmp = bx0; - bx0 = bx3; - bx3 = bx2; - bx2 = bx1; - bx1 = Tmp; - Tmp = by0; - by0 = by3; - by3 = by2; - by2 = by1; - by1 = Tmp; } - pTmpTex->m_TexCoordTopLeft[0] = x0; - pTmpTex->m_TexCoordTopLeft[1] = y0; - pTmpTex->m_TexCoordBottomLeft[0] = x3; - pTmpTex->m_TexCoordBottomLeft[1] = y3; - pTmpTex->m_TexCoordTopRight[0] = x1; - pTmpTex->m_TexCoordTopRight[1] = y1; - pTmpTex->m_TexCoordBottomRight[0] = x2; - pTmpTex->m_TexCoordBottomRight[1] = y2; - - pTmpTex->m_TexCoordTopLeftRightOrBottom[0] = bx0; - pTmpTex->m_TexCoordTopLeftRightOrBottom[1] = by0; - pTmpTex->m_TexCoordBottomLeftRightOrBottom[0] = bx3; - pTmpTex->m_TexCoordBottomLeftRightOrBottom[1] = by3; - pTmpTex->m_TexCoordTopRightRightOrBottom[0] = bx1; - pTmpTex->m_TexCoordTopRightRightOrBottom[1] = by1; - pTmpTex->m_TexCoordBottomRightRightOrBottom[0] = bx2; - pTmpTex->m_TexCoordBottomRightRightOrBottom[1] = by2; + pTmpTex->m_TexCoordTopLeft.x = x0; + pTmpTex->m_TexCoordTopLeft.y = y0; + pTmpTex->m_TexCoordTopLeft.z = Index; + pTmpTex->m_TexCoordBottomLeft.x = x3; + pTmpTex->m_TexCoordBottomLeft.y = y3; + pTmpTex->m_TexCoordBottomLeft.z = Index; + pTmpTex->m_TexCoordTopRight.x = x1; + pTmpTex->m_TexCoordTopRight.y = y1; + pTmpTex->m_TexCoordTopRight.z = Index; + pTmpTex->m_TexCoordBottomRight.x = x2; + pTmpTex->m_TexCoordBottomRight.y = y2; + pTmpTex->m_TexCoordBottomRight.z = Index; } pTmpTile->m_TopLeft.x = x*Scale; @@ -401,8 +338,8 @@ bool AddTile(std::vector& TmpTiles, std::vector& Tmp struct STmpQuadVertexTextured { float m_X, m_Y, m_CenterX, m_CenterY; - float m_U, m_V; unsigned char m_R, m_G, m_B, m_A; + float m_U, m_V; }; struct STmpQuadVertex @@ -839,10 +776,10 @@ void CMapLayers::OnMapLoad() size_t UploadDataSize = tmpTileTexCoords.size() * sizeof(STmpTileTexCoord) + tmpTiles.size() * sizeof(STmpTile); char* pUploadData = new char[UploadDataSize]; - mem_copy_special(pUploadData, pTmpTiles, sizeof(vec2), tmpTiles.size() * 4, (DoTextureCoords ? (sizeof(unsigned char) * 2 * 2) : 0)); + mem_copy_special(pUploadData, pTmpTiles, sizeof(vec2), tmpTiles.size() * 4, (DoTextureCoords ? sizeof(vec3) : 0)); if(DoTextureCoords) { - mem_copy_special(pUploadData + sizeof(vec2), pTmpTileTexCoords, sizeof(unsigned char) * 2 * 2, tmpTiles.size() * 4, (DoTextureCoords ? (sizeof(vec2)) : 0)); + mem_copy_special(pUploadData + sizeof(vec2), pTmpTileTexCoords, sizeof(vec3), tmpTiles.size() * 4, (DoTextureCoords ? (sizeof(vec2)) : 0)); } // first create the buffer object @@ -851,7 +788,7 @@ void CMapLayers::OnMapLoad() // then create the buffer container SBufferContainerInfo ContainerInfo; - ContainerInfo.m_Stride = (DoTextureCoords ? (sizeof(float) * 2 + sizeof(unsigned char) * 2 * 2) : 0); + ContainerInfo.m_Stride = (DoTextureCoords ? (sizeof(float) * 2 + sizeof(vec3)) : 0); ContainerInfo.m_Attributes.push_back(SBufferContainerInfo::SAttribute()); SBufferContainerInfo::SAttribute* pAttr = &ContainerInfo.m_Attributes.back(); pAttr->m_DataTypeCount = 2; @@ -864,21 +801,12 @@ void CMapLayers::OnMapLoad() { ContainerInfo.m_Attributes.push_back(SBufferContainerInfo::SAttribute()); pAttr = &ContainerInfo.m_Attributes.back(); - pAttr->m_DataTypeCount = 2; - pAttr->m_Type = GRAPHICS_TYPE_UNSIGNED_BYTE; + pAttr->m_DataTypeCount = 3; + pAttr->m_Type = GRAPHICS_TYPE_FLOAT; pAttr->m_Normalized = false; pAttr->m_pOffset = (void*)(sizeof(vec2)); pAttr->m_FuncType = 0; pAttr->m_VertBufferBindingIndex = BufferObjectIndex; - - ContainerInfo.m_Attributes.push_back(SBufferContainerInfo::SAttribute()); - pAttr = &ContainerInfo.m_Attributes.back(); - pAttr->m_DataTypeCount = 2; - pAttr->m_Type = GRAPHICS_TYPE_UNSIGNED_BYTE; - pAttr->m_Normalized = false; - pAttr->m_pOffset = (void*)(sizeof(vec2) + sizeof(unsigned char) * 2); - pAttr->m_FuncType = 1; - pAttr->m_VertBufferBindingIndex = BufferObjectIndex; } Visuals.m_BufferContainerIndex = Graphics()->CreateBufferContainer(&ContainerInfo); @@ -971,6 +899,14 @@ void CMapLayers::OnMapLoad() pAttr->m_pOffset = 0; pAttr->m_FuncType = 0; pAttr->m_VertBufferBindingIndex = BufferObjectIndex; + ContainerInfo.m_Attributes.push_back(SBufferContainerInfo::SAttribute()); + pAttr = &ContainerInfo.m_Attributes.back(); + pAttr->m_DataTypeCount = 4; + pAttr->m_Type = GRAPHICS_TYPE_UNSIGNED_BYTE; + pAttr->m_Normalized = true; + pAttr->m_pOffset = (void*)(sizeof(float) * 4); + pAttr->m_FuncType = 0; + pAttr->m_VertBufferBindingIndex = BufferObjectIndex; if(Textured) { ContainerInfo.m_Attributes.push_back(SBufferContainerInfo::SAttribute()); @@ -978,18 +914,10 @@ void CMapLayers::OnMapLoad() pAttr->m_DataTypeCount = 2; pAttr->m_Type = GRAPHICS_TYPE_FLOAT; pAttr->m_Normalized = false; - pAttr->m_pOffset = (void*)(sizeof(float) * 4); + pAttr->m_pOffset = (void*)(sizeof(float) * 4 + sizeof(unsigned char) * 4); pAttr->m_FuncType = 0; pAttr->m_VertBufferBindingIndex = BufferObjectIndex; } - ContainerInfo.m_Attributes.push_back(SBufferContainerInfo::SAttribute()); - pAttr = &ContainerInfo.m_Attributes.back(); - pAttr->m_DataTypeCount = 4; - pAttr->m_Type = GRAPHICS_TYPE_UNSIGNED_BYTE; - pAttr->m_Normalized = true; - pAttr->m_pOffset = (void*)(sizeof(float) * 4 + (Textured ? (sizeof(float) * 2) : 0)); - pAttr->m_FuncType = 0; - pAttr->m_VertBufferBindingIndex = BufferObjectIndex; pQLayerVisuals->m_BufferContainerIndex = Graphics()->CreateBufferContainer(&ContainerInfo); // and finally inform the backend how many indices are required @@ -1935,7 +1863,7 @@ void CMapLayers::OnRender() // draw arrow -- clamp to the edge of the arrow image Graphics()->WrapClamp(); - Graphics()->TextureSet(g_pData->m_aImages[IMAGE_SPEEDUP_ARROW].m_Id); + Graphics()->TextureSet(m_pImages->GetSpeedupArrow()); RenderTileLayer(TileLayerCounter-3, &Color, pTMap, pGroup); Graphics()->WrapNormal(); if(g_Config.m_ClTextEntities)