Skip to content

Commit

Permalink
Fix text rendering blend mode, make progress bar text bold.
Browse files Browse the repository at this point in the history
Fixes the progress bar legibility, part of ticket:4569.
  • Loading branch information
Cyp committed Apr 5, 2017
1 parent d0934ff commit 0bfd217
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 34 deletions.
15 changes: 15 additions & 0 deletions data/base/shaders/text.frag
@@ -0,0 +1,15 @@
#version 130

uniform vec4 color = vec4(1.);
uniform sampler2D texture;

in vec2 uv;
out vec4 FragColor;
out vec4 FragColor1;

void main()
{
vec4 texColour = texture2D(texture, uv) * color.a;
FragColor = vec4(texColour.rgb * color.rgb, texColour.rgb * vec3(0.299, 0.587, 0.114));
FragColor1 = texColour;
}
15 changes: 13 additions & 2 deletions lib/ivis_opengl/pieblitfunc.cpp
Expand Up @@ -323,11 +323,11 @@ static bool assertValidImage(IMAGEFILE *imageFile, unsigned id)
return true;
}

static void iv_DrawImageImpl(Vector2i offset, Vector2i size, Vector2f TextureUV, Vector2f TextureSize, PIELIGHT colour, const glm::mat4 &modelViewProjection)
static void iv_DrawImageImpl(Vector2i offset, Vector2i size, Vector2f TextureUV, Vector2f TextureSize, PIELIGHT colour, const glm::mat4 &modelViewProjection, SHADER_MODE mode = SHADER_TEXRECT)
{
glm::mat4 transformMat = modelViewProjection * glm::translate(offset.x, offset.y, 0) * glm::scale(size.x, size.y, 1);

pie_ActivateShader(SHADER_TEXRECT,
pie_ActivateShader(mode,
transformMat,
Vector2f(TextureUV.x, TextureUV.y),
Vector2f(TextureSize.x, TextureSize.y),
Expand All @@ -347,6 +347,17 @@ void iV_DrawImage(GLuint TextureID, Vector2i Position, Vector2i offset, Vector2i
iv_DrawImageImpl(offset, size, Vector2f(0.f, 0.f), Vector2f(1.f, 1.f), colour, mvp);
}

void iV_DrawImageText(GLuint TextureID, Vector2i Position, Vector2i offset, Vector2i size, float angle, REND_MODE mode, PIELIGHT colour)
{
pie_SetRendMode(mode);
pie_SetTexturePage(TEXPAGE_EXTERN);
glBindTexture(GL_TEXTURE_2D, TextureID);

glm::mat4 mvp = defaultProjectionMatrix() * glm::translate(Position.x, Position.y, 0) * glm::rotate(angle, glm::vec3(0.f, 0.f, 1.f));

iv_DrawImageImpl(offset, size, Vector2f(0.f, 0.f), Vector2f(1.f, 1.f), colour, mvp, SHADER_TEXT);
}

static void pie_DrawImage(IMAGEFILE *imageFile, int id, Vector2i size, const PIERECT *dest, PIELIGHT colour, const glm::mat4 &modelViewProjection)
{
ImageDef const &image2 = imageFile->imageDefs[id];
Expand Down
1 change: 1 addition & 0 deletions lib/ivis_opengl/pieblitfunc.h
Expand Up @@ -123,6 +123,7 @@ static inline void iV_Box(int x0, int y0, int x1, int y1, PIELIGHT first)
}
extern void pie_BoxFill(int x0, int y0, int x1, int y1, PIELIGHT colour, REND_MODE rendermode = REND_OPAQUE);
extern void iV_DrawImage(GLuint TextureID, Vector2i position, Vector2i offset, Vector2i size, float angle, REND_MODE mode, PIELIGHT colour);
extern void iV_DrawImageText(GLuint TextureID, Vector2i position, Vector2i offset, Vector2i size, float angle, REND_MODE mode, PIELIGHT colour);
extern void iV_DrawImage(IMAGEFILE *ImageFile, UWORD ID, int x, int y, const glm::mat4 &modelViewProjection = defaultProjectionMatrix());
void iV_DrawImage2(const QString &filename, float x, float y, float width = -0.0f, float height = -0.0f);
void iV_DrawImageTc(Image image, Image imageTc, int x, int y, PIELIGHT colour, const glm::mat4 &modelViewProjection = defaultProjectionMatrix());
Expand Down
55 changes: 31 additions & 24 deletions lib/ivis_opengl/piestate.cpp
Expand Up @@ -339,83 +339,90 @@ bool pie_LoadShaders()
// Load some basic shaders
memset(&program, 0, sizeof(program));
pie_internal::shaderProgram.push_back(program);
int shaderEnum = 0;

// TCMask shader for map-placed models with advanced lighting
debug(LOG_3D, "Loading shader: SHADER_COMPONENT");
result = pie_LoadShader("Component program", "shaders/tcmask.vert", "shaders/tcmask.frag",
{ "colour", "teamcolour", "stretch", "tcmask", "fogEnabled", "normalmap", "specularmap", "ecmEffect", "alphaTest", "graphicsCycle",
"ModelViewMatrix", "ModelViewProjectionMatrix", "NormalMatrix", "lightPosition", "sceneColor", "ambient", "diffuse", "specular",
"fogEnd", "fogStart", "fogColor" });
ASSERT_OR_RETURN(false, result, "Failed to load component shader");
ASSERT_OR_RETURN(false, result && ++shaderEnum == SHADER_COMPONENT, "Failed to load component shader");

// TCMask shader for buttons with flat lighting
debug(LOG_3D, "Loading shader: SHADER_BUTTON");
result = pie_LoadShader("Button program", "shaders/button.vert", "shaders/button.frag",
{ "colour", "teamcolour", "stretch", "tcmask", "fogEnabled", "normalmap", "specularmap", "ecmEffect", "alphaTest", "graphicsCycle",
"ModelViewMatrix", "ModelViewProjectionMatrix", "NormalMatrix", "lightPosition", "sceneColor", "ambient", "diffuse", "specular",
"fogEnd", "fogStart", "fogColor" });
ASSERT_OR_RETURN(false, result, "Failed to load button shader");
ASSERT_OR_RETURN(false, result && ++shaderEnum == SHADER_BUTTON, "Failed to load button shader");

// Plain shader for no lighting
debug(LOG_3D, "Loading shader: SHADER_NOLIGHT");
result = pie_LoadShader("Plain program", "shaders/nolight.vert", "shaders/nolight.frag",
{ "colour", "teamcolour", "stretch", "tcmask", "fogEnabled", "normalmap", "specularmap", "ecmEffect", "alphaTest", "graphicsCycle",
"ModelViewMatrix", "ModelViewProjectionMatrix", "NormalMatrix", "lightPosition", "sceneColor", "ambient", "diffuse", "specular",
"fogEnd", "fogStart", "fogColor" });
ASSERT_OR_RETURN(false, result, "Failed to load no-lighting shader");
ASSERT_OR_RETURN(false, result && ++shaderEnum == SHADER_NOLIGHT, "Failed to load no-lighting shader");

debug(LOG_3D, "Loading shader: TERRAIN");
debug(LOG_3D, "Loading shader: SHADER_TERRAIN");
result = pie_LoadShader("terrain program", "shaders/terrain_water.vert", "shaders/terrain.frag",
{ "ModelViewProjectionMatrix", "paramx1", "paramy1", "paramx2", "paramy2", "tex", "lightmap_tex", "textureMatrix2",
"fogEnabled", "fogEnd", "fogStart", "fogColor" });
ASSERT_OR_RETURN(false, result, "Failed to load terrain shader");
ASSERT_OR_RETURN(false, result && ++shaderEnum == SHADER_TERRAIN, "Failed to load terrain shader");

debug(LOG_3D, "Loading shader: TERRAIN_DEPTH");
debug(LOG_3D, "Loading shader: SHADER_TERRAIN_DEPTH");
result = pie_LoadShader("terrain_depth program", "shaders/terrain_water.vert", "shaders/terraindepth.frag",
{ "ModelViewProjectionMatrix", "paramx2", "paramy2", "lightmap_tex" });
ASSERT_OR_RETURN(false, result, "Failed to load terrain_depth shader");
ASSERT_OR_RETURN(false, result && ++shaderEnum == SHADER_TERRAIN_DEPTH, "Failed to load terrain_depth shader");

debug(LOG_3D, "Loading shader: DECALS");
debug(LOG_3D, "Loading shader: SHADER_DECALS");
result = pie_LoadShader("decals program", "shaders/decals.vert", "shaders/decals.frag",
{ "ModelViewProjectionMatrix", "paramxlight", "paramylight", "tex", "lightmap_tex", "lightTextureMatrix",
"fogEnabled", "fogEnd", "fogStart", "fogColor" });
ASSERT_OR_RETURN(false, result, "Failed to load decals shader");
ASSERT_OR_RETURN(false, result && ++shaderEnum == SHADER_DECALS, "Failed to load decals shader");

debug(LOG_3D, "Loading shader: WATER");
debug(LOG_3D, "Loading shader: SHADER_WATER");
result = pie_LoadShader("water program", "shaders/terrain_water.vert", "shaders/water.frag",
{ "ModelViewProjectionMatrix", "paramx1", "paramy1", "paramx2", "paramy2", "tex1", "tex2", "textureMatrix1",
"fogEnabled", "fogEnd", "fogStart" });
ASSERT_OR_RETURN(false, result, "Failed to load water shader");
ASSERT_OR_RETURN(false, result && ++shaderEnum == SHADER_WATER, "Failed to load water shader");

// Rectangular shader
debug(LOG_3D, "Loading shader: RECT");
debug(LOG_3D, "Loading shader: SHADER_RECT");
result = pie_LoadShader("Rect program", "shaders/rect.vert", "shaders/rect.frag",
{ "transformationMatrix", "color" });
ASSERT_OR_RETURN(false, result, "Failed to load rect shader");
ASSERT_OR_RETURN(false, result && ++shaderEnum == SHADER_RECT, "Failed to load rect shader");

// Textured rectangular shader
debug(LOG_3D, "Loading shader: TEXRECT");
debug(LOG_3D, "Loading shader: SHADER_TEXRECT");
result = pie_LoadShader("Rect program", "shaders/rect.vert", "shaders/texturedrect.frag",
{ "transformationMatrix", "tuv_offset", "tuv_scale", "color", "texture" });
ASSERT_OR_RETURN(false, result, "Failed to load textured rect shader");
ASSERT_OR_RETURN(false, result && ++shaderEnum == SHADER_TEXRECT, "Failed to load textured rect shader");

debug(LOG_3D, "Loading shader: GFX_COLOR");
debug(LOG_3D, "Loading shader: SHADER_GFX_COLOUR");
result = pie_LoadShader("gfx_color program", "shaders/gfx.vert", "shaders/gfx.frag",
{ "posMatrix" });
ASSERT_OR_RETURN(false, result, "Failed to load textured gfx shader");
ASSERT_OR_RETURN(false, result && ++shaderEnum == SHADER_GFX_COLOUR, "Failed to load textured gfx shader");

debug(LOG_3D, "Loading shader: GFX_TEXT");
debug(LOG_3D, "Loading shader: SHADER_GFX_TEXT");
result = pie_LoadShader("gfx_text program", "shaders/gfx.vert", "shaders/texturedrect.frag",
{ "posMatrix", "texture" });
ASSERT_OR_RETURN(false, result, "Failed to load textured gfx shader");
ASSERT_OR_RETURN(false, result && ++shaderEnum == SHADER_GFX_TEXT, "Failed to load textured gfx shader");

debug(LOG_3D, "Loading shader: GENERIC_COLOR");
debug(LOG_3D, "Loading shader: SHADER_GENERIC_COLOR");
result = pie_LoadShader("generic color program", "shaders/generic.vert", "shaders/rect.frag", { "ModelViewProjectionMatrix", "color" });
ASSERT_OR_RETURN(false, result, "Failed to load generic color shader");
ASSERT_OR_RETURN(false, result && ++shaderEnum == SHADER_GENERIC_COLOR, "Failed to load generic color shader");

debug(LOG_3D, "Loading shader: LINE");
debug(LOG_3D, "Loading shader: SHADER_LINE");
result = pie_LoadShader("line program", "shaders/line.vert", "shaders/rect.frag", { "from", "to", "color", "ModelViewProjectionMatrix" });
ASSERT_OR_RETURN(false, result, "Failed to load line shader");
ASSERT_OR_RETURN(false, result && ++shaderEnum == SHADER_LINE, "Failed to load line shader");

// Text shader
debug(LOG_3D, "Loading shader: SHADER_TEXT");
result = pie_LoadShader("Text program", "shaders/rect.vert", "shaders/text.frag",
{ "transformationMatrix", "tuv_offset", "tuv_scale", "color", "texture" });
ASSERT_OR_RETURN(false, result && ++shaderEnum == SHADER_TEXT, "Failed to load text shader");

pie_internal::currentShaderMode = SHADER_NONE;
return true;
Expand Down Expand Up @@ -648,7 +655,7 @@ void pie_SetRendMode(REND_MODE rendMode)

case REND_TEXT:
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA /*should be GL_ONE_MINUS_SRC1_COLOR, if supported*/);
break;

default:
Expand Down
1 change: 1 addition & 0 deletions lib/ivis_opengl/pietypes.h
Expand Up @@ -104,6 +104,7 @@ enum SHADER_MODE
SHADER_GFX_TEXT,
SHADER_GENERIC_COLOR,
SHADER_LINE,
SHADER_TEXT,
SHADER_MAX
};

Expand Down
11 changes: 9 additions & 2 deletions lib/ivis_opengl/textdraw.cpp
Expand Up @@ -407,6 +407,7 @@ static FTFace *regular = nullptr;
static FTFace *bold = nullptr;
static FTFace *medium = nullptr;
static FTFace *small = nullptr;
static FTFace *smallBold = nullptr;

static FTFace &getFTFace(iV_fonts FontID)
{
Expand All @@ -421,6 +422,8 @@ static FTFace &getFTFace(iV_fonts FontID)
return *medium;
case font_small:
return *small;
case font_bar:
return *smallBold;
}
}

