从多维数据集中删除内部面的最佳方法是什么?

时间:2019-07-09 05:56:51

标签: c++ opengl visual-c++ opengl-4

我正在尝试使用opengl创建一个类似于Minecraft的游戏,现在我可以绘制聚在一起的多维数据集的“大块”。但是,我似乎找不到一种好的方法来从多维数据集(一个16x16x16多维数据集)内部删除所有看不见的面孔。

我已经为单个多维数据集(所有面坐标彼此分开)创建了基本基础结构,然后复制所有多维数据集信息并使用glm :: translate和drawVertexArrays进行绘制。

例如:用于背面

float cubeMapTest1[] =
{
    // Back face
    -0.5f, -0.5, -0.5f,  0.0f, 0.0f, // Bottom-left
     0.5f, -0.5f, -0.5f,  1.0f, 0.0f, // bottom-right    
     0.5f,  0.5f, -0.5f,  1.0f, 1.0f, // top-right              
     0.5f,  0.5f, -0.5f,  1.0f, 1.0f, // top-right
    -0.5f,  0.5f, -0.5f,  0.0f, 1.0f, // top-left
    -0.5f, -0.5f, -0.5f,  0.0f, 0.0f, // bottom-left  
};

// ...

unsigned int VBOs[6], VAOs[6];
glGenVertexArrays(6, VAOs);
glGenBuffers(6, VBOs);

glBindVertexArray(VAOs[0]);

glBindBuffer(GL_ARRAY_BUFFER, VBOs[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeMapTest1), cubeMapTest1, GL_STATIC_DRAW);

// position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// texture coord attribute
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);

// ...

// ^^^重复全部6张脸^^^

//然后创建一个从0到16 ^ 3的值的多维数据集,以便稍后绘制

std::vector<glm::vec3> cubePositions;
int i = 0;
int chunkSize = 16;
int chunkVolume = chunkSize * chunkSize * chunkSize;

for (size_t j = 0; j < chunkSize; j++)
{
    for (size_t k = 0; k < chunkSize; k++)
    {
        for (size_t h = 0; h < chunkSize; h++)
        {
            i++;
            //order of h j k affect layers
            cubePositions.resize(i + 1);
            cubePositions[i] = { h, j, k };
        }
    }
}

//启动while循环

//绘制

// ...

以此,我是否应该使用法线来确定要“剔除”哪些内表面?根据我的目标,最好的剔除方法是什么?我知道这很乱,我的问题有点含糊,但我不知道从哪里开始这个问题。稍后,我还将通过实例化和索引对其进行优化。

1 个答案:

答案 0 :(得分:1)

算法本身非常简单。对于块中的每个多维数据集,对于立方体的每个面,请检查该方向上的相邻多维数据集(在该块内。不要打扰基于相邻块的剔除)。如果存在该相邻的立方体,则将其剔除。

换句话说,您正在做的是为特定块构建顶点数据数组。对于每个多维数据集,根据该多维数据集的哪些面未被剔除,可以向该数组中添加一些顶点。因此,您检查了6个相邻的多维数据集(同样在同一块内),如果没有多维数据集,则为该面添加顶点。