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

Font Change #39

Closed
oct0 opened this issue Aug 29, 2014 · 27 comments
Closed

Font Change #39

oct0 opened this issue Aug 29, 2014 · 27 comments

Comments

@oct0
Copy link

oct0 commented Aug 29, 2014

This is more of a request than an issue.

Is there an easy way to change the font? I'm trying to embed this in my application, and the font is somewhat anti-aliased and pixelated.

@ChengduLittleA
Copy link

Why not consider use Freetype?It has anti-aliase mode to render characters into bitmaps then you can draw them as textured quads in OpenGL/DX.And Freetype is NOT a platform-specific library,you can use it everywhere.

@oct0
Copy link
Author

oct0 commented Aug 29, 2014

I'm looking for a imgui-specific change. Plus freetype is a whole library with another dependency. I just want a way to change the default imgui font.

@ocornut
Copy link
Owner

ocornut commented Aug 29, 2014

oct0:

a) If the font isn't crisp (compare your render to the screenshot) it means your rendering hasn't been set up correctly. First make sure you update to the latest version, then try 1/ to offset your projection matrix by (0.5,0.5) pixels or (0.375,0.375), or 2/ change GetIO().PixelCenterOffset to 0.5 or 0.375 or 0.0

b) in case you really want to change the font, which I think you don't actually need to if your problem is a rendering issue. You can use the BMFont software to export a .png and .fnt data. I will however update the folder structure to include other fonts at some point.

c) I actually would like to use truetype at some point. freetype is out of question, it is too big and goes against the fundation principle of imgui. But stb_truetype.h by Sean Barrett is a single file and does it but unfortunately I couldn't figure out how to export non-anti aliased font by the proggy_clean font used by default in ImGui. I will reinvestigate using truetype later if I can get nice visual output for small fonts.

@oct0
Copy link
Author

oct0 commented Aug 29, 2014

Thanks for the quick reply

Nothing against the font you are using now, but it doesn't look suitable for my needs. I'll see if using BMFont works and report back then.

@ocornut
Copy link
Owner

ocornut commented Aug 29, 2014

But you said that the font has some sort of "anti-aliasing" and it shouldn't. All the pixels should be pure opaque white or invisible. This kind of 1-pixel thick bitmap font looks terrible and unreadable with anti-aliasing or incorrect render that is why you want to make sure it is being rendered correctly.

@oct0
Copy link
Author

oct0 commented Aug 30, 2014

I'm sorry for the bad terminology, the rendering of the text seems fine(it's identical to the pictures you have up). It's just the font I don't like

@oct0
Copy link
Author

oct0 commented Aug 30, 2014

Ok. I'm having a problem. Once I copied down all my png and font data to a C++ array, I build fine. Then when I run it's giving me the ol' access violation reading location. Here's my initialization code:

// Load font texture
glGenTextures(1, &fontTex);
glBindTexture(GL_TEXTURE_2D, fontTex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
const void* png_data;
unsigned int png_size;
ImGui::GetDefaultFontData(NULL, NULL, &png_data, &png_size);
int tex_x, tex_y, tex_comp;
void* tex_data = stbi_load_from_memory((const unsigned char*)png_data, (int)png_size, &tex_x, &tex_y, &tex_comp, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_x, tex_y, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_data);
stbi_image_free(tex_data);

And it's giving me the error on line stbi_image_free();.

Have you run into this problem before? If so, how is it fixed?

Thanks

And here's the exact debug message:
Unhandled exception at 0x53EBAF13 (ig75icd32.dll) in program.exe: 0xC0000005: Access violation reading location 0x04CF8000.

@ocornut
Copy link
Owner

ocornut commented Aug 30, 2014

You don't need to have your png and font data in a C++ array, just load them from file. ImGui embed the default .fnt and .png so it is easier to distribute. ImGui doesn't load/know about your texture so you can load the font image into a texture any way that is convenient for you, maybe your engine has function to load pictures etc.

I used stb_image in the OpenGL sample. I suppose that in your case stbi_load_from_memory() returned NULL and the stbi_image_free() call crashes. Maybe your png data is incorrect?
I will upload some texture data in the folder shortly.

@oct0
Copy link
Author

oct0 commented Aug 30, 2014

That's what I thought at first, but I'm able to open it up in GIMP. Shouldn't that be an indicator that the texture data isn't corrupt?

"you can load the font image into a texture any way that is convenient for you, maybe your engine has function to load pictures etc."

But how would I load the font data?

@ocornut
Copy link
Owner

ocornut commented Aug 30, 2014

To load the font data:

ImGui::GetIO().Font = new ImBitmapFont();
ImGui::GetIO().Font->LoadFromFile(filename);

You also have to set FontSize (see how ImGui does it at the beginning of Update()) but I wil make that automatic in my next commit.

On 2014/08/30, at 15:38, oct0 notifications@github.com wrote:

That's what I thought at first, but I'm able to open it up in GIMP. Shouldn't that be an indicator that the texture data isn't corrupt?

"you can load the font image into a texture any way that is convenient for you, maybe your engine has function to load pictures etc."

But how would I load the font data?


Reply to this email directly or view it on GitHub.

@oct0
Copy link
Author

oct0 commented Aug 30, 2014

I'm sorry, but I don't see an Update() function in imgui, or any of the examples you gave. I see the ImGuiUpdate function in the example code, but saw nothing relating to font size.

@ocornut
Copy link
Owner

ocornut commented Aug 30, 2014

Sorry I meant NewFrame() - update was its old name :)

