我对这一点感到有些困惑。
我在书籍,博客,论坛甚至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中的多个网格(具有不同的纹理和行为)?使用多个程序?怎么样?
答案 0 :(得分:2)
要绘制多个网格,只需多次调用glDrawElements / glDrawArrays。如果这些网格需要不同的着色器,只需设置它们即可。一个,只有一个着色器程序处于活动状态。
因此,每次更改着色器程序(特别是VS)时,都需要重置所有顶点属性和指针。
就这么简单。
答案 1 :(得分:0)
感谢您的回答,
但我认为你只是重复我自己的话......关于Draw方法,关于一个活动的程序,关于一切。
无论。
关键是你的话给了我一个见解! 你说:“你需要重置所有顶点属性和指针”。
嗯......没有完全重置,但是我没有在渲染周期中更新所有顶点属性,比如纹理坐标。我正在更新那些改变的属性。当我清除缓冲区时,我丢失了较旧的值。
现在我开始更新所有属性,无论改变与否,它们的价值都一致,一切正常!
看,我以前拥有的是:
glCreateProgram();
...
glAttachShader();
glAttachShader();
...
glLinkProgram();
glUseProgram();
...
glGetAttribLocation();
glVertexAttribPointer();
glEnableVertexAttribArray();
...
glDrawElements();
我将过程重复到第二个程序,但只需调用glVertexAttribPointer()几次。
现在,我所拥有的是对所有属性调用glVertexAttribPointer()。
让我疯狂的是,如果我将第一段代码删除到第一个程序,整个第二个程序工作正常。 如果我将第二个代码块移到第二个程序中,那么第一个代码就可以了。
现在看起来很明显。 当然,如果VSH是每顶点操作,如果我不更新所有属性和制服,它将使用无效值。 我认为OpenGL更像是一个3D引擎,它可以处理3d对象,它有一个放置对象,设置灯光的场景。但不是...... OpenGL只知道三角形,线条和点,仅此而已。我现在觉得不一样了。
无论如何,重点是现在我可以前进了!
由于