diff --git a/Source/Client/Mode/CMode.h b/Source/Client/Mode/CMode.h index 0b58e14..4d36419 100644 --- a/Source/Client/Mode/CMode.h +++ b/Source/Client/Mode/CMode.h @@ -5,7 +5,10 @@ #include #include +class CTexture; class UIWindow; +struct TextureRegion; +struct tagRECT; class CMode { public: @@ -36,6 +39,7 @@ public: virtual void Slot7(int value); CMode(); + void DrawTexture(const tagRECT& rect, int angle, float rhw, std::uint32_t color, CTexture* texture, TextureRegion region); }; #if defined(_WIN32) && !defined(_WIN64) diff --git a/Source/Render/TextureQuad.cpp b/Source/Render/TextureQuad.cpp index b8be6bf..5587dd8 100644 --- a/Source/Render/TextureQuad.cpp +++ b/Source/Render/TextureQuad.cpp @@ -1,7 +1,88 @@ +#include "Client/Mode/CMode.h" +#include "Render/Primitives/RenderPrimitivePool.h" +#include "Render/Primitives/RenderQueues.h" +#include "Render/Renderer.h" #include "Render/TextureQuad.h" +#include "Render/Textures/Texture.h" +#include "Utility/Math/AffineMatrix.h" + +#include + +// GLOBAL: gl_24520 +float g_depthStart; +// GLOBAL: gl_24521 +float g_depthEnd; // OFFSET: 0x0055D310 // FUNCTION: fn_02101 float RhwToDepth(float rhw) { return ((1.0f / rhw - 10.0f) * 1.0067114f) * rhw; } + +// OFFSET: 0x00AD5FA0 +// FUNCTION: fn_17826 +void CMode::DrawTexture(const RECT& rect, int angle, float rhw, std::uint32_t color, CTexture* texture, TextureRegion region) { + RenderPrimitive* primitive = g_renderer->primitives.Acquire(); + RenderVertex* vertices = primitive->vertices; + primitive->texture = texture; + const float bottomZ = RhwToDepth(rhw); + const float topZ = RhwToDepth(rhw); + + if (angle != 0) { + const float cosine = ClientCosine(angle); + const float sine = ClientSine(angle); + const float width = static_cast(rect.right - rect.left); + const float height = static_cast(rect.bottom - rect.top); + const float right = width * 0.5f; + const float bottom = height * 0.5f; + const float centerX = static_cast(rect.left) + right; + const float centerY = static_cast(rect.top) + bottom; + const float left = -width * 0.5f; + const float top = -height * 0.5f; + + vertices[0].x = left * cosine - top * sine + centerX; + vertices[0].y = top * cosine + left * sine + centerY; + vertices[1].x = right * cosine - top * sine + centerX; + vertices[1].y = right * sine + top * cosine + centerY; + vertices[2].x = left * cosine - bottom * sine + centerX; + vertices[3].x = right * cosine - bottom * sine + centerX; + vertices[2].y = bottom * cosine + left * sine + centerY; + vertices[3].y = bottom * cosine + right * sine + centerY; + } else { + vertices[0].x = static_cast(rect.left); + vertices[0].y = static_cast(rect.top); + vertices[1].x = static_cast(rect.right); + vertices[1].y = static_cast(rect.top); + vertices[2].x = static_cast(rect.left); + vertices[2].y = static_cast(rect.bottom); + vertices[3].x = static_cast(rect.right); + vertices[3].y = static_cast(rect.bottom); + } + + const float scaleU = static_cast(texture->ImageWidth()) / static_cast(texture->TextureWidth()); + const float scaleV = static_cast(texture->ImageHeight()) / static_cast(texture->TextureHeight()); + const float margin = 0.0f; + + vertices[0].z = topZ; + vertices[0].rhw = rhw; + vertices[0].diffuse = color; + vertices[0].u = region.left * scaleU + margin; + vertices[0].v = region.top * scaleV + margin; + vertices[1].z = topZ; + vertices[1].rhw = rhw; + vertices[1].diffuse = color; + vertices[1].u = region.right * scaleU - margin; + vertices[1].v = region.top * scaleV + margin; + vertices[2].z = bottomZ; + vertices[2].rhw = rhw; + vertices[2].diffuse = color; + vertices[2].u = region.left * scaleU + margin; + vertices[2].v = region.bottom * scaleV - margin; + vertices[3].z = bottomZ; + vertices[3].rhw = rhw; + vertices[3].diffuse = color; + vertices[3].u = region.right * scaleU - margin; + vertices[3].v = region.bottom * scaleV - margin; + + g_renderer->queues.Submit(primitive, 0x201, g_renderer->fog.supported != 0, g_depthStart, g_depthEnd); +} diff --git a/Source/Render/TextureQuad.h b/Source/Render/TextureQuad.h index 735915e..8e227fe 100644 --- a/Source/Render/TextureQuad.h +++ b/Source/Render/TextureQuad.h @@ -1,6 +1,16 @@ #ifndef RAGNAROK_SOURCE_RENDER_TEXTUREQUAD_H #define RAGNAROK_SOURCE_RENDER_TEXTUREQUAD_H +struct TextureRegion { + /* 0000 */ float left; + /* 0004 */ float top; + /* 0008 */ float right; + /* 000C */ float bottom; +}; + +extern float g_depthStart; +extern float g_depthEnd; + float RhwToDepth(float rhw); #endif diff --git a/Source/Render/Textures/Texture.h b/Source/Render/Textures/Texture.h index 9399b9b..51140e3 100644 --- a/Source/Render/Textures/Texture.h +++ b/Source/Render/Textures/Texture.h @@ -42,6 +42,14 @@ public: return this->m_textureHeight; } // INLINED + std::uint32_t ImageWidth() const { + return this->m_width; + } + // INLINED + std::uint32_t ImageHeight() const { + return this->m_height; + } + // INLINED std::int32_t Format() const { return this->m_format; }