Expand All @@ -442,18 +445,22 @@ void iV_TextInit()
bold = new FTFace(getGlobalFTlib().lib, "fonts/DejaVuSans-Bold.ttf", 21 * 64, DPI, DPI);
medium = new FTFace(getGlobalFTlib().lib, "fonts/DejaVuSans.ttf", 16 * 64, DPI, DPI);
small = new FTFace(getGlobalFTlib().lib, "fonts/DejaVuSans.ttf", 9 * 64, DPI, DPI);
smallBold = new FTFace(getGlobalFTlib().lib, "fonts/DejaVuSans-Bold.ttf", 9 * 64, DPI, DPI);
}

void iV_TextShutdown()
{
delete regular;
delete medium;
delete bold;
delete small;
delete smallBold;
small = nullptr;
regular = nullptr;
medium = nullptr;
bold = nullptr;
small = nullptr;
smallBold = nullptr;
glDeleteBuffers(1, &pbo);
glDeleteTextures(1, &textureID);
}
Expand Down Expand Up @@ -686,7 +693,7 @@ void iV_DrawTextRotated(const char *string, float XPos, float YPos, float rotati
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glDisable(GL_CULL_FACE);
iV_DrawImage(textureID, Vector2i(XPos, YPos), Vector2i(xoffset, yoffset), Vector2i(width, height), rotation, REND_TEXT, color);
iV_DrawImageText(textureID, Vector2i(XPos, YPos), Vector2i(xoffset, yoffset), Vector2i(width, height), rotation, REND_TEXT, color);
glEnable(GL_CULL_FACE);
}
}
Expand Down Expand Up @@ -783,6 +790,6 @@ void WzText::render(Vector2i position, PIELIGHT colour, float rotation)
rotation = 180. - rotation;
}
glDisable(GL_CULL_FACE);
iV_DrawImage(texture, position, offsets, dimensions, rotation, REND_TEXT, colour);
iV_DrawImageText(texture, position, offsets, dimensions, rotation, REND_TEXT, colour);
glEnable(GL_CULL_FACE);
}
1 change: 1 addition & 0 deletions lib/ivis_opengl/textdraw.h
Expand Up @@ -30,6 +30,7 @@ enum iV_fonts
font_large,
font_medium,
font_small,
font_bar,
font_scaled,
font_count
};
Expand Down
14 changes: 8 additions & 6 deletions lib/widget/bar.cpp
Expand Up @@ -130,19 +130,21 @@ static void barGraphDisplayText(W_BARGRAPH *barGraph, int x0, int x1, int y1)
if (!barGraph->text.isEmpty())
{
QByteArray utf = barGraph->text.toUtf8();
int textWidth = iV_GetTextWidth(utf.constData(), font_small);
int textWidth = iV_GetTextWidth(utf.constData(), font_bar);
Vector2i pos((x0 + x1 - textWidth) / 2, y1);
iV_SetTextColour(WZCOL_BLACK); // Add a shadow, to make it visible against any background.
for (int dx = -1; dx <= 1; ++dx)
for (int dx = -2; dx <= 2; ++dx)
{
for (int dy = -1; dy <= 1; ++dy)
for (int dy = -2; dy <= 2; ++dy)
{
iV_DrawText(utf.constData(), pos.x + dx * 1.25f, pos.y + dy * 1.25f, font_small);
if (dx*dx + dy*dy <= 4)
{
iV_DrawText(utf.constData(), pos.x + dx, pos.y + dy, font_bar);
}
}
}
iV_SetTextColour(barGraph->textCol);
iV_DrawText(utf.constData(), pos.x, pos.y - 0.25f, font_small);
iV_DrawText(utf.constData(), pos.x, pos.y + 0.25f, font_small); // Draw twice, to make it more visible.
iV_DrawText(utf.constData(), pos.x, pos.y, font_bar);
}
}

Expand Down

0 comments on commit 0bfd217

Please sign in to comment.