Index: ps/trunk/binaries/data/mods/mod/shaders/arb/canvas2d.fp
===================================================================
--- ps/trunk/binaries/data/mods/mod/shaders/arb/canvas2d.fp (revision 25602)
+++ ps/trunk/binaries/data/mods/mod/shaders/arb/canvas2d.fp (revision 25603)
@@ -1,15 +1,27 @@
!!ARBfp1.0
TEMP colorTex;
TEX colorTex, fragment.texcoord[0], texture[0], 2D;
+TEMP grayscale;
+MOV grayscale.r, 0.3;
+MOV grayscale.g, 0.59;
+MOV grayscale.b, 0.11;
+MOV grayscale.a, 0.0;
+
PARAM colorAdd = program.local[1];
PARAM colorMul = program.local[2];
+PARAM grayscaleFactor = program.local[3];
+
+TEMP colorGray;
+DP3 colorGray.rgb, colorTex, grayscale;
+MOV colorGray.a, colorTex.a;
TEMP color;
-MUL color, colorTex, colorMul;
+LRP color, grayscaleFactor, colorGray, colorTex;
+MUL color, color, colorMul;
ADD color, color, colorAdd;
MOV result.color, color;
END
Index: ps/trunk/binaries/data/mods/mod/shaders/arb/canvas2d.xml
===================================================================
--- ps/trunk/binaries/data/mods/mod/shaders/arb/canvas2d.xml (revision 25602)
+++ ps/trunk/binaries/data/mods/mod/shaders/arb/canvas2d.xml (revision 25603)
@@ -1,16 +1,17 @@
+
Index: ps/trunk/binaries/data/mods/mod/shaders/glsl/canvas2d.fs
===================================================================
--- ps/trunk/binaries/data/mods/mod/shaders/glsl/canvas2d.fs (revision 25602)
+++ ps/trunk/binaries/data/mods/mod/shaders/glsl/canvas2d.fs (revision 25603)
@@ -1,12 +1,15 @@
#version 110
+uniform sampler2D tex;
uniform vec4 colorAdd;
uniform vec4 colorMul;
-uniform sampler2D tex;
+uniform float grayscaleFactor;
varying vec2 v_uv;
void main()
{
- gl_FragColor = clamp(texture2D(tex, v_uv) * colorMul + colorAdd, 0.0, 1.0);
+ vec4 colorTex = texture2D(tex, v_uv);
+ vec3 grayColor = vec3(dot(vec3(0.3, 0.59, 0.11), colorTex.rgb));
+ gl_FragColor = clamp(mix(colorTex, vec4(grayColor, colorTex.a), grayscaleFactor) * colorMul + colorAdd, 0.0, 1.0);
}
Index: ps/trunk/source/graphics/Canvas2D.cpp
===================================================================
--- ps/trunk/source/graphics/Canvas2D.cpp (revision 25602)
+++ ps/trunk/source/graphics/Canvas2D.cpp (revision 25603)
@@ -1,152 +1,153 @@
/* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see .
*/
#include "precompiled.h"
#include "Canvas2D.h"
#include "graphics/Color.h"
#include "graphics/ShaderManager.h"
#include "graphics/TextureManager.h"
#include "gui/GUIMatrix.h"
#include "maths/Rect.h"
#include "maths/Vector2D.h"
#include "ps/CStrInternStatic.h"
#include "renderer/Renderer.h"
#include
namespace
{
// Array of 2D elements unrolled into 1D array.
using PlaneArray2D = std::array;
inline void DrawTextureImpl(CTexturePtr texture,
const PlaneArray2D& vertices, PlaneArray2D uvs,
- const CColor& multiply, const CColor& add)
+ const CColor& multiply, const CColor& add, const float grayscaleFactor)
{
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);
for (size_t idx = 0; idx < uvs.size(); idx += 2)
{
if (texture->GetWidth() > 0.0f)
uvs[idx + 0] /= texture->GetWidth();
if (texture->GetHeight() > 0.0f)
uvs[idx + 1] /= texture->GetHeight();
}
shader->Uniform(str_transform, GetDefaultGuiMatrix());
shader->Uniform(str_colorAdd, add);
shader->Uniform(str_colorMul, multiply);
+ shader->Uniform(str_grayscaleFactor, grayscaleFactor);
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& points, const float width, const CColor& color)
{
std::vector vertices;
vertices.reserve(points.size() * 3);
for (const CVector2D& point : points)
{
vertices.emplace_back(point.X);
vertices.emplace_back(point.Y);
vertices.emplace_back(0.0f);
}
// Setup the render state
CMatrix3D transform = GetDefaultGuiMatrix();
CShaderDefines lineDefines;
CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect(str_gui_solid, g_Renderer.GetSystemShaderDefines(), lineDefines);
tech->BeginPass();
CShaderProgramPtr shader = tech->GetShader();
shader->Uniform(str_transform, transform);
shader->Uniform(str_color, color);
shader->VertexPointer(3, GL_FLOAT, 0, vertices.data());
shader->AssertPointersBound();
#if !CONFIG2_GLES
glEnable(GL_LINE_SMOOTH);
#endif
glLineWidth(width);
if (!g_Renderer.DoSkipSubmit())
glDrawArrays(GL_LINE_STRIP, 0, vertices.size() / 3);
glLineWidth(1.0f);
#if !CONFIG2_GLES
glDisable(GL_LINE_SMOOTH);
#endif
tech->EndPass();
}
void CCanvas2D::DrawRect(const CRect& rect, const CColor& color)
{
const PlaneArray2D uvs = {
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f
};
const PlaneArray2D vertices = {
rect.left, rect.bottom,
rect.right, rect.bottom,
rect.right, rect.top,
rect.left, rect.top
};
DrawTextureImpl(
g_Renderer.GetTextureManager().GetTransparentTexture(),
- vertices, uvs, CColor(0.0f, 0.0f, 0.0f, 0.0f), color);
+ vertices, uvs, CColor(0.0f, 0.0f, 0.0f, 0.0f), color, 0.0f);
}
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));
+ CColor(1.0f, 1.0f, 1.0f, 1.0f), CColor(0.0f, 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)
+ const CColor& multiply, const CColor& add, const float grayscaleFactor)
{
const PlaneArray2D uvs = {
source.left, source.bottom,
source.right, source.bottom,
source.right, source.top,
source.left, source.top
};
const PlaneArray2D vertices = {
destination.left, destination.bottom,
destination.right, destination.bottom,
destination.right, destination.top,
destination.left, destination.top
};
- DrawTextureImpl(texture, vertices, uvs, multiply, add);
+ DrawTextureImpl(texture, vertices, uvs, multiply, add, grayscaleFactor);
}
Index: ps/trunk/source/graphics/Canvas2D.h
===================================================================
--- ps/trunk/source/graphics/Canvas2D.h (revision 25602)
+++ ps/trunk/source/graphics/Canvas2D.h (revision 25603)
@@ -1,63 +1,65 @@
/* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see .
*/
#ifndef INCLUDED_CANVAS2D
#define INCLUDED_CANVAS2D
#include "graphics/Texture.h"
#include "maths/Vector2D.h"
#include
class CRect;
struct CColor;
// Encapsulates 2D drawing functionality to hide and optimize
// low level API calls.
class CCanvas2D
{
public:
/**
* Draws a line by the given points with the width and color.
*/
void DrawLine(
const std::vector& 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
+ * 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,
- const CColor& multiply, const CColor& add);
+ 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);
};
#endif // INCLUDED_CANVAS2D
Index: ps/trunk/source/gui/GUIRenderer.cpp
===================================================================
--- ps/trunk/source/gui/GUIRenderer.cpp (revision 25602)
+++ ps/trunk/source/gui/GUIRenderer.cpp (revision 25603)
@@ -1,425 +1,361 @@
/* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see .
*/
#include "precompiled.h"
#include "GUIRenderer.h"
#include "graphics/Canvas2D.h"
-#include "graphics/ShaderManager.h"
#include "graphics/TextureManager.h"
#include "gui/CGUI.h"
#include "gui/CGUISprite.h"
#include "gui/GUIMatrix.h"
#include "gui/SettingTypes/CGUIColor.h"
#include "i18n/L10n.h"
#include "lib/ogl.h"
#include "lib/res/graphics/ogl_tex.h"
#include "lib/res/h_mgr.h"
#include "lib/tex/tex.h"
#include "lib/utf8.h"
#include "ps/CLogger.h"
#include "ps/CStrInternStatic.h"
#include "ps/Filesystem.h"
#include "renderer/Renderer.h"
using namespace GUIRenderer;
DrawCalls::DrawCalls()
{
}
// DrawCalls needs to be copyable, so it can be used in other copyable types.
// But actually copying data is hard, since we'd need to avoid losing track of
// who owns various pointers, so instead we just return an empty list.
// The list should get filled in again (by GUIRenderer::UpdateDrawCallCache)
// before it's used for rendering. (TODO: Is this class actually used safely
// in practice?)
DrawCalls::DrawCalls(const DrawCalls&)
: std::vector()
{
}
DrawCalls& DrawCalls::operator=(const DrawCalls&)
{
return *this;
}
void GUIRenderer::UpdateDrawCallCache(const CGUI& pGUI, DrawCalls& Calls, const CStr& SpriteName, const CRect& Size, std::map& Sprites)
{
// This is called only when something has changed (like the size of the
// sprite), so it doesn't need to be particularly efficient.
// Clean up the old data
Calls.clear();
// If this object has zero size, there's nothing to render. (This happens
// with e.g. tooltips that have zero size before they're first drawn, so
// it isn't necessarily an error.)
if (Size.left == Size.right && Size.top == Size.bottom)
return;
std::map::iterator it(Sprites.find(SpriteName));
if (it == Sprites.end())
{
/*
* Sprite not found. Check whether this a special sprite,
* and if so create a new sprite:
* "stretched:filename.ext" - stretched image
* "stretched:grayscale:filename.ext" - stretched grayscale image.
* "cropped:0.5, 0.25" - stretch this ratio (x,y) of the top left of the image
* "color:r g b a" - solid color
* > "textureAsMask" - when using color, use the (optional) texture alpha channel as mask.
* These can be combined, but they must be separated by a ":"
* so you can have a white overlay over an stretched grayscale image with:
* "grayscale:color:255 255 255 100:stretched:filename.ext"
*/
// Check that this can be a special sprite.
if (SpriteName.ReverseFind(":") == -1 && SpriteName.Find("color(") == -1)
{
LOGERROR("Trying to use a sprite that doesn't exist (\"%s\").", SpriteName.c_str());
return;
}
CGUISprite* Sprite = new CGUISprite;
VfsPath TextureName = VfsPath("art/textures/ui") / wstring_from_utf8(SpriteName.AfterLast(":"));
if (SpriteName.Find("stretched:") != -1)
{
// TODO: Should check (nicely) that this is a valid file?
SGUIImage* Image = new SGUIImage();
Image->m_TextureName = TextureName;
if (SpriteName.Find("grayscale:") != -1)
{
Image->m_Effects = std::make_shared();
Image->m_Effects->m_Greyscale = true;
}
Sprite->AddImage(Image);
Sprites[SpriteName] = Sprite;
}
else if (SpriteName.Find("cropped:") != -1)
{
// TODO: Should check (nicely) that this is a valid file?
SGUIImage* Image = new SGUIImage();
const bool centered = SpriteName.Find("center:") != -1;
CStr info = SpriteName.AfterLast("cropped:").BeforeFirst(":");
double xRatio = info.BeforeFirst(",").ToDouble();
double yRatio = info.AfterLast(",").ToDouble();
const CRect percentSize = centered
? CRect(50 - 50 / xRatio, 50 - 50 / yRatio, 50 + 50 / xRatio, 50 + 50 / yRatio)
: CRect(0, 0, 100 / xRatio, 100 / yRatio);
Image->m_TextureSize = CGUISize(CRect(0, 0, 0, 0), percentSize);
Image->m_TextureName = TextureName;
if (SpriteName.Find("grayscale:") != -1)
{
Image->m_Effects = std::make_shared();
Image->m_Effects->m_Greyscale = true;
}
Sprite->AddImage(Image);
Sprites[SpriteName] = Sprite;
}
if (SpriteName.Find("color:") != -1)
{
CStrW value = wstring_from_utf8(SpriteName.AfterLast("color:").BeforeFirst(":"));
SGUIImage* Image = new SGUIImage();
CGUIColor* color;
// If we are using a mask, this is an effect.
// Otherwise we can fallback to the "back color" attribute
// TODO: we are assuming there is a filename here.
if (SpriteName.Find("textureAsMask:") != -1)
{
Image->m_TextureName = TextureName;
Image->m_Effects = std::make_shared();
color = &Image->m_Effects->m_SolidColor;
}
else
color = &Image->m_BackColor;
// Check color is valid
if (!CGUI::ParseString(&pGUI, value, *color))
{
LOGERROR("GUI: Error parsing sprite 'color' (\"%s\")", utf8_from_wstring(value));
return;
}
Sprite->AddImage(Image);
Sprites[SpriteName] = Sprite;
}
it = Sprites.find(SpriteName);
// Otherwise, just complain and give up:
if (it == Sprites.end())
{
SAFE_DELETE(Sprite);
LOGERROR("Trying to use a sprite that doesn't exist (\"%s\").", SpriteName.c_str());
return;
}
}
Calls.reserve(it->second->m_Images.size());
// Iterate through all the sprite's images, loading the texture and
// calculating the texture coordinates
std::vector::const_iterator cit;
for (cit = it->second->m_Images.begin(); cit != it->second->m_Images.end(); ++cit)
{
SDrawCall Call(*cit); // pointers are safe since we never modify sprites/images after startup
CRect ObjectSize = (*cit)->m_Size.GetSize(Size);
if (ObjectSize.GetWidth() == 0.0 || ObjectSize.GetHeight() == 0.0)
{
// Zero sized object. Don't report as an error, since it's common for e.g. hitpoint bars.
continue; // i.e. don't continue with this image
}
Call.m_Vertices = ObjectSize;
if ((*cit)->m_RoundCoordinates)
{
// Round the vertex coordinates to integers, to avoid ugly filtering artifacts
Call.m_Vertices.left = (int)(Call.m_Vertices.left + 0.5f);
Call.m_Vertices.right = (int)(Call.m_Vertices.right + 0.5f);
Call.m_Vertices.top = (int)(Call.m_Vertices.top + 0.5f);
Call.m_Vertices.bottom = (int)(Call.m_Vertices.bottom + 0.5f);
}
+ bool hasTexture = false;
if (!(*cit)->m_TextureName.empty())
{
CTextureProperties textureProps(g_L10n.LocalizePath((*cit)->m_TextureName));
textureProps.SetWrap((*cit)->m_WrapMode);
CTexturePtr texture = g_Renderer.GetTextureManager().CreateTexture(textureProps);
texture->Prefetch();
- Call.m_HasTexture = true;
+ hasTexture = true;
Call.m_Texture = texture;
Call.m_ObjectSize = ObjectSize;
}
- else
- {
- Call.m_HasTexture = false;
- }
Call.m_BackColor = &(*cit)->m_BackColor;
- if (!Call.m_HasTexture)
+ Call.m_GrayscaleFactor = 0.0f;
+ if (!hasTexture)
{
- 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)
{
if ((*cit)->m_Effects->m_AddColor != CGUIColor())
{
- Call.m_Material = str_gui_add;
const CColor color = (*cit)->m_Effects->m_AddColor;
Call.m_ColorAdd = CColor(color.r, color.g, color.b, 0.0f);
Call.m_ColorMultiply = CColor(1.0f, 1.0f, 1.0f, 1.0f);
}
else if ((*cit)->m_Effects->m_Greyscale)
{
- Call.m_Shader = g_Renderer.GetShaderManager().LoadEffect(str_gui_grayscale);
- Call.m_Material = str_gui_grayscale;
+ Call.m_ColorAdd = CColor(0.0f, 0.0f, 0.0f, 0.0f);
+ Call.m_ColorMultiply = CColor(1.0f, 1.0f, 1.0f, 1.0f);
+ Call.m_GrayscaleFactor = 1.0f;
}
else if ((*cit)->m_Effects->m_SolidColor != CGUIColor())
{
- Call.m_Material = str_gui_solid_mask;
const CColor color = (*cit)->m_Effects->m_SolidColor;
Call.m_ColorAdd = CColor(color.r, color.g, color.b, 0.0f);
Call.m_ColorMultiply = CColor(0.0f, 0.0f, 0.0f, color.a);
}
else /* Slight confusion - why no effects? */
{
- Call.m_Material = str_gui_basic;
Call.m_ColorAdd = CColor(0.0f, 0.0f, 0.0f, 0.0f);
Call.m_ColorMultiply = CColor(1.0f, 1.0f, 1.0f, 1.0f);
}
}
else
{
- Call.m_Material = str_gui_basic;
Call.m_ColorAdd = CColor(0.0f, 0.0f, 0.0f, 0.0f);
Call.m_ColorMultiply = CColor(1.0f, 1.0f, 1.0f, 1.0f);
}
Calls.push_back(Call);
}
}
CRect SDrawCall::ComputeTexCoords() const
{
float TexWidth = m_Texture->GetWidth();
float TexHeight = m_Texture->GetHeight();
if (!TexWidth || !TexHeight)
return CRect(0, 0, 1, 1);
// Textures are positioned by defining a rectangular block of the
// texture (usually the whole texture), and a rectangular block on
// the screen. The texture is positioned to make those blocks line up.
// Get the screen's position/size for the block
CRect BlockScreen = m_Image->m_TextureSize.GetSize(m_ObjectSize);
if (m_Image->m_FixedHAspectRatio)
BlockScreen.right = BlockScreen.left + BlockScreen.GetHeight() * m_Image->m_FixedHAspectRatio;
// Get the texture's position/size for the block:
CRect BlockTex;
// "real_texture_placement" overrides everything
if (m_Image->m_TexturePlacementInFile != CRect())
BlockTex = m_Image->m_TexturePlacementInFile;
// Use the whole texture
else
BlockTex = CRect(0, 0, TexWidth, TexHeight);
// When rendering, BlockTex will be transformed onto BlockScreen.
// Also, TexCoords will be transformed onto ObjectSize (giving the
// UV coords at each vertex of the object). We know everything
// except for TexCoords, so calculate it:
CVector2D translation(BlockTex.TopLeft()-BlockScreen.TopLeft());
float ScaleW = BlockTex.GetWidth()/BlockScreen.GetWidth();
float ScaleH = BlockTex.GetHeight()/BlockScreen.GetHeight();
CRect TexCoords (
// Resize (translating to/from the origin, so the
// topleft corner stays in the same place)
(m_ObjectSize-m_ObjectSize.TopLeft())
.Scale(ScaleW, ScaleH)
+ m_ObjectSize.TopLeft()
// Translate from BlockTex to BlockScreen
+ translation
);
// The tex coords need to be scaled so that (texwidth,texheight) is
// mapped onto (1,1)
TexCoords.left /= TexWidth;
TexCoords.right /= TexWidth;
TexCoords.top /= TexHeight;
TexCoords.bottom /= TexHeight;
return TexCoords;
}
void GUIRenderer::Draw(DrawCalls& Calls, CCanvas2D& canvas)
{
if (Calls.empty())
return;
// Called every frame, to draw the object (based on cached calculations)
// TODO: batching by shader/texture/etc would be nice
- CMatrix3D matrix = GetDefaultGuiMatrix();
-
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Iterate through each DrawCall, and execute whatever drawing code is being called
for (DrawCalls::const_iterator cit = Calls.begin(); cit != Calls.end(); ++cit)
{
- if (cit->m_HasTexture && (cit->m_Material == str_gui_basic || cit->m_Material == str_gui_solid_mask || cit->m_Material == str_gui_add))
- {
- // A hack to preload the handle to get a correct texture size.
- GLuint h;
- ogl_tex_get_texture_id(cit->m_Texture->GetHandle(), &h);
-
- CRect texCoords = cit->ComputeTexCoords().Scale(
- cit->m_Texture->GetWidth(), cit->m_Texture->GetHeight());
-
- // Ensure the quad has the correct winding order
- CRect rect = cit->m_Vertices;
- if (rect.right < rect.left)
- {
- std::swap(rect.right, rect.left);
- std::swap(texCoords.right, texCoords.left);
- }
- if (rect.bottom < rect.top)
- {
- std::swap(rect.bottom, rect.top);
- std::swap(texCoords.bottom, texCoords.top);
- }
+ // A hack to preload the handle to get a correct texture size.
+ GLuint h;
+ ogl_tex_get_texture_id(cit->m_Texture->GetHandle(), &h);
- canvas.DrawTexture(cit->m_Texture,
- rect, texCoords, cit->m_ColorMultiply, cit->m_ColorAdd);
- }
- else if (cit->m_HasTexture)
- {
- cit->m_Shader->BeginPass();
- CShaderProgramPtr shader = cit->m_Shader->GetShader();
- shader->Uniform(str_transform, matrix);
- shader->Uniform(str_color, cit->m_ShaderColorParameter);
- shader->BindTexture(str_tex, cit->m_Texture);
-
- CRect TexCoords = cit->ComputeTexCoords();
-
- // Ensure the quad has the correct winding order, and update texcoords to match
- CRect Verts = cit->m_Vertices;
- if (Verts.right < Verts.left)
- {
- std::swap(Verts.right, Verts.left);
- std::swap(TexCoords.right, TexCoords.left);
- }
- if (Verts.bottom < Verts.top)
- {
- std::swap(Verts.bottom, Verts.top);
- std::swap(TexCoords.bottom, TexCoords.top);
- }
-
- std::vector data;
-#define ADD(u, v, x, y, z) STMT(data.push_back(u); data.push_back(v); data.push_back(x); data.push_back(y); data.push_back(z))
- ADD(TexCoords.left, TexCoords.bottom, Verts.left, Verts.bottom, 0.0f);
- ADD(TexCoords.right, TexCoords.bottom, Verts.right, Verts.bottom, 0.0f);
- ADD(TexCoords.right, TexCoords.top, Verts.right, Verts.top, 0.0f);
-
- ADD(TexCoords.right, TexCoords.top, Verts.right, Verts.top, 0.0f);
- ADD(TexCoords.left, TexCoords.top, Verts.left, Verts.top, 0.0f);
- ADD(TexCoords.left, TexCoords.bottom, Verts.left, Verts.bottom, 0.0f);
-#undef ADD
-
- shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 5*sizeof(float), &data[0]);
- shader->VertexPointer(3, GL_FLOAT, 5*sizeof(float), &data[2]);
- glDrawArrays(GL_TRIANGLES, 0, 6);
+ CRect texCoords = cit->ComputeTexCoords().Scale(
+ cit->m_Texture->GetWidth(), cit->m_Texture->GetHeight());
- cit->m_Shader->EndPass();
+ // Ensure the quad has the correct winding order
+ CRect rect = cit->m_Vertices;
+ if (rect.right < rect.left)
+ {
+ std::swap(rect.right, rect.left);
+ std::swap(texCoords.right, texCoords.left);
}
- else
+ if (rect.bottom < rect.top)
{
- // Ensure the quad has the correct winding order
- CRect rect = cit->m_Vertices;
- if (rect.right < rect.left)
- std::swap(rect.right, rect.left);
- if (rect.bottom < rect.top)
- std::swap(rect.bottom, rect.top);
- canvas.DrawTexture(cit->m_Texture,
- rect, CRect(0, 0, cit->m_Texture->GetWidth(), cit->m_Texture->GetHeight()),
- cit->m_ColorMultiply, cit->m_ColorAdd);
+ std::swap(rect.bottom, rect.top);
+ std::swap(texCoords.bottom, texCoords.top);
}
+
+ canvas.DrawTexture(cit->m_Texture,
+ rect, texCoords, cit->m_ColorMultiply, cit->m_ColorAdd, cit->m_GrayscaleFactor);
}
glDisable(GL_BLEND);
}
Index: ps/trunk/source/gui/GUIRenderer.h
===================================================================
--- ps/trunk/source/gui/GUIRenderer.h (revision 25602)
+++ ps/trunk/source/gui/GUIRenderer.h (revision 25603)
@@ -1,80 +1,73 @@
/* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see .
*/
#ifndef INCLUDED_GUIRENDERER
#define INCLUDED_GUIRENDERER
#include "graphics/Color.h"
#include "graphics/ShaderTechniquePtr.h"
#include "graphics/Texture.h"
#include "lib/res/handle.h"
#include "maths/Rect.h"
#include "ps/CStrIntern.h"
#include