Public Group

#### Archived

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.

## 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]);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

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

SDL_FreeSurface(realSurface);
SDL_FreeSurface(textSurface);

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);
glEnd();
glFlush();


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 on other sites
quote:
Original post by incubator01
stuff

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

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

ahem, ahem.

##### 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 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 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 on other sites
yes, you should, because I still didnt get it to work.

##### 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(){	SDL_Init(SDL_INIT_VIDEO);	surface = SDL_SetVideoMode(800,600,0,SDL_OPENGL);	TTF_Init();	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 );    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );				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 );    glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );    glBlendFunc( GL_ONE, GL_ONE );    glEnable(GL_BLEND);    glViewport( 0, 0, 800, 600 );    glMatrixMode( GL_PROJECTION );    glLoadIdentity( );    gluPerspective( 45.0f, 800.0f/600.0f, 0.1f, 100.0f );    glMatrixMode( GL_MODELVIEW );    glLoadIdentity( );		glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );	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 );	glEnd();	SDL_GL_SwapBuffers( );	SDL_Delay(2000);		TTF_CloseFont(ourFont);	TTF_Quit();	SDL_Quit();	return 0;}

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

glBlendFunc(GL_ONE,GL_ONE);
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);

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 on other sites
quote:
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);
or
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.
-CProgrammer

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

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

##### 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 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:
2.)Render
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.

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

Do this:
glPushMatrix();
glTranslatef(0, 0, -5);
drawcubes();
glPopMatrix();

glPushMatrix();
glTranslatef(0, 0, -4);
drawtext();
glPopMatrix();

-CProgrammer

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

1. 1
Rutin
67
2. 2
3. 3
4. 4
5. 5

• 21
• 10
• 33
• 20
• 9
• ### Forum Statistics

• Total Topics
633420
• Total Posts
3011790
• ### Who's Online (See full list)

There are no registered users currently online

×