【问题标题】:How to use glUniform1f in this example?在这个例子中如何使用 glUniform1f?
【发布时间】:2014-07-07 13:07:14
【问题描述】:

我已经搜索、阅读并尝试了许多关于如何将值传递给 GLSL 程序的不同示例。但可悲的是,每次尝试都失败了:(

我打算做的很简单:只是在我的 Android 应用程序中打开一点 gl 3d 动画。由于我的 GUI 设计,我更喜欢使用 TextureView 作为 OpenGL Surface。我找到了一些非常适合我的项目的代码。

但我的问题似乎完全在 this example 内部。

当我编译并运行它时,它完全按照它应该做的事情去做。在屏幕上绘制一个三角形。

然后我像这样修改了顶点着色器:

final String vertexShaderSource = 
   "attribute vec4 position;\n" +
   "attribute float myValue;\n" +
   "void main () {\n" +
         "vec4 oo;\n"+
         "oo[0] = position[0];\n"+
         "oo[1] = position[1] * myValue;\n"+
         "oo[2] = position[2];\n"+
         "oo[3] = position[3];\n"+
         "gl_Position = oo;\n" +
   "}";

现在,我想将值传递给属性myValue

以下是我对 run 方法的修改。

public void run() {
   initGL();

   int attribPosition = GLES20.glGetAttribLocation(mProgram,
           "position");
   checkGlError();

   int valuePosition = GLES20.glGetAttribLocation(mProgram,
           "myValue");
   checkGlError();

   System.out.println("att id:"+ attribPosition 
           + " val id:" + valuePosition);

//[...]

   while (true) {
       checkCurrent();

       mVertices.position(0);
       GLES20.glVertexAttribPointer(attribPosition, 3,
                 GLES20.GL_FLOAT, false, 0, mVertices);
       checkGlError();

       GLES20.glUniform1f(valuePosition, 1.5f);
       checkGlError();
    //[...]           
    }
}

据我了解,这应该将 y 轴上的三角形扩展为 1.5f。但它不起作用。 我的调试行的输出是:

I/System.out(22427): att id:1 val id:0

所以这些应该是正确的位置,因为它们都没有 -1 内容。 但是通过将值1.5f 传递给myValueglUniform1f,我唯一能实现的结果就是连续的OpenGL Error 0x502 输出。不再有三角形,因为着色器脚本不会接收到1.5f,而是使用值 0 来扩展它。

我真的希望有人能给我解释一下,如何完成这项工作。因为它是如此基本的东西,所以我认为我在这里遗漏了一些非常明显的东西。

【问题讨论】:

  • 检查在着色器执行期间是否产生任何 OpenGL 错误并用它更新问题。
  • 没有其他 OpenGL 错误。该示例检查了很多错误。

标签: java android opengl-es textureview


【解决方案1】:

您混合了attributeuniform 变量的概念。

由于您在着色器中将myValue 变量声明为attribute,因此您需要使用glVertexAttrib() 设置值:

glVertexAttrib1f(valuePosition, 1.5f);

如果您希望它是uniform,请将顶点着色器中的声明更改为:

uniform float myValue;

以及获取位置的调用:

int valuePosition = GLES20.glGetUniformLocation(mProgram, "myValue");

两种解决方案都有效。顾名思义,uniform 变量非常适合变化不大的值,即理想情况下它们在整个帧中保持不变。 attribute 变量对于渲染帧时频繁更改的值更有效。

【讨论】:

    【解决方案2】:

    您需要在通过glUniform1f 设置之前声明一个制服。因此,将myValue 设为统一。

    uniform float myValue;
    

    接下来你需要它的位置来绑定一个值。您可以使用glGetUniformLocation 函数来做到这一点。

    int valuePosition = GLES20.glGetUniformLocation(mProgram, "myValue");
    

    最后,您使用 glUniform 函数为该位置设置制服。

    GLES20.glUniform1f(valuePosition, 0.5f);
    

    即使使用属性,您也可以获得相同的结果。属性对于不断变化的值是有效的,而制服对于变化较小的值是有效的。

    【讨论】:

      【解决方案3】:

      尝试修改以下内容:

      "attribute float myValue;\n" -> "uniform float myValue;\n"

      int valuePosition = GLES20.glGetAttribLocation(mProgram, "myValue"); -> int valuePosition = GLES20.glGetUniformLocation(mProgram, "myValue");

      另外,请查看以下文档页面,该页面显示了更简洁的转换和缩放顶点的方式。

      http://developer.android.com/reference/android/opengl/Matrix.html

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多