2013-04-11 28 views
4

編輯:作爲建議,我想設置一個「初始」的價值在我的構造我的着色均勻,我已經包括了一些代碼,將不勝感激,如果有人可以解釋爲什麼我得到一個空白屏幕如果我通過了值通過我的構造函數 - 感謝是否可以爲着色器制服設置初始值? (安卓,OpenGL ES 2.0的)

方法加載我的紋理

public void setTexture(GLSurfaceView view, Bitmap imgTexture) { 
    this.imgTexture=imgTexture; 
    iProgId = Utils.LoadProgram(strVShader, strFShader); 
    iBaseMap = GLES20.glGetUniformLocation(iProgId, "u_baseMap"); 
    iPosition = GLES20.glGetAttribLocation(iProgId, "a_position"); 
    iTexCoords = GLES20.glGetAttribLocation(iProgId, "a_texCoords"); 
    texID = Utils.LoadTexture(view, imgTexture); 

    //Everything is working if I include the lines as part of my setTexture() method 
    GLES20.glUseProgram(iProgId); 
    mOpacityHandle = GLES20.glGetUniformLocation(iProgId, "opValue"); 
    GLES20.glUniform1f(mOpacityHandle, 1.0f); 
} 

但如果我把它們放在我的構造,沒有什麼....

public Quad() { 
    //iProgId = Utils.LoadProgram(strVShader, strFShader); //I've tried with and without this line - I can confirm that loading/linking is working OK 
    GLES20.glUseProgram(iProgId); 
    mOpacityHandle = GLES20.glGetUniformLocation(iProgId, "opValue");   
    GLES20.glUniform1f(mOpacityHandle, 1.0f);   
} 

其實我已經抄了我的整個紋理加載程序到我的建設者和創造我的股四頭肌時通過它的相關參數,但我仍然沒有構造函數運行後的某個時候,除非我設置的值!

我有如下片段着色器:

String strFShader = 
    "precision mediump float;" + 
    "uniform float opValue;"+ 
    "varying vec2 v_texCoords;" + 
    "uniform sampler2D u_baseMap;" + 
    "void main()" + 
    "{" + 
    "gl_FragColor = texture2D(u_baseMap, v_texCoords);" + 
    "gl_FragColor *= opValue;"+ 
    "}"; 

當我創建我的對象(四芯)我有一個方法,我可以設置上述四的不透明度,像這樣:

public void setOpacity(float op) { 
    GLES20.glUseProgram(iProgId);  
    mOpacityHandle = GLES20.glGetUniformLocation(iProgId, "opValue"); 
    GLES20.glUniform1f(mOpacityHandle, op); 
} 

但是,我只想運行我的setOpacity方法,如果我想讓我的精靈(四)具有某種程度的透明度。如果我沒有指定不透明度級別(即,如果我不運行setOpacity方法),我希望它使用默認值或「初始」值(顯然我想成爲1.0的浮點數)。

這是可能的嗎?

回答

3

不能使用某種uniform opValue = 1.0;着色器內初始化一個統一的,如果它是你的意思。即使你可以,它也不會給你買太多,因爲統一值在程序使用中持續存在。這意味着如果您激活另一個程序(使用glUseProgram),然後重新綁定該程序,則制服仍將具有您上次設置的值。所以你可以在連接程序之後立即將制服設置爲一些初始值,但是隻要你改變了一些透明的精靈,它就會永遠失去這個值。

在單個程序使用過程中它甚至不會工作,因爲統一值在繪製調用中持續存在超過。想想吧,如果你寫了

draw_opaque_sprite(); 

setOpacity(0.5f); 
draw_transparent_sprite(); 

draw_opaque_sprite(); 

程序如何知道你想在繪製透明精靈之後將不透明度重置爲某個默認值。當然,要求應用程序爲每個平局呼叫設置所有制服將是不行的。

所以你不會得到解決正確設置爲每個精靈制服。在這種情況下,通常的優化是通過渲染狀態來排序對象(在這種情況下,透明度,但也許其他一些狀態更重要,如紋理或類似的東西),以減少狀態變化(如着色器更改,紋理綁定,或在這種情況下統一更新)儘可能多。

+0

感謝這個@ChristianRau,但我不希望每次抽籤後的不透明度重置/渲染,而是當我創建我的對象(例如quad1 =新的四();),我後來不那麼設置不透明度,我想它假設1.0的標準不透明度。 – Zippy 2013-04-11 17:55:40

+0

@Zippy嗯,將它設置爲默認值1.0(像往常一樣使用'glUniform'),它會一直保持這樣,直到你改變它,然後它會保持新值直到你改變它,就像在答案中解釋的一樣。你不能爲每個*「對象」*設置一個值,因爲OpenGL絕對沒有任何*「對象」*的概念。每個程序的每個統一都有一個單一的值,並且只有*你*調用'glUniform'時纔會更改該值。這就是在OpenGL中一切正常的方式,它是一個狀態機。 – 2013-04-11 18:57:44

+0

再次感謝@ChristianRau,我必須承認我對OGL相當陌生,所以你的解釋非常感謝。如果我從我的自定義類創建2個四邊形,然後設置不同級別的不透明度,如果他們共享相同的程序和着色器,他們如何顯示每個都具有不同的不透明度級別?謝謝,我無法理解這一點。關於使用glUniform設置'初始'級別,我試圖在構造函數中這樣做,但它不會工作,我假設,因爲在構造函數的着色器程序尚未創建/鏈接。 – Zippy 2013-04-11 19:56:19

相關問題