4

编辑:正如建议的那样,我试图在我的构造函数中为我的着色器制服设置一个“初始”值,我已经包含了一些代码,如果有人能解释为什么我通过传递值时会出现空白屏幕,我将不胜感激我的构造函数 - 谢谢

加载我的纹理的方法

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);
}

但是,如果我希望我的 sprite(quad) 具有一定程度的透明度,我只想运行我的 setOpacity 方法。如果我不指定不透明度级别(即,如果我不运行 setOpacity 方法),我希望它使用默认值或“初始”值(显然我希望它是 1.0 的浮点数)。

这是可能吗?

4

1 回答 1

3

uniform opValue = 1.0;如果这就是您的意思,您不能使用着色器内部的某种方式初始化制服。即使可以,它也不会为您带来太多好处,因为统一值在程序使用中是持久的。这意味着如果您激活另一个程序(使用glUseProgram)然后重新绑定该程序,则制服仍将具有您上次设置的值。因此,您可以在链接程序后立即将制服设置为某个初始值,但是一旦您将其更改为某些透明精灵,它就会永远失去该值。

它甚至在单个程序使用期间都不起作用,因为在绘图调用中甚至不止这些统一值是持久的。想想看,如果你写

draw_opaque_sprite();

setOpacity(0.5f);
draw_transparent_sprite();

draw_opaque_sprite();

在绘制透明精灵后,程序如何知道您想要将不透明度重置为某个默认值。当然,要求应用程序为每个绘图调用设置所有制服是没有选择的。

因此,您将无法为每个精灵正确设置制服。在这种情况下,通常的优化是按对象的渲染状态(在您的情况下是不透明度,但可能其他一些状态甚至更重,如纹理或类似的东西)以减少状态变化(如着色器变化、纹理绑定,或者在这种情况下统一更新)尽可能多。

于 2013-04-11T17:36:01.480 回答