Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unable to use custom font #22

Closed
sadguitarius opened this issue Feb 18, 2025 · 6 comments
Closed

unable to use custom font #22

sadguitarius opened this issue Feb 18, 2025 · 6 comments

Comments

@sadguitarius
Copy link

sadguitarius commented Feb 18, 2025

Hi, not sure if this is the best place to post, but I'm struggling trying to adapt the demo to use a custom font. I've attempted to pull the relevant code from imgui-highdpi-sapp.cc in the sokol-samples repo and adapt it to C (and copied over the header with font data). I can build and run the demo, but all text is missing. As in there's not even empty space or white blocks where text should be, just nothing at all. I'm sure I'm misunderstanding something, but this looks to me like it should work. Thank you!

//------------------------------------------------------------------------------
//  Simple C99 cimgui+sokol starter project for Win32, Linux and macOS.
//------------------------------------------------------------------------------
#include "cimgui.h"
#include "imgui_font.h"
#include "sokol_app.h"
#include "sokol_gfx.h"
#include "sokol_glue.h"
#include "sokol_imgui.h"
#include "sokol_log.h"

static struct {
  sg_pass_action pass_action;
} state;

static void init(void) {
  sg_setup(&(sg_desc){
      .environment = sglue_environment(),
      .logger.func = slog_func,
  });
  // simgui_setup(&(simgui_desc_t){ 0 });

  // setup sokol-imgui, but provide our own font
  simgui_desc_t simgui_desc = {};
  simgui_desc.no_default_font = true;
  simgui_desc.logger.func = slog_func;
  simgui_setup(&simgui_desc);

  // configure Dear ImGui with our own embedded font
  ImGuiIO *io = igGetIO();
  ImFontConfig fontCfg = {};
  fontCfg.FontDataOwnedByAtlas = false;
  fontCfg.OversampleH = 2;
  fontCfg.OversampleV = 2;
  fontCfg.RasterizerMultiply = 1.5f;
  ImFontAtlas_AddFontFromMemoryTTF(io->Fonts, dump_font, sizeof(dump_font),
                                   16.0f, &fontCfg, NULL);

  // create font texture and linear-filtering sampler for the custom font
  // NOTE: linear filtering looks better on low-dpi displays, while
  // nearest-filtering looks better on high-dpi displays
  simgui_font_tex_desc_t font_texture_desc = {};
  font_texture_desc.min_filter = SG_FILTER_LINEAR;
  font_texture_desc.mag_filter = SG_FILTER_LINEAR;
  simgui_create_fonts_texture(&font_texture_desc);

  // initial clear color
  state.pass_action =
      (sg_pass_action){.colors[0] = {.load_action = SG_LOADACTION_CLEAR,
                                     .clear_value = {0.0f, 0.5f, 1.0f, 1.0}}};
}

static void frame(void) {
  simgui_new_frame(&(simgui_frame_desc_t){
      .width = sapp_width(),
      .height = sapp_height(),
      .delta_time = sapp_frame_duration(),
      .dpi_scale = sapp_dpi_scale(),
  });

  /*=== UI CODE STARTS HERE ===*/
  igSetNextWindowPos((ImVec2){10, 10}, ImGuiCond_Once);
  igSetNextWindowSize((ImVec2){400, 100}, ImGuiCond_Once);
  igBegin("Hello Dear ImGui!", 0, ImGuiWindowFlags_None);
  igColorEdit3("Background", &state.pass_action.colors[0].clear_value.r,
               ImGuiColorEditFlags_None);
  igShowMetricsWindow(NULL);
  igEnd();
  /*=== UI CODE ENDS HERE ===*/

  sg_begin_pass(
      &(sg_pass){.action = state.pass_action, .swapchain = sglue_swapchain()});
  simgui_render();
  sg_end_pass();
  sg_commit();
}

static void cleanup(void) {
  simgui_shutdown();
  sg_shutdown();
}

static void event(const sapp_event *ev) { simgui_handle_event(ev); }

sapp_desc sokol_main(int argc, char *argv[]) {
  (void)argc;
  (void)argv;
  return (sapp_desc){
      .init_cb = init,
      .frame_cb = frame,
      .cleanup_cb = cleanup,
      .event_cb = event,
      .window_title = "Hello Sokol + Dear ImGui",
      .width = 800,
      .height = 600,
      .fullscreen = true,
      .high_dpi = true,
      .icon.sokol_default = true,
      .logger.func = slog_func,
  };
}

edit: I cleaned up the fontCfg struct a little

@floooh
Copy link
Owner

floooh commented Feb 19, 2025

I could reproduce the issue but also was able to fix it... it looks like the cimgui C-API wrapper doesn't properly initialize default values in the ImFontCfg struct, so you'll have to explicitly provide a couple of additional values which are not needed in the C++ API (and you can also use C99 designated init which looks a bit nicer):

    simgui_setup(&(simgui_desc_t){
        .no_default_font = true,
        .logger.func = slog_func,
    });

    ImFontConfig fontCfg = {
        .FontDataOwnedByAtlas = false,
        .OversampleH = 2,
        .OversampleV = 2,
        .GlyphMaxAdvanceX = 1024.0f,    // some arbitrary big value
        .RasterizerMultiply = 1.5f,
        .RasterizerDensity = 1.0f,
    };
    ImFontAtlas_AddFontFromMemoryTTF(igGetIO()->Fonts, dump_font, sizeof(dump_font), 16.0f, &fontCfg, 0);

    simgui_create_fonts_texture(&(simgui_font_tex_desc_t){
        .min_filter = SG_FILTER_LINEAR,
        .mag_filter = SG_FILTER_LINEAR,
    });

The important changes are in the ImFontConfig. For a nicer quality you should also set .high_dpi = true, down in sokol_main. With those changes I get:

Image

@floooh floooh closed this as completed Feb 19, 2025
@sadguitarius
Copy link
Author

Fantastic! Thank you so much. I'll keep that in mind when using cimgui and check default values in the C++ API. I was getting a crash using designated initializers before the proper default values were in there, so I thought that was breaking things somehow. Anyway, thank you!

@sonoro1234
Copy link

it looks like the cimgui C-API wrapper doesn't properly initialize default values in the ImFontCfg struct

You can create an ImFontConfig* which is correctly initialized with ImFontConfig_ImFontConfig()
Please give me some feedback on the next issue

@sadguitarius
Copy link
Author

I think I may have been a little mixed up here, but cimgui in this repo is generated in a different manner than the cimgui here right? I'm new to this library and trying to follow the trail of the different bindings. Apologies to all who I may have confused in my own confusion.

@floooh
Copy link
Owner

floooh commented Feb 22, 2025

Yes the Dear ImGui bindings used in the cimgiui-sokol-starterkit repo are generated with the Dear ImGui approach. I just used the 'ig' prefix and the cimgui library name so I only had to change the few differences between the original cimgui bindings and the Dear ImGui bindings.

@sadguitarius
Copy link
Author

Got it! And so relating to the missing constructor in this repository, I guess this is a whole thing with dearbindings. I understand things are changing quickly so I'll try not to annoy people any further while I'm figuring this stuff out. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants