2008-10-09 16 views
12

默認情況下,對象是從前到後繪製的。我正在繪製一個2-D UI對象,並希望將其重新創建。例如,我可以先創建一個白色正方形,然後在其上創建一個稍小的黑色正方形,從而創建一個帶有白色邊框的黑色窗格。 This post對它有一些討論,並將此順序描述爲「畫家算法」,但最終他們給出的例子只是以相反的順序渲染對象以獲得所需的效果。我回到前面(第一個物體回來,後面的物體在頂部繪製)可以通過一些轉換(gOrtho?)實現。在openGL中,如何讓項目回到前面?

我還會提到我對使用GLUT等包裝庫的解決方案不感興趣。

我也發現Mac上使用Cocoa NSOpenGLView的默認行爲似乎回到前面,因爲在Windows中我無法得到這種行爲。在我使用的窗口中的設置代碼是這樣的:

glViewport (0, 0, wd, ht); 
glMatrixMode(GL_PROJECTION);   
glLoadIdentity();      
glOrtho (0.0f, wd, ht, 0.0f, -1.0f, 1.0f); 
glMatrixMode(GL_MODELVIEW);    
glLoadIdentity();      

回答

20

以下調用將關閉深度測試,從而導致以創建的順序繪製對象。這實際上會導致物體回到前面。

glDepthFunc(GL_NEVER);  // Ignore depth values (Z) to cause drawing bottom to top 

確保你不叫這樣的:

glEnable (GL_DEPTH_TEST); // Enables Depth Testing 
2

繪製順序很難。沒有簡單的解決方案。畫家的算法(根據相機視角的距離排序物體)是最直接的,但正如您發現的那樣,它並不能解決所有情況。我會建議畫家的algroithm和層的組合。您可以爲程序上的特定元素構建圖層。所以你有一個背景圖層,對象圖層,特殊效果圖層和GUI圖層。

在每個圖層的項目上使用畫家的算法。在一些特殊的層次上(比如你的GUI層),不要按照畫家的算法排序,而要根據你的調用順序排序。你首先把這個白色的方塊稱爲它,然後它被首先畫出。

+0

好的想法,但所有這些都需要額外的工作。正如我所提到的,在Mac上,如果我沒有弄錯,它似乎會做我想做的事情。 NSOpenGLView的默認設置允許無需特殊處理的前後訂購 – AlanKley 2008-10-09 01:34:07

2

繪製您希望稍後放置在要放在前面的項目後面的項目。也就是說,實際上改變z值(假設z垂直於屏幕平面)。你不必爲了讓物品在彼此面前畫畫而做很多改變。如果你只是稍微改變z值,你不應該注意到他們想要的位置的偏移。你甚至可以非常喜歡,並根據改變後的z位置計算正確的x,y位置,以便該項目出現在應該出現的位置。

+0

好主意。不過,我想沒有「自動」的方式來做到這一點。 – AlanKley 2008-10-09 01:58:30

+1

或者,如果你真的想生活在二維世界中,你可以使用正射投影。然後,z值(同樣,假設z垂直於屏幕平面)無關緊要,除了確定哪些對象被遮擋之外! – 2011-04-13 18:52:43

5

對於你的具體問題,沒有沒有標準的方式來指定OpenGL中的深度排序。某些實現默認情況下可能會進行深度排序,因爲它通常更快,但不能保證(如您發現的那樣)。

但我真的不明白它會如何幫助你在你的情況。如果您在白色正方形前繪製黑色正方形,則應在白色正方形前面繪製黑色正方形,而不管它們以何種順序繪製,只要您啓用了深度緩衝。如果它們實際上是共面的,那麼沒有一個真正在另一個之前,並且任何深度排序算法都是不可預測的。

您發佈了一個鏈接的教程只講了它,因爲當您使用透明度時,深度排序是相關的。但對我而言,這聽起來並不像你以前那樣。

但是,如果你真的必須這樣做,那麼你必須自己做。首先將您的白色方塊發送到渲染管道,強制渲染,然後發送您的黑色方塊。如果你這樣做,並禁用深度緩衝,那麼廣場可以共面,你仍然可以保證黑色方形畫在白色方框上。

+0

謝謝傑拉德。在我的二維思維模式中,我根本不用Z平面,期望所有物體落在同一個Z座標上,其順序對於確定顯示內容非常重要。我已經實現了一個內存中的對象列表,可以很容易地根據標誌向後迭代。 – AlanKley 2008-10-09 01:57:45

+0

我相信我找到了一種方法來設置GL世界以啓用回到前面的繪圖。見下面我提供的答案。我不接受這個答案。 – AlanKley 2008-10-10 02:30:25

+0

您的解決方案不是您在問題中所要求的。當然,禁用深度緩衝區會按照您提供的順序繪製它們,但它不是一個標誌,它們會讓它們回到前面,除非您將它們拉回到前面。 – Gerald 2008-10-10 02:40:19

0

由於AlanKley指出,要做到這一點的方法是禁用深度緩衝。畫家的算法實際上是一種2D掃描轉換技術,用於在沒有像z緩衝區之類的東西時按正確的順序渲染多邊形。但是你不會將它應用到3D多邊形。您通常會對它們進行變形和投影(處理與其他多邊形的交點),然後根據其投影的Z座標對得到的2D投影多邊形列表進行排序,然後以相反的Z順序繪製它們。

當你不能(或不想)使用z緩衝區時,我一直認爲畫家的算法是隱藏表面移除的替代技術。

1

您的東西將按照您調用glBegin/glEnd函數的順序繪製。您可以使用z緩衝區獲得深度緩衝區,如果您的2d對象具有不同的z值,則可以獲得效果想這樣。你看到你在Mac上描述的行爲的唯一方法是,如果程序正在手動繪製東西,或者使用z緩衝區來完成此操作。 OpenGL否則不會像您所描述的那樣自動執行任何功能。