Android OpenGL ES 2.0中的随机纹理抗锯齿/透明度问题

时间:2017-04-21 14:42:21

标签: android android-ndk opengl-es-2.0

我用本机代码编写游戏,所有图形都是用OpenGL ES 2.0完成的。我编写了自己的字体渲染引擎,它使用字体精灵图集将所有文本渲染为使用帧缓冲区的单独新纹理。这样,实际文本只进行一次,后续绘制调用只针对一个纹理。

虽然这就像一个魅力,但结果是一些文本被精美地渲染,而另一些则有曲线(都来自相同的抗锯齿精灵字体)。代码段如下所示。什么可能导致这种行为?我试过使用高精度(可能是错误的?),但它似乎没有效果。然而,当添加或删除字母(甚至相同)并因此使最终产生的纹理不同尺寸时,有时会使其具有粗糙的边缘并且有时变得光滑。 Sprite字体表消除锯齿是使用alpha通道/透明度。

static const char *VERTEX_SHADER =
    "attribute vec4 aPosition;\n"
            "attribute vec2 aTexture;\n"
            "varying vec2 vTexture;\n"
            "uniform mat4 uProjection;\n"
            "void main() {\n"
            "   vTexture = aTexture;\n"
            "   gl_Position = uProjection * aPosition;\n"
            "}";

static const char *FRAGMENT_SHADER =
    "precision mediump float;"
            "uniform sampler2D uTexture;\n"
            "uniform vec3 uColor;\n"
            "varying vec2 vTexture;\n"
            "void main() {\n"
            "   vec4 tex = texture2D(uTexture, vTexture);\n"
            "   if (tex.a != 0.0f)"
            "       gl_FragColor = vec4(uColor, tex.a);\n"
            "   else\n"
            "       gl_FragColor = tex;\n"
            "}\n";

    ...CREATE AND COMPILE SHADERS...THEN:
aPosition = glGetAttribLocation(m_renderShaderProgram, "aPosition");
aTexture = glGetAttribLocation(m_renderShaderProgram, "aTexture");
uProjection = glGetUniformLocation(m_renderShaderProgram, "uProjection");
uTexture = glGetUniformLocation(m_renderShaderProgram, "uTexture");
uColor = glGetUniformLocation(m_renderShaderProgram, "uColor");    GLuint renderTexture;
GLuint renderFrameBuffer;
glGenTextures(1, &renderTexture);
glBindTexture(GL_TEXTURE_2D, renderTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, finalTextWidth, finalTextHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glGenFramebuffers(1, &renderFrameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, renderFrameBuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderTexture, 0);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, finalTextWidth, finalTextHeight);
memset(m_projectionMatrix[0], 0, sizeof(m_projectionMatrix));
m_projectionMatrix[0][0] = 2.0f / (float)finalTextWidth;
m_projectionMatrix[1][1] = 2.0f / (float)finalTextHeight;
m_projectionMatrix[2][2] = -1.0f;
m_projectionMatrix[3][0] = -1.0f;
m_projectionMatrix[3][1] = -1.0f;
m_projectionMatrix[3][2] = 0.0f;
m_projectionMatrix[3][3] = 1.0f;
glUseProgram(m_renderShaderProgram);
glUniformMatrix4fv(uProjection, 1, GL_FALSE, m_projectionMatrix[0]);
glUniform1i(uTexture, 0);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, <...ID TO THE FONT SPRITE SHEET TEXTURE...>);
...DRAW ACTUAL LETTERS AND THEN CLEAN UP...

1 个答案:

答案 0 :(得分:1)

问题是由过滤设置引起的。应用这些解决了问题

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

但是,帧缓冲的使用仍有重要注意事项,请参阅-SOLVED- Maximum texture creation/deletion in Android OpenGL ES 2.0