OpenGLES 'vertex attribute index out of boundary' 错误,尽管渲染效果很好

OpenGLES 'vertex attribute index out of boundary' error although the rendering works perfectly fine

在 OpenGLES 2.0/JAVA:

我最近从使用顶点数组渲染切换到使用顶点和索引缓冲区渲染。

在绘制我的对象 (a table) 时,我仍然收到错误消息。 (只在模拟器上,不在真机上phone)

这是我绘制对象的方式:

public class IndexedTable {

    private static final int POSITION_COMPONENT_COUNT = 3;
    private static final int TEXTURE_COORDINATES_COMPONENT_COUNT = 2;
    private static final int POSITION_STRIDE = (POSITION_COMPONENT_COUNT) * BYTES_PER_FLOAT;
    private static final int TEXTURE_STRIDE = (TEXTURE_COORDINATES_COMPONENT_COUNT) * BYTES_PER_FLOAT;

    private int textureID;
    private Point position;
    private float width;
    private float height;
    private float[] vertexData;
    private float[] textureData;
    private short[] indexData;
    private final VertexBuffer vertexBuffer;
    private final VertexBuffer textureBuffer;
    private final IndexBuffer indexBuffer;

    public IndexedTable(Point position, float width, float height, int textureID) {
        vertexData = new float[]{
                // Order of COORDINATES: X, Y, Z, S, T

                // Indexed Square = 4 vertices mapped by 6 indices
                -(width/2), 0f, -(height/2),    //index 0
                -(width/2), 0f, (height/2),     //index 1
                (width/2), 0f,  (height/2),     //index 2
                (width/2), 0f,  -(height/2)    //index 3
        };

        textureData = new float[] {
                0f, 0.1f,
                0f, 0.9f,
                1f, 0.9f,
                1f, 0.1f
        };

        indexData = new short[]{
                // First triangle
                0, 1, 3,
                // Second triangle
                3, 1, 2
        };

        this.textureID = textureID;
        this.position = position;
        this.width = width;
        this.height = height;

        vertexBuffer = new VertexBuffer(vertexData);
        textureBuffer = new VertexBuffer(textureData);
        indexBuffer = new IndexBuffer(indexData);
    }

    public void bindData(TextureShaderProgram textureShaderProgram) {
        vertexBuffer.setVertexAttribPointer(0, textureShaderProgram.getPositionAttributeLocation(), POSITION_COMPONENT_COUNT, POSITION_STRIDE);
        textureBuffer.setVertexAttribPointer(0, textureShaderProgram.getTextureCoordinatesAttributeLocation(), TEXTURE_COORDINATES_COMPONENT_COUNT, TEXTURE_STRIDE);
    }

    public void draw(TextureShaderProgram textureShaderProgram, float[] viewProjectionMatrix) {
        textureShaderProgram.useProgram();
        textureShaderProgram.setUniforms(viewProjectionMatrix, MatrixHelper.createTransformationMatrix(new Vector(position.x, position.y, position.z), new Vector(1,1,1)), textureID);
        bindData(textureShaderProgram);

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer.getBufferID());
        glDrawElements(GL_TRIANGLES, indexData.length, GL_UNSIGNED_SHORT, 0);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    }

我是不是做错了什么?

这是我得到的错误(大约每秒 500 次):

2020-05-19 17:50:33.253 7995-8054/com.example.andreas.firstopenglproject E/emuglGLESv2_enc: a vertex attribute index out of boundary is detected. Skipping corresponding vertex attribute. buf=0xbfca10f0 2020-05-19 17:50:33.253 7995-8054/com.example.andreas.firstopenglproject E/emuglGLESv2_enc: Out of bounds vertex attribute info: clientArray? 1 attribute 1 vbo 5 allocedBufferSize 32 bufferDataSpecified? 1 wantedStart 272 wantedEnd 800

我试图在一个 vertexArray 中使用 vertexData 和 textureData 渲染相同的东西,但纹理永远无法正确渲染。 (我在 Khronus-OpenGL 论坛上问过这个问题:https://community.khronos.org/t/weird-texture-behaviour-after-switching-from-vertexarray-to-vertexbuffer-indexbuffer/105776

这对我有用。

变量声明:

protected final byte INT_SIZE = 4; // number of bytes for integer type
private final byte FLOAT_SIZE = 4; // number of bytes for float type

// the number of array elements per vertex (x, y, z)
protected final byte VERTEX_COMPONENT = 3;
// the number of array elements per texture coordinate (u, v)
protected final byte TEXTURE_COMPONENT = 2;
// step for the vertex: the number of bytes per float type multiplied 
// by the number of array elements for the vertex (x, y, z)
protected final byte VERTEX_STRIDE = FLOAT_SIZE * VERTEX_COMPONENT;
// step for texture coordinate: number of bytes per float type multiplied by 
// the number of array elements for texture coordinate (u, v)
protected final byte TEXTURE_STRIDE = FLOAT_SIZE * TEXTURE_COMPONENT;

protected final int NUMBER_VERTICES; // number of vertices
protected final int NUMBERS_TEXTURES; // number of texture coordinates
protected final int NUMBER_INDICES; // number of indices

protected FloatBuffer bufferVertices;
protected FloatBuffer bufferTextureCoordinates;
protected IntBuffer bufferIndices;

初始化:

float[] vertices = modelData.getVertices(); // all vertices of 3D-object
bufferVertices = floatBuffer(vertices);
NUMBER_VERTICES = vertices.length / VERTEX_COMPONENT;

int[] indices = modelData.getIndices(); // all indices of 3D-object
bufferIndices = intBuffer(indices);
NUMBER_INDICES = indices.length;

float[] textureCoordinates = modelData.getTextureCoordinates(); // all UV
bufferTextureCoordinates = floatBuffer(textureCoordinates);
NUMBERS_TEXTURES = textureCoordinates.length / TEXTURE_COMPONENT;

创建 VBO:

private final int[] VBO = new int[3];
...
VBO[0] = 0;
VBO[1] = 0;
VBO[2] = 0;

GLES20.glGenBuffers(3, VBO, 0);
bufferVertices.position(0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, VBO[0]);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, VERTEX_STRIDE * NUMBER_VERTICES,
        bufferVertices, GLES20.GL_STATIC_DRAW);

bufferTextureCoordinates.position(0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, VBO[1]);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, TEXTURE_STRIDE * NUMBERS_TEXTURES,
        bufferTextureCoordinates, GLES20.GL_STATIC_DRAW);

bufferIndices.position(0);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, VBO[2]);
GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER, INT_SIZE * NUMBER_INDICES,
        bufferIndices, GLES20.GL_STATIC_DRAW);

平局:

...
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, VBO[0]);
GLES20.glVertexAttribPointer(positionLink, VERTEX_COMPONENT, GLES20.GL_FLOAT,
        false, VERTEX_STRIDE, 0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
...
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, VBO[1]);
GLES20.glVertexAttribPointer(textureCoordinatesLink, TEXTURE_COMPONENT, GLES20.GL_FLOAT,
        false, TEXTURE_STRIDE, 0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
...
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, VBO[2]);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, NUMBER_INDICES, GLES20.GL_UNSIGNED_INT, 0);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
...