2着色器使用相同的顶点数据

时间:2012-09-04 21:23:41

标签: objective-c ios opengl-es glsl

因此,使用2个不同着色器渲染时出现问题。我目前正在呈现代表骰子的形状,我想要的是如果骰子是由用户选择的,它通过将骰子绘制成完全红色并略微放大来绘制轮廓,然后在其上渲染适当的骰子。目前,由于某些原因,一些骰子会为轮廓渲染错误的骰子,但正确的骰子会产生正确的前景骰子。

我想知道他们是否没有以某种方式混淆他们的顶点数据。我不确定在openGL中是否允许做这样的事情:

glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, numVertices*sizeof(GLfloat), vertices, GL_STATIC_DRAW);

glEnableVertexAttribArray(effect->vertCoord);        
glVertexAttribPointer(effect->vertCoord, 3, GL_FLOAT, GL_FALSE, 0, 0);

glEnableVertexAttribArray(effect->toon_vertCoord);        
glVertexAttribPointer(effect->toon_vertCoord, 3, GL_FLOAT, GL_FALSE, 0, 0);

我试图将顶点数据绑定到2个不同的着色器 当我加载我的第一个着色器时,我有:

vertCoord = glGetAttribLocation(TexAndLighting, "position");

另一个着色器有:

toon_vertCoord = glGetAttribLocation(Toon, "position");

如果我彼此独立地使用着色器它们可以正常工作,但是当我尝试将两个着色器放在另一个上面时,它们会使模型混淆一些。这是我的绘制函数的外观:

- (void) draw {
[EAGLContext setCurrentContext:context];

glBindVertexArrayOES(_vertexArray); 

effect->modelViewMatrix = mvm;
effect->numberColour = GLKVector4Make(numbers[colorSelected].r, numbers[colorSelected].g, numbers[colorSelected].b, 1);
effect->faceColour = GLKVector4Make(faceColors[colorSelected].r, faceColors[colorSelected].g, faceColors[colorSelected].b, 1);

if(selected){
    [effect drawOutline]; //this function prepares the shader
    glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, 0);
}

[effect prepareToDraw]; //same with this one
glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, 0);
}

这就是它的样子,因为你可以看到大多数轮廓都使用了错误的骰子,或者根本没有: picture of dice

指向完整代码的链接:
http://pastebin.com/yDKb3wrD Dice.mm //渲染东西
http://pastebin.com/eBK0pzrK Effects.mm //着色器的东西
http://pastebin.com/5LtDAk8J //我的着色器,不应该与他们有任何关系

TL; DR:尝试使用2个不同的着色器,这些着色器使用相同的顶点数据,但是在同时使用两者进行渲染时,模型会混淆,这就是我认为出错的地方,实际上是非常难倒的。 / p>

1 个答案:

答案 0 :(得分:2)

你是对的,因为这是不允许的(或者说它不符合你的想法):

glEnableVertexAttribArray(effect->vertCoord);        
glVertexAttribPointer(effect->vertCoord, 3, GL_FLOAT, GL_FALSE, 0, 0);

glEnableVertexAttribArray(effect->toon_vertCoord);        
glVertexAttribPointer(effect->toon_vertCoord, 3, GL_FLOAT, GL_FALSE, 0, 0);

属性与着色器没有特定的关联。你不能告诉OpenGL“属性 N 是针对这个着色器的,属性 M 是针对这个其他着色器的。”

属性只是绑定到索引,并且碰巧在该索引处有输入的任何着色器都会污染最后绑定到该特定索引的数据。

因此,如果您有两个着色器,我们称之为“toon”和“normal”,它们具有以下输入(这是假设的):

normal
  input vertCoord (index = 0)
  input texCoord (index = 1)

toon
  input toon_vertCoord (index = 0)
  input toon_somethingElse (index = 1)

然后当你运行这段代码时:

glEnableVertexAttribArray(effect->vertCoord);        
glVertexAttribPointer(effect->vertCoord, 3, GL_FLOAT, GL_FALSE, 0, 0);

glEnableVertexAttribArray(effect->toon_vertCoord);        
glVertexAttribPointer(effect->toon_vertCoord, 3, GL_FLOAT, GL_FALSE, 0, 0);

draw_normal_object();

您的effect->vertCoord不再绑定任何内容,因为toon_vertCoord具有相同的索引,并且您已覆盖输入指针。所以这里你的普通着色器将从toon_vertCoord中采样,一切都将搞砸。

你想要做的是启用/指针“普通着色器”的所有属性,绘制普通对象,然后切换到香椿着色器,启用/指针所有的香椿属性,然后绘制香椿对象。