Text rendering working again

master
Joey Pollack 3 years ago
parent f88c8a8918
commit dfa237d2be

@ -7,6 +7,7 @@
******************************************************************************/
#include "text_renderer.h"
#include "renderer2D.h"
#include <utils/logger.h>
#include "texture.h"
@ -99,6 +100,8 @@ namespace lunarium
u32 max_width = 0;
u32 max_height = 0;
u32 running_width = 0;
for (u8 c = 0; c < 128; c++)
{
// Load character glyph
@ -115,7 +118,7 @@ namespace lunarium
Character character = Character
{
c, pixel_data, 0, 0, Sizeu { width, height },
c, pixel_data, 0, 0, Sizei { (i32)width, (i32)height },
glm::vec2((float)face->glyph->bitmap_left, (float)face->glyph->bitmap_top), // bearing
(int)face->glyph->bitmap.rows - face->glyph->bitmap_top, // downshift
(unsigned int)face->glyph->advance.x // advance
@ -147,6 +150,13 @@ namespace lunarium
}
}
// Set the character's texture offsets to the max values
for (int i = 0; i < mFonts.back().CharSet.size(); i++)
{
mFonts.back().CharSet[i].TextureDataWidthOffset = max_width * i;
mFonts.back().CharSet[i].TextureDataHeightOffset = 0; // TEXTURE IS ONE ROW SO THIS IS ALWAYS ZERO
}
// Put the font texture together
u32 single_row_width = f.CharSet.size() * max_width;
if (single_row_width > Texture::GetMaxSize())
@ -190,9 +200,85 @@ namespace lunarium
return fontIdx;
}
void TextRenderer::DrawString(Renderer2D& r, u32 font_id, const char* str, Rectangle bounding_box, Color c, float scale)
void TextRenderer::DrawString(Renderer2D& r, u32 font_id, const char* str, Rectangle bounding_box, Color color, float scale)
{
if (font_id < 0 || font_id >= mFonts.size())
{
Logger::Error(LogCategory::GRAPHICS, "Invalid font ID specified for DrawString: %d", font_id);
return;
}
float lineSize = (mFonts[font_id].MaxHeight + mFonts[font_id].MaxDownShift) * scale;
float curX = bounding_box.left(); //topLeft.x;
float curY = bounding_box.top(); //topLeft.y;
// Iterate through all characters
int len = (int)strlen(str);
for (int c = 0; c < len; c++)
{
// if the last character was a space then we must
// be starting a new word
if (c > 0 && ' ' == str[c - 1])
{
// check the total advance of this word to see if
// it would go beyond the right boundry
float totalAdvance = 0;
for (int i = c; str[i] != ' ' && str[i] != '\0'; i++)
{
Character ch = mFonts[font_id].CharSet[str[c]];
totalAdvance += (ch.Advance >> 6) * scale;
}
if (curX + totalAdvance > bounding_box.right())
{
curX = bounding_box.left();
curY += lineSize;
}
if (curY + lineSize > bounding_box.bottom())
{
break;
}
}
Character ch = mFonts[font_id].CharSet[str[c]];
float xpos = curX + ch.Bearing.x * scale;
float ypos = curY + (mFonts[font_id].MaxHeight - ch.Size.Height) * scale;
// Apply a down offset if the char should go below the baseline
ypos += (ch.DownShift * scale);
// NOTE: The following code does not work because it assumes that positive y is the upward direction
//
//GLfloat test_ypos = curY + (ch.Size.Height - ch.Bearing.Y) * scale;
//
float w = ch.Size.Width * scale;
float h = ch.Size.Height * scale;
// Update VBO for each character
// float vertices[6][4] = {
// { xpos, ypos + h, 0.0, 1.0 },
// { xpos + w, ypos, 1.0, 0.0 },
// { xpos, ypos, 0.0, 0.0 },
// { xpos, ypos + h, 0.0, 1.0 },
// { xpos + w, ypos + h, 1.0, 1.0 },
// { xpos + w, ypos, 1.0, 0.0 }
// };
// Now advance cursors for next glyph (note that advance is number of 1/64 pixels)
curX += (ch.Advance >> 6) * scale; // Bitshift by 6 to get value in pixels (2^6 = 64)
// DrawQuad
float offset_x = ch.TextureDataWidthOffset;
float offset_y = ch.TextureDataHeightOffset;
Rectangle tex_region = Rectangle::MakeFromTopLeft(offset_x, offset_y, ch.Size.Width, ch.Size.Height);
r.DrawQuad(Rectangle::MakeFromTopLeft(xpos, ypos, w, h), color, mFonts[font_id].FontTexture, 0.0f, tex_region);
}
}

