C++ OpenGL не отображаются отдельные части

155
23 декабря 2019, 16:50

Для изучения OpenGL в 3D начал писать игру, за основу взял minecraft как более менее простую с точки зрения графики 3D игру.

Написал отрисовку частями, мир делится на секции 16х16х16 блоков, с отдельными vbo, ebo и vao для каждой. При этом некоторые секции не отображаются - они просто прозрачны. Mesh вроде создаётся правильно, ошибка должно быть где-то после этого, но где именно - понять не могу.

Так как код отрисовки расположен не в одном файле, выложу ссылку на проект: https://yadi.sk/d/EFhT-PnrGDF2Lg

Ссылка на исполняемый файл: https://yadi.sk/d/eiyvoDvMsaCxTw

Скрин:

Основные части кода отрисовки, спрашивайте, если надо показать ещё какой-то код. GameState.cpp:

void GameState::update(float delta) {
    // Update the camera
    // Здесь всё в порядке
    m_cam.input(delta);
    m_cam.update();
    // Update the world
    m_world.update(); // возможно, проблема здесь
    ...
}
void GameState::draw() {
    // Draw the world
    m_texture.bind(GL_TEXTURE0);
    float chunksDrawn = m_world.draw(m_renderer) / 16.f;
    // Render
    m_renderer.update(m_cam, m_controller->getWindow());
}

World.cpp:

int World::draw(RenderMaster &renderer) {
    int r = 0;
    for (auto &it : m_chunksMap) {
        auto &chunk = it.second;
        r += chunk.draw(*m_pCam, renderer);
    }
    return r;
}
void World::update() {
    int player_chunk_x = toChunkPos(m_pCam->pos.x);
    int player_chunk_z = toChunkPos(m_pCam->pos.z);
    // Delete chunks out of render distance
    for (auto &it : m_chunksMap) {
        auto pos = it.second.getPos();
        if (max(abs(pos.x - player_chunk_x), abs(pos.z - player_chunk_z)) > RD + 1) {
            addChunkToDelete(pos);
        }
    }
    if (m_chunksToDelete.size())
        deleteChunks();
    // Loading new chunks
    for (int x = -RD; x <= RD; ++x) {
        for (int z = -RD; z <= RD; ++z) {
            VectorXZ pos{ x + player_chunk_x, z + player_chunk_z };
            if (m_chunksMap.find(pos) == m_chunksMap.end()) {
                addChunkToLoad(pos);
                continue;
            }
        }
    }
    if (m_chunksToLoad.size())
        loadChunks();
}

Chunk.cpp:

int Chunk::draw(Camera &cam, RenderMaster &renderer) {
    int r = 0;
    for (int i = 0; i < 16; ++i) {
        if (!m_sections[i].isMade)
            break;
        ChunkSection &section = m_sections[i];
        if (section.mesh.getFacesCount()) { // это работает правильно, проверял
            if (!cam.getFrustum().boxInFrustum(section.aabb)) // отсечение секций вне обзора камеры, здесь ошибок нет
                continue;
            ++r;
            if (!section.isBuffered) // тут всё верно
                section.buffer();
            renderer.draw(section);
        }
    }
    return r;
}

RenderMaster.cpp:

void RenderMaster::draw(ChunkSection &section) {
    m_chunkRenderer.draw(section.mesh.getModel());
}
void RenderMaster::update(Camera &cam, sf::RenderWindow &window) { // вызывается после всей прочей отрисовки
    m_chunkRenderer.update(cam);
    m_sfmlRenderer.update(window);
}

ChunkRenderer.cpp:

void ChunkRenderer::draw(Model &model) {
    m_renderInfos.push_back(RenderInfo{ model.getVAO(), model.getIndicesCount() });
}
void ChunkRenderer::update(const Camera &cam) {
    glEnable(GL_CULL_FACE);
    m_shader.use();
    m_shader.setVariable4x4f("projView_matrix", cam.getProjectionMatrix() * cam.getViewMatrix());
    for (auto &i : m_renderInfos) {
        glBindVertexArray(i.vao);
        glDrawElements(GL_TRIANGLES, i.indicesCount, GL_UNSIGNED_INT, nullptr);
    }
    m_shader.unuse();
    m_renderInfos.clear();
}
Answer 1

Вопрос решён, переменная с VAO иногда оставалась неинициализированной и затем удалялась. При этом очищался какой-то случайный буфер, что и приводило к ошибке!

READ ALSO
std::bind для функции класса с параметром

std::bind для функции класса с параметром

Есть некоторая стандартная системная функция (в примере Job_test), вызывающая callback функцию с параметромСаму callback функцию я хочу расположить...

152
Получение None в качестве аргумента в boost.python

Получение None в качестве аргумента в boost.python

Пытаюсь экспортировать из С++ в Python перегруженную функцию, которая должна принимать, в том числе, NoneНепонятно какой тип данных следует использовать...

148
Как определить путь к текстуре модели в Arcgis?

Как определить путь к текстуре модели в Arcgis?

Можно менять текстуру у добавленной модели в Arcgis ? У меня добавляется модель на сцену так :

151
Передача id от одной таблицы к другой. Hibernate

Передача id от одной таблицы к другой. Hibernate

У меня есть две таблицы: customers и phoneNumbers У одного customer может быть 1+ phoneNumbers

156