On 2014/08/30, at 17:02, oct0 notifications@github.com wrote:

I'm sorry, but I don't see an Update() function in imgui, or any of the examples you gave. I see the ImGuiUpdate function in the example code, but saw nothing relating to font size.


Reply to this email directly or view it on GitHub.

@oct0
Copy link
Author

oct0 commented Aug 30, 2014

Alright, sorry for being so thick headed right now. But I can't figure out what I'm doing wrong.

Here's my code:

ImGui::GetIO().Font = new ImBitmapFont();
ImGui::GetIO().Font->LoadFromFile("..\\res\\font\\nue.fnt");
ImGui::GetIO().FontHeight = ImGui::GetIO().Font->GetFontSize();

This is literally a copy of the one in the NewFrame function, only I'm loading from the file. The last line gives me the error. What am I missing here?

@ocornut
Copy link
Owner

ocornut commented Aug 30, 2014

I think the font loading failed (probably your path is wrong?) - it returns false on failure. Check your path or the starting directory?
What I'll do to is I'll add an assertion in GetFontSize() and one in NewFrame() that will notify you if the font isn't loaded.

@ocornut
Copy link
Owner

ocornut commented Aug 30, 2014

Made a commit to remove FontHeight (it is now automatic) and added some extra assertion if the font isn't loaded.
8fc50f5

@ocornut
Copy link
Owner

ocornut commented Aug 30, 2014

I was exporting more fonts to include them in the package by default. In Export Options to need to export as BINARY and not as Text/XML! That may be the reason why ImGui is failing to load them. I will clarify this in the documentation.

@ocornut
Copy link
Owner

ocornut commented Aug 30, 2014

I have added an "extra_fonts" folder with some pre-exported fonts and more detailed instructions on how to export your own fonts.

@oct0
Copy link
Author

oct0 commented Aug 30, 2014

That last comment saved me! That should have been obvious to the start because of the function name BINARYtoc.

Yes, my text is now successfully loading. Although the weird thing is only the text is rendering. I don't see any window decorations. I'm assuming it's something wrong with my texture loading.

@zao
Copy link

zao commented Aug 30, 2014

Isn't there a requirement that there shall be a white pixel at the FontTexUvForWhite UV coordinate? Maybe your font images are missing it, much all the extra_fonts images except for proggy_clean_13?

@oct0
Copy link
Author

oct0 commented Aug 30, 2014

How do I test for something like that? I'm experiencing some really weird behavior, as the only thing that's rendering is the font. The behavior's still there, just not the actual rendering.

@ocornut
Copy link
Owner

ocornut commented Aug 30, 2014

As Lars pointed out, you have to set io.FontTexUvForWhite to a texture coordinate value that refers to a white pixel. By default this value is (0,0) which requires your font texture to have a white pixel on the upper left corner.

Say if you have a white pixel at position (5.10) and your texture is 256x256 pixels, set Io.FontTexUvForWhite to (5.0f,256, 100f/256).

On 2014/08/30, at 21:45, oct0 notifications@github.com wrote:

How do I test for something like that? I'm experiencing some really weird behavior, as the only thing that's rendering is the font. The behavior's still there, just not the actual rendering.


Reply to this email directly or view it on GitHub.

@oct0
Copy link
Author

oct0 commented Aug 30, 2014

I've tried this, and it doesn't work. Although when I comment out the glTexImage2D command, all the window decorations work. The text shows up as gray bars.

@ocornut
Copy link
Owner

ocornut commented Aug 31, 2014

If you don't bind the texture it won't work. Show us your texture and the UV value you set, the later is most certainly incorrect.
PS: I've been adding extra comments in the documentation following our discussion to make it easier for future users to do the same thing.

@oct0
Copy link
Author

oct0 commented Aug 31, 2014

neutronium_0

    ImGui::GetIO().FontTexUvForWhite = ImVec2(72, 35);

I've also tried different values, but nothing has worked so far. I got the coordinates from GIMP's lower bar and my mouse.

@ocornut
Copy link
Owner

ocornut commented Aug 31, 2014

You need to divide pixel coordinates by the texture size to get texture coordinates. So something like (72.0f/256, 35.0f/256).

@oct0
Copy link
Author

oct0 commented Aug 31, 2014

Ohhh wow I knew something was missing! Well, it's all working besides transparency(the text has black outline around it). And yes, I'm using GL_RGBA when creating my texture.

@ocornut
Copy link
Owner

ocornut commented Aug 31, 2014

Your image doesn't have an alpha channel (as seen when loaded with paint.net).

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

No branches or pull requests

4 participants