目前我正在开发适用于Android的3D游戏引擎。该项目刚刚开始,但有一个问题我无法解决。 我想使用VertexBufferObjects来渲染从.obj文件加载的模型。 这是代码
public class Mesh {
private final int mBytesPerFloat = 4;
private FloatBuffer vertices;
private FloatBuffer normals;
private IntBuffer faces;
private int vertexBuffer;
private int normalBuffer;
private int indexBuffer;
public Mesh(float[] vertices, float[] normals, int[] faces, int shaderProgram) {
this.normals = ByteBuffer.allocateDirect(normals.length * mBytesPerFloat)
.order(ByteOrder.nativeOrder())
.asFloatBuffer();
this.normals.put(normals).position(0);
this.faces = ByteBuffer.allocateDirect(faces.length * mBytesPerFloat)
.order(ByteOrder.nativeOrder())
.asIntBuffer();
this.faces.put(faces).position(0);
this.vertices = ByteBuffer.allocateDirect(vertices.length * mBytesPerFloat)
.order(ByteOrder.nativeOrder())
.asFloatBuffer();
this.vertices.put(vertices).position(0);
ByteBuffer bb = ByteBuffer.allocateDirect(8);
bb.order(ByteOrder.nativeOrder());
IntBuffer buffer = bb.asIntBuffer();
GLES20.glGenBuffers(1, buffer);
vertexBuffer = buffer.get(0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vertexBuffer);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, this.vertices.capacity() * mBytesPerFloat, this.vertices, GLES20.GL_STATIC_DRAW);
bb = ByteBuffer.allocateDirect(8);
bb.order(ByteOrder.nativeOrder());
buffer = bb.asIntBuffer();
GLES20.glGenBuffers(1, buffer);
normalBuffer = buffer.get(0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, normalBuffer);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, this.normals.capacity() * mBytesPerFloat, this.normals, GLES20.GL_STATIC_DRAW);
bb = ByteBuffer.allocateDirect(8);
bb.order(ByteOrder.nativeOrder());
buffer = bb.asIntBuffer();
GLES20.glGenBuffers(1, buffer);
indexBuffer = buffer.get(0);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER, this.faces.capacity() * mBytesPerFloat, this.faces, GLES20.GL_STATIC_DRAW);
}
public Mesh() {
// TODO Auto-generated constructor stub
}
public void render(int shaderProgram) {
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vertexBuffer);
GLES20.glVertexAttribPointer(GLES20.glGetAttribLocation(shaderProgram, "vertex"), 3, GLES20.GL_FLOAT, false, 0, 0);
GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(shaderProgram, "vertex"));
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, normalBuffer);
GLES20.glVertexAttribPointer(GLES20.glGetAttribLocation(shaderProgram, "normal"), 3, GLES20.GL_FLOAT, false, 0, 0);
GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(shaderProgram, "normal"));
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, vertices.capacity()/3, GLES20.GL_INT, faces);
}
}
问题是我什么都没看到。 问题不在于我使用的着色器(我知道它正常工作)并且模型视图矩阵和投影矩阵是正确的,因此对象应该是可见的,如果它被渲染它不是。 有谁知道问题可能是什么?
答案 0 :(得分:1)
glDrawElements
似乎不接受GL_INT
作为数据类型,因此glDrawElements
调用可能会失败(可能很容易通过一些简单的glGetError
进行检查为了调试而调用)。只需尝试GL_UNSIGNED_INT
代替(UIntBuffer
代替faces
或类似内容(如果存在)。
也许它在ES中甚至没有GL_UNSIGNED_INT
,你需要2字节GL_UNSIGNED_SHORT
,但我不确定。但你肯定需要一个无符号类型(签名类型对索引有什么意义呢?但是好吧,那就是 Java )。无论如何,一些glGetError
可能会在这里创造奇迹。