简体   繁体   English

FloatBuffer 绘制纹理四边形,但 ShortBuffer 不绘制

[英]FloatBuffer draws textured quad, but ShortBuffer doesn't

I am trying to draw a textured quad.我正在尝试绘制一个带纹理的四边形。 Since it is a quad I want to use glDrawElements and a VEO, but that requires a ShortBuffer instead of a FloatBuffer .因为它是一个四边形,我想使用glDrawElements和一个 VEO,但这需要一个ShortBuffer而不是一个FloatBuffer I tried changing my code, but now nothing draws.我尝试更改我的代码,但现在没有任何内容。 Old code: Uploading and drawing:旧代码:上传和绘图:

 public void flush() {
    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;
    }
}

Adding texture to buffer:将纹理添加到缓冲区:

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;

Updated code: Uploading and Drawing:更新代码:上传和绘图:

public void flush() {
    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;
    }
}

Adding texture to buffer:将纹理添加到缓冲区:

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

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

    short sx1 = (short) Math.round(x1), sx2 = (short) Math.round(x2), sy1 = (short) Math.round(y1), sy2 = (short) Math.round(y2), ss1 = (short) Math.round(s1), ss2 = (short) Math.round(s2), st1 = (short) Math.round(t1), st2 = (short) Math.round(t2);
    vertices.put(sx1).put(sy1).put(r).put(g).put(b).put(a).put(ss1).put(st1);
    vertices.put(sx1).put(sy2).put(r).put(g).put(b).put(a).put(ss1).put(st2);
    vertices.put(sx2).put(sy2).put(r).put(g).put(b).put(a).put(ss2).put(st2);

    vertices.put(sx1).put(sy1).put(r).put(g).put(b).put(a).put(ss1).put(st1);
    vertices.put(sx2).put(sy2).put(r).put(g).put(b).put(a).put(ss2).put(st2);
    vertices.put(sx2).put(sy1).put(r).put(g).put(b).put(a).put(ss2).put(st1);

    numVertices += 6;

There were no other changes to the code, except replacing FloatBuffer with ShortBuffer in my uploadSubData method.除了在我的uploadSubData方法中用ShortBuffer替换FloatBuffer之外,没有对代码进行其他更改。 The VBO class is just a wrapper for the OpenGL methods, so uploadSubData is glUploadSubData , etc... What am I missing? VBO 类只是 OpenGL 方法的包装器,所以uploadSubDataglUploadSubData等......我错过了什么? Why doesn't glDrawArrays draw the ShortBuffer ?为什么glDrawArrays不绘制ShortBuffer If I left out anything, please tell me, I didn't have much time to write this.如果我遗漏了什么,请告诉我,我没有太多时间写这篇文章。

You are confusing indices and vertex coordinates.您混淆了索引和顶点坐标。 The coordinates are tuples of type GL_FLOAT in an GL_ARRAY_BUFFER .坐标是GL_FLOATGL_ARRAY_BUFFER类型的元组。 But the indices are a list of integral indices (eg type GL_SHORT ) in a GL_ELEMENT_ARRAY_BUFFER which refer to the vertex coordinates.但指数整体指标(如类型的列表GL_SHORT的) GL_ELEMENT_ARRAY_BUFFER其中提到顶点坐标。

A quad can be be drawn by 2 triangles.四边形可以由2个三角形绘制。 You can define 6 vertex coordinates and attributes and use glDrawArrays .您可以定义 6 个顶点坐标和属性并使用glDrawArrays

In the following vertices is of type FloatBuffer :在以下verticesFloatBuffer类型:

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;
vbo.bind(GL_ARRAY_BUFFER);
vbo.uploadSubData(GL_ARRAY_BUFFER, 0, vertices);

glDrawArrays(GL_TRIANGLES, 0, numVertices);

Or you can define 4 vertex coordinates respectively attributes and 6 indices and use glDrawElements .或者您可以分别定义 4 个顶点坐标属性和 6 个索引并使用glDrawElements

In the following vertices still is of type FloatBuffer , but indices is of type ShortBuffer :在以下vertices仍然是FloatBuffer类型,但indicesShortBuffer类型:

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(x2).put(y1).put(r).put(g).put(b).put(a).put(s2).put(t1);

numVertices += 4;
indices.put(0).put(1).put(2);
indices.put(0).put(2).put(3);

numIndices += 4;
vbo.bind(GL_ARRAY_BUFFER);
vbo.uploadSubData(GL_ARRAY_BUFFER, 0, vertices);
ibo.bind(GL_ELEMENT_ARRAY_BUFFER);
ibo.uploadSubData(GL_ELEMENT_ARRAY_BUFFER, 0, indices);

glDrawElements(GL_TRIANGLES, GL_SHORT, numIndices, null);

So the key is that you'll need 2 uploadSubData methods.所以关键是你需要 2 个uploadSubData方法。 The former hast to deal with FloatBuffer and the later has to deal with ShortBuffer .前者必须处理FloatBuffer ,后者必须处理ShortBuffer
Note, in common the vertex attributes are floating point values.请注意,通常顶点属性是浮点值。 Colors are often floating point values in the range [0, 1].颜色通常是 [0, 1] 范围内的浮点值。 Texture coordinates are in range [0, 1].纹理坐标在 [0, 1] 范围内。 Of course it is possible to encode this to an integral data type, but at least for the vertex coordinates this would cause a loss of accuracy.当然,可以将其编码为整数数据类型,但至少对于顶点坐标而言,这会导致精度损失。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM