我正在尝试通过导入.obj文件来渲染模型。我成功导入和准备要在FloatBuffers / IntegerBuffers中呈现的数据,但无法设法呈现它。有人能帮助我吗?
这是渲染和初始化VBO的类
private int vertexBufferID;
private int indexBufferID;
private int numberIndices;
public void init() {
try{
InputStream objInputStream = new FileInputStream("./res/obj/Terrain.obj");
Obj obj = ObjReader.read(objInputStream);
obj = ObjUtils.convertToRenderable(obj);
IntBuffer indices = ObjData.getFaceVertexIndices(obj, 3);
FloatBuffer vertices = ObjData.getVertices(obj);
// FloatBuffer texCoords = ObjData.getTexCoords(obj, 2);
// FloatBuffer normals = ObjData.getNormals(obj);
vertexBufferID = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vertexBufferID);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vertices, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GL30.glBindVertexArray(0);
indexBufferID = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indices, GL15.GL_STATIC_DRAW);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
}catch(IOException e)
{
e.printStackTrace();
}
}
public void render() {
GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vertexBufferID);
GL11.glVertexPointer(3, GL11.GL_FLOAT, 0, 0);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
GL11.glDrawElements(GL11.GL_TRIANGLES, numberIndices, GL11.GL_UNSIGNED_INT, 0);
}
我没有得到错误代码,只是没有渲染对象。我可以使用显示列表渲染对象。
答案 0 :(得分:3)
我现在已经解决了问题,现在可以导入.obj-Files并使用vbo / vao渲染它们。我使用"Obj - a simple Wavefront OBJ file loader and writer"来准备要呈现的数据。
加载和准备.obj文件的代码
InputStream objInputStream = new FileInputStream(pathTObjFile);
Obj obj = ObjReader.read(objInputStream);
obj = ObjUtils.convertToRenderable(obj);
IntBuffer indices = ObjData.getFaceVertexIndices(obj, 3);
FloatBuffer vertices = ObjData.getVertices(obj);
现在数据存储在2个VBO中,顶点的VBO存储在VAO中:
vaoId = GL30.glGenVertexArrays();
顶点数组对象ID(vaoID)是一个在调用VAO时调用的Integer。
GL30.glBindVertexArray(vaoId);
为了能够对我们必须绑定的VAO做任何事情,或者选择"它
vboId = GL15.glGenBuffers();
VBO也有一个要调用的ID。我们在这里创建顶点缓冲区对象ID(vboId)
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboId);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vertices, GL15.GL_STATIC_DRAW);
现在我们选择VBO并将顶点存储在其中。
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GL30.glBindVertexArray(0);
首先我们将VBO放在VAO的第一个属性列表中(VAO有16个列表),然后我们取消绑定VAO和VBO。
vboiId = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboiId);
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indices, GL15.GL_STATIC_DRAW);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
indicesCount = indices.capacity();
在初始化结束时,我们为索引创建了vbo,因此Vertices可以相互连接以正确的方式创建面。因此,我们绑定vboiId并将索引数据存储在其中。然后我们再次取消绑定VBO并保存存储在VBO中的Indices数量,因为我们必须告诉它OpenGL能够在以后渲染它。
渲染对象:
GL30.glBindVertexArray(vaoId);
GL20.glEnableVertexAttribArray(0);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboiId);
要渲染对象,我们必须将VAO和VBO绑定在里面。我们还必须为指数选择VBO。这是由上面的代码片段完成的。
GL11.glDrawElements(GL11.GL_TRIANGLES, indicesCount, GL11.GL_UNSIGNED_INT, 0);
现在我们绘制对象和
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
GL20.glDisableVertexAttribArray(0);
GL30.glBindVertexArray(0);
再次取消选择VBO和VAO。
以下是整个代码组合
private int vboiId;
private int vaoId;
private int vboId;
private int indicesCount;
public void init() {
try{
InputStream objInputStream =
new FileInputStream("./res/obj/Terrain.obj");
Obj obj = ObjReader.read(objInputStream);
obj = ObjUtils.convertToRenderable(obj);
IntBuffer indices = ObjData.getFaceVertexIndices(obj, 3);
FloatBuffer vertices = ObjData.getVertices(obj);
FloatBuffer texCoords = ObjData.getTexCoords(obj, 2);
FloatBuffer normals = ObjData.getNormals(obj);
indicesCount = indices.capacity();
vaoId = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vaoId);
vboId = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboId);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vertices, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GL30.glBindVertexArray(0);
vboiId = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboiId);
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indices, GL15.GL_STATIC_DRAW);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
}catch(IOException e)
{
e.printStackTrace();
}
}
public void render() {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
GL30.glBindVertexArray(vaoId);
GL20.glEnableVertexAttribArray(0);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboiId);
GL11.glDrawElements(GL11.GL_TRIANGLES, indicesCount, GL11.GL_UNSIGNED_INT, 0);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
GL20.glDisableVertexAttribArray(0);
GL30.glBindVertexArray(0);
}
有关更多详细信息,我强烈建议您阅读The quad with Draw Array,The Quad with Draw Elements,如果您想更详细地查看Main Page上的OpenGL 3.2及以上教程LWJGL维基百科。 有关如何使用我使用的Obj加载器的信息,请查看The sample projects using this loader
我的代码基本上由这些网站上的代码组成。
编辑:如果您尝试渲染多个对象,则必须在渲染第一个对象之前清除颜色(渲染方法的第一行)