Text on hud in open gl

Member
Posts: 39
Joined: 2008.10
Post: #1
Hello again,

Im looking for the best way to render text as a hud on my game, i am using texture2d etc as discussed in my other topic.

I need to be able to display score as well as other information on the hud and i was wondering the best way to do this in open gl. Thanks for any help Smile
Quote this message in a reply
Member
Posts: 39
Joined: 2008.10
Post: #2
I have tried this from an example file

_textures[kTexture_LabelSpeed] = [[Texture2D alloc] initWithString:@"Speed" dimensions:CGSizeMake(64, 32) alignment:UITextAlignmentLeft fontName:kFontName fontSize:kLabelFontSize];

[_textures[kTexture_LabelSpeed] drawAtPoint:CGPointMake(100, 100)];

It ruins all of my rendering and shows just the background colour, any idea whats wrong?
Quote this message in a reply
Apprentice
Posts: 13
Joined: 2008.10
Post: #3
If i'm not mistaken
Code:
[_textures[kTexture_LabelSpeed] drawAtPoint:CGPointMake(100, 100)];
draws the text at 100, 100, be sure that you aren't trying to draw it at a location that isn't on your screen.
Quote this message in a reply
Apprentice
Posts: 5
Joined: 2008.09
Post: #4
Try switching the blend function to (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) when you draw the text graphic.
Quote this message in a reply
Member
Posts: 39
Joined: 2008.10
Post: #5
i tried drawing it at 0,0 with that rendering mode enabled and it still comes up with a green screen which is the background colour (clear colour) , if i don render the text everything runs fine and its as soon as i use:

[_textures[kTexture_LabelSpeed] drawAtPoint:CGPointMake(0, 0)];

any ideas ? im confused
Quote this message in a reply
Moderator
Posts: 3,571
Joined: 2003.06
Post: #6
Gavin Bowman Wrote:Try switching the blend function to (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) when you draw the text graphic.

The Texture2D header says to use (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) with text.

[edit] whoops, sorry, that's what you said. For some reason, I read it as GL_ONE. My bad...
Quote this message in a reply
Moderator
Posts: 3,571
Joined: 2003.06
Post: #7
Don't forget that Texture2D has to change vertex and tex coord pointers, and also rebinds to a new texture, so if you forget to change those back, that could mess up your stuff.

[edit] Plus, you need glEnableClientState(GL_TEXTURE_COORD_ARRAY); and glEnableClientState(GL_VERTEX_ARRAY); before Texture2D will work.
Quote this message in a reply
Member
Posts: 39
Joined: 2008.10
Post: #8
I managed to get it working using this:

Code:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glPushMatrix();
        //screen size is 480 by 320 - the middle is x:160 y:240
        xpos = ((115)*2)-bounds.size.width;//convert to relitive position -1 to 1
        ypos = ((9)*3)-(bounds.size.height*1.5);//convert to relitive position -1.5 to 1.5
        
        xscalepos = xpos/bounds.size.width;
        yscalepos = ypos/(bounds.size.height);
        glTranslatef(xscalepos, yscalepos, 0.0f);
        
        glScalef(0.007f, 0.007f, 1.0f);
        
        _textures[kTexture_GameHudText] = [[Texture2D alloc] initWithString:[NSString stringWithFormat:@"SCORE: %i", playerScore] dimensions:CGSizeMake(240, 40) alignment:UITextAlignmentCenter fontName:kFontName fontSize:kLabelFontSize];
        //glBindTexture(GL_TEXTURE_2D, [_textures[kTexture_LabelSpeed] name]);
        [_textures[kTexture_GameHudText] drawAtPoint:CGPointMake(0, 0)];
        
        glPopMatrix();
        glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

then i reset the texture coords etc afterwards:

Code:
glVertexPointer(2, GL_FLOAT, 0, spriteVertices);
glTexCoordPointer(2, GL_SHORT, 0, spriteTexcoords);

Only problem is it slowly degrades the framerate, im painting it onto the hud and if i disable the text drawing part the game runs fine forever but as soon as i render the text over time the fps gets lower and it will eventually crash.... ive tried a few things but i can work out why... any ideas?
Quote this message in a reply
Member
Posts: 21
Joined: 2008.06
Post: #9
jjslay Wrote:I managed to get it working using this:

Only problem is it slowly degrades the framerate, im painting it onto the hud and if i disable the text drawing part the game runs fine forever but as soon as i render the text over time the fps gets lower and it will eventually crash.... ive tried a few things but i can work out why... any ideas?

yes, Texture2d creation is VERY slow.

Basically, create all you Texture2d objects in your 'init' method. Never create them in you main loop.

to display your score I recommend you:
  • create 10 texture2d objects: 0, 1, 2, 3, 4, 5, etc in you init, and render them in your main loop as much as you need them.
  • or implement an object that does that for you... you will use it all of your games.
Quote this message in a reply
Apprentice
Posts: 5
Joined: 2008.09
Post: #10
I imagine it's made worse in this case because you're not releasing the texture, you're just creating a new one each tick. It might run reasonably well if you release the texture, and it would run even better if you only created a new version when the score changes.

Sooner or later you'll end up using the suggestion in the previous reply though, and you won't regret it.
Quote this message in a reply
Moderator
Posts: 3,571
Joined: 2003.06
Post: #11
jjslay Wrote:Only problem is it slowly degrades the framerate, im painting it onto the hud and if i disable the text drawing part the game runs fine forever but as soon as i render the text over time the fps gets lower and it will eventually crash.... ive tried a few things but i can work out why... any ideas?

ricardoquesada is correct, Texture2D creation is fairly slow, especially depending on how big it is and how much text is to be rendered. But also, it looks like you're creating a new texture every frame (which is not good), but also not releasing the previous one (which is *really* bad). That will plug up memory pretty quick, and slow things down to a crawl, and eventual crash.

You don't have to create Texture2D objects only at init, but it is preferable to pre-generate if possible. What I often do is something like:

Code:
if (myTexture == nil)
    myTexture = [[Texture2D alloc] initWithString:@"my string" dimensions:CGSizeMake(128.0f, 16.0f) alignment:UITextAlignmentLeft fontName:@"Verdana" fontSize:14.0f];

That way it gets initialized lazily, and only created once, as needed.

Then if I change the value of the string, I simply do this before the Texture2D alloc:

Code:
[myTexture release];
myTexture = nil;

Which will trigger the automatic regeneration of the string texture.
Quote this message in a reply
Member
Posts: 39
Joined: 2008.10
Post: #12
Thanks a lot guys, great answers put well.. i get it now Smile
Quote this message in a reply
Apprentice
Posts: 5
Joined: 2008.10
Post: #13
I just use a UILabel; works great and I can animate it with Core Animation.
Quote this message in a reply
Post Reply