OpenGL ES中的有效绘图方式 [英] Efficient way of drawing in OpenGL ES

查看:87
本文介绍了OpenGL ES中的有效绘图方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序中,我通过OpenGL ES Api绘制了很多立方体.所有的多维数据集都具有相同的尺寸,只是它们位于空间的不同坐标上.我可以想到两种绘制方法,但是我不确定哪种方法最有效.我不是OpenGL专家,所以我决定在这里询问.

In my application I draw a lot of cubes through OpenGL ES Api. All the cubes are of same dimensions, only they are located at different coordinates in space. I can think of two ways of drawing them, but I am not sure which is the most efficient one. I am no OpenGL expert, so I decided to ask here.

方法1,这是我现在使用的方法:由于所有多维数据集都具有相同的尺寸,因此我只计算一次顶点缓冲区,索引缓冲区,普通缓冲区和颜色缓冲区.在刷新场景期间,我遍历所有多维数据集,对同一组缓冲区执行bufferData(),然后使用drawElements()调用绘制多维数据集的三角形网格.由于每个立方体都位于不同的位置,因此我在绘制之前先转换mvMatrix.每个多维数据集都执行bufferData()和drawElements().在这种方法中,我可能不每次都计算缓冲区而节省了很多内存.但是我要进行很多drawElements()调用.

Method 1, which is what I use now: Since all the cubes are of identical dimensions, I calculate vertex buffer, index buffer, normal buffer and color buffer only once. During a refresh of the scene, I go over all cubes, do bufferData() for same set of buffers and then draw the triangle mesh of the cube using drawElements() call. Since each cube is at different position, I translate the mvMatrix before I draw. bufferData() and drawElements() is executed for each cube. In this method, I probably save a lot of memory, by not calculating the buffers every time. But I am making lot of drawElements() calls.

方法2将是:将所有多维数据集视为分布在整个场景中的一组多边形.计算每个多边形(实际上是多边形内的三角形)的顶点,索引,颜色,法线缓冲区,并在一次调用bufferData()的情况下将其推入图形卡内存.然后通过一次调用drawElements()绘制它们.这种方法的优点是,我只执行一次bindBuffer和drawElements调用.缺点是,我使用大量内存来创建缓冲区.

Method 2 would be: Treat all cubes as set of polygons spread all over the scene. Calculate vertex, index, color, normal buffers for each polygon (actually triangles within the polygons) and push them to graphics card memory in single call to bufferData(). Then draw them with single call to drawElements(). The advantage of this approach is, I do only one bindBuffer and drawElements call. The downside is, I use lot of memory to create the buffers.

我在OpenGL方面的经验非常有限,以至于从性能的角度不知道上述哪种方法更好.

My experience with OpenGL is limited enough, to not know which one of the above methods is better from performance point of view.

我正在WebGL应用程序中使用它,但这是一个通用的OpenGL ES问题.

I am using this in a WebGL app, but it's a generic OpenGL ES question.

推荐答案

我实现了方法2,但以压倒性优势获胜.内存过多的所谓缺点似乎只是我的想象.实际上,垃圾回收器在方法2中仅被调用一次,而在方法1中被调用4-5次.

I implemented method 2 and it wins by a landslide. The supposed downside of high amount of memory seemed to be only my imagination. In fact the garbage collector got invoked in method 2 only once, while it was invoked for 4-5 times in method 1.

您的OpenGL场景可能与我的不同,但是如果您在此处找到性能提示,则此问题的教训是:确定场景中不经常更改的部分.无论它们有多大,都应将它们放入单个缓冲区集(VBO)中,并最少上传到图形内存中.这就是使用VBO的方式.客户端(即您的应用程序)和图形卡之间的内存带宽非常宝贵,您不想无故浪费它.

Your OpenGL scenario might be different from mine, but if you reached here in search of performance tips, the lesson from this question is: Identify the parts in your scene that don't change frequently. No matter how big they are, put them in single buffer set (VBOs) and upload to graphics memory minimum number of times. That's how VBOs are meant to be used. The memory bandwidth between client (i.e. your app) and graphics card is precious and you don't want to consume it often without reason.

阅读第二章的顶点缓冲对象"部分. "OpenGL ES 2.0编程指南"的第6章了解如何使用它们. http://opengles-book.com/

Read the section "Vertex Buffer Objects" in Ch. 6 of "OpenGL ES 2.0 Programming Guide" to understand how they are supposed to be used. http://opengles-book.com/

这篇关于OpenGL ES中的有效绘图方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