diff --git a/src/rendering/polyrenderer/backend/poly_renderstate.cpp b/src/rendering/polyrenderer/backend/poly_renderstate.cpp index 046a5c4671..56ea11a33e 100644 --- a/src/rendering/polyrenderer/backend/poly_renderstate.cpp +++ b/src/rendering/polyrenderer/backend/poly_renderstate.cpp @@ -233,7 +233,7 @@ void PolyRenderState::ApplyMaterial() if (base) { DCanvas *texcanvas = base->GetImage(mMaterial); - PolyTriangleDrawer::SetTexture(GetPolyFrameBuffer()->GetDrawCommands(), 0, texcanvas->GetPixels(), texcanvas->GetHeight(), texcanvas->GetWidth()); + PolyTriangleDrawer::SetTexture(GetPolyFrameBuffer()->GetDrawCommands(), 0, texcanvas->GetPixels(), texcanvas->GetHeight(), texcanvas->GetWidth(), texcanvas->IsBgra()); int numLayers = mMaterial.mMaterial->GetLayers(); for (int i = 1; i < numLayers; i++) @@ -242,7 +242,7 @@ void PolyRenderState::ApplyMaterial() auto systex = static_cast(mMaterial.mMaterial->GetLayer(i, 0, &layer)); texcanvas = systex->GetImage(mMaterial); - PolyTriangleDrawer::SetTexture(GetPolyFrameBuffer()->GetDrawCommands(), i, texcanvas->GetPixels(), texcanvas->GetHeight(), texcanvas->GetWidth()); + PolyTriangleDrawer::SetTexture(GetPolyFrameBuffer()->GetDrawCommands(), i, texcanvas->GetPixels(), texcanvas->GetHeight(), texcanvas->GetWidth(), texcanvas->IsBgra()); } } diff --git a/src/rendering/polyrenderer/drawers/poly_triangle.cpp b/src/rendering/polyrenderer/drawers/poly_triangle.cpp index 965214aad8..5cae9821c4 100644 --- a/src/rendering/polyrenderer/drawers/poly_triangle.cpp +++ b/src/rendering/polyrenderer/drawers/poly_triangle.cpp @@ -153,9 +153,9 @@ void PolyTriangleDrawer::SetRenderStyle(const DrawerCommandQueuePtr &queue, FRen queue->Push(style); } -void PolyTriangleDrawer::SetTexture(const DrawerCommandQueuePtr &queue, int unit, void *pixels, int width, int height) +void PolyTriangleDrawer::SetTexture(const DrawerCommandQueuePtr &queue, int unit, void *pixels, int width, int height, bool bgra) { - queue->Push(unit, pixels, width, height); + queue->Push(unit, pixels, width, height, bgra); } void PolyTriangleDrawer::SetShader(const DrawerCommandQueuePtr &queue, int specialEffect, int effectState, bool alphaTest) @@ -408,9 +408,9 @@ void PolyTriangleThreadData::SetShader(int specialEffect, int effectState, bool AlphaTest = alphaTest; } -void PolyTriangleThreadData::SetTexture(int unit, void *pixels, int width, int height) +void PolyTriangleThreadData::SetTexture(int unit, const void *pixels, int width, int height, bool bgra) { - textures[unit].pixels = (uint8_t*)pixels; + textures[unit].pixels = pixels; textures[unit].width = width; textures[unit].height = height; textures[unit].bgra = true; diff --git a/src/rendering/polyrenderer/drawers/poly_triangle.h b/src/rendering/polyrenderer/drawers/poly_triangle.h index 9b30e478ac..f5a3519947 100644 --- a/src/rendering/polyrenderer/drawers/poly_triangle.h +++ b/src/rendering/polyrenderer/drawers/poly_triangle.h @@ -65,7 +65,7 @@ public: static void SetScissor(const DrawerCommandQueuePtr &queue, int x, int y, int w, int h); static void EnableDepthTest(const DrawerCommandQueuePtr &queue, bool on); static void SetRenderStyle(const DrawerCommandQueuePtr &queue, FRenderStyle style); - static void SetTexture(const DrawerCommandQueuePtr &queue, int unit, void *pixels, int width, int height); + static void SetTexture(const DrawerCommandQueuePtr &queue, int unit, void *pixels, int width, int height, bool bgra); static void SetShader(const DrawerCommandQueuePtr &queue, int specialEffect, int effectState, bool alphaTest); static void PushStreamData(const DrawerCommandQueuePtr &queue, const StreamData &data, const PolyPushConstants &constants); static void PushMatrices(const DrawerCommandQueuePtr &queue, const VSMatrix &modelMatrix, const VSMatrix &normalModelMatrix, const VSMatrix &textureMatrix); @@ -149,7 +149,7 @@ public: void SetScissor(int x, int y, int w, int h); void EnableDepthTest(bool on); void SetRenderStyle(FRenderStyle style); - void SetTexture(int unit, void *pixels, int width, int height); + void SetTexture(int unit, const void *pixels, int width, int height, bool bgra); void SetShader(int specialEffect, int effectState, bool alphaTest); void UpdateClip(); @@ -245,7 +245,7 @@ public: struct TextureUnit { - const uint8_t* pixels = nullptr; + const void* pixels = nullptr; int width = 0; int height = 0; bool bgra = true; @@ -429,14 +429,15 @@ private: class PolySetTextureCommand : public PolyDrawerCommand { public: - PolySetTextureCommand(int unit, void *pixels, int width, int height) : unit(unit), pixels(pixels), width(width), height(height) { } - void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->SetTexture(unit, pixels, width, height); } + PolySetTextureCommand(int unit, void *pixels, int width, int height, bool bgra) : unit(unit), pixels(pixels), width(width), height(height), bgra(bgra) { } + void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->SetTexture(unit, pixels, width, height, bgra); } private: int unit; void *pixels; int width; int height; + bool bgra; }; class PolySetShaderCommand : public PolyDrawerCommand diff --git a/src/rendering/polyrenderer/drawers/screen_triangle.cpp b/src/rendering/polyrenderer/drawers/screen_triangle.cpp index 91248c7df7..d1a2ae6211 100644 --- a/src/rendering/polyrenderer/drawers/screen_triangle.cpp +++ b/src/rendering/polyrenderer/drawers/screen_triangle.cpp @@ -351,11 +351,20 @@ static float wrap(float value) } #endif -static uint32_t sampleTexture(float u, float v, const uint32_t* texPixels, int texWidth, int texHeight) +static uint32_t sampleTexture(float u, float v, const void* texPixels, int texWidth, int texHeight, bool texBgra) { int texelX = MIN(static_cast(wrap(u) * texWidth), texWidth - 1); int texelY = MIN(static_cast(wrap(v) * texHeight), texHeight - 1); - return texPixels[texelX * texHeight + texelY]; + int texelOffset = texelX * texHeight + texelY; + if (texBgra) + { + return static_cast(texPixels)[texelOffset]; + } + else + { + uint32_t c = static_cast(texPixels)[texelOffset]; + return c | 0xff000000; + } } static void RunShader(int x0, int x1, PolyTriangleThreadData* thread) @@ -377,11 +386,13 @@ static void RunShader(int x0, int x1, PolyTriangleThreadData* thread) { int texWidth = thread->textures[0].width; int texHeight = thread->textures[0].height; - const uint32_t* texPixels = (const uint32_t*)thread->textures[0].pixels; + const void* texPixels = thread->textures[0].pixels; + bool texBgra = thread->textures[0].bgra; int tex2Width = thread->textures[1].width; int tex2Height = thread->textures[1].height; - const uint32_t* tex2Pixels = (const uint32_t*)thread->textures[1].pixels; + const void* tex2Pixels = thread->textures[1].pixels; + bool tex2Bgra = thread->textures[1].bgra; uint32_t frag = thread->mainVertexShader.vColor; uint32_t frag_r = RPART(frag); @@ -394,8 +405,8 @@ static void RunShader(int x0, int x1, PolyTriangleThreadData* thread) frag_a += frag_a >> 7; // 255 -> 256 for (int x = x0; x < x1; x++) { - uint32_t t1 = sampleTexture(u[x], v[x], texPixels, texWidth, texHeight); - uint32_t t2 = sampleTexture(u[x], 1.0f - v[x], tex2Pixels, tex2Width, tex2Height); + uint32_t t1 = sampleTexture(u[x], v[x], texPixels, texWidth, texHeight, texBgra); + uint32_t t2 = sampleTexture(u[x], 1.0f - v[x], tex2Pixels, tex2Width, tex2Height, tex2Bgra); uint32_t r = (frag_r * RPART(t1)) >> 8; uint32_t g = (frag_g * GPART(t1)) >> 8; @@ -443,7 +454,8 @@ static void RunShader(int x0, int x1, PolyTriangleThreadData* thread) { int texWidth = thread->textures[0].width; int texHeight = thread->textures[0].height; - const uint32_t* texPixels = (const uint32_t*)thread->textures[0].pixels; + const void* texPixels = thread->textures[0].pixels; + bool texBgra = thread->textures[0].bgra; switch (constants->uTextureMode) { @@ -452,35 +464,35 @@ static void RunShader(int x0, int x1, PolyTriangleThreadData* thread) case TM_FOGLAYER: for (int x = x0; x < x1; x++) { - uint32_t texel = sampleTexture(u[x], v[x], texPixels, texWidth, texHeight); + uint32_t texel = sampleTexture(u[x], v[x], texPixels, texWidth, texHeight, texBgra); fragcolor[x] = texel; } break; case TM_STENCIL: // TM_STENCIL for (int x = x0; x < x1; x++) { - uint32_t texel = sampleTexture(u[x], v[x], texPixels, texWidth, texHeight); + uint32_t texel = sampleTexture(u[x], v[x], texPixels, texWidth, texHeight, texBgra); fragcolor[x] = texel | 0x00ffffff; } break; case TM_OPAQUE: for (int x = x0; x < x1; x++) { - uint32_t texel = sampleTexture(u[x], v[x], texPixels, texWidth, texHeight); + uint32_t texel = sampleTexture(u[x], v[x], texPixels, texWidth, texHeight, texBgra); fragcolor[x] = texel | 0xff000000; } break; case TM_INVERSE: for (int x = x0; x < x1; x++) { - uint32_t texel = sampleTexture(u[x], v[x], texPixels, texWidth, texHeight); + uint32_t texel = sampleTexture(u[x], v[x], texPixels, texWidth, texHeight, texBgra); fragcolor[x] = MAKEARGB(APART(texel), 0xff - RPART(texel), 0xff - BPART(texel), 0xff - GPART(texel)); } break; case TM_ALPHATEXTURE: for (int x = x0; x < x1; x++) { - uint32_t texel = sampleTexture(u[x], v[x], texPixels, texWidth, texHeight); + uint32_t texel = sampleTexture(u[x], v[x], texPixels, texWidth, texHeight, texBgra); uint32_t gray = (RPART(texel) * 77 + GPART(texel) * 143 + BPART(texel) * 37) >> 8; uint32_t alpha = APART(texel); alpha += alpha >> 7; @@ -493,7 +505,7 @@ static void RunShader(int x0, int x1, PolyTriangleThreadData* thread) for (int x = x0; x < x1; x++) { if (v[x] >= 0.0 && v[x] <= 1.0) - fragcolor[x] = sampleTexture(u[x], v[x], texPixels, texWidth, texHeight); + fragcolor[x] = sampleTexture(u[x], v[x], texPixels, texWidth, texHeight, texBgra); else fragcolor[x] = 0; } @@ -501,7 +513,7 @@ static void RunShader(int x0, int x1, PolyTriangleThreadData* thread) case TM_INVERTOPAQUE: for (int x = x0; x < x1; x++) { - uint32_t texel = sampleTexture(u[x], v[x], texPixels, texWidth, texHeight); + uint32_t texel = sampleTexture(u[x], v[x], texPixels, texWidth, texHeight, texBgra); fragcolor[x] = MAKEARGB(0xff, 0xff - RPART(texel), 0xff - BPART(texel), 0xff - GPART(texel)); } }