如何在这个例子中使用glUniform1f?

Arc*_*ord 3 java android opengl-es textureview

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

我打算做的很简单:在我的Android应用程序中只需要一个小小的开放式3D动画.由于我的GUI设计,我更喜欢使用TextureView作为OpenGl Surface.我找到了一些适合我项目的代码.

但我的问题似乎完全在这个例子中.

当我编译并运行它时,它确实完成了它应该做的事情.在屏幕上绘制一个三角形.

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

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" +
   "}";
Run Code Online (Sandbox Code Playgroud)

现在,我想将值传递给属性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();
    //[...]           
    }
}
Run Code Online (Sandbox Code Playgroud)

根据我的理解,这应该在y轴上扩展三角形,因子为1.5f.但它没有用.我的调试行的输出是:

I/System.out(22427): att id:1 val id:0
Run Code Online (Sandbox Code Playgroud)

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

我真的希望有人能解释我,如何完成这件事.因为它是如此根本的东西,我想我错过了一些非常明显的东西.

Ret*_*adi 7

你正在混合概念attributeuniform变量.

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

glVertexAttrib1f(valuePosition, 1.5f);
Run Code Online (Sandbox Code Playgroud)

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

uniform float myValue;
Run Code Online (Sandbox Code Playgroud)

和获取位置的电话:

int valuePosition = GLES20.glGetUniformLocation(mProgram, "myValue");
Run Code Online (Sandbox Code Playgroud)

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