Войти
ПрограммированиеФорумГрафика

glDrawArrays

#0
12:16, 30 сен. 2017

Subj.

На Windows платформе и Nvidia карточке при вызове этой функции я получаю Access violation внутри драйверов Nvidia. 0_o
На встроенной Intel и Ubuntu - все ок.

Контекст - OpenGL 3.3. Версия дров - 375.95. Карточка - GTX 970

Как я инициализирую буфер:

 static const float verts[] = {
            1,  1,
            -1,  1,
            -1, -1,
            1,  1,
            -1, -1,
            1,  -1,
    };
    const int vertsLength = sizeof(verts) ;/// sizeof(verts[0]);
//    std::cout << "vertsLength = " << vertsLength << std::endl;
    GLuint vertBuffer = 0;
    glGenBuffers(1, &vertBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertBuffer);
    glBufferData(GL_ARRAY_BUFFER, 24, &verts[0], GL_STATIC_DRAW);

    this->vertBuffer = vertBuffer;
Как я делаю вывод геометрии:
    glDisable(GL_DEPTH_TEST);
    glBindBuffer(GL_ARRAY_BUFFER, this->vertBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    glVertexAttribPointer(+drawDepthShader::Attribute::position, 2, GL_FLOAT, GL_FALSE, 0, nullptr);

    glUniform1f(this->drawDepthBuffer->getUnf("uWidth"), width/canv_width);
    glUniform1f(this->drawDepthBuffer->getUnf("uHeight"), height/canv_height);
    glUniform1f(this->drawDepthBuffer->getUnf("uX"), x/canv_width);
    glUniform1f(this->drawDepthBuffer->getUnf("uY"), y/canv_height);
    glUniform1i(this->drawDepthBuffer->getUnf("drawDepth"), (drawDepth) ? 1 : 0);

    glBindTexture(GL_TEXTURE_2D, texture);
    glDrawArrays(GL_TRIANGLES, 0, 6); // <- если закомментировать эту строчку падения не происходит.
    glEnable(GL_DEPTH_TEST);
Где я оказываюсь в итоге в Clion дебагере:
+ Показать

Очевидно, что stack поврежден :(. Предыдущих функций по стеку не видно. Несказанно радует vk_optimusGetInstanceProcAddr, хотя у меня обычный стационарный комп.
Пройдясь по exe файлу в дебагере в IDA, я подтвердил, что access violation происходит внутри nvoglv64.dll и именно при вызове glDrawArrays



#1
12:36, 30 сен. 2017

1) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - эта строчка очень подозрительная, надо закомментировать. У меня была подобная ситуация когда из-за неправильного бинда буфера падала функция glxSwapBuffers в недрах драйвера.
2) ещё способ (вообще рецепт №1, но возможно не сейчас): после каждой строчки с gl-функцией делать вывод glGetError, мне помогало в 95% непонятного поведения
3) на всякий случай: всё ли в порядке с контекстом? Может быть и такое, что нет.

#2
12:44, 30 сен. 2017

Я правильно считаю?
6 вершин * 2 координаты * 4 байта флоата = 6*2*4=48 байт
>>glBufferData(GL_ARRAY_BUFFER, 24, &verts[0], GL_STATIC_DRAW);
А тут почему-то только 24 байта

P.S. glDrawArrays не использует индексный буфер, потому glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) в принципе не нужен, но и не мешает.

#3
12:59, 30 сен. 2017

Все магические числа нахрен.
Вылет вероятно происходит при выходе за предел  буфера, Но разные дрова раскидывают данные по-разному, так что это непредсказуемо.
У меня такое было когда случайно забыл переподключить нужный VBO и рисовалось из левого буфера меньшего размера. Вылетало раз в пол часа, совершенно случайным образом.

#4
13:09, 30 сен. 2017

Спасибо всем отписавшимся

Fantom09
Похоже я таки идиот. Спасибо. Позже проверю.

В этом случае меня обескуражило то, что падение происходило внутри драйвера.
У меня такое было в первый раз :(

#5
18:12, 30 сен. 2017

Нашел причину.
1) Это конечно неправильный размер
2) После переключения шейдеров и VBO оставались активными лишние вертексные атрибуты. Т.е. не было вызывов glDisableVertexAttribArray. А из-за того, что у этого шейдера всего один аттрибут - только на нем все и падало.

Всем спасибо

ПрограммированиеФорумГрафика

Тема в архиве.