C ++ - сбой OpenGL в glDrawElements ()

0

Поэтому в моей программе у меня есть несколько текстур, которые я пытаюсь отобразить. Раньше в моем коде я генерировал VAO для текстур и ibo (или индексного буфера) для каждой текстуры. Но когда я запускаю свой код, он падает на glDrawElements() и в nvoglv32.dll. Я читал, что ошибка драйвера nvidia может быть причиной этого, но я сомневаюсь. Возможно, что-то неправильно, когда я создаю или связываю VAO или ibo, но я понятия не имею, где. Вот раздел кода, где происходит ошибка:

for (int i = 0; i < NUM_TEXTURES; i++){

    glBindVertexArray(VAO_T[i]);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[i]);
    glBindTexture(GL_TEXTURE_2D, texture[i]);

    //error here
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, BUFFER_OFFSET(0));//error right here

}

Это ошибка, которую я получаю при отладке:

Необработанное исключение в 0x0263FE4A в Comp465.exe: 0xC0000005: место для чтения нарушения доступа 0x00000000.

Вот мой код, где я создаю VAO, ibo и текстуры:

glGenVertexArrays(NUM_TEXTURES, VAO_T);
glGenBuffers(NUM_TEXTURES, VBO_T);
glGenBuffers(NUM_TEXTURES, ibo);
glGenTextures(NUM_TEXTURES, texture);

...

for (int i = 0; i < NUM_TEXTURES; i++){

    //Tel GL which VAO we are using
    glBindVertexArray(VAO_T[i]);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[i]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices[i]), indices[i], GL_STATIC_DRAW);

    //initialize a buffer object
    glEnableVertexAttribArray(VBO_T[i]);
    glBindBuffer(GL_ARRAY_BUFFER, VBO_T[i]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(point[i]) + sizeof(texCoords), NULL, GL_STATIC_DRAW);
    glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(point[i]), point[i]);
    glBufferSubData(GL_ARRAY_BUFFER, sizeof(point[i]), sizeof(texCoords), texCoords);

    GLuint vPosition = glGetAttribLocation(textureShader, "vPosition");
    glVertexAttribPointer(vPosition, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
    glEnableVertexAttribArray(vPosition);

    GLuint vTexCoord = glGetAttribLocation(textureShader, "vTexCoord");
    glVertexAttribPointer(vTexCoord, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(point[i])));
    glEnableVertexAttribArray(vTexCoord);

    //Get handles for the uniform structures in the texture shader program
    VP = glGetUniformLocation(textureShader, "ViewProjection");

    //Bind the texture that we want to use
    glBindTexture(GL_TEXTURE_2D, texture[i]);

    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    // set texture parameters
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

    //Load texture
    texture[i] = loadRawTexture(texture[i], TEX_FILE_NAME[i], PixelSizes[i][0], PixelSizes[i][1]);
    if (texture[i] != 0) {
        printf("texture loaded \n");
    }
    else
        printf("Error loading texture \n");
}
  • 0
    Используйте glGetError чтобы проверить, не glGetError ли какой-либо вызов.
  • 0
    Я полагаю, макрос BUFFER_OFFSET просто BUFFER_OFFSET void* ?
Показать ещё 1 комментарий
Теги:
opengl
visual-c++

1 ответ

3
Лучший ответ

Это утверждение, безусловно, выглядит неправильно:

glEnableVertexAttribArray(VBO_T[i]);

glEnableVertexAttribArray() принимает местоположение атрибута как свой аргумент, а не идентификатор буфера. Вы действительно используете его правильно позже:

GLuint vPosition = glGetAttribLocation(textureShader, "vPosition");
...
glEnableVertexAttribArray(vPosition);

GLuint vTexCoord = glGetAttribLocation(textureShader, "vTexCoord");
...
glEnableVertexAttribArray(vTexCoord);

Таким образом, вы должны иметь возможность просто удалить этот дополнительный вызов с недопустимым аргументом.

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

  • Следующий вызов бессмысленен, если вы используете программируемый конвейер, который основан на том, что показано в остальной части кода. Его можно удалить.

    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    
  • Вероятно, это просто проблема с именами, но textureShader должен быть программным объектом, то есть возвращаемым значением glCreateProgram(), а не шейдерным объектом.

  • Несмотря на неубедительность, не видя декларации, у меня плохое отношение к этому, и еще несколько подобных звонков:

    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices[i]), indices[i], GL_STATIC_DRAW);
    

    Если indices[i] - это массив, то декларация выглядит примерно так:

    indices[NUM_TEXTURES][INDEX_COUNT];
    

    то это нормально. Но если indices[i] являются указателями или вырождены до указателя, когда он передан как аргумент функции, sizeof(indices[i]) будет размером указателя. Вы можете дважды проверить, что он дает фактический размер массива индексов. То же самое для других подобных случаев.

  • 0
    Огромное спасибо!! Комментирование glEnableVertexAttribArray (VBO_T [i]); заставил это работать !!

Ещё вопросы

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