STB字体渲染仅在纹理上渲染黑匣子

时间:2019-01-25 00:24:10

标签: java opengl lwjgl

我正在尝试使用STB在Java中从ttf文件渲染字体,但是我在渲染时遇到了问题。我认为问题在于烘焙的字体数据是某种格式,我没有正确使用它,而是查看this 使用LWJGL3进行演示,但使用的是旧版OpenGL。查看代码,我首先看到它被称为

glBindTexture(GL_TEXTURE_2D, texID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, BITMAP_W, BITMAP_H, 0, 
    GL_ALPHA, GL_UNSIGNED_BYTE, bitmap);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glClearColor(43f / 255f, 43f / 255f, 43f / 255f, 0f); // BG color
glColor3f(169f / 255f, 183f / 255f, 198f / 255f); // Text color

glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

所以在我的代码中,我绑定了纹理,而不是这个:

glTexCoord2f(q.s0(), q.t0());
glVertex2f(x0, y0);

glTexCoord2f(q.s1(), q.t0());
glVertex2f(x1, y0);

glTexCoord2f(q.s1(), q.t1());
glVertex2f(x1, y1);

glTexCoord2f(q.s0(), q.t1());
glVertex2f(x0, y1);

我将数据添加到FloatBuffer中,如下所示:

if (vertices.remaining() < 7 * 6) {
    /* We need more space in the buffer, so flush it */
    flush();
}

float r = c.getRed();
float g = c.getGreen();
float b = c.getBlue();
float a = c.getAlpha();

vertices.put(x1).put(y1).put(r).put(g).put(b).put(a).put(s1).put(t1);
vertices.put(x1).put(y2).put(r).put(g).put(b).put(a).put(s1).put(t2);
vertices.put(x2).put(y2).put(r).put(g).put(b).put(a).put(s2).put(t2);

vertices.put(x1).put(y1).put(r).put(g).put(b).put(a).put(s1).put(t1);
vertices.put(x2).put(y2).put(r).put(g).put(b).put(a).put(s2).put(t2);
vertices.put(x2).put(y1).put(r).put(g).put(b).put(a).put(s2).put(t1);

numVertices += 6;

然后将其冲洗:

if (numVertices > 0) {
    vertices.flip();

    if (vao != null) {
        vao.bind();
    } else {
        vbo.bind(GL_ARRAY_BUFFER);
        specifyVertexAttributes();
    }
    program.use();

    /* Upload the new vertex data */
    vbo.bind(GL_ARRAY_BUFFER);
    vbo.uploadSubData(GL_ARRAY_BUFFER, 0, vertices);

    /* Draw batch */
    glDrawArrays(GL_TRIANGLES, 0, numVertices);

    /* Clear vertex data for next batch */
    vertices.clear();
    numVertices = 0;
}

我在这里得到ByteBuffer:

STBTTBakedChar.Buffer cdata = STBTTBakedChar.malloc(96);
ByteBuffer bitmap = BufferUtils.createByteBuffer(BITMAP_W*BITMAP_H);
stbtt_BakeFontBitmap(ttf, font.getSize()*Window.getContentScaleY(), bitmap, 
    BITMAP_W, BITMAP_H, 32, cdata);

每个字形都在此处呈现:

try (MemoryStack stack = stackPush()) {
    IntBuffer pCodePoint = stack.mallocInt(1);

    FloatBuffer x = stack.floats(0.0f);
    FloatBuffer y = stack.floats(0.0f);

    STBTTAlignedQuad q = STBTTAlignedQuad.mallocStack(stack);

    float factorX = 1.0f/Window.getContentScaleX();
    float factorY = 1.0f/Window.getContentScaleY();

    float lineY = 0.0f;

    for (int i = 0, to = text.length(); i < to; ) {
        int cp = pCodePoint.get(0);
        if (cp == '\n') {
            y.put(0, lineY = y.get(0)+(ascent- 
                descent+lineGap)*font.getSize());
            x.put(0, 0.0f);
            i += getCP(text, to, i, pCodePoint);
            continue;
        } else if (cp < 32 || 128 <= cp) {
            i += getCP(text, to, i, pCodePoint);
            continue;
        }

        float cpX = x.get(0);
        stbtt_GetBakedQuad(cdata, BITMAP_W, BITMAP_H, cp-32, x, y, q, 
            true);
        x.put(0, scale(cpX, x.get(0), factorX));
        getCP(text, to, i, pCodePoint);
        x.put(0, x.get(0)+stbtt_GetCodepointKernAdvance(info, cp, 
            pCodePoint.get(0))*font.getSize());
        float
                x0 = scale(cpX, q.x0(), factorX),
                x1 = scale(cpX, q.x1(), factorX),
                y0 = scale(lineY, q.y0(), factorY),
                y1 = scale(lineY, q.y1(), factorY);
        font.genMipmaps();
        drawTextureRegion(x0, y0, x1, y1, q.s0(), q.s1(), q.t0(), 
            q.t1(), font.getC());

        i += getCP(text, to, i, pCodePoint);
    }
}

(getCP仅用于堆叠的字符,出于我的目的,它将始终返回1) 现在,无需渲染字体,我只能看到应该绘制的一种播放器纹理,包括颜色和所有内容。当我渲染字体时。一个大黑盒子覆盖了播放器的区域,并且没有文本呈现。

我尝试用纹理进行贴图,但这没有用。我确保调用glEnableVertexAttribArray()。 那么,为什么黑匣子在那里,为什么文本没有呈现? (我在右上角制作了图片,在左下角制作了文字)

Here is the GitHub with the entire project

仔细检查ByteBuffer我很确定这些值的顺序正确。

添加了glTexImage2D和glTexParameteri,但仍然没有。

浏览问题时,我看到的唯一答案是mipmapping(我尝试过)并调用glEnableVertexAttribArray()。

本来没有做很多,但是经过更多的移动研究之后,我仍然茫然无措。

0 个答案:

没有答案