• Advertisement
Sign in to follow this  

calculating texture coords

This topic is 2901 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I hope this is the forum to post in. I am doing a dynamic TTF loader for OpenGL. I am using SDL and SDL_ttf for this. 1. Create a string with the chosen characters to be included ( ASCII table 33 to 126 ) 2. Use SDL_ttf to render that string onto a SDL_Surface. Create texture. The texture will be later used for rendering. 3. Calculate each characters texture size and vertex size. This is to be stored in the video memory using VBO. One texture array and one vertex array. I think you know where I am going with this, it is basically a font sheet. I am using three fonts to try this out, Verdana, Times New Roman and a custom font I downloaded from the net (Amiga style). It works... almost. Amiga works perfectly for some reason but the other two are turning out wrong. Like you can see a little bit of the next character in line etc. The problem must lie where the coords are being layed out. I am not sure if you want to look at the whole foor loop or the actual calculation. I start with a tiny bit. I think startX and endX speaks for themselves but here it goes. startX = starting position of the texture. endX = end position of the texture. Layed out for each single character.
if( i != 0 )
	startX = endX;
	startX = 0.0f;
endX += 1.0f / ( ( GLfloat )asciiTable->w / tempSurf->w );

"asciiTable->w" gives me the width of the actual "font sheet". "tempSurf->w" gives me the width of the character currently being processed. 1.0f is equal to 100% of the texture, in this case it would be the font sheet. So my thoughts went like this, first I get the wdith size according to the asciiTable and then I get the size according to texture messurement. I use ( GLfloat ) cast to get a little more precision. However, if you count the tempSurf width in the loop by adding it each time to a variable you will get a number that is higher than the asciiTable width. So, any thoughts? Or is the integer meassurements screwing it up?

Share this post

Link to post
Share on other sites
You should print the string to texture without kerning. It's causing them to be stored with uneven spacing. Which is causing you to loop over them to find the "correct" position.

Which is incorrect since it has been kerned only for it's neighboring letters.

Say you had a string
ABCDEFG and you choose B to display on your screen. B has been spaced specifically to be between A and C in this case and it's spacing would be different in a different word.

So anyways, you dont want to store the letters kerned. It's just going to screw you up. You should store the letters centered in each of their cell (horizontally). Then finding the letter index is simple, since they're evenly spaced.
float characterStart = characterIndex * characterCellsWidth;

You can then adjust your texture coordinates and vertices depending on the actual width of the character. For example the letter 'i' would have a lot of extra space around it that you would want to trim out.

So you'd have an evenly spaced texture of letters, a table indicated how wide each letter is. And optionally another table indicating what the additional placement spacing (can be negative) of each letter placed next to each other letter.

That being said, your method should "work" it will just cause a lot of extra computation to find each character start, and apparently has a bug in it.

Share this post

Link to post
Share on other sites
Yea I had this in the back of my head, the technique you are describing is what I used when doing it with a image already layed out in photoshop. Well what everybody is probably using for font sheets.

However, lets take the ABC as an example.

A has the width of 5.
B has the width of 10.
C has the width of 5.

Rendering them in one string would give me a total width of 20. They are uneven but they are not overlapping or anything but instead just thouching each others edge (though they are not exactly touching each others sides, most glyph has a little space on each side).

When I assign the texture coordinates I am adding the previous width of the character to get the new position. Instead of increasing by a "fixed" cell size. Would that not give me the same effect? The starting position of a new character is still there. I am not using any "texture position" talk below, just to get the idea out.

My way
A has starting position 0
B has starting position 5 <--- A has width of 5
C has starting position 15 <--- B has width of 10

Cell way
A has starting position 0
B has starting position 10 <-- cell size is 10
C has starting position 20
D has starting position 30

Also, my "ending position" is the width of my current letter which will be the next start position.

When I am drawing the letters out I am using this "technique". I will just paste the whole loop.

GLint fontSize = myAsciiTable.length() * selection;
GLint stepSize = 8; //8 vertex per quad
GLint offset;
for( GLuint i = 0; i < text.length(); i++ ) {

for( GLuint j = 0; j < myAsciiTable.length(); j++ ) {

if( text[ i ] == myAsciiTable[ j ] ) {
glTranslatef( x, y, 0.0f );
x += myFontWidth[ fontSize + j ];

offset = stepSize * j;
glDrawElements( GL_QUADS, 4, GL_UNSIGNED_SHORT, BUFFER_OFFSET( offset ) );

As I mentioned earlier, it is working with one particular font and it does it perfectly. Though every other font seems to do it wrong for some reason.

Anyhow, did this make any sens?
If I am totaly wrong I guess the only problem is how to dynamically load the font in with fixed cell size.

Share this post

Link to post
Share on other sites
If you're set on using a sheet, then render each glyph individually and pack them into the texture.
That will ensure that there's no overlap between cells due to kerning or stylistic choices by the font. If you want a fixed-width look, center the rendered glyph within its grid cell.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement