使用OpenGL VBO绘制数千个多边形

时间:2016-09-11 15:00:28

标签: c++ qt opengl 2d vbo

我正在尝试创建能够渲染超过100000个2d原始对象的OpenGL应用程序。

AFAIK,应该可以使用现代的OpenGL和VBO。

所以这是代码(使用Qt):

#include "paintwidget.h"

PaintWidget::PaintWidget(QGLWidget *parent) : QGLWidget(parent)
{
    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(updateTimer()));
    timer->start(16);
}

GLuint indices[100000];

void PaintWidget::initializeGL()
{
    VBOBuffer= new QGLBuffer(QGLBuffer::VertexBuffer);
    VBOBuffer->create();
    VBOBuffer->bind();
    VBOBuffer->setUsagePattern(QGLBuffer::DynamicDraw);
    VBOBuffer->allocate(100000 * 10 * sizeof(double));

    // load data into VBO:
    for(int i=0; i<100000; i++)
    {

        GLdouble vertices[] = {100 + (double)i * 100, 100 + (double)i * 100,
                               100 + (double)i * 100, 200 + (double)i * 100,
                               200 + (double)i * 100, 200 + (double)i * 100,
                               300 + (double)i * 100, 150 + (double)i * 100,
                               200 + (double)i * 100, 100 + (double)i * 100 };

        VBOBuffer->write(i * 10 * sizeof(double), vertices, 10 * sizeof(double));
    }

    // fill indices array:
    for(int i=0; i<100000; i+=10)
    {
        indices[i] = i;
        indices[i+1] = i+1;
        indices[i+2] = i+1;
        indices[i+3] = i+2;
        indices[i+4] = i+2;
        indices[i+5] = i+3;
        indices[i+6] = i+3;
        indices[i+7] = i+4;
        indices[i+8] = i+4;
        indices[i+9] = i;
    }
}

void PaintWidget::paintEvent(QPaintEvent*)
{
    QPainter paint(this);
    paint.beginNativePainting();

    glEnable(GL_LINE_SMOOTH);
    glEnable(GL_MULTISAMPLE);
    glClearColor(0.1, 0.96, 0.1, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);


    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(2, GL_DOUBLE, 0, 0);

    // draw my polygons:
    for(int i=0; i<100000; i+=5)
    {
        glDrawArrays(GL_POLYGON, i, 5);
    }
    glDisableClientState(GL_VERTEX_ARRAY);

    paint.endNativePainting();
}

void PaintWidget::updateTimer()
{
    paintEvent(nullptr);
}

此代码每16ms简单渲染100000个多边形。

我对代码的优先性并不满意。它加载了很多处理器(尽管使用了VBO)。我可以提高效率,或者这是最好的表现吗?

感谢。

1 个答案:

答案 0 :(得分:4)

那就是你的问题:

// draw my polygons:
for(int i=0; i<100000; i+=5)
{
    glDrawArrays(GL_POLYGON, i, 5);
}

您正在为该单个VBO执行100000次绘制调用。这对你的CPU有什么影响。为了进行比较,最新的Doom平均需要不到1500个绘制调用才能完成整个场景。

您只需拨打一次glDrawArraysglDrawElements即可绘制整个几何图形。顺便说一下:现代OpenGL不再支持GL_POLYGON(唯一受支持的原语是GL_POINTS,GL_LINE *和GL_TRIANGLE *)。

如果你关心的是开始一个新的原语,with glDrawElements you can specify a special index that restarts。或者(并且实际上这是首选方法)只是将其绘制为索引三角形。索引是高效缓存的关键,因此如果您希望获得最佳性能,那就是最佳选择。