我在哪里可以更改着色器制服并调用 GL 函数?

Where i can change shader uniforms and call GL Functions?

我只是想用 GLSurfaceView 编写简单的 android 应用程序,但我遇到了一个问题。 我编写了一个简单的着色器程序,并在其中放置了一个浮点参数。这是我的

顶点着色器:

        attribute vec2 vPosition;
        attribute vec2 vTexCoord;
        varying vec2 texCoord;

        void main(){
           texCoord = vTexCoord;
           gl_Position = vec4 ( vPosition.x, vPosition.y, 0.0, 1.0 );
        }

片段着色器:

        precision mediump float;
        uniform samplerExternalOES sTexture;
        uniform float myParam;
        varying vec2 texCoord;

        void main(){
          gl_FragColor = texture2D(sTexture,texCoord);
          gl_FragColor.r = gl_FragColor.r*myParam.x;
        }

一切都很好。

我获得了访问 myParam 的句柄(int paramHandle - 我的 class 的成员):

        public void onSurfaceCreated(....){
          ....
          paramHandle= GLES20.glGetUniformLocation(shaderProgram,"myParam");
          ....
        }

现在我想改变 myParam 并观察屏幕上的图像发生了什么。对于这个任务,我需要调用:

 GLES20.glUseProgram(myShaderProgram);
 GLES20.glUniform1f(paramHandle, new_value);

所以:如果我尝试更改这些函数中的 myParam 值:

onSurfaceCreated(...)、onSurfaceChanged(...) 或 onDrawFrame(...)

我可以在屏幕上看到这个变化,所以我觉得 myParam 值被改变了。

但是如果我想使用按钮设置 maParam 值,例如在单击按钮时调用函数 setMyParamValue

    public void setMyParamValue(float newValue){
      GLES20.glUseProgram(myShaderProgram);
      GLES20.glUniform1f(paramHandle, new_value);
    }

好像什么都没发生

有人可以向我解释一下它是如何工作的吗?为什么我不能在我的函数中设置统一值?

渲染发生在与 UI 事件传递来源不同的线程上。 openGL 调用应该只发生在渲染线程中。

您应该将这些调用转发给您传递给 queueEvent 的可运行对象:

public void setMyParamValue(final float newValue){
    queueEvent(new Runnable(){
        public void run(){
           GLES20.glUseProgram(myShaderProgram);
           GLES20.glUniform1f(paramHandle, new_value);
        }
    });
}

run() 中的代码将在渲染线程中执行。