如何在基于Java和LWJGL的体素游戏中实现面剔除
体素游戏面剔除问题求助
近几周我通过LWJGL教程学习,能生成立方体后停止跟进,打算制作Minecraft类体素游戏。目前可生成多个立方体,但所有6个面都会被渲染,我尝试只渲染未与其他立方体相连的面却未成功。
Mesh类create函数中顶点、索引相关代码
// Creation of the VAO vertexArrayObject = GL30.glGenVertexArrays(); GL30.glBindVertexArray(vertexArrayObject); /* All the buffers we add will be binded to the vertexArrayObject. */ // Creation of the PBO FloatBuffer positionBuffer = MemoryUtil.memAllocFloat(vertices.length * 3); float[] positionData = new float[vertices.length * 3]; /* Stores all the (x,y,z) coordinates in an array so we can send it to the buffer so that GPU can do stuff. */ for(int i = 0; i < vertices.length; i++) { positionData[i * 3] = vertices[i].getPosition().getX(); positionData[i * 3 + 1] = vertices[i].getPosition().getY(); positionData[i * 3 + 2] = vertices[i].getPosition().getZ(); } positionBuffer.put(positionData).flip(); // For some reason OpenGl like the data flipped. positionBufferObject = storeData(positionBuffer, 0, 3); // Code tied to the creation of the IBO IntBuffer indicesBuffer = MemoryUtil.memAllocInt(indices.length); indicesBuffer.put(indices).flip(); indicesBufferObject = GL15.glGenBuffers(); GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesBufferObject); GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL15.GL_STATIC_DRAW); GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0); // Unbinds the buffer.
Renderer类renderMesh函数代码
public void renderMesh(GameObject object, Camera camera) { GL30.glBindVertexArray(object.getMesh().getVAO()); GL30.glEnableVertexAttribArray(0); GL30.glEnableVertexAttribArray(1); GL30.glEnableVertexAttribArray(2); GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER,object.getMesh().getIBO()); // Binds the shader to draw GL13.glActiveTexture(GL13.GL_TEXTURE0); GL13.glBindTexture(GL11.GL_TEXTURE_2D, object.getMesh().getMaterial().getTextureID()); shader.bind(); shader.setUniform("model", Matrix4f.transform(object.getPosition(), object.getRotation(), object.getScale())); shader.setUniform("projection", window.getProjectionMatrix()); shader.setUniform("view", Matrix4f.view(camera.getPosition(), camera.getRotation())); GL11.glDrawElements(GL11.GL_TRIANGLES, object.getMesh().getIndices().length, GL11.GL_UNSIGNED_INT, 0); // unbinds the shader to get ready for the next shader shader.unbind(); GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER,0); GL30.glDisableVertexAttribArray(0); GL30.glDisableVertexAttribArray(1); GL30.glDisableVertexAttribArray(2); GL30.glBindVertexArray(0); }
通用立方体Mesh定义
public Mesh mesh = new Mesh(new Vertex[] { // Vertices //Back face new Vertex(new Vector3f(-0.5f, 0.5f, -0.5f), new Vector2f(0.0f, 0.0f)), new Vertex(new Vector3f(-0.5f, -0.5f, -0.5f), new Vector2f(0.0f, 1.0f)), new Vertex(new Vector3f( 0.5f, -0.5f, -0.5f), new Vector2f(1.0f, 1.0f)), new Vertex(new Vector3f( 0.5f, 0.5f, -0.5f), new Vector2f(1.0f, 0.0f)), //Front face new Vertex(new Vector3f(-0.5f, 0.5f, 0.5f), new Vector2f(0.0f, 0.0f)), new Vertex(new Vector3f(-0.5f, -0.5f, 0.5f), new Vector2f(0.0f, 1.0f)), new Vertex(new Vector3f( 0.5f, -0.5f, 0.5f), new Vector2f(1.0f, 1.0f)), new Vertex(new Vector3f( 0.5f, 0.5f, 0.5f), new Vector2f(1.0f, 0.0f)), //Right face new Vertex(new Vector3f( 0.5f, 0.5f, -0.5f), new Vector2f(0.0f, 0.0f)), new Vertex(new Vector3f( 0.5f, -0.5f, -0.5f), new Vector2f(0.0f, 1.0f)), new Vertex(new Vector3f( 0.5f, -0.5f, 0.5f), new Vector2f(1.0f, 1.0f)), new Vertex(new Vector3f( 0.5f, 0.5f, 0.5f), new Vector2f(1.0f, 0.0f)), //Left face new Vertex(new Vector3f(-0.5f, 0.5f, -0.5f), new Vector2f(0.0f, 0.0f)), new Vertex(new Vector3f(-0.5f, -0.5f, -0.5f), new Vector2f(0.0f, 1.0f)), new Vertex(new Vector3f(-0.5f, -0.5f, 0.5f), new Vector2f(1.0f, 1.0f)), new Vertex(new Vector3f(-0.5f, 0.5f, 0.5f), new Vector2f(1.0f, 0.0f)), //Top face new Vertex(new Vector3f(-0.5f, 0.5f, 0.5f), new Vector2f(0.0f, 0.0f)), new Vertex(new Vector3f(-0.5f, 0.5f, -0.5f), new Vector2f(0.0f, 1.0f)), new Vertex(new Vector3f( 0.5f, 0.5f, -0.5f), new Vector2f(1.0f, 1.0f)), new Vertex(new Vector3f( 0.5f, 0.5f, 0.5f), new Vector2f(1.0f, 0.0f)), //Bottom face new Vertex(new Vector3f(-0.5f, -0.5f, 0.5f), new Vector2f(0.0f, 0.0f)), new Vertex(new Vector3f(-0.5f, -0.5f, -0.5f), new Vector2f(0.0f, 1.0f)), new Vertex(new Vector3f( 0.5f, -0.5f, -0.5f), new Vector2f(1.0f, 1.0f)), new Vertex(new Vector3f( 0.5f, -0.5f, 0.5f), new Vector2f(1.0f, 0.0f)), }, new int[] { // Indices //Back face 0, 1, 3, 3, 1, 2, //Front face 4, 5, 7, 7, 5, 6, //Right face 8, 9, 11, 11, 9, 10, //Left face 12, 13, 15, 15, 13, 14, //Top face 16, 17, 19, 19, 17, 18, //Bottom face 20, 21, 23, 23, 21, 22 }, new Material("/textures/acacia_planks.png")); // The texture (it works fine, ignore it)
我的项目里Main类有一个通用的立方体Mesh对象,GameObject类包含位置、旋转向量以及这个Mesh。最初尝试修改GameObject的顶点或索引列表但无效,发现是因为Mesh的create()仅在初始化时调用,IBO、VAO等并未更新。于是尝试在update方法中重复执行创建代码来更新VAO和IBO,虽实现了部分面不渲染(但不是正确的面),但性能暴跌,从100fps降至不足10fps。这是我首次做此类项目,对相关概念不熟悉,寻求帮助。
已尝试方案:在update方法中重复更新VAO和IBO,性能大幅下降。
内容的提问来源于stack exchange,提问作者Samuel Fournier
相关产品推荐
相关产品推荐

