font rendering in OGL 3.3

Started by
7 comments, last by Yours3!f 12 years, 10 months ago
Hi,

I'm trying to render text in OGL 3.3 using VBOs and VAOs, I can load the font files, however, when I write out the texture IDs I always get this number 4294967295, and I don't get any OpenGL errors...
When I try to display the text in OGL 2.1 using immediate mode, it works as expected.

here's how I render:

//-----------------------------------------

modelview_stack.push_matrix();

modelview_stack.translate_matrix ( mymath::vec3f ( 1.0f, 0.0f, -1.0f ) );
modelview_stack.rotate_matrix( 90.0f, mymath::vec3f ( 1.0f, 0.0f, 0.0f ) );

the_pipeline.get_model_view_matrix().copy_m4x4_data ( mv );
the_pipeline.get_projection_matrix().copy_m4x4_data ( proj );

font_shader.use_program();

glUniformMatrix4fv ( glGetUniformLocation ( font_shader.shader_program, font_shader.resources[0].name.c_str() ), 1, false, proj );
glUniformMatrix4fv ( glGetUniformLocation ( font_shader.shader_program, font_shader.resources[1].name.c_str() ), 1, false, mv );

//something is not right...
glBindTexture ( GL_TEXTURE_2D, character_textures[96].tex_data );
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glUniform1i ( glGetUniformLocation ( font_shader.shader_program, font_shader.resources[2].name.c_str() ), 0 );

glEnable(GL_BLEND); //change
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //change

draw_meshes_vbo ( plane );

glDisable(GL_BLEND); //change

font_shader.return_to_fixed_program();

modelview_stack.pop_matrix();

//-----------------------------------------


here's how I load the font texture:

void font::font_loadfontmap ()
{
font_setpointsize ( pointsize );

font_map fontmap;

fontmap.pointsize = pointsize; //change

for ( int c = 0;c < 256;c++ )
{
glGenTextures ( 1, &fontmap.charlist[c].texture );

//FT_Load_Char(ftface, c, FT_LOAD_RENDER);

if ( FT_Load_Char ( ftface, c, FT_LOAD_RENDER ) )
{
std::cerr << "error loading glyph....\n";
}

fontmap.charlist[c].charwidth = ftslot -> bitmap.width;
fontmap.charlist[c].charheight = ftslot -> bitmap.rows;

fontmap.charlist[c].width = font_next_powa2 ( ftslot -> bitmap.width );
fontmap.charlist[c].height = font_next_powa2 ( ftslot -> bitmap.rows );
fontmap.charlist[c].advancex = ftslot -> advance.x >> 6;

fontmap.charlist[c].offsetx = ftslot -> bitmap_left;
fontmap.charlist[c].offsety = ftslot -> bitmap_top;

GLubyte * data = new GLubyte[4 * fontmap.charlist[c].width * fontmap.charlist[c].height];

for ( int j = 0;j < fontmap.charlist[c].height; j++ )
{
for ( int i = 0;i < fontmap.charlist[c].width; i++ )
{
data[2 * ( i + j * fontmap.charlist[c].width ) ] = 255;
data[2 * ( i + j * fontmap.charlist[c].width ) + 1] = 255;
data[2 * ( i + j * fontmap.charlist[c].width ) + 2] = 255;
data[2 * ( i + j * fontmap.charlist[c].width ) + 3] = ( i >= ftslot -> bitmap.width || j >= ftslot -> bitmap.rows ) ? 0 : ftslot -> bitmap.buffer[i + ftslot -> bitmap.width * j];
}
}

glBindTexture ( GL_TEXTURE_2D, fontmap.charlist[c].texture );
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGBA, fontmap.charlist[c].width, fontmap.charlist[c].height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );

delete [] data;
}

fontmaps.push_back ( fontmap );
}


here's the shader code:

/*
* font.vs
*
*/
#version 330

//modelviewprojection, modelview matrices
uniform mat4 m4_p, m4_mv;

//the vertex position
in vec4 v4_vertex;
//the texture coordinates
in vec2 v2_texture;

