OpenGL ES 2.0多重网格?(只是真实世界的例子)

use*_*230 7 shader opengl-es objective-c

我对这一点感到困惑.

我在书籍,博客,论坛甚至OpenGl规范中发现的一切都只是谈论一种非常抽象的技术.没有关于现实世界的例子.

我对此感到疯狂:如何使用OpenGL ES 2.x放置和管理多个对象(网格)?

理论上似乎很简单.你有一个顶点着色器(vsh)和片段着色器(fsh),然后你将两者绑定到一个程序(glGenProgram,glUseProgram,...).在每个渲染周期中,该程序将通过每个顶点执行其VSH,然后在该3d对象的每个"像素"上执行FSH,最后将最终结果发送到缓冲区(显然没有谈论每个顶点,光栅化和管道中的其他步骤).

好的,看起来很简单......

所有这些都是通过调用draw函数(glDrawArrays或glDrawElements)来解决的.

再好吧.

现在事情让我很困惑.如果你有几个要渲染的对象?

我们来谈谈一个现实世界的例子.想象一下,你有一个树木和一个角色的风景.景观的草有一个纹理,树有纹理到树干和树叶(纹理图集),最后字符有另一个纹理(纹理图集),也是动画.

想象一下这个场景后,我的问题很简单:你如何组织这个?

您是否为场景中的每个元素创建了一个单独的程序(带有一个VSH和FSH)?就像草地和土壤的救济计划一样,树木计划和角色计划?

我已经尝试过了,但是......当我创建多个程序并尝试使用glVertexAttribPointer()时,对象的纹理和颜色会相互冲突.因为第一个程序的属性,索引的位置在第二个程序中重复.

让我解释一下,我在一个控制场景底层的类中使用了glGetAttribLocation(),因此OpenGL核心为我返回了顶点属性的索引0,1和2.之后,在树类中我创建了另一个程序,其他的着色器,并且在此次使用glGetAttribLocation()之后,OpenGL核心返回索引为0,1,2和3.

在渲染周期之后,我开始用glUseProgram()设置第一个程序,并且我用glVertexAttribPointer()更改了它的顶点属性,最后调用了glDrawElements().在此之后,再次调用glUseProgram()到第二个程序并再次使用glVertexAttribPointer(),最后再使用glDrawElements().但是在这一点上,事物进入冲突,因为第二个程序的顶点属性索引也会影响第一个程序的顶点.

我尝试了很多东西,搜索了很多,问了很多......我很累.我找不到有什么不对.

所以我开始认为我做错了!

现在我再次重复我的问题:如何使用OpenGL ES 2.x中的多个网格(具有不同的纹理和行为)?使用多个程序?怎么样?

use*_*230 0

感谢您的回答,

但我认为你只是重复我自己的话......关于绘制方法,关于一个活动程序,关于一切。

任何。

重点是你的话让我有了见识!您说:“您需要重置所有顶点属性和指针”。

嗯...没有完全重置,但我没有更新渲染周期上的所有顶点属性,例如纹理坐标。我只是更新了那些发生变化的属性。当我清除缓冲区时,我丢失了旧值。

现在我开始更新所有属性,无论其值是否发生变化,一切正常!

你看,我之前的情况是:

glCreateProgram();
...
glAttachShader();
glAttachShader();
...
glLinkProgram();
glUseProgram();
...
glGetAttribLocation();
glVertexAttribPointer();
glEnableVertexAttribArray();
...
glDrawElements();
Run Code Online (Sandbox Code Playgroud)

我对第二个程序重复了该过程,但只调用了 glVertexAttribPointer() 几次。

现在,我对所有属性调用 glVertexAttribPointer() 。

让我发疯的是,如果我删除第一个程序的第一段代码,整个第二个程序就可以正常工作。如果我将第二个代码块删除到第二个程序中,第一个代码块就可以正常工作。

现在看来是那么明显。当然,如果 VSH 是按顶点操作,如果我不更新所有属性和制服,它将使用空值。我认为 OpenGL 更像是一个 3D 引擎,它可以处理 3D 对象,有一个场景,您可以在其中放置对象、设置灯光。但不是……OpenGL 只知道三角形、直线和点,仅此而已。我现在认为不同了。

不管怎样,重点是现在我可以继续前进了!

谢谢