在OpenGLES 2.0 / JAVA中:
我最近从使用顶点数组进行渲染切换为使用顶点和索引缓冲区进行渲染。
虽然在绘制我的对象(一个表)时有效,但仍然收到错误消息。 (仅在模拟器上,而不在真实手机上)
这是我绘制对象的方式:
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:检测到超出边界的顶点属性索引。跳过相应的顶点属性。 buf = 0xbfca10f02020-05-19 17:50:33.253 7995-8054 / com.example.andreas.firstopenglproject E / emuglGLESv2_enc:越界顶点属性信息:clientArray? 1属性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;
// 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;
protected final int NUMBER_VERTICES; // number of vertices
protected final int NUMBER_INDICES; // number of indices
protected FloatBuffer bufferVertices;
protected IntBuffer bufferIndices;
初始化:
float[] vertices = modelData.getVertices(); // all vertex 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;
创建VBO:
private final int[] VBO = new int[2];
...
VBO[0] = 0;
VBO[1] = 0;
GLES20.glGenBuffers(2, 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);
bufferIndices.position(0);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, VBO[1]);
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_ELEMENT_ARRAY_BUFFER, VBO[1]);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, NUMBER_INDICES, GLES20.GL_UNSIGNED_INT, 0);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
...