Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (540)
Games in Android Showcase (133)
games submitted by our members
Games in WIP (603)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Write a text in OpenGl  (Read 4992 times)
0 Members and 1 Guest are viewing this topic.
Offline InfoRital

Junior Devvie





« Posted 2005-07-16 16:23:01 »

Hi,
I'm learning OpenGL using LWJGL, but i have a litte question, and i've found no answer on google (but i might not search very well..).
How can i write a text in my Display screen ?
I want to add the number of the frame (not the FPS) and as i'm in fullscreen mode, i can't take it in the title of the Window..no way i want to know how to write a text in opengl.

PS : Is the Window class of LWJGL removed in the lasts versions ? Because i see many docs where they used the org.lwjgl.opengl.Window class, and i don't have it  Huh
And maybe, an other question : what's the origin point in opengl (and so lwjgl) ? i believed that was the left bottom corner , but when i do  :
1  
2  
3  
4  
 glVertex2f(2,-2);
glVertex2f(-2,-2);
glVertex2f(-2,2);
glVertex2f(2,2 );


The quad is drown at the top right corner..


Thanks for answering and sorry for my bad english (i'm a french man...).

Java In Games : Java Games Community for French Developers
Offline tom
« Reply #1 - Posted 2005-07-16 20:37:08 »

Drawing text with LWJGL is difficult. You either have to texture map the characters on to triangles, or use drawPixels.

GLU has an easy way of writing text, but I don't think it's been ported to LWJGL.

Offline Orangy Tang

JGO Kernel


Medals: 56
Projects: 11


Monkey for a head


« Reply #2 - Posted 2005-07-16 20:42:39 »

PS : Is the Window class of LWJGL removed in the lasts versions ? Because i see many docs where they used the org.lwjgl.opengl.Window class, and i don't have it  Huh
And maybe, an other question : what's the origin point in opengl (and so lwjgl) ? i believed that was the left bottom corner , but when i do  :
The functionality of the Window class was mearged into the Display class a couple of versions back, and some docs havn't been updated yet. All the same stuff is still there though.

The origin depends on how you set up your projection and modelview matrices. By default LWJGL sets up the screen with the origin at the bottom left, with one pixel per unit. You can easily change this via glOrtho or glPerspective though.

For simple text, one of the NeHe tutorials does text with display lists and glDrawPixels, it should be ported to LWJGL somewhere.

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline InfoRital

Junior Devvie





« Reply #3 - Posted 2005-07-16 21:05:23 »

Thanks for your answers.

I initialize projection and co like that :
1  
2  
3  
4  
5  
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      gluOrtho2D(0, 800, 600, 0);
      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();


But the origin corner is the top left one...


For the text, i've found the nehe tutorial, but it looks a bit difficult, no portable as he said, and he seems use a special API for Windows (wgl) and Java and the Jogl ports used AWT and Canvas.
But maybe, with de AWTGLCanvas, i can do something ? But it make me use AWT, and i want to be independant of it (taht's why i use lwjgl instead of jogl).

Java In Games : Java Games Community for French Developers
Offline InfoRital

Junior Devvie





« Reply #4 - Posted 2005-07-16 21:14:19 »

shame on me, i didn't see the LWJGL port. But it looks very very complexe for a simple text...
Will be an easier method implemented in the nexts LWJGL versions ?

Java In Games : Java Games Community for French Developers
Offline Orangy Tang

JGO Kernel


Medals: 56
Projects: 11


Monkey for a head


« Reply #5 - Posted 2005-07-16 21:36:52 »

Thanks for your answers.

I initialize projection and co like that :
1  
2  
3  
4  
5  
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      gluOrtho2D(0, 800, 600, 0);
      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();


But the origin corner is the top left one...

Thats because the params are gluOrtho2d(left, right, bottom, top). So if you want the origin to be bottom-left you want (0, width, 0, height);

shame on me, i didn't see the LWJGL port. But it looks very very complexe for a simple text...
Will be an easier method implemented in the nexts LWJGL versions ?
Text is fundamentally complicated, especially if you want nice crisp fonts and variable-width characters. In fact text in OpenGL is always going to be tricky, as font-rendering is almost always tied to a platform-specific API. I doubt you'll see anything 'simple' appear in LWJGL as it would be somewhat outside the aims.

If you want another method of drawing text you could try Cas' SPGL lib (on sourceforge), but be warned that it'll likely not be any simpler and doesn't exactly come with much documentation (although you might be able to find more details in the forums here).

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
Offline InfoRital

Junior Devvie





« Reply #6 - Posted 2005-07-16 22:27:38 »

Thansk, but in all  little games in java, they used text in their opengl display, didn't they ?
So, it's possible, and it's difficult to make a correct game without using text in it...
I'm trying to make a little class, based on the NeHe tutorial, but for the moment, that just doesn't work...

Java In Games : Java Games Community for French Developers
Offline princec

« JGO Spiffy Duke »


Medals: 437
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #7 - Posted 2005-07-17 10:28:00 »

I have some horribly complicated font generating and rendering code in the Shaven Puppy Game Library, which is just an open view on my work so there's no downloads and it's generally unstable.

It's at sourceforge: http://www.sourceforge.net/projects/spgl

I preprocess normal Java fonts and write them into .jgfont files, which contain a square luminance-alpha bitmap of all the glyphs in the font packed tightly, and a whole load of kerning information. The class in charge of the conversion is in the spgl-tools project, and it's com.shavenpuppy.jglib.tools.FontConverter. It creates com.shavenpuppy.jglib.Font objects. Then I load these into com.shavenpuppy.jglib.opengl.GLFont objects, which creates a GLTexture out of the bitmap; and then I use GLTextAreas and GLStrings in the same package to do rendering.

Cas Smiley

Offline Alan_W

JGO Knight


Medals: 8
Projects: 3


Java tames rock!


« Reply #8 - Posted 2005-07-18 18:22:43 »

Some ideas (None of these are easy)

Method 1
1) Use AWT to draw the desired text onto a BufferedImage.
2) Get the bytes from the BufferedImage and use them as an OpenGL Texture
3) Draw a Textured Quad using OpenGL

Method 2
1) Use a paint program to draw all the letters into a .png graphics file.  (A fixed width font like Courier is easiest)
2) Read the graphics file into a BufferedImage
3) Get the bytes from the BufferedImage and use them as an OpenGL Texture
4) Draw a series of Quads, with the texture coordinates set so each Quad displays the correct letter

Method 3 (I've used this one)
1) Use a paint program to draw all the letters into a .png graphics file.  (A fixed width font like Courier is easiest)
2) Write a java program to convert it into a series of NxN two colour bitmaps with the width a multiple of 8
3) Use glBitmap() (easy) or glDrawPixels() (harder) to paint each letter on the screen as required.

Time flies like a bird. Fruit flies like a banana.
Offline InfoRital

Junior Devvie





« Reply #9 - Posted 2005-07-19 15:12:50 »

Thanks, the last seems to be the best solution (for me, because i don't want to use AWT) and makes Quads to draw letters, i suppose that's consum lots of CPU for anything...

But how did oddlabs in tribal trouble to make text with LWJGL ?

Java In Games : Java Games Community for French Developers
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline oNyx

JGO Coder


Medals: 2


pixels! :x


« Reply #10 - Posted 2005-07-19 18:06:00 »

>i suppose that's consum lots of CPU for anything...

No, it doesn't. Its actually about as fast as it can get... that is as long as you dont use intermediate mode. One texture bind and then a call list per line of text.

If you do something similar in Java2D its also way faster than drawString.

Drawing a fart of polys with one texture isn't much work for your graphics card.

*selfquote*

"The speed seems to be ok. I get around 100 fps if I fill the whole screen with 4368 characters (that's 48lines with 91 characters each... all cramped together like the red/right stuff [line height 10]). Oh and my machine has only 500mhz and a gf2mx... so, yea... it should be fast enough Wink"

4368 characters is a lot of text. (Don't forget that there are games which are <=4096 bytes.)

edit: Oh and I used vertex arrays instead of display lists because of rather odd circumstances. Well, with display lists its most likely faster.

弾幕 ☆ @mahonnaiseblog
Offline InfoRital

Junior Devvie





« Reply #11 - Posted 2005-07-19 18:27:25 »

Thanks for the reply, but , can i have your little code to display caracteres please ?

Java In Games : Java Games Community for French Developers
Offline Alan_W

JGO Knight


Medals: 8
Projects: 3


Java tames rock!


« Reply #12 - Posted 2005-07-19 18:51:32 »

Thanks, the last seems to be the best solution (for me, because i don't want to use AWT) ...

If you don't want to use AWT, that means you can't use BufferedImage.  So... You need to make a separate program (which does use AWT) to read in the .png with the characterset.  You then get the underlying bytes and save them to a file.

You AWTless program, then directly reads the bytes from the file and puts them into a texture or a bitmap.  The textured Quad solution looks tempting, however I do have some code for glDrawPixels.  It will slow your game down if you write lots of letters.

Here is part of my code to convert a .png file to a set of font characters. Note that this code misses out characters that aren't used in the game to save space

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
    /** Include font support for all characters in this string */
    public void includeFont(String s) {
        for (int i=0; i< s.length(); i++) {
            char c = s.charAt(i);
            if (c>='.' && c<='9') c -='.';
            else if (c>='A' && c<='Z') c -='A'-12;
            else if (c>='a' && c<='z') c -='a'-38;
            else continue;
            font[(int)c] = true;
        }
    }

    /** Add 64 character, 16x22 font to the data file */
    public void convertFont(String filename) {
        try {
            // Get the font graphics file
            System.out.println(" "+filename);
            is = new FileInputStream(filename);
            BufferedImage img = ImageIO.read(is);
            // Construct 64 bit header
            // Bit 0 is set if char 0 is present in file etc.
            long f = 0;
            for (int i=63; i>=0; i--)
                if (font[i])
                    f=(f<<1) | 1;
                else
                    f<<=1;
            // Write header as a 'long'
            for (int i=7; i>=0; i--)
                os.write( (int)((f>>(i*8)) & 0xff) );
            for (int c=0; c<64; c++)
                if (font[c])
                    for (int y=0; y<22; y++)
                        for (int x=0; x<2; x++) {
                            int bits = 0;
                            for (int b=0; b<8; b++) {
                                int colour = img.getRGB(16*c+8*x+b, 21-y) & 0xffffff;
                                int mask = (colour==0)?1:0;
                                bits = bits*2 + mask;
                            }
                            os.write(bits);
                        }
            is.close();
        } catch (Exception e) {e.printStackTrace(); };
       
    }


Now we need to open the data file (not shown) & stuff the data into a series of ByteBuffers.  Of course you could just stick it in one texture & use texture coordinates to select the letter for each Quad, which is probably faster (but I have no code for it)

1  
2  
    // Bitmap data
    public ByteBuffer[] fontData = new ByteBuffer[64]; // Font data


1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
            // Load Font data
            long font = is.readLong(); // 64 bits indicating which chars
            for (int c=0; c<64;c++) {  // are defined
                fontData[c] = BufferUtils.createByteBuffer(44);
                for (int i=0; i<44; i++)
                    if ((font & 1) == 1)          // Define char
                        fontData[c].put(is.readByte());
                    else
                        fontData[c].put((byte)0); // Space if no definition
                fontData[c].rewind();
                font>>=1;
            }


1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
    /** Print text string at x, y at specified size */
    public void print(int x, int y, int size, String s) {
        GL11.glPixelZoom(size, size);
        for (int i=0; i<s.length(); i++) {
            char c = s.charAt(i);
            if (c>='.' && c<='9') c -='.';
            else if (c>='A' && c<='Z') c -='A'-12;
            else if (c>='a' && c<='z') c -='a'-38;
            else continue;
            GL11.glRasterPos2i(x+size*16*i, y);           
            GL11.glDrawPixels(16, 22, GL11.GL_COLOR_INDEX,
                                      GL11.GL_BITMAP, fontData[(int)c]);
        }
    }


BTW. You need a fair bit of setup (not shown) to use glDrawPixels, so as to make the background transparent.  glBitmap() is easier as the background is automatically transparent, but you can't scale the letters, nor can you do multi-colour (or anti-aliased) letters.

Time flies like a bird. Fruit flies like a banana.
Offline oNyx

JGO Coder


Medals: 2


pixels! :x


« Reply #13 - Posted 2005-07-19 19:07:42 »

Thanks for the reply, but , can i have your little code to display caracteres please ?

http://cvs.sourceforge.net/viewcvs.py/fluffware/fluffware_ant/src/org/fluffware/game/VAFont.java?rev=1.3&view=log

See also:

http://cvs.sourceforge.net/viewcvs.py/fluffware/fluffware_ant/src/org/fluffware/media/OGLImage.java?rev=1.1&view=log

Its pretty much used like...
1  
2  
3  
4  
5  
6  
VAFont va;
[...]
va=new VAFont(someTexture,VAFont.NEHE,7);
va.setLineHeight(12);
[...]
va.print("foo",x,y);


But maybe you should start with a simpler version.

弾幕 ☆ @mahonnaiseblog
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Mr.CodeIt (22 views)
2014-12-23 03:34:11

rwatson462 (53 views)
2014-12-15 09:26:44

Mr.CodeIt (45 views)
2014-12-14 19:50:38

BurntPizza (84 views)
2014-12-09 22:41:13

BurntPizza (110 views)
2014-12-08 04:46:31

JscottyBieshaar (78 views)
2014-12-05 12:39:02

SHC (89 views)
2014-12-03 16:27:13

CopyableCougar4 (94 views)
2014-11-29 21:32:03

toopeicgaming1999 (155 views)
2014-11-26 15:22:04

toopeicgaming1999 (151 views)
2014-11-26 15:20:36
Resources for WIP games
by kpars
2014-12-18 10:26:14

Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!