Index: source/graphics/Canvas2D.h =================================================================== --- source/graphics/Canvas2D.h +++ source/graphics/Canvas2D.h @@ -62,15 +62,25 @@ * The texture color is blended with its own grayscale version according to * the grayscale factor. */ - void DrawTexture(CTexturePtr texture, - const CRect& destination, const CRect& source, + void DrawTexture( + const CTexturePtr& texture, const CRect& destination, const CRect& source, const CColor& multiply, const CColor& add, const float grayscaleFactor); /** * A simpler version of the previous one, draws the texture into the * destination rect without color modifications. */ - void DrawTexture(CTexturePtr texture, const CRect& destination); + void DrawTexture(const CTexturePtr& texture, const CRect& destination); + + /** + * A similar to the original one, draws the texture into the + * destination rect but rotates it first around the origin point by angle + * radians (a positive angle denotes a clockwise rotation). + */ + void DrawRotatedTexture( + const CTexturePtr& texture, const CRect& destination, const CRect& source, + const CColor& multiply, const CColor& add, const float grayscaleFactor, + const CVector2D& origin, const float angle); /** * Draws a text using canvas materials. Index: source/graphics/Canvas2D.cpp =================================================================== --- source/graphics/Canvas2D.cpp +++ source/graphics/Canvas2D.cpp @@ -69,11 +69,11 @@ deviceCommandContext->SetVertexAttributeFormat( Renderer::Backend::VertexAttributeStream::POSITION, - Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, + Renderer::Backend::Format::R32G32_SFLOAT, 0, sizeof(float) * 2, Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0); deviceCommandContext->SetVertexAttributeFormat( Renderer::Backend::VertexAttributeStream::UV0, - Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, + Renderer::Backend::Format::R32G32_SFLOAT, 0, sizeof(float) * 2, Renderer::Backend::VertexAttributeRate::PER_VERTEX, 1); deviceCommandContext->SetVertexBufferData( @@ -331,7 +331,7 @@ m->BindingSlots); } -void CCanvas2D::DrawTexture(CTexturePtr texture, const CRect& destination) +void CCanvas2D::DrawTexture(const CTexturePtr& texture, const CRect& destination) { DrawTexture(texture, destination, CRect(0, 0, texture->GetWidth(), texture->GetHeight()), @@ -339,7 +339,7 @@ } void CCanvas2D::DrawTexture( - CTexturePtr texture, const CRect& destination, const CRect& source, + const CTexturePtr& texture, const CRect& destination, const CRect& source, const CColor& multiply, const CColor& add, const float grayscaleFactor) { const PlaneArray2D uvs = @@ -375,6 +375,45 @@ m->BindingSlots.grayscaleFactor, 0.0f); textRenderer.Render(m->DeviceCommandContext, m->Tech->GetShader(), GetDefaultGuiMatrix()); +} + +void CCanvas2D::DrawRotatedTexture( + const CTexturePtr& texture, const CRect& destination, const CRect& source, + const CColor& multiply, const CColor& add, const float grayscaleFactor, + const CVector2D& origin, const float angle) +{ + const PlaneArray2D uvs = + { + source.left, source.bottom, + source.right, source.bottom, + source.right, source.top, + source.left, source.bottom, + source.right, source.top, + source.left, source.top + }; + std::array corners = + { + destination.BottomLeft(), + destination.BottomRight(), + destination.TopRight(), + destination.BottomLeft(), + destination.TopRight(), + destination.TopLeft() + }; + PlaneArray2D vertices; + static_assert(vertices.size() == corners.size() * 2, "We need two coordinates from each corner."); + auto it = vertices.begin(); + for (const CVector2D& corner : corners) + { + const CVector2D vertex = origin + (corner - origin).Rotated(angle); + *it++ = vertex.X; + *it++ = vertex.Y; + } + + m->BindTechIfNeeded(); + DrawTextureImpl( + m->DeviceCommandContext, texture, vertices, uvs, + multiply, add, grayscaleFactor, m->BindingSlots); } void CCanvas2D::Flush() Index: source/graphics/MiniMapTexture.h =================================================================== --- source/graphics/MiniMapTexture.h +++ source/graphics/MiniMapTexture.h @@ -50,7 +50,7 @@ */ void Render(Renderer::Backend::IDeviceCommandContext* deviceCommandContext); - Renderer::Backend::ITexture* GetTexture() const { return m_FinalTexture.get(); } + const CTexturePtr& GetTexture() const { return m_FinalTexture; } /** * @return The maximum height for unit passage in water. @@ -86,7 +86,9 @@ // minimap texture handles std::unique_ptr - m_TerrainTexture, m_FinalTexture; + m_TerrainTexture; + + CTexturePtr m_FinalTexture; std::unique_ptr m_FinalTextureFramebuffer; Index: source/graphics/MiniMapTexture.cpp =================================================================== --- source/graphics/MiniMapTexture.cpp +++ source/graphics/MiniMapTexture.cpp @@ -344,11 +344,13 @@ m_TerrainData = std::make_unique((m_MapSize - 1) * (m_MapSize - 1)); - m_FinalTexture = backendDevice->CreateTexture2D("MiniMapFinalTexture", - Renderer::Backend::Format::R8G8B8A8_UNORM, FINAL_TEXTURE_SIZE, FINAL_TEXTURE_SIZE, defaultSamplerDesc); + m_FinalTexture = g_Renderer.GetTextureManager().WrapBackendTexture( + backendDevice->CreateTexture2D("MiniMapFinalTexture", + Renderer::Backend::Format::R8G8B8A8_UNORM, + FINAL_TEXTURE_SIZE, FINAL_TEXTURE_SIZE, defaultSamplerDesc)); m_FinalTextureFramebuffer = backendDevice->CreateFramebuffer("MiniMapFinalFramebuffer", - m_FinalTexture.get(), nullptr); + m_FinalTexture->GetBackendTexture(), nullptr); ENSURE(m_FinalTextureFramebuffer); } Index: source/gui/ObjectTypes/CMiniMap.cpp =================================================================== --- source/gui/ObjectTypes/CMiniMap.cpp +++ source/gui/ObjectTypes/CMiniMap.cpp @@ -23,15 +23,12 @@ #include "graphics/GameView.h" #include "graphics/MiniMapTexture.h" #include "graphics/MiniPatch.h" -#include "graphics/ShaderManager.h" -#include "graphics/ShaderProgramPtr.h" #include "graphics/Terrain.h" #include "graphics/TerrainTextureEntry.h" #include "graphics/TerrainTextureManager.h" #include "graphics/TextureManager.h" #include "gui/CGUI.h" #include "gui/GUIManager.h" -#include "gui/GUIMatrix.h" #include "lib/bits.h" #include "lib/external_libraries/libsdl.h" #include "lib/timer.h" @@ -45,7 +42,6 @@ #include "ps/Profile.h" #include "ps/World.h" #include "renderer/Renderer.h" -#include "renderer/RenderingOptions.h" #include "renderer/SceneRenderer.h" #include "renderer/WaterManager.h" #include "scriptinterface/Object.h" @@ -93,54 +89,6 @@ } } -void DrawTexture( - Renderer::Backend::IDeviceCommandContext* deviceCommandContext, - float angle, float x, float y, float x2, float y2, float mapScale) -{ - // Rotate the texture coordinates (0,0)-(coordMax,coordMax) around their center point (m,m) - // Scale square maps to fit in circular minimap area - const float s = sin(angle) * mapScale; - const float c = cos(angle) * mapScale; - const float m = 0.5f; - - float quadTex[] = - { - m*(-c + s + 1.f), m*(-c + -s + 1.f), - m*(c + s + 1.f), m*(-c + s + 1.f), - m*(c + -s + 1.f), m*(c + s + 1.f), - - m*(c + -s + 1.f), m*(c + s + 1.f), - m*(-c + -s + 1.f), m*(c + -s + 1.f), - m*(-c + s + 1.f), m*(-c + -s + 1.f) - }; - float quadVerts[] = - { - x, y, 0.0f, - x2, y, 0.0f, - x2, y2, 0.0f, - - x2, y2, 0.0f, - x, y2, 0.0f, - x, y, 0.0f - }; - - deviceCommandContext->SetVertexAttributeFormat( - Renderer::Backend::VertexAttributeStream::POSITION, - Renderer::Backend::Format::R32G32B32_SFLOAT, 0, 0, - Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0); - deviceCommandContext->SetVertexAttributeFormat( - Renderer::Backend::VertexAttributeStream::UV0, - Renderer::Backend::Format::R32G32_SFLOAT, 0, 0, - Renderer::Backend::VertexAttributeRate::PER_VERTEX, 1); - - deviceCommandContext->SetVertexBufferData( - 0, quadVerts, std::size(quadVerts) * sizeof(quadVerts[0])); - deviceCommandContext->SetVertexBufferData( - 1, quadTex, std::size(quadTex) * sizeof(quadTex[0])); - - deviceCommandContext->Draw(0, 6); -} - } // anonymous namespace const CStr CMiniMap::EventNameWorldClick = "WorldClick"; @@ -417,44 +365,16 @@ CMiniMapTexture& miniMapTexture = g_Game->GetView()->GetMiniMapTexture(); if (miniMapTexture.GetTexture()) { - CShaderDefines baseDefines; - baseDefines.Add(str_MINIMAP_BASE, str_1); - - CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect(str_minimap, baseDefines); - Renderer::Backend::GraphicsPipelineStateDesc pipelineStateDesc = - tech->GetGraphicsPipelineStateDesc(); - pipelineStateDesc.blendState.enabled = true; - pipelineStateDesc.blendState.srcColorBlendFactor = pipelineStateDesc.blendState.srcAlphaBlendFactor = - Renderer::Backend::BlendFactor::SRC_ALPHA; - pipelineStateDesc.blendState.dstColorBlendFactor = pipelineStateDesc.blendState.dstAlphaBlendFactor = - Renderer::Backend::BlendFactor::ONE_MINUS_SRC_ALPHA; - pipelineStateDesc.blendState.colorBlendOp = pipelineStateDesc.blendState.alphaBlendOp = - Renderer::Backend::BlendOp::ADD; - Renderer::Backend::IDeviceCommandContext* deviceCommandContext = - g_Renderer.GetDeviceCommandContext(); - deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc); - deviceCommandContext->BeginPass(); - - Renderer::Backend::IShaderProgram* shader = tech->GetShader(); - - deviceCommandContext->SetTexture( - shader->GetBindingSlot(str_baseTex), miniMapTexture.GetTexture()); - - const CMatrix3D baseTransform = GetDefaultGuiMatrix(); - CMatrix3D baseTextureTransform; - baseTextureTransform.SetIdentity(); - - deviceCommandContext->SetUniform( - shader->GetBindingSlot(str_transform), baseTransform.AsFloatArray()); - deviceCommandContext->SetUniform( - shader->GetBindingSlot(str_textureTransform), baseTextureTransform.AsFloatArray()); - - const float x = m_CachedActualSize.left, y = m_CachedActualSize.bottom; - const float x2 = m_CachedActualSize.right, y2 = m_CachedActualSize.top; - const float angle = GetAngle(); - DrawTexture(deviceCommandContext, angle, x, y, x2, y2, m_MapScale); - - deviceCommandContext->EndPass(); + const CVector2D center = m_CachedActualSize.CenterPoint(); + const CRect source( + 0, miniMapTexture.GetTexture()->GetHeight(), + miniMapTexture.GetTexture()->GetWidth(), 0); + const CSize2D size(m_CachedActualSize.GetSize() / m_MapScale); + const CRect destination(center - size / 2.0f, size); + canvas.DrawRotatedTexture( + miniMapTexture.GetTexture(), destination, source, + CColor(1.0f, 1.0f, 1.0f, 1.0f), CColor(0.0f, 0.0f, 0.0f, 0.0f), 0.0f, + center, GetAngle()); } for (const CMiniMapTexture::Icon& icon : miniMapTexture.GetIcons())