在OpenGL中快速绘制许多相同的对象 [英] Draw many of the same object quickly in OpenGL

查看:154
本文介绍了在OpenGL中快速绘制许多相同的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我在一个游戏,我需要绘制很多相同的对象。相同的形状,相同的大小,相同的颜色,只是不同的位置。

So I'm working on a game and I need to draw a lot of the same object. Same shape, same size, same color, just different locations.

现在我的设置是这样的。

Right now my setup is like this.

我有一些类 Renderer 其中想要在屏幕上绘制的对象可以调用 static void addVertex(float x,float y,float z); ,它将顶点存储到 std :: vector 中。当每个人都完成绘制静态无效draw(); 在 Renderer 被调用,其中一切都被填充到VBO和绘制

I have some class Renderer where object that want to draw on the screen can call static void addVertex(float x, float y, float z); which will store the vertex into an std::vector. When everyone is done drawing static void draw(); in Renderer is called where everything is stuffed into a VBO and drawn onto the screen.

绘制如下:

void Renderer::draw() {
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, _quadID);
    glBufferSubDataARB(GL_QUADS, 0, _vertexBuffer.dataSize(), _vertexBuffer.toArray());

    glColorPointer(4, GL_FLOAT, 0, _colorBuffer.toArray());

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    glVertexPointer(3, GL_FLOAT, 0, _vertexBuffer.toArray());

    glDrawArrays(GL_QUADS, 0, (_vertexBuffer.size() / 3));
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);

    glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);

    _vertexBuffer.clear();
    _colorBuffer.clear();
}

其中 _vertexBuffer _colorBuffer 是类的模板< class T>缓冲区,它或多或少是一个托管 std :: vector< T> 用于我的目的。

Where _vertexBuffer and _colorBuffer are of a class template <class T> Buffer which is more or less a managed std::vector<T> for my purposes.

使用这个设置,我可以得到大约300的东西在屏幕上,然后我开始减速。现在一切都是一个GL_QUAD。请记住我对OpenGL有点陌生,如果上面的是尴尬我很抱歉。

With this setup I can get about 300 things on screen before I start slowing down. Right now everything is a GL_QUAD. Bear in mind I'm a little new to OpenGL, if the above is embarrassing I'm sorry.

如何改善这个多边形? p>

How can I improve this to account for like polygons?

推荐答案

在现代硬件上,

On ~modern hardware, instancing is the way to go.

这个想法是将几何图形发送到GPU一次(一次绘图调用),指定你想要的实例数量( primCount 参数)。

The idea is that you send the geometry to your GPU once (one draw call), specifying how many instances you want to draw (primCount parameter).

然后在顶点着色器中可以使用内在输入变量 gl_InstanceID 以了解正在呈现的实例,然后对其使用适当的变换。此方法意味着您应该在顶点着色器中使用所有实例的转换,例如在统一缓冲区对象中。

Then in the vertex shader you can use the intrinsic input variable gl_InstanceID to learn which instance is being rendered and then use the appropriate transformation for it. This approach implies that you should have the transformations for all your instances available in the vertex shader, for example in an Uniform Buffer Object.

编辑: glVertexAttribDivisor 函数与实例非常有用;它基本上允许有一些每顶点属性以及一些每实例属性。

The glVertexAttribDivisor function is very useful together with instancing; it basically allows to have some per-vertex attributes together with some per-instance attributes.

这篇关于在OpenGL中快速绘制许多相同的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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