2017-03-26 22 views
0

現在、私はPythonバインディングを使用してOpenGLを学習しています。私は効果的に基本的に、私は別の幅、高さの2500枚の長方形のグリッドを描画しています。このPythonとOpenGLのパフォーマンス向上

def draw(): 
    background(35) 
    for x in range(50): 
     for y in range(50): 
      fill(random(), 1.0, 1.0) 
      rect(x, y, random(), random()) 

のような何かをするいくつかのコードを書いた、と色を記入してください。

draw()単一の呼び出しを実行するのに約40ミリを取るようです。

私は、オブジェクトを描画する方法は、私は非近代的なOpenGLのであると信じるものです:

rect(x, y, w, h)は単にglRectf(x, y, x + w, y + h)への呼び出しです。

fill(r, g, b)は、glColor3f(r, g, b)への呼び出しです。

ダブルバッファリングが使用されていないと、最後に、メインループは次のようになります。

while True: 
    draw() 
    glutSwapBuffers() 

draw()とても遅いですなぜ今、私は疑問に思って?問題を修正/診断で

私の試み:

私はオンラインで読むと、最終的には自分自身が問題は私がVBOs/VAOsを使用していなかったという事実に嘘をついたことを信じて、GPUへの呼び出しのすべてがわかりましたGPUに1回のメインドローコールを行うのではなく、すべての矩形でglRectfと呼ぶので無用です。

頂点の配列を構築するのがまだ遅いかどうかはわかりません。だから、多くのコードをリファクタリングする前に、これが実際の問題である可能性が高いかどうか疑問に思っています。つまり、ボトルネックはGPUへの描画呼び出しが多すぎることになり、代わりにVBOを使用して、巨大な頂点の配列を構築し、drawの最後にGPUを呼び出します。

ご協力いただければ幸いです。ありがとう!

答えて

2

まず、あなたが描いているものとは対照的に、2500は多くの描画呼び出しです。

私は、オブジェクトを描画する方法は、私はあなたが正しい非近代的なOpenGLの

であると信じるものです。

glBegin(GL_POLYGON); 
glVertex2(x1, y1); 
glVertex2(x2, y1); 
glVertex2(x2, y2); 
glVertex2(x1, y2); 
glEnd(); 

として即時モードと呼ばれる:glRect(x1, y1, x2, y2)を呼び出す

はやってするのと同じです。

これが実際の問題である可能性が高いのでしょうか。

もう一度、あなたは正しいです。基本的にglBegin()/glEnd(...) 2500回を使用していることを考えてください。それは多くのコマンドだけでなく、2500以上のデータが広がっているドローコール

頂点配列と頂点バッファの唯一の理由は、速度が遅くなります。 glDrawArray()に2500回も等しく電話する場合(毎回バッファーを更新することを考慮して)でしたか?私が代わりに親指の一般的なルールがいくつかのOpenGLとして行うことです描く

の最後に頂点の巨大な配列を構築し、GPUに1つの描画呼び出しを行うためにVBOsを使用する必要があります

可能な限り州の変更はほとんどありません。

あなたが2500個の長方形(または5000個の三角形)について話していることを考慮してください。これは、各フレームを更新する必要があるときに、まず最初に描画するための三角形です。

glBufferData()およびglDrawArrays()は、各フレームよりも2500 glBegin()/glEnd(...)より速いでしょうか?おそらく。しかし、2つのバッファを持つほうが速いかもしれません。その理由は、CPUとGPUが非同期であるためです。だから、あなたが大きな頂点の配列を構築している間に、次の部分を構築している間に、GPUはすでにそれらのいくつかを描画している可能性があります。それは間違いなく速くなるでしょう。

最後に、私は即時モード(glBegin()/glEnd(...))の使用を主張していません。私がしようとしている点は、あなたの問題とは対照的に、1 glDrawArray()が1glDrawArray()よりも遅くなる可能性があるということです。 CPUが次の500個の三角形を更新している間に、GPUはすべてが描画可能になるまで待つのではなく、最初の500個の三角形を描画することができます。

ボトムラインはもちろん、それぞれのソリューションとベンチマークを試みることです。

+0

大丈夫です!私が行うことは、頂点のリストを持ち、 'n '個のエントリでいっぱいになるたびに' glDrawArrays() 'を呼ぶことになります。私はそれがどれくらいうまくいくかを見ていきますありがとう! –

関連する問題