smooth out vec2 v2_texture_coords;

void main()
{
v2_texture_coords = v2_texture;
mat4 m4_mvp = m4_p * m4_mv;
gl_Position = m4_mvp * v4_vertex; //simple mvp transformation, and pass the texture coords
}

/*
* font.ps
*
*/
#version 330

uniform sampler2D texture_map;

smooth in vec2 v2_texture_coords;

out vec4 v4_frag_color;

void main()
{
//simply display the texture
v4_frag_color = texture(texture_map, v2_texture_coords.st); //no texture?
}


here's the texture loading:

texture font::get_char_texture ( int char_num )
{
if ( index < 0 )
{
for ( int ind = 0; ind < fontmaps.size(); ind++ )
{
if ( fontmaps[ind].pointsize == pointsize )
{
index = ind;
break;
}
}
}

texture out;

if ( index < 0 || index > fontmaps.size() - 1 )
{
//font_loadfontmap(); we don't need it
index = fontmaps.size() - 1;

if ( index < 0 )
{
std::cerr << "Cannot set index for character: " << char_num << "\n";
return out;
}
}

if ( char_num < 0 || char_num > 255 )
{
std::cerr << "Invalid charnum: " << char_num << "\n";
return out;
}

//if we have the index and the char_num right, then lets pass the texture's id, width, and height
out.tex_data = fontmaps[index].charlist[char_num].texture;
out.tex_width = fontmaps[index].charlist[char_num].width;
out.tex_height = fontmaps[index].charlist[char_num].height;

return out;
}


and here's the mesh loading:

mesh font::get_char_mesh ( int char_num )
{
if ( index < 0 )
{
for ( int ind = 0; ind < fontmaps.size(); ind++ )
{
if ( fontmaps[ind].pointsize == pointsize )
{
index = ind;
break;
}
}
}

mesh out;

if ( index < 0 || index > fontmaps.size() - 1 )
{
//font_loadfontmap(); we don't need it
index = fontmaps.size() - 1;

if ( index < 0 )
{
std::cerr << "Cannot set index for character: " << char_num << "\n";
return out;
}
}

if ( char_num < 0 || char_num > 255 )
{
std::cerr << "Invalid charnum: " << char_num << "\n";
return out;
}

//if we got the index and the char_num right then let's set the offset for the char (the padding)
int offsetx = fontmaps[index].charlist[char_num].offsetx;
int offsety = -fontmaps[index].charlist[char_num].offsety;

//texture coordinates
float tx = ( float ) fontmaps[index].charlist[char_num].charwidth / ( float ) fontmaps[index].charlist[char_num].width;
float ty = ( float ) fontmaps[index].charlist[char_num].charheight / ( float ) fontmaps[index].charlist[char_num].height;

//make some space for four vertices and two faces
out.vertices.resize ( 4 );
out.tex_coords.resize ( 4 );
out.faces.resize ( 2 );

for ( int c = 0; c < 4; c++ )
{
out.vertices[c].resize ( 3 );
out.tex_coords[c].resize ( 2 );
}
out.faces[0].resize ( 9 );
out.faces[1].resize ( 9 );

//first vertex
out.vertices[0][0] = offsetx;
out.vertices[0][1] = offsety;
out.vertices[0][2] = 0.0f;
out.tex_coords[0][0] = 0.0f;
out.tex_coords[0][1] = 0.0f;

//second vertex
out.vertices[1][0] = offsetx;
out.vertices[1][1] = fontmaps[index].charlist[char_num].charheight + offsety;
out.vertices[1][2] = 0.0f;
out.tex_coords[1][0] = 0.0f;
out.tex_coords[1][1] = ty;

//third vertex
out.vertices[2][0] = fontmaps[index].charlist[char_num].charwidth + offsetx;
out.vertices[2][1] = fontmaps[index].charlist[char_num].charheight + offsety;
out.vertices[2][2] = 0.0f;
out.tex_coords[2][0] = tx;
out.tex_coords[2][1] = ty;

//fourth vertex
out.vertices[3][0] = fontmaps[index].charlist[char_num].charwidth + offsetx;
out.vertices[3][1] = offsety;
out.vertices[3][2] = 0.0f;
out.tex_coords[3][0] = tx;
out.tex_coords[3][1] = 0.0f;

//first poly, we use 1 for vertex index, since it should look like it was loaded from an obj file, so that our fill_obj() function will work
out.faces[0][0] = 1;
out.faces[0][1] = 1;
out.faces[0][2] = 0;

out.faces[0][3] = 3;
out.faces[0][4] = 3;
out.faces[0][5] = 0;

out.faces[0][6] = 2;
out.faces[0][7] = 2;
out.faces[0][8] = 0;

//second poly
out.faces[1][0] = 1;
out.faces[1][1] = 1;
out.faces[1][2] = 0;

out.faces[1][3] = 4;
out.faces[1][4] = 4;
out.faces[1][5] = 0;

out.faces[1][6] = 3;
out.faces[1][7] = 3;
out.faces[1][8] = 0;

return out;
}


