Jump to content
  • Advertisement


This topic is now archived and is closed to further replies.


text in opengl using SDL (not working as it should :( )

This topic is 5277 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I incuired about this a while ago and someone posted some usefull code on how to render text using SDL_ttf and Opengl instead of the winAPI or glx (for X11) However, I got a very different result from what I excepted to see . the text isnt really text but just a non-manipulatable bitmap here is a little screenie http://users.skynet.be/incubator/text.jpg this is the tutorial of displaylists (NeHe) mixed with the first tutorial on fonts (bitmap fonts) with some SDL adjustments to get hte font. What I wanted, was to have some text printed over the many cubes (static text) so that the cubes still rotate in the background and some text in the foreground still being visible. (silly thing I want to try but it is a crucial thing if I ever want to make a working HUD) my buildFont method:
bool GLApplication::createFromText(char* text, int r, int g, int b, int a) {
	SDL_Color color = {r,g,b,255};
	TTF_Font* font = TTF_OpenFont("/home/incubator/xpfonts/arial.ttf", 20);
	SDL_Surface* textSurface = TTF_RenderText_Solid(font, text, color);
	int new_width = 1;
	while (new_width < textSurface->w) new_width *= 2;
	SDL_Surface* realSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, new_width, textSurface->h, 24,0xff000000,0x00ff0000,0x0000ff00,0);
	SDL_BlitSurface(textSurface, 0, realSurface, 0);
	glGenTextures(1, &tex_id[0]);
	glBindTexture(GL_TEXTURE_2D, tex_id[0]);


	glTexImage2D(GL_TEXTURE_2D, 0,3, new_width, new_width,0, GL_RGB, GL_UNSIGNED_BYTE, realSurface->pixels);


	realSurface = NULL;
	textSurface = NULL;
	return true;

and the actual drawing in drawGLscene():

glBindTexture(GL_TEXTURE_2D, tex_id[0]);
			glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);	
			glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);	
			glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);	
			glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);	

as you will see, the background of the text is garbled black, not transparent. If I enable alphablending, this is no longer the case, but the font itself is transparent as well. (and the garbling too) [edited by - incubator01 on June 5, 2004 5:45:37 PM]

Share this post

Link to post
Share on other sites
Original post by incubator01

CreateRGBSurface(SDL_SWSURFACE, new_width, textSurface->h.....

glTexImage2D(GL_TEXTURE_2D, 0,3, new_width, new_width.....

ahem, ahem.

Share this post

Link to post
Share on other sites
that was part of the code I found in google.

besides, what do you want me to do?
without the new_width thing I get a square with one filled color.
The internet is so big and yet I havent got my hands on a simple example on how to render fonts properly using sdl_ttf and opengl.
Either I find posts that have other problems concerning SDL_ttf or sdl-only examples.

and your example a while back has a glTexImage2D call as well.

I dont even understand why there are so little available resources for drawing stuff like a HUD. I mean, how many games are there today?
Just like i was looking for how to make GUI controls with SDL....took me a long while before I found a few examples...

[edited by - incubator01 on June 5, 2004 7:28:35 PM]

Share this post

Link to post
Share on other sites
alright, i replaced that height by new_width in teh createRGBSurface function, but I still get a solid background.
What I am looking for, is the ability to draw text on anything just like in a game.
But all I got out of this is a black rectangle with text.
I want no rectangle with text without the text being transparent

Share this post

Link to post
Share on other sites
Well, I''m surprised that it worked without crashing using mismatching dimensions for the pixel data.

Now, to get rid of the black border, one possiblity is to to use the RenderAlpha version of the SDL_TTF render function, and then tell OpenGL (in the 2DImage function) that it is GL_RGBA.

There are other ways, as well, but this seems to be the "simplest" in that it involved changing two small things.

er three. Sorry, forgot to mention that oyu also need to make the surface you CreateRGB''d have an alpha channel, too.

The other methods of getting it to work are, well, yichy and complicated, although probably more memory efficient.

I really should write a GD article on doing this...

Share this post

Link to post
Share on other sites
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>

SDL_Surface *surface;

TTF_Font* ourFont;
SDL_Color ourColor = {255,255,255};
SDL_Surface *ourSurface;
SDL_Surface *myNewSurface;
int texture;
int w;
int t;

int main()
surface = SDL_SetVideoMode(800,600,0,SDL_OPENGL);
ourFont = TTF_OpenFont("/home/ted/Projects/empire/img/vera.ttf", 20);
ourSurface = TTF_RenderText_Blended(ourFont, "Yo diggity, dog!", ourColor);
w = pow(2,ceil(log(ourSurface->w)/log(2))) +0.5f; /* round up to the nearest power of two*/
myNewSurface = SDL_CreateRGBSurface(0,w,w,32,0x00ff0000,0x0000ff00,0x000000ff,0xff000000);
SDL_BlitSurface(ourSurface,0,myNewSurface,0); /* blit onto a correctly-size surface */

glGenTextures( 1, &texture );
glBindTexture( GL_TEXTURE_2D, texture );
glTexImage2D( GL_TEXTURE_2D, 0, 4, w, w, 0, GL_BGRA,
GL_UNSIGNED_BYTE, myNewSurface->pixels );

glEnable( GL_TEXTURE_2D );
glShadeModel( GL_SMOOTH );
glClearColor( 0.5f, 0.0f, 0.0f, 0.0f );
glClearDepth( 1.0f );
glDisable( GL_DEPTH_TEST );
glDepthFunc( GL_LEQUAL );
glBlendFunc( GL_ONE, GL_ONE );
glViewport( 0, 0, 800, 600 );
glMatrixMode( GL_PROJECTION );
glLoadIdentity( );
gluPerspective( 45.0f, 800.0f/600.0f, 0.1f, 100.0f );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity( );

glLoadIdentity( );
glTranslatef( 0.0f, 0.0f, -5.0f );
glBindTexture( GL_TEXTURE_2D, texture );

glBegin( GL_QUADS );
glNormal3f( 0.0f, 0.0f, 1.0f );
glTexCoord2f( 0.0f, 1.0f ); glVertex3f( -1.0f, -1.0f, 1.0f );
glTexCoord2f( 1.0f, 1.0f ); glVertex3f( 1.0f, -1.0f, 1.0f );
glTexCoord2f( 1.0f, 0.0f ); glVertex3f( 1.0f, 1.0f, 1.0f );
glTexCoord2f( 0.0f, 0.0f ); glVertex3f( -1.0f, 1.0f, 1.0f );
SDL_GL_SwapBuffers( );

return 0;

That works for me. (against a red clear color, so you see the transparency)

I think that this might help you, specifically:


before you render the quad.

edit: oh yeah, and I'll see about writing a SDL/GL text article later today, hopefully.

[edited by - C-Junkie on June 6, 2004 11:04:54 AM]

Share this post

Link to post
Share on other sites
I incuired about this a while ago and someone posted some usefull code on how to render text using SDL_ttf and Opengl instead of the winAPI or glx (for X11)

That would be me hehe.

First of set the blend func to either:
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glBlendFunc(GL_ONE, GL_ONE);

Enable blending.

Now you're black background will be completely gone.
Yes you're text will also be slightly transparent but I like that effect. Just make the font the right color and it'll make it look even better as 'status' text in a game or such.
Next off:
You changed the texture to have height and width the same value. You can do this but I dont see why not have them both power of 2 but different. This way you'll have really good detail. If you don't do this it'll look like you're text is stretched.
It works fine on my computer and I really dont think its a problem but maybe someone here will give a valid reason why it is.
In the code I gave you I saved the 'real' width and height of the text. I used this data in other code to scale my geometrie exactly according to the original size and the screens dimensions. That way you can achieve the same kind of text function as TextOut is in Win32. Only here its layed over your 3d-scene.
Oh and use glOrtho for the drawing the text over the scene.

Hope this helps.

[edited by - CProgrammer on June 6, 2004 11:35:50 AM]

[edited by - CProgrammer on June 6, 2004 11:36:44 AM]

Share this post

Link to post
Share on other sites
indeed, now it works

but here is one other thing I cant get right.
The text is drawn behind all other objects, even though I draw it first.
I tried translating to z = -4.0f, drawing it, glLoadIdentity() and then translate to z = -5.0f to draw the cubes.
but that didnt help

Share this post

Link to post
Share on other sites
K heres the problem.
2 ways:
Way 1:
You shouldnt draw the text in 3d-mode.
Make some functions to switch between 3d and 2d.
For 3d use gluPerspective.
2d: glOrtho.
Basically do this then:

1.)Switch to 3d:
3.)Switch to 2d
4.)Render text with z-value 0

Way 2:
If you want to keep it 3d. Then thats a strange problem. Are you sure you enabled GL_DEPTH_TEST?
Plus heres how Id do the drawing.
first call glLoadIdentity()

Now treat the cubes as an object and the text as another.

Do this:
glTranslatef(0, 0, -5);

glTranslatef(0, 0, -4);


[edited by - CProgrammer on June 6, 2004 12:06:22 PM]

Share this post

Link to post
Share on other sites

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!