1. ホーム
  2. java

[解決済み] この例では、glUniform1fをどのように使用するのですか?

2022-03-01 15:36:25

質問

GLSLプログラムに値を渡す方法について、いろいろな例を検索し、読み、試してみました。しかし、悲しいかな、すべての試みは失敗でした :(

私が計画していることは、非常にシンプルです。Androidアプリの中に、ちょっとしたopen gl 3dアニメーションを作るだけです。私のGUIデザインからすると、OpenGLのサーフェイスとしてTextureViewを使いたい。私のプロジェクトにぴったりなコードをいくつか見つけました。

しかし、私の問題は完全に内部にあるようです この例 .

コンパイルして実行すると、まさに想定したとおりの動作をしてくれます。画面に1つの三角形を描きます。

そこで、バーテックスシェーダーをこのように改造してみました。

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.5fmyValueglUniform1f を使用した場合、私が達成できる唯一の結果は、連続した OpenGL Error 0x502 を出力します。シェーダスクリプトが 1.5f で、値0を使用して展開します。

どうすればいいのか、誰か説明してくれないかな。なぜなら、それはとても基本的なことであり、私はここで非常に明白な何かを見逃していると思うからです。

どのように解決するのですか?

の概念が混在していますね。 attributeuniform という変数があります。

を宣言したので myValue 変数を attribute をシェーダに設定する必要があります。 glVertexAttrib() :

glVertexAttrib1f(valuePosition, 1.5f);

にしたい場合は uniform に、バーテックスシェーダーの宣言を変更します。

uniform float myValue;

と位置を取得するための呼び出しを行います。

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

どちらの解決策も有効です。名前が示すように uniform 変数は、あまり変化しない値、つまりフレーム全体が同じであることが理想的です。 attribute フレームをレンダリングしている間に頻繁に変化する値には、変数の方が効率的です。