![]() |
work in progress: a simple library to render dynamic text | ![]() |
Trev
![]() |
![]() |
Check out http://lackeyccg.com/code/ for a user-friendly way to render dynamic text.
http://lackeyccg.com/code/MainREADME.cpp explains how it works. This is a work in progress and feedback is appreciated. You should be able to very easily incorporate the text drawing functions in any SDL/SDL_ttf equipped project, or at least that is the goal. |
||||||||||
|
![]() |
![]() |
![]() |
![]() |
Trev
![]() |
![]() |
I added some changes so things work on the iPad, and it almost works.
Here is a screenshot showing the desktop and the iPad version side by side: http://lackeyccg.com/code/ipadFontBug.jpg The fonts are definitely loading on the iPad, but they aren't displaying properly for some reason. Still trying to figure that out. I included another read me file specific to the iPad, at http://lackeyccg.com/code/READMEiPad.txt The FontGlyphClass::Draw function in http://lackeyccg.com/code/FontGlyphClass.cpp currently has 2 sections, one for the iPad (OpenGL ES), and one for regular OpenGL. For regular OpenGL, the OpenGL ES code works too, and seems to yield identical results. At this point, I'm not completely sure which will give me better performance. I may end up using the OpenGL ES code for both. If anyone has any suggestions for improvements, please let me know. This is a work in progress. |
||||||||||
|
![]() |
![]() |
Trev
![]() |
![]() |
I added some changes to have more control over drawing text as a paragraph. Text should properly align now, rather than getting chopped off mid-word.
![]() That paragraph is drawn with
|
||||||||||||
|
![]() |
![]() |
Trev
![]() |
![]() |
This is what things looked like before:http://lackeyccg.com/code/ipadFontBug.jpg
Regarding that iPad bug, where the text wasn't rendering properly, I made an unexpected discovery when I made the following singular change (marked in red): FontGlyphClass::FontGlyphClass(SDL_Surface *surface) { SetWidth(surface->w); SetHeight(surface->h); texture[0]=-1; glGenTextures(1, &texture[0]); glBindTexture(GL_TEXTURE_2D, texture[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, nextPowerOfTwo(surface->w), nextPowerOfTwo(surface->h), 0, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR); } There are some odd things about this change. First, unlike before, now the text renders exactly the same on the Mac OSX target and on the iPad (simulator) target, as shown here: http://lackeyccg.com/code/ipadFontBug2.jpg But now neither of them looks right. If I remove that nextPowerOfTwo() function, the OSX version looks perfect and the iPad version gets worse. I'm not sure what could cause this inconsistent behavior. |
||||||||||
|
![]() |
![]() |
Trev
![]() |
![]() |
I just fixed things so now text renders properly on iOS with OpenGL ES. Look at the new changes to FontGlyphClass::FontGlyphClass(SDL_Surface *surface) to see the changes that needed to be done to fix this issue. |
||||||||||||
|
![]() |
work in progress: a simple library to render dynamic text | ![]() |
Forest Hale
Guest
![]() |
![]() |
I believe you need to set these before glTexImage2D:
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // if using a format other than GL_RGBA glPixelStorei(GL_UNPACK_ROW_LENGTH, surface->pitch); // not sure if surface->pitch is the best thing to put here glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, surface->h); But I've never tried uploading an image this way before, I normally would pad the surface size to a power of 2 and then upload that, rather than pulling tricks with unpack settings - also I'm not sure if these unpack settings exist on iOS. It's best to create an atlas texture (large texture that you upload many small pieces into) and maintain it as a software surface, and when you have copied some additional text images into it, update the texture - preferably no more than once a frame (mobile hardware is not fast!), so do this as two passes through your relevant code (preparing the needed text images, then uploading, then drawing them all). Note that all OpenGL drivers will greatly prefer that you two pass your render anyway, upload all vertex buffers, textures and anything else of that nature, before you issue your first glDrawElements of the frame. On 06/13/2012 03:57 AM, Trev wrote:
-- LordHavoc Author of DarkPlaces Quake1 engine - http://icculus.org/twilight/darkplaces Co-designer of Nexuiz - http://alientrap.org/nexuiz "War does not prove who is right, it proves who is left." - Unknown "Any sufficiently advanced technology is indistinguishable from a rigged demo." - James Klass "A game is a series of interesting choices." - Sid Meier _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
||||||||||||
|
![]() |
Re: work in progress: a simple library to render dynamic tex | ![]() |
Trev
![]() |
![]() |
Here is the code that loads the FontGlyph:
Regarding a software surface as opposed to an opengl texture, I don't see any reason to maintain (i.e., retain) anything besides the opengl textures. The opengl textures are the only things I actually need to render the glyphs, and I figure I might as well load all the glyphs once and be done loading. I suppose if I happened to never use a particular glyph, there would be some wasted memory, but I'm not sure that would make it worth it to maintain the software surface and dynamically load only those glyphs I need at the moment. But perhaps I am not understanding your point. You seem to be advocating updating the texture very frequently which I would think would result in worse performance. Regarding a single atlas texture, currently how I am doing it is loading every glyph to an OpenGL texture via glBindTexture(GL_TEXTURE_2D, texture[0]);. This results in a lot of separate opengl texture IDs (which I am not sure is intrinsically bad). I agree that it might be better to load all glyphs to a single texture and have each glyph know its specific UV coordinates on the atlas texture. I did it how I did it because my code was based on http://codepad.org/QS26ciMD from Chris Bush, and that's how he did it. I'm curious why he decided to load all of the glyphs as separate opengl images. Perhaps he had a reason for it, or perhaps it was simply easier to implement.
|
||||||||||||||||||
|