2011-04-27 39 views
2

在OpenGL中,一切都與主迴路的工作(據我所知)。如果你想繪製一個物體給定的時間,這是一個問題。現在,我做的是以下幾點:我測量我的應用程序的近似FPS,並設置一個計數器,以減少主循環中的每次迭代。當計數器達到0時,我停止繪圖。因此,例如,如果我想在屏幕上繪製一個物體2秒,並且我的FPS爲30,則將計數器設置爲60並繪製對象,直到計數器達到0.繪製X秒對象在OpenGL

這可以正常工作,但它不是大。例如,由於對象有時距主循環「遠」,所以很難寫出類似 drawObjectFor(object, time)的東西。有沒有更好的方法來做到這一點?

回答

5

你的FPS可能(而且通常會)有所不同,所以計算幀是不是一個好主意。

假設這個例子,看看這可能會咬你:
你的應用程序運行vsynced到60 FPS,你的幀時間是16.58ms。這意味着在屏幕上顯示對象2秒鐘,您將不得不繪製120幀的對象。簡單,讓我們走吧!
繪製對象增加了0.1 ms,總幀時間爲16.68ms。哦,sh * t。現在你有30 FPS,你的對象顯示4秒...

使用適當的時間決定是否繪製你的對象。當你得出結論,你的對象的時間到了,只需設置一個標記,這樣你就不會繪製它(或者,從場景圖中刪除它,如果你有一個,或刪除它,或其他)。

這可以通過多種方式來實現:

  • 在Windows
    • 使用SetTimer,這將發佈一條消息到你的窗口的消息隊列。當您收到WM_TIMER通知時,將該對象的do_draw標誌(或任何您想調用它的標誌)設置爲false。
    • 如果您已經使用WaitFor(Single|Multiple)Object某處一次架,做一個CreateWaitableTimer,並等待這一點。您可以使用MsgWaitForMultipleObjectsEx來執行消息泵送和一次等待,並同時檢查APC。
    • 沒有什麼能阻止你從每幀讀取時間手動一次。 GetTickCount一次,加2000,並做一個if(new_count <= old_count + 2000) draw_object()。儘管GetTickCount的準確度很差(幾十毫秒),但在等待2秒時完全沒有關係。
  • 在Linux下
    • 使用timerfdepoll檢查準備情況,或設置timerfd它非阻塞,看看是否從中讀取返回EAGAIN
    • 使用clock_gettime和做手工(如GetTickCount
    • 使用setitimer
1

你可以有一個「生存時間」字段中的對象本身,這倒計數,直到對象被銷燬(或至少不可見)。

然後drawObjectFor(object, time)將只設置object.timeToLive = time。然後,您還需要將幀時間傳遞給對象,可能在渲染時,可以相應地減少它的timeToLive

+0

是的,我也想過類似的東西,但我想知道是否沒有更直接的方法來實現它,例如通過創建獨立於程序其餘部分的新線程 – seb 2011-04-27 11:14:31

+0

適當的實時循環對於OpenGL應用程序通常比線程更好(至少對於渲染部分 - 你可以使用線程來處理其他任何事情,注意線程同步)。然而,爲場景中的每個對象生成一個線程並不是真正可擴展的,並且對於所有消失的對象和其他任何對象都有一個線程,就像沒有多線程一樣好。 – Kos 2011-04-27 14:49:26