[英]Text does not appear when using egl (opengl) and freetype2 to render text on screen
我已經編寫了在嵌入式設備上運行的應用程序,但是我看到的只是在glViewPort中指定的顏色填充的表面積。
文本不出現。
我有glError打印,以查看某些gl API調用是否失敗,但是什么都沒有失敗。
我也沒有FT庫錯誤。
雖然我的照片顯示face-> glyph-> bitmap.width face-> glyph-> bitmap_left對於我加載的任何字符均為零。
// ******** CODE BELOW ******//
int OpenGlInit()
{
/* Here is the Init code for embedded graphics
This works fine.*/
glViewport(0, 0, 800, 600);
PrintGlError();
char vShaderStr[] =
"attribute vec4 vertex;\n"
"varying vec2 TexCoords;\n"
"uniform vec4 projection;\n"
"void main()\n"
"{\n"
"gl_Position = projection * vec4(vertex.xy, 0, 1);\n"
"TexCoords = vertex.zw;\n"
"}\n";
char fShaderStr[]=
"varying vec2 TexCoords;\n"
"uniform sampler2D text;\n"
"uniform vec4 color;\n"
"void main(void) {\n"
"gl_FragColor = vec4(1, 1, 1, texture2D(text, TexCoords).r) * color;\n"
"}\n";
GLuint vertexShader;
GLuint fragmentShader;
GLint linked;
vertexShader = LoadShader(GL_VERTEX_SHADER, vShaderStr);
fragmentShader = LoadShader(GL_FRAGMENT_SHADER, fShaderStr);
ProgramObject = glCreateProgram();
PrintGlError();
if (ProgramObject == 0) {
printf("DEBUG- glCreateProgram() returned 0\n");
return 0;
}
glAttachShader( ProgramObject, vertexShader );
PrintGlError();
glAttachShader( ProgramObject, fragmentShader );
PrintGlError();
glLinkProgram( ProgramObject );
PrintGlError();
glGetProgramiv( ProgramObject, GL_LINK_STATUS, &linked );
PrintGlError();
if (!linked)
{
printf("failed to link program\n");
GLint infoLen = 0;
glGetProgramiv( ProgramObject, GL_INFO_LOG_LENGTH, &infoLen);
PrintGlError();
if (infoLen > 1)
{
char infoLog[infoLen];
glGetProgramInfoLog( ProgramObject, infoLen, NULL, infoLog );
PrintGlError();
printf("Error linking program:\n%s\n", infoLog);
}
glDeleteProgram( ProgramObject );
PrintGlError();
return GL_FALSE;
}
printf("\nAfter Linked ProgramObject and compiled shaders");
printf("\nBefore Gen Buffers");
glGenBuffers(1, &VBO);
PrintGlError();
printf("\nAfter Gen Buffers");
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
PrintGlError();
glClear(GL_COLOR_BUFFER_BIT);
PrintGlError();
glEnable(GL_BLEND);
PrintGlError();
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
PrintGlError();
if(glGetUniformLocation(ProgramObject, "color") == -1)
printf("\n ERROR uniform color is -1");
GLfloat black[4] = {1, 0, 0, 1};
glUniform4fv(glGetUniformLocation(ProgramObject, "color"), 1, black);
PrintGlError();
printf("\nAfter Matrix4fv");
float sx = 2.0 / 800;
float sy = 2.0 / 600;
RenderText("This is sample text", -1 + 8 * sx, 1 - 50 * sy, sx, sy);
printf("DEBUG\n\n\n\n\n\n\n\n\n\n\n");
RenderText("(C) LearnOpenGL.com", -1 + 8.5 * sx, 1 - 100.5 * sy, sx, sy);
eglSwapBuffers(egldisplay, eglsurface);
PrintGlError();
sleep(30);
glDeleteProgram(ProgramObject);
}
void RenderText(std::string message, GLfloat x, GLfloat y, GLfloat sx, GLfloat sy)
{
FT_Library ft;
FT_Face face;
if(FT_Init_FreeType(&ft))
std::cout << "ERROR::FREETYPE: Could not init FreeType Library" << std::endl;
if(FT_New_Face(ft, "/usr/share/fonts/tt7268mi_.ttf", 0, &face))
std::cout << "ERROR::FREETYPE: Failed to load calibri display" << std::endl;
if(FT_Set_Char_Size(face, 0, 16*64, 300, 300))
std::cout << "ERROR::FREETYPE: Failed to set char size" << std::endl;
printf("\nDEBUG after freetype\n");
if(FT_Set_Pixel_Sizes(face, 0, 48))
std::cout << "ERROR::FREETYPE: Failed to set pixel size" << std::endl;
printf("DEBUG after pixel sizes\n");
glActiveTexture(GL_TEXTURE0);
PrintGlError();
GLuint text;
glGenTextures(1, &text);
PrintGlError();
glBindTexture(GL_TEXTURE_2D, text);
PrintGlError();
if (glGetUniformLocation(ProgramObject, "text") == -1)
printf("\n ERROR uniform text is -1");
glUniform1i(glGetUniformLocation(ProgramObject, "text"), 0);
PrintGlError();
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
PrintGlError();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
PrintGlError();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
PrintGlError();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
PrintGlError();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
PrintGlError();
int vPosition = glGetAttribLocation(ProgramObject, "vertex");
if (vPosition == -1)
printf("\nERROR vPosition is -1");
PrintGlError();
glEnableVertexAttribArray(vPosition);
PrintGlError();
glBindBuffer(GL_ARRAY_BUFFER, VBO);
PrintGlError();
//glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6 * 4, NULL, GL_DYNAMIC_DRAW);
glVertexAttribPointer(vPosition, 4, GL_FLOAT, GL_FALSE, 0, 0);
PrintGlError();
std::string::const_iterator ch;
for (ch = message.begin(); ch != message.end(); ch++)
{
const char c = *ch;
if (FT_Load_Char(face, c, FT_LOAD_RENDER))
{
std::cout << "ERROR::FREETYTPE: Failed to load Glyph" << std::endl;
continue;
}
FT_UInt glyph_index = FT_Get_Char_Index(face, c);
printf("\nglyphindex is: %u",glyph_index);
FT_Load_Glyph(face, glyph_index, FT_LOAD_RENDER);
printf("\nChar: %c, facewidth:%f, faceheight:%f", c, (face->glyph->bitmap.width), (face->glyph->bitmap.rows));
printf("\nfaceleft:%f, facetop:%f ", (face->glyph->bitmap_left), (face->glyph->bitmap_top));
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA,
face->glyph->bitmap.width,
face->glyph->bitmap.rows,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
face->glyph->bitmap.buffer
);
PrintGlError();
GLfloat xpos = x + (face->glyph->bitmap_left) * sx;
GLfloat ypos = -y - (face->glyph->bitmap_top) * sy;
GLfloat w = (face->glyph->bitmap.width) * sx;
GLfloat h = (face->glyph->bitmap.rows) * sy;
printf("\n xpos:%f ypos:%f w:%f h:%f", xpos, ypos, w, h);
/*GLfloat vertices[6][4] = {
{ xpos, ypos + h, 0.0, 0.0 },
{ xpos, ypos, 0.0, 1.0 },
{ xpos + w, ypos, 1.0, 1.0 },
{ xpos, ypos + h, 0.0, 0.0 },
{ xpos + w, ypos, 1.0, 1.0 },
{ xpos + w, ypos + h, 1.0, 0.0 }
};*/
point vertices[4] = {
{xpos, -ypos , 0, 0},
{xpos + w, -ypos , 1, 0},
{xpos, -ypos - h, 0, 1},
{xpos + w, -ypos - h, 1, 1},
};
glBufferData(GL_ARRAY_BUFFER, sizeof vertices, vertices, GL_DYNAMIC_DRAW);
PrintGlError();
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
PrintGlError();
x += (face->glyph->advance.x/64) * sx;
y += (face->glyph->advance.y/64) * sy;
}
glDeleteTextures(1, &text);
glDisableVertexAttribArray(vPosition);
FT_Done_Face(face);
FT_Done_FreeType(ft);
}
void PrintGlError()
{
GLenum ErrorCheckValue = glGetError();
if (ErrorCheckValue != GL_NO_ERROR)
{
fprintf(stderr,"\nGL ERROR:%d", ErrorCheckValue);
}
}
GLuint LoadShader(GLenum type, const char *shaderSrc)
{
GLuint shader;
GLint compiled;
shader = glCreateShader( type );
if (shader == 0) {
return 0;
}
glShaderSource( shader, 1, &shaderSrc, NULL);
PrintGlError();
glCompileShader(shader);
PrintGlError();
glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled);
PrintGlError();
if (!compiled)
{
printf("failed to compile shader\n");
GLint infoLen = 0;
glGetShaderiv(shader,GL_INFO_LOG_LENGTH, &infoLen);
PrintGlError();
if (infoLen > 1) {
char infoLog[infoLen];
glGetProgramInfoLog( ProgramObject, infoLen, NULL, infoLog );
PrintGlError();
printf("Error compiling shader:\n%s\n", infoLog);
}
glDeleteShader(shader);
PrintGlError();
return 0;
}
return shader;
}
您的程序中存在一些問題。
FT_Load_Glyph
生成的位圖只有一個顏色通道。 這意味着在定義紋理圖像時, glTexImage2D
的第七個參數必須是GL_RED
:
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA,
face->glyph->bitmap.width,
face->glyph->bitmap.rows,
0,
GL_RED, // <--------------- GL_RED instead of GL_RGBA
GL_UNSIGNED_BYTE,
face->glyph->bitmap.buffer
);
您錯過了通過glUseProgram
將着色器程序對象安裝為當前渲染狀態的glUseProgram
。 必須在程序鏈接([ glLinkProgram
])( https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glLinkProgram.xhtml )之后並且在制服的任何值指定( glUniform*
):
glLinkProgram( ProgramObject );
GLint color_location = glGetUniformLocation(ProgramObject, "color");
....
glUseProgram( ProgramObject );
GLfloat black[4] = {1, 0, 0, 1};
glUniform4fv(color_location, 1, black);
投影矩陣的GLSL數據類型必須為mat4
。 注意,類型vec4
的2個變量的乘法將導致向量的所有分量的vec4
乘法。 請參閱GLSL編程/向量和矩陣運算 。
但是,由於您已在規范化的設備空間中初始化了頂點坐標,因此不需要任何投影:
attribute vec4 vertex;
varying vec2 TexCoords;
void main()
{
gl_Position = vec4(vertex.xy, 0, 1);
TexCoords = vertex.zw;
}
預習:
但是我正在使用gl2庫,並且(gl2.h)沒有定義GL_RED。
由於OpenGL ES 2.0不支持GL_RED
,因此您必須采取解決方法。 GL_ALPHA
ES 2.0支持GL_ALPHA,請參閱glTexImage2D
。
使用GL_ALPHA
格式說明符:
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGBA,
face->glyph->bitmap.width, face->glyph->bitmap.rows, 0,
GL_ALPHA,
GL_UNSIGNED_BYTE,
face->glyph->bitmap.buffer
);
和讀出的alpha通道形成a
部件,查找在片段着色器的紋理時:
float alpha = texture2D(text, TexCoords).a;
gl_FragColor = vec4(1.0, 1.0, 1.0, alpha) * color;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.