2015-03-27 4 views
1

У меня случайные сбои в glBufferData, и это происходит только в Windows. Mac OS и Linux не имеют проблем. Это моя функция загрузки, которая загружает все, что я сохранил в памяти, на GPU. vertex является вектор массив с плавающей точкой, который является:Crash on glBufferData

std::vector<float> vertex[MAX_VBO]; 

и код случайно врезается в первой функции glBufferData, я звоню, что случайно, поскольку он может работать иногда, но когда мои данные вершина огромна она почти гарантированно авария.

void VertexBuffer::upload() { 
    glGenBuffers(5, vbo); 

    printf("VBO %d - %d - %d\n", vertex[vboPosition].size(), vertex[vboNormal].size(), indices.size()); 
    if (vertex[vboPosition].size() > 0) { 
     glBindBuffer(GL_ARRAY_BUFFER, vbo[vboPosition]); 
     glBufferData(GL_ARRAY_BUFFER, vertex[vboPosition].size() * sizeof(float)*4, &vertex[vboPosition][0], GL_STATIC_DRAW); 
    } 


    if (vertex[vboNormal].size() > 0) { 
     glBindBuffer(GL_ARRAY_BUFFER, vbo[vboNormal]); 
     glBufferData(GL_ARRAY_BUFFER, vertex[vboNormal].size() * sizeof(float)*3, &vertex[vboNormal][0], GL_STATIC_DRAW); 
    } 


    if (vertex[vboColor].size() > 0) { 
     glBindBuffer(GL_ARRAY_BUFFER, vbo[vboColor]); 
     glBufferData(GL_ARRAY_BUFFER, vertex[vboColor].size() * sizeof(float)*4, &vertex[vboColor][0], GL_STATIC_DRAW); 
    } 


    if (vertex[vboUV].size() > 0) { 
     glBindBuffer(GL_ARRAY_BUFFER, vbo[vboUV]); 
     glBufferData(GL_ARRAY_BUFFER, vertex[vboUV].size() * sizeof(float)*2, &vertex[vboUV][0], GL_STATIC_DRAW); 
    } 


    if (vertex[vboTangent].size() > 0) { 
     glBindBuffer(GL_ARRAY_BUFFER, vbo[vboTangent]); 
     glBufferData(GL_ARRAY_BUFFER, vertex[vboTangent].size() * sizeof(float)*3, &vertex[vboTangent][0], GL_STATIC_DRAW); 
    } 

    glBindBuffer(GL_ARRAY_BUFFER, 0); 

    glGenBuffers(1, &vboind); 
    if (indices.size() > 0) { 
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboind); 
     glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW); 
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 

    } 
    printf("Success \n"); 
} 

Дополнительная информация: Я попытался как освобождение и режим отладки в случае Microsoft компилятор помещает странные вещи между векторами (не непрерывен и т.д.), но это то же самое. Также я использую основной профиль OpenGL 3.3.

ответ

2

Похоже, что размер, который вы переходите на glBufferData(), намного больше, чем фактический размер данных. Например, в этом одном:

std::vector<float> vertex[MAX_VBO]; 
    ... 
    glBufferData(GL_ARRAY_BUFFER, vertex[vboPosition].size() * sizeof(float)*4, 
      &vertex[vboPosition][0], GL_STATIC_DRAW); 

Поскольку vertex[vboPosition] является вектор поплавков, вызывая .size() на возвращает количество поплавков в векторе. Затем вы умножаете это значение на sizeof(float)и на 4, что приводит к его умножению на 16. Но один float составляет всего 4 байта, так что это в 4 раза больше.

Второй аргумент - это объем данных для загрузки в байтах. Таким образом, правильный расчет:

glBufferData(GL_ARRAY_BUFFER, vertex[vboPosition].size() * sizeof(float), 
      &vertex[vboPosition][0], GL_STATIC_DRAW); 

То же самое относится и ко всем остальным glBufferData() вызовов.

+0

К сожалению, это не помогло. Я помещаю * 4, потому что каждая позиция имеет 4 поплавка (x, y, z, w). Я действительно собирался использовать glm :: vec4, но поскольку атрибуты вершин не имеют одинаковых размеров, я просто решил использовать float. – deniz

+0

Прошу прощения, вы правы, я просто забыл исправить это для UV. Спасибо. – deniz