![]() |
|
This thread is locked; no one can reply to it.
![]() ![]() |
1
2
|
[A5] TTF Fonts not caching correctly? |
jmasterx
Member #11,410
October 2009
|
I'm using Allegro 5.0.5 In the game I'm making, the game's text dynamically resizes and therefore I load and use a lot of fonts. Each Gui component, when receiving a resize event accesses the font manager and sets its font to the appropriate font. I load fonts in the constructor of the core class, after Allegro has been initialized and after a display has been created. 1 Core::Core(int argc, char *argv[])
2 :display(NULL),
3 m_fontManager(NULL)
4 {
5 //initialize Allegro 5
6 _initAllegro();
7
8 //initialize Agui
9 _initAgui();
10
11 //create the display
12 Vec2 optimalSize = Display::getOptimalResoluton();
13 display = new Display(optimalSize.getX(),optimalSize.getY());
14 appIcon = new Sprite("res/appico.png");
15 display->setIcon(appIcon);
16
17 //init font manager
18 m_fontManager = new GuiFontManager("res/font.ttf",8,32,17);
19 agui::Widget::setGlobalFont(m_fontManager->getDefaultFont());
20
21 //create the scene manager
22 sceneManager = new SceneManager(settings, m_dynamicUIManager);
23 display->setSceneMessenger(sceneManager);
24
25 }
26...
27 GuiFontManager::GuiFontManager(
28 const std::string& fontPath, int beginRange, int endRange, int defaultSize )
29 : m_beginRange(beginRange), m_endRange(endRange), m_defaultSize(defaultSize)
30 {
31 for(int i = beginRange; i <= endRange; ++i)
32 {
33 m_fonts.push_back(agui::Font::load(fontPath,i));
34 }
35 }
My issue is when I get into a scene and start using a bunch of these fonts. Sometimes only part of a word is rendered, and on occasion, a glyph is totally the wrong one. I also tried, after loading a font to render the alphabet and this actually helped, but there were still certain circumstances when the word 'Across' rendered as 'Acro' or 'o'. I've looked through my code for hours trying to find something wrong with it but I cannot seem to find anything wrong. Is there some sort of precaution to take when loading and using around 40 TTF fonts? Thanks Agui GUI API -> https://github.com/jmasterx/Agui |
MiquelFire
Member #3,110
January 2003
![]() |
Sounds like an issue I had with my last SpeedHack game, only I loaded only two. In my case, only some computers failed to load the fonts correctly. --- |
jmasterx
Member #11,410
October 2009
|
On my PC, the same exe and conditions cause different letters to show and different letters not to... I do not know what to do. It is very important for me to be able to have this feature. Edit: I can confirm that this only happens with Direct3D, not OpenGL. Agui GUI API -> https://github.com/jmasterx/Agui |
Peter Wang
Member #23
April 2000
|
Best provide a test case.
|
Trent Gamblin
Member #261
April 2000
![]() |
I think I had a similar issue with the D3D driver at one point. I fixed it by making sure bitmaps were a minimum size, I think 16x16. Not sure if it's related. I don't know for certain but I assumed that fix was either done before 5.0 was released or ported back.
|
jmasterx
Member #11,410
October 2009
|
Here is an example that produces the problem. It seems to happen when calling al_get_text_width and loading many fonts. 1#include <stdio.h>
2#include <allegro5/allegro.h>
3#include <allegro5/allegro5.h>
4#include <allegro5/allegro_primitives.h>
5#include <allegro5/allegro_font.h>
6#include <allegro5/allegro_ttf.h>
7#include "stdlib.h"
8#include <vector>
9struct Example
10{
11 double fps;
12 ALLEGRO_CONFIG *config;
13} ex;
14//Globals are bad but it is an example
15std::vector<ALLEGRO_FONT*> m_fonts;
16
17static const char *get_string(const char *key)
18{
19 const char *v = al_get_config_value(ex.config, "", key);
20 return (v) ? v : key;
21}
22
23static void render(void)
24{
25 al_clear_to_color(al_map_rgb(0,0,0));
26
27 int fontSz = al_get_display_height(al_get_current_display()) * 0.03f;
28 if(fontSz >= m_fonts.size())
29 {
30 fontSz = m_fonts.size() - 1;
31 }
32
33 al_draw_text((m_fonts[fontSz]),al_map_rgb(255,255,255),0,0,0,"ABCDEFGHIJKLMNOPQRSTUVWXYZ");
34
35 al_get_text_width(m_fonts[6],"ALLEGRO");
36}
37
38int main(int argc, const char *argv[])
39{
40 const char *font_file = "data/DejaVuSans.ttf";
41 ALLEGRO_DISPLAY *display;
42 ALLEGRO_TIMER *timer;
43 ALLEGRO_EVENT_QUEUE *queue;
44 int redraw = 0;
45 double t = 0;
46
47 if(!al_init())
48 {
49 return 1;
50 }
51
52
53 if(!al_init_primitives_addon())
54 {
55 return 1;
56 }
57
58 al_init_font_addon();
59
60 if(!al_init_ttf_addon())
61 {
62 return 1;
63 }
64
65
66 al_set_new_display_flags(ALLEGRO_RESIZABLE);
67 display = al_create_display(640, 480);
68 if (!display) {
69 return 1;
70 }
71 al_install_keyboard();
72
73 //load the fonts
74 for(int i = 8; i < 32; ++i)
75 {
76 m_fonts.push_back(al_load_font(font_file,i,0));
77 }
78
79 timer = al_create_timer(1.0 / 60);
80
81 queue = al_create_event_queue();
82 al_register_event_source(queue, al_get_keyboard_event_source());
83 al_register_event_source(queue, al_get_display_event_source(display));
84 al_register_event_source(queue, al_get_timer_event_source(timer));
85
86 al_start_timer(timer);
87 while (true) {
88 ALLEGRO_EVENT event;
89 al_wait_for_event(queue, &event);
90 if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
91 break;
92 if (event.type == ALLEGRO_EVENT_KEY_DOWN &&
93 event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) {
94 break;
95 }
96 if (event.type == ALLEGRO_EVENT_TIMER)
97 redraw++;
98
99 if(event.type == ALLEGRO_EVENT_DISPLAY_RESIZE)
100 {
101 al_acknowledge_resize(display);
102
103 }
104
105 while (redraw > 0 && al_is_event_queue_empty(queue)) {
106 double dt;
107 redraw--;
108
109 dt = al_get_time();
110 render();
111 dt = al_get_time() - dt;
112
113 t = 0.99 * t + 0.01 * dt;
114
115 ex.fps = 1.0 / t;
116 al_flip_display();
117 }
118 }
119 //free mem
120
121 return 0;
122}
123
124/* vim: set sts=4 sw=4 et: */
Just keep resizing the window until you see the image I've attached: It's quite tricky to reproduce. If I draw the alphabet with all the loaded fonts the issue does not occur. Agui GUI API -> https://github.com/jmasterx/Agui |
Trent Gamblin
Member #261
April 2000
![]() |
Something to do with display lost/found probably. When you resize a window D3D has to reinit all bitmaps from system memory, including fonts.
|
jmasterx
Member #11,410
October 2009
|
Do you think it can be fixed? I do not want to use GL on Windows because: When it resizes it flickers. Theres no way to address this because I cant get a resize begin / end events and therefore cannot render black while resizing. And it reduces a lot of compatibility. If a person does not have an OpenGL driver from NVidia or ATI Allegro does not work well. Also, it seems like it does have to do with resizing. If I launch the Window at 320x240, it does not happen (but in my game it still does, just differently). Agui GUI API -> https://github.com/jmasterx/Agui |
Trent Gamblin
Member #261
April 2000
![]() |
I'm sure it can be fixed. Change the fonts to use memory bitmaps. See if that "fixes" it. I know it'll be slow but that'll narrow down the bug.
|
jmasterx
Member #11,410
October 2009
|
Yup 'fixes' the problem. It also 'fixes' it for my game. Agui GUI API -> https://github.com/jmasterx/Agui |
Trent Gamblin
Member #261
April 2000
![]() |
Now try cycling through different sizes without resizing (using video bitmaps). Just have a font_index, increase it each render and wrap it around to zero. See if you have any problems.
|
jmasterx
Member #11,410
October 2009
|
Cycling does not have the issue. However, when cycling, I can resize and the issue does not happen. Agui GUI API -> https://github.com/jmasterx/Agui |
Trent Gamblin
Member #261
April 2000
![]() |
Yeah, it seems like a threading issue. WM_SIZE events come in on a separate thread than the user thread (the one you write your code on.) So a bitmap "backup" must be performed before the resize takes place, and _flip() should probably be blocked with a mutex until all of this is done.
|
Thomas Fjellstrom
Member #476
June 2000
![]() |
If the bitmaps are invalidated, just send down the LOST_DISPLAY event and call it a day -- |
Trent Gamblin
Member #261
April 2000
![]() |
That's not required to be handled by Allegro user programs. They can handle it if they choose, and skip all of the automatic stuff in favor of perhaps a little more performance and flexibility. But I think it's too complicated and different from other platforms that it shouldn't be the only way.
|
jmasterx
Member #11,410
October 2009
|
Most games I see using D3D that resize do postpone display flipping until resizing is done. This causes the game to also look better when resizing. Instead of a fuzzy stretched version of your output you get the last frame and some black which to me looks more elegant anyways. It just seems to me like it is better not to render while resizing; On all platforms too. Agui GUI API -> https://github.com/jmasterx/Agui |
Trent Gamblin
Member #261
April 2000
![]() |
Can you build 5.1 svn and try that? It probably doesn't work, but you'll be ready to test some patches in case I feel like trying to fix this now
|
jmasterx
Member #11,410
October 2009
|
Would you happen to have FreeType and some of Allegro's other deps (for MSVC 9)? Otherwise it might take a while. I can compile core Allegro without trouble, but the TTF and other addons need the deps. Agui GUI API -> https://github.com/jmasterx/Agui |
Trent Gamblin
Member #261
April 2000
![]() |
I don't have them, but they come with the A5 binaries on this page that Michal Cichon makes.
|
jmasterx
Member #11,410
October 2009
|
Wouldn't I still need the headers though? I added the .libs to my PATH environment variable and CMAKE still cannot find them. Agui GUI API -> https://github.com/jmasterx/Agui |
MiquelFire
Member #3,110
January 2003
![]() |
I was going to say use the libs from the binary package of 5.0.5, but I noticed you would need to deal with static compiling to do that... [edit] Just noticed that the only header included is the Physfs one (assuming an example needs it) --- |
jmasterx
Member #11,410
October 2009
|
MiquelFire said: [edit] Just noticed that the only header included is the Physfs one (assuming an example needs it) Exactly, that's my problem. Agui GUI API -> https://github.com/jmasterx/Agui |
Peter Wang
Member #23
April 2000
|
I seem to have this file on my Windows system. FreeType comes with MSVC build stuff in builds/win32 so it should not be that hard to build yourself anyway. http://libagar.org/FreeType235-win32-i386.zip Edit: here is a copy of one of my deps directories (I have a few). I do not remember if it works, where all the files came from, how they were built, if anything is missing, or if it is virus infected (I don't use antivirus). Use at your own risk.
|
jmasterx
Member #11,410
October 2009
|
Has there been any progress on the issue. I do not know if you saw the similar OpenGL issue here as well: (Maybe this thread and the other should be moved to the Development section since I guess it is an allegro bug and not an issue with my code which had been my initial speculation) Also, I compiled FreeType, but I'm not sure how to get CMAKE to know where it is. Agui GUI API -> https://github.com/jmasterx/Agui |
Elias
Member #358
May 2000
|
Easiest way is to drop it (both the include and lib folder) into a folder called "deps" in the build folder. -- |
|
1
2
|