1
0
forked from 0ad/0ad

Implements DrawTexture in Canvas2D.

This was SVN commit r25593.
This commit is contained in:
Vladislav Belov 2021-05-29 22:30:23 +00:00
parent dacbab8b02
commit df7cabd653
5 changed files with 108 additions and 28 deletions

View File

@ -30,6 +30,38 @@
#include <array>
namespace
{
// Array of 2D elements unrolled into 1D array.
using PlaneArray2D = std::array<float, 8>;
void DrawTextureImpl(CTexturePtr texture,
const PlaneArray2D& vertices, const PlaneArray2D& uvs,
const CColor& multiply, const CColor& add)
{
CShaderDefines defines;
CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect(
str_canvas2d, g_Renderer.GetSystemShaderDefines(), defines);
tech->BeginPass();
CShaderProgramPtr shader = tech->GetShader();
shader->BindTexture(str_tex, texture);
shader->Uniform(str_transform, GetDefaultGuiMatrix());
shader->Uniform(str_colorAdd, add);
shader->Uniform(str_colorMul, multiply);
shader->VertexPointer(2, GL_FLOAT, 0, vertices.data());
shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 0, uvs.data());
shader->AssertPointersBound();
if (!g_Renderer.DoSkipSubmit())
glDrawArrays(GL_TRIANGLE_FAN, 0, vertices.size() / 2);
tech->EndPass();
}
} // anonymous namespace
void CCanvas2D::DrawLine(const std::vector<CVector2D>& points, const float width, const CColor& color)
{
std::vector<float> vertices;
@ -69,32 +101,51 @@ void CCanvas2D::DrawLine(const std::vector<CVector2D>& points, const float width
void CCanvas2D::DrawRect(const CRect& rect, const CColor& color)
{
const std::array<float, 8> uvs = {
const PlaneArray2D uvs = {
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f
};
const std::array<float, 8> vertices = {
const PlaneArray2D vertices = {
rect.left, rect.bottom,
rect.right, rect.bottom,
rect.right, rect.top,
rect.left, rect.top
};
CShaderDefines defines;
CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect(
str_canvas2d, g_Renderer.GetSystemShaderDefines(), defines);
tech->BeginPass();
CShaderProgramPtr shader = tech->GetShader();
shader->BindTexture(str_tex, g_Renderer.GetTextureManager().GetTransparentTexture());
shader->Uniform(str_transform, GetDefaultGuiMatrix());
shader->Uniform(str_colorAdd, color);
shader->Uniform(str_colorMul, CColor(0.0f, 0.0f, 0.0f, 0.0f));
shader->VertexPointer(2, GL_FLOAT, 0, vertices.data());
shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 0, uvs.data());
shader->AssertPointersBound();
if (!g_Renderer.DoSkipSubmit())
glDrawArrays(GL_TRIANGLE_FAN, 0, vertices.size() / 2);
tech->EndPass();
DrawTextureImpl(
g_Renderer.GetTextureManager().GetTransparentTexture(),
vertices, uvs, CColor(0.0f, 0.0f, 0.0f, 0.0f), color);
}
void CCanvas2D::DrawTexture(CTexturePtr texture, const CRect& destination)
{
DrawTexture(texture,
destination, CRect(0, 0, texture->GetWidth(), texture->GetHeight()),
CColor(1.0f, 1.0f, 1.0f, 1.0f), CColor(0.0f, 0.0f, 0.0f, 0.0f));
}
void CCanvas2D::DrawTexture(
CTexturePtr texture, const CRect& destination, const CRect& source,
const CColor& multiply, const CColor& add)
{
PlaneArray2D uvs = {
source.left, source.bottom,
source.right, source.bottom,
source.right, source.top,
source.left, source.top
};
for (size_t idx = 0; idx < uvs.size() / 2; idx += 2)
{
uvs[idx + 0] /= texture->GetWidth();
uvs[idx + 1] /= texture->GetHeight();
}
const PlaneArray2D vertices = {
destination.left, destination.bottom,
destination.right, destination.bottom,
destination.right, destination.top,
destination.left, destination.top
};
DrawTextureImpl(
g_Renderer.GetTextureManager().GetTransparentTexture(),
vertices, uvs, multiply, add);
}

View File

@ -18,6 +18,7 @@
#ifndef INCLUDED_CANVAS2D
#define INCLUDED_CANVAS2D
#include "graphics/Texture.h"
#include "maths/Vector2D.h"
#include <vector>
@ -31,9 +32,32 @@ struct CColor;
class CCanvas2D
{
public:
void DrawLine(const std::vector<CVector2D>& points, const float width, const CColor& color);
/**
* Draws a line by the given points with the width and color.
*/
void DrawLine(
const std::vector<CVector2D>& points,
const float width, const CColor& color);
/**
* Draws the rect filled with the color.
*/
void DrawRect(const CRect& rect, const CColor& color);
/**
* Draws a piece of the texture from the source rect into the
* destination rect. The result color is set by the following formula:
* TEXTURE_COLOR * COLOR_MULTIPLY + COLOR_ADD
*/
void DrawTexture(CTexturePtr texture,
const CRect& destination, const CRect& source,
const CColor& multiply, const CColor& add);
/**
* A simpler version of the previous one, draws the texture into the
* destination rect without color modifications.
*/
void DrawTexture(CTexturePtr texture, const CRect& destination);
};
#endif // INCLUDED_CANVAS2D

View File

@ -213,24 +213,22 @@ void GUIRenderer::UpdateDrawCallCache(const CGUI& pGUI, DrawCalls& Calls, const
texture->Prefetch();
Call.m_HasTexture = true;
Call.m_Texture = texture;
Call.m_EnableBlending = false; // will be overridden if the texture has an alpha channel
Call.m_ObjectSize = ObjectSize;
}
else
{
Call.m_HasTexture = false;
// Enable blending if it's transparent (allowing a little error in the calculations)
Call.m_EnableBlending = !(fabs((*cit)->m_BackColor.a - 1.0f) < 0.0000001f);
Call.m_EnableBlending = true;
}
Call.m_BackColor = &(*cit)->m_BackColor;
if (!Call.m_HasTexture)
{
Call.m_Shader = g_Renderer.GetShaderManager().LoadEffect(str_gui_solid);
Call.m_Material = str_gui_solid;
Call.m_ColorAdd = *Call.m_BackColor;
Call.m_ColorMultiply = CColor(0.0f, 0.0f, 0.0f, 0.0f);
Call.m_Texture = g_Renderer.GetTextureManager().GetTransparentTexture();
}
else if ((*cit)->m_Effects)
{
@ -406,7 +404,9 @@ void GUIRenderer::Draw(DrawCalls& Calls, CCanvas2D& canvas)
std::swap(rect.right, rect.left);
if (rect.bottom < rect.top)
std::swap(rect.bottom, rect.top);
canvas.DrawRect(rect, *(cit->m_BackColor));
canvas.DrawTexture(cit->m_Texture,
rect, CRect(0, 0, cit->m_Texture->GetWidth(), cit->m_Texture->GetHeight()),
cit->m_ColorMultiply, cit->m_ColorAdd);
if (cit->m_EnableBlending)
glDisable(GL_BLEND);

View File

@ -60,6 +60,9 @@ namespace GUIRenderer
// Temporary type to make a soft transition to canvas rendering.
CStrIntern m_Material;
CColor m_ColorAdd;
CColor m_ColorMultiply;
};
class DrawCalls : public std::vector<SDrawCall>

View File

@ -233,6 +233,8 @@ void CConsole::DrawWindow()
CVector2D{0.0f, m_fHeight - static_cast<float>(m_iFontHeight) - 4.0f},
CVector2D{m_fWidth, m_fHeight - static_cast<float>(m_iFontHeight) - 4.0f}
};
for (CVector2D& point : points)
point += CVector2D{m_fX, m_fY - (1.0f - m_fVisibleFrac) * m_fHeight};
canvas.DrawLine(points, 1.0f, CColor(0.5f, 0.5f, 0.0f, 0.6f));
}
}