2013-01-22 18 views
4

系統:的Android 4.03,OpenGL ES 2.0的在OpenGL ES中提供良好/有效的練習期間編譯着色器?

問題:當glAttachShader在第一幀之後調用已經呈現與另一個程序/着色器,某些設備(銀河S3)崩潰與 「GL_INVALID_VALUE」錯誤(錯誤堆棧中沒有更多詳細信息)。其他設備(華碩eee TF101)完全正確。該錯誤並不總是會發生,有時它也是一個「GL_INVALID_ENUM」。 如果我強制在第一次調用onDrawFrame時編譯所有着色器,它可以在所有(我的)設備上運行。

問題: 是否存在openGL(ES)機器不能編譯着色器的狀態? 綁定緩衝區,紋理或啓用的屬性數組是否有可能干擾將着色器附加到程序? 如果是這樣,在附加着色器和鏈接程序之前,必須確保什麼樣的理想狀態? 在其他對象已經被其他着色器渲染之後編譯着色器是否合法?

背景:我開發一個Android的庫,這將允許我使用OpenGL圖形以一種更加面向對象的方式(使用對象,如「場景」,「材料」,「模範」等),utlimatively到輕鬆寫遊戲。場景,模型等創建在與GL上下文不同的線程中。只有當onDrawFrame遇到其中一個對象時,它纔會在正確的線程中執行緩衝區對象綁定,紋理綁定和着色器編譯。 我想避免在我的代碼開始處編譯所有着色器。着色器源根據材質,模型和場景的要求進行組裝(例如:材質:包含凹凸貼圖,模型:包含矩陣 - 調色板 - 略圖,場景:包含霧)。當模型從場景中移除時,我將再次刪除着色器 - 如果我添加另一個模型,則應該編寫新的着色器。

在這一點上,我試圖儘可能簡潔,沒有發佈代碼 - 你可以想象,從這個庫中提取相關部分是困難的。

回答

0

如果複製自帶的Android開發工具包,以啓動項目,然後

checkGlError 

是連接頂點着色後的第一次調用BasicGLSurfaceView示例代碼。但是,您可能在代碼中使用了無效值或更早枚舉或在其他位置枚舉。但是這隻會在glAttachShader之後被這個調用拾取。

在我的情況下,我刪除了一個仍然鏈接爲幀緩衝區渲染目標的紋理。我的較舊的Android設備運行較慢,在刪除之前編譯着色器,我的較新設備以某種方式設法在編譯着色器之前調用

glFramebufferTexture2D 

。整個事情以某種方式鏈接到隊列事件和我對線程安全性的理解不足。

感謝您的努力,TraxNet和Prateek Nina。

2

在渲染過程中編譯完全有效,但由於驅動程序需要佔用資源(CPU),因此不鼓勵。某些驅動程序在驅動程序端指示我的觸發器着色器重新編譯,因爲有些狀態被注入着色器。明智的做法是將您的繪圖調用重新組織爲共享相同驅動程序狀態的塊(由着色器程序首選,也是驅動程序完成的最昂貴操作之一)。

提示:確保將所有變量,制服和屬性聲明到您的着色器中,否則,馬裏驅動程序會在編譯過程中將它們刪除,並且當您嘗試獲取統一位置,attrib位置和兒子時,驅動程序返回GL_INVALID_VALUE。

希望有所幫助。

+0

這聽起來很有趣 - 我是否得到了正確的結論,即使它們之前已經編譯過,驅動程序會在觸發某些狀態/事件時自動重新編譯着色器?我可以在哪裏瞭解更多關於這種行爲 –

+0

這對您而言是透明的,但瞭解其含義是獲得良好表現的關鍵。在此查看示例Tegra文檔:http://docs.nvidia.com/tegra/data/Optimize_OpenGL_ES_2_0_Performance_for_Tegra.html – Trax

+0

AMD提供了一個名爲MakeBinaryShader.exe的Windows可執行文件,該文件將文本着色器編譯爲二進制文件。 AMD還提供了一個基於庫的界面BinaryShader.lib,它提供了可以調用的函數,以直接從應用程序中編譯着色器。 Imagination Technologies還提供了自己的二進制着色器編譯工具PVRUniSCo和一個名爲PVRUniSCo Editor的編輯器。 – GLES