Сбой OpenGL на glDrawElements при попытке рендеринга карты высот

0

Я пишу класс для рендеринга карты высоты из 32-битного BMP с использованием современных методов OpenGL. Я работал с немедленным режимом, но хотел попробовать преобразовать его в современный контекст OpenGL. Я использую буфер массива элементов с данными индекса для карты и vbo, который имеет данные вершин, где y-компонент берется с высоты (цвета пикселя) растрового изображения.

Прямо сейчас, я получаю необработанное нарушение исключения/доступа при вызове розыгрыша. Вот мой код:

void HeightMap::initHeightMap(const char* filePath, float size, float height){
SDL_Surface* image = SDL_LoadBMP(filePath);
if (!image)
{
    smodgine::fatalError("Image could not be loaded!");
}

std::vector<float> tmp;
for (int y = 0; y< image->h; y++)
{
    tmp.clear();
    for (int x = 0; x < image->w; x++)
    {
        Uint32 pixel = ((Uint32*)image->pixels)[y * image->pitch/4 + x];
        Uint8 r, g, b;
        SDL_GetRGB(pixel, image->format, &r, &g, &b);

        tmp.push_back((float)r / 255.0f);
    }
    heights.push_back(tmp);
}

for (int z = 0; z < heights.size(); z++)
{
    for (int x = 0; x < heights[0].size(); x++)
    {
        vertices.push_back(x * size);
        vertices.push_back(heights[z][x] * height);
        vertices.push_back(z * size);
    }
}

if (_vbo == 0) {
    glGenBuffers(1, &_vbo);
}

glBindBuffer(GL_ARRAY_BUFFER, _vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

_numRows = heights.size() - 1;
_numColumns = heights[0].size() - 1;

SDL_FreeSurface(image);

createElementBuffer();
}

void HeightMap::renderHeightMap()
{
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _eleBuffer);

glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_SHORT, 0);
}

void HeightMap::createElementBuffer()
{
for (int z = 0; z < _numRows; z++)
{
    for (int x = 0; x < _numColumns; x++)
    {
        //top left
        indices.push_back(z * _numRows + x);
        //bottom left
        indices.push_back((z + 1) * _numRows + x);
        //top right
        indices.push_back(z * _numRows + (x + 1));

        //top right
        indices.push_back(z * _numRows + (x + 1));
        //bottom left
        indices.push_back((z + 1) * _numRows + x);
        //bottom right
        indices.push_back((z + 1) * _numRows + (x + 1));
    }
}

if (_eleBuffer == 0){
    glGenBuffers(1, &_eleBuffer);
}

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _eleBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}

Я использую только современный OpenGL около недели или около того, любая помощь приветствуется: D

Теги:
opengl
sdl
heightmap

2 ответа

3

Вы используете оператор sizeof для экземпляров std::vector, ожидая, что он даст вам размер данных в векторе:

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices.data(), GL_STATIC_DRAW);
...
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices.data(), GL_STATIC_DRAW);

Это не даст ожидаемого результата. sizeof дает вам размер в памяти vector объекта, а не данных, хранящихся в векторе. Эти данные динамически распределяются и не сохраняются в самом экземпляре vector.

Чтобы получить правильный размер, вы можете использовать:

glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(vertices[0]), vertices.data(), GL_STATIC_DRAW);
...
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(indices[0]), indices.data(), GL_STATIC_DRAW);
  • 0
    Спасибо за ответ, это имеет большой смысл. Однако, я изменил это и все еще получаю сбой ...
0

Я понял это, кроме ошибки, с которой мне помог Reto Koradi, в другой части моего кода (во время основной функции) я случайно вызывал glEnableVertexAttribArray (1)

  • 0
    Да, это заставит драйвер пытаться получить доступ к 0x0 - всегда плохо ...

Ещё вопросы

Сообщество Overcoder
Наверх
Меню