问题描述
我正在使用2D游戏引擎,并且想实现文本渲染。我想使用freetype。我有以下代码:
gluint va;
glGenVertexArrays(1,&va);
gluint vb;
glGenBuffers(1,&vb);
glBindVertexArray(va);
glBindBuffer(GL_ARRAY_BUFFER,vb);
glBufferData(GL_ARRAY_BUFFER,sizeof(float) * 6 * 4,NULL,GL_DYNAMIC_DRAW);
glEnabLevertexAttribArray(0);
glVertexAttribPointer(0,4,GL_FLOAT,GL_FALSE,4 * sizeof(float),0);
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindVertexArray(0);
FT_Face testface;
FT_Error error;
error = FT_New_Face(ftlib,"arial.ttf",&testface);
if (error == FT_Err_UnkNown_File_Format)
{
std::cout << "Font format not supported" << std::endl;
}
else if (error)
{
std::cout << "Something else" << "\n";
}
error = FT_Set_Pixel_Sizes(testface,48);
if (error)
{
std::cout << "Problem with set px szes occ\n";
}
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
for (unsigned char c = 0; c < 128; c++)
{
if (FT_Load_Char(testface,c,FT_LOAD_RENDER))
{
std::cout << "Error. Failed to load glyph "<<c<<"\n";
continue;
}
gluint texture;
glGenTextures(1,&texture);
glBindTexture(GL_TEXTURE_2D,texture);
glTexImage2D(
GL_TEXTURE_2D,GL_RED,testface->glyph->bitmap.width,testface->glyph->bitmap.rows,GL_UNSIGNED_BYTE,testface->glyph->bitmap.buffer
);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
Character newchar = {
texture,glm::ivec2(testface->glyph->bitmap.width,testface->glyph->bitmap.rows),glm::ivec2(testface->glyph->bitmap_left,testface->glyph->bitmap_top),testface->glyph->advance.x
};
characters.insert(std::pair<char,Character>{c,newchar});
}
FT_Done_Face(testface);
//glPixelStorei(GL_UNPACK_ALIGNMENT,4);
gluseProgram(text_shader_program);
gluniform4f(glGetUniformlocation(text_shader_program,"textColor"),1.f,1.f);
glActiveTexture(GL_TEXTURE0);
std::string::const_iterator c;
std::string text = "TEST";
glBindVertexArray(va);
float x = 0.f;
for (c = text.begin(); c != text.end(); c++)
{
Character ch = characters[*c];
float xpos = x + ch.bearing.x;
float ypos = 0.f - (ch.size.y - ch.bearing.y);
float w = ch.size.x;
float h = ch.size.y;
float vertices[6][4] = {
{xpos,ypos + h,0.f,0.f},{xpos,ypos,1.f},{xpos + w,0.f}
};
glBindTexture(GL_TEXTURE_2D,ch.textureID);
glBindBuffer(GL_ARRAY_BUFFER,vb);
glBufferSubData(GL_ARRAY_BUFFER,sizeof(vertices),vertices);
glBindBuffer(GL_ARRAY_BUFFER,0);
glDrawArrays(GL_TRIANGLES,6);
x += (ch.advance >> 6);
}
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D,0);
FT_Error error = FT_Init_FreeType(&ftlib);
if (error)
{
std::cout << "????" << std::endl;
}
人脸和库正确初始化,字形已加载,但未绘制任何内容。我不使用摄像头,因此所有坐标都在-1到1的空间内。
我具有以下用于着色的着色器: 顶点着色器
#version 330 core
layout(location=0) in vec4 vertex;
out vec2 TextCoords;
void main() {
gl_Position = vec4(vertex.xy,0.0,1.0);
TextCoords = vertex.zw;
}
fragmentshader
#version 330 core
in vec3 TextCoords;
out vec4 color;
uniform sampler2D text;
uniform vec4 textColor;
void main(){
vec4 sampled = vec4(1.0,1.0,texture(text,TextCoords).r);
color = textColor * sampled;
}
更新:
我将FT_Set_Pixel_Sizes(testface,48)
行更改为FT_Set_Pixel_Sizes(testface,1)
,并在文本应有的地方得到了一个巨大的灰色矩形。
有人有什么想法吗?
解决方法
问题似乎是未使用z坐标的结果。问题是,当使用坐标空间-1到1时,文本呈现的比例过大,无法看到或识别。解决方案是将z坐标用作静态相机视图,因此对于500x500窗口,边框为-250.f和250.f