CFont: Make use of std::array
Same behavior, stronger typing.
This commit is contained in:
parent
b6b7bcace1
commit
1c292f5e2d
|
@ -31,32 +31,35 @@ CVector2f CFont::RenderString(const TString& rkString, CRenderer* /*pRenderer*/,
|
||||||
CVector2f /*Position*/, CColor FillColor, CColor StrokeColor, uint32 FontSize)
|
CVector2f /*Position*/, CColor FillColor, CColor StrokeColor, uint32 FontSize)
|
||||||
{
|
{
|
||||||
// WIP
|
// WIP
|
||||||
if (!smBuffersInitialized) InitBuffers();
|
if (!smBuffersInitialized)
|
||||||
|
InitBuffers();
|
||||||
|
|
||||||
// Shader setup
|
// Shader setup
|
||||||
CShader *pTextShader = CDrawUtil::GetTextShader();
|
CShader *pTextShader = CDrawUtil::GetTextShader();
|
||||||
pTextShader->SetCurrent();
|
pTextShader->SetCurrent();
|
||||||
|
|
||||||
GLuint ModelMtxLoc = pTextShader->GetUniformLocation("ModelMtx");
|
const GLuint ModelMtxLoc = pTextShader->GetUniformLocation("ModelMtx");
|
||||||
GLuint ColorLoc = pTextShader->GetUniformLocation("FontColor");
|
const GLuint ColorLoc = pTextShader->GetUniformLocation("FontColor");
|
||||||
GLuint LayerLoc = pTextShader->GetUniformLocation("RGBALayer");
|
const GLuint LayerLoc = pTextShader->GetUniformLocation("RGBALayer");
|
||||||
mpFontTexture->Bind(0);
|
mpFontTexture->Bind(0);
|
||||||
smGlyphVertices->Bind();
|
smGlyphVertices->Bind();
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
// Initialize some more stuff before we start the character loop
|
// Initialize some more stuff before we start the character loop
|
||||||
CVector2f PrintHead(-1.f, 1.f);
|
CVector2f PrintHead(-1.f, 1.f);
|
||||||
CTransform4f PtScale = CTransform4f::ScaleMatrix(PtsToFloat(1));
|
const CTransform4f PtScale = CTransform4f::ScaleMatrix(PtsToFloat(1));
|
||||||
SGlyph *pPrevGlyph = nullptr;
|
SGlyph *pPrevGlyph = nullptr;
|
||||||
|
|
||||||
float Scale;
|
float Scale;
|
||||||
if (FontSize == CFONT_DEFAULT_SIZE) Scale = 1.f;
|
if (FontSize == CFONT_DEFAULT_SIZE)
|
||||||
else Scale = (float) FontSize / (mDefaultSize != 0 ? mDefaultSize : 18);
|
Scale = 1.f;
|
||||||
|
else
|
||||||
|
Scale = static_cast<float>(FontSize) / (mDefaultSize != 0 ? mDefaultSize : 18);
|
||||||
|
|
||||||
for (uint32 iChar = 0; iChar < rkString.Length(); iChar++)
|
for (uint32 iChar = 0; iChar < rkString.Length(); iChar++)
|
||||||
{
|
{
|
||||||
// Get character, check for newline
|
// Get character, check for newline
|
||||||
char Char = rkString[iChar];
|
const char Char = rkString[iChar];
|
||||||
|
|
||||||
if (Char == '\n')
|
if (Char == '\n')
|
||||||
{
|
{
|
||||||
|
@ -68,7 +71,8 @@ CVector2f CFont::RenderString(const TString& rkString, CRenderer* /*pRenderer*/,
|
||||||
|
|
||||||
// Get glyph
|
// Get glyph
|
||||||
auto iGlyph = mGlyphs.find(Char);
|
auto iGlyph = mGlyphs.find(Char);
|
||||||
if (iGlyph == mGlyphs.end()) continue;
|
if (iGlyph == mGlyphs.end())
|
||||||
|
continue;
|
||||||
SGlyph *pGlyph = &iGlyph->second;
|
SGlyph *pGlyph = &iGlyph->second;
|
||||||
|
|
||||||
// Apply left padding and kerning
|
// Apply left padding and kerning
|
||||||
|
@ -76,7 +80,7 @@ CVector2f CFont::RenderString(const TString& rkString, CRenderer* /*pRenderer*/,
|
||||||
|
|
||||||
if (pPrevGlyph)
|
if (pPrevGlyph)
|
||||||
{
|
{
|
||||||
if (pPrevGlyph->KerningIndex != -1)
|
if (pPrevGlyph->KerningIndex != UINT32_MAX)
|
||||||
{
|
{
|
||||||
for (uint32 iKern = pPrevGlyph->KerningIndex; iKern < mKerningTable.size(); iKern++)
|
for (uint32 iKern = pPrevGlyph->KerningIndex; iKern < mKerningTable.size(); iKern++)
|
||||||
{
|
{
|
||||||
|
@ -99,22 +103,24 @@ CVector2f CFont::RenderString(const TString& rkString, CRenderer* /*pRenderer*/,
|
||||||
if (Char == ' ') continue;
|
if (Char == ' ') continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
float XTrans = PrintHead.X;
|
const float XTrans = PrintHead.X;
|
||||||
float YTrans = PrintHead.Y + ((PtsToFloat(pGlyph->BaseOffset * 2) - PtsToFloat(mVerticalOffset * 2)) * Scale);
|
const float YTrans = PrintHead.Y + ((PtsToFloat(pGlyph->BaseOffset * 2) - PtsToFloat(mVerticalOffset * 2)) * Scale);
|
||||||
|
|
||||||
CTransform4f GlyphTransform = PtScale;
|
CTransform4f GlyphTransform = PtScale;
|
||||||
GlyphTransform.Scale(CVector3f((float) pGlyph->Width / 2, (float) pGlyph->Height, 1.f));
|
GlyphTransform.Scale(CVector3f(static_cast<float>(pGlyph->Width) / 2, static_cast<float>(pGlyph->Height), 1.f));
|
||||||
GlyphTransform.Scale(Scale);
|
GlyphTransform.Scale(Scale);
|
||||||
GlyphTransform.Translate(CVector3f(XTrans, YTrans, 0.f));
|
GlyphTransform.Translate(CVector3f(XTrans, YTrans, 0.f));
|
||||||
|
|
||||||
// Get glyph layer
|
// Get glyph layer
|
||||||
uint8 GlyphLayer = pGlyph->RGBAChannel;
|
uint8 GlyphLayer = pGlyph->RGBAChannel;
|
||||||
if (mTextureFormat == 3) GlyphLayer *= 2;
|
if (mTextureFormat == 3)
|
||||||
else if (mTextureFormat == 8) GlyphLayer = 3;
|
GlyphLayer *= 2;
|
||||||
|
else if (mTextureFormat == 8)
|
||||||
|
GlyphLayer = 3;
|
||||||
|
|
||||||
// Load shader uniforms, buffer texture
|
// Load shader uniforms, buffer texture
|
||||||
glUniformMatrix4fv(ModelMtxLoc, 1, GL_FALSE, (GLfloat*) &GlyphTransform);
|
glUniformMatrix4fv(ModelMtxLoc, 1, GL_FALSE, (GLfloat*) &GlyphTransform);
|
||||||
smGlyphVertices->BufferAttrib(EVertexAttribute::Tex0, &pGlyph->TexCoords);
|
smGlyphVertices->BufferAttrib(EVertexAttribute::Tex0, pGlyph->TexCoords.data());
|
||||||
|
|
||||||
// Draw fill
|
// Draw fill
|
||||||
glUniform1i(LayerLoc, GlyphLayer);
|
glUniform1i(LayerLoc, GlyphLayer);
|
||||||
|
@ -122,12 +128,15 @@ CVector2f CFont::RenderString(const TString& rkString, CRenderer* /*pRenderer*/,
|
||||||
smGlyphIndices.DrawElements();
|
smGlyphIndices.DrawElements();
|
||||||
|
|
||||||
// Draw stroke
|
// Draw stroke
|
||||||
if ((mTextureFormat == 1) || (mTextureFormat == 3) || (mTextureFormat == 8))
|
if (mTextureFormat == 1 || mTextureFormat == 3 || mTextureFormat == 8)
|
||||||
{
|
{
|
||||||
uint8 StrokeLayer;
|
uint8 StrokeLayer;
|
||||||
if (mTextureFormat == 1) StrokeLayer = 1;
|
if (mTextureFormat == 1)
|
||||||
else if (mTextureFormat == 3) StrokeLayer = GlyphLayer + 1;
|
StrokeLayer = 1;
|
||||||
else if (mTextureFormat == 8) StrokeLayer = GlyphLayer - 2;
|
else if (mTextureFormat == 3)
|
||||||
|
StrokeLayer = GlyphLayer + 1;
|
||||||
|
else if (mTextureFormat == 8)
|
||||||
|
StrokeLayer = GlyphLayer - 2;
|
||||||
|
|
||||||
glUniform1i(LayerLoc, StrokeLayer);
|
glUniform1i(LayerLoc, StrokeLayer);
|
||||||
glUniform4fv(ColorLoc, 1, &StrokeColor.R);
|
glUniform4fv(ColorLoc, 1, &StrokeColor.R);
|
||||||
|
@ -150,21 +159,21 @@ void CFont::InitBuffers()
|
||||||
smGlyphVertices->SetActiveAttribs(EVertexAttribute::Position | EVertexAttribute::Tex0);
|
smGlyphVertices->SetActiveAttribs(EVertexAttribute::Position | EVertexAttribute::Tex0);
|
||||||
smGlyphVertices->SetVertexCount(4);
|
smGlyphVertices->SetVertexCount(4);
|
||||||
|
|
||||||
CVector3f Vertices[4] = {
|
static constexpr std::array Vertices{
|
||||||
CVector3f( 0.f, 0.f, 0.f),
|
CVector3f( 0.f, 0.f, 0.f),
|
||||||
CVector3f( 2.f, 0.f, 0.f),
|
CVector3f( 2.f, 0.f, 0.f),
|
||||||
CVector3f( 0.f, -2.f, 0.f),
|
CVector3f( 0.f, -2.f, 0.f),
|
||||||
CVector3f( 2.f, -2.f, 0.f)
|
CVector3f( 2.f, -2.f, 0.f)
|
||||||
};
|
};
|
||||||
smGlyphVertices->BufferAttrib(EVertexAttribute::Position, Vertices);
|
smGlyphVertices->BufferAttrib(EVertexAttribute::Position, Vertices.data());
|
||||||
|
|
||||||
CVector2f TexCoords[4] = {
|
static constexpr std::array TexCoords{
|
||||||
CVector2f(0.f, 0.f),
|
CVector2f(0.f, 0.f),
|
||||||
CVector2f(1.f, 0.f),
|
CVector2f(1.f, 0.f),
|
||||||
CVector2f(0.f, 1.f),
|
CVector2f(0.f, 1.f),
|
||||||
CVector2f(1.f, 1.f)
|
CVector2f(1.f, 1.f)
|
||||||
};
|
};
|
||||||
smGlyphVertices->BufferAttrib(EVertexAttribute::Tex0, TexCoords);
|
smGlyphVertices->BufferAttrib(EVertexAttribute::Tex0, TexCoords.data());
|
||||||
|
|
||||||
smGlyphIndices.Reserve(4);
|
smGlyphIndices.Reserve(4);
|
||||||
smGlyphIndices.AddIndex(0);
|
smGlyphIndices.AddIndex(0);
|
||||||
|
|
|
@ -9,12 +9,13 @@
|
||||||
#include "Core/OpenGL/CIndexBuffer.h"
|
#include "Core/OpenGL/CIndexBuffer.h"
|
||||||
#include <Common/BasicTypes.h>
|
#include <Common/BasicTypes.h>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#define CFONT_DEFAULT_SIZE -1
|
#define CFONT_DEFAULT_SIZE UINT32_MAX
|
||||||
|
|
||||||
class CRenderer;
|
class CRenderer;
|
||||||
|
|
||||||
|
@ -37,16 +38,16 @@ class CFont : public CResource
|
||||||
|
|
||||||
struct SGlyph
|
struct SGlyph
|
||||||
{
|
{
|
||||||
uint16 Character; // The UTF-16 character that this glyph corresponds to
|
uint16 Character; // The UTF-16 character that this glyph corresponds to
|
||||||
CVector2f TexCoords[4]; // The format only lists the min/max X/Y values; tracking absolute coordinates in memory is faster
|
std::array<CVector2f, 4> TexCoords; // The format only lists the min/max X/Y values; tracking absolute coordinates in memory is faster
|
||||||
int32 LeftPadding; // The amount of padding applied left of this glyph, in points
|
int32 LeftPadding; // The amount of padding applied left of this glyph, in points
|
||||||
int32 RightPadding; // The amount of padding applied right of this glyph, in points
|
int32 RightPadding; // The amount of padding applied right of this glyph, in points
|
||||||
uint32 Width; // The width of the glyph, in points
|
uint32 Width; // The width of the glyph, in points
|
||||||
uint32 Height; // The height of the glyph, in points
|
uint32 Height; // The height of the glyph, in points
|
||||||
uint32 PrintAdvance; // How far the print head advances horizontally after printing this glyph, in points
|
uint32 PrintAdvance; // How far the print head advances horizontally after printing this glyph, in points
|
||||||
uint32 BaseOffset; // Vertical offset for this glyph, in points; the font-wide offset is added to this
|
uint32 BaseOffset; // Vertical offset for this glyph, in points; the font-wide offset is added to this
|
||||||
uint32 KerningIndex; // Index into the kerning table of the first kerning pair for this glyph. -1 if no pairs.
|
uint32 KerningIndex; // Index into the kerning table of the first kerning pair for this glyph. -1 if no pairs.
|
||||||
uint8 RGBAChannel; // Fonts can store multiple glyphs in the same space on different RGBA channels. This value corresponds to R, G, B, or A.
|
uint8 RGBAChannel; // Fonts can store multiple glyphs in the same space on different RGBA channels. This value corresponds to R, G, B, or A.
|
||||||
};
|
};
|
||||||
std::unordered_map<uint16, SGlyph> mGlyphs;
|
std::unordered_map<uint16, SGlyph> mGlyphs;
|
||||||
|
|
||||||
|
@ -54,7 +55,7 @@ class CFont : public CResource
|
||||||
{
|
{
|
||||||
uint16 CharacterA; // Left character
|
uint16 CharacterA; // Left character
|
||||||
uint16 CharacterB; // Right character
|
uint16 CharacterB; // Right character
|
||||||
int32 Adjust; // The horizontal offset to apply to CharacterB if this pair is encountered, in points
|
int32 Adjust; // The horizontal offset to apply to CharacterB if this pair is encountered, in points
|
||||||
};
|
};
|
||||||
std::vector<SKerningPair> mKerningTable; // The kerning table should be laid out in alphabetical order for the indices to work properly
|
std::vector<SKerningPair> mKerningTable; // The kerning table should be laid out in alphabetical order for the indices to work properly
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue