Hello Guest

Trying to make a font renderer system...

  • 13 Replies
  • 9617 Views
*

Offline Yuri6037

  • ***
  • 104
  • Check out our website : http://www.sldt-team.net !
    • SLDT
Trying to make a font renderer system...
« on: October 23, 2013, 15:18:39 »
Hello,

Because of limitations, performence issues and blockages I need to kill the library I was using : Slick2D ! Currently I have finished the RenderEngine (rendering math forms, mounting colors and textures)...

Now the problem is text rendering... So my idea would be to create a 1024 by 1024 font texture in ascii (.png), devide it into squares that matches ascii char code like name ! But i don't know how to do that in LWJGL !

I only need that and the whole renderer system is terminated, it only rest to change the references to Graphics (Slick2d) with the unique instance of RenderEngine...


Please help me,
Yuri6037

*

Offline Yuri6037

  • ***
  • 104
  • Check out our website : http://www.sldt-team.net !
    • SLDT
Re: Trying to make a font renderer system...
« Reply #1 on: October 24, 2013, 07:35:42 »
Nobody has an idea... Nobody can help ? You know how to render math forms, and you have helped me in the past. But you don't know how to render fonts ?
Strange...

I will never finish the new version of my game !
« Last Edit: October 24, 2013, 07:37:34 by Yuri6037 »

*

Offline quew8

  • *****
  • 569
  • Because Square Eyes Look More Real
Re: Trying to make a font renderer system...
« Reply #2 on: October 24, 2013, 16:56:54 »
What do you mean by "Maths Forms"? As in mathematical notation? How did you do that? I'm not really sure how the two would be different.

As for your idea (which is an established way of doing it) you load the whole thing as one texture and then mess around with the texture coords when you draw. This is a very general description so please feel free to ask specific questions. It's just that there's no point me going into any detail since 90% of it you'll probably already know.

Re: Trying to make a font renderer system...
« Reply #3 on: October 24, 2013, 19:00:17 »

*

Offline Yuri6037

  • ***
  • 104
  • Check out our website : http://www.sldt-team.net !
    • SLDT
Re: Trying to make a font renderer system...
« Reply #4 on: October 24, 2013, 19:52:00 »
@Quew8
Hi, that's was a long time !
In effect, because i'm French it's complicated for me to explain something good in english... So excuse me, i will try to explain better now :
I would like to create a class called FontRenderer that will be used by the game to draw text at the screen...

For the "math forms", i  have to say that for example it refer to the functions renderQuad, renderUnfilledQuad, renderTriangle or renderRound in the game RenderEngine, it means respectively draw a quad, draw an unfilled quad, draw a triangle or draw a round at screen.

I wan't another time to say that i'm completly sorry for this incomprehention, that's because i'm French !
I had to leave french programming forums because of excessive number of kikoolols, noob, no brain's kid and many other reasons, in plus in all french programming forums nobody know how to use LWJGL (they don't know what is glVertex2f, and when you ask what class is to use when you wan't OpenGL 1.1 they answer org.lwjgl.Display). I hope now you understand the problem...


@juemisorg
Good code, i don't know if i will take that because i'm searching for a 1024 (i prefer 4096 but that exced my Ram) font reader not a 256 (too bad quality) font reader...
Thank you very much, you helped a little !

Yuri6037 !
« Last Edit: October 24, 2013, 19:53:58 by Yuri6037 »

*

Offline quew8

  • *****
  • 569
  • Because Square Eyes Look More Real
Re: Trying to make a font renderer system...
« Reply #5 on: October 24, 2013, 20:39:25 »
OK. Call them "shapes" or "geometry", not "maths forms." I do know where you're coming from - the french "formes" - but otherwise you will seriously confuse people. Or at least you will me. I've often imagined how hard it must be to learn programming or an API from another language. Now on to serious matters.

So first of all take a look at the OpenGL texture coordinate system. Yes the Y-Axis is upside down. Maybe you already knew this, I'm just saying it in case you didn't to save you the annoyance. As it happens I think that'll help you here... So from the picture you can see how you might get the texture coordinates of a particular grid square.



Now what you need then is a way to access the appropriate texture coordinate from the ascii code of the character. Personally, if it was me I would store the locations in an ArrayList and just look them up each time. You could also however work them out each time if you so wished.

