objective-c - 2个着色器使用相同的顶点数据

标签 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);

我在这里尝试将顶点数据绑定(bind)到 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 个使用相同顶点数据的不同着色器,但在同时使用两者进行渲染时会混淆模型,这就是我认为出错的地方,实际上非常难过。

最佳答案

你是对的,因为这是不允许的(或者更确切地说,它不会按照你的想法去做):

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 用于其他着色器。”

属性简单地绑定(bind)到索引,任何恰好在该索引处有输入的着色器都会吞噬最后绑定(bind)到该特定索引的数据。

因此,如果您有两个着色器,我们称它们为“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 不再绑定(bind)任何东西,因为 toon_vertCoord 具有相同的索引,并且您已经覆盖了输入指针。所以这里你的普通着色器将从 toon_vertCoord 采样,一切都会变得一团糟。

您要做的是启用/指向“普通着色器”的所有属性,绘制普通对象,然后切换到卡通着色器,启用/指向所有卡通属性,然后绘制卡通对象.

关于objective-c - 2个着色器使用相同的顶点数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12271550/

相关文章:

iOS 自定义键盘扩展自动大写

objective-c - 手机数据不更新

iphone - iPhone 中的 GridView 问题

ios - 使用 UITextView 的子类和自定义屏幕键盘,调用 textField.textShouldChange

iphone - 设置 segue 之后选项卡栏中第一个选项卡的值

ios - UIPageViewController最后一页跳动效果?

oop - 在面向对象的设置中使用OpenGL绘图操作?

ios - 如何在 iOS 上调整 OpenGL ES 渲染缓冲区的大小?

android - OpenGL ES 纹理内存

ios - 动态 UITableViewCell 在 iOS 7 和 iOS 8 中的高度是不可能的