From 639a8c3c8b72b0eb3fe1160f0d00b523b0898931 Mon Sep 17 00:00:00 2001 From: Jupeyy Date: Sat, 4 Nov 2023 14:51:39 +0100 Subject: [PATCH] Switch to a fragment shader solution for border tile rendering --- CMakeLists.txt | 5 + cmake/BuildVulkanShaders.cmake | 16 +- data/editor/speed_arrow_array.png | Bin 0 -> 35535 bytes data/shader/tile.vert | 29 +- data/shader/tile_border.frag | 28 + data/shader/tile_border.vert | 28 + data/shader/vulkan/tile.vert | 29 +- data/shader/vulkan/tile_border.frag | 28 + data/shader/vulkan/tile_border.vert | 33 + src/base/vmath.h | 2 + .../client/backend/opengl/backend_opengl.cpp | 554 +++++----------- .../client/backend/opengl/backend_opengl.h | 9 +- .../client/backend/opengl/backend_opengl3.cpp | 147 +---- .../client/backend/opengl/backend_opengl3.h | 5 - .../client/backend/opengl/opengl_sl_program.h | 1 + .../client/backend/vulkan/backend_vulkan.cpp | 148 ++--- src/engine/client/backend_sdl.h | 3 +- src/engine/client/graphics_threaded.cpp | 38 +- src/engine/client/graphics_threaded.h | 39 +- src/engine/graphics.h | 18 +- src/game/client/components/mapimages.cpp | 14 +- src/game/client/components/maplayers.cpp | 602 +++++++----------- src/game/client/components/maplayers.h | 24 +- src/game/client/render_map.cpp | 193 +++++- src/game/editor/editor.cpp | 6 +- src/game/editor/mapitems/map_io.cpp | 4 +- src/game/editor/tileart.cpp | 2 +- 27 files changed, 825 insertions(+), 1180 deletions(-) create mode 100644 data/editor/speed_arrow_array.png create mode 100644 data/shader/tile_border.frag create mode 100644 data/shader/tile_border.vert create mode 100644 data/shader/vulkan/tile_border.frag create mode 100644 data/shader/vulkan/tile_border.vert diff --git a/CMakeLists.txt b/CMakeLists.txt index 59ad00543..ce36a703f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1403,6 +1403,7 @@ set(EXPECTED_DATA editor/entities_clear/vanilla.png editor/front.png editor/speed_arrow.png + editor/speed_arrow_array.png editor/speedup.png editor/switch.png editor/tele.png @@ -1554,6 +1555,8 @@ set(EXPECTED_DATA shader/text.vert shader/tile.frag shader/tile.vert + shader/tile_border.frag + shader/tile_border.vert shader/vulkan/prim.frag shader/vulkan/prim.vert shader/vulkan/prim3d.frag @@ -1568,6 +1571,8 @@ set(EXPECTED_DATA shader/vulkan/text.vert shader/vulkan/tile.frag shader/vulkan/tile.vert + shader/vulkan/tile_border.frag + shader/vulkan/tile_border.vert skins/PaladiN.png skins/antiantey.png skins/beast.png diff --git a/cmake/BuildVulkanShaders.cmake b/cmake/BuildVulkanShaders.cmake index 3eeffe55d..c6cb0d6fe 100644 --- a/cmake/BuildVulkanShaders.cmake +++ b/cmake/BuildVulkanShaders.cmake @@ -136,18 +136,12 @@ if(NOT FOUND_MATCHING_SHA256_FILE) generate_shader_file("-DTW_TILE_TEXTURED" "" "${PROJECT_SOURCE_DIR}/data/shader/vulkan/tile.frag" "data/shader/vulkan/tile_textured.frag.spv") generate_shader_file("-DTW_TILE_TEXTURED" "" "${PROJECT_SOURCE_DIR}/data/shader/vulkan/tile.vert" "data/shader/vulkan/tile_textured.vert.spv") - generate_shader_file("-DTW_TILE_BORDER" "" "${PROJECT_SOURCE_DIR}/data/shader/vulkan/tile.frag" "data/shader/vulkan/tile_border.frag.spv") - generate_shader_file("-DTW_TILE_BORDER" "" "${PROJECT_SOURCE_DIR}/data/shader/vulkan/tile.vert" "data/shader/vulkan/tile_border.vert.spv") - - generate_shader_file("-DTW_TILE_BORDER" "-DTW_TILE_TEXTURED" "${PROJECT_SOURCE_DIR}/data/shader/vulkan/tile.frag" "data/shader/vulkan/tile_border_textured.frag.spv") - generate_shader_file("-DTW_TILE_BORDER" "-DTW_TILE_TEXTURED" "${PROJECT_SOURCE_DIR}/data/shader/vulkan/tile.vert" "data/shader/vulkan/tile_border_textured.vert.spv") - - generate_shader_file("-DTW_TILE_BORDER_LINE" "" "${PROJECT_SOURCE_DIR}/data/shader/vulkan/tile.frag" "data/shader/vulkan/tile_border_line.frag.spv") - generate_shader_file("-DTW_TILE_BORDER_LINE" "" "${PROJECT_SOURCE_DIR}/data/shader/vulkan/tile.vert" "data/shader/vulkan/tile_border_line.vert.spv") - - generate_shader_file("-DTW_TILE_BORDER_LINE" "-DTW_TILE_TEXTURED" "${PROJECT_SOURCE_DIR}/data/shader/vulkan/tile.frag" "data/shader/vulkan/tile_border_line_textured.frag.spv") - generate_shader_file("-DTW_TILE_BORDER_LINE" "-DTW_TILE_TEXTURED" "${PROJECT_SOURCE_DIR}/data/shader/vulkan/tile.vert" "data/shader/vulkan/tile_border_line_textured.vert.spv") + generate_shader_file("" "" "${PROJECT_SOURCE_DIR}/data/shader/vulkan/tile_border.frag" "data/shader/vulkan/tile_border.frag.spv") + generate_shader_file("" "" "${PROJECT_SOURCE_DIR}/data/shader/vulkan/tile_border.vert" "data/shader/vulkan/tile_border.vert.spv") + generate_shader_file("" "-DTW_TILE_TEXTURED" "${PROJECT_SOURCE_DIR}/data/shader/vulkan/tile_border.frag" "data/shader/vulkan/tile_border_textured.frag.spv") + generate_shader_file("" "-DTW_TILE_TEXTURED" "${PROJECT_SOURCE_DIR}/data/shader/vulkan/tile_border.vert" "data/shader/vulkan/tile_border_textured.vert.spv") + # quad layer generate_shader_file("" "" "${PROJECT_SOURCE_DIR}/data/shader/vulkan/quad.frag" "data/shader/vulkan/quad.frag.spv") generate_shader_file("" "" "${PROJECT_SOURCE_DIR}/data/shader/vulkan/quad.vert" "data/shader/vulkan/quad.vert.spv") diff --git a/data/editor/speed_arrow_array.png b/data/editor/speed_arrow_array.png new file mode 100644 index 0000000000000000000000000000000000000000..f85db1a0f4c0dcbf8c0566e3f42c197bfabc38f9 GIT binary patch literal 35535 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 bYWZWp{)=T-|C~Rx!=;OsFT6WHBI*ACOYz;^ literal 0 HcmV?d00001 diff --git a/data/shader/tile.vert b/data/shader/tile.vert index 0d3a4cfa7..6288371e9 100644 --- a/data/shader/tile.vert +++ b/data/shader/tile.vert @@ -1,44 +1,19 @@ layout (location = 0) in vec2 inVertex; #ifdef TW_TILE_TEXTURED -layout (location = 1) in vec3 inVertexTexCoord; +layout (location = 1) in uvec4 inVertexTexCoord; #endif 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() { -#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 * float(XCount); - VertPos.y += gOffset.y + gDir.y * float(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 * float(gl_InstanceID); - VertPos.y += gDir.y * float(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; + TexCoord = vec3(inVertexTexCoord.xyz); #endif } diff --git a/data/shader/tile_border.frag b/data/shader/tile_border.frag new file mode 100644 index 000000000..a186901c3 --- /dev/null +++ b/data/shader/tile_border.frag @@ -0,0 +1,28 @@ +#ifdef TW_TILE_TEXTURED +#ifdef TW_TILE_3D_TEXTURED +uniform sampler3D gTextureSampler; +#else +uniform sampler2DArray gTextureSampler; +#endif +#endif + +uniform vec4 gVertColor; + +#ifdef TW_TILE_TEXTURED +noperspective in vec3 TexCoord; +#endif + +out vec4 FragClr; + +void main() +{ +#ifdef TW_TILE_TEXTURED + vec3 realTexCoords = vec3(fract(TexCoord.xy), TexCoord.z); + vec2 dx = dFdx(TexCoord.xy); + vec2 dy = dFdy(TexCoord.xy); + vec4 tex = textureGrad(gTextureSampler, realTexCoords, dx, dy); + FragClr = tex * gVertColor; +#else + FragClr = gVertColor; +#endif +} diff --git a/data/shader/tile_border.vert b/data/shader/tile_border.vert new file mode 100644 index 000000000..f8f71ebda --- /dev/null +++ b/data/shader/tile_border.vert @@ -0,0 +1,28 @@ +layout (location = 0) in vec2 inVertex; +#ifdef TW_TILE_TEXTURED +layout (location = 1) in uvec4 inVertexTexCoord; +#endif + +uniform mat4x2 gPos; + +uniform vec2 gOffset; +uniform vec2 gScale; + +#ifdef TW_TILE_TEXTURED +noperspective out vec3 TexCoord; +#endif + +void main() +{ + // scale then position vertex + vec2 VertexPos = (inVertex * gScale) + gOffset; + gl_Position = vec4(gPos * vec4(VertexPos, 0.0, 1.0), 0.0, 1.0); + +#ifdef TW_TILE_TEXTURED + // scale the texture coordinates too + vec2 TexScale = gScale; + if (float(inVertexTexCoord.w) > 0.0) + TexScale = gScale.yx; + TexCoord = vec3(vec2(inVertexTexCoord.xy) * TexScale, float(inVertexTexCoord.z)); +#endif +} diff --git a/data/shader/vulkan/tile.vert b/data/shader/vulkan/tile.vert index 0dfebab96..7dd9d35fd 100644 --- a/data/shader/vulkan/tile.vert +++ b/data/shader/vulkan/tile.vert @@ -3,20 +3,11 @@ layout (location = 0) in vec2 inVertex; #ifdef TW_TILE_TEXTURED -layout (location = 1) in vec3 inVertexTexCoord; +layout (location = 1) in uvec4 inVertexTexCoord; #endif layout(push_constant) uniform SPosBO { layout(offset = 0) uniform mat4x2 gPos; - -#if defined(TW_TILE_BORDER) || defined(TW_TILE_BORDER_LINE) - layout(offset = 32) uniform vec2 gDir; - layout(offset = 40) uniform vec2 gOffset; -#endif - -#if defined(TW_TILE_BORDER) - layout(offset = 48) uniform int gJumpIndex; -#endif } gPosBO; #ifdef TW_TILE_TEXTURED @@ -25,25 +16,9 @@ layout (location = 0) noperspective out vec3 TexCoord; void main() { -#if defined(TW_TILE_BORDER) - vec4 VertPos = vec4(inVertex, 0.0, 1.0); - int XCount = gl_InstanceIndex - (int(gl_InstanceIndex/gPosBO.gJumpIndex) * gPosBO.gJumpIndex); - int YCount = (int(gl_InstanceIndex/gPosBO.gJumpIndex)); - VertPos.x += gPosBO.gOffset.x + gPosBO.gDir.x * float(XCount); - VertPos.y += gPosBO.gOffset.y + gPosBO.gDir.y * float(YCount); - - gl_Position = vec4(gPosBO.gPos * VertPos, 0.0, 1.0); -#elif defined(TW_TILE_BORDER_LINE) - vec4 VertPos = vec4(inVertex.x + gPosBO.gOffset.x, inVertex.y + gPosBO.gOffset.y, 0.0, 1.0); - VertPos.x += gPosBO.gDir.x * float(gl_InstanceIndex); - VertPos.y += gPosBO.gDir.y * float(gl_InstanceIndex); - - gl_Position = vec4(gPosBO.gPos * VertPos, 0.0, 1.0); -#else gl_Position = vec4(gPosBO.gPos * vec4(inVertex, 0.0, 1.0), 0.0, 1.0); -#endif #ifdef TW_TILE_TEXTURED - TexCoord = inVertexTexCoord; + TexCoord = vec3(inVertexTexCoord.xyz); #endif } diff --git a/data/shader/vulkan/tile_border.frag b/data/shader/vulkan/tile_border.frag new file mode 100644 index 000000000..31166b661 --- /dev/null +++ b/data/shader/vulkan/tile_border.frag @@ -0,0 +1,28 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable + +#ifdef TW_TILE_TEXTURED +layout(binding = 0) uniform sampler2DArray gTextureSampler; +#endif + +layout(push_constant) uniform SVertexColorBO { + layout(offset = 64) uniform vec4 gVertColor; +} gColorBO; + +#ifdef TW_TILE_TEXTURED +layout (location = 0) noperspective in vec3 TexCoord; +#endif + +layout (location = 0) out vec4 FragClr; +void main() +{ +#ifdef TW_TILE_TEXTURED + vec3 realTexCoords = vec3(fract(TexCoord.xy), TexCoord.z); + vec2 dx = dFdx(TexCoord.xy); + vec2 dy = dFdy(TexCoord.xy); + vec4 tex = textureGrad(gTextureSampler, realTexCoords, dx, dy); + FragClr = tex * gColorBO.gVertColor; +#else + FragClr = gColorBO.gVertColor; +#endif +} diff --git a/data/shader/vulkan/tile_border.vert b/data/shader/vulkan/tile_border.vert new file mode 100644 index 000000000..5463fdf39 --- /dev/null +++ b/data/shader/vulkan/tile_border.vert @@ -0,0 +1,33 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable + +layout (location = 0) in vec2 inVertex; +#ifdef TW_TILE_TEXTURED +layout (location = 1) in uvec4 inVertexTexCoord; +#endif + +layout(push_constant) uniform SPosBO { + layout(offset = 0) uniform mat4x2 gPos; + + layout(offset = 32) uniform vec2 gOffset; + layout(offset = 40) uniform vec2 gScale; +} gPosBO; + +#ifdef TW_TILE_TEXTURED +layout (location = 0) noperspective out vec3 TexCoord; +#endif + +void main() +{ + // scale then position vertex + vec2 VertexPos = (inVertex * gPosBO.gScale) + gPosBO.gOffset; + gl_Position = vec4(gPosBO.gPos * vec4(VertexPos, 0.0, 1.0), 0.0, 1.0); + +#ifdef TW_TILE_TEXTURED + // scale the texture coordinates too + vec2 TexScale = gPosBO.gScale; + if (inVertexTexCoord.w > 0) + TexScale = gPosBO.gScale.yx; + TexCoord = vec3(vec2(inVertexTexCoord.xy) * TexScale, float(inVertexTexCoord.z)); +#endif +} diff --git a/src/base/vmath.h b/src/base/vmath.h index 37205b108..6797e5db1 100644 --- a/src/base/vmath.h +++ b/src/base/vmath.h @@ -4,6 +4,7 @@ #define BASE_VMATH_H #include +#include #include "math.h" @@ -399,5 +400,6 @@ public: typedef vector4_base vec4; typedef vector4_base bvec4; typedef vector4_base ivec4; +typedef vector4_base ubvec4; #endif diff --git a/src/engine/client/backend/opengl/backend_opengl.cpp b/src/engine/client/backend/opengl/backend_opengl.cpp index 176f74b1f..a599a9903 100644 --- a/src/engine/client/backend/opengl/backend_opengl.cpp +++ b/src/engine/client/backend/opengl/backend_opengl.cpp @@ -451,7 +451,7 @@ bool CCommandProcessorFragment_OpenGL::InitOpenGL(const SCommand_Init *pCommand) pCommand->m_pCapabilities->m_ContextPatch = 0; } - pCommand->m_pCapabilities->m_TileBuffering = pCommand->m_pCapabilities->m_2DArrayTextures || pCommand->m_pCapabilities->m_3DTextures; + pCommand->m_pCapabilities->m_TileBuffering = pCommand->m_pCapabilities->m_2DArrayTextures; pCommand->m_pCapabilities->m_QuadBuffering = false; pCommand->m_pCapabilities->m_TextBuffering = false; pCommand->m_pCapabilities->m_QuadContainerBuffering = false; @@ -464,8 +464,6 @@ bool CCommandProcessorFragment_OpenGL::InitOpenGL(const SCommand_Init *pCommand) pCommand->m_pCapabilities->m_2DArrayTextures = false; pCommand->m_pCapabilities->m_ShaderSupport = false; - if(MinorV >= 1) - pCommand->m_pCapabilities->m_ShaderSupport = true; int Texture3DSize = 0; glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &Texture3DSize); @@ -474,19 +472,7 @@ bool CCommandProcessorFragment_OpenGL::InitOpenGL(const SCommand_Init *pCommand) pCommand->m_pCapabilities->m_3DTextures = true; } - // check for array texture extension - if(pCommand->m_pCapabilities->m_ShaderSupport && GLEW_EXT_texture_array) - { - int TextureLayers = 0; - glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS_EXT, &TextureLayers); - if(TextureLayers >= 256) - { - pCommand->m_pCapabilities->m_2DArrayTextures = true; - pCommand->m_pCapabilities->m_2DArrayTexturesAsExtension = true; - } - } - - pCommand->m_pCapabilities->m_TileBuffering = pCommand->m_pCapabilities->m_2DArrayTextures || pCommand->m_pCapabilities->m_3DTextures; + pCommand->m_pCapabilities->m_TileBuffering = false; pCommand->m_pCapabilities->m_QuadBuffering = false; pCommand->m_pCapabilities->m_TextBuffering = false; pCommand->m_pCapabilities->m_QuadContainerBuffering = false; @@ -815,8 +801,8 @@ void CCommandProcessorFragment_OpenGL::TextureCreate(int Slot, int Width, int He glTexImage2D(GL_TEXTURE_2D, 0, GLStoreFormat, Width, Height, 0, GLFormat, GL_UNSIGNED_BYTE, pTexData); } - int Flag2DArrayTexture = (CCommandBuffer::TEXFLAG_TO_2D_ARRAY_TEXTURE | CCommandBuffer::TEXFLAG_TO_2D_ARRAY_TEXTURE_SINGLE_LAYER); - int Flag3DTexture = (CCommandBuffer::TEXFLAG_TO_3D_TEXTURE | CCommandBuffer::TEXFLAG_TO_3D_TEXTURE_SINGLE_LAYER); + int Flag2DArrayTexture = CCommandBuffer::TEXFLAG_TO_2D_ARRAY_TEXTURE; + int Flag3DTexture = CCommandBuffer::TEXFLAG_TO_3D_TEXTURE; if((Flags & (Flag2DArrayTexture | Flag3DTexture)) != 0) { bool Is3DTexture = (Flags & Flag3DTexture) != 0; @@ -882,46 +868,32 @@ void CCommandProcessorFragment_OpenGL::TextureCreate(int Slot, int Width, int He uint8_t *p3DImageData = NULL; - bool IsSingleLayer = (Flags & (CCommandBuffer::TEXFLAG_TO_2D_ARRAY_TEXTURE_SINGLE_LAYER | CCommandBuffer::TEXFLAG_TO_3D_TEXTURE_SINGLE_LAYER)) != 0; - - if(!IsSingleLayer) - p3DImageData = (uint8_t *)malloc((size_t)Width * Height * PixelSize); + p3DImageData = (uint8_t *)malloc((size_t)Width * Height * PixelSize); int Image3DWidth, Image3DHeight; int ConvertWidth = Width; int ConvertHeight = Height; - if(!IsSingleLayer) + if(ConvertWidth == 0 || (ConvertWidth % 16) != 0 || ConvertHeight == 0 || (ConvertHeight % 16) != 0) { - if(ConvertWidth == 0 || (ConvertWidth % 16) != 0 || ConvertHeight == 0 || (ConvertHeight % 16) != 0) - { - dbg_msg("gfx", "3D/2D array texture was resized"); - int NewWidth = maximum(HighestBit(ConvertWidth), 16); - int NewHeight = maximum(HighestBit(ConvertHeight), 16); - uint8_t *pNewTexData = (uint8_t *)Resize((const uint8_t *)pTexData, ConvertWidth, ConvertHeight, NewWidth, NewHeight, GLFormatToPixelSize(GLFormat)); + dbg_msg("gfx", "3D/2D array texture was resized"); + int NewWidth = maximum(HighestBit(ConvertWidth), 16); + int NewHeight = maximum(HighestBit(ConvertHeight), 16); + uint8_t *pNewTexData = (uint8_t *)Resize((const uint8_t *)pTexData, ConvertWidth, ConvertHeight, NewWidth, NewHeight, GLFormatToPixelSize(GLFormat)); - ConvertWidth = NewWidth; - ConvertHeight = NewHeight; + ConvertWidth = NewWidth; + ConvertHeight = NewHeight; - free(pTexData); - pTexData = pNewTexData; - } + free(pTexData); + pTexData = pNewTexData; } - if(IsSingleLayer || (Texture2DTo3D(pTexData, ConvertWidth, ConvertHeight, PixelSize, 16, 16, p3DImageData, Image3DWidth, Image3DHeight))) + if((Texture2DTo3D(pTexData, ConvertWidth, ConvertHeight, PixelSize, 16, 16, p3DImageData, Image3DWidth, Image3DHeight))) { - if(IsSingleLayer) - { - glTexImage3D(Target, 0, GLStoreFormat, ConvertWidth, ConvertHeight, 1, 0, GLFormat, GL_UNSIGNED_BYTE, pTexData); - } - else - { - glTexImage3D(Target, 0, GLStoreFormat, Image3DWidth, Image3DHeight, 256, 0, GLFormat, GL_UNSIGNED_BYTE, p3DImageData); - } + glTexImage3D(Target, 0, GLStoreFormat, Image3DWidth, Image3DHeight, 256, 0, GLFormat, GL_UNSIGNED_BYTE, p3DImageData); } - if(!IsSingleLayer) - free(p3DImageData); + free(p3DImageData); } } @@ -1116,7 +1088,6 @@ ERunCommandReturnTypes CCommandProcessorFragment_OpenGL::RunCommand(const CComma case CCommandBuffer::CMD_RENDER_TILE_LAYER: Cmd_RenderTileLayer(static_cast(pBaseCommand)); break; case CCommandBuffer::CMD_RENDER_BORDER_TILE: Cmd_RenderBorderTile(static_cast(pBaseCommand)); break; - case CCommandBuffer::CMD_RENDER_BORDER_TILE_LINE: Cmd_RenderBorderTileLine(static_cast(pBaseCommand)); break; case CCommandBuffer::CMD_RENDER_QUAD_LAYER: Cmd_RenderQuadLayer(static_cast(pBaseCommand)); break; case CCommandBuffer::CMD_RENDER_TEXT: Cmd_RenderText(static_cast(pBaseCommand)); break; case CCommandBuffer::CMD_RENDER_QUAD_CONTAINER: Cmd_RenderQuadContainer(static_cast(pBaseCommand)); break; @@ -1283,7 +1254,7 @@ void CCommandProcessorFragment_OpenGL2::SetState(const CCommandBuffer::SState &S } #ifndef BACKEND_GL_MODERN_API -bool CCommandProcessorFragment_OpenGL2::DoAnalyzeStep(size_t StepN, size_t CheckCount, size_t VerticesCount, uint8_t aFakeTexture[], size_t SingleImageSize) +bool CCommandProcessorFragment_OpenGL2::DoAnalyzeStep(size_t CheckCount, size_t VerticesCount, uint8_t aFakeTexture[], size_t SingleImageSize) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -1291,18 +1262,10 @@ bool CCommandProcessorFragment_OpenGL2::DoAnalyzeStep(size_t StepN, size_t Check if(m_HasShaders) { CGLSLTWProgram *pProgram = m_pPrimitive3DProgramTextured; - if(StepN == 1) - pProgram = m_pTileProgramTextured; UseProgram(pProgram); pProgram->SetUniform(pProgram->m_LocTextureSampler, Slot); - if(StepN == 1) - { - float aColor[4] = {1.f, 1.f, 1.f, 1.f}; - pProgram->SetUniformVec4(((CGLSLTileProgram *)pProgram)->m_LocColor, 1, aColor); - } - float m[2 * 4] = { 1, 0, 0, 0, 0, 1, 0, 0}; @@ -1317,44 +1280,19 @@ bool CCommandProcessorFragment_OpenGL2::DoAnalyzeStep(size_t StepN, size_t Check glOrtho(-1, 1, -1, 1, -10.0f, 10.f); } - GLuint BufferID = 0; - if(StepN == 1 && m_HasShaders) - { - glGenBuffers(1, &BufferID); - glBindBuffer(GL_ARRAY_BUFFER, BufferID); - glBufferData(GL_ARRAY_BUFFER, VerticesCount * sizeof((m_aStreamVertices[0])), m_aStreamVertices, GL_STATIC_DRAW); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 2, GL_FLOAT, false, sizeof((m_aStreamVertices[0])), 0); - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, false, sizeof((m_aStreamVertices[0])), (GLvoid *)(sizeof(vec4) + sizeof(vec2))); - } - else - { - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - glVertexPointer(2, GL_FLOAT, sizeof(m_aStreamVertices[0]), m_aStreamVertices); - glColorPointer(4, GL_FLOAT, sizeof(m_aStreamVertices[0]), (uint8_t *)m_aStreamVertices + (ptrdiff_t)(sizeof(vec2))); - glTexCoordPointer(3, GL_FLOAT, sizeof(m_aStreamVertices[0]), (uint8_t *)m_aStreamVertices + (ptrdiff_t)(sizeof(vec2) + sizeof(vec4))); - } + glVertexPointer(2, GL_FLOAT, sizeof(m_aStreamVertices[0]), m_aStreamVertices); + glColorPointer(4, GL_FLOAT, sizeof(m_aStreamVertices[0]), (uint8_t *)m_aStreamVertices + (ptrdiff_t)(sizeof(vec2))); + glTexCoordPointer(3, GL_FLOAT, sizeof(m_aStreamVertices[0]), (uint8_t *)m_aStreamVertices + (ptrdiff_t)(sizeof(vec2) + sizeof(vec4))); glDrawArrays(GL_QUADS, 0, VerticesCount); - if(StepN == 1 && m_HasShaders) - { - glDisableVertexAttribArray(0); - glDisableVertexAttribArray(1); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glDeleteBuffers(1, &BufferID); - } - else - { - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); if(m_HasShaders) { @@ -1585,9 +1523,7 @@ bool CCommandProcessorFragment_OpenGL2::IsTileMapAnalysisSucceeded() } // everything build up, now do the analyze steps - bool NoError = DoAnalyzeStep(0, CheckCount, VertexCount, pFakeTexture, SingleImageSize); - if(NoError && m_HasShaders) - NoError &= DoAnalyzeStep(1, CheckCount, VertexCount, pFakeTexture, SingleImageSize); + bool NoError = DoAnalyzeStep(CheckCount, VertexCount, pFakeTexture, SingleImageSize); glDeleteTextures(1, &FakeTexture); free(pFakeTexture); @@ -1615,7 +1551,7 @@ bool CCommandProcessorFragment_OpenGL2::Cmd_Init(const SCommand_Init *pCommand) { HasAllFunc &= (glUniformMatrix4x2fv != NULL) && (glGenBuffers != NULL); HasAllFunc &= (glBindBuffer != NULL) && (glBufferData != NULL); - HasAllFunc &= (glEnableVertexAttribArray != NULL) && (glVertexAttribPointer != NULL); + HasAllFunc &= (glEnableVertexAttribArray != NULL) && (glVertexAttribPointer != NULL) && (glVertexAttribIPointer != NULL); HasAllFunc &= (glDisableVertexAttribArray != NULL) && (glDeleteBuffers != NULL); HasAllFunc &= (glUseProgram != NULL) && (glTexImage3D != NULL); HasAllFunc &= (glBindAttribLocation != NULL) && (glTexImage3D != NULL); @@ -1641,6 +1577,8 @@ bool CCommandProcessorFragment_OpenGL2::Cmd_Init(const SCommand_Init *pCommand) { m_pTileProgram = new CGLSLTileProgram; m_pTileProgramTextured = new CGLSLTileProgram; + m_pBorderTileProgram = new CGLSLTileProgram; + m_pBorderTileProgramTextured = new CGLSLTileProgram; m_pPrimitive3DProgram = new CGLSLPrimitiveProgram; m_pPrimitive3DProgramTextured = new CGLSLPrimitiveProgram; @@ -1743,6 +1681,63 @@ bool CCommandProcessorFragment_OpenGL2::Cmd_Init(const SCommand_Init *pCommand) m_pTileProgramTextured->m_LocTextureSampler = m_pTileProgramTextured->GetUniformLoc("gTextureSampler"); m_pTileProgramTextured->m_LocColor = m_pTileProgramTextured->GetUniformLoc("gVertColor"); } + if(pCommand->m_pCapabilities->m_2DArrayTextures) + ShaderCompiler.SetTextureReplaceType(CGLSLCompiler::GLSL_COMPILER_TEXTURE_REPLACE_TYPE_2D_ARRAY); + else + ShaderCompiler.SetTextureReplaceType(CGLSLCompiler::GLSL_COMPILER_TEXTURE_REPLACE_TYPE_3D); + { + CGLSL VertexShader; + CGLSL FragmentShader; + VertexShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/tile_border.vert", GL_VERTEX_SHADER); + FragmentShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/tile_border.frag", GL_FRAGMENT_SHADER); + ShaderCompiler.ClearDefines(); + + m_pBorderTileProgram->CreateProgram(); + m_pBorderTileProgram->AddShader(&VertexShader); + m_pBorderTileProgram->AddShader(&FragmentShader); + + glBindAttribLocation(m_pBorderTileProgram->GetProgramID(), 0, "inVertex"); + + m_pBorderTileProgram->LinkProgram(); + + UseProgram(m_pBorderTileProgram); + + 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_LocScale = m_pBorderTileProgram->GetUniformLoc("gScale"); + } + if(pCommand->m_pCapabilities->m_2DArrayTextures) + ShaderCompiler.SetTextureReplaceType(CGLSLCompiler::GLSL_COMPILER_TEXTURE_REPLACE_TYPE_2D_ARRAY); + else + ShaderCompiler.SetTextureReplaceType(CGLSLCompiler::GLSL_COMPILER_TEXTURE_REPLACE_TYPE_3D); + { + CGLSL VertexShader; + CGLSL FragmentShader; + ShaderCompiler.AddDefine("TW_TILE_TEXTURED", ""); + if(!pCommand->m_pCapabilities->m_2DArrayTextures) + ShaderCompiler.AddDefine("TW_TILE_3D_TEXTURED", ""); + VertexShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/tile_border.vert", GL_VERTEX_SHADER); + FragmentShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/tile_border.frag", GL_FRAGMENT_SHADER); + ShaderCompiler.ClearDefines(); + + m_pBorderTileProgramTextured->CreateProgram(); + m_pBorderTileProgramTextured->AddShader(&VertexShader); + m_pBorderTileProgramTextured->AddShader(&FragmentShader); + + glBindAttribLocation(m_pBorderTileProgramTextured->GetProgramID(), 0, "inVertex"); + glBindAttribLocation(m_pBorderTileProgramTextured->GetProgramID(), 1, "inVertexTexCoord"); + + m_pBorderTileProgramTextured->LinkProgram(); + + UseProgram(m_pBorderTileProgramTextured); + + 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_LocScale = m_pBorderTileProgramTextured->GetUniformLoc("gScale"); + } glUseProgram(0); } @@ -1850,13 +1845,10 @@ void CCommandProcessorFragment_OpenGL2::Cmd_CreateBufferObject(const CCommandBuf GLuint VertBufferID = 0; - if(m_HasShaders) - { - glGenBuffers(1, &VertBufferID); - glBindBuffer(GL_ARRAY_BUFFER, VertBufferID); - glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(pCommand->m_DataSize), pUploadData, GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); - } + glGenBuffers(1, &VertBufferID); + glBindBuffer(GL_ARRAY_BUFFER, VertBufferID); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(pCommand->m_DataSize), pUploadData, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); SBufferObject &BufferObject = m_vBufferObjectIndices[Index]; BufferObject.m_BufferObjectID = VertBufferID; @@ -1875,12 +1867,9 @@ void CCommandProcessorFragment_OpenGL2::Cmd_RecreateBufferObject(const CCommandB int Index = pCommand->m_BufferIndex; SBufferObject &BufferObject = m_vBufferObjectIndices[Index]; - if(m_HasShaders) - { - glBindBuffer(GL_ARRAY_BUFFER, BufferObject.m_BufferObjectID); - glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(pCommand->m_DataSize), pUploadData, GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); - } + glBindBuffer(GL_ARRAY_BUFFER, BufferObject.m_BufferObjectID); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(pCommand->m_DataSize), pUploadData, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); BufferObject.m_DataSize = pCommand->m_DataSize; free(BufferObject.m_pData); @@ -1898,12 +1887,9 @@ void CCommandProcessorFragment_OpenGL2::Cmd_UpdateBufferObject(const CCommandBuf int Index = pCommand->m_BufferIndex; SBufferObject &BufferObject = m_vBufferObjectIndices[Index]; - if(m_HasShaders) - { - glBindBuffer(GL_ARRAY_BUFFER, BufferObject.m_BufferObjectID); - glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)(pCommand->m_pOffset), (GLsizeiptr)(pCommand->m_DataSize), pUploadData); - glBindBuffer(GL_ARRAY_BUFFER, 0); - } + glBindBuffer(GL_ARRAY_BUFFER, BufferObject.m_BufferObjectID); + glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)(pCommand->m_pOffset), (GLsizeiptr)(pCommand->m_DataSize), pUploadData); + glBindBuffer(GL_ARRAY_BUFFER, 0); if(pUploadData) mem_copy(((uint8_t *)BufferObject.m_pData) + (ptrdiff_t)pCommand->m_pOffset, pUploadData, pCommand->m_DataSize); @@ -1922,12 +1908,9 @@ void CCommandProcessorFragment_OpenGL2::Cmd_CopyBufferObject(const CCommandBuffe mem_copy(((uint8_t *)WriteBufferObject.m_pData) + (ptrdiff_t)pCommand->m_WriteOffset, ((uint8_t *)ReadBufferObject.m_pData) + (ptrdiff_t)pCommand->m_ReadOffset, pCommand->m_CopySize); - if(m_HasShaders) - { - glBindBuffer(GL_ARRAY_BUFFER, WriteBufferObject.m_BufferObjectID); - glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)(pCommand->m_WriteOffset), (GLsizeiptr)(pCommand->m_CopySize), ((uint8_t *)WriteBufferObject.m_pData) + (ptrdiff_t)pCommand->m_WriteOffset); - glBindBuffer(GL_ARRAY_BUFFER, 0); - } + glBindBuffer(GL_ARRAY_BUFFER, WriteBufferObject.m_BufferObjectID); + glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)(pCommand->m_WriteOffset), (GLsizeiptr)(pCommand->m_CopySize), ((uint8_t *)WriteBufferObject.m_pData) + (ptrdiff_t)pCommand->m_WriteOffset); + glBindBuffer(GL_ARRAY_BUFFER, 0); } void CCommandProcessorFragment_OpenGL2::Cmd_DeleteBufferObject(const CCommandBuffer::SCommand_DeleteBufferObject *pCommand) @@ -1935,10 +1918,7 @@ void CCommandProcessorFragment_OpenGL2::Cmd_DeleteBufferObject(const CCommandBuf int Index = pCommand->m_BufferIndex; SBufferObject &BufferObject = m_vBufferObjectIndices[Index]; - if(m_HasShaders) - { - glDeleteBuffers(1, &BufferObject.m_BufferObjectID); - } + glDeleteBuffers(1, &BufferObject.m_BufferObjectID); free(BufferObject.m_pData); BufferObject.m_pData = NULL; @@ -1994,10 +1974,7 @@ void CCommandProcessorFragment_OpenGL2::Cmd_DeleteBufferContainer(const CCommand int VertBufferID = BufferContainer.m_ContainerInfo.m_VertBufferBindingIndex; if(VertBufferID != -1) { - if(m_HasShaders) - { - glDeleteBuffers(1, &m_vBufferObjectIndices[VertBufferID].m_BufferObjectID); - } + glDeleteBuffers(1, &m_vBufferObjectIndices[VertBufferID].m_BufferObjectID); free(m_vBufferObjectIndices[VertBufferID].m_pData); m_vBufferObjectIndices[VertBufferID].m_pData = NULL; @@ -2011,170 +1988,6 @@ void CCommandProcessorFragment_OpenGL2::Cmd_IndicesRequiredNumNotify(const CComm { } -void CCommandProcessorFragment_OpenGL2::RenderBorderTileEmulation(SBufferContainer &BufferContainer, const CCommandBuffer::SState &State, const ColorRGBA &Color, const char *pBuffOffset, unsigned int DrawNum, const vec2 &Offset, const vec2 &Dir, int JumpIndex) -{ - if(m_HasShaders) - { - CGLSLPrimitiveProgram *pProgram = NULL; - if(IsTexturedState(State)) - { - pProgram = m_pPrimitive3DProgramTextured; - } - else - pProgram = m_pPrimitive3DProgram; - - UseProgram(pProgram); - - SetState(State, pProgram, true); - } - else - { - CCommandProcessorFragment_OpenGL::SetState(State, true); - } - - bool IsTextured = BufferContainer.m_ContainerInfo.m_vAttributes.size() == 2; - - SBufferObject &BufferObject = m_vBufferObjectIndices[(size_t)BufferContainer.m_ContainerInfo.m_VertBufferBindingIndex]; - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - - if(IsTextured) - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - glVertexPointer(2, GL_FLOAT, sizeof(m_aStreamVertices[0]), m_aStreamVertices); - glColorPointer(4, GL_FLOAT, sizeof(m_aStreamVertices[0]), (uint8_t *)m_aStreamVertices + (ptrdiff_t)(sizeof(vec2))); - if(IsTextured) - glTexCoordPointer(3, GL_FLOAT, sizeof(m_aStreamVertices[0]), (uint8_t *)m_aStreamVertices + (ptrdiff_t)(sizeof(vec2) + sizeof(vec4))); - - size_t VertexCount = 0; - for(size_t i = 0; i < DrawNum; ++i) - { - GLint RealOffset = (GLint)((((size_t)(uintptr_t)(pBuffOffset)) / (6 * sizeof(unsigned int))) * 4); - size_t SingleVertSize = (sizeof(vec2) + (IsTextured ? sizeof(vec3) : 0)); - size_t CurBufferOffset = RealOffset * SingleVertSize; - int XCount = i - (size_t)(i / JumpIndex) * JumpIndex; - int YCount = (size_t)(i / JumpIndex); - for(size_t n = 0; n < 4; ++n) - { - ptrdiff_t VertOffset = (ptrdiff_t)(CurBufferOffset + (n * SingleVertSize)); - vec2 *pPos = (vec2 *)((uint8_t *)BufferObject.m_pData + VertOffset); - - GL_SVertexTex3D &Vertex = m_aStreamVertices[VertexCount++]; - Vertex.m_Pos = *pPos; - Vertex.m_Color = Color; - if(IsTextured) - { - vec3 *pTex = (vec3 *)((uint8_t *)BufferObject.m_pData + VertOffset + (ptrdiff_t)sizeof(vec2)); - Vertex.m_Tex = *pTex; - } - - Vertex.m_Pos += Offset + Dir * vec2(XCount, YCount); - - if(VertexCount >= std::size(m_aStreamVertices)) - { - glDrawArrays(GL_QUADS, 0, VertexCount); - VertexCount = 0; - } - } - } - if(VertexCount > 0) - glDrawArrays(GL_QUADS, 0, VertexCount); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - - if(IsTextured) - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - - if(m_HasShaders) - { - glUseProgram(0); - } -} - -void CCommandProcessorFragment_OpenGL2::RenderBorderTileLineEmulation(SBufferContainer &BufferContainer, const CCommandBuffer::SState &State, const ColorRGBA &Color, const char *pBuffOffset, unsigned int IndexDrawNum, unsigned int DrawNum, const vec2 &Offset, const vec2 &Dir) -{ - if(m_HasShaders) - { - CGLSLPrimitiveProgram *pProgram = NULL; - if(IsTexturedState(State)) - { - pProgram = m_pPrimitive3DProgramTextured; - } - else - pProgram = m_pPrimitive3DProgram; - - UseProgram(pProgram); - - SetState(State, pProgram, true); - } - else - { - CCommandProcessorFragment_OpenGL::SetState(State, true); - } - - bool IsTextured = BufferContainer.m_ContainerInfo.m_vAttributes.size() == 2; - - SBufferObject &BufferObject = m_vBufferObjectIndices[(size_t)BufferContainer.m_ContainerInfo.m_VertBufferBindingIndex]; - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - - if(IsTextured) - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - glVertexPointer(2, GL_FLOAT, sizeof(m_aStreamVertices[0]), m_aStreamVertices); - glColorPointer(4, GL_FLOAT, sizeof(m_aStreamVertices[0]), (uint8_t *)m_aStreamVertices + (ptrdiff_t)(sizeof(vec2))); - if(IsTextured) - glTexCoordPointer(3, GL_FLOAT, sizeof(m_aStreamVertices[0]), (uint8_t *)m_aStreamVertices + (ptrdiff_t)(sizeof(vec2) + sizeof(vec4))); - - size_t VertexCount = 0; - for(size_t i = 0; i < DrawNum; ++i) - { - GLint RealOffset = (GLint)((((size_t)(uintptr_t)(pBuffOffset)) / (6 * sizeof(unsigned int))) * 4); - size_t SingleVertSize = (sizeof(vec2) + (IsTextured ? sizeof(vec3) : 0)); - size_t CurBufferOffset = (RealOffset)*SingleVertSize; - size_t VerticesPerLine = (size_t)IndexDrawNum / 6; - - for(size_t n = 0; n < 4 * (size_t)VerticesPerLine; ++n) - { - ptrdiff_t VertOffset = (ptrdiff_t)(CurBufferOffset + (n * SingleVertSize)); - vec2 *pPos = (vec2 *)((uint8_t *)BufferObject.m_pData + VertOffset); - - GL_SVertexTex3D &Vertex = m_aStreamVertices[VertexCount++]; - Vertex.m_Pos = *pPos; - Vertex.m_Color = Color; - if(IsTextured) - { - vec3 *pTex = (vec3 *)((uint8_t *)BufferObject.m_pData + VertOffset + (ptrdiff_t)sizeof(vec2)); - Vertex.m_Tex = *pTex; - } - - Vertex.m_Pos += Offset + Dir * i; - - if(VertexCount >= std::size(m_aStreamVertices)) - { - glDrawArrays(GL_QUADS, 0, VertexCount); - VertexCount = 0; - } - } - } - if(VertexCount > 0) - glDrawArrays(GL_QUADS, 0, VertexCount); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - - if(IsTextured) - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - - if(m_HasShaders) - { - glUseProgram(0); - } -} - void CCommandProcessorFragment_OpenGL2::Cmd_RenderBorderTile(const CCommandBuffer::SCommand_RenderBorderTile *pCommand) { int Index = pCommand->m_BufferContainerIndex; @@ -2184,19 +1997,42 @@ void CCommandProcessorFragment_OpenGL2::Cmd_RenderBorderTile(const CCommandBuffe SBufferContainer &BufferContainer = m_vBufferContainers[Index]; - RenderBorderTileEmulation(BufferContainer, pCommand->m_State, pCommand->m_Color, pCommand->m_pIndicesOffset, pCommand->m_DrawNum, pCommand->m_Offset, pCommand->m_Dir, pCommand->m_JumpIndex); -} + CGLSLTileProgram *pProgram = NULL; + if(IsTexturedState(pCommand->m_State)) + pProgram = m_pBorderTileProgramTextured; + else + pProgram = m_pBorderTileProgram; + UseProgram(pProgram); -void CCommandProcessorFragment_OpenGL2::Cmd_RenderBorderTileLine(const CCommandBuffer::SCommand_RenderBorderTileLine *pCommand) -{ - int Index = pCommand->m_BufferContainerIndex; - // if space not there return - if((size_t)Index >= m_vBufferContainers.size()) - return; + SetState(pCommand->m_State, pProgram, true); + pProgram->SetUniformVec4(pProgram->m_LocColor, 1, (float *)&pCommand->m_Color); - SBufferContainer &BufferContainer = m_vBufferContainers[Index]; + pProgram->SetUniformVec2(pProgram->m_LocOffset, 1, (float *)&pCommand->m_Offset); + pProgram->SetUniformVec2(pProgram->m_LocScale, 1, (float *)&pCommand->m_Scale); - RenderBorderTileLineEmulation(BufferContainer, pCommand->m_State, pCommand->m_Color, pCommand->m_pIndicesOffset, pCommand->m_IndexDrawNum, pCommand->m_DrawNum, pCommand->m_Offset, pCommand->m_Dir); + bool IsTextured = BufferContainer.m_ContainerInfo.m_vAttributes.size() == 2; + + SBufferObject &BufferObject = m_vBufferObjectIndices[(size_t)BufferContainer.m_ContainerInfo.m_VertBufferBindingIndex]; + + glBindBuffer(GL_ARRAY_BUFFER, BufferObject.m_BufferObjectID); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, false, BufferContainer.m_ContainerInfo.m_Stride, BufferContainer.m_ContainerInfo.m_vAttributes[0].m_pOffset); + if(IsTextured) + { + glEnableVertexAttribArray(1); + glVertexAttribIPointer(1, 4, GL_UNSIGNED_BYTE, BufferContainer.m_ContainerInfo.m_Stride, BufferContainer.m_ContainerInfo.m_vAttributes[1].m_pOffset); + } + + size_t RealDrawCount = pCommand->m_DrawNum * 4; + GLint RealOffset = (GLint)((((size_t)(uintptr_t)(pCommand->m_pIndicesOffset)) / (6 * sizeof(unsigned int))) * 4); + glDrawArrays(GL_QUADS, RealOffset, RealDrawCount); + + glDisableVertexAttribArray(0); + if(IsTextured) + glDisableVertexAttribArray(1); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glUseProgram(0); } void CCommandProcessorFragment_OpenGL2::Cmd_RenderTileLayer(const CCommandBuffer::SCommand_RenderTileLayer *pCommand) @@ -2213,113 +2049,45 @@ void CCommandProcessorFragment_OpenGL2::Cmd_RenderTileLayer(const CCommandBuffer return; // nothing to draw } - if(m_HasShaders) + CGLSLTileProgram *pProgram = NULL; + if(IsTexturedState(pCommand->m_State)) { - CGLSLTileProgram *pProgram = NULL; - if(IsTexturedState(pCommand->m_State)) - { - pProgram = m_pTileProgramTextured; - } - else - pProgram = m_pTileProgram; - - UseProgram(pProgram); - - SetState(pCommand->m_State, pProgram, true); - pProgram->SetUniformVec4(pProgram->m_LocColor, 1, (float *)&pCommand->m_Color); + pProgram = m_pTileProgramTextured; } else - { - CCommandProcessorFragment_OpenGL::SetState(pCommand->m_State, true); - } + pProgram = m_pTileProgram; + + UseProgram(pProgram); + + SetState(pCommand->m_State, pProgram, true); + pProgram->SetUniformVec4(pProgram->m_LocColor, 1, (float *)&pCommand->m_Color); bool IsTextured = BufferContainer.m_ContainerInfo.m_vAttributes.size() == 2; SBufferObject &BufferObject = m_vBufferObjectIndices[(size_t)BufferContainer.m_ContainerInfo.m_VertBufferBindingIndex]; - if(m_HasShaders) - glBindBuffer(GL_ARRAY_BUFFER, BufferObject.m_BufferObjectID); - if(!m_HasShaders) + glBindBuffer(GL_ARRAY_BUFFER, BufferObject.m_BufferObjectID); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, false, BufferContainer.m_ContainerInfo.m_Stride, BufferContainer.m_ContainerInfo.m_vAttributes[0].m_pOffset); + if(IsTextured) { - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - - if(IsTextured) - glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableVertexAttribArray(1); + glVertexAttribIPointer(1, 4, GL_UNSIGNED_BYTE, BufferContainer.m_ContainerInfo.m_Stride, BufferContainer.m_ContainerInfo.m_vAttributes[1].m_pOffset); } - if(m_HasShaders) + for(int i = 0; i < pCommand->m_IndicesDrawNum; ++i) { - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 2, GL_FLOAT, false, BufferContainer.m_ContainerInfo.m_Stride, BufferContainer.m_ContainerInfo.m_vAttributes[0].m_pOffset); - if(IsTextured) - { - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, false, BufferContainer.m_ContainerInfo.m_Stride, BufferContainer.m_ContainerInfo.m_vAttributes[1].m_pOffset); - } - - for(int i = 0; i < pCommand->m_IndicesDrawNum; ++i) - { - size_t RealDrawCount = (pCommand->m_pDrawCount[i] / 6) * 4; - GLint RealOffset = (GLint)((((size_t)(uintptr_t)(pCommand->m_pIndicesOffsets[i])) / (6 * sizeof(unsigned int))) * 4); - glDrawArrays(GL_QUADS, RealOffset, RealDrawCount); - } - } - else - { - glVertexPointer(2, GL_FLOAT, sizeof(m_aStreamVertices[0]), m_aStreamVertices); - glColorPointer(4, GL_FLOAT, sizeof(m_aStreamVertices[0]), (uint8_t *)m_aStreamVertices + (ptrdiff_t)(sizeof(vec2))); - if(IsTextured) - glTexCoordPointer(3, GL_FLOAT, sizeof(m_aStreamVertices[0]), (uint8_t *)m_aStreamVertices + (ptrdiff_t)(sizeof(vec2) + sizeof(vec4))); - - size_t VertexCount = 0; - for(int i = 0; i < pCommand->m_IndicesDrawNum; ++i) - { - size_t RealDrawCount = (pCommand->m_pDrawCount[i] / 6) * 4; - GLint RealOffset = (GLint)((((size_t)(uintptr_t)(pCommand->m_pIndicesOffsets[i])) / (6 * sizeof(unsigned int))) * 4); - size_t SingleVertSize = (sizeof(vec2) + (IsTextured ? sizeof(vec3) : 0)); - size_t CurBufferOffset = RealOffset * SingleVertSize; - - for(size_t n = 0; n < RealDrawCount; ++n) - { - ptrdiff_t VertOffset = (ptrdiff_t)(CurBufferOffset + (n * SingleVertSize)); - vec2 *pPos = (vec2 *)((uint8_t *)BufferObject.m_pData + VertOffset); - GL_SVertexTex3D &Vertex = m_aStreamVertices[VertexCount++]; - Vertex.m_Pos = *pPos; - Vertex.m_Color = pCommand->m_Color; - if(IsTextured) - { - vec3 *pTex = (vec3 *)((uint8_t *)BufferObject.m_pData + VertOffset + (ptrdiff_t)sizeof(vec2)); - Vertex.m_Tex = *pTex; - } - - if(VertexCount >= std::size(m_aStreamVertices)) - { - glDrawArrays(GL_QUADS, 0, VertexCount); - VertexCount = 0; - } - } - } - if(VertexCount > 0) - glDrawArrays(GL_QUADS, 0, VertexCount); + size_t RealDrawCount = (pCommand->m_pDrawCount[i] / 6) * 4; + GLint RealOffset = (GLint)((((size_t)(uintptr_t)(pCommand->m_pIndicesOffsets[i])) / (6 * sizeof(unsigned int))) * 4); + glDrawArrays(GL_QUADS, RealOffset, RealDrawCount); } - if(!m_HasShaders) - { - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - - if(IsTextured) - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - else - { - glDisableVertexAttribArray(0); - if(IsTextured) - glDisableVertexAttribArray(1); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glUseProgram(0); - } + glDisableVertexAttribArray(0); + if(IsTextured) + glDisableVertexAttribArray(1); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glUseProgram(0); } #undef BACKEND_GL_MODERN_API diff --git a/src/engine/client/backend/opengl/backend_opengl.h b/src/engine/client/backend/opengl/backend_opengl.h index 3b2c844b3..2d339c0fd 100644 --- a/src/engine/client/backend/opengl/backend_opengl.h +++ b/src/engine/client/backend/opengl/backend_opengl.h @@ -116,7 +116,6 @@ protected: virtual void Cmd_RenderTileLayer(const CCommandBuffer::SCommand_RenderTileLayer *pCommand) { dbg_assert(false, "Call of unsupported Cmd_RenderTileLayer"); } virtual void Cmd_RenderBorderTile(const CCommandBuffer::SCommand_RenderBorderTile *pCommand) { dbg_assert(false, "Call of unsupported Cmd_RenderBorderTile"); } - virtual void Cmd_RenderBorderTileLine(const CCommandBuffer::SCommand_RenderBorderTileLine *pCommand) { dbg_assert(false, "Call of unsupported Cmd_RenderBorderTileLine"); } virtual void Cmd_RenderQuadLayer(const CCommandBuffer::SCommand_RenderQuadLayer *pCommand) { dbg_assert(false, "Call of unsupported Cmd_RenderQuadLayer"); } virtual void Cmd_RenderText(const CCommandBuffer::SCommand_RenderText *pCommand) { dbg_assert(false, "Call of unsupported Cmd_RenderText"); } virtual void Cmd_RenderQuadContainer(const CCommandBuffer::SCommand_RenderQuadContainer *pCommand) { dbg_assert(false, "Call of unsupported Cmd_RenderQuadContainer"); } @@ -158,11 +157,8 @@ class CCommandProcessorFragment_OpenGL2 : public CCommandProcessorFragment_OpenG std::vector m_vBufferObjectIndices; #ifndef BACKEND_GL_MODERN_API - bool DoAnalyzeStep(size_t StepN, size_t CheckCount, size_t VerticesCount, uint8_t aFakeTexture[], size_t SingleImageSize); + bool DoAnalyzeStep(size_t CheckCount, size_t VerticesCount, uint8_t aFakeTexture[], size_t SingleImageSize); bool IsTileMapAnalysisSucceeded(); - - void RenderBorderTileEmulation(SBufferContainer &BufferContainer, const CCommandBuffer::SState &State, const ColorRGBA &Color, const char *pBuffOffset, unsigned int DrawNum, const vec2 &Offset, const vec2 &Dir, int JumpIndex); - void RenderBorderTileLineEmulation(SBufferContainer &BufferContainer, const CCommandBuffer::SState &State, const ColorRGBA &Color, const char *pBuffOffset, unsigned int IndexDrawNum, unsigned int DrawNum, const vec2 &Offset, const vec2 &Dir); #endif void UseProgram(CGLSLTWProgram *pProgram); @@ -189,11 +185,12 @@ protected: void Cmd_RenderTileLayer(const CCommandBuffer::SCommand_RenderTileLayer *pCommand) override; void Cmd_RenderBorderTile(const CCommandBuffer::SCommand_RenderBorderTile *pCommand) override; - void Cmd_RenderBorderTileLine(const CCommandBuffer::SCommand_RenderBorderTileLine *pCommand) override; #endif CGLSLTileProgram *m_pTileProgram; CGLSLTileProgram *m_pTileProgramTextured; + CGLSLTileProgram *m_pBorderTileProgram; + CGLSLTileProgram *m_pBorderTileProgramTextured; CGLSLPrimitiveProgram *m_pPrimitive3DProgram; CGLSLPrimitiveProgram *m_pPrimitive3DProgramTextured; }; diff --git a/src/engine/client/backend/opengl/backend_opengl3.cpp b/src/engine/client/backend/opengl/backend_opengl3.cpp index 5fdee8c2c..315dd887d 100644 --- a/src/engine/client/backend/opengl/backend_opengl3.cpp +++ b/src/engine/client/backend/opengl/backend_opengl3.cpp @@ -106,8 +106,6 @@ bool CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand m_pPrimitive3DProgramTextured = new CGLSLPrimitiveProgram; 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; @@ -237,9 +235,8 @@ bool CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand { CGLSL VertexShader; CGLSL FragmentShader; - 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); + VertexShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/tile_border.vert", GL_VERTEX_SHADER); + FragmentShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/tile_border.frag", GL_FRAGMENT_SHADER); ShaderCompiler.ClearDefines(); m_pBorderTileProgram->CreateProgram(); @@ -252,16 +249,14 @@ bool CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand 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"); + m_pBorderTileProgram->m_LocScale = m_pBorderTileProgram->GetUniformLoc("gScale"); } { CGLSL VertexShader; CGLSL FragmentShader; - 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); + VertexShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/tile_border.vert", GL_VERTEX_SHADER); + FragmentShader.LoadShader(&ShaderCompiler, pCommand->m_pStorage, "shader/tile_border.frag", GL_FRAGMENT_SHADER); ShaderCompiler.ClearDefines(); m_pBorderTileProgramTextured->CreateProgram(); @@ -275,50 +270,7 @@ bool CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand 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; - 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); - m_pBorderTileLineProgram->AddShader(&FragmentShader); - m_pBorderTileLineProgram->LinkProgram(); - - UseProgram(m_pBorderTileLineProgram); - - 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; - 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); - m_pBorderTileLineProgramTextured->AddShader(&FragmentShader); - m_pBorderTileLineProgramTextured->LinkProgram(); - - UseProgram(m_pBorderTileLineProgramTextured); - - 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"); + m_pBorderTileProgramTextured->m_LocScale = m_pBorderTileProgramTextured->GetUniformLoc("gScale"); } { CGLSL VertexShader; @@ -485,8 +437,6 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Shutdown(const SCommand_Shutdown * m_pPrimitiveProgramTextured->DeleteProgram(); m_pBorderTileProgram->DeleteProgram(); m_pBorderTileProgramTextured->DeleteProgram(); - m_pBorderTileLineProgram->DeleteProgram(); - m_pBorderTileLineProgramTextured->DeleteProgram(); m_pQuadProgram->DeleteProgram(); m_pQuadProgramTextured->DeleteProgram(); m_pTileProgram->DeleteProgram(); @@ -505,8 +455,6 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Shutdown(const SCommand_Shutdown * delete m_pPrimitiveProgramTextured; delete m_pBorderTileProgram; delete m_pBorderTileProgramTextured; - delete m_pBorderTileLineProgram; - delete m_pBorderTileLineProgramTextured; delete m_pQuadProgram; delete m_pQuadProgramTextured; delete m_pTileProgram; @@ -652,7 +600,7 @@ void CCommandProcessorFragment_OpenGL3_3::TextureCreate(int Slot, int Width, int glGenerateMipmap(GL_TEXTURE_2D); } - if((Flags & (CCommandBuffer::TEXFLAG_TO_2D_ARRAY_TEXTURE | CCommandBuffer::TEXFLAG_TO_2D_ARRAY_TEXTURE_SINGLE_LAYER)) != 0) + if((Flags & (CCommandBuffer::TEXFLAG_TO_2D_ARRAY_TEXTURE)) != 0) { glGenTextures(1, &m_vTextures[Slot].m_Tex2DArray); glBindTexture(GL_TEXTURE_2D_ARRAY, m_vTextures[Slot].m_Tex2DArray); @@ -672,47 +620,33 @@ void CCommandProcessorFragment_OpenGL3_3::TextureCreate(int Slot, int Width, int uint8_t *p3DImageData = NULL; - bool IsSingleLayer = (Flags & CCommandBuffer::TEXFLAG_TO_2D_ARRAY_TEXTURE_SINGLE_LAYER) != 0; - - if(!IsSingleLayer) - p3DImageData = (uint8_t *)malloc((size_t)Width * Height * PixelSize); + p3DImageData = (uint8_t *)malloc((size_t)Width * Height * PixelSize); int Image3DWidth, Image3DHeight; int ConvertWidth = Width; int ConvertHeight = Height; - if(!IsSingleLayer) + if(ConvertWidth == 0 || (ConvertWidth % 16) != 0 || ConvertHeight == 0 || (ConvertHeight % 16) != 0) { - if(ConvertWidth == 0 || (ConvertWidth % 16) != 0 || ConvertHeight == 0 || (ConvertHeight % 16) != 0) - { - dbg_msg("gfx", "3D/2D array texture was resized"); - int NewWidth = maximum(HighestBit(ConvertWidth), 16); - int NewHeight = maximum(HighestBit(ConvertHeight), 16); - uint8_t *pNewTexData = (uint8_t *)Resize((const uint8_t *)pTexData, ConvertWidth, ConvertHeight, NewWidth, NewHeight, GLFormatToPixelSize(GLFormat)); + dbg_msg("gfx", "3D/2D array texture was resized"); + int NewWidth = maximum(HighestBit(ConvertWidth), 16); + int NewHeight = maximum(HighestBit(ConvertHeight), 16); + uint8_t *pNewTexData = (uint8_t *)Resize((const uint8_t *)pTexData, ConvertWidth, ConvertHeight, NewWidth, NewHeight, GLFormatToPixelSize(GLFormat)); - ConvertWidth = NewWidth; - ConvertHeight = NewHeight; + ConvertWidth = NewWidth; + ConvertHeight = NewHeight; - free(pTexData); - pTexData = pNewTexData; - } + free(pTexData); + pTexData = pNewTexData; } - if(IsSingleLayer || (Texture2DTo3D(pTexData, ConvertWidth, ConvertHeight, PixelSize, 16, 16, p3DImageData, Image3DWidth, Image3DHeight))) + if((Texture2DTo3D(pTexData, ConvertWidth, ConvertHeight, PixelSize, 16, 16, p3DImageData, Image3DWidth, Image3DHeight))) { - if(IsSingleLayer) - { - glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GLStoreFormat, ConvertWidth, ConvertHeight, 1, 0, GLFormat, GL_UNSIGNED_BYTE, pTexData); - } - else - { - glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GLStoreFormat, Image3DWidth, Image3DHeight, 256, 0, GLFormat, GL_UNSIGNED_BYTE, p3DImageData); - } + glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GLStoreFormat, Image3DWidth, Image3DHeight, 256, 0, GLFormat, GL_UNSIGNED_BYTE, p3DImageData); glGenerateMipmap(GL_TEXTURE_2D_ARRAY); } - if(!IsSingleLayer) - free(p3DImageData); + free(p3DImageData); } } @@ -1088,9 +1022,7 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_RenderBorderTile(const CCommandBuf CGLSLTileProgram *pProgram = NULL; if(IsTexturedState(pCommand->m_State)) - { pProgram = m_pBorderTileProgramTextured; - } else pProgram = m_pBorderTileProgram; UseProgram(pProgram); @@ -1099,8 +1031,7 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_RenderBorderTile(const CCommandBuf 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); - pProgram->SetUniform(pProgram->m_LocJumpIndex, (int)pCommand->m_JumpIndex); + pProgram->SetUniformVec2(pProgram->m_LocScale, 1, (float *)&pCommand->m_Scale); glBindVertexArray(BufferContainer.m_VertArrayID); if(BufferContainer.m_LastIndexBufferBound != m_QuadDrawIndexBufferID) @@ -1108,41 +1039,7 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_RenderBorderTile(const CCommandBuf glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_QuadDrawIndexBufferID); BufferContainer.m_LastIndexBufferBound = m_QuadDrawIndexBufferID; } - glDrawElementsInstanced(GL_TRIANGLES, 6, GL_UNSIGNED_INT, pCommand->m_pIndicesOffset, pCommand->m_DrawNum); -} - -void CCommandProcessorFragment_OpenGL3_3::Cmd_RenderBorderTileLine(const CCommandBuffer::SCommand_RenderBorderTileLine *pCommand) -{ - int Index = pCommand->m_BufferContainerIndex; - // if space not there return - if((size_t)Index >= m_vBufferContainers.size()) - return; - - SBufferContainer &BufferContainer = m_vBufferContainers[Index]; - if(BufferContainer.m_VertArrayID == 0) - return; - - CGLSLTileProgram *pProgram = NULL; - if(IsTexturedState(pCommand->m_State)) - { - pProgram = m_pBorderTileLineProgramTextured; - } - else - pProgram = m_pBorderTileLineProgram; - UseProgram(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); - - glBindVertexArray(BufferContainer.m_VertArrayID); - if(BufferContainer.m_LastIndexBufferBound != m_QuadDrawIndexBufferID) - { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_QuadDrawIndexBufferID); - BufferContainer.m_LastIndexBufferBound = m_QuadDrawIndexBufferID; - } - glDrawElementsInstanced(GL_TRIANGLES, pCommand->m_IndexDrawNum, GL_UNSIGNED_INT, pCommand->m_pIndicesOffset, pCommand->m_DrawNum); + glDrawElements(GL_TRIANGLES, pCommand->m_DrawNum * 6, GL_UNSIGNED_INT, pCommand->m_pIndicesOffset); } void CCommandProcessorFragment_OpenGL3_3::Cmd_RenderTileLayer(const CCommandBuffer::SCommand_RenderTileLayer *pCommand) diff --git a/src/engine/client/backend/opengl/backend_opengl3.h b/src/engine/client/backend/opengl/backend_opengl3.h index 4f839564d..5b3b88360 100644 --- a/src/engine/client/backend/opengl/backend_opengl3.h +++ b/src/engine/client/backend/opengl/backend_opengl3.h @@ -28,10 +28,6 @@ protected: CGLSLPrimitiveProgram *m_pPrimitiveProgram; CGLSLPrimitiveProgram *m_pPrimitiveProgramTextured; - CGLSLTileProgram *m_pBorderTileProgram; - CGLSLTileProgram *m_pBorderTileProgramTextured; - CGLSLTileProgram *m_pBorderTileLineProgram; - CGLSLTileProgram *m_pBorderTileLineProgramTextured; CGLSLQuadProgram *m_pQuadProgram; CGLSLQuadProgram *m_pQuadProgramTextured; CGLSLTextProgram *m_pTextProgram; @@ -110,7 +106,6 @@ protected: void Cmd_RenderTileLayer(const CCommandBuffer::SCommand_RenderTileLayer *pCommand) override; void Cmd_RenderBorderTile(const CCommandBuffer::SCommand_RenderBorderTile *pCommand) override; - void Cmd_RenderBorderTileLine(const CCommandBuffer::SCommand_RenderBorderTileLine *pCommand) override; void Cmd_RenderQuadLayer(const CCommandBuffer::SCommand_RenderQuadLayer *pCommand) override; void Cmd_RenderText(const CCommandBuffer::SCommand_RenderText *pCommand) override; void Cmd_RenderQuadContainer(const CCommandBuffer::SCommand_RenderQuadContainer *pCommand) override; diff --git a/src/engine/client/backend/opengl/opengl_sl_program.h b/src/engine/client/backend/opengl/opengl_sl_program.h index 30d35b79a..75243b6e7 100644 --- a/src/engine/client/backend/opengl/opengl_sl_program.h +++ b/src/engine/client/backend/opengl/opengl_sl_program.h @@ -155,6 +155,7 @@ public: int m_LocColor; int m_LocOffset; int m_LocDir; + int m_LocScale = -1; int m_LocNum; int m_LocJumpIndex; }; diff --git a/src/engine/client/backend/vulkan/backend_vulkan.cpp b/src/engine/client/backend/vulkan/backend_vulkan.cpp index e35b8652a..63b32af22 100644 --- a/src/engine/client/backend/vulkan/backend_vulkan.cpp +++ b/src/engine/client/backend/vulkan/backend_vulkan.cpp @@ -721,22 +721,17 @@ class CCommandProcessorFragment_Vulkan : public CCommandProcessorFragment_GLBase float m_aPos[4 * 2]; }; - struct SUniformTileGPosBorderLine : public SUniformTileGPos + struct SUniformTileGPosBorder : public SUniformTileGPos { - vec2 m_Dir; vec2 m_Offset; - }; - - struct SUniformTileGPosBorder : public SUniformTileGPosBorderLine - { - int32_t m_JumpIndex; + vec2 m_Scale; }; typedef ColorRGBA SUniformTileGVertColor; struct SUniformTileGVertColorAlign { - float m_aPad[(64 - 52) / 4]; + float m_aPad[(64 - 48) / 4]; }; struct SUniformPrimExGPosRotationless @@ -1011,7 +1006,6 @@ private: SPipelineContainer m_TextPipeline; SPipelineContainer m_TilePipeline; SPipelineContainer m_TileBorderPipeline; - SPipelineContainer m_TileBorderLinePipeline; SPipelineContainer m_PrimExPipeline; SPipelineContainer m_PrimExRotationlessPipeline; SPipelineContainer m_SpriteMultiPipeline; @@ -1274,7 +1268,6 @@ protected: m_aCommandCallbacks[CommandBufferCMDOff(CCommandBuffer::CMD_RENDER_TILE_LAYER)] = {true, [this](SRenderCommandExecuteBuffer &ExecBuffer, const CCommandBuffer::SCommand *pBaseCommand) { Cmd_RenderTileLayer_FillExecuteBuffer(ExecBuffer, static_cast(pBaseCommand)); }, [this](const CCommandBuffer::SCommand *pBaseCommand, SRenderCommandExecuteBuffer &ExecBuffer) { return Cmd_RenderTileLayer(static_cast(pBaseCommand), ExecBuffer); }}; m_aCommandCallbacks[CommandBufferCMDOff(CCommandBuffer::CMD_RENDER_BORDER_TILE)] = {true, [this](SRenderCommandExecuteBuffer &ExecBuffer, const CCommandBuffer::SCommand *pBaseCommand) { Cmd_RenderBorderTile_FillExecuteBuffer(ExecBuffer, static_cast(pBaseCommand)); }, [this](const CCommandBuffer::SCommand *pBaseCommand, SRenderCommandExecuteBuffer &ExecBuffer) { return Cmd_RenderBorderTile(static_cast(pBaseCommand), ExecBuffer); }}; - m_aCommandCallbacks[CommandBufferCMDOff(CCommandBuffer::CMD_RENDER_BORDER_TILE_LINE)] = {true, [this](SRenderCommandExecuteBuffer &ExecBuffer, const CCommandBuffer::SCommand *pBaseCommand) { Cmd_RenderBorderTileLine_FillExecuteBuffer(ExecBuffer, static_cast(pBaseCommand)); }, [this](const CCommandBuffer::SCommand *pBaseCommand, SRenderCommandExecuteBuffer &ExecBuffer) { return Cmd_RenderBorderTileLine(static_cast(pBaseCommand), ExecBuffer); }}; m_aCommandCallbacks[CommandBufferCMDOff(CCommandBuffer::CMD_RENDER_QUAD_LAYER)] = {true, [this](SRenderCommandExecuteBuffer &ExecBuffer, const CCommandBuffer::SCommand *pBaseCommand) { Cmd_RenderQuadLayer_FillExecuteBuffer(ExecBuffer, static_cast(pBaseCommand)); }, [this](const CCommandBuffer::SCommand *pBaseCommand, SRenderCommandExecuteBuffer &ExecBuffer) { return Cmd_RenderQuadLayer(static_cast(pBaseCommand), ExecBuffer); }}; m_aCommandCallbacks[CommandBufferCMDOff(CCommandBuffer::CMD_RENDER_TEXT)] = {true, [this](SRenderCommandExecuteBuffer &ExecBuffer, const CCommandBuffer::SCommand *pBaseCommand) { Cmd_RenderText_FillExecuteBuffer(ExecBuffer, static_cast(pBaseCommand)); }, [this](const CCommandBuffer::SCommand *pBaseCommand, SRenderCommandExecuteBuffer &ExecBuffer) { return Cmd_RenderText(static_cast(pBaseCommand), ExecBuffer); }}; m_aCommandCallbacks[CommandBufferCMDOff(CCommandBuffer::CMD_RENDER_QUAD_CONTAINER)] = {true, [this](SRenderCommandExecuteBuffer &ExecBuffer, const CCommandBuffer::SCommand *pBaseCommand) { Cmd_RenderQuadContainer_FillExecuteBuffer(ExecBuffer, static_cast(pBaseCommand)); }, [this](const CCommandBuffer::SCommand *pBaseCommand, SRenderCommandExecuteBuffer &ExecBuffer) { return Cmd_RenderQuadContainer(static_cast(pBaseCommand), ExecBuffer); }}; @@ -2600,8 +2593,7 @@ protected: } bool Requires2DTexture = (Flags & CCommandBuffer::TEXFLAG_NO_2D_TEXTURE) == 0; - bool Requires2DTextureArray = (Flags & (CCommandBuffer::TEXFLAG_TO_2D_ARRAY_TEXTURE | CCommandBuffer::TEXFLAG_TO_2D_ARRAY_TEXTURE_SINGLE_LAYER)) != 0; - bool Is2DTextureSingleLayer = (Flags & CCommandBuffer::TEXFLAG_TO_2D_ARRAY_TEXTURE_SINGLE_LAYER) != 0; + bool Requires2DTextureArray = (Flags & (CCommandBuffer::TEXFLAG_TO_2D_ARRAY_TEXTURE)) != 0; bool RequiresMipMaps = (Flags & CCommandBuffer::TEXFLAG_NOMIPMAPS) == 0; size_t MipMapLevelCount = 1; if(RequiresMipMaps) @@ -2645,44 +2637,32 @@ protected: int ConvertWidth = Width; int ConvertHeight = Height; - if(!Is2DTextureSingleLayer) + if(ConvertWidth == 0 || (ConvertWidth % 16) != 0 || ConvertHeight == 0 || (ConvertHeight % 16) != 0) { - if(ConvertWidth == 0 || (ConvertWidth % 16) != 0 || ConvertHeight == 0 || (ConvertHeight % 16) != 0) - { - dbg_msg("vulkan", "3D/2D array texture was resized"); - int NewWidth = maximum(HighestBit(ConvertWidth), 16); - int NewHeight = maximum(HighestBit(ConvertHeight), 16); - uint8_t *pNewTexData = (uint8_t *)Resize((const uint8_t *)pData, ConvertWidth, ConvertHeight, NewWidth, NewHeight, PixelSize); + dbg_msg("vulkan", "3D/2D array texture was resized"); + int NewWidth = maximum(HighestBit(ConvertWidth), 16); + int NewHeight = maximum(HighestBit(ConvertHeight), 16); + uint8_t *pNewTexData = (uint8_t *)Resize((const uint8_t *)pData, ConvertWidth, ConvertHeight, NewWidth, NewHeight, PixelSize); - ConvertWidth = NewWidth; - ConvertHeight = NewHeight; + ConvertWidth = NewWidth; + ConvertHeight = NewHeight; - free(pData); - pData = pNewTexData; - } + free(pData); + pData = pNewTexData; } - void *p3DTexData = pData; bool Needs3DTexDel = false; - if(!Is2DTextureSingleLayer) + void *p3DTexData = malloc((size_t)PixelSize * ConvertWidth * ConvertHeight); + if(!Texture2DTo3D(pData, ConvertWidth, ConvertHeight, PixelSize, 16, 16, p3DTexData, Image3DWidth, Image3DHeight)) { - p3DTexData = malloc((size_t)PixelSize * ConvertWidth * ConvertHeight); - if(!Texture2DTo3D(pData, ConvertWidth, ConvertHeight, PixelSize, 16, 16, p3DTexData, Image3DWidth, Image3DHeight)) - { - free(p3DTexData); - p3DTexData = nullptr; - } - Needs3DTexDel = true; - } - else - { - Image3DWidth = ConvertWidth; - Image3DHeight = ConvertHeight; + free(p3DTexData); + p3DTexData = nullptr; } + Needs3DTexDel = true; if(p3DTexData != nullptr) { - const size_t ImageDepth2DArray = Is2DTextureSingleLayer ? 1 : ((size_t)16 * 16); + const size_t ImageDepth2DArray = (size_t)16 * 16; VkExtent3D ImgSize{(uint32_t)Image3DWidth, (uint32_t)Image3DHeight, 1}; if(RequiresMipMaps) { @@ -3224,24 +3204,20 @@ protected: return GetPipeline(m_StandardPipeline, IsTextured, BlendModeIndex, DynamicIndex); } - VkPipelineLayout &GetTileLayerPipeLayout(int Type, bool IsTextured, size_t BlendModeIndex, size_t DynamicIndex) + VkPipelineLayout &GetTileLayerPipeLayout(bool IsBorder, bool IsTextured, size_t BlendModeIndex, size_t DynamicIndex) { - if(Type == 0) + if(!IsBorder) return GetPipeLayout(m_TilePipeline, IsTextured, BlendModeIndex, DynamicIndex); - else if(Type == 1) - return GetPipeLayout(m_TileBorderPipeline, IsTextured, BlendModeIndex, DynamicIndex); else - return GetPipeLayout(m_TileBorderLinePipeline, IsTextured, BlendModeIndex, DynamicIndex); + return GetPipeLayout(m_TileBorderPipeline, IsTextured, BlendModeIndex, DynamicIndex); } - VkPipeline &GetTileLayerPipe(int Type, bool IsTextured, size_t BlendModeIndex, size_t DynamicIndex) + VkPipeline &GetTileLayerPipe(bool IsBorder, bool IsTextured, size_t BlendModeIndex, size_t DynamicIndex) { - if(Type == 0) + if(!IsBorder) return GetPipeline(m_TilePipeline, IsTextured, BlendModeIndex, DynamicIndex); - else if(Type == 1) - return GetPipeline(m_TileBorderPipeline, IsTextured, BlendModeIndex, DynamicIndex); else - return GetPipeline(m_TileBorderLinePipeline, IsTextured, BlendModeIndex, DynamicIndex); + return GetPipeline(m_TileBorderPipeline, IsTextured, BlendModeIndex, DynamicIndex); } void GetStateIndices(const SRenderCommandExecuteBuffer &ExecBuffer, const CCommandBuffer::SState &State, bool &IsTextured, size_t &BlendModeIndex, size_t &DynamicIndex, size_t &AddressModeIndex) @@ -3372,7 +3348,7 @@ protected: ExecBufferFillDynamicStates(State, ExecBuffer); } - [[nodiscard]] bool RenderTileLayer(SRenderCommandExecuteBuffer &ExecBuffer, const CCommandBuffer::SState &State, int Type, const GL_SColorf &Color, const vec2 &Dir, const vec2 &Off, int32_t JumpIndex, size_t IndicesDrawNum, char *const *pIndicesOffsets, const unsigned int *pDrawCount, size_t InstanceCount) + [[nodiscard]] bool RenderTileLayer(SRenderCommandExecuteBuffer &ExecBuffer, const CCommandBuffer::SState &State, bool IsBorder, const GL_SColorf &Color, const vec2 &Scale, const vec2 &Off, size_t IndicesDrawNum, char *const *pIndicesOffsets, const unsigned int *pDrawCount) { std::array m; GetStateMatrix(State, m); @@ -3382,8 +3358,8 @@ protected: size_t DynamicIndex; size_t AddressModeIndex; GetStateIndices(ExecBuffer, State, IsTextured, BlendModeIndex, DynamicIndex, AddressModeIndex); - auto &PipeLayout = GetTileLayerPipeLayout(Type, IsTextured, BlendModeIndex, DynamicIndex); - auto &PipeLine = GetTileLayerPipe(Type, IsTextured, BlendModeIndex, DynamicIndex); + auto &PipeLayout = GetTileLayerPipeLayout(IsBorder, IsTextured, BlendModeIndex, DynamicIndex); + auto &PipeLine = GetTileLayerPipe(IsBorder, IsTextured, BlendModeIndex, DynamicIndex); VkCommandBuffer *pCommandBuffer; if(!GetGraphicCommandBuffer(pCommandBuffer, ExecBuffer.m_ThreadIndex)) @@ -3409,19 +3385,12 @@ protected: mem_copy(VertexPushConstants.m_aPos, m.data(), m.size() * sizeof(float)); FragPushConstants = Color; - if(Type == 1) + if(IsBorder) { - VertexPushConstants.m_Dir = Dir; + VertexPushConstants.m_Scale = Scale; VertexPushConstants.m_Offset = Off; - VertexPushConstants.m_JumpIndex = JumpIndex; VertexPushConstantSize = sizeof(SUniformTileGPosBorder); } - else if(Type == 2) - { - VertexPushConstants.m_Dir = Dir; - VertexPushConstants.m_Offset = Off; - VertexPushConstantSize = sizeof(SUniformTileGPosBorderLine); - } vkCmdPushConstants(CommandBuffer, PipeLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, VertexPushConstantSize, &VertexPushConstants); vkCmdPushConstants(CommandBuffer, PipeLayout, VK_SHADER_STAGE_FRAGMENT_BIT, sizeof(SUniformTileGPosBorder) + sizeof(SUniformTileGVertColorAlign), FragPushConstantSize, &FragPushConstants); @@ -3432,7 +3401,7 @@ protected: { VkDeviceSize IndexOffset = (VkDeviceSize)((ptrdiff_t)pIndicesOffsets[i] / sizeof(uint32_t)); - vkCmdDrawIndexed(CommandBuffer, static_cast(pDrawCount[i]), InstanceCount, IndexOffset, 0, 0); + vkCmdDrawIndexed(CommandBuffer, static_cast(pDrawCount[i]), 1, IndexOffset, 0, 0); } return true; @@ -4911,21 +4880,19 @@ public: } template - [[nodiscard]] bool CreateTileGraphicsPipelineImpl(const char *pVertName, const char *pFragName, int Type, SPipelineContainer &PipeContainer, EVulkanBackendTextureModes TexMode, EVulkanBackendBlendModes BlendMode, EVulkanBackendClipModes DynamicMode) + [[nodiscard]] bool CreateTileGraphicsPipelineImpl(const char *pVertName, const char *pFragName, bool IsBorder, SPipelineContainer &PipeContainer, EVulkanBackendTextureModes TexMode, EVulkanBackendBlendModes BlendMode, EVulkanBackendClipModes DynamicMode) { std::array aAttributeDescriptions = {}; aAttributeDescriptions[0] = {0, 0, VK_FORMAT_R32G32_SFLOAT, 0}; if(HasSampler) - aAttributeDescriptions[1] = {1, 0, VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 2}; + aAttributeDescriptions[1] = {1, 0, VK_FORMAT_R8G8B8A8_UINT, sizeof(float) * 2}; std::array aSetLayouts; aSetLayouts[0] = m_Standard3DTexturedDescriptorSetLayout; uint32_t VertPushConstantSize = sizeof(SUniformTileGPos); - if(Type == 1) + if(IsBorder) VertPushConstantSize = sizeof(SUniformTileGPosBorder); - else if(Type == 2) - VertPushConstantSize = sizeof(SUniformTileGPosBorderLine); uint32_t FragPushConstantSize = sizeof(SUniformTileGVertColor); @@ -4933,11 +4900,11 @@ public: aPushConstants[0] = {VK_SHADER_STAGE_VERTEX_BIT, 0, VertPushConstantSize}; aPushConstants[1] = {VK_SHADER_STAGE_FRAGMENT_BIT, sizeof(SUniformTileGPosBorder) + sizeof(SUniformTileGVertColorAlign), FragPushConstantSize}; - return CreateGraphicsPipeline(pVertName, pFragName, PipeContainer, HasSampler ? (sizeof(float) * (2 + 3)) : (sizeof(float) * 2), aAttributeDescriptions, aSetLayouts, aPushConstants, TexMode, BlendMode, DynamicMode); + return CreateGraphicsPipeline(pVertName, pFragName, PipeContainer, HasSampler ? (sizeof(float) * 2 + sizeof(uint8_t) * 4) : (sizeof(float) * 2), aAttributeDescriptions, aSetLayouts, aPushConstants, TexMode, BlendMode, DynamicMode); } template - [[nodiscard]] bool CreateTileGraphicsPipeline(const char *pVertName, const char *pFragName, int Type) + [[nodiscard]] bool CreateTileGraphicsPipeline(const char *pVertName, const char *pFragName, bool IsBorder) { bool Ret = true; @@ -4947,7 +4914,7 @@ public: { for(size_t j = 0; j < VULKAN_BACKEND_CLIP_MODE_COUNT; ++j) { - Ret &= CreateTileGraphicsPipelineImpl(pVertName, pFragName, Type, Type == 0 ? m_TilePipeline : (Type == 1 ? m_TileBorderPipeline : m_TileBorderLinePipeline), TexMode, EVulkanBackendBlendModes(i), EVulkanBackendClipModes(j)); + Ret &= CreateTileGraphicsPipelineImpl(pVertName, pFragName, IsBorder, !IsBorder ? m_TilePipeline : m_TileBorderPipeline, TexMode, EVulkanBackendBlendModes(i), EVulkanBackendClipModes(j)); } } @@ -5429,7 +5396,6 @@ public: m_TextPipeline.Destroy(m_VKDevice); m_TilePipeline.Destroy(m_VKDevice); m_TileBorderPipeline.Destroy(m_VKDevice); - m_TileBorderLinePipeline.Destroy(m_VKDevice); m_PrimExPipeline.Destroy(m_VKDevice); m_PrimExRotationlessPipeline.Destroy(m_VKDevice); m_SpriteMultiPipeline.Destroy(m_VKDevice); @@ -6086,22 +6052,16 @@ public: if(!CreateTextGraphicsPipeline("shader/vulkan/text.vert.spv", "shader/vulkan/text.frag.spv")) return -1; - if(!CreateTileGraphicsPipeline("shader/vulkan/tile.vert.spv", "shader/vulkan/tile.frag.spv", 0)) + if(!CreateTileGraphicsPipeline("shader/vulkan/tile.vert.spv", "shader/vulkan/tile.frag.spv", false)) return -1; - if(!CreateTileGraphicsPipeline("shader/vulkan/tile_textured.vert.spv", "shader/vulkan/tile_textured.frag.spv", 0)) + if(!CreateTileGraphicsPipeline("shader/vulkan/tile_textured.vert.spv", "shader/vulkan/tile_textured.frag.spv", false)) return -1; - if(!CreateTileGraphicsPipeline("shader/vulkan/tile_border.vert.spv", "shader/vulkan/tile_border.frag.spv", 1)) + if(!CreateTileGraphicsPipeline("shader/vulkan/tile_border.vert.spv", "shader/vulkan/tile_border.frag.spv", true)) return -1; - if(!CreateTileGraphicsPipeline("shader/vulkan/tile_border_textured.vert.spv", "shader/vulkan/tile_border_textured.frag.spv", 1)) - return -1; - - if(!CreateTileGraphicsPipeline("shader/vulkan/tile_border_line.vert.spv", "shader/vulkan/tile_border_line.frag.spv", 2)) - return -1; - - if(!CreateTileGraphicsPipeline("shader/vulkan/tile_border_line_textured.vert.spv", "shader/vulkan/tile_border_line_textured.frag.spv", 2)) + if(!CreateTileGraphicsPipeline("shader/vulkan/tile_border_textured.vert.spv", "shader/vulkan/tile_border_textured.frag.spv", true)) return -1; if(!CreatePrimExGraphicsPipeline("shader/vulkan/primex_rotationless.vert.spv", "shader/vulkan/primex_rotationless.frag.spv", false, true)) @@ -7076,11 +7036,9 @@ public: [[nodiscard]] bool Cmd_RenderTileLayer(const CCommandBuffer::SCommand_RenderTileLayer *pCommand, SRenderCommandExecuteBuffer &ExecBuffer) { - int Type = 0; - vec2 Dir{}; + vec2 Scale{}; vec2 Off{}; - int32_t JumpIndex = 0; - return RenderTileLayer(ExecBuffer, pCommand->m_State, Type, pCommand->m_Color, Dir, Off, JumpIndex, (size_t)pCommand->m_IndicesDrawNum, pCommand->m_pIndicesOffsets, pCommand->m_pDrawCount, 1); + return RenderTileLayer(ExecBuffer, pCommand->m_State, false, pCommand->m_Color, Scale, Off, (size_t)pCommand->m_IndicesDrawNum, pCommand->m_pIndicesOffsets, pCommand->m_pDrawCount); } void Cmd_RenderBorderTile_FillExecuteBuffer(SRenderCommandExecuteBuffer &ExecBuffer, const CCommandBuffer::SCommand_RenderBorderTile *pCommand) @@ -7090,24 +7048,10 @@ public: [[nodiscard]] bool Cmd_RenderBorderTile(const CCommandBuffer::SCommand_RenderBorderTile *pCommand, SRenderCommandExecuteBuffer &ExecBuffer) { - int Type = 1; - vec2 Dir = pCommand->m_Dir; + vec2 Scale = pCommand->m_Scale; vec2 Off = pCommand->m_Offset; - unsigned int DrawNum = 6; - return RenderTileLayer(ExecBuffer, pCommand->m_State, Type, pCommand->m_Color, Dir, Off, pCommand->m_JumpIndex, (size_t)1, &pCommand->m_pIndicesOffset, &DrawNum, pCommand->m_DrawNum); - } - - void Cmd_RenderBorderTileLine_FillExecuteBuffer(SRenderCommandExecuteBuffer &ExecBuffer, const CCommandBuffer::SCommand_RenderBorderTileLine *pCommand) - { - RenderTileLayer_FillExecuteBuffer(ExecBuffer, 1, pCommand->m_State, pCommand->m_BufferContainerIndex); - } - - [[nodiscard]] bool Cmd_RenderBorderTileLine(const CCommandBuffer::SCommand_RenderBorderTileLine *pCommand, SRenderCommandExecuteBuffer &ExecBuffer) - { - int Type = 2; - vec2 Dir = pCommand->m_Dir; - vec2 Off = pCommand->m_Offset; - return RenderTileLayer(ExecBuffer, pCommand->m_State, Type, pCommand->m_Color, Dir, Off, 0, (size_t)1, &pCommand->m_pIndicesOffset, &pCommand->m_IndexDrawNum, pCommand->m_DrawNum); + unsigned int DrawNum = pCommand->m_DrawNum * 6; + return RenderTileLayer(ExecBuffer, pCommand->m_State, true, pCommand->m_Color, Scale, Off, 1, &pCommand->m_pIndicesOffset, &DrawNum); } void Cmd_RenderQuadLayer_FillExecuteBuffer(SRenderCommandExecuteBuffer &ExecBuffer, const CCommandBuffer::SCommand_RenderQuadLayer *pCommand) diff --git a/src/engine/client/backend_sdl.h b/src/engine/client/backend_sdl.h index c2c4e07f9..03d48fd50 100644 --- a/src/engine/client/backend_sdl.h +++ b/src/engine/client/backend_sdl.h @@ -281,7 +281,8 @@ public: bool HasQuadBuffering() override { return m_Capabilites.m_QuadBuffering; } bool HasTextBuffering() override { return m_Capabilites.m_TextBuffering; } bool HasQuadContainerBuffering() override { return m_Capabilites.m_QuadContainerBuffering; } - bool Has2DTextureArrays() override { return m_Capabilites.m_2DArrayTextures; } + bool Uses2DTextureArrays() override { return m_Capabilites.m_2DArrayTextures; } + bool HasTextureArraysSupport() override { return m_Capabilites.m_2DArrayTextures || m_Capabilites.m_3DTextures; } const char *GetErrorString() override { diff --git a/src/engine/client/graphics_threaded.cpp b/src/engine/client/graphics_threaded.cpp index a578c3fb2..f3576253f 100644 --- a/src/engine/client/graphics_threaded.cpp +++ b/src/engine/client/graphics_threaded.cpp @@ -454,10 +454,6 @@ IGraphics::CTextureHandle CGraphics_Threaded::LoadTextureRaw(size_t Width, size_ 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; if((Flags & IGraphics::TEXLOAD_NO_2D_TEXTURE) != 0) Cmd.m_Flags |= CCommandBuffer::TEXFLAG_NO_2D_TEXTURE; @@ -1094,7 +1090,7 @@ void CGraphics_Threaded::QuadsTex3DDrawTL(const CQuadItem *pArray, int Num) { for(int n = 0; n < VertNum; ++n) { - if(HasTextureArrays()) + if(Uses2DTextureArrays()) m_aVerticesTex3D[CurNumVert + VertNum * i + n].m_Tex.w = (float)m_CurIndex; else m_aVerticesTex3D[CurNumVert + VertNum * i + n].m_Tex.w = ((float)m_CurIndex + 0.5f) / 256.f; @@ -1564,7 +1560,7 @@ void CGraphics_Threaded::RenderTileLayer(int BufferContainerIndex, const ColorRG // todo max indices group check!! } -void CGraphics_Threaded::RenderBorderTiles(int BufferContainerIndex, const ColorRGBA &Color, char *pIndexBufferOffset, const vec2 &Offset, const vec2 &Dir, int JumpIndex, unsigned int DrawNum) +void CGraphics_Threaded::RenderBorderTiles(int BufferContainerIndex, const ColorRGBA &Color, char *pIndexBufferOffset, const vec2 &Offset, const vec2 &Scale, uint32_t DrawNum) { if(DrawNum == 0) return; @@ -1576,32 +1572,9 @@ void CGraphics_Threaded::RenderBorderTiles(int BufferContainerIndex, const Color Cmd.m_Color = Color; Cmd.m_pIndicesOffset = pIndexBufferOffset; - Cmd.m_JumpIndex = JumpIndex; Cmd.m_Offset = Offset; - Cmd.m_Dir = Dir; - - AddCmd(Cmd); - - m_pCommandBuffer->AddRenderCalls(1); -} - -void CGraphics_Threaded::RenderBorderTileLines(int BufferContainerIndex, const ColorRGBA &Color, char *pIndexBufferOffset, const vec2 &Offset, const vec2 &Dir, unsigned int IndexDrawNum, unsigned int RedrawNum) -{ - if(IndexDrawNum == 0 || RedrawNum == 0) - return; - // Draw a border tile a lot of times - CCommandBuffer::SCommand_RenderBorderTileLine Cmd; - Cmd.m_State = m_State; - Cmd.m_IndexDrawNum = IndexDrawNum; - Cmd.m_DrawNum = RedrawNum; - Cmd.m_BufferContainerIndex = BufferContainerIndex; - Cmd.m_Color = Color; - - Cmd.m_pIndicesOffset = pIndexBufferOffset; - - Cmd.m_Offset = Offset; - Cmd.m_Dir = Dir; + Cmd.m_Scale = Scale; AddCmd(Cmd); @@ -2396,7 +2369,8 @@ int CGraphics_Threaded::IssueInit() m_GLQuadBufferingEnabled = m_pBackend->HasQuadBuffering(); m_GLQuadContainerBufferingEnabled = m_pBackend->HasQuadContainerBuffering(); m_GLTextBufferingEnabled = (m_GLQuadContainerBufferingEnabled && m_pBackend->HasTextBuffering()); - m_GLHasTextureArrays = m_pBackend->Has2DTextureArrays(); + m_GLUses2DTextureArrays = m_pBackend->Uses2DTextureArrays(); + m_GLHasTextureArraysSupport = m_pBackend->HasTextureArraysSupport(); m_ScreenHiDPIScale = m_ScreenWidth / (float)g_Config.m_GfxScreenWidth; m_ScreenRefreshRate = g_Config.m_GfxScreenRefreshRate; } @@ -2630,7 +2604,7 @@ int CGraphics_Threaded::Init() mem_copy(&aNullTextureData[(y * NullTextureDimension + x) * PixelSize], pColor, PixelSize); } } - const int TextureLoadFlags = HasTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE; + const int TextureLoadFlags = Uses2DTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE; m_NullTexture.Invalidate(); m_NullTexture = LoadTextureRaw(NullTextureDimension, NullTextureDimension, CImageInfo::FORMAT_RGBA, aNullTextureData, TextureLoadFlags); dbg_assert(m_NullTexture.IsNullTexture(), "Null texture invalid"); diff --git a/src/engine/client/graphics_threaded.h b/src/engine/client/graphics_threaded.h index f7ff189fb..03ca8dba9 100644 --- a/src/engine/client/graphics_threaded.h +++ b/src/engine/client/graphics_threaded.h @@ -117,7 +117,6 @@ public: CMD_RENDER_TILE_LAYER, // render a tilelayer CMD_RENDER_BORDER_TILE, // render one tile multiple times - CMD_RENDER_BORDER_TILE_LINE, // render an amount of tiles multiple times CMD_RENDER_QUAD_LAYER, // render a quad layer CMD_RENDER_TEXT, // render text CMD_RENDER_QUAD_CONTAINER, // render a quad buffer container @@ -148,9 +147,7 @@ public: TEXFLAG_NOMIPMAPS = 1, 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), - TEXFLAG_NO_2D_TEXTURE = (1 << 7), + TEXFLAG_NO_2D_TEXTURE = (1 << 5), }; enum @@ -380,28 +377,12 @@ public: SCommand(CMD_RENDER_BORDER_TILE) {} SState m_State; SColorf m_Color; // the color of the whole tilelayer -- already enveloped - char *m_pIndicesOffset; // you should use the command buffer data to allocate vertices for this command - unsigned int m_DrawNum; + char *m_pIndicesOffset; + uint32_t m_DrawNum; int m_BufferContainerIndex; vec2 m_Offset; - vec2 m_Dir; - int m_JumpIndex; - }; - - struct SCommand_RenderBorderTileLine : public SCommand - { - SCommand_RenderBorderTileLine() : - SCommand(CMD_RENDER_BORDER_TILE_LINE) {} - SState m_State; - SColorf m_Color; // the color of the whole tilelayer -- already enveloped - char *m_pIndicesOffset; // you should use the command buffer data to allocate vertices for this command - unsigned int m_IndexDrawNum; - unsigned int m_DrawNum; - int m_BufferContainerIndex; - - vec2 m_Offset; - vec2 m_Dir; + vec2 m_Scale; }; struct SCommand_RenderQuadLayer : public SCommand @@ -755,7 +736,8 @@ public: virtual bool HasQuadBuffering() { return false; } virtual bool HasTextBuffering() { return false; } virtual bool HasQuadContainerBuffering() { return false; } - virtual bool Has2DTextureArrays() { return false; } + virtual bool Uses2DTextureArrays() { return false; } + virtual bool HasTextureArraysSupport() { return false; } virtual const char *GetErrorString() { return NULL; } virtual const char *GetVendorString() = 0; @@ -788,7 +770,8 @@ class CGraphics_Threaded : public IEngineGraphics bool m_GLQuadBufferingEnabled; bool m_GLTextBufferingEnabled; bool m_GLQuadContainerBufferingEnabled; - bool m_GLHasTextureArrays; + bool m_GLUses2DTextureArrays; + bool m_GLHasTextureArraysSupport; bool m_GLUseTrianglesAsQuad; CCommandBuffer *m_apCommandBuffers[NUM_CMDBUFFERS]; @@ -1214,8 +1197,7 @@ public: void FlushVerticesTex3D() override; void RenderTileLayer(int BufferContainerIndex, const ColorRGBA &Color, char **pOffsets, unsigned int *pIndicedVertexDrawNum, size_t NumIndicesOffset) override; - void RenderBorderTiles(int BufferContainerIndex, const ColorRGBA &Color, char *pIndexBufferOffset, const vec2 &Offset, const vec2 &Dir, int JumpIndex, unsigned int DrawNum) override; - void RenderBorderTileLines(int BufferContainerIndex, const ColorRGBA &Color, char *pIndexBufferOffset, const vec2 &Offset, const vec2 &Dir, unsigned int IndexDrawNum, unsigned int RedrawNum) override; + virtual void RenderBorderTiles(int BufferContainerIndex, const ColorRGBA &Color, char *pIndexBufferOffset, const vec2 &Offset, const vec2 &Scale, uint32_t DrawNum) override; void RenderQuadLayer(int BufferContainerIndex, SQuadRenderInfo *pQuadInfo, size_t QuadNum, int QuadOffset) override; void RenderText(int BufferContainerIndex, int TextQuadNum, int TextureSize, int TextureTextIndex, int TextureTextOutlineIndex, const ColorRGBA &TextColor, const ColorRGBA &TextOutlineColor) override; @@ -1286,7 +1268,8 @@ public: bool IsQuadBufferingEnabled() override { return m_GLQuadBufferingEnabled; } bool IsTextBufferingEnabled() override { return m_GLTextBufferingEnabled; } bool IsQuadContainerBufferingEnabled() override { return m_GLQuadContainerBufferingEnabled; } - bool HasTextureArrays() override { return m_GLHasTextureArrays; } + bool Uses2DTextureArrays() override { return m_GLUses2DTextureArrays; } + bool HasTextureArraysSupport() override { return m_GLHasTextureArraysSupport; } const char *GetVendorString() override; const char *GetVersionString() override; diff --git a/src/engine/graphics.h b/src/engine/graphics.h index 24b2b3dfd..dac4a3107 100644 --- a/src/engine/graphics.h +++ b/src/engine/graphics.h @@ -57,10 +57,10 @@ struct SGraphicTile struct SGraphicTileTexureCoords { - vec3 m_TexCoordTopLeft; - vec3 m_TexCoordTopRight; - vec3 m_TexCoordBottomRight; - vec3 m_TexCoordBottomLeft; + ubvec4 m_TexCoordTopLeft; + ubvec4 m_TexCoordTopRight; + ubvec4 m_TexCoordBottomRight; + ubvec4 m_TexCoordBottomLeft; }; class CImageInfo @@ -246,9 +246,7 @@ public: 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), - TEXLOAD_NO_2D_TEXTURE = (1 << 7), + TEXLOAD_NO_2D_TEXTURE = (1 << 5), }; class CTextureHandle @@ -357,8 +355,7 @@ public: // specific render functions virtual void RenderTileLayer(int BufferContainerIndex, const ColorRGBA &Color, char **pOffsets, unsigned int *pIndicedVertexDrawNum, size_t NumIndicesOffset) = 0; - virtual void RenderBorderTiles(int BufferContainerIndex, const ColorRGBA &Color, char *pIndexBufferOffset, const vec2 &Offset, const vec2 &Dir, int JumpIndex, unsigned int DrawNum) = 0; - virtual void RenderBorderTileLines(int BufferContainerIndex, const ColorRGBA &Color, char *pIndexBufferOffset, const vec2 &Offset, const vec2 &Dir, unsigned int IndexDrawNum, unsigned int RedrawNum) = 0; + virtual void RenderBorderTiles(int BufferContainerIndex, const ColorRGBA &Color, char *pIndexBufferOffset, const vec2 &Offset, const vec2 &Scale, uint32_t DrawNum) = 0; virtual void RenderQuadLayer(int BufferContainerIndex, SQuadRenderInfo *pQuadInfo, size_t QuadNum, int QuadOffset) = 0; virtual void RenderText(int BufferContainerIndex, int TextQuadNum, int TextureSize, int TextureTextIndex, int TextureTextOutlineIndex, const ColorRGBA &TextColor, const ColorRGBA &TextOutlineColor) = 0; @@ -387,7 +384,8 @@ public: virtual bool IsQuadBufferingEnabled() = 0; virtual bool IsTextBufferingEnabled() = 0; virtual bool IsQuadContainerBufferingEnabled() = 0; - virtual bool HasTextureArrays() = 0; + virtual bool Uses2DTextureArrays() = 0; + virtual bool HasTextureArraysSupport() = 0; virtual const char *GetVendorString() = 0; virtual const char *GetVersionString() = 0; diff --git a/src/game/client/components/mapimages.cpp b/src/game/client/components/mapimages.cpp index 434bbfe0f..089303bf5 100644 --- a/src/game/client/components/mapimages.cpp +++ b/src/game/client/components/mapimages.cpp @@ -101,13 +101,13 @@ void CMapImages::OnMapLoadImpl(class CLayers *pLayers, IMap *pMap) } } - const int TextureLoadFlag = Graphics()->HasTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE; + const int TextureLoadFlag = Graphics()->Uses2DTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE; // load new textures bool ShowWarning = false; for(int i = 0; i < m_Count; i++) { - const int LoadFlag = (((m_aTextureUsedByTileOrQuadLayerFlag[i] & 1) != 0) ? TextureLoadFlag : 0) | (((m_aTextureUsedByTileOrQuadLayerFlag[i] & 2) != 0) ? 0 : (Graphics()->IsTileBufferingEnabled() ? IGraphics::TEXLOAD_NO_2D_TEXTURE : 0)); + const int LoadFlag = (((m_aTextureUsedByTileOrQuadLayerFlag[i] & 1) != 0) ? TextureLoadFlag : 0) | (((m_aTextureUsedByTileOrQuadLayerFlag[i] & 2) != 0) ? 0 : (Graphics()->HasTextureArraysSupport() ? IGraphics::TEXLOAD_NO_2D_TEXTURE : 0)); const CMapItemImage_v2 *pImg = (CMapItemImage_v2 *)pMap->GetItem(Start + i); const CImageInfo::EImageFormat Format = pImg->m_Version < CMapItemImage_v2::CURRENT_VERSION ? CImageInfo::FORMAT_RGBA : CImageInfo::ImageFormatFromInt(pImg->m_Format); @@ -220,8 +220,8 @@ IGraphics::CTextureHandle CMapImages::GetEntities(EMapImageEntityLayerType Entit bool GameTypeHasTuneLayer = HasTuneLayer(EntitiesModType) || WasUnknown; int TextureLoadFlag = 0; - if(Graphics()->IsTileBufferingEnabled()) - TextureLoadFlag = (Graphics()->HasTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE) | IGraphics::TEXLOAD_NO_2D_TEXTURE; + if(Graphics()->HasTextureArraysSupport()) + TextureLoadFlag = (Graphics()->Uses2DTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE) | IGraphics::TEXLOAD_NO_2D_TEXTURE; CImageInfo ImgInfo; bool ImagePNGLoaded = false; @@ -356,8 +356,8 @@ 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) | IGraphics::TEXLOAD_NO_2D_TEXTURE; - m_SpeedupArrowTexture = Graphics()->LoadTexture(g_pData->m_aImages[IMAGE_SPEEDUP_ARROW].m_pFilename, IStorage::TYPE_ALL, TextureLoadFlag); + int TextureLoadFlag = (Graphics()->Uses2DTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE) | IGraphics::TEXLOAD_NO_2D_TEXTURE; + m_SpeedupArrowTexture = Graphics()->LoadTexture("editor/speed_arrow_array.png", IStorage::TYPE_ALL, TextureLoadFlag); m_SpeedupArrowIsLoaded = true; } @@ -444,7 +444,7 @@ IGraphics::CTextureHandle CMapImages::UploadEntityLayerText(int TextureSize, int UpdateEntityLayerText(pMem, PixelSize, Width, Height, TextureSize, MaxWidth, YOffset, 1); UpdateEntityLayerText(pMem, PixelSize, Width, Height, TextureSize, MaxWidth, YOffset, 2, 255); - const int TextureLoadFlag = (Graphics()->HasTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE) | IGraphics::TEXLOAD_NO_2D_TEXTURE; + const int TextureLoadFlag = (Graphics()->Uses2DTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE) | IGraphics::TEXLOAD_NO_2D_TEXTURE; IGraphics::CTextureHandle Texture = Graphics()->LoadTextureRaw(Width, Height, CImageInfo::FORMAT_RGBA, pMem, TextureLoadFlag); free(pMem); diff --git a/src/game/client/components/maplayers.cpp b/src/game/client/components/maplayers.cpp index b292e3ec0..191e613a9 100644 --- a/src/game/client/components/maplayers.cpp +++ b/src/game/client/components/maplayers.cpp @@ -143,77 +143,7 @@ void CMapLayers::EnvelopeEval(int TimeOffsetMillis, int Env, ColorRGBA &Channels } } -void FillTmpTileSpeedup(SGraphicTile *pTmpTile, SGraphicTileTexureCoords *pTmpTex, bool As3DTextureCoord, unsigned char Flags, unsigned char Index, int x, int y, int Scale, CMapItemGroup *pGroup, short AngleRotate) -{ - if(pTmpTex) - { - 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; - - pTmpTex->m_TexCoordTopLeft.x = x0; - pTmpTex->m_TexCoordTopLeft.y = y0; - pTmpTex->m_TexCoordBottomLeft.x = x3; - pTmpTex->m_TexCoordBottomLeft.y = y3; - pTmpTex->m_TexCoordTopRight.x = x1; - pTmpTex->m_TexCoordTopRight.y = y1; - pTmpTex->m_TexCoordBottomRight.x = x2; - pTmpTex->m_TexCoordBottomRight.y = y2; - - if(As3DTextureCoord) - { - pTmpTex->m_TexCoordTopLeft.z = ((float)Index + 0.5f) / 256.f; - pTmpTex->m_TexCoordBottomLeft.z = ((float)Index + 0.5f) / 256.f; - pTmpTex->m_TexCoordTopRight.z = ((float)Index + 0.5f) / 256.f; - pTmpTex->m_TexCoordBottomRight.z = ((float)Index + 0.5f) / 256.f; - } - else - { - pTmpTex->m_TexCoordTopLeft.z = Index; - pTmpTex->m_TexCoordBottomLeft.z = Index; - pTmpTex->m_TexCoordTopRight.z = Index; - pTmpTex->m_TexCoordBottomRight.z = Index; - } - } - - //same as in rotate from Graphics() - float Angle = (float)AngleRotate * (pi / 180.0f); - float c = std::cos(Angle); - float s = std::sin(Angle); - float xR, yR; - int i; - - int ScaleSmaller = 2; - pTmpTile->m_TopLeft.x = x * Scale + ScaleSmaller; - pTmpTile->m_TopLeft.y = y * Scale + ScaleSmaller; - pTmpTile->m_BottomLeft.x = x * Scale + ScaleSmaller; - pTmpTile->m_BottomLeft.y = y * Scale + Scale - ScaleSmaller; - pTmpTile->m_TopRight.x = x * Scale + Scale - ScaleSmaller; - pTmpTile->m_TopRight.y = y * Scale + ScaleSmaller; - pTmpTile->m_BottomRight.x = x * Scale + Scale - ScaleSmaller; - pTmpTile->m_BottomRight.y = y * Scale + Scale - ScaleSmaller; - - float *pTmpTileVertices = (float *)pTmpTile; - - vec2 Center; - Center.x = pTmpTile->m_TopLeft.x + (Scale - ScaleSmaller) / 2.f; - Center.y = pTmpTile->m_TopLeft.y + (Scale - ScaleSmaller) / 2.f; - - for(i = 0; i < 4; i++) - { - xR = pTmpTileVertices[i * 2] - Center.x; - yR = pTmpTileVertices[i * 2 + 1] - Center.y; - pTmpTileVertices[i * 2] = xR * c - yR * s + Center.x; - pTmpTileVertices[i * 2 + 1] = xR * s + yR * c + Center.y; - } -} - -void FillTmpTile(SGraphicTile *pTmpTile, SGraphicTileTexureCoords *pTmpTex, bool As3DTextureCoord, unsigned char Flags, unsigned char Index, int x, int y, int Scale, CMapItemGroup *pGroup) +void FillTmpTile(SGraphicTile *pTmpTile, SGraphicTileTexureCoords *pTmpTex, unsigned char Flags, unsigned char Index, int x, int y, const ivec2 &Offset, int Scale, CMapItemGroup *pGroup) { if(pTmpTex) { @@ -265,30 +195,32 @@ void FillTmpTile(SGraphicTile *pTmpTile, SGraphicTileTexureCoords *pTmpTex, bool pTmpTex->m_TexCoordBottomRight.x = x2; pTmpTex->m_TexCoordBottomRight.y = y2; - if(As3DTextureCoord) - { - pTmpTex->m_TexCoordTopLeft.z = ((float)Index + 0.5f) / 256.f; - pTmpTex->m_TexCoordBottomLeft.z = ((float)Index + 0.5f) / 256.f; - pTmpTex->m_TexCoordTopRight.z = ((float)Index + 0.5f) / 256.f; - pTmpTex->m_TexCoordBottomRight.z = ((float)Index + 0.5f) / 256.f; - } - else - { - pTmpTex->m_TexCoordTopLeft.z = Index; - pTmpTex->m_TexCoordBottomLeft.z = Index; - pTmpTex->m_TexCoordTopRight.z = Index; - pTmpTex->m_TexCoordBottomRight.z = Index; - } + pTmpTex->m_TexCoordTopLeft.z = Index; + pTmpTex->m_TexCoordBottomLeft.z = Index; + pTmpTex->m_TexCoordTopRight.z = Index; + pTmpTex->m_TexCoordBottomRight.z = Index; + + bool HasRotation = (Flags & TILEFLAG_ROTATE) != 0; + pTmpTex->m_TexCoordTopLeft.w = HasRotation; + pTmpTex->m_TexCoordBottomLeft.w = HasRotation; + pTmpTex->m_TexCoordTopRight.w = HasRotation; + pTmpTex->m_TexCoordBottomRight.w = HasRotation; } - pTmpTile->m_TopLeft.x = x * Scale; - pTmpTile->m_TopLeft.y = y * Scale; - pTmpTile->m_BottomLeft.x = x * Scale; - pTmpTile->m_BottomLeft.y = y * Scale + Scale; - pTmpTile->m_TopRight.x = x * Scale + Scale; - pTmpTile->m_TopRight.y = y * Scale; - pTmpTile->m_BottomRight.x = x * Scale + Scale; - pTmpTile->m_BottomRight.y = y * Scale + Scale; + pTmpTile->m_TopLeft.x = x * Scale + Offset.x; + pTmpTile->m_TopLeft.y = y * Scale + Offset.y; + pTmpTile->m_BottomLeft.x = x * Scale + Offset.x; + pTmpTile->m_BottomLeft.y = y * Scale + Scale + Offset.y; + pTmpTile->m_TopRight.x = x * Scale + Scale + Offset.x; + pTmpTile->m_TopRight.y = y * Scale + Offset.y; + pTmpTile->m_BottomRight.x = x * Scale + Scale + Offset.x; + pTmpTile->m_BottomRight.y = y * Scale + Scale + Offset.y; +} + +void FillTmpTileSpeedup(SGraphicTile *pTmpTile, SGraphicTileTexureCoords *pTmpTex, unsigned char Flags, unsigned char Index, int x, int y, const ivec2 &Offset, int Scale, CMapItemGroup *pGroup, short AngleRotate) +{ + int Angle = AngleRotate % 360; + FillTmpTile(pTmpTile, pTmpTex, Angle >= 270 ? ROTATION_270 : (Angle >= 180 ? ROTATION_180 : (Angle >= 90 ? ROTATION_90 : 0)), AngleRotate % 90, x, y, Offset, Scale, pGroup); } bool CMapLayers::STileLayerVisuals::Init(unsigned int Width, unsigned int Height) @@ -303,35 +235,22 @@ bool CMapLayers::STileLayerVisuals::Init(unsigned int Width, unsigned int Height m_pTilesOfLayer = new CMapLayers::STileLayerVisuals::STileVisual[Height * Width]; - if(Width > 2) - { - m_pBorderTop = new CMapLayers::STileLayerVisuals::STileVisual[Width - 2]; - m_pBorderBottom = new CMapLayers::STileLayerVisuals::STileVisual[Width - 2]; - } - if(Height > 2) - { - m_pBorderLeft = new CMapLayers::STileLayerVisuals::STileVisual[Height - 2]; - m_pBorderRight = new CMapLayers::STileLayerVisuals::STileVisual[Height - 2]; - } + m_vBorderTop.resize(Width); + m_vBorderBottom.resize(Width); + + m_vBorderLeft.resize(Height); + m_vBorderRight.resize(Height); return true; } CMapLayers::STileLayerVisuals::~STileLayerVisuals() { delete[] m_pTilesOfLayer; - delete[] m_pBorderTop; - delete[] m_pBorderBottom; - delete[] m_pBorderLeft; - delete[] m_pBorderRight; m_pTilesOfLayer = NULL; - m_pBorderTop = NULL; - m_pBorderBottom = NULL; - m_pBorderLeft = NULL; - m_pBorderRight = NULL; } -bool AddTile(std::vector &vTmpTiles, std::vector &vTmpTileTexCoords, bool As3DTextureCoord, unsigned char Index, unsigned char Flags, int x, int y, CMapItemGroup *pGroup, bool DoTextureCoords, bool FillSpeedup = false, int AngleRotate = -1) +bool AddTile(std::vector &vTmpTiles, std::vector &vTmpTileTexCoords, unsigned char Index, unsigned char Flags, int x, int y, CMapItemGroup *pGroup, bool DoTextureCoords, bool FillSpeedup = false, int AngleRotate = -1, const ivec2 &Offset = ivec2{0, 0}, int Scale = 32) { if(Index) { @@ -345,9 +264,9 @@ bool AddTile(std::vector &vTmpTiles, std::vector vtmpQuads; std::vector vtmpQuadsTextured; - bool As3DTextureCoords = !Graphics()->HasTextureArrays(); - for(int g = 0; g < m_pLayers->NumGroups(); g++) { CMapItemGroup *pGroup = m_pLayers->GetGroup(g); @@ -696,13 +613,13 @@ void CMapLayers::OnMapLoad() //the amount of tiles handled before this tile int TilesHandledCount = vtmpTiles.size(); - Visuals.m_pTilesOfLayer[y * pTMap->m_Width + x].SetIndexBufferByteOffset((offset_ptr32)(TilesHandledCount * 6 * sizeof(unsigned int))); + Visuals.m_pTilesOfLayer[y * pTMap->m_Width + x].SetIndexBufferByteOffset((offset_ptr32)(TilesHandledCount)); bool AddAsSpeedup = false; if(IsSpeedupLayer && CurOverlay == 0) AddAsSpeedup = true; - if(AddTile(vtmpTiles, vtmpTileTexCoords, As3DTextureCoords, Index, Flags, x, y, pGroup, DoTextureCoords, AddAsSpeedup, AngleRotate)) + if(AddTile(vtmpTiles, vtmpTileTexCoords, Index, Flags, x, y, pGroup, DoTextureCoords, AddAsSpeedup, AngleRotate)) Visuals.m_pTilesOfLayer[y * pTMap->m_Width + x].Draw(true); //do the border tiles @@ -710,61 +627,49 @@ void CMapLayers::OnMapLoad() { if(y == 0) { - Visuals.m_BorderTopLeft.SetIndexBufferByteOffset((offset_ptr32)(vtmpBorderCorners.size() * 6 * sizeof(unsigned int))); - if(AddTile(vtmpBorderCorners, vtmpBorderCornersTexCoords, As3DTextureCoords, Index, Flags, x, y, pGroup, DoTextureCoords, AddAsSpeedup, AngleRotate)) + Visuals.m_BorderTopLeft.SetIndexBufferByteOffset((offset_ptr32)(vtmpBorderCorners.size())); + if(AddTile(vtmpBorderCorners, vtmpBorderCornersTexCoords, Index, Flags, 0, 0, pGroup, DoTextureCoords, AddAsSpeedup, AngleRotate, ivec2{-32, -32})) Visuals.m_BorderTopLeft.Draw(true); } else if(y == pTMap->m_Height - 1) { - Visuals.m_BorderBottomLeft.SetIndexBufferByteOffset((offset_ptr32)(vtmpBorderCorners.size() * 6 * sizeof(unsigned int))); - if(AddTile(vtmpBorderCorners, vtmpBorderCornersTexCoords, As3DTextureCoords, Index, Flags, x, y, pGroup, DoTextureCoords, AddAsSpeedup, AngleRotate)) + Visuals.m_BorderBottomLeft.SetIndexBufferByteOffset((offset_ptr32)(vtmpBorderCorners.size())); + if(AddTile(vtmpBorderCorners, vtmpBorderCornersTexCoords, Index, Flags, 0, 0, pGroup, DoTextureCoords, AddAsSpeedup, AngleRotate, ivec2{-32, 0})) Visuals.m_BorderBottomLeft.Draw(true); } - else - { - Visuals.m_pBorderLeft[y - 1].SetIndexBufferByteOffset((offset_ptr32)(vtmpBorderLeftTiles.size() * 6 * sizeof(unsigned int))); - if(AddTile(vtmpBorderLeftTiles, vtmpBorderLeftTilesTexCoords, As3DTextureCoords, Index, Flags, x, y, pGroup, DoTextureCoords, AddAsSpeedup, AngleRotate)) - Visuals.m_pBorderLeft[y - 1].Draw(true); - } + Visuals.m_vBorderLeft[y].SetIndexBufferByteOffset((offset_ptr32)(vtmpBorderLeftTiles.size())); + if(AddTile(vtmpBorderLeftTiles, vtmpBorderLeftTilesTexCoords, Index, Flags, 0, y, pGroup, DoTextureCoords, AddAsSpeedup, AngleRotate, ivec2{-32, 0})) + Visuals.m_vBorderLeft[y].Draw(true); } else if(x == pTMap->m_Width - 1) { if(y == 0) { - Visuals.m_BorderTopRight.SetIndexBufferByteOffset((offset_ptr32)(vtmpBorderCorners.size() * 6 * sizeof(unsigned int))); - if(AddTile(vtmpBorderCorners, vtmpBorderCornersTexCoords, As3DTextureCoords, Index, Flags, x, y, pGroup, DoTextureCoords, AddAsSpeedup, AngleRotate)) + Visuals.m_BorderTopRight.SetIndexBufferByteOffset((offset_ptr32)(vtmpBorderCorners.size())); + if(AddTile(vtmpBorderCorners, vtmpBorderCornersTexCoords, Index, Flags, 0, 0, pGroup, DoTextureCoords, AddAsSpeedup, AngleRotate, ivec2{0, -32})) Visuals.m_BorderTopRight.Draw(true); } else if(y == pTMap->m_Height - 1) { - Visuals.m_BorderBottomRight.SetIndexBufferByteOffset((offset_ptr32)(vtmpBorderCorners.size() * 6 * sizeof(unsigned int))); - if(AddTile(vtmpBorderCorners, vtmpBorderCornersTexCoords, As3DTextureCoords, Index, Flags, x, y, pGroup, DoTextureCoords, AddAsSpeedup, AngleRotate)) + Visuals.m_BorderBottomRight.SetIndexBufferByteOffset((offset_ptr32)(vtmpBorderCorners.size())); + if(AddTile(vtmpBorderCorners, vtmpBorderCornersTexCoords, Index, Flags, 0, 0, pGroup, DoTextureCoords, AddAsSpeedup, AngleRotate, ivec2{0, 0})) Visuals.m_BorderBottomRight.Draw(true); } - else - { - Visuals.m_pBorderRight[y - 1].SetIndexBufferByteOffset((offset_ptr32)(vtmpBorderRightTiles.size() * 6 * sizeof(unsigned int))); - if(AddTile(vtmpBorderRightTiles, vtmpBorderRightTilesTexCoords, As3DTextureCoords, Index, Flags, x, y, pGroup, DoTextureCoords, AddAsSpeedup, AngleRotate)) - Visuals.m_pBorderRight[y - 1].Draw(true); - } + Visuals.m_vBorderRight[y].SetIndexBufferByteOffset((offset_ptr32)(vtmpBorderRightTiles.size())); + if(AddTile(vtmpBorderRightTiles, vtmpBorderRightTilesTexCoords, Index, Flags, 0, y, pGroup, DoTextureCoords, AddAsSpeedup, AngleRotate, ivec2{0, 0})) + Visuals.m_vBorderRight[y].Draw(true); } - else if(y == 0) + if(y == 0) { - if(x > 0 && x < pTMap->m_Width - 1) - { - Visuals.m_pBorderTop[x - 1].SetIndexBufferByteOffset((offset_ptr32)(vtmpBorderTopTiles.size() * 6 * sizeof(unsigned int))); - if(AddTile(vtmpBorderTopTiles, vtmpBorderTopTilesTexCoords, As3DTextureCoords, Index, Flags, x, y, pGroup, DoTextureCoords, AddAsSpeedup, AngleRotate)) - Visuals.m_pBorderTop[x - 1].Draw(true); - } + Visuals.m_vBorderTop[x].SetIndexBufferByteOffset((offset_ptr32)(vtmpBorderTopTiles.size())); + if(AddTile(vtmpBorderTopTiles, vtmpBorderTopTilesTexCoords, Index, Flags, x, 0, pGroup, DoTextureCoords, AddAsSpeedup, AngleRotate, ivec2{0, -32})) + Visuals.m_vBorderTop[x].Draw(true); } else if(y == pTMap->m_Height - 1) { - if(x > 0 && x < pTMap->m_Width - 1) - { - Visuals.m_pBorderBottom[x - 1].SetIndexBufferByteOffset((offset_ptr32)(vtmpBorderBottomTiles.size() * 6 * sizeof(unsigned int))); - if(AddTile(vtmpBorderBottomTiles, vtmpBorderBottomTilesTexCoords, As3DTextureCoords, Index, Flags, x, y, pGroup, DoTextureCoords, AddAsSpeedup, AngleRotate)) - Visuals.m_pBorderBottom[x - 1].Draw(true); - } + Visuals.m_vBorderBottom[x].SetIndexBufferByteOffset((offset_ptr32)(vtmpBorderBottomTiles.size())); + if(AddTile(vtmpBorderBottomTiles, vtmpBorderBottomTilesTexCoords, Index, Flags, x, 0, pGroup, DoTextureCoords, AddAsSpeedup, AngleRotate, ivec2{0, 0})) + Visuals.m_vBorderBottom[x].Draw(true); } } } @@ -772,61 +677,61 @@ void CMapLayers::OnMapLoad() //append one kill tile to the gamelayer if(IsGameLayer) { - Visuals.m_BorderKillTile.SetIndexBufferByteOffset((offset_ptr32)(vtmpTiles.size() * 6 * sizeof(unsigned int))); - if(AddTile(vtmpTiles, vtmpTileTexCoords, As3DTextureCoords, TILE_DEATH, 0, 0, 0, pGroup, DoTextureCoords)) + Visuals.m_BorderKillTile.SetIndexBufferByteOffset((offset_ptr32)(vtmpTiles.size())); + if(AddTile(vtmpTiles, vtmpTileTexCoords, TILE_DEATH, 0, 0, 0, pGroup, DoTextureCoords)) Visuals.m_BorderKillTile.Draw(true); } //add the border corners, then the borders and fix their byte offsets int TilesHandledCount = vtmpTiles.size(); - Visuals.m_BorderTopLeft.AddIndexBufferByteOffset(TilesHandledCount * 6 * sizeof(unsigned int)); - Visuals.m_BorderTopRight.AddIndexBufferByteOffset(TilesHandledCount * 6 * sizeof(unsigned int)); - Visuals.m_BorderBottomLeft.AddIndexBufferByteOffset(TilesHandledCount * 6 * sizeof(unsigned int)); - Visuals.m_BorderBottomRight.AddIndexBufferByteOffset(TilesHandledCount * 6 * sizeof(unsigned int)); + Visuals.m_BorderTopLeft.AddIndexBufferByteOffset(TilesHandledCount); + Visuals.m_BorderTopRight.AddIndexBufferByteOffset(TilesHandledCount); + Visuals.m_BorderBottomLeft.AddIndexBufferByteOffset(TilesHandledCount); + Visuals.m_BorderBottomRight.AddIndexBufferByteOffset(TilesHandledCount); //add the Corners to the tiles vtmpTiles.insert(vtmpTiles.end(), vtmpBorderCorners.begin(), vtmpBorderCorners.end()); vtmpTileTexCoords.insert(vtmpTileTexCoords.end(), vtmpBorderCornersTexCoords.begin(), vtmpBorderCornersTexCoords.end()); //now the borders TilesHandledCount = vtmpTiles.size(); - if(pTMap->m_Width > 2) + if(pTMap->m_Width > 0) { - for(int i = 0; i < pTMap->m_Width - 2; ++i) + for(int i = 0; i < pTMap->m_Width; ++i) { - Visuals.m_pBorderTop[i].AddIndexBufferByteOffset(TilesHandledCount * 6 * sizeof(unsigned int)); + Visuals.m_vBorderTop[i].AddIndexBufferByteOffset(TilesHandledCount); } } vtmpTiles.insert(vtmpTiles.end(), vtmpBorderTopTiles.begin(), vtmpBorderTopTiles.end()); vtmpTileTexCoords.insert(vtmpTileTexCoords.end(), vtmpBorderTopTilesTexCoords.begin(), vtmpBorderTopTilesTexCoords.end()); TilesHandledCount = vtmpTiles.size(); - if(pTMap->m_Width > 2) + if(pTMap->m_Width > 0) { - for(int i = 0; i < pTMap->m_Width - 2; ++i) + for(int i = 0; i < pTMap->m_Width; ++i) { - Visuals.m_pBorderBottom[i].AddIndexBufferByteOffset(TilesHandledCount * 6 * sizeof(unsigned int)); + Visuals.m_vBorderBottom[i].AddIndexBufferByteOffset(TilesHandledCount); } } vtmpTiles.insert(vtmpTiles.end(), vtmpBorderBottomTiles.begin(), vtmpBorderBottomTiles.end()); vtmpTileTexCoords.insert(vtmpTileTexCoords.end(), vtmpBorderBottomTilesTexCoords.begin(), vtmpBorderBottomTilesTexCoords.end()); TilesHandledCount = vtmpTiles.size(); - if(pTMap->m_Height > 2) + if(pTMap->m_Height > 0) { - for(int i = 0; i < pTMap->m_Height - 2; ++i) + for(int i = 0; i < pTMap->m_Height; ++i) { - Visuals.m_pBorderLeft[i].AddIndexBufferByteOffset(TilesHandledCount * 6 * sizeof(unsigned int)); + Visuals.m_vBorderLeft[i].AddIndexBufferByteOffset(TilesHandledCount); } } vtmpTiles.insert(vtmpTiles.end(), vtmpBorderLeftTiles.begin(), vtmpBorderLeftTiles.end()); vtmpTileTexCoords.insert(vtmpTileTexCoords.end(), vtmpBorderLeftTilesTexCoords.begin(), vtmpBorderLeftTilesTexCoords.end()); TilesHandledCount = vtmpTiles.size(); - if(pTMap->m_Height > 2) + if(pTMap->m_Height > 0) { - for(int i = 0; i < pTMap->m_Height - 2; ++i) + for(int i = 0; i < pTMap->m_Height; ++i) { - Visuals.m_pBorderRight[i].AddIndexBufferByteOffset(TilesHandledCount * 6 * sizeof(unsigned int)); + Visuals.m_vBorderRight[i].AddIndexBufferByteOffset(TilesHandledCount); } } vtmpTiles.insert(vtmpTiles.end(), vtmpBorderRightTiles.begin(), vtmpBorderRightTiles.end()); @@ -842,10 +747,10 @@ void CMapLayers::OnMapLoad() { char *pUploadData = (char *)malloc(sizeof(char) * UploadDataSize); - mem_copy_special(pUploadData, pTmpTiles, sizeof(vec2), vtmpTiles.size() * 4, (DoTextureCoords ? sizeof(vec3) : 0)); + mem_copy_special(pUploadData, pTmpTiles, sizeof(vec2), vtmpTiles.size() * 4, (DoTextureCoords ? sizeof(ubvec4) : 0)); if(DoTextureCoords) { - mem_copy_special(pUploadData + sizeof(vec2), pTmpTileTexCoords, sizeof(vec3), vtmpTiles.size() * 4, sizeof(vec2)); + mem_copy_special(pUploadData + sizeof(vec2), pTmpTileTexCoords, sizeof(ubvec4), vtmpTiles.size() * 4, sizeof(vec2)); } // first create the buffer object @@ -853,7 +758,7 @@ void CMapLayers::OnMapLoad() // then create the buffer container SBufferContainerInfo ContainerInfo; - ContainerInfo.m_Stride = (DoTextureCoords ? (sizeof(float) * 2 + sizeof(vec3)) : 0); + ContainerInfo.m_Stride = (DoTextureCoords ? (sizeof(float) * 2 + sizeof(ubvec4)) : 0); ContainerInfo.m_VertBufferBindingIndex = BufferObjectIndex; ContainerInfo.m_vAttributes.emplace_back(); SBufferContainerInfo::SAttribute *pAttr = &ContainerInfo.m_vAttributes.back(); @@ -866,11 +771,11 @@ void CMapLayers::OnMapLoad() { ContainerInfo.m_vAttributes.emplace_back(); pAttr = &ContainerInfo.m_vAttributes.back(); - pAttr->m_DataTypeCount = 3; - pAttr->m_Type = GRAPHICS_TYPE_FLOAT; + pAttr->m_DataTypeCount = 4; + pAttr->m_Type = GRAPHICS_TYPE_UNSIGNED_BYTE; pAttr->m_Normalized = false; pAttr->m_pOffset = (void *)(sizeof(vec2)); - pAttr->m_FuncType = 0; + pAttr->m_FuncType = 1; } Visuals.m_BufferContainerIndex = Graphics()->CreateBufferContainer(&ContainerInfo); @@ -1014,36 +919,36 @@ void CMapLayers::RenderTileLayer(int LayerIndex, ColorRGBA &Color, CMapItemLayer int BorderX0, BorderY0, BorderX1, BorderY1; bool DrawBorder = false; - int Y0 = BorderY0 = std::floor((ScreenY0) / 32); - int X0 = BorderX0 = std::floor((ScreenX0) / 32); - int Y1 = BorderY1 = std::floor((ScreenY1) / 32); - int X1 = BorderX1 = std::floor((ScreenX1) / 32); + int Y0 = BorderY0 = std::floor(ScreenY0 / 32); + int X0 = BorderX0 = std::floor(ScreenX0 / 32); + int Y1 = BorderY1 = std::ceil(ScreenY1 / 32); + int X1 = BorderX1 = std::ceil(ScreenX1 / 32); - if(X0 <= 0) + if(X0 < 0) { X0 = 0; DrawBorder = true; } - if(Y0 <= 0) + if(Y0 < 0) { Y0 = 0; DrawBorder = true; } - if(X1 >= pTileLayer->m_Width - 1) + if(X1 > pTileLayer->m_Width) { - X1 = pTileLayer->m_Width - 1; + X1 = pTileLayer->m_Width; DrawBorder = true; } - if(Y1 >= pTileLayer->m_Height - 1) + if(Y1 > pTileLayer->m_Height) { - Y1 = pTileLayer->m_Height - 1; + Y1 = pTileLayer->m_Height; DrawBorder = true; } bool DrawLayer = true; - if(X1 < 0) + if(X1 <= 0) DrawLayer = false; - if(Y1 < 0) + if(Y1 <= 0) DrawLayer = false; if(X0 >= pTileLayer->m_Width) DrawLayer = false; @@ -1063,14 +968,15 @@ void CMapLayers::RenderTileLayer(int LayerIndex, ColorRGBA &Color, CMapItemLayer s_vpIndexOffsets.reserve(Reserve); s_vDrawCounts.reserve(Reserve); - for(int y = Y0; y <= Y1; ++y) + for(int y = Y0; y < Y1; ++y) { if(X0 > X1) continue; + int XR = X1 - 1; - dbg_assert(Visuals.m_pTilesOfLayer[y * pTileLayer->m_Width + X1].IndexBufferByteOffset() >= Visuals.m_pTilesOfLayer[y * pTileLayer->m_Width + X0].IndexBufferByteOffset(), "Tile count wrong."); + dbg_assert(Visuals.m_pTilesOfLayer[y * pTileLayer->m_Width + XR].IndexBufferByteOffset() >= Visuals.m_pTilesOfLayer[y * pTileLayer->m_Width + X0].IndexBufferByteOffset(), "Tile count wrong."); - unsigned int NumVertices = ((Visuals.m_pTilesOfLayer[y * pTileLayer->m_Width + X1].IndexBufferByteOffset() - Visuals.m_pTilesOfLayer[y * pTileLayer->m_Width + X0].IndexBufferByteOffset()) / sizeof(unsigned int)) + (Visuals.m_pTilesOfLayer[y * pTileLayer->m_Width + X1].DoDraw() ? 6lu : 0lu); + unsigned int NumVertices = ((Visuals.m_pTilesOfLayer[y * pTileLayer->m_Width + XR].IndexBufferByteOffset() - Visuals.m_pTilesOfLayer[y * pTileLayer->m_Width + X0].IndexBufferByteOffset()) / sizeof(unsigned int)) + (Visuals.m_pTilesOfLayer[y * pTileLayer->m_Width + XR].DoDraw() ? 6lu : 0lu); if(NumVertices) { @@ -1092,23 +998,10 @@ void CMapLayers::RenderTileLayer(int LayerIndex, ColorRGBA &Color, CMapItemLayer } if(DrawBorder) - RenderTileBorder(LayerIndex, Color, pTileLayer, pGroup, BorderX0, BorderY0, BorderX1, BorderY1, -std::floor(-ScreenX1 / 32.f) - BorderX0, -std::floor(-ScreenY1 / 32.f) - BorderY0); + RenderTileBorder(LayerIndex, Color, pTileLayer, pGroup, BorderX0, BorderY0, BorderX1, BorderY1); } -void CMapLayers::RenderTileBorderCornerTiles(int WidthOffsetToOrigin, int HeightOffsetToOrigin, int TileCountWidth, int TileCountHeight, int BufferContainerIndex, const ColorRGBA &Color, offset_ptr_size IndexBufferOffset, const vec2 &Offset, const vec2 &Dir) -{ - // if border is still in range of the original corner, it doesn't needs to be redrawn - bool CornerVisible = (WidthOffsetToOrigin - 1 < TileCountWidth) && (HeightOffsetToOrigin - 1 < TileCountHeight); - - int CountX = minimum(WidthOffsetToOrigin, TileCountWidth); - int CountY = minimum(HeightOffsetToOrigin, TileCountHeight); - - int Count = (CountX * CountY) - (CornerVisible ? 1 : 0); // Don't draw the corner again - - Graphics()->RenderBorderTiles(BufferContainerIndex, Color, IndexBufferOffset, Offset, Dir, CountX, Count); -} - -void CMapLayers::RenderTileBorder(int LayerIndex, const ColorRGBA &Color, CMapItemLayerTilemap *pTileLayer, CMapItemGroup *pGroup, int BorderX0, int BorderY0, int BorderX1, int BorderY1, int ScreenWidthTileCount, int ScreenHeightTileCount) +void CMapLayers::RenderTileBorder(int LayerIndex, const ColorRGBA &Color, CMapItemLayerTilemap *pTileLayer, CMapItemGroup *pGroup, int BorderX0, int BorderY0, int BorderX1, int BorderY1) { STileLayerVisuals &Visuals = *m_vpTileLayerVisuals[LayerIndex]; @@ -1117,145 +1010,147 @@ void CMapLayers::RenderTileBorder(int LayerIndex, const ColorRGBA &Color, CMapIt int Y1 = BorderY1; int X1 = BorderX1; - int CountWidth = ScreenWidthTileCount; - int CountHeight = ScreenHeightTileCount; + if(X0 < 0) + X0 = 0; + if(Y0 < 0) + Y0 = 0; + if(X1 > pTileLayer->m_Width) + X1 = pTileLayer->m_Width; + if(Y1 > pTileLayer->m_Height) + Y1 = pTileLayer->m_Height; - if(X0 < 1) - X0 = 1; - if(Y0 < 1) - Y0 = 1; - if(X1 >= pTileLayer->m_Width - 1) - X1 = pTileLayer->m_Width - 2; - if(Y1 >= pTileLayer->m_Height - 1) - Y1 = pTileLayer->m_Height - 2; - - if(BorderX0 <= 0) + // corners + if(BorderX0 < 0) { // Draw corners on left side - if(BorderY0 <= 0) + if(BorderY0 < 0) { if(Visuals.m_BorderTopLeft.DoDraw()) { vec2 Offset; - Offset.x = BorderX0 * 32.f; - Offset.y = BorderY0 * 32.f; - vec2 Dir; - Dir.x = 32.f; - Dir.y = 32.f; + Offset.x = 0; + Offset.y = 0; + vec2 Scale; + Scale.x = absolute(BorderX0); + Scale.y = absolute(BorderY0); - RenderTileBorderCornerTiles(absolute(BorderX0) + 1, absolute(BorderY0) + 1, CountWidth, CountHeight, Visuals.m_BufferContainerIndex, Color, (offset_ptr_size)Visuals.m_BorderTopLeft.IndexBufferByteOffset(), Offset, Dir); + Graphics()->RenderBorderTiles(Visuals.m_BufferContainerIndex, Color, (offset_ptr_size)Visuals.m_BorderTopLeft.IndexBufferByteOffset(), Offset, Scale, 1); } } - if(BorderY1 >= pTileLayer->m_Height - 1) + if(BorderY1 > pTileLayer->m_Height) { if(Visuals.m_BorderBottomLeft.DoDraw()) { vec2 Offset; - Offset.x = BorderX0 * 32.f; - Offset.y = (BorderY1 - (pTileLayer->m_Height - 1)) * 32.f; - vec2 Dir; - Dir.x = 32.f; - Dir.y = -32.f; + Offset.x = 0; + Offset.y = pTileLayer->m_Height * 32.0f; + vec2 Scale; + Scale.x = absolute(BorderX0); + Scale.y = BorderY1 - pTileLayer->m_Height; - RenderTileBorderCornerTiles(absolute(BorderX0) + 1, (BorderY1 - (pTileLayer->m_Height - 1)) + 1, CountWidth, CountHeight, Visuals.m_BufferContainerIndex, Color, (offset_ptr_size)Visuals.m_BorderBottomLeft.IndexBufferByteOffset(), Offset, Dir); + Graphics()->RenderBorderTiles(Visuals.m_BufferContainerIndex, Color, (offset_ptr_size)Visuals.m_BorderBottomLeft.IndexBufferByteOffset(), Offset, Scale, 1); } } } + if(BorderX1 > pTileLayer->m_Width) + { + // Draw corners on right side + if(BorderY0 < 0) + { + if(Visuals.m_BorderTopRight.DoDraw()) + { + vec2 Offset; + Offset.x = pTileLayer->m_Width * 32.0f; + Offset.y = 0; + vec2 Scale; + Scale.x = BorderX1 - pTileLayer->m_Width; + Scale.y = absolute(BorderY0); + + Graphics()->RenderBorderTiles(Visuals.m_BufferContainerIndex, Color, (offset_ptr_size)Visuals.m_BorderTopRight.IndexBufferByteOffset(), Offset, Scale, 1); + } + } + if(BorderY1 > pTileLayer->m_Height) + { + if(Visuals.m_BorderBottomRight.DoDraw()) + { + vec2 Offset; + Offset.x = pTileLayer->m_Width * 32.0f; + Offset.y = pTileLayer->m_Height * 32.0f; + vec2 Scale; + Scale.x = BorderX1 - pTileLayer->m_Width; + Scale.y = BorderY1 - pTileLayer->m_Height; + + Graphics()->RenderBorderTiles(Visuals.m_BufferContainerIndex, Color, (offset_ptr_size)Visuals.m_BorderBottomRight.IndexBufferByteOffset(), Offset, Scale, 1); + } + } + } + + if(BorderX1 > pTileLayer->m_Width) + { + // Draw right border + if(Y0 < pTileLayer->m_Height && Y1 > 0) + { + int YB = Y1 - 1; + unsigned int DrawNum = ((Visuals.m_vBorderRight[YB].IndexBufferByteOffset() - Visuals.m_vBorderRight[Y0].IndexBufferByteOffset()) / (sizeof(unsigned int) * 6)) + (Visuals.m_vBorderRight[YB].DoDraw() ? 1lu : 0lu); + offset_ptr_size pOffset = (offset_ptr_size)Visuals.m_vBorderRight[Y0].IndexBufferByteOffset(); + vec2 Offset; + Offset.x = 32.f * pTileLayer->m_Width; + Offset.y = 0.f; + vec2 Scale; + Scale.x = BorderX1 - pTileLayer->m_Width; + Scale.y = 1.f; + Graphics()->RenderBorderTiles(Visuals.m_BufferContainerIndex, Color, pOffset, Offset, Scale, DrawNum); + } + } if(BorderX0 < 0) { // Draw left border - if(Y0 < pTileLayer->m_Height - 1 && Y1 > 0) + if(Y0 < pTileLayer->m_Height && Y1 > 0) { - unsigned int DrawNum = ((Visuals.m_pBorderLeft[Y1 - 1].IndexBufferByteOffset() - Visuals.m_pBorderLeft[Y0 - 1].IndexBufferByteOffset()) / sizeof(unsigned int)) + (Visuals.m_pBorderLeft[Y1 - 1].DoDraw() ? 6lu : 0lu); - offset_ptr_size pOffset = (offset_ptr_size)Visuals.m_pBorderLeft[Y0 - 1].IndexBufferByteOffset(); + int YB = Y1 - 1; + unsigned int DrawNum = ((Visuals.m_vBorderLeft[YB].IndexBufferByteOffset() - Visuals.m_vBorderLeft[Y0].IndexBufferByteOffset()) / (sizeof(unsigned int) * 6)) + (Visuals.m_vBorderLeft[YB].DoDraw() ? 1lu : 0lu); + offset_ptr_size pOffset = (offset_ptr_size)Visuals.m_vBorderLeft[Y0].IndexBufferByteOffset(); vec2 Offset; - Offset.x = 32.f * BorderX0; - Offset.y = 0.f; - vec2 Dir; - Dir.x = 32.f; - Dir.y = 0.f; - Graphics()->RenderBorderTileLines(Visuals.m_BufferContainerIndex, Color, pOffset, Offset, Dir, DrawNum, minimum(absolute(BorderX0), CountWidth)); - } - } - - if(BorderX1 >= pTileLayer->m_Width - 1) - { - // Draw corners on right side - if(BorderY0 <= 0) - { - if(Visuals.m_BorderTopRight.DoDraw()) - { - vec2 Offset; - Offset.x = (BorderX1 - (pTileLayer->m_Width - 1)) * 32.f; - Offset.y = BorderY0 * 32.f; - vec2 Dir; - Dir.x = -32.f; - Dir.y = 32.f; - - RenderTileBorderCornerTiles((BorderX1 - (pTileLayer->m_Width - 1)) + 1, absolute(BorderY0) + 1, CountWidth, CountHeight, Visuals.m_BufferContainerIndex, Color, (offset_ptr_size)Visuals.m_BorderTopRight.IndexBufferByteOffset(), Offset, Dir); - } - } - if(BorderY1 >= pTileLayer->m_Height - 1) - { - if(Visuals.m_BorderBottomRight.DoDraw()) - { - vec2 Offset; - Offset.x = (BorderX1 - (pTileLayer->m_Width - 1)) * 32.f; - Offset.y = (BorderY1 - (pTileLayer->m_Height - 1)) * 32.f; - vec2 Dir; - Dir.x = -32.f; - Dir.y = -32.f; - - RenderTileBorderCornerTiles((BorderX1 - (pTileLayer->m_Width - 1)) + 1, (BorderY1 - (pTileLayer->m_Height - 1)) + 1, CountWidth, CountHeight, Visuals.m_BufferContainerIndex, Color, (offset_ptr_size)Visuals.m_BorderBottomRight.IndexBufferByteOffset(), Offset, Dir); - } - } - } - if(BorderX1 > pTileLayer->m_Width - 1) - { - // Draw right border - if(Y0 < pTileLayer->m_Height - 1 && Y1 > 0) - { - unsigned int DrawNum = ((Visuals.m_pBorderRight[Y1 - 1].IndexBufferByteOffset() - Visuals.m_pBorderRight[Y0 - 1].IndexBufferByteOffset()) / sizeof(unsigned int)) + (Visuals.m_pBorderRight[Y1 - 1].DoDraw() ? 6lu : 0lu); - offset_ptr_size pOffset = (offset_ptr_size)Visuals.m_pBorderRight[Y0 - 1].IndexBufferByteOffset(); - vec2 Offset; - Offset.x = 32.f * (BorderX1 - (pTileLayer->m_Width - 1)); - Offset.y = 0.f; - vec2 Dir; - Dir.x = -32.f; - Dir.y = 0.f; - Graphics()->RenderBorderTileLines(Visuals.m_BufferContainerIndex, Color, pOffset, Offset, Dir, DrawNum, minimum((BorderX1 - (pTileLayer->m_Width - 1)), CountWidth)); + Offset.x = 0; + Offset.y = 0; + vec2 Scale; + Scale.x = absolute(BorderX0); + Scale.y = 1; + Graphics()->RenderBorderTiles(Visuals.m_BufferContainerIndex, Color, pOffset, Offset, Scale, DrawNum); } } if(BorderY0 < 0) { // Draw top border - if(X0 < pTileLayer->m_Width - 1 && X1 > 0) + if(X0 < pTileLayer->m_Width && X1 > 0) { - unsigned int DrawNum = ((Visuals.m_pBorderTop[X1 - 1].IndexBufferByteOffset() - Visuals.m_pBorderTop[X0 - 1].IndexBufferByteOffset()) / sizeof(unsigned int)) + (Visuals.m_pBorderTop[X1 - 1].DoDraw() ? 6lu : 0lu); - offset_ptr_size pOffset = (offset_ptr_size)Visuals.m_pBorderTop[X0 - 1].IndexBufferByteOffset(); + int XR = X1 - 1; + unsigned int DrawNum = ((Visuals.m_vBorderTop[XR].IndexBufferByteOffset() - Visuals.m_vBorderTop[X0].IndexBufferByteOffset()) / (sizeof(unsigned int) * 6)) + (Visuals.m_vBorderTop[XR].DoDraw() ? 1lu : 0lu); + offset_ptr_size pOffset = (offset_ptr_size)Visuals.m_vBorderTop[X0].IndexBufferByteOffset(); vec2 Offset; Offset.x = 0.f; - Offset.y = 32.f * BorderY0; - vec2 Dir; - Dir.x = 0.f; - Dir.y = 32.f; - Graphics()->RenderBorderTileLines(Visuals.m_BufferContainerIndex, Color, pOffset, Offset, Dir, DrawNum, minimum(absolute(BorderY0), CountHeight)); + Offset.y = 0; + vec2 Scale; + Scale.x = 1; + Scale.y = absolute(BorderY0); + Graphics()->RenderBorderTiles(Visuals.m_BufferContainerIndex, Color, pOffset, Offset, Scale, DrawNum); } } - if(BorderY1 >= pTileLayer->m_Height) + if(BorderY1 > pTileLayer->m_Height) { // Draw bottom border - if(X0 < pTileLayer->m_Width - 1 && X1 > 0) + if(X0 < pTileLayer->m_Width && X1 > 0) { - unsigned int DrawNum = ((Visuals.m_pBorderBottom[X1 - 1].IndexBufferByteOffset() - Visuals.m_pBorderBottom[X0 - 1].IndexBufferByteOffset()) / sizeof(unsigned int)) + (Visuals.m_pBorderBottom[X1 - 1].DoDraw() ? 6lu : 0lu); - offset_ptr_size pOffset = (offset_ptr_size)Visuals.m_pBorderBottom[X0 - 1].IndexBufferByteOffset(); + int XR = X1 - 1; + unsigned int DrawNum = ((Visuals.m_vBorderBottom[XR].IndexBufferByteOffset() - Visuals.m_vBorderBottom[X0].IndexBufferByteOffset()) / (sizeof(unsigned int) * 6)) + (Visuals.m_vBorderBottom[XR].DoDraw() ? 1lu : 0lu); + offset_ptr_size pOffset = (offset_ptr_size)Visuals.m_vBorderBottom[X0].IndexBufferByteOffset(); vec2 Offset; Offset.x = 0.f; - Offset.y = 32.f * (BorderY1 - (pTileLayer->m_Height - 1)); - vec2 Dir; - Dir.x = 0.f; - Dir.y = -32.f; - Graphics()->RenderBorderTileLines(Visuals.m_BufferContainerIndex, Color, pOffset, Offset, Dir, DrawNum, minimum((BorderY1 - (pTileLayer->m_Height - 1)), CountHeight)); + Offset.y = 32.f * pTileLayer->m_Height; + vec2 Scale; + Scale.x = 1; + Scale.y = BorderY1 - pTileLayer->m_Height; + Graphics()->RenderBorderTiles(Visuals.m_BufferContainerIndex, Color, pOffset, Offset, Scale, DrawNum); } } } @@ -1271,18 +1166,18 @@ void CMapLayers::RenderKillTileBorder(int LayerIndex, const ColorRGBA &Color, CM bool DrawBorder = false; - int BorderY0 = (int)(ScreenY0 / 32) - 1; - int BorderX0 = (int)(ScreenX0 / 32) - 1; - int BorderY1 = (int)(ScreenY1 / 32) + 1; - int BorderX1 = (int)(ScreenX1 / 32) + 1; + int BorderY0 = std::floor(ScreenY0 / 32); + int BorderX0 = std::floor(ScreenX0 / 32); + int BorderY1 = std::ceil(ScreenY1 / 32); + int BorderX1 = std::ceil(ScreenX1 / 32); if(BorderX0 < -201) DrawBorder = true; if(BorderY0 < -201) DrawBorder = true; - if(BorderX1 >= pTileLayer->m_Width + 201) + if(BorderX1 > pTileLayer->m_Width + 201) DrawBorder = true; - if(BorderY1 >= pTileLayer->m_Height + 201) + if(BorderY1 > pTileLayer->m_Height + 201) DrawBorder = true; if(!DrawBorder) @@ -1311,64 +1206,54 @@ void CMapLayers::RenderKillTileBorder(int LayerIndex, const ColorRGBA &Color, CM // Draw left kill tile border if(BorderX0 < -201) { + unsigned int DrawNum = 1; + offset_ptr_size pOffset = (offset_ptr_size)Visuals.m_BorderKillTile.IndexBufferByteOffset(); vec2 Offset; - Offset.x = BorderX0 * 32.f; - Offset.y = BorderY0 * 32.f; - vec2 Dir; - Dir.x = 32.f; - Dir.y = 32.f; - - int Count = (absolute(BorderX0) - 201) * (BorderY1 - BorderY0); - - Graphics()->RenderBorderTiles(Visuals.m_BufferContainerIndex, Color, (offset_ptr_size)Visuals.m_BorderKillTile.IndexBufferByteOffset(), Offset, Dir, (absolute(BorderX0) - 201), Count); + Offset.x = 32.f * BorderX0; + Offset.y = 32.f * BorderY0; + vec2 Scale; + Scale.x = -201 - BorderX0; + Scale.y = BorderY1 - BorderY0; + Graphics()->RenderBorderTiles(Visuals.m_BufferContainerIndex, Color, pOffset, Offset, Scale, DrawNum); } // Draw top kill tile border if(BorderY0 < -201) { + unsigned int DrawNum = 1; + offset_ptr_size pOffset = (offset_ptr_size)Visuals.m_BorderKillTile.IndexBufferByteOffset(); vec2 Offset; - int OffX0 = (BorderX0 < -201 ? -201 : BorderX0); - int OffX1 = (BorderX1 >= pTileLayer->m_Width + 201 ? pTileLayer->m_Width + 201 : BorderX1); - OffX0 = clamp(OffX0, -201, (int)pTileLayer->m_Width + 201); - OffX1 = clamp(OffX1, -201, (int)pTileLayer->m_Width + 201); - Offset.x = OffX0 * 32.f; - Offset.y = BorderY0 * 32.f; - vec2 Dir; - Dir.x = 32.f; - Dir.y = 32.f; - - int Count = (OffX1 - OffX0) * (absolute(BorderY0) - 201); - - Graphics()->RenderBorderTiles(Visuals.m_BufferContainerIndex, Color, (offset_ptr_size)Visuals.m_BorderKillTile.IndexBufferByteOffset(), Offset, Dir, (OffX1 - OffX0), Count); + Offset.x = maximum(BorderX0, -201) * 32.0f; + Offset.y = 32.f * BorderY0; + vec2 Scale; + Scale.x = minimum(BorderX1, pTileLayer->m_Width + 201) - maximum(BorderX0, -201); + Scale.y = -201 - BorderY0; + Graphics()->RenderBorderTiles(Visuals.m_BufferContainerIndex, Color, pOffset, Offset, Scale, DrawNum); } - if(BorderX1 >= pTileLayer->m_Width + 201) + // Draw right kill tile border + if(BorderX1 > pTileLayer->m_Width + 201) { + unsigned int DrawNum = 1; + offset_ptr_size pOffset = (offset_ptr_size)Visuals.m_BorderKillTile.IndexBufferByteOffset(); vec2 Offset; - Offset.x = (pTileLayer->m_Width + 201) * 32.f; - Offset.y = BorderY0 * 32.f; - vec2 Dir; - Dir.x = 32.f; - Dir.y = 32.f; - - int Count = (BorderX1 - (pTileLayer->m_Width + 201)) * (BorderY1 - BorderY0); - - Graphics()->RenderBorderTiles(Visuals.m_BufferContainerIndex, Color, (offset_ptr_size)Visuals.m_BorderKillTile.IndexBufferByteOffset(), Offset, Dir, (BorderX1 - (pTileLayer->m_Width + 201)), Count); + Offset.x = 32.0f * (pTileLayer->m_Width + 201); + Offset.y = 32.0f * BorderY0; + vec2 Scale; + Scale.x = BorderX1 - (pTileLayer->m_Width + 201); + Scale.y = BorderY1 - BorderY0; + Graphics()->RenderBorderTiles(Visuals.m_BufferContainerIndex, Color, pOffset, Offset, Scale, DrawNum); } - if(BorderY1 >= pTileLayer->m_Height + 201) + // Draw bottom kill tile border + if(BorderY1 > pTileLayer->m_Height + 201) { + unsigned int DrawNum = 1; + offset_ptr_size pOffset = (offset_ptr_size)Visuals.m_BorderKillTile.IndexBufferByteOffset(); vec2 Offset; - int OffX0 = (BorderX0 < -201 ? -201 : BorderX0); - int OffX1 = (BorderX1 >= pTileLayer->m_Width + 201 ? pTileLayer->m_Width + 201 : BorderX1); - OffX0 = clamp(OffX0, -201, (int)pTileLayer->m_Width + 201); - OffX1 = clamp(OffX1, -201, (int)pTileLayer->m_Width + 201); - Offset.x = OffX0 * 32.f; - Offset.y = (pTileLayer->m_Height + 201) * 32.f; - vec2 Dir; - Dir.x = 32.f; - Dir.y = 32.f; - - int Count = (OffX1 - OffX0) * (BorderY1 - (pTileLayer->m_Height + 201)); - - Graphics()->RenderBorderTiles(Visuals.m_BufferContainerIndex, Color, (offset_ptr_size)Visuals.m_BorderKillTile.IndexBufferByteOffset(), Offset, Dir, (OffX1 - OffX0), Count); + Offset.x = maximum(BorderX0, -201) * 32.0f; + Offset.y = 32.0f * (pTileLayer->m_Height + 201); + vec2 Scale; + Scale.x = minimum(BorderX1, pTileLayer->m_Width + 201) - maximum(BorderX0, -201); + Scale.y = BorderY1 - (pTileLayer->m_Height + 201); + Graphics()->RenderBorderTiles(Visuals.m_BufferContainerIndex, Color, pOffset, Offset, Scale, DrawNum); } } @@ -1960,6 +1845,7 @@ void CMapLayers::OnRender() Graphics()->TextureSet(m_pImages->GetSpeedupArrow()); RenderTileLayer(TileLayerCounter - 3, Color, pTMap, pGroup); Graphics()->WrapNormal(); + if(g_Config.m_ClTextEntities) { Graphics()->TextureSet(m_pImages->GetOverlayBottom()); diff --git a/src/game/client/components/maplayers.h b/src/game/client/components/maplayers.h index b6d260237..6f273976e 100644 --- a/src/game/client/components/maplayers.h +++ b/src/game/client/components/maplayers.h @@ -40,7 +40,7 @@ class CMapLayers : public CComponent struct STileLayerVisuals { STileLayerVisuals() : - m_pTilesOfLayer(nullptr), m_pBorderTop(nullptr), m_pBorderLeft(nullptr), m_pBorderRight(nullptr), m_pBorderBottom(nullptr) + m_pTilesOfLayer(nullptr) { m_Width = 0; m_Height = 0; @@ -63,27 +63,27 @@ class CMapLayers : public CComponent public: bool DoDraw() { - return (m_IndexBufferByteOffset & 0x00000001) != 0; + return (m_IndexBufferByteOffset & 0x10000000) != 0; } void Draw(bool SetDraw) { - m_IndexBufferByteOffset = (SetDraw ? 0x00000001 : (offset_ptr32)0) | (m_IndexBufferByteOffset & 0xFFFFFFFE); + m_IndexBufferByteOffset = (SetDraw ? 0x10000000 : (offset_ptr32)0) | (m_IndexBufferByteOffset & 0xEFFFFFFF); } offset_ptr IndexBufferByteOffset() { - return ((offset_ptr)(m_IndexBufferByteOffset & 0xFFFFFFFE)); + return ((offset_ptr)(m_IndexBufferByteOffset & 0xEFFFFFFF) * 6 * sizeof(uint32_t)); } void SetIndexBufferByteOffset(offset_ptr32 IndexBufferByteOff) { - m_IndexBufferByteOffset = IndexBufferByteOff | (m_IndexBufferByteOffset & 0x00000001); + m_IndexBufferByteOffset = IndexBufferByteOff | (m_IndexBufferByteOffset & 0x10000000); } void AddIndexBufferByteOffset(offset_ptr32 IndexBufferByteOff) { - m_IndexBufferByteOffset = ((m_IndexBufferByteOffset & 0xFFFFFFFE) + IndexBufferByteOff) | (m_IndexBufferByteOffset & 0x00000001); + m_IndexBufferByteOffset = ((m_IndexBufferByteOffset & 0xEFFFFFFF) + IndexBufferByteOff) | (m_IndexBufferByteOffset & 0x10000000); } }; STileVisual *m_pTilesOfLayer; @@ -95,10 +95,10 @@ class CMapLayers : public CComponent STileVisual m_BorderKillTile; //end of map kill tile -- game layer only - STileVisual *m_pBorderTop; - STileVisual *m_pBorderLeft; - STileVisual *m_pBorderRight; - STileVisual *m_pBorderBottom; + std::vector m_vBorderTop; + std::vector m_vBorderLeft; + std::vector m_vBorderRight; + std::vector m_vBorderBottom; unsigned int m_Width; unsigned int m_Height; @@ -132,8 +132,6 @@ class CMapLayers : public CComponent void LayersOfGroupCount(CMapItemGroup *pGroup, int &TileLayerCount, int &QuadLayerCount, bool &PassedGameLayer); - void RenderTileBorderCornerTiles(int WidthOffsetToOrigin, int HeightOffsetToOrigin, int TileCountWidth, int TileCountHeight, int BufferContainerIndex, const ColorRGBA &Color, offset_ptr_size IndexBufferOffset, const vec2 &Offset, const vec2 &Dir); - protected: virtual bool CanRenderMenuBackground() { return true; } @@ -155,7 +153,7 @@ public: virtual void OnMapLoad() override; void RenderTileLayer(int LayerIndex, ColorRGBA &Color, CMapItemLayerTilemap *pTileLayer, CMapItemGroup *pGroup); - void RenderTileBorder(int LayerIndex, const ColorRGBA &Color, CMapItemLayerTilemap *pTileLayer, CMapItemGroup *pGroup, int BorderX0, int BorderY0, int BorderX1, int BorderY1, int ScreenWidthTileCount, int ScreenHeightTileCount); + void RenderTileBorder(int LayerIndex, const ColorRGBA &Color, CMapItemLayerTilemap *pTileLayer, CMapItemGroup *pGroup, int BorderX0, int BorderY0, int BorderX1, int BorderY1); void RenderKillTileBorder(int LayerIndex, const ColorRGBA &Color, CMapItemLayerTilemap *pTileLayer, CMapItemGroup *pGroup); void RenderQuadLayer(int LayerIndex, CMapItemLayerQuads *pQuadLayer, CMapItemGroup *pGroup, bool ForceRender = false); diff --git a/src/game/client/render_map.cpp b/src/game/client/render_map.cpp index b04cbbaa5..5e858292d 100644 --- a/src/game/client/render_map.cpp +++ b/src/game/client/render_map.cpp @@ -459,7 +459,10 @@ void CRenderTools::RenderTileRectangle(int RectX, int RectY, int RectW, int Rect pfnEval(ColorEnvOffset, ColorEnv, Channels, pUser); } - Graphics()->QuadsBegin(); + if(Graphics()->HasTextureArraysSupport()) + Graphics()->QuadsTex3DBegin(); + else + Graphics()->QuadsBegin(); Graphics()->SetColor(Color.r * Channels.r, Color.g * Channels.g, Color.b * Channels.b, Color.a * Channels.a); int StartY = (int)(ScreenY0 / Scale) - 1; @@ -501,15 +504,39 @@ void CRenderTools::RenderTileRectangle(int RectX, int RectY, int RectW, int Rect float x3 = Nudge + Px0 / TexSize + Frac; float y3 = Nudge + Py1 / TexSize - Frac; - Graphics()->QuadsSetSubsetFree(x0, y0, x1, y1, x2, y2, x3, y3); - IGraphics::CQuadItem QuadItem(x * Scale, y * Scale, Scale, Scale); - Graphics()->QuadsDrawTL(&QuadItem, 1); + if(Graphics()->HasTextureArraysSupport()) + { + x0 = 0; + y0 = 0; + x1 = x0 + 1; + y1 = y0; + x2 = x0 + 1; + y2 = y0 + 1; + x3 = x0; + y3 = y0 + 1; + } + + if(Graphics()->HasTextureArraysSupport()) + { + Graphics()->QuadsSetSubsetFree(x0, y0, x1, y1, x2, y2, x3, y3, Index); + IGraphics::CQuadItem QuadItem(x * Scale, y * Scale, Scale, Scale); + Graphics()->QuadsTex3DDrawTL(&QuadItem, 1); + } + else + { + Graphics()->QuadsSetSubsetFree(x0, y0, x1, y1, x2, y2, x3, y3); + IGraphics::CQuadItem QuadItem(x * Scale, y * Scale, Scale, Scale); + Graphics()->QuadsDrawTL(&QuadItem, 1); + } } } } } - Graphics()->QuadsEnd(); + if(Graphics()->HasTextureArraysSupport()) + Graphics()->QuadsTex3DEnd(); + else + Graphics()->QuadsEnd(); Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1); } @@ -530,7 +557,7 @@ void CRenderTools::RenderTilemap(CTile *pTiles, int w, int h, float Scale, Color pfnEval(ColorEnvOffset, ColorEnv, Channels, pUser); } - if(Graphics()->IsTileBufferingEnabled()) + if(Graphics()->HasTextureArraysSupport()) Graphics()->QuadsTex3DBegin(); else Graphics()->QuadsBegin(); @@ -613,7 +640,7 @@ void CRenderTools::RenderTilemap(CTile *pTiles, int w, int h, float Scale, Color float x3 = Nudge + Px0 / TexSize + Frac; float y3 = Nudge + Py1 / TexSize - Frac; - if(Graphics()->IsTileBufferingEnabled()) + if(Graphics()->HasTextureArraysSupport()) { x0 = 0; y0 = 0; @@ -655,7 +682,7 @@ void CRenderTools::RenderTilemap(CTile *pTiles, int w, int h, float Scale, Color y1 = Tmp; } - if(Graphics()->IsTileBufferingEnabled()) + if(Graphics()->HasTextureArraysSupport()) { Graphics()->QuadsSetSubsetFree(x0, y0, x1, y1, x2, y2, x3, y3, Index); IGraphics::CQuadItem QuadItem(x * Scale, y * Scale, Scale, Scale); @@ -673,7 +700,7 @@ void CRenderTools::RenderTilemap(CTile *pTiles, int w, int h, float Scale, Color } } - if(Graphics()->IsTileBufferingEnabled()) + if(Graphics()->HasTextureArraysSupport()) Graphics()->QuadsTex3DEnd(); else Graphics()->QuadsEnd(); @@ -918,7 +945,10 @@ void CRenderTools::RenderTelemap(CTeleTile *pTele, int w, int h, float Scale, Co float FinalTileSize = Scale / (ScreenX1 - ScreenX0) * Graphics()->ScreenWidth(); float FinalTilesetScale = FinalTileSize / TilePixelSize; - Graphics()->QuadsBegin(); + if(Graphics()->HasTextureArraysSupport()) + Graphics()->QuadsTex3DBegin(); + else + Graphics()->QuadsBegin(); Graphics()->SetColor(Color); int StartY = (int)(ScreenY0 / Scale) - 1; @@ -987,14 +1017,38 @@ void CRenderTools::RenderTelemap(CTeleTile *pTele, int w, int h, float Scale, Co float x3 = Nudge + Px0 / TexSize + Frac; float y3 = Nudge + Py1 / TexSize - Frac; - Graphics()->QuadsSetSubsetFree(x0, y0, x1, y1, x2, y2, x3, y3); - IGraphics::CQuadItem QuadItem(x * Scale, y * Scale, Scale, Scale); - Graphics()->QuadsDrawTL(&QuadItem, 1); + if(Graphics()->HasTextureArraysSupport()) + { + x0 = 0; + y0 = 0; + x1 = x0 + 1; + y1 = y0; + x2 = x0 + 1; + y2 = y0 + 1; + x3 = x0; + y3 = y0 + 1; + } + + if(Graphics()->HasTextureArraysSupport()) + { + Graphics()->QuadsSetSubsetFree(x0, y0, x1, y1, x2, y2, x3, y3, Index); + IGraphics::CQuadItem QuadItem(x * Scale, y * Scale, Scale, Scale); + Graphics()->QuadsTex3DDrawTL(&QuadItem, 1); + } + else + { + Graphics()->QuadsSetSubsetFree(x0, y0, x1, y1, x2, y2, x3, y3); + IGraphics::CQuadItem QuadItem(x * Scale, y * Scale, Scale, Scale); + Graphics()->QuadsDrawTL(&QuadItem, 1); + } } } } - Graphics()->QuadsEnd(); + if(Graphics()->HasTextureArraysSupport()) + Graphics()->QuadsTex3DEnd(); + else + Graphics()->QuadsEnd(); Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1); } @@ -1010,7 +1064,10 @@ void CRenderTools::RenderSpeedupmap(CSpeedupTile *pSpeedupTile, int w, int h, fl float FinalTileSize = Scale / (ScreenX1 - ScreenX0) * Graphics()->ScreenWidth(); float FinalTilesetScale = FinalTileSize / TilePixelSize; - Graphics()->QuadsBegin(); + if(Graphics()->HasTextureArraysSupport()) + Graphics()->QuadsTex3DBegin(); + else + Graphics()->QuadsBegin(); Graphics()->SetColor(Color); int StartY = (int)(ScreenY0 / Scale) - 1; @@ -1079,14 +1136,38 @@ void CRenderTools::RenderSpeedupmap(CSpeedupTile *pSpeedupTile, int w, int h, fl float x3 = Nudge + Px0 / TexSize + Frac; float y3 = Nudge + Py1 / TexSize - Frac; - Graphics()->QuadsSetSubsetFree(x0, y0, x1, y1, x2, y2, x3, y3); - IGraphics::CQuadItem QuadItem(x * Scale, y * Scale, Scale, Scale); - Graphics()->QuadsDrawTL(&QuadItem, 1); + if(Graphics()->HasTextureArraysSupport()) + { + x0 = 0; + y0 = 0; + x1 = x0 + 1; + y1 = y0; + x2 = x0 + 1; + y2 = y0 + 1; + x3 = x0; + y3 = y0 + 1; + } + + if(Graphics()->HasTextureArraysSupport()) + { + Graphics()->QuadsSetSubsetFree(x0, y0, x1, y1, x2, y2, x3, y3, Index); + IGraphics::CQuadItem QuadItem(x * Scale, y * Scale, Scale, Scale); + Graphics()->QuadsTex3DDrawTL(&QuadItem, 1); + } + else + { + Graphics()->QuadsSetSubsetFree(x0, y0, x1, y1, x2, y2, x3, y3); + IGraphics::CQuadItem QuadItem(x * Scale, y * Scale, Scale, Scale); + Graphics()->QuadsDrawTL(&QuadItem, 1); + } } } } - Graphics()->QuadsEnd(); + if(Graphics()->HasTextureArraysSupport()) + Graphics()->QuadsTex3DEnd(); + else + Graphics()->QuadsEnd(); Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1); } @@ -1102,7 +1183,10 @@ void CRenderTools::RenderSwitchmap(CSwitchTile *pSwitchTile, int w, int h, float float FinalTileSize = Scale / (ScreenX1 - ScreenX0) * Graphics()->ScreenWidth(); float FinalTilesetScale = FinalTileSize / TilePixelSize; - Graphics()->QuadsBegin(); + if(Graphics()->HasTextureArraysSupport()) + Graphics()->QuadsTex3DBegin(); + else + Graphics()->QuadsBegin(); Graphics()->SetColor(Color); int StartY = (int)(ScreenY0 / Scale) - 1; @@ -1184,6 +1268,18 @@ void CRenderTools::RenderSwitchmap(CSwitchTile *pSwitchTile, int w, int h, float float x3 = Nudge + Px0 / TexSize + Frac; float y3 = Nudge + Py1 / TexSize - Frac; + if(Graphics()->HasTextureArraysSupport()) + { + x0 = 0; + y0 = 0; + x1 = x0 + 1; + y1 = y0; + x2 = x0 + 1; + y2 = y0 + 1; + x3 = x0; + y3 = y0 + 1; + } + if(Flags & TILEFLAG_XFLIP) { x0 = x2; @@ -1214,14 +1310,26 @@ void CRenderTools::RenderSwitchmap(CSwitchTile *pSwitchTile, int w, int h, float y1 = Tmp; } - Graphics()->QuadsSetSubsetFree(x0, y0, x1, y1, x2, y2, x3, y3); - IGraphics::CQuadItem QuadItem(x * Scale, y * Scale, Scale, Scale); - Graphics()->QuadsDrawTL(&QuadItem, 1); + if(Graphics()->HasTextureArraysSupport()) + { + Graphics()->QuadsSetSubsetFree(x0, y0, x1, y1, x2, y2, x3, y3, Index); + IGraphics::CQuadItem QuadItem(x * Scale, y * Scale, Scale, Scale); + Graphics()->QuadsTex3DDrawTL(&QuadItem, 1); + } + else + { + Graphics()->QuadsSetSubsetFree(x0, y0, x1, y1, x2, y2, x3, y3); + IGraphics::CQuadItem QuadItem(x * Scale, y * Scale, Scale, Scale); + Graphics()->QuadsDrawTL(&QuadItem, 1); + } } } } - Graphics()->QuadsEnd(); + if(Graphics()->HasTextureArraysSupport()) + Graphics()->QuadsTex3DEnd(); + else + Graphics()->QuadsEnd(); Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1); } @@ -1235,7 +1343,10 @@ void CRenderTools::RenderTunemap(CTuneTile *pTune, int w, int h, float Scale, Co float FinalTileSize = Scale / (ScreenX1 - ScreenX0) * Graphics()->ScreenWidth(); float FinalTilesetScale = FinalTileSize / TilePixelSize; - Graphics()->QuadsBegin(); + if(Graphics()->HasTextureArraysSupport()) + Graphics()->QuadsTex3DBegin(); + else + Graphics()->QuadsBegin(); Graphics()->SetColor(Color); int StartY = (int)(ScreenY0 / Scale) - 1; @@ -1304,13 +1415,37 @@ void CRenderTools::RenderTunemap(CTuneTile *pTune, int w, int h, float Scale, Co float x3 = Nudge + Px0 / TexSize + Frac; float y3 = Nudge + Py1 / TexSize - Frac; - Graphics()->QuadsSetSubsetFree(x0, y0, x1, y1, x2, y2, x3, y3); - IGraphics::CQuadItem QuadItem(x * Scale, y * Scale, Scale, Scale); - Graphics()->QuadsDrawTL(&QuadItem, 1); + if(Graphics()->HasTextureArraysSupport()) + { + x0 = 0; + y0 = 0; + x1 = x0 + 1; + y1 = y0; + x2 = x0 + 1; + y2 = y0 + 1; + x3 = x0; + y3 = y0 + 1; + } + + if(Graphics()->HasTextureArraysSupport()) + { + Graphics()->QuadsSetSubsetFree(x0, y0, x1, y1, x2, y2, x3, y3, Index); + IGraphics::CQuadItem QuadItem(x * Scale, y * Scale, Scale, Scale); + Graphics()->QuadsTex3DDrawTL(&QuadItem, 1); + } + else + { + Graphics()->QuadsSetSubsetFree(x0, y0, x1, y1, x2, y2, x3, y3); + IGraphics::CQuadItem QuadItem(x * Scale, y * Scale, Scale, Scale); + Graphics()->QuadsDrawTL(&QuadItem, 1); + } } } } - Graphics()->QuadsEnd(); + if(Graphics()->HasTextureArraysSupport()) + Graphics()->QuadsTex3DEnd(); + else + Graphics()->QuadsEnd(); Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1); } diff --git a/src/game/editor/editor.cpp b/src/game/editor/editor.cpp index adbf16d25..951cfee20 100644 --- a/src/game/editor/editor.cpp +++ b/src/game/editor/editor.cpp @@ -3941,7 +3941,7 @@ bool CEditor::ReplaceImage(const char *pFileName, int StorageType, bool CheckDup } pImg->m_AutoMapper.Load(pImg->m_aName); - int TextureLoadFlag = Graphics()->HasTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE; + int TextureLoadFlag = Graphics()->Uses2DTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE; if(ImgInfo.m_Width % 16 != 0 || ImgInfo.m_Height % 16 != 0) TextureLoadFlag = 0; pImg->m_Texture = Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, TextureLoadFlag, pFileName); @@ -4000,7 +4000,7 @@ bool CEditor::AddImage(const char *pFileName, int StorageType, void *pUser) DilateImage((unsigned char *)ImgInfo.m_pData, ImgInfo.m_Width, ImgInfo.m_Height); } - int TextureLoadFlag = pEditor->Graphics()->HasTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE; + int TextureLoadFlag = pEditor->Graphics()->Uses2DTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE; if(ImgInfo.m_Width % 16 != 0 || ImgInfo.m_Height % 16 != 0) TextureLoadFlag = 0; pImg->m_Texture = pEditor->Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, TextureLoadFlag, pFileName); @@ -7561,7 +7561,7 @@ void CEditor::Reset(bool CreateDefault) int CEditor::GetTextureUsageFlag() { - return Graphics()->HasTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE; + return Graphics()->Uses2DTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE; } IGraphics::CTextureHandle CEditor::GetFrontTexture() diff --git a/src/game/editor/mapitems/map_io.cpp b/src/game/editor/mapitems/map_io.cpp index e054737e3..30a88ee40 100644 --- a/src/game/editor/mapitems/map_io.cpp +++ b/src/game/editor/mapitems/map_io.cpp @@ -505,7 +505,7 @@ bool CEditorMap::Load(const char *pFileName, int StorageType, const std::functio pImg->m_Height = ImgInfo.m_Height; pImg->m_Format = ImgInfo.m_Format; pImg->m_pData = ImgInfo.m_pData; - int TextureLoadFlag = m_pEditor->Graphics()->HasTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE; + int TextureLoadFlag = m_pEditor->Graphics()->Uses2DTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE; if(ImgInfo.m_Width % 16 != 0 || ImgInfo.m_Height % 16 != 0) TextureLoadFlag = 0; pImg->m_Texture = m_pEditor->Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, TextureLoadFlag, aBuf); @@ -524,7 +524,7 @@ bool CEditorMap::Load(const char *pFileName, int StorageType, const std::functio const size_t DataSize = (size_t)pImg->m_Width * pImg->m_Height * CImageInfo::PixelSize(Format); pImg->m_pData = malloc(DataSize); mem_copy(pImg->m_pData, pData, DataSize); - int TextureLoadFlag = m_pEditor->Graphics()->HasTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE; + int TextureLoadFlag = m_pEditor->Graphics()->Uses2DTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE; if(pImg->m_Width % 16 != 0 || pImg->m_Height % 16 != 0) TextureLoadFlag = 0; pImg->m_Texture = m_pEditor->Graphics()->LoadTextureRaw(pImg->m_Width, pImg->m_Height, pImg->m_Format, pImg->m_pData, TextureLoadFlag); diff --git a/src/game/editor/tileart.cpp b/src/game/editor/tileart.cpp index e6e88ef97..da96fdcff 100644 --- a/src/game/editor/tileart.cpp +++ b/src/game/editor/tileart.cpp @@ -154,7 +154,7 @@ static std::shared_ptr ImageInfoToEditorImage(CEditor *pEditor, co pEditorImage->m_Format = Image.m_Format; pEditorImage->m_pData = Image.m_pData; - int TextureLoadFlag = pEditor->Graphics()->HasTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE; + int TextureLoadFlag = pEditor->Graphics()->Uses2DTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE; pEditorImage->m_Texture = pEditor->Graphics()->LoadTextureRaw(Image.m_Width, Image.m_Height, Image.m_Format, Image.m_pData, TextureLoadFlag, pName); pEditorImage->m_External = 0; str_copy(pEditorImage->m_aName, pName);