A little example of how to draw them then. This assumes the grid you use is 8 across by 16 down (8 * 16 = 128). I know there aren't actually 128 characters you'll want to draw but you get the picture.

Code: [Select]
public void drawLine(String line, float xPos, float yPos, float charWidth, float charHeight) {
    bindTexture();
    float x = xPos;
    glBegin(GL_QUADS);
    for(int i = 0; i < line.length; i++) {
        int code = (int) line.charAt(i);
        int gridX = code % 16;  //Works out the position in the grid of this character.
        int gridY = ( code - gridX ) / 16;
        float texX = (float) gridX / 8; //Works out the texture coord of the upper left corner of the char.
        float texY = (float) gridY / 16;

        glTexCoord2f(texX, texY); //Upper Left Corner
        glVertex2f(xPos, yPos);

        glTexCoord2f(texX, texY + (1 / 16) ); //Bottom Left Corner
        glVertex2f(xPos, yPos - charHeight);

        glTexCoord2f(texX + (1 / 8), texY + (1 / 16) ); //Bottom Right Corner
        glVertex2f(xPos + charWidth, yPos - charHeight);

        glTexCoord2f(texX + (1 / 8), texY); // Top Right Corner
        glVertex2f(xPos + charWidth, yPos);
    }
    glEnd();
}

I haven't tested this code and it has been years since I've used immediate mode so I am the first to admit that it might not quite work. But I hope it should give you a good idea.
« Last Edit: October 24, 2013, 20:42:12 by quew8 »

*

Offline quew8

  • *****
  • 569
  • Because Square Eyes Look More Real
Re: Trying to make a font renderer system...
« Reply #6 on: October 25, 2013, 16:59:12 »
Also I just remembered this: http://www.blackpawn.com/texts/lightmaps/ Maybe it will be of some help.

*

Offline Yuri6037

  • ***
  • 104
  • Check out our website : http://www.sldt-team.net !
    • SLDT
Re: Trying to make a font renderer system...
« Reply #7 on: October 27, 2013, 15:40:20 »
I think i will Slick Util...
I can't find any way to do what i'm searching for !
I hope one day i will arrive to something ! But if i arrive to something that's will not a font of 1024 by 1024 (it's impossible to get one character on a 1024 by 1024 grid) !

If you have some other things, I will take...

I have tried many many many things for that but nothing works, your code too !

*

Offline Cornix

  • *****
  • 488
Re: Trying to make a font renderer system...
« Reply #8 on: October 27, 2013, 15:44:08 »
Maybe you should study the openGL functions a little bit more.
A font rendering system is actually quite easy to write yourself. I didnt have any problem writing mine.
What exactly are you having problems with, and why would you need a 1024x1024 texture for that?

*

Offline Yuri6037

  • ***
  • 104
  • Check out our website : http://www.sldt-team.net !
    • SLDT
Re: Trying to make a font renderer system...
« Reply #9 on: October 28, 2013, 20:23:43 »
Thanks for answer. The problem is that I can't find any working way to do a font renderer. I have tried tutorials but tutorials gived me code which the game not rendering, game crash or game enter in a loop wich can not be stopped until use CTRL + ALT + SUPPRESS !

Why wan't I to do a 1024 by 1024 font rendering ?
For the moment all my textures are in HD so I don't won't to see any pixelisation effect.

And you are saying that making a Font Renderer is easy... Not at all it's extremely complicated like the render engine wich I have done (without any help) !


You are telling study OpenGL !
You are funny !
Yeah I won't so much to study OpenGL. But nobody, no working tutorials, no website nothing interessant about OpenGL ! Only this forum I have found !!!
So if you have a few sites to learn I will take them quickly !

Thank you again for answer,
Yuri6037


*

Offline Cornix

  • *****
  • 488
Re: Trying to make a font renderer system...
« Reply #10 on: October 28, 2013, 21:47:28 »
You didnt find anything about openGL? This sounds highly dubious. There are more tutorials about openGL then you have cells in your body.

The premise of a font renderer is simple. You have a texture with the glyphs, and you have to map those glyphs on quads.
I would suggest using some kind of a map, for example a hashmap, to map characters and texture cutouts.
Then, iterate through the string you want to render, for each letter you fetch the cutout from the map and save it in a vbo.
Here is an example code. I wrote this code in 10 minutes and I didnt test it, but it should be enough to give you a general idea:
Code: [Select]
public class FontRenderer {

// Both a float and an int use 4 bytes.
private static final int FLOAT_BYTE_SIZE = 4;
private static final int INT_BYTE_SIZE = 4;

// Each quad is one glyph and needs 4 vertices.
private static final int VERTICES_PER_QUAD = 4;
// Each quad is split up into 2 triangles, thus we need 6 indices.
private static final int INDICES_PER_QUAD = 6;

private static final int VERTEX_COUNT = 4;
private static final int TEXCOORD_COUNT = 4;

// These correspond to the cutouts for the glyphs in our map.
private static final int CUTOUT_X = 0;
private static final int CUTOUT_Y = 1;
private static final int CUTOUT_WIDTH = 2;
private static final int CUTOUT_HEIGHT = 3;

// We save our glyphs in this map. It maps character to a float array with 4 elements = x, y, width and height.
private HashMap<Character, float[]> cutouts = new HashMap<>();
private int vboID = 0;
private int iboID = 0;
private int size = 0;
private int stride = (VERTEX_COUNT + TEXCOORD_COUNT) * FLOAT_BYTE_SIZE;

public FontRenderer() {
vboID = GL15.glGenBuffers();
iboID = GL15.glGenBuffers();
}

public void addGlyph(Character character, float x, float y, float width, float height) {
cutouts.put(character, new float[] {x, y, width, height});
}

public void makeVBO(String text, float x, float y, float z) {
/*
* If you want to draw a quad with 2 triangles you need 6 indices.
* These are 0, 1, 2 for the first triangle, and 2, 3, 0 for the second one.
*/
size = text.length() * INDICES_PER_QUAD;

/*
* For each vertex we put:
* x, y, z, w = 1
* u, v, 0, 1
* Each letter needs 4 vertices.
*/
float[] vertices = new float[text.length() * (VERTEX_COUNT + TEXCOORD_COUNT) * VERTICES_PER_QUAD];
int[] indices = new int[size];

int offsetVertices = 0;
int offsetIndices = 0;

for (int letterID = 0; letterID < text.length(); letterID++) {
Character letter = text.charAt(letterID);
// This array is always 4 elements in size: x, y, width and height.
float[] cutout = cutouts.get(letter);

// Upper left corner
vertices[offsetVertices++] = x;
vertices[offsetVertices++] = y;
vertices[offsetVertices++] = z;
vertices[offsetVertices++] = 1;

vertices[offsetVertices++] = cutout[CUTOUT_X];
vertices[offsetVertices++] = cutout[CUTOUT_Y];
vertices[offsetVertices++] = 0;
vertices[offsetVertices++] = 1;

// Lower left corner
vertices[offsetVertices++] = x;
vertices[offsetVertices++] = y + cutout[CUTOUT_HEIGHT];
vertices[offsetVertices++] = z;
vertices[offsetVertices++] = 1;

vertices[offsetVertices++] = cutout[CUTOUT_X];
vertices[offsetVertices++] = cutout[CUTOUT_Y] + cutout[CUTOUT_HEIGHT];
vertices[offsetVertices++] = 0;
vertices[offsetVertices++] = 1;

// Lower right corner
vertices[offsetVertices++] = x + cutout[CUTOUT_WIDTH];
vertices[offsetVertices++] = y + cutout[CUTOUT_HEIGHT];
vertices[offsetVertices++] = z;
vertices[offsetVertices++] = 1;

vertices[offsetVertices++] = cutout[CUTOUT_X] + cutout[CUTOUT_WIDTH];
vertices[offsetVertices++] = cutout[CUTOUT_Y] + cutout[CUTOUT_HEIGHT];
vertices[offsetVertices++] = 0;
vertices[offsetVertices++] = 1;

// Upper right corner
vertices[offsetVertices++] = x + cutout[CUTOUT_WIDTH];
vertices[offsetVertices++] = y;
vertices[offsetVertices++] = z;
vertices[offsetVertices++] = 1;

vertices[offsetVertices++] = cutout[CUTOUT_X] + cutout[CUTOUT_WIDTH];
vertices[offsetVertices++] = cutout[CUTOUT_Y];
vertices[offsetVertices++] = 0;
vertices[offsetVertices++] = 1;

// We make sure that the next letter will be drawn to the right of this letter.
x += cutout[CUTOUT_WIDTH];

// Indices
indices[offsetIndices++] = letterID * VERTICES_PER_QUAD + 0;
indices[offsetIndices++] = letterID * VERTICES_PER_QUAD + 1;
indices[offsetIndices++] = letterID * VERTICES_PER_QUAD + 2;
indices[offsetIndices++] = letterID * VERTICES_PER_QUAD + 2;
indices[offsetIndices++] = letterID * VERTICES_PER_QUAD + 3;
indices[offsetIndices++] = letterID * VERTICES_PER_QUAD + 0;
}
assert offsetVertices == vertices.length;

bind();
vertexData(vertices);
indexData(indices);
}

public void bind() {
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboID);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, iboID);

GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);

GL11.glVertexPointer(VERTEX_COUNT, GL11.GL_FLOAT, stride, 0);
GL11.glTexCoordPointer(TEXCOORD_COUNT, GL11.GL_FLOAT, stride, VERTEX_COUNT * FLOAT_BYTE_SIZE);
}

public void dispose() {
GL15.glDeleteBuffers(vboID);
GL15.glDeleteBuffers(iboID);
}

public void vertexData(float[] data) {
FloatBuffer buffer = ByteBuffer.allocateDirect(data.length * FLOAT_BYTE_SIZE)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
buffer.put(data);
buffer.flip();

GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
}

public void indexData(int[] data) {
IntBuffer buffer = ByteBuffer.allocateDirect(data.length * INT_BYTE_SIZE)
.order(ByteOrder.nativeOrder()).asIntBuffer();
buffer.put(data);
buffer.flip();

GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
}

public void render() {
bind();
GL11.glDrawElements(GL11.GL_TRIANGLES, size, GL11.GL_UNSIGNED_INT, 0);
}

}

You need some kind of implementation for textures too.
This is not a very efficient implementation. Many things can be done much better then here, but it should be enough to understand the concept behind it.
« Last Edit: October 28, 2013, 21:50:09 by Cornix »

*

Offline Yuri6037

  • ***
  • 104
  • Check out our website : http://www.sldt-team.net !
    • SLDT
Re: Trying to make a font renderer system...
« Reply #11 on: October 29, 2013, 09:11:01 »
Thanks,
I will try your code ! And don't worry about texture implementation. I have maked a void in my render engine wich mount textures into OpenGL and saves the id of it in a hashMap !


*

Offline Yuri6037

  • ***
  • 104
  • Check out our website : http://www.sldt-team.net !
    • SLDT
Re: Trying to make a font renderer system...
« Reply #12 on: October 29, 2013, 13:45:20 »
I have maked this code but nothing appear to the screen :
    
Code: [Select]
    public void drawLine(int texture, String line, float xPos, float yPos, float charWidth, float charHeight) {
        renderEngine.bindTexture(texture);
        glBegin(GL_QUADS);
        for(int i = 0; i < line.length(); i++) {
            int code = (int) line.charAt(i);
            int gridX = code % 16;  //Works out the position in the grid of this character.
            int gridY = ( code - gridX ) / 16;
            float texX = (float) gridX / 16; //Works out the texture coord of the upper left corner of the char.
            float texY = (float) gridY / 16;

            glTexCoord2f(texX, texY); //Upper Left Corner
            glVertex2f(xPos, yPos);

            glTexCoord2f(texX, texY + (1 / 16) ); //Bottom Left Corner
            glVertex2f(xPos, yPos - charHeight);

            glTexCoord2f(texX + (1 / 16), texY + (1 / 16)); //Bottom Right Corner
            glVertex2f(xPos + charWidth, yPos - charHeight);

            glTexCoord2f(texX + (1 / 16), texY); // Top Right Corner
            glVertex2f(xPos + charWidth, yPos);
        }
        glEnd();
    }
« Last Edit: October 29, 2013, 15:25:30 by Yuri6037 »

*

Offline Yuri6037

  • ***
  • 104
  • Check out our website : http://www.sldt-team.net !
    • SLDT
Re: Trying to make a font renderer system...
« Reply #13 on: November 01, 2013, 19:33:04 »
I have created a new topic !