Как создать кусок Minecraft в opengl? - PullRequest
3 голосов
/ 12 октября 2019

Я изучаю OpenGL и пытался создать воксельную игру, такую ​​как Minecraft. В начале все было хорошо. Я создал класс CubeRenderer для рендеринга куба с его позицией. На рисунке ниже показано, что я сделал.

https://imgur.com/yqn783x

А потом у меня возникла серьезная проблема, когда я пытался создать большую местность, я столкнулся с замедленной производительностью. Я думал, что скорость была очень медленной, а частота кадров около 15 кадров в секунду. Затем я выяснил, что алгоритм Minecraft chunk и culling face может решить проблему снижения производительности, разделив карту мира на маленькие кусочки, такие как chunk, и просто визуализируя видимые грани куба. Итак, как правильно создать чанк и как применить алгоритм отбраковки граней в чанке?

До сих пор это то, что я пытался прочитать о чанке в Minecraft на https://minecraft.gamepedia.com/Chunk

*. 1010 * Я создал демонстрационный Chunk с помощью этого кода ниже (это не законченный код, потому что я его удалил)

Я создал CubeData, который содержит позицию и тип куба. И я вызываю функцию GenerateTerrain для создания простых данных чанка (16x16x16), как показано ниже (CHUNK_SIZE равно 16)

for (int x = 0; x < CHUNK_SIZE; x++) {  
        for (int y = 0; y < CHUNK_SIZE; y++) {  
            for (int z = 0; z < CHUNK_SIZE; z++) {
                CubeType cubeType = { GRASS_BLOCK }; 
                Location cubeLocation = { x, y, z };
                CubeData cubeData = { cubeLocation, cubeType };
                this->Cubes[x][y][z] = cubeData;
            }
        }
    }

После этого у меня был логический массив, который называется «маска», содержит два значения: 0(не виден) или 1 (виден) и соответствует их данным куба. И тогда я вызываю функцию Render класса Chunk для рендеринга чанка. Этот код ниже похож на то, что я сделал (но это не полный код, потому что я удалил этот код и заменил его новым кодом)

for (int x = 0; x < CHUNK_SIZE; x++) {  
        for (int y = 0; y < CHUNK_SIZE; y++) {  
            for (int z = 0; z < CHUNK_SIZE; z++) {
                for(int side = 0; side < 6;side++){
if(this->mask[x][y][z][side] == true) cubeRenderer.Render(cubeData[x][y][z]);
}
            }
        }
    }

Но в результате я получил, что все по-прежнему медленно (но это лучше, чемпервые fps, от 15fps до 25-30fps, может быть)

Я думаю, это не проблема с GPU, это проблема с процессором, потому что в вызове рендеринга слишком много циклов.

Я продолжал исследования, потому что я думаю, что мой подход был неправильным. Там может быть какой-то правильный способ создания чанка, верно?

Так что я нашел решение, которое помещает каждую видимую вертикалку в один VBO. Поэтому мне просто нужно определенно позвонить и связать VBO один раз.

Итак, этот код ниже показывает, что я пробовал

cout << "Generating Terrain..." << endl;

    for (int side = 0; side < 6; side++) {
        for (int x = 0; x < CHUNK_SIZE; x++) {
            for (int y = 0; y < CHUNK_SIZE; y++) {
                for (int z = 0; z < CHUNK_SIZE; z++) {
                    if (this->isVisibleSide(x, y, z, side) == true) {
                        this->cubeRenderer.AddVerticleToVBO(this->getCubeSide(side), glm::vec3(x, y, z), this->getTexCoord(this->Cubes[x][y][z].cubeType, side));
                    }
                }
            }
        }
    }

    this->cubeRenderer.GenerateVBO();

И вызвать рендер один раз.

void CubeChunk::Update()
{
    this->cubeRenderer.Render(); // with VBO data have already init above
}

И я получил это:

https://imgur.com/YqsrtPP

Я думаю, что мой путь был неправильным.

Так, что я должен сделать, чтобы создать чанк? Любое предложение?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...