0

私の OpenGL プログラムには、2 つのシェーダーがあります。1 つはテクスチャを使用してレンダリングし、もう 1 つは単色のみをレンダリングします。シェーダーをコンパイルしてリンクした後、天候に応じてテクスチャ座標頂点属性配列を有効にするか、シェーダーに属性が含まれていないかを確認します。

//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) のみが含まれます。 )。

問題は次のとおりです。GL コンテキストで最初itemにレンダリングされたものがテクスチャを持たない場合、glDrawElementssegfault が発生します。ただし、レンダリングされた最初のアイテムにテクスチャがある場合、それは正常に機能し、テクスチャ付きのアイテムの後の未テクスチャのアイテムは正常に機能します (つまり、新しいコンテキストが作成されるまで)。

このコードのチャンクは、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 を使用しています。

4

2 に答える 2

2

glDisableVertexAttribArray()ドローコールの後に対応する を追加してみてください:

glEnableVertexAttribArray(positionA);
if(hasTexture) glEnableVertexAttribArray(texcoordA);
// draw
glDisableVertexAttribArray(positionA);
if(hasTexture) glDisableVertexAttribArray(texcoordA);
于 2013-01-12T10:29:35.247 に答える
0

問題は、シェーダーをコンパイルした後に頂点属性配列を有効にしたことです。これは、私がそれらを有効にするべきだった場所ではありません。

シェーダーをコンパイルするときに texcoord 属性を有効にしましたが、最初のアイテムがそれを使用しなかったため、glDrawElements が segfault を起こしました。

シェーダーを設定するときに属性を有効にすることでこれを修正しました。

于 2013-01-12T21:32:39.327 に答える