Android OpenGL ES 2.0图形四元崩溃
我在使用VBOs使用OpenGL ES 2.0在Android中渲染四边形时遇到问题 由于某种原因,当我运行程序时,它会使仿真器崩溃。我正在使用Andy作为模拟器。我曾尝试使用android附带的默认模拟器,但在这种情况下,应用程序根本无法运行。我使用eclipse作为我的ide 我已经设法将问题缩小到Quad类的render方法 我想我想知道我设置VBO和渲染它们的方式是否有问题 这是我的密码: 四元渲染方法:Android OpenGL ES 2.0图形四元崩溃,android,opengl-es,vbo,Android,Opengl Es,Vbo,我在使用VBOs使用OpenGL ES 2.0在Android中渲染四边形时遇到问题 由于某种原因,当我运行程序时,它会使仿真器崩溃。我正在使用Andy作为模拟器。我曾尝试使用android附带的默认模拟器,但在这种情况下,应用程序根本无法运行。我使用eclipse作为我的ide 我已经设法将问题缩小到Quad类的render方法 我想我想知道我设置VBO和渲染它们的方式是否有问题 这是我的密码: 四元渲染方法: @TargetApi(Build.VERSION_CODES.GINGERBREA
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public void render()
{
mat.useMaterial();
GLES20.glFrontFace(GLES20.GL_CW);
//Generate VBO Buffer Handles and assign it to 'buffers'
GLES20.glGenBuffers(4, buffers, 0);
GLES20.glGenBuffers(1, ibo, 0);
//Positions
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[0]);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, vertexBuffer.capacity() * 4, vertexBuffer, GLES20.GL_STATIC_DRAW);
GLES20.glEnableVertexAttribArray(0);
GLES20.glVertexAttribPointer(0, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer);
//GLES10.glVertexPointer(3, GLES10.GL_FLOAT, 0, vertexBuffer);
//Normals
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[1]);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, normalBuffer.capacity() * 4, normalBuffer, GLES20.GL_STATIC_DRAW);
GLES20.glEnableVertexAttribArray(1);
GLES20.glVertexAttribPointer(1, 3, GLES20.GL_FLOAT, false, 0, normalBuffer);
//GLES10.glNormalPointer(GLES10.GL_FLOAT, 0, normalBuffer);
//Texcoords
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[2]);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, texcoordBuffer.capacity() * 4, texcoordBuffer, GLES20.GL_STATIC_DRAW);
GLES20.glEnableVertexAttribArray(2);
GLES20.glVertexAttribPointer(2, 2, GLES20.GL_FLOAT, false, 0, texcoordBuffer);
//GLES10.glTexCoordPointer(2, GLES10.GL_FLOAT, 0, texcoordBuffer);
//Colors
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[3]);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, colorBuffer.capacity() * 4, colorBuffer, GLES20.GL_STATIC_DRAW);
GLES20.glEnableVertexAttribArray(3);
GLES20.glVertexAttribPointer(3, 4, GLES20.GL_FLOAT, false, 0, colorBuffer);
//GLES10.glColorPointer(4, GLES10.GL_FLOAT, 0, colorBuffer);
//Indices
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, ibo[0]);
GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER, indexBuffer.capacity() * 4, indexBuffer, GLES20.GL_STATIC_DRAW);
//Draw
GLES20.glDrawElements(GLES20.GL_TRIANGLES, indexBuffer.capacity(), GLES20.GL_UNSIGNED_INT, indexBuffer);
//GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertices.length / 3);
//Unbind buffers
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
}
这里还有材质类别:
package com.game.shading;
import android.opengl.GLES20;
public class Material
{
private final String vertexShaderCode =
"attribute vec3 vPosition;" +
"attribute vec3 vNormal;" +
"attribute vec2 vTexcoord" +
"" +
"void main()" +
"{" +
" gl_Position = vec4(vPosition, 0);" +
"}";
private final String fragmentShaderCode =
"precision mediump float;" +
"uniform vec4 vColor;" +
"" +
"void main()" +
"{" +
" gl_FragColor = vColor;" +
"}";
private int vertShader;
private int fragShader;
private int shaderProgram;
public Material()
{
vertShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
fragShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
shaderProgram = GLES20.glCreateProgram();
GLES20.glAttachShader(shaderProgram, vertShader);
GLES20.glAttachShader(shaderProgram, fragShader);
GLES20.glLinkProgram(shaderProgram);
}
public void useMaterial()
{
GLES20.glUseProgram(shaderProgram);
}
public void cleanupMaterial()
{
GLES20.glDetachShader(shaderProgram, vertShader);
GLES20.glDetachShader(shaderProgram, fragShader);
GLES20.glDeleteShader(vertShader);
GLES20.glDeleteShader(fragShader);
GLES20.glDeleteProgram(shaderProgram);
}
private int loadShader(int type, String source)
{
int shader = GLES20.glCreateShader(type);
GLES20.glShaderSource(shader, source);
GLES20.glCompileShader(shader);
return shader;
}
}
设置属性的方式有问题。以其中一个为例,同样的事情适用于所有这些,以及索引缓冲区:
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[0]);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, vertexBuffer.capacity() * 4, vertexBuffer, GLES20.GL_STATIC_DRAW);
GLES20.glVertexAttribPointer(0, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer);
在ES 2.0中,GLVertexAttributePointer调用有两种变体。它们在Java绑定中具有不同的签名:
其中一个将缓冲区作为最后一个参数。它用于指定顶点数据应直接从传入的缓冲区内存中提取。这通常称为客户端顶点数组。
另一个取int作为最后一个参数。它用于存储在VBO中的属性值。然后,该参数是相对于VBO起点的偏移量。
您正在使用调用的第一个版本,而实际上您有一个VBO绑定。在这种情况下,您需要使用第二个版本。由于属性数据从VBO的开始处开始,因此偏移值为0:
GLES20.glVertexAttribPointer(0, 3, GLES20.GL_FLOAT, false, 0, 0);
然后纠正其他属性和索引的相同问题
我也没有看到将顶点属性位置与顶点着色器中的属性相关联的代码。要添加的一个选项是在链接程序之前使用glBindAttribLocation调用