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

发布于 2024-09-28 23:26:56 字数 1310 浏览 0 评论 0原文

我对这一点有点困惑。

我在书籍、博客、论坛甚至 OpenGL 规范中找到的所有内容都只是谈论非常抽象的技术。没有关于现实世界的例子。

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

理论上看起来很简单。您有一个顶点着色器 (vsh) 和片段着色器 (fsh),然后将两者绑定到一个程序(glGenProgram、glUseProgram,...)。在渲染的每个周期中,该程序将通过每个顶点执行其 VSH,之后将对该 3d 对象的每个“像素”执行 FSH,最后将最终结果发送到缓冲区(显然不讨论每个顶点,光栅化以及管道中的其他步骤)。

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

所有这些都是通过调用绘制函数(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 中使用多个网格(具有不同的纹理和行为)?使用多个程序?如何?

I`m a little confused about this point.

Everything that I found in books, blogs, forums and even in OpenGl specs just talk about a very abstract techniques. Nothing about real world examples.

And I`m going crazy with this: How to put and manage multiple objects (meshes) with OpenGL ES 2.x?

In theory seems simple. You have a Vertex Shader (vsh) and Fragment Shader (fsh), then you bind the both to one Program(glGenProgram, glUseProgram, ...). In the every cycle of render, that Program will perform its VSH by each Vertex and after this will perform FSH on every "pixel" of that 3d object and finally send the final result to the buffer (obviously without talk about the per-vertex, rasterization, and other steps in the pipeline).

OK, seems simple...

All this is fired by a call to the draw function (glDrawArrays or glDrawElements).

OK again.

Now the things comes confused to me.
And If you have several objects to render?

Let's talk about a real world example.
Imagine that you have a landscape with trees, and a character.
The grass of the landscape have one texture, the trees have texture to the trunk and leaves (Texture Atlas) and finally the character has another texture (Texture Atlas) and is animated too.

After imagine this scene, my question is simple:
How you organize this?

You create a separated Program (with one VSH and FSH) for each element on the scene? Like a Program to the grass and soil's relief, a Program to the trees and a Program to the character?

I've tried it, but... when I create multiple Programs and try to use glVertexAttribPointer() the textures and colors of the objects enter in conflicts with each others. Because the location of the attributes, the indexes, of the first Program repeat in the second Program.

Let me explain, I used glGetAttribLocation() in one class that controls the floor of the scene, so the OpenGL core returned to me the index of 0,1 and 2 for the vertexes attributes.
After, in the class of trees I created another Program, anothers shaders, and after used again the glGetAttribLocation() at this time the OpenGL core return with indexes of 0, 1, 2 and 3.

After in the render cycle, I started setting the first Program with glUseProgram() and I've made changes to its vertexes attributes with glVertexAttribPointer() and finally a call to glDrawElements(). After this, call again glUseProgram() to the second Program and use glVertexAttribPointer() again and finally glDrawElements().
But at this point, the things enter in conflicts, because the indexes of vertexes attributes of the second Program affects the vertexes of the first Program too.

I'm tried a lot of thing, searched a lot, asked a lot... I'm exhausted. I can't find what is wrong.

So I started to think that I'm doing everything wrong!

Now I repeat my question again: How to work with multiple meshes (with different textures and behavior) in OpenGL ES 2.x? Using multiple Programs? How?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

此生挚爱伱 2024-10-05 23:26:56

要绘制多个网格,只需多次调用glDrawElements/glDrawArrays即可。如果这些网格需要不同的着色器,只需设置它们即可。一个,并且只有一个着色器程序处于活动状态。

因此,每次更改着色器程序(特别是 VS)时,您都需要重置所有顶点属性和指针。

就这么简单。

To draw multiple meshes, just call glDrawElements/glDrawArrays multiple times. If those meshes require different shaders, just set them. ONE, and only ONE shader program is active.

So each time you change your shader program (Specifically the VS), you need to reset all vertex attributes and pointers.

Just simple as that.

执妄 2024-10-05 23:26:56

感谢您的回答,

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

任何。

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

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

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

看,我之前的情况是:

glCreateProgram();
...
glAttachShader();
glAttachShader();
...
glLinkProgram();
glUseProgram();
...
glGetAttribLocation();
glVertexAttribPointer();
glEnableVertexAttribArray();
...
glDrawElements();

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

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

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

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

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

谢谢

Thanks for answer,

But I think that you just repeat my own words... about the Draw methods, about one Program active, about everything.

Whatever.

The point is that your words give me an insight!
You said: "you need to reset all vertex attributes and pointers".

Well... not exactly reseted, but what I was not updating ALL vertex attributes on render cycle, like texture coordinates. I was updating just that attributes that change. And when I cleared the buffers, I lost the older values.

Now I start to update ALL attributes, independent of change or not their values, everything works!

See, what I had before is:

glCreateProgram();
...
glAttachShader();
glAttachShader();
...
glLinkProgram();
glUseProgram();
...
glGetAttribLocation();
glVertexAttribPointer();
glEnableVertexAttribArray();
...
glDrawElements();

I repeated the process to the second Program, but just call glVertexAttribPointer() a few times.

Now, what I have is a call to glVertexAttribPointer() for ALL attributes.

What drived me crazy is the point that if I removed the First block of code to the first Program, the whole second Program worked fine.
If I removed the Second block of code to the second Program, the first one worked fine.

Now seems so obvious.
Of course, if the VSH is a per-vertex operation, it will work with nulled value if I don't update ALL attributes and uniforms.
I though about OpenGL more like a 3D engine, that work with 3d objects, has a scene where you place your objects, set lights. But not... OpenGL just know about triangles, lines and points, nothing more. I think different now.

Anyway, the point is that now I can move forward!

Thanks

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文