2011-09-14 175 views
5

我有這行代碼:Java:openGL:JOGL:當我調用display()方法時,幕後會發生什麼?

renderableObject.renderObject(gl, glu); 

這導致通過openGL的被渲染對象的大名單,但是它只能使用時如下:

@Override 
public void display(GLAutoDrawable drawable) 
    {    
     renderableObject.renderObject(gl, glu); 
    } 

如果我所說的行重寫的顯示方法以外,我得到一個異常說有在當前線程上沒有glContext,其實如果我叫任何GL得出這樣的方法我得到相同的異常之外的命令

現在最好我想創造了很多顯示列表一次,然後渲染他們的每一幀奇數顯示列表定期重新創建。但是我必須通過這個單一的display()方法,這意味着如果顯示列表已經創建或者需要更改等,我將不得不測試每一幀。每秒60次!當我需要時可以單獨處理它們時,多少浪費處理能力。

因此,無論調用display()方法,我都希望能夠複製它,使我可以創建大量我自己的自定義顯示方法,而無需通過這一種方法處理所有事情!

那麼是否有一個簡單的電話我可以讓自己?

回答

2

看起來很奇怪,這是它應該工作的方式。

在幕後發生的事情是,當您創建的GLCanvas被繪製出來時,幕後JOGL正在完成一大堆工作。它正在創建一個GLContext,並使其成爲當前線程的GLCanvas。只有完成後才能進行渲染調用。一個GLContext沒有變成當前的,或者是一個從它派生的GL對象,對你來說沒用。此外,GLContext僅針對該線程製作爲當前,並且在顯示調用完成後立即變爲非當前,因此掛到其對GL或GL的引用以供以後使用將不起作用。

幾乎所有JOGL應用程序都以這種方式工作。您創建一個GLEventListener,並在其中實現display(),從GLAutoDrawable中提取一個GL並用它進行渲染調用。你不想在任何其他地方進行渲染調用,除了你想在paint()方法外進行Graphics2D調用。大多數初學Java程序員都試圖從繪畫方法的外部進行繪畫;這是相似的。如果您需要觸發重繪,那麼您可以像使用Java2D一樣進行重繪:使用invalidate()。 (當然,你可以編寫從display()方法中調用的子方法,並將GL或GLAutoDrawable作爲參數)。

有幾種方法可以專門創建一個GLContext並使其自己處於最新狀態,但它們很少是必需的。在這裏使用這種方法幾乎總是更好。

+1

幕後JOGL正在做一堆工作。它正在創建一個GLContext,並使其成爲當前線程的GLCanvas。 -------我不能自己做這個嗎? – Troyseph

+0

塞巴斯蒂安特洛伊,你可以但它做什麼並不是微不足道的。您可以執行嚴格的最小操作(從GLAutoDrawable獲取GLContext並使其成爲最新版本),但請記住,JOGL包含許多不錯的怪癖和解決方法,這些操作比C中的本地純OpenGL或Java中的其他綁定更安全, C#,Python,...而且,如果你做了不好的事情,那麼破壞你的性能真的很容易。當我將Ardor3D移植到JOGL 2時,我發現makeCurrent()被無用地調用了一次,當v-sync關閉時,刪除這個調用給了我一個巨大的提升。 – gouessej

相關問題