Каков наилучший способ удаления внутренних граней из массива кубов? - PullRequest
1 голос
/ 09 июля 2019

Я пытаюсь создать аналог Minecraft с помощью opengl и дошел до того, что могу нарисовать «кусок» кубов, сгруппированных вместе. Тем не менее, я не могу найти хороший метод для удаления всех невидимых граней из группы кубов (куб 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 };
        }
    }
}

// запуск во время цикла

// рисует

// ...

При этом я должен использовать нормали, чтобы определить, какие внутренние грани "отбраковывать"? Какой метод отбраковки лучший, учитывая мою цель? Я знаю, что это грязно, и мой вопрос довольно неопределенный, но я не знаю, с чего начать с этой проблемой. Я оптимизирую его позже с помощью инстансинга и индексов.

1 Ответ

1 голос
/ 09 июля 2019

Сам алгоритм довольно прост.Для каждого куба в чанке, для каждой грани куба, проверьте соседний куб в этом направлении (в пределах чанка. Не беспокойтесь о отбраковке, основанной на соседних чанках).Если этот соседний куб существует, то отберите грань.

Чтобы выразить это иначе, вы создаете массив данных вершин для определенного фрагмента.Для каждого куба вы добавляете некоторое количество вершин в этот массив, основываясь на том, какие грани этого куба не отбракованы.Таким образом, вы проверяете 6 смежных кубов (опять же, внутри одного куска) и добавляете вершины для этой грани, если там нет куба.

...