freetype2在android上生成的位图,文字会重复,如何解决
The bitmap generated by freetype2 on android, the text will repeat, how to solve it
我使用 FreeType 2.10.2 在 Android 上呈现文本。现在生成了位图,但是有多个(4)个重复的文本。图片如下:
渲染的文字是"G",其中黑色范围是位图的大小,但是有问题。首先位图中有四个"G",然后文字"G"并没有填满整个位图。我不知道这是为什么,这是代码:
int initTexture() {
if (init) return -1;
FT_Face face;
FT_Library ft;
FT_Init_FreeType(&ft);
FT_New_Face(ft, fontPathNativeString, 0, &face);
FT_Set_Pixel_Sizes(face, 0, 12 * 12);
FT_ULong wChar = textUnicodeString[0];
FT_Load_Char(face, wChar, FT_LOAD_DEFAULT);
FT_GlyphSlot glyph = face->glyph;
FT_Render_Glyph(glyph, FT_RENDER_MODE_NORMAL);
glActiveTexture(GL_TEXTURE0);
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
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
);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
characterTextureID = texture;
GLfloat xpos = 0 + face->glyph->bitmap_left;
GLfloat ypos = 500 + (face->glyph->bitmap.rows - face->glyph->bitmap_top);
GLfloat scale = 5.0f;
GLfloat w = face->glyph->bitmap.width / surfaceWidth * scale;
GLfloat h = face->glyph->bitmap.rows * scale / surfaceHeight;
xpos = (xpos - surfaceWidth) / surfaceWidth;
ypos = (surfaceHeight - ypos) / surfaceHeight;
GLfloat vertices[24] = {
xpos, ypos, 0.0f, 0.0f,
xpos, ypos - h, 0.0f, 1.0f,
xpos + w, ypos - h, 1.0f, 1.0f,
xpos, ypos, 0.0f, 0.0f,
xpos + w, ypos - h, 1.0f, 1.0f,
xpos + w, ypos, 1.0f, 0.0f
};
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6 * 4, vertices, GL_STATIC_DRAW);
FT_Done_Face(face);
FT_Done_FreeType(ft);
init = 1;
return 0;
}
JNIEXPORT void JNICALL
Java_me_excq_androidopengles20demo_chapters11_MyRenderer02_drawFrame(JNIEnv *env, jobject thiz) {
initTexture();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0.3f, 0.5f, 1.0f, 0.0f);
glUseProgram(programID);
glUniform3f(glGetUniformLocation(programID, "ourTextColor"), 0.5, 0.8, 0.2);
GLuint vertexHandle = (GLuint) glGetAttribLocation(programID, "vertex");
glEnableVertexAttribArray(vertexHandle);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(vertexHandle, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, characterTextureID);
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableVertexAttribArray(vertexHandle);
}
我的顶点着色器代码是:
attribute vec4 vertex;
varying vec2 outTexCoord;
void main() {
gl_Position = vec4(vertex.xy, 0.0, 1.0);
outTexCoord = vertex.zw;
}
我是按照this tutorial(LearnOpenGL - Text Rendering)写的,但是不知道为什么会这样,请问如何解决?
谢谢。
如果你仔细看图片,你会发现这 4 个字符是不同的:
看似4个字,实际上是1个字,拆成几段。
问题是由于 FT_Render_Glyph
生成的图像具有 1 个通道而不是 RGBA 图像。因此 glTexImage2D
的格式参数必须是 GL_RED
、GL_LUMINANCE
或 GL_ALPHA
:
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RED,
face->glyph->bitmap.width,
face->glyph->bitmap.rows,
0,
GL_RED,
GL_UNSIGNED_BYTE,
face->glyph->bitmap.buffer
);
我使用 FreeType 2.10.2 在 Android 上呈现文本。现在生成了位图,但是有多个(4)个重复的文本。图片如下:
渲染的文字是"G",其中黑色范围是位图的大小,但是有问题。首先位图中有四个"G",然后文字"G"并没有填满整个位图。我不知道这是为什么,这是代码:
int initTexture() {
if (init) return -1;
FT_Face face;
FT_Library ft;
FT_Init_FreeType(&ft);
FT_New_Face(ft, fontPathNativeString, 0, &face);
FT_Set_Pixel_Sizes(face, 0, 12 * 12);
FT_ULong wChar = textUnicodeString[0];
FT_Load_Char(face, wChar, FT_LOAD_DEFAULT);
FT_GlyphSlot glyph = face->glyph;
FT_Render_Glyph(glyph, FT_RENDER_MODE_NORMAL);
glActiveTexture(GL_TEXTURE0);
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
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
);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
characterTextureID = texture;
GLfloat xpos = 0 + face->glyph->bitmap_left;
GLfloat ypos = 500 + (face->glyph->bitmap.rows - face->glyph->bitmap_top);
GLfloat scale = 5.0f;
GLfloat w = face->glyph->bitmap.width / surfaceWidth * scale;
GLfloat h = face->glyph->bitmap.rows * scale / surfaceHeight;
xpos = (xpos - surfaceWidth) / surfaceWidth;
ypos = (surfaceHeight - ypos) / surfaceHeight;
GLfloat vertices[24] = {
xpos, ypos, 0.0f, 0.0f,
xpos, ypos - h, 0.0f, 1.0f,
xpos + w, ypos - h, 1.0f, 1.0f,
xpos, ypos, 0.0f, 0.0f,
xpos + w, ypos - h, 1.0f, 1.0f,
xpos + w, ypos, 1.0f, 0.0f
};
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6 * 4, vertices, GL_STATIC_DRAW);
FT_Done_Face(face);
FT_Done_FreeType(ft);
init = 1;
return 0;
}
JNIEXPORT void JNICALL
Java_me_excq_androidopengles20demo_chapters11_MyRenderer02_drawFrame(JNIEnv *env, jobject thiz) {
initTexture();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0.3f, 0.5f, 1.0f, 0.0f);
glUseProgram(programID);
glUniform3f(glGetUniformLocation(programID, "ourTextColor"), 0.5, 0.8, 0.2);
GLuint vertexHandle = (GLuint) glGetAttribLocation(programID, "vertex");
glEnableVertexAttribArray(vertexHandle);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(vertexHandle, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, characterTextureID);
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableVertexAttribArray(vertexHandle);
}
我的顶点着色器代码是:
attribute vec4 vertex;
varying vec2 outTexCoord;
void main() {
gl_Position = vec4(vertex.xy, 0.0, 1.0);
outTexCoord = vertex.zw;
}
我是按照this tutorial(LearnOpenGL - Text Rendering)写的,但是不知道为什么会这样,请问如何解决?
谢谢。
如果你仔细看图片,你会发现这 4 个字符是不同的:
看似4个字,实际上是1个字,拆成几段。
问题是由于 FT_Render_Glyph
生成的图像具有 1 个通道而不是 RGBA 图像。因此 glTexImage2D
的格式参数必须是 GL_RED
、GL_LUMINANCE
或 GL_ALPHA
:
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RED,
face->glyph->bitmap.width,
face->glyph->bitmap.rows,
0,
GL_RED,
GL_UNSIGNED_BYTE,
face->glyph->bitmap.buffer
);