2011-05-25 68 views
3

我遇到了OpenGL中的顏色採集和抗鋸齒問題。激活AA時,glReadPixels的結果在對象邊界和對象交點處顯然是錯誤的。例如:在OpenGL中採用AntiAliasing進行顏色採集?

我在#32(RGBA:32,0,0,0)附近渲染了一個盒子#28(RGBA:28,0,0,0)。使用AA時,由於AA算法,我可以得到一個錯誤的ReadPixel值(例如30),其中立方體和三角形重疊,或者盒邊緣的值爲14。

我有4000萬個物體需要我可以挑選(這是一個拼圖遊戲)。能夠按形狀選擇對象是至關重要的。

我試着glDisable(GL_MULTISAMPLE)來禁用AA,但它不與某些AA模式下運行(我讀這取決於AA實施 - SS,MS,CS ..)

那麼,怎麼辦我選擇一個基礎對象?

  1. 有辦法暫時禁用AA嗎?
  2. 使用不同的緩衝區或甚至渲染上下文?
  3. 還有其他建議嗎?
+1

大多數圖形驅動程序都可以選擇強制消除鋸齒而忽略設置。 [嘗試使用FBO](http://www.gamedev.net/topic/570321-glreadpixel-selection--driver-forced-anti-aliasing/)。 – 2011-05-25 11:21:02

+0

如何獨立於光柵器/ OpenGL實現拾取?有易於使用,高性能庫光線三角相交測試,如OPCODE http://www.codercorner.com/Opcode.htm – datenwolf 2011-05-25 14:37:06

+0

@datenwolf當他工作與拼圖(我將實施爲阿爾法測試四邊形或類似的東西),我認爲這對他不起作用。 – 2011-05-25 14:39:10

回答

7

爲什麼不使用FBO作爲您的選擇緩衝區?

+0

我已經用顏色和深度附件組裝了FBO(用於拾取和未投影),並且它效果很好。謝謝! – Kromster 2011-05-26 17:44:16

+1

唯一的缺點是有些GPU不支持FBO,但有AA,那麼我需要回退到主緩衝區顏色選擇和問題返回 – Kromster 2012-05-13 18:06:14

1

我使用這個黑客:挑選不僅僅一個像素,而是挑選點周圍的所有3x3 = 9像素。如果他們都是一樣的,我們是安全的。否則,它必須處於邊緣,我們可以跳過它。

int renderer::pick_(int x, int y) 
{ 
    static_assert(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__, 
      "only works on little-endian architecture"); 
    static_assert(sizeof(int) == 4, 
      "only works on architecture that has int size of 4"); 

    // sort of edge detection. selection only happens at non-edge 
    // since the edge may cause anti-aliasing glitch 
    int ids[3*3]; 
    glReadPixels(x-1, y-1, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, ids); 
    for (auto& id: ids) id &= 0x00FFFFFF;  // mask out alpha 
    if (ids[0] == 0x00FFFFFF) return -1;  // pure white for background 

    // prevent anti-aliasing glitch 
    bool same = true; 
    for (auto id: ids) same = (same && id == ids[0]); 
    if (same) return ids[0]; 

    return -2;         // edge 
}