我是OpenGL和图形编程的新手,虽然我一直对这个主题很感兴趣,但理论上有一个基础。
我想要做的是创建一个场景,其中一组对象在其中移动。具体来说,他们是一个场上的机器人足球运动员。对象是:
所以对我的GL新手来说,我想将这些对象加载到场景中然后只是移动它们。顶点的属性不会改变,无论是它们的定位还是纹理/法线/等。只是将他们的“父母”对象整体转变。
此外,球员都有相同的身体。我可以通过将模型加载到内存中一次,然后每次使用不同的转换矩阵多次绘制它来进行优化吗?
我目前正在使用OpenTK,这是一个基于OpenGL库的轻量级包装器。
这个问题的有用答案可能是:
请注意,我需要在.NET across multiple platforms中运行任何解决方案。
答案 0 :(得分:5)
使用所谓的顶点数组可能是优化这种场景的最可靠方法。这是一个很好的教程:
http://www.songho.ca/opengl/gl_vertexarray.html
顶点数组或更一般地说,gl数据数组保存顶点位置,法线,颜色等数据。您还可以使用一个数组来保存这些缓冲区的索引,以指示绘制它们的顺序
然后你有一些密切相关的函数来管理这些数组,分配它们,设置数据并绘制它们。您只需使用一个OpenGL命令(如glDrawElements()
这些数组通常驻留在主机内存中。进一步的优化是使用顶点缓冲区对象,这些对象与常规数组具有相同的概念,但驻留在GPU内存上并且速度稍快。以下是对此的反对意见:
http://www.songho.ca/opengl/gl_vbo.html
使用缓冲区而不是旧的glBegin() .. glEnd()
具有与OpenGL ES兼容的优点。在OpenGL ES中,数组和缓冲区是绘制内容的唯一方法。
--- 编辑
使用“模型视图”矩阵移动,旋转它们并在场景中变换它们,并且不需要对网格数据进行任何更改。举例说明:
你有初始化:
void initGL() {
// create set of arrays to draw a player
// set data in them
// create set of arrays for ball
// set data in them
}
void drawScene {
glMatrixMode(GL_MODEL_VIEW);
glLoadIdentity();
// set up view transformation
gluLookAt(...);
drawPlayingField();
glPushMatrix();
glTranslate( player 1 position );
drawPlayer();
glPopMatrix();
glPushMatrix();
glTranslate( player 2 position );
drawPlayer();
glPopMatrix();
glPushMatix();
glTranslate( ball position );
glRotate( ball rotation );
drawBall();
glPopMatrix();
}
答案 1 :(得分:4)
由于你的开始,我建议坚持立即模式渲染并让它首先工作。如果您感觉更舒服,可以改进顶点数组。如果你觉得更舒服,那就是VBOs。最后,如果您获得超级舒适,实例化是您案例中最快的解决方案(没有变形,只有整个对象转换)。
除非你试图实现像Fifa 2009这样的东西,否则最好坚持使用简单的方法,直到你遇到明显的效率问题。不需要过早地让自己头疼。
对于整个对象转换,通常会转换模型视图矩阵。
glPushMatrix();
// do gl transforms here and render your object
glPopMatrix();
对于加载对象,你甚至需要提出一些格式或实现可以加载网格格式的东西(obj是最容易支持的格式之一)。有一些高级库可以简化这一过程,但我建议您使用OpenGL来获得您的体验和控制。
答案 2 :(得分:1)
我希望OpenGL API可以通过IDE支持(intellisense等)轻松导航。几个小时后,显然需要建立一些基本规则。所以我停止了输入和RTFM。
http://www.glprogramming.com/red/
在找到他们的OpenGL基础时,我可以给予发现此问题的任何其他人的最佳建议。长篇大论,但赋权。