@ -53,7 +53,7 @@ namespace lunarium
u8* PixelDataBuffer; // Temporary storage for the character's pixel data - this should be cleanup after the font texture is created
u32 TextureDataWidthOffset; // how far into the row does this chars texture data begin
u32 TextureDataHeightOffset; // how far into the col does this chars texture data begin
Sizeu Size; // Size of glyph
Sizei Size; // Size of glyph
glm::vec2 Bearing; // Offset from baseline to left/top of glyph
int DownShift; // Size/Amount of glyph below the baseline
unsigned int Advance; // Offset to advance to next glyph
@ -65,7 +65,7 @@ namespace lunarium
std::string Name;
// The tallest character that does not go below the base line
// This is also the distance from the string Y position to the baseline
u32 MaxHeight;
i32 MaxHeight;
// This is the max distance a char will go below the baseline
u32 MaxDownShift;

@ -27,7 +27,7 @@
namespace lunarium
{
SimpleRenderScene::SimpleRenderScene(uint32_t logCat)
: BaseScene(logCat), mTestMode(TestMode::String), mFrameTime(0.0), mNumFrames(0)
: BaseScene(logCat), mTestMode(TestMode::Basic), mFrameTime(0.0), mNumFrames(0), mpTestImageLoad3(nullptr)
{
srand((u32)time(0));
}
@ -65,9 +65,10 @@ namespace lunarium
mSrcWidth = w;
mSrcHeight = h;
//delete[] buffer;
delete[] buffer;
stbi_set_flip_vertically_on_load(0);
buffer = stbi_load("debug_texture.jpeg", &w, &h, &n, 0);
//buffer = stbi_load("lunarium_text_test.png", &w, &h, &n, 0);
format = TextureFormat::RGBA;
if (n == 3)
@ -80,7 +81,23 @@ namespace lunarium
}
mpTestImageLoad2 = Texture::Create(buffer, w, h, format);
//delete[] buffer;
delete[] buffer;
stbi_set_flip_vertically_on_load(0);
buffer = stbi_load("lunarium_text_test.png", &w, &h, &n, 0);
format = TextureFormat::RGBA;
if (n == 3)
{
format = TextureFormat::RGB;
}
else if (n == 1)
{
format = TextureFormat::RED;
}
mpTestImageLoad3 = Texture::Create(buffer, w, h, format);
delete[] buffer;
mQuads = new Rectangle[NUM_QUADS];
for (int i = 0; i < NUM_QUADS; i++)
@ -181,10 +198,16 @@ namespace lunarium
mTestMode = TestMode::Stress;
else if (mTestMode == TestMode::Stress)
{
mSubTex = Rectangle::MakeFromTopLeft(2858, 0, 32, 32);
mTestMode = TestMode::String;
}
else if (mTestMode == TestMode::String)
{
mTestMode = TestMode::Basic;
mSubTex = Rectangle::MakeFromTopLeft(0, 0, 256, 256);
}
}
if (Core::Input().IsKeyPressed(KeyCode::Q))
@ -331,9 +354,13 @@ namespace lunarium
void SimpleRenderScene::RenderStringTest(Renderer2D& g)
{
Texture* dt = g.GetTextDebugTexture();
g.DrawQuad(Rectangle(mTextDebugPosX, 400, dt->GetWidth() , dt->GetHeight() ), Color::Blue(), dt);
g.DrawQuad(Rectangle(mTextDebugPosX, 300, dt->GetWidth() , dt->GetHeight() ), Color::Blue(), dt);
g.DrawQuad(Rectangle(200, 100, 32, 32), Color(0.25f, 0.75f, 0.6f, 1.0f), mpTestImageLoad3, 0.0f, mSubTex);
g.DrawString("A", Rectangle(200, 170, 32, 32), Color(0.25f, 0.75f, 0.6f, 1.0f));
//g.DrawString("This is a test string!", Rectangle(100, 400, 200, 50), Color::Green());
g.DrawString("This is a test string!", Rectangle::MakeFromTopLeft(100, 500, 500, 50), Color::Green());
g.DrawString("This is a very long string that should end up on more than one line when printed out test string!", Rectangle::MakeFromTopLeft(300, 50, 400, 500), Color::Red());
}

@ -43,6 +43,7 @@ namespace lunarium
Texture* mpRenderedImage;
Texture* mpTestImageLoad;
Texture* mpTestImageLoad2;
Texture* mpTestImageLoad3;
FrameBuffer* mFrameBufferOne;
FrameBuffer* mFrameBufferTwo;
float angle;
@ -60,12 +61,14 @@ namespace lunarium
TestMode mTestMode;
// STRESS TEST MODE
int mNumQuadsToRender = 500;
bool mUseTextures = false;
const int NUM_QUADS = 50000;
Color* mQuadColors;
Rectangle* mQuads;
Texture** mQuadTexures;
//
struct GridTestObj
{

Loading…
Cancel
Save