2013-02-27 66 views
0

OpenGL ES是否具有XOR繪圖模式?我想在該模式下繪製一個立方體,然後繪製一個與立方體相交的球體,輸出應該是立方體的一部分,而球體的一部分卻是空的交點。用於繪圖的OpenGL ES xor模式

+0

ES對像素沒有實際的邏輯運算。最好的選擇似乎是一些模板緩衝技巧。順便說一句,ES 1或2? – 2013-02-27 12:55:16

+0

@ChristianRau你能提供關於如何做到這一點的任何鏈接?即時通訊使用Cocos3D爲iPhone,它現在不支持ES 2,所以答案是ES 1 – medvedNick 2013-02-27 14:07:28

回答

3

既然你要投射後兩個對象的圖像空間交集,而不是與球體的立方體的實際幾何交集(因爲這絕對不是OpenGL是),你可以使用stencilbuffer此:

首先確保你有一個模板緩衝區(取決於你的上下文創建框架,不知道Cocos3D如何做,但OpenGL ES 1本身支持模板測試)。然後做立方體和球體的事情之前,當然使製版,並在幀的開始(與其他緩衝區可能在一起)清除模板緩存:

glClear(... | GL_STENCIL_BUFFER_BIT); 
... 
glEnable(GL_STENCIL_TEST); 

首先我們呈現立方體只有到模板緩衝,爲每個繪製的像素遞增模板值(開始於0)。

glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); //don't really draw anything 
glStencilFunc(GL_ALWAYS, 0, -1); //always pass the test (default anyway) 
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); //increment for each drawn pixel 
//draw object 

然後我們對球體做同樣的事情。之後,模板緩衝區的每個立方體像素或球體像素處都有一個1,而立方體和球體像素處處都有一個1

然後,我們只是借鑑的東西都正常,但只有在模板緩存不2(或者它在哪裏1如果你想),因此,我們不會在路口畫什麼:

glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); //draw something 
glStencilFunc(GL_NOTEQUAL, 2, -1);  //draw everywhere except at intersection 
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); //leave the stencil buffer as is 
//draw cube 
//draw sphere 

最後,完成後,我們再次禁用模板測試(glDisable(GL_STENCIL_TEST))。

這只是一個基本的例子,但它應該讓你開始使用相當強大的模板緩衝區。

目前整個事情都依賴於深度測試結果,這意味着它取決於您繪製對象的順序。如果您希望它與深度無關(因此只考慮它們的2D屏幕投影) ,則可以在不進行深度測試的情況下繪製對象,也可以將第二個參數glStencilOp(這是在模板測試通過但深度測試失敗時執行的操作)設置爲GL_INCR

此刻,它也只適用於啓用背面剔除的情況,否則模板值會爲每個對象增加兩次(至少如果忽略深度),並且事情對於非凸對象。也許你也可以使用其他的模板操作來執行你的任務,但不幸的是OpenGL ES 1似乎不支持模板值的二進制操作,也沒有包裝操作(因此遞減0再次爲0)。

編輯︰好吧,你真的想要在3D對象之間的幾何交叉(或者看起來不同)。那麼你的問題不能被OpenGL本身解決。 OpenGL不會做任何事情,然後在屏幕上繪製簡單的圖元(點,線和三角形)。它既不是一個場景管理系統,也不是一個幾何圖書館。你試圖實現的是一個不是那麼簡單的任務(儘管使用像立方體和球體這樣簡單的對象當然有幫助),你可能需要尋找一些幾何庫來實現網格布爾操作(或者Constructive Solid Geomtry (CSG)),它可以產生適當的幾何差異一個三角網格,然後你可以像往常一樣用OpenGL繪製。

另一種選擇,類似於您提到「3D模板緩衝區」的概念將使用規則的網格來離散的空間,從而細分對象爲小體素(3D像素,認爲小框)。在那些離散的有限體素集上,布爾運算非常容易。但是,當然這種方法是以引入離散化誤差和性能開銷爲代價的(在體素上操作意味着在大數據集上運行,確定CSG也不容易,但可能比O(n^3)更好)。而且,您還必須重新從體素集重新創建可渲染的對象,可以使用一些表面提取方法再次獲取網格,或者僅繪製小點或框。

最終使用合適的CSG庫可能是您最好的選擇,無論哪種方式,OpenGL都沒有任何關係。

+0

感謝您的詳細答案,但我認爲我問我的問題不夠正確......我其實是指幾何交叉口,而詞「空間」不是用於投影圖像,而是用於3D空間。澄清:如果算子不是「立方體xor球體」而是「立方體而不是球體」,應該畫出一部分半球形立方體(在3D中)。所以我需要有點像模板緩衝區,不是用於平面圖像,而是3D空間。我開始懷疑,如果GL能夠自己處理。儘管 – medvedNick 2013-02-27 16:09:01

+0

@medvedNick哦,那麼這改變了一切,事實上這個問題並沒有被OpenGL完全實現,因爲如你所知,OpenGL只是將簡單的東西繪製到屏幕上而沒有其他東西。 – 2013-02-27 16:30:55