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