2012-10-21 24 views
1

如何在openGL中逐步顯示動畫?如何在openGL中逐步顯示動畫?

我正在做一個reprap打印機項目來讀取GCode文件並將其解釋爲圖形。 現在我很難做出一步一步的繪製整個對象的動畫。 我需要畫很多短線來組成一個完整的對象。 例如:

|-----| 
|  | 
|  | 
|-----| 

正方形是由許多短行,並且通過像代碼生成的各行:

glPushMatrix(); 
..... 
for(int i=0; i< instruction[i].size(),i++) 
{ .... 
    glBegin(GL_LINES); 
    glVertex3f(oldx, oldy, oldz); 
    glVertex3f(x, y, z); 
    glEnd(); 
} 
glPopMatrix(); 

現在我想使一個步驟的動畫來顯示這是如何方被製成。每次畫一條新線時,我都試圖刷新屏幕,但它不起作用,整個廣場立刻出現。任何人都知道如何做到這一點?

回答

0

典型的OpenGL實現將排隊大量的調用,以將它們一起批量處理成活動突發,以便優化使用可用的通信帶寬和GPU時間資源。

你想要做的事情基本上與雙緩衝渲染相反,即渲染每個繪圖步驟立即可見的地方。一種方法是通過渲染到單個緩衝窗口並在每個步驟後調用glFinish()。主要缺點:在使用合成窗口管理器和類似工具的現代系統上很可能無法正常工作。

我推薦的另一種方法是使用單獨的緩衝區進行增量繪製,並不斷刷新主幀緩衝區。關鍵主題是幀緩衝區對象渲染到紋理

首先你創建一個FBO(大量的教程,並作爲StackOverflow的答案)。 FBO基本上是一種抽象,您可以將目標緩衝區(如紋理或渲染緩衝區)連接到該抽象層,並將其綁定爲繪圖調用的目標。

那麼如何解決你的問題呢?首先,您不應該通過延遲繪圖循環來執行動畫。這有幾個原因,但主要的問題是,你鬆散的程序交互性。相反,您需要維護一個(全局)計數器,以指明您的動畫中的哪一步。讓我們把它叫做step

int step = 0; 

然後在你的繪圖功能,你必須階段:1)紋理更新2)屏幕刷新

第一階段由結合您的幀緩衝區對象爲渲染目標。對於這項工作的目標質地必須是未綁定

glBindTexture(GL_TEXTURE_2D, 0); 
glBindFramebuffer(GL_FRAMEBUFFER, animFBO); 
glViewport(0, 0, fbo.width, fbo.height); 
set_animFBO_projection(); 

的伎倆,現在是,你清除animFBO只有一次,創建後即,然後永遠不再。現在,根據動畫一步

draw_lines_for_step(step); 

畫你的線條,並增加步驟計數器(能做到這一點作爲一個複合語句,但是這是更清楚了)

step++; 

更新動畫FBO它的後有時間更新屏幕。首先取消綁定animFBO

glBindFramebuffer(GL_FRAMEBUFFER, 0); 

我們現在主,屏幕上的幀緩衝

glViewport(0, 0, window.width, window.height); 
set_window_projection(); //most likely a glMatrixMode(GL_PROJECTION); glOrtho(0, 1, 0, 1, -1, 1); 

現在綁定FBO附加質地和失敗中汲取到全視四

glBindTexture(GL_TEXTURE_2D, animFBOTexture); 
draw_full_viewport_textured_quad(); 

最後做緩衝區交換顯示動畫步驟迭代

SwapBuffers(); 
0

您應該在每次繪製調用後調用SwapBuffer方法。 確保你沒有擰上矩陣堆棧,你可能需要一些東西來「暫停」像斷點一樣的渲染。

+0

交換緩衝區調用很可能會損壞後臺緩衝區的內容,因此繪製延續將不起作用。 – datenwolf

+0

SwapBuffer沒有工作,我不知道這是因爲座標文件太大還是其他原因。該程序進入永遠運行的心情,屏幕上沒有任何顯示......但thx無論如何! – Solorchid

0

如果只想線路出現了一個又一個和你沒有被吹毛求疵的有關效率和良好的編程風格嘗試類似:

(在你的繪圖程序)

if (timer > 100) {

//draw the next line

timer = 0;

}

else

timer++;

//draw all the other lines (you have to remember wich one already appeared)

//for example using a boolean array "lineDrawn[10]"

定時器是一個整數,告訴你,你已經多久繪製現場。如果你將它放大,當你運行你的程序時,屏幕上的東西發生得更慢。

當然,這隻適用於你有繪圖程序。如果不是,我強烈建議使用一個。

- >很多教程都很漂亮,例如:

http://nehe.gamedev.net/tutorial/creating_an_opengl_window_%28win32%29/13001/

古爾祝你好運!

PS:我認爲你已經完成了幾乎相同的工作,但沒有計時器。這就是爲什麼一切都被畫得如此之快,以至於你認爲它同時出現。

+0

Thx〜這似乎是一個好主意〜我會試試〜 – Solorchid