【发布时间】:2015-04-19 18:55:53
【问题描述】:
我对 VBO 和现代 openGL 感到困惑。这篇文章的末尾有一个直接的问题,然后在途中有一堆问题。如果您对此有任何了解,我将不胜感激。如果你回复,请把我当成一个完全白痴,什么都不知道。
所以,我的历史是这样的:
我有一个游戏,它是一个自上而下的 2d 游戏。我使用 immideate 模式来渲染 2d 精灵。我的纹理图集的实际纹理坐标是静态的,并且在单独的类中预定义。四边形坐标在每个实体中定义并随着游戏的进行而更新。当我渲染时,我只是绑定了一个特定的纹理,称为 glBegin(triangles),然后调用每个可见对象的渲染方法。这反过来将四边形坐标和纹理坐标发送到我的 Renderer 类,该类进行了 openGl 调用。然后我刷新了只调用 glEnd() 的纹理。
我为所有不同的图集按顺序执行此操作,以便获得适当的深度。
但时代确实在变。我想转而使用 VBO 和着色器。我过去曾尝试过几次,但都失败了。我在 google 上找不到一些简单的东西来让我完全理解它,以及如何使用它来加快我的游戏速度。
我知道基础知识。无需在每次渲染调用时通过总线将所有信息发送到 gpu,我可以简单地存储初始化阶段所需的所有内容,然后使用着色器计算最终结果。但是……
我对纹理坐标有了一个想法。这些将是静态的,因为它们永远不会改变。将它们存储在 GPU 上是有意义的。但是我怎么知道哪个坐标对应于每个 QUAD/TRIANGLE。我在想,游戏中的每个可渲染对象都可以有某种索引,而不是四个浮点数,它作为属性传递给顶点着色器。顶点着色器使用索引来查找 VBO 中的四个纹理坐标。这是一个可行的解决方案吗?你会如何实现这样的东西?
但至于四边形顶点,我迷路了。这些将不断移动。它们将是可见的,然后消失,等等。这意味着我的 quad VBO 将在每次渲染调用时发生变化,而且我看到的更新 VBO 的代码非常难看。我见过类似的东西:
- 将 4 个四边形坐标存储在一个数组中。
- 创建一个浮动缓冲区,将它们放入其中
- 操作缓冲区。
- 将缓冲区发送到 VBO
对我来说看起来很贵。而且我不明白如何删除某个条目(如果实体移出屏幕等),也不明白如何操纵某个条目(实体移动)。如果每次渲染调用都必须以这种方式更新 VBO,性能提升是多少?看起来对我来说更像是一种损失......
另外,我如何跟踪结果图像的“深度”。我正在做 2d,但“深度”是指渲染的顺序,例如确保 object2 呈现在 object1 之上。也许每个深度都有不同的 VBO?或者我应该为此使用 z 坐标并启用深度内容。后者不会给表演带来冲击吗?
还有二维因素。我非常尊重 3d,但我想使用 2d 并利用它在理论上应该产生更好的性能这一事实。但是,从我收集到的信息来看,情况似乎并非如此。在 opengl 3+ 中,似乎为了让我渲染 2d 的东西,我需要先将其转换为 3d,因为这就是硬件中的过程。对我来说似乎很奇怪,因为屏幕上的最终结果是 2d。有没有办法规避这一点,并为 GPU 节省 2d -> 3d -> 2d 的工作?
换句话说,我怎样才能有效地改变这一点:
class main{
void main(){
while(true){
Renderer.bind();
//call render in all gameObjects
Renderer.flush();
}
}
}
class GameObject{
private float X1, X2, Y1, Y2;
private TexureCoordinate tex;
render(float dt){
//update X1, X2...
Renderer.render(tex.getX1(), tex.getX2()... X1, X2 ...);
}
}
class Renderer{
//called once
void bind(Texture texture){
texture.bind();
glBegin(GL_TRIANGLES)
}
//called "nr of visable objects" times
void render(texX1, texX2, texY1, texY2, quadX1, quadX2, quadY1, quadY2){
glTexCoo2d(texX1, texY1)
....
etc.
....
}
void flush(){
glEnd();
}
}
进入使用现代 openGl 的东西?
【问题讨论】:
标签: java opengl game-engine