2017-03-26 28 views
0

我目前使用Python綁定學習OpenGL。我寫了一些代碼,有效地做這樣的事情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()) 

從本質上講,我繪製的矩形2500具有不同的寬度,高度一格,並填充顏色。

看來,它需要大約40 MS執行一次調用draw()

我畫的對象的方式是什麼,我認爲是不現代的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()這麼慢?

我在診斷/修復問題的嘗試:

我在網上,最終閱讀發現自己相信這個問題的事實撒謊說,我沒有使用維也納組織/ VAOs,所有的調用GPU的人因爲我在每個矩形上調用了glRectf,而不是對GPU進行一次主繪製調用。我不確定構建頂點數組是否還要慢。所以,在我開始重構很多代碼之前,我想知道這是否是真正的問題。也就是說,瓶頸可能是過多GPU的繪製調用,並且我應該使用VBOs來構建大量的頂點,並在draw的末尾對GPU執行一次繪製調用。

任何幫助,將不勝感激。謝謝!

回答

2

首先,2500是一個很多的繪製電話,而不是你正在繪製。

我畫的對象的方式是什麼,我認爲是不現代的OpenGL

你是正確的。

調用glRect(x1, y1, x2, y2)是做等價的:

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

這被稱爲直接模式。

我想知道是否有可能這是實際問題。

再說一遍,你是對的。考慮到你基本上使用了glBegin()/glEnd(...) 2500次。這是很多命令以及數據分佈在2500 平局呼叫

頂點數組和頂點緩衝區的唯一原因會更慢。如果您同樣要撥打glDrawArray() 2500次(考慮到您每次都更新緩衝區)。

,我應該使用駐維也納各組織建立一個龐大的頂點數組,並做一個抽獎調用GPU在年底畫

一般的經驗法則是做盡可能少的OpenGL通話和儘可能少的狀態變化。

考慮到你正在談論2500個矩形(或5000個三角形)。當你必須更新每一幀時,仍然有很多三角形需要繪製。

會單個glBufferData()glDrawArrays()比2500 glBegin()/glEnd(...)每個幀快?有可能。但是,有一些緩衝區可能會更快。原因是CPU和GPU是異步的。因此,在構建大量頂點時,GPU在創建下一部分時可能已經在繪製其中一些頂點。那肯定會更快。

最後但並非最不重要的一點,我不主張使用即時模式(glBegin()/glEnd(...))。我試圖提出的一點是,與您的問題相比,1 glDrawArray()可能會比10 glDrawArray()慢。當CPU正在更新接下來的500個三角形時,GPU可能會繪製前500個三角形,而不是等到它們都可以繪製出來。

底線當然是嘗試每個解決方案和基準。

+0

好吧!我可能會做的是有一個頂點列表,每次用'n'條目填充時,我會調用'glDrawArrays()'。我會看到它的效果如何。謝謝! –