diff options
| author | talha <talha@talhaamir.xyz> | 2023-08-31 11:18:52 +0500 | 
|---|---|---|
| committer | talha <talha@talhaamir.xyz> | 2023-08-31 11:18:52 +0500 | 
| commit | df0d5fcea9682c7890f3b0ae5e8caea2a3867199 (patch) | |
| tree | a3d0dfe35f3aac401b93311c7412359b10b25c41 /code | |
| parent | 66e84eabf70a11d91abbbe8777b1746573a51bae (diff) | |
Refactoring font rendering
Diffstat (limited to 'code')
| -rw-r--r-- | code/amr_fonts.h | 51 | ||||
| -rw-r--r-- | code/game_main.h | 11 | ||||
| -rw-r--r-- | code/math.h | 6 | ||||
| -rw-r--r-- | code/win32_main.cpp | 61 | 
4 files changed, 82 insertions, 47 deletions
| diff --git a/code/amr_fonts.h b/code/amr_fonts.h new file mode 100644 index 0000000..f44893c --- /dev/null +++ b/code/amr_fonts.h @@ -0,0 +1,51 @@ +#ifndef AMR_FONTS_H +#define AMR_FONTS_H + +typedef struct amr_glyph_info { +  u32 charset_start_index; +  u32 charset_end_index; +} amr_glyph_info; + +typedef struct amr_font_details_debug { +  i32 advance; +  i32 lsb; +  i32 x0, y0, x1, y1; +  i32 kern; +  f32 lx; +  f32 ly; +  i32 byte_offset; +  i32 baseline; +} debug_font_details; + +typedef struct amr_font_state_debug { +  stbtt_fontinfo font_info; +} amr_font_state; +// initialise a font and loads the font in the fontbuffer +// input:  +// - font path +// - font buffer, must be initialised by caller +// - size of the font file, must be known beforehand +// output: +// - error code +u32 amr_InitFont(const u8 *FontPath, u8 *FontBuffer, u32 FontFz);  +u32 amr_GetGlyphIdFromCodepoint(amr_glyph_info glyph, u32 *GlyphIndexArray, u32 Codepoint); + +u32 amr_InitFont(stbtt_fontinfo *font_info, const char *FontPath, u8 *FontBuffer, u32 FontSz) +{ +  PlatformDebugFileRead(FontPath, FontBuffer, FontSz); +  if (!stbtt_InitFont(font_info, FontBuffer, 0)) +  { +    printf("ERROR: failed to read arial font"); +    assert(1 == 0); +  } + +  return 0; +} + +u32 amr_GetGlyphIdFromCodepoint(amr_glyph_info glyph, u32 *GlyphIndexArray, u32 Codepoint) +{ +  u32 glyph_id = *(GlyphIndexArray + (Codepoint - glyph.charset_start_index)); +  return glyph_id; +} + +#endif diff --git a/code/game_main.h b/code/game_main.h index 2194e27..1b4e1af 100644 --- a/code/game_main.h +++ b/code/game_main.h @@ -33,17 +33,6 @@ typedef struct Rect2 {    Vec2 br;  } Rect2; -typedef struct debug_font_details { -  i32 advance; -  i32 lsb; -  i32 x0, y0, x1, y1; -  i32 kern; -  f32 lx; -  f32 ly; -  i32 byte_offset; -  i32 baseline; -} debug_font_details; -  typedef struct GameState {    GameCamera Camera;    GameInput Input; diff --git a/code/math.h b/code/math.h index ca5e96e..2ab7ac3 100644 --- a/code/math.h +++ b/code/math.h @@ -42,8 +42,8 @@ typedef struct Vec2 {    Vec2 operator/(f32 s)    {      Vec2 R = {0}; -    R.x = x/2; -    R.y = y/2; +    R.x = x/s; +    R.y = y/s;      return R;    } @@ -191,8 +191,6 @@ Vec3 CrossProductVec3(Vec3 S, Vec3 K)      return R;  } - -  // @note: I am creating vectors in many places so created a function to make initialising abit easier  Vec4 InitVec4(f32 x, f32 y, f32 z, f32 w)  { diff --git a/code/win32_main.cpp b/code/win32_main.cpp index 208e85a..4ba86e1 100644 --- a/code/win32_main.cpp +++ b/code/win32_main.cpp @@ -33,6 +33,9 @@ typedef  double   f64;  #define internal static  /** + * - enhance filereading to read bytes + * error todo: + * - start having error codes to help with error detection in case something went wrong in functions   * Font rendering todos:   * - Look into font-packing, what is that? why is it needed?   * - Look into generating a single bitmap and then extracting characters from the  @@ -41,13 +44,14 @@ typedef  double   f64;   * */  internal i64 GlobalPerfCountFrequency; -i8 PlatformDebugReadFile(char *FileName, void *FileBuffer, u32 MaxSize, LPDWORD BytesRead) +u8 PlatformDebugFileRead(const char *FileName, void *FileBuffer, u32 MaxSize)  {    // @todo: refactor function, check for closehandle error codes -  HANDLE FileHandle = CreateFileA(FileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); +  HANDLE FileHandle = CreateFileA(FileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);    if (FileHandle != INVALID_HANDLE_VALUE)    { -    if (ReadFile(FileHandle, FileBuffer, MaxSize, BytesRead, NULL) != 0) +    DWORD BytesRead; +    if (ReadFile(FileHandle, FileBuffer, MaxSize, &BytesRead, NULL) != 0)      {        CloseHandle(FileHandle);        return 1; @@ -100,19 +104,10 @@ Win32GetSecondsElapsed(LARGE_INTEGER Start, LARGE_INTEGER End)  #include "amr_memory.c"  #include "gl_graphics.cpp" +//#include "amr_camera.c" +#include "amr_fonts.h"  #include "game_main.h" -typedef struct amr_glyph_info { -  u32 charset_start_index; -  u32 charset_end_index; -} amr_glyph_info; - -u32 amr_GetGlyphIdFromCodepoint(amr_glyph_info glyph, u32 *GlyphIndexArray, u32 Codepoint) -{ -  u32 glyph_id = *(GlyphIndexArray + (Codepoint - glyph.charset_start_index)); -  return glyph_id; -} -  int main()  {      // ==================== PROGRAM STATE INITIALISATION ===================== @@ -184,14 +179,14 @@ int main()      DWORD BytesRead = 0;      u32 max_fsz = MB((u64)5);      u8 *vs_file = (u8 *)amr_ArenaAlloc(&State.Memory.Arena, max_fsz); -    if (PlatformDebugReadFile("./code/shaders/text.vs.glsl", vs_file, max_fsz, &BytesRead) != 1) +    if (PlatformDebugFileRead("./code/shaders/text.vs.glsl", vs_file, max_fsz) != 1)      {        printf("ERROR: failed to open text vertex shader");        return -1;      }      u8 *fs_file = (u8 *)amr_ArenaAlloc(&State.Memory.Arena, max_fsz); -    if (PlatformDebugReadFile("./code/shaders/text.fs.glsl", fs_file, max_fsz, &BytesRead) != 1) +    if (PlatformDebugFileRead("./code/shaders/text.fs.glsl", fs_file, max_fsz) != 1)      {        printf("ERROR: failed to open text vertex shader");        return -1; @@ -204,25 +199,24 @@ int main()      amr_ArenaFreeAll(&State.Memory.Arena);      // =================== FONT RENDERING =================== +    // @resume: abstracting font rendering to draw text easily +    // --------- Init Font ----------------- +    // input: +    // - filepath, memory buffer, memory buffer size +    // - maybe a font_object reference that I need      u32 font_fz = MB(2);      u8 *ArialBuffer = (u8 *)amr_ArenaAlloc(&State.Memory.Arena, font_fz); +    amr_font_state ArialFontState = {0}; -    // @todo: change to PlatformDebugFileRead -    fread(ArialBuffer, 1, font_fz, fopen("c:/windows/fonts/arial.ttf", "rb")); - -    stbtt_fontinfo font_info; -    if (!stbtt_InitFont(&font_info, ArialBuffer, 0)) -    { -      printf("ERROR: failed to read arial font"); -      assert(1 == 0); -    } +    amr_InitFont(&(ArialFontState.font_info), "c:/windows/fonts/arial.ttf", ArialBuffer, font_fz); +    ///////////////////////////////////// PREPARE TEXT INFO ///////////////////      // get a SF (scale factor) -    f32 SF = stbtt_ScaleForPixelHeight(&font_info, 32.0f); +    f32 SF = stbtt_ScaleForPixelHeight(&(ArialFontState.font_info), 32.0f);      // get vertical metrics      i32 f_ascent, f_descent, f_line_gap; -    stbtt_GetFontVMetrics(&font_info, &f_ascent, &f_descent, &f_line_gap); +    stbtt_GetFontVMetrics(&(ArialFontState.font_info), &f_ascent, &f_descent, &f_line_gap);      // ========================= GLYPH AND FONT INFO STORAGE ================      amr_glyph_info latin_basic = {32, 126}; @@ -231,7 +225,7 @@ int main()      u32 *glyph_array_iter = GlyphIndexArray;      for (u32 i = 0; i < glyph_count; i++)      { -      *glyph_array_iter = stbtt_FindGlyphIndex(&font_info, latin_basic.charset_start_index + i); +      *glyph_array_iter = stbtt_FindGlyphIndex(&(ArialFontState.font_info), latin_basic.charset_start_index + i);         glyph_array_iter++;      } @@ -260,8 +254,8 @@ int main()          continue;        } -      stbtt_GetGlyphHMetrics(&font_info, amr_GetGlyphIdFromCodepoint(latin_basic, GlyphIndexArray, text[i]), &_fi->advance, &_fi->lsb); -      stbtt_GetGlyphBitmapBox(&font_info, amr_GetGlyphIdFromCodepoint(latin_basic, GlyphIndexArray, text[i]), SF, SF, &_fi->x0, &_fi->y0, &_fi->x1, &_fi->y1); +      stbtt_GetGlyphHMetrics(&(ArialFontState.font_info), amr_GetGlyphIdFromCodepoint(latin_basic, GlyphIndexArray, text[i]), &_fi->advance, &_fi->lsb); +      stbtt_GetGlyphBitmapBox(&(ArialFontState.font_info), amr_GetGlyphIdFromCodepoint(latin_basic, GlyphIndexArray, text[i]), SF, SF, &_fi->x0, &_fi->y0, &_fi->x1, &_fi->y1);        _fi->ly = (f32)(_fi->baseline + _fi->y0);        lx += (_fi->advance * SF); @@ -269,7 +263,7 @@ int main()        i32 kern;        if (i < char_sz - 1 && text[i+1] != '\n')        { -        kern = stbtt_GetGlyphKernAdvance(&font_info, amr_GetGlyphIdFromCodepoint(latin_basic, GlyphIndexArray, text[i]), amr_GetGlyphIdFromCodepoint(latin_basic, GlyphIndexArray, text[i+1])); +        kern = stbtt_GetGlyphKernAdvance(&(ArialFontState.font_info), amr_GetGlyphIdFromCodepoint(latin_basic, GlyphIndexArray, text[i]), amr_GetGlyphIdFromCodepoint(latin_basic, GlyphIndexArray, text[i+1]));          lx += roundf(kern * SF);        } @@ -297,11 +291,12 @@ int main()        }        _fi->byte_offset = (i32)(_fi->lx + roundf(_fi->lsb * SF) + (_fi->ly * bitmap_width_from_text_info)) ;        // store image data in bitmap -      stbtt_MakeGlyphBitmap(&font_info, Bitmap + _fi->byte_offset, _fi->x1 - _fi->x0, _fi->y1 - _fi->y0, bitmap_width_from_text_info, SF, SF, amr_GetGlyphIdFromCodepoint(latin_basic, GlyphIndexArray, text[i])); +      stbtt_MakeGlyphBitmap(&(ArialFontState.font_info), Bitmap + _fi->byte_offset, _fi->x1 - _fi->x0, _fi->y1 - _fi->y0, bitmap_width_from_text_info, SF, SF, amr_GetGlyphIdFromCodepoint(latin_basic, GlyphIndexArray, text[i]));        _fi++;      }      // ---------- prepare bitmap texture and buffer objects ----------- +    ////////////////////////////////// PREPARE TEXT FOR RENDERING ////////////      glPixelStorei(GL_UNPACK_ALIGNMENT, 1);      f32 bmp_vertices[] = { @@ -372,6 +367,7 @@ int main()      State.ScreenCoords.tl = ScreenMidCoords - ScreenMidPx;      State.ScreenCoords.br = ScreenMidCoords + ScreenMidPx; +    // ////////////////////// DEFINE TEXT POSITION AND SCALE //////////////////      // ====================== TEXT POSITIONING AND SCALING ======      Vec2 text_dims = {((f32)bitmap_width_from_text_info)/2.0f, ((f32)bitmap_height_from_text_info)/2.0f};      Vec2 text_scaled_dims = State.px_ratio * text_dims; @@ -502,6 +498,7 @@ int main()  #endif          // =============== DRAW TEXT BITMAP RENDERING =============== +        // ////////////////// RENDER TEXT BITMAP /////////////////////////////          {            Model = IdentityMat();            Mat4 Scale = CreateScaleMat(InitVec4(text_scaled_dims.x, text_scaled_dims.y, 1, 0)); | 
