2016-09-11 6 views
0

私は100000を超える2次元プリミティブオブジェクトをレンダリングできるOpenGLアプリケーションを作成しようとしています。OpenGL VBOで何千ものポリゴンを描画する

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を使用しているにもかかわらず、プロセッサにかなり多くの負荷がかかります。より効率的にすることができますか?これが最高の性能ですか?

ありがとうございました。

+2

ポリゴンごとに1回の描画呼び出しを使用しています。これは、これが遅く、あなたのGPU負荷をすべて消費するのは不思議ではありません。現代のOpenGLはまったく使用していません。現代のGLには 'GL_POLYGON'がなく、' glEnableClientState'や 'glVertexPointer'もありません。 – derhass

答えて

4

はまあ、あなたの問題があります:

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

あなたはその単一のVBO用100000回の描画呼び出しをやっています。それがあなたのCPUに課税するものです。比較のために、平均での最新のDoomは、シーン全体で1500回未満のドローコールを必要とします。

glDrawArraysまたはglDrawElementsを一度呼び出してジオメトリ全体を描画する必要があります。 BTW:GL_POLYGONは、現代OpenGL(GL_POINTS、GL_LINE *、GL_TRIANGLE *のみサポートされているプリミティブ)でサポートされなくなりました。

新しいプリミティブを開始する場合は、with glDrawElements you can specify a special index that restartsです。または(それは実際には好ましい方法です)、単にインデックス付きの三角形として描画します。効率的なキャッシュを実現するためには、インデックス作成が重要です。

+0

本当に助けていただきありがとうございますが、このVBOのインデックスはどうすればよいですか?私はすでにいくつかの設定を試しましたが、まったく動作しませんでした。 – Soup71

+0

@ Soup71:要素配列バッファ( 'glBindBuffer(GL_ELEMENT_ARRAY_BUFFER、...)')を作成し、それをインデックス配列で埋め、次に 'glDrawElements(...、NULL)'あなたは既にインデックス作成コードを持っており、QGLBufferとその 'write'メソッドをインデックスにも使用できます。頂点配列オブジェクトは頂点*属性のみをカバーするので、要素インデックスバッファは個別にバインドして管理する必要があります。 – datenwolf

+0

もう一度Thak、あなた。 – Soup71

関連する問題