glDrawElements падает, когда не используются определенные атрибуты вершин

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

//This code is called after the shaders are compiled.

//Get the handles
textureU = glGetUniformLocation(program,"texture");
tintU = glGetUniformLocation(program,"tint");
viewMatrixU = glGetUniformLocation(program,"viewMatrix");
transformMatrixU = glGetUniformLocation(program,"transformMatrix");
positionA = glGetAttribLocation(program,"position");
texcoordA = glGetAttribLocation(program,"texcoord");

//Detect if this shader can handle textures
if(texcoordA < 0 || textureU < 0) hasTexture = false;
else hasTexture = true;

//Enable Attributes
glEnableVertexAttribArray(positionA);
if(hasTexture) glEnableVertexAttribArray(texcoordA);

Если я оказываю item это текстурированный, каждый элемент в verts состоит из 5 значений (x, y, z, tx, ty), но если элемент не является текстурой, каждый элемент verts содержит только 3 значения (x, y, z).

Вот проблема: когда первый item отображается в контексте GL не имеет текстуры, glDrawElements ошибку сегментации! Однако, если первый визуализированный элемент имеет текстуру, он работает нормально, и любые нетекстурированные элементы после текстурированного работают нормально (то есть до тех пор, пока не будет создан новый контекст).

Этот кусок кода делает item

glBindBuffer(GL_ARRAY_BUFFER,engine->vertBuffer);
glBufferData(GL_ARRAY_BUFFER,sizeof(GLfloat)*item->verts.size(),&item->verts[0],GL_DYNAMIC_DRAW);

item->shader->SetShader();

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,engine->elementBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(GLuint) * item->indicies.size(),&item->indicies[0],GL_DYNAMIC_DRAW);

if(item->usingTexture)
item->shader->SetTexture(item->texture->handle);

glUniformMatrix4fv(item->shader->transformMatrixU,1,GL_TRUE,&item->matrix.contents[0]);
glUniformMatrix4fv(item->shader->viewMatrixU,1,GL_TRUE,&item->batch->matrix.contents[0]);
glUniform4f(item->shader->tintU,item->color.x,item->color.y,item->color.z,item->color.w);

glDrawElements(GL_TRIANGLES,item->indicies.size(),GL_UNSIGNED_INT,0); //segfault

Вот функция, показанная выше, которая устанавливает шейдер.

glUseProgram(program); currentShader = program;
GLsizei stride = 12;
if(hasTexture) stride = 20;
glVertexAttribPointer(positionA,3,GL_FLOAT,GL_FALSE,stride,0);
if(hasTexture)
glVertexAttribPointer(texcoordA,2,GL_FLOAT,GL_FALSE,stride,(void*)12);

Насколько я знаю, эта проблема не проявляется в Intel Integrated Graphics, которая выглядит довольно снисходительно.

Редактировать: Если это полезно знать, я использую GLFW и GLEW.

0

Решение

Попробуйте добавить соответствующий glDisableVertexAttribArray()s после вашего розыгрыша:

glEnableVertexAttribArray(positionA);
if(hasTexture) glEnableVertexAttribArray(texcoordA);
// draw
glDisableVertexAttribArray(positionA);
if(hasTexture) glDisableVertexAttribArray(texcoordA);
2

Другие решения

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

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

Я исправил это, включив атрибут при настройке шейдера.

0

По вопросам рекламы [email protected]