C++ 在一个vbo中绘制多个形状

C++ 在一个vbo中绘制多个形状,c++,qt,opengl,C++,Qt,Opengl,我想从一个vbo渲染多个3D立方体。每个立方体有一个统一的颜色。 此时,我创建了一个vbo,其中每个顶点都有颜色信息 一个形状(垂直列表)只能上传一种颜色吗 我还想在同一着色器的glpaurements-方法中混合GL_三角形和GL_线。可能吗 //编辑:我只有OpenGL 2.1。稍后我想在Android上构建这个项目 //编辑2: 我想渲染大量立方体(最多150.000个)。一个立方体有24个垂直的几何和颜色以及34个索引。现在我的想法是创建一些vbo(可能50个),并将多维数据集共享给vb

我想从一个vbo渲染多个3D立方体。每个立方体有一个统一的颜色。 此时,我创建了一个vbo,其中每个顶点都有颜色信息

一个形状(垂直列表)只能上传一种颜色吗

我还想在同一着色器的
glpaurements
-方法中混合
GL_三角形
GL_线
。可能吗

//编辑:我只有OpenGL 2.1。稍后我想在Android上构建这个项目

//编辑2:
我想渲染大量立方体(最多150.000个)。一个立方体有24个垂直的几何和颜色以及34个索引。现在我的想法是创建一些vbo(可能50个),并将多维数据集共享给vbo。我希望这能最大限度地减少开销

关于您的问题:

一个形状只能上传一种颜色吗

是的,您可以使用统一属性而不是顶点属性(ofc,这意味着在更多地方进行更改)。但是,您需要为每个形状设置制服,并为每个不同颜色的形状设置不同的drawcall

是否可以在GLD元素中混合GL_三角形和GL_线

是和否。是的,但是你需要一个新的drawcall(很明显)。不能在同一绘图上调用带有GL_三角形的某些形状和带有GL_线的某些形状

在伪代码中,如下所示:

draw shapes 1,2,10 from the vbo using color red and GL_TRIANGLES
draw shapes 3,4,6 from the vbo using color blue and GL_LINES
draw shapes 7,8,9 from the vb using color blue and GL_TRIANGLES
画很多立方体 是的,如果要绘制一组立方体,可以为每个立方体指定一次颜色

  • 创建包含一个立方体顶点的VBO

    // cube = 36 vertexes with glDrawArrays(GL_TRIANGLES)
    vbo1 = [v1] [v2] [v3] ... [v36]
    
  • 使用视图矩阵和每个立方体的颜色创建另一个VBO,并使用1的属性除数。(您可以使用相同的vbo,但我将使用单独的vbo。)

  • 调用
    glDrawlementsInstanced()
    glDrawArraysInstanced()
    。这将一次又一次地绘制立方体

  • 或者,您可以对每个多维数据集使用
    glUniform()
    ,但这将限制您可以绘制的多维数据集的数量。上面的方法可以让你轻松地画上千张

    混合
    GL\u三角形
    GL\u线

    对于每种类型的原语,您必须调用
    glDraw???()
    一次。如果愿意,您可以在这两次使用相同的着色器。

    对于OpenGL 2.1,我认为没有一种合理的方法可以只为每个立方体指定一次颜色,并且仍然在一次绘制调用中绘制所有内容

    最直接的方法是,不在VBO中使用颜色属性,而是直接在绘图调用之前指定它。假设您使用的是通用顶点属性,您当前将拥有:

    glEnableVertexAttribArray(colorLoc);
    glVertexAttripPointer(colorLoc, ...);
    
    您可以这样做:

    glDisableVertexAttribArray(colorLoc);
    glVertexAttrib3f(colorLoc, r, g, b);
    
    其中
    glDisableVertexAttribArray()
    仅在先前为该位置启用了阵列时才需要

    最大的缺点是在一次绘制调用中只能绘制具有相同颜色的立方体。在极端情况下,即每个立方体有一个抽签调用。当然,如果您有多个具有相同颜色的多维数据集,您仍然可以将这些多维数据集批处理到单个绘图调用中

    您想知道这是否比在VBO中为每个顶点设置颜色更有效?无法概括地说。在这种情况下,您总是会得到相同的答案:两种方法都尝试,然后进行基准测试。我怀疑你是否会觉得它有益。根据我的经验,获取顶点数据成为主要性能瓶颈的情况非常罕见。因此,删除一个属性可能不会给你带来太多好处。另一方面,进行许多小的抽签调用绝对会(通常会)损害性能

    有一个选择,你可以使用的是一种混合。我不一定推荐它,只是为了集思广益。如果使用的颜色数量相当有限,则可以在VBO中使用单个标量属性来编码“颜色索引”。然后在顶点着色器中,可以使用纹理查找将“颜色索引”转换为实际颜色

    真正好的选项超出了OpenGL 2.1@DietrichEpp很好地解释了实例化渲染,这是一种适用于此类情况的优雅解决方案


    不,您可以在同一绘图调用中使用线和三角形。即使是OpenGL 4.x中最灵活的draw调用,如
    glDrawerElementsInDirect()
    ,仍然只使用一种原语类型。

    这听起来不错。非常感谢。我将使用我看到的
    glDrawArraysInstanced()
    glDrawArraysInstanced()是一个opengl 3.2命令。在开发人员的机器上,我只有Opengl 2.1(带有英特尔GMA HD的笔记本电脑,运行Ubuntu)。你是说英特尔高清图形?您运行的是什么版本的Mesa?如果你安装一个更新的版本,你可能会得到OpenGL 3.3。是的,这是一个英特尔高清图形。我用的是英特尔M560。我的研究告诉我这只是支持2.1。在机器上,Mesa10.1.3在Ubuntu 14.04上运行。我认为驱动程序是最新的。好吧,对于OpenGL3.x来说,这可能有点太旧了。任何更新的版本都支持3.x。你认为统一的命令可以代替包含每个顶点颜色的vbo带来更好的性能吗?例如,我想渲染27.000立方,具体取决于。如果每个立方体都有不同的颜色,那么就没有了。如果只有少数颜色(比如6或9),那么使用统一的颜色会更好,因为你会给GPU提供更少的数据,而且它会更方便缓存。您需要自己测试这两种方法之间的性能。感谢您提供此信息。这是最坏的情况,因为每个立方体都有不同的颜色。如果我释放vbo并将多维数据集共享给多个vbo,是否有可能加快进程?
    glDisableVertexAttribArray(colorLoc);
    glVertexAttrib3f(colorLoc, r, g, b);