Author Topic: OpenGL loading a custom font image.[BMAX]  (Read 6054 times)

0 Members and 1 Guest are viewing this topic.

Offline Pixel_Outlaw

  • Pentium
  • *****
  • Posts: 1388
  • Karma: 83
    • View Profile
Hello, and first post...

I've just started OpenGL in Blitzmax. I really like it so far. I'm making a game and it is coming along splendedly. My question is how to load and draw my 95 character ascii image font. The font ins a png image. It has the 95 printable characters arranged by their value in the ascii code. I've been able to build a base engine in the native blitz graphics language but OpenGL handles things differntly. I've tried to read through the Nehe Tutorials but it's hard for me to pick out the snippets OpenGL from the other languages.

I can provide the images for my game text if somebody has time to make a quick demo.

Here is my image font. If you have time and would be willing to throw together a sample that would be great. ;D

Please do not use my font in your game, it took me 3 hours in MS Paint to make...



This is how I would do it with the blitz2d driver: (Just to show I'm not just demanding code....
Code: [Select]
' this demonstrates loading and use of image text

Strict
Graphics 800,600

Global font:timage=LoadAnimImage("index.png",16,16,0,95)

Function draw_text_image(my_text:String,x#,y#,scale#)

SetScale scale,scale
Local counter%=0
For Local i=0 To my_text.length-1
DrawImage(font,x+(16*counter)*scale,y,Asc(Chr(my_text[counter]-32)))
counter:+1
Next
SetScale 1.0,1.0
End Function

While Not KeyDown(key_escape)
Cls

draw_text_image("Ryan Burnside is cool!",0,128,.5)
draw_text_image("Super Neat Custom font demo...",0,128+16,1.0)
draw_text_image("Symbols you say? <>,(),^%$#@!&*()",0,128+32,1.5)

draw_text_image("Symbols you say? <>,(),^%$#@!&*()",0,128+64,2.0)
Flip
WEnd
« Last Edit: July 21, 2007 by Shockwave »
Challenge Trophies Won:

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1668
  • Karma: 133
    • View Profile
Re: OpenGL loading a custom font image.
« Reply #1 on: April 01, 2007 »
never used blitz max but the general way i know of doing it in opengl is to use display list.

basically you generate a display list for every character in your font image.

i suppose source would help better so this is straight out of the freebasic examples.

Code: [Select]
'------------------------------------------------------------------------
sub BuildFont()                                  '' Build Our Font Display List

dim cx as single                             '' Holds Our X Character Coord
dim cy as single                             '' Holds Our Y Character Coord

gbase = glGenLists(256)                      '' Creating 256 Display Lists
glBindTexture GL_TEXTURE_2D, texture(0)      '' Select Our Font Texture
for gloop = 0 to 255                         '' Loop Through All 256 Lists

cx = (gloop mod 16)/16.0                 '' X Position Of Current Character
cy = (gloop\16)/16.0                     '' Y Position Of Current Character

glNewList gbase+gloop, GL_COMPILE        '' Start Building A List
glBegin GL_QUADS                         '' Use A Quad For Each Character
glTexCoord2f cx, 1-cy-0.0625         '' Texture Coord (Bottom Left)
glVertex2i 0, 0                      '' Vertex Coord (Bottom Left)
glTexCoord2f cx+0.0625, 1-cy-0.0625  '' Texture Coord (Bottom Right)
glVertex2i 16,0                      '' Vertex Coord (Bottom Right)
glTexCoord2f cx+0.0625, 1-cy         '' Texture Coord (Top Right)
glVertex2i 16, 16                    '' Vertex Coord (Top Right)
glTexCoord2f cx,1-cy                 '' Texture Coord (Top Left)
glVertex2i 0, 16                     '' Vertex Coord (Top Left)
glEnd                                    '' Done Building Our Quad (Character)
glTranslated 10, 0, 0                    '' Move To The Right Of The Character
glEndList                                '' Done Building The Display List
next                                         '' Loop Until All 256 Are Built
end sub

'------------------------------------------------------------------------
'' Where The Printing Happens
sub glPrint(byval x as integer, byval y as integer, glstring as string, byval gset as integer)

if gset>1 then gset=1

glBindTexture GL_TEXTURE_2D, texture(0)                         '' Select Our Font Texture
glDisable GL_DEPTH_TEST                                         '' Disables Depth Testing
glMatrixMode GL_PROJECTION                                      '' Select The Projection Matrix
glPushMatrix                                                    '' Store The Projection Matrix
glLoadIdentity                                              '' Reset The Projection Matrix
glOrtho 0, 640, 0, 480,-1, 1                                '' Set Up An Ortho Screen
glMatrixMode GL_MODELVIEW                                   '' Select The Modelview Matrix
glPushMatrix                                                '' Store The Modelview Matrix
glLoadIdentity                                          '' Reset The Modelview Matrix
glTranslated x, y, 0                                    '' Position The Text (0,0 - Bottom Left)
glListBase gbase-32+(128*gset)                          '' Choose The Font Set (0 or 1)
glCallLists len(glstring),GL_BYTE, strptr(glstring)     '' Write The Text To The Screen
glMatrixMode GL_PROJECTION                              '' Select The Projection Matrix
glPopMatrix                                                 '' Restore The Old Projection Matrix
glMatrixMode GL_MODELVIEW                                   '' Select The Modelview Matrix
glPopMatrix                                                     '' Restore The Old Projection Matrix
glEnable GL_DEPTH_TEST                                          '' Enables Depth Testing
end sub

obviously youll have to convert that to work with your font image and also bmax but it should give you an idea as to how to go about it.
Challenge Trophies Won:

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17417
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: OpenGL loading a custom font image.
« Reply #2 on: April 01, 2007 »
There's no need to make a table of positions for the letters Nino, they seem to be laid out in ascii order anyway. Having not used Bmax myself, I am unsure of how it stores and draws images, but the first thing to do would be to load in your font image.

Then have an x co-ordinate that starts at 0 and a loop that counts from 0 to 94 and you will need to chop up your image into 95 individual letters. In Blitzbasic you could use the loadanimimage and drawanimimage commands for that.

When it comes to drawing the letters, get the ascii value of the text you want to draw and subtract 31 from that value to put the offset at the right letter in your animimage.

That's the basic technique, there are however bmaxers here who may be able to give you better help than that and  :hi: to the board!
Shockwave ^ Codigos
Challenge Trophies Won:

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1668
  • Karma: 133
    • View Profile
Re: OpenGL loading a custom font image.
« Reply #3 on: April 01, 2007 »
of course just change this line to .

cy = Hight of your text

also youll need to change it to hold the amount of letters in your list.

i did say it would need modifying to suit your needs.

@shockwave this is the opengl way which is what i thought he ment it works by simply holding all the letters in an array( ie display list ) not the atuall positions.

then it uses gltranslatef to position the text wherever. its posibile to do sine wave scrollers with this methode its also really really fast.

ohh one last thing about the ascii positions these lines do that.

glListBase gbase-32+(128*gset)                          '' Choose The Font Set (0 or 1)
glCallLists len(glstring),GL_BYTE, strptr(glstring)     '' Write The Text To The Screen


Challenge Trophies Won:

Offline Pixel_Outlaw

  • Pentium
  • *****
  • Posts: 1388
  • Karma: 83
    • View Profile
Re: OpenGL loading a custom font image.
« Reply #4 on: April 01, 2007 »
Thanks for your help, this looks to be a good community. ;D
Challenge Trophies Won:

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1668
  • Karma: 133
    • View Profile
Re: OpenGL loading a custom font image.
« Reply #5 on: April 01, 2007 »
yeah were a good bunch.

we will try to help wherever we can anywho :hi: hope you stick around
Challenge Trophies Won:

Offline Pixel_Outlaw

  • Pentium
  • *****
  • Posts: 1388
  • Karma: 83
    • View Profile
Re: OpenGL loading a custom font image.
« Reply #6 on: April 03, 2007 »
It seems that my problems aren't over yet...

I've found the correct way to load the strip of text into memory. The problem is that blitzmax doesn't appear to have a way to store textures.

I had to first break the font image into smaller pixmaps. There appears to be an type of pixmap array to hold them. So far so good. The problem comes in storing the new textures before use without having a direct name for each one. I had originally planned to convert each pixmap to a texture and then store them in an array so I could corilate the index number of the array to the ascii codes for each letter in the string. It attempts to store the values then throws an error stating that it cannot calculate the texture size..

This is my code currently: (I tried to understand the multiple lists under one list name. Just couldn't understand a list with multiple lists within.)


Here all the subimages of the picture are loaded into the Tpixmap[] array
Code: [Select]
Incbin "index.png"
Global text_image:timage=LoadAnimImage("Incbin::index.png",16.0,16.0,0.0,95.0,FILTEREDIMAGE=False)

Global letters:TPixmap[]=text_image.pixmaps



Ok now for the hair pulling it works but there is a major leak...
Code: [Select]
Function draw_text_image(text:String,x#,y#)
glEnable(GL_TEXTURE_2D)
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_replace)


For Local i#=0 To text.Length-1
glLoadIdentity
glTranslatef x+(i*16),y,0
Local texture = GLTexFromPixmap(letters[Asc(Chr(text[i]-32))]) ' these get stuck in memory
glBindTexture GL_TEXTURE_2D,texture
glBegin GL_QUADS
' Front Face
glcolor3f 0,0,0
glTexCoord2f 0.0, 0.0; glVertex3f 0.0, 0.0, 0.0       ' Bottom Left Of The Texture And Quad
glTexCoord2f 1.0, 0.0; glVertex3f  16.0, 0.0, 0.0       ' Bottom Right Of The Texture And Quad
glTexCoord2f 1.0, 1.0; glVertex3f  16.0,  16.0, 0.0       ' Top Right Of The Texture And Quad
glTexCoord2f 0.0, 1.0; glVertex3f 0.0,  16.0, 0.0       ' Top Left Of The Texture And Quad

glEnd


Next
glDisable(GL_TEXTURE_2D)
End Function


I know that there are probably converted pixmaps piling up the whazoo. I tried to save them to an array before the game starts but it throws the can't calculate size error.

here is a screen...

http://img489.imageshack.us/img489/9396/helprr5.png
« Last Edit: April 03, 2007 by Pixel_Outlaw »
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: OpenGL loading a custom font image.
« Reply #7 on: April 03, 2007 »
Try doing the array thing after calling GLGraphics.  In fact, move all the image loading/allocating until after you've set the screen mode.  I'm guessing that might help.

Jim
Challenge Trophies Won:

Offline Pixel_Outlaw

  • Pentium
  • *****
  • Posts: 1388
  • Karma: 83
    • View Profile
Re: OpenGL loading a custom font image.
« Reply #8 on: April 03, 2007 »
Try doing the array thing after calling GLGraphics.  In fact, move all the image loading/allocating until after you've set the screen mode.  I'm guessing that might help.

Jim


You were totally right. Late night programming isn't always the most productive.
Challenge Trophies Won:

Offline zawran

  • Sponsor
  • Pentium
  • *******
  • Posts: 909
  • Karma: 67
    • View Profile
Re: OpenGL loading a custom font image.
« Reply #9 on: April 03, 2007 »
Since you are using quads anyways, why not have all the characters on one power2 image, load that as a pixmap, convert to an openGL texture. Then in the code where you "draw" the characters, have it create a quad for each letter, but instead of using all of the texture, use the texture coords commands to have it draw that quad with just the texture of the single letter.