SDL2 + OpenGL+ SDL_ttf and rendering text question |
Trev
|
I am porting my program from mac/windows to the iPad. Up until now, I have been using the GLUT functions for drawing text, such as:
glutBitmapCharacter (GLUT_BITMAP_HELVETICA_10,theString[i]); But those functions are not supported on the iPad, so I am trying to use SDL_ttf for text. There are 2 examples that demonstrate SDL_ttf. http://lackeyccg.com/glfont.c shows how things are done with OpenGL. http://lackeyccg.com/showfont.c shows how things are done with just SDL. I'm not sure what is the better method for my uses. I am using text for essentially 3 kinds of uses: Labels for things like buttons and menus. [img]http://lackeyccg.com/images/SDL_ttfNonDynamicText.jpg[/img] Text for text fields. [img]http://lackeyccg.com/images/SDL_ttfDynamicText.jpg[/img] And text labels that appear in 3D space. (The text itself is flat, but it appears in 3D OpenGL space.) [img]http://lackeyccg.com/images/SDL_ttf3DText.jpg[/img] If I understand things correctly, with SDL_ttf, fonts are loaded and then you can use those fonts to create surface images, or load those images into opengl which you can refer to later by the texture id. In either case, it seems like you need to store a unique image in memory for each unique bit of text. Alternatively, you can generate this image every time you display the text, but it seems like generating the image every display cycle, while simpler to implement, would be a drag on the system. Is that correct, or could I simply generate everything I need every display cycle and not suffer a performance hit? What I think might be the best thing to do is create some persistent record of all text images. Whenever a new word or phrase is needed (or with different style, like italics or bold) then a new entry to the record is added for that surface image (or opengl texture id). This is pretty straight-forward for something like a button label, but a text field seems to be more complicated. I think the best approach for a text field would be to store in the record only those lines of the text field that are currently visible, and have a separate entry for each line. Another idea is to persistently store the images for all of a font's glyphs, and then generate any needed word or phrase by cobbling them together. I would hope that SDL_ttf does this for me somehow to save me all the work. I would love to be able to just call a function, passing it a string to display, its X,Y,Z coordinates, it's color, and size, and it would just draw it to the screen with all of the complex stuff like memory management and kerning all done behind the scenes. Does anyone know if anything like that already exists? All I can currently find is functions like TTF_RenderText_Solid that create a surface image that I then have to manage in a complex way as stated above. As far as the text labels that appear in 3D space, I am not sure but I think this requires the opengl method like in the glfont.c example instead of the pure SDL method. Does anyone have any suggestions for me? Do you think I am thinking about things in the right manner? How have you handled rendering both non-dynamic and dynamic text with SDL_ttf? Any insight you have on this subject would be helpful. Thanks in advance. -Trevor |
|||||||||||
|
SDL2 + OpenGL+ SDL_ttf and rendering text question |
gabomdq
|
2012/5/24 Trev
Both methods basically do the same, even though the SDL method does it behind the scenes with SDL_CreateTextureFromSurface, they create a "software" surface where SDL_ttf renders the text, then copy it to a "hardware" texture and render that.
I generally render the text to a software surface, copy it to a texture and render it using SDL, I don't think there's a way around it because SDL_ttf is fundamentally CPU centered and rendering GPU centered, and you have to bridge those eventually...if there's a lot of text or it is constantly changing, maybe you can do the glyphs thing (uploading all symbols to a texture and render them "by hand"), but it really depends on the application you are developing. You could, in theory, render fonts using only geometry or shaders, but it seems the technology is not there yet: http://stackoverflow.com/questions/5262951/what-is-state-of-the-art-for-text-rendering-in-opengl-as-of-version-4-1 -- Gabriel. |
|||||||||||||||
|
SDL2 + OpenGL+ SDL_ttf and rendering text question |
Chris Bush
Guest
|
You're right that generating the textures for each new string every cycle will not perform well. Preloading the glyphs from a font to a texture set and assembling on the fly instead seems to work alright for me. The relevant parts I've mashed into the example program below (c++/sdl2). But this approach is only for game text. It's not great for regular applications where the standard OS widgets are familiar, complete and comfortable for people. So, for the text areas and things, you might want to be using a GUI library such as GTK+... but if you do choose to render letters as individual textures, feel free to have at the code here (note the paths to fonts at lines 102-105).
http://codepad.org/QS26ciMD On Thu, May 24, 2012 at 10:56 PM, Trev wrote:
|
|||||||||||||
|
Re: SDL2 + OpenGL+ SDL_ttf and rendering text question |
Trev
|
I have a minor tweak that I think is an improvement. If you pass some RGB values to void Text_ure::write(float x, float y, float lh, float r,float g,float b), then you can dynamically change the color of the font without having to reload it. You just need to add glColor4f(r,g,b,1.0); right before "glBegin(GL_QUADS);". Just make sure you pass a white color to TTF_RenderText_Blended when the glyph images are being created initially. And you can pass RGB values to write_left_aligned so it in turn can pass them to Text_ure::write. That leaves you with:
And that one function is all you need from that point on. Now all I need is to convert that code to an OpenGL ES safe version and I think I'll be all set for rendering text on the iPad. |
|||||||||||||||
|
SDL2 + OpenGL+ SDL_ttf and rendering text question |
Chris Bush
Guest
|
Oh, yes... the function could be improved in many ways. However, you could just use glColor4f(r, g, b, a); prior to calling the write_left_aligned function. The color will be as set without needing to reload the textures.
On Fri, May 25, 2012 at 5:15 PM, Trev wrote:
|
|||||||||||||
|
Re: SDL2 + OpenGL+ SDL_ttf and rendering text question |
Trev
|
I tried my hand at making the code more easy to use. I appreciate suggestions for improvement. http://forums.libsdl.org/viewtopic.php?t=8194 |
|||||||||||||
|
SDL2 + OpenGL+ SDL_ttf and rendering text question |
Chris Bush
Guest
|
It's neat. I like the prospective alignment feature. One might go in the direction of creating something like a paragraph class that you can create, position on the plane, set the typeface and kerning and so on, and fill and refill with text. I think setting the color in the glyph drawing function might not be optimal, since for a given input to DrawText you must pass and set the colors to each letter. Anyway, it looks useful. Thanks for leaving the credit.
Chris On Sat, May 26, 2012 at 8:39 AM, Trev wrote:
|
|||||||||||||
|