首页 > 解决方案 > 奇怪的类似我的世界的地形生成

问题描述

我正在尝试使用 opengl 实现类似我的世界的游戏。所以我已经到了想用剔除替换愚蠢的网格生成的地步。

没有块间剔除的地形视图:图像

在地形内部查看:图像

它工作得很好,但是当我尝试在块之间剔除这些块时,事情变得很奇怪。

添加块间剔除时的地形视图:图像

这是网格生成的代码:

void Chunk::CreateMesh()
{
    for (int x = 0; x < CHUNK_SIZE; x++)
    {
        for (int y = 0; y < CHUNK_SIZE; y++)
        {
            for (int z = 0; z < CHUNK_SIZE; z++)
            {
                BlockType currentBlock = blocks[x][y][z];
                BlockChunkPosition currentPos(x, y, z);
                if (currentBlock != BlockType::AIR)
                {

                    // Right face
                    if (GetBlock(x + 1, y, z) == BlockType::AIR || GetBlock(x + 1, y, z) == BlockType::LEAVES)
                    {
                        mesh.AddFace(RIGHT_FACE, currentBlock, currentPos);
                    }

                    // Left face
                    if (GetBlock(x - 1, y, z) == BlockType::AIR || GetBlock(x - 1, y, z) == BlockType::LEAVES)
                    {
                        mesh.AddFace(LEFT_FACE, currentBlock, currentPos);
                    }

                    // Top face
                    if (GetBlock(x, y + 1, z) == BlockType::AIR || GetBlock(x, y + 1, z) == BlockType::LEAVES)
                    {
                        mesh.AddFace(TOP_FACE, currentBlock, currentPos);
                    }

                    // Bottom face
                    if (GetBlock(x, y - 1, z) == BlockType::AIR || GetBlock(x, y - 1, z) == BlockType::LEAVES)
                    {
                        mesh.AddFace(BOTTOM_FACE, currentBlock, currentPos);
                    }

                    // Front face
                    if (GetBlock(x, y, z + 1) == BlockType::AIR || GetBlock(x, y, z + 1) == BlockType::LEAVES)
                    {
                        mesh.AddFace(FRONT_FACE, currentBlock, currentPos);
                    }

                    // Back face
                    if (GetBlock(x, y, z - 1) == BlockType::AIR || GetBlock(x, y, z - 1) == BlockType::LEAVES)
                    {
                        mesh.AddFace(BACK_FACE, currentBlock, currentPos);
                    }


                }
            }
        }
    }
}
BlockType Chunk::GetBlock(int x, int y, int z)
{
    try
    {
        return blocks.at(x).at(y).at(z);
    }
    catch (std::out_of_range &)
    {
        BlockWorldPosition pos = ToWorldCoordinates(position, BlockChunkPosition(x, y, z));
        return terrain->GetBlock(pos);
    }
}

BlockType Terrain::GetBlock(BlockWorldPosition pos)
{
    ChunkPosition chunkPos;
    chunkPos = GetChunkPos(pos);

    BlockChunkPosition blockPos;
    blockPos = GetBlockLocalPos(pos);


    ChunkTable::iterator currentChunk;
    if(((currentChunk = chunks.find(chunkPos)) != chunks.end()))
    {
        return currentChunk->second->GetBlock(blockPos.x, blockPos.y, blockPos.z);
    }
    return BlockType::AIR;
}

当我使用调试器时,它在 try-catch 块中工作得很奇怪。那里有什么问题吗?

什么会导致这样的问题?

标签: c++opengl

解决方案


最后我发现了问题。发生此问题是因为我在不需要时将顶点和索引缓冲区绑定了几次。vetrex 数组已经绑定了缓冲区。

void ChunkMesh::GenerateMesh()
{
    ibo.Bind();
    vbo.Bind();
    vao.Bind();
    vbo.GenerateBuffer(sizeof(float) * mesh.size(), &mesh[0]);
    ibo.GenerateBuffer(indices.size(), &indices[0]);
    vao.AddBuffer(vbo, layout);
}

替换为

void ChunkMesh::GenerateMesh()
{
    vao.Bind();
    vbo.GenerateBuffer(sizeof(float) * mesh.size(), &mesh[0]);
    ibo.GenerateBuffer(indices.size(), &indices[0]);
    vao.AddBuffer(vbo, layout);
}

void ChunkMesh::Render()const
{
    ibo.Bind();
    vao.Bind();
    shader.Bind();
    GLCall(glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0));
}

我替换为

void ChunkMesh::Render()const
{
    vao.Bind();
    shader.Bind();
    GLCall(glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0));
}

虽然,我仍然不完全明白为什么会这样。


推荐阅读