You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 13:29:54