akrinke / Font-Stash

A dynamic font glyph cache for OpenGL.
114 stars 18 forks source link

Recreation of stash when changing resolution adds graphic artifacts #5

Closed ghost closed 11 years ago

ghost commented 11 years ago

Upon losing an OpenGL context with a resolution change in our game, we need to reinitialize the font stashes. However when switching to full screen mode and back to windowed mode, most letters show OK save a few that seem to have artifacts. Here is a screenshot after switching the resolution back and forth:

snapshot4

Note the artifacts on several letters displayed throughout, especially the white text at the top.

After some research, I found this solution to a similar problem: http://stackoverflow.com/questions/1191093/im-seeing-artifacts-when-i-attempt-to-rotate-an-image/1191281#1191281

However after adding the suggested OpenGL calls to various parts within my application and within fontstash.c, the problem is still there.

Could this just be related to my hardware? (I'm running on an NVidia NVS 3100M chip)

Here is how we're using Font-Stash in our application (we initialize with FontManager::initialize()): https://code.google.com/p/bitfighter/source/browse/zap/FontManager.cpp

Thanks for a great library!

akrinke commented 11 years ago

This reminds me of bug #3. Did you use the latest master?

ghost commented 11 years ago

Hi,

Yes. I just did a diff to upstream to make sure, and we are using the latest code. (We needed the string-width calculation fix for issue #4 )

akrinke commented 11 years ago

OK. I don't think it's a problem with texture wrapping, because the individual letters belong to a larger texture.

Do you use SDL in your game? If that's the case, you have to reload all textures when toggling fullscreen (if I remember correctly).

ghost commented 11 years ago

Yes, we are using SDL and we are reloading the textures (otherwise there would just be colored boxes instead of letters). I wonder if we are still doing something wrong, though. We reload by cleaning up all the stashes and re-creating them. Cleanup uses sth_delete, and recreating uses 'sth_create' then 'sth_add_font' again. You can see this in the Constructor/Destructor of BfFont here: https://code.google.com/p/bitfighter/source/browse/zap/FontManager.cpp#65

ghost commented 11 years ago

OK., I found our issue. It was a coding error on our side. I have it fixed and it is working just fine. Thank you for your time; and thanks for such a great library!

akrinke commented 11 years ago

I'm glad you found the issue and it's nice to hear from people using it (even if they file bugs :smiley:)

ghost commented 11 years ago

Hi again,

I know this is crazy (and please forgive me) - I thought the artifacts had gone away (and my code changes had mitigated it), but they do still show up in some cases. When I start the game in windowed mode, and change to fullscreen (and reload all the textures), this is what I see now:

snapshot22

Notice the numbers in the lower right of the screen. They have thin lines on the edges of the textures.

I did some experimenting and found that if I replace these calls in the font-stash code: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

with: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

the problem goes away; however, the text then looks ugly and pixelated. I'm still doing research, but I did find a post somewhere on the same issue: http://www.gamedev.net/topic/326261-gl_texture_mag_filter-gl_linear-causing-artifacts/

I am not sure how to interpret the solutions given there with my current knowledge of OpenGL. I am still studying..

akrinke commented 11 years ago

It's puzzling that this bug only occurs after context switching. Maybe your OpenGL context is configured slightly different? Are you using

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

?

ghost commented 11 years ago

Yes, we call that on each screen change when we reinitialize all the textures and OpenGL context and settings. I also tried moving the calls around a bit to see if it would make a difference; no luck.

I'm not sure this issue has to do with the context switching.. maybe the resizing instead? We do keep an internal OpenGL screen size of 800x600 that we scale up to whatever resolution the user's full screen may be.

akrinke commented 11 years ago

I will try to reproduce the bug with the font-stash example.

akrinke commented 11 years ago

So far no success in reproducing the bug. Does it happen on both, Windows and Linux?

ghost commented 11 years ago

Both Linux developers (myself and one other, using different distros) see the artifacts. I also tested on OSX 10.6 and see them as well. However, our Windows developers sees no issues, and I confirm no artifacts in a Window VM test of mine.

akrinke commented 11 years ago

Thank you, I think that's an interesting fact. Could you point me to a revision of bitfighter that builds cleanly and shows the artifacts? I tried the current HEAD last night but couldn't build it on Linux.

ghost commented 11 years ago

I fixed a build error last night and we recently finished porting to CMake. Instructions to get a debug build running:

  1. Check out HEAD and go into the top level directory
  2. cd build
  3. cmake -DCMAKE_BUILD_TYPE=Debug ..
  4. make
  5. cd ../exe
  6. for i in $( ls ../resource ); do ln -s ../resource/$i; done
  7. ./bitfighter

Step #6 is so you have all the resources available to the game, including the fonts. When the game starts, and you get to the main menu, start a game by selecting 'HOST GAME'. Once in, press ALT + ENTER to change screen modes; in the fullscreen modes, you should see the artifacts (especially on the game timer).

Feel free to join #bitfighter on freenode if you have any other issues or questions.

Thank you very much for taking the time to look at this.

akrinke commented 11 years ago

OK, that was a long bug hunt. The latest commit should fix it. The problem was that textures got reused and contained data from previous stashes. Now, textures are explicitly cleared at the beginning.

ghost commented 11 years ago

Confirmed fixed on Linux and Mac.

Thank you for your dedication!