如何在OpenGL中的单个绘制调用中绘制多个顶点数组?

时间:2015-09-15 04:13:36

标签: c++ opengl opengl-es

我想模拟一堆球的运动。使用GL_TRIANGLE_FAN将这些球渲染为12个顶点。在我的设计中,每个球对象都维护着一个自己的顶点属性数组。但是,每次调用glDrawElements时,它只会绘制一个Vertex Buffer Object。 1000个球需要1000个抽签。它效率不高。如果我画点而不是三角扇,我可以画如下:

class Ball
{
public:
    GLfloat x, y;
    // ...
}

Ball balls[] = {Ball(100, 100), Ball(80, 120), ...};

void display()
{
    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(2, GL_FLOAT, sizeof(Ball), 0); // stride

    glDrawArrays(GL_POINTS, 0, vertex_num);
    //...
}

使用stride参数,我可以从球阵列'选择'x,y并跳过其他成员。我想知道当每个对象都维护一个顶点属性数组时,我怎么能做同样的事情?或者我应该提取所有顶点属性并将它们组合成一个VBO?但它需要额外的代码来维护它并增加耦合。

1 个答案:

答案 0 :(得分:3)

如果所有对象(完全或大部分)相同,您应该查看" instanced "渲染或绘图(即glDrawArraysInstanced等)

如果您的对象大多不同且大部分是动态的但具有相同的渲染状态(纹理,着色器等),并且您可以使用OpenGL 4+,则应使用" multi-draw indirect"设施(即glMultiDrawArraysIndirect等)请注意,在考虑所有先前的扩展等时,版本要求有点棘手。

如果您的对象不相同但是是静态的,则应将它们组合成一个(或几个)对象并绘制它们。这将需要更多代码,并且会降低灵活性,您必须弄清楚它是否值得获得性能优势。

如果以上都不合适(即您的对象都不同,非常动态,并且您无法使用现代OpenGL),那么您就没有任何简单的方法来提高绘图效率。您可能需要使用ubershaders(实际上,很少有着色器所有),纹理数组(或无绑定纹理)和其他技巧。