@ -7,6 +7,7 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "text_renderer.h"
# include "text_renderer.h"
# include "renderer2D.h"
# include <utils/logger.h>
# include <utils/logger.h>
# include "texture.h"
# include "texture.h"
@ -99,6 +100,8 @@ namespace lunarium
u32 max_width = 0 ;
u32 max_width = 0 ;
u32 max_height = 0 ;
u32 max_height = 0 ;
u32 running_width = 0 ;
for ( u8 c = 0 ; c < 128 ; c + + )
for ( u8 c = 0 ; c < 128 ; c + + )
{
{
// Load character glyph
// Load character glyph
@ -115,7 +118,7 @@ namespace lunarium
Character character = Character
Character character = Character
{
{
c , pixel_data , 0 , 0 , Size u { width , height } ,
c , pixel_data , 0 , 0 , Size i { ( i32 ) width , ( i32 ) height } ,
glm : : vec2 ( ( float ) face - > glyph - > bitmap_left , ( float ) face - > glyph - > bitmap_top ) , // bearing
glm : : vec2 ( ( float ) face - > glyph - > bitmap_left , ( float ) face - > glyph - > bitmap_top ) , // bearing
( int ) face - > glyph - > bitmap . rows - face - > glyph - > bitmap_top , // downshift
( int ) face - > glyph - > bitmap . rows - face - > glyph - > bitmap_top , // downshift
( unsigned int ) face - > glyph - > advance . x // advance
( 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
// Put the font texture together
u32 single_row_width = f . CharSet . size ( ) * max_width ;
u32 single_row_width = f . CharSet . size ( ) * max_width ;
if ( single_row_width > Texture : : GetMaxSize ( ) )
if ( single_row_width > Texture : : GetMaxSize ( ) )
@ -190,9 +200,85 @@ namespace lunarium
return fontIdx ;
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 c olor , 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 ) ;
}
}
}