any ideas?

Best regards,
Yours3!f
Advertisement
What do you mean, when you write out the texture IDs? What variable are you writing out where?

What do you mean, when you write out the texture IDs? What variable are you writing out where?


I do:

std::cout << character_textures[96].tex_data << "\n";

where tex_data is a GLuint containing the texture's id.
I see character_textures on your rendering snippet but not in your font loading snippet. Where does character_textures get it's tex IDs generated? 4294967295 looks like an uninitialized variable. Have you stepped through with a debugger?
ok so I checked the texture generation and I just didn't set the pointsize right, so it loaded the data into the -1 th element of the array XD

now I did some modifications and now the the rectangles are all white, so I guess the RGB channels are loaded fine (all 255), but the alpha channel is just not right.
I tried to see what might be the error, so I wrote out the alpha values, here's the alpha values for "2":

R ? ? ? ? ? k ?
? ? ? ? ? ? ? ? ? ? '
? ? ? ? ? ? ? ? ? ? ?
X ? ? ? ? T ? \ ? ? ? ? |
? ? ? ? ? ? ? ?
? ? ? 9 P ? ? ?
? ? ? ?
c ? ? ?
? ? ? ]
+ ? ? ?
? ? ? ? $
? ? ? ? L
? ? ? ? X
? ? ? ? O
F ? ? ? B
] ? ? ? &
C ? ? ? ?
? ? ? ? ?
a ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? ? ? ?

looks nice (despite some lines have slipped here, the output is ok) isn't it?

I've modified the code above so you can see the changes. Any ideas why the alpha values are wrong?

Best regards,
Yours3lf
Just skim reading...


for ( int j = 0;j < fontmap.charlist[c].height; j++ )
{
for ( int i = 0;i < fontmap.charlist[c].width; i++ )
{
data[2 * ( i + j * fontmap.charlist[c].width ) ] = 255;
data[2 * ( i + j * fontmap.charlist[c].width ) + 1] = 255;
data[2 * ( i + j * fontmap.charlist[c].width ) + 2] = 255;
data[2 * ( i + j * fontmap.charlist[c].width ) + 3] = ( i >= ftslot -> bitmap.width || j >= ftslot -> bitmap.rows ) ? 0 : ftslot -> bitmap.buffer[i + ftslot -> bitmap.width * j];
}
}


Why is your channel coefficient 2? You are working with a 4 channel image, should that not be 4? In my experience, if an image looks skewed and/or channels are corrupt, this is usually the reason.

Why is your channel coefficient 2? You are working with a 4 channel image, should that not be 4? In my experience, if an image looks skewed and/or channels are corrupt, this is usually the reason.


ooops I left it in, in the OGL 2.1 version I used to work with 2 channels and GL_LUMINANCE_ALPHA as the format. However, I changed it but it's the same, except it is now translucent.
Turn off blending and post a screenshot. It's difficult to visualise the problem based on your description and ASCII diagram. What do you mean by "It's the same but translucent"?
here are the screenshots

I meant that the white square's opacity decreased as in the pictures

This topic is closed to new replies.

Advertisement