Поэтому в моей программе у меня есть несколько текстур, которые я пытаюсь отобразить. Раньше в моем коде я генерировал 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");
}
Это утверждение, безусловно, выглядит неправильно:
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])
будет размером указателя. Вы можете дважды проверить, что он дает фактический размер массива индексов. То же самое для других подобных случаев.
glGetError
чтобы проверить, неglGetError
ли какой-либо вызов.BUFFER_OFFSET
простоBUFFER_OFFSET
void*
?