0

編集 6 - コメント/進行中の研究に関連して完全に書き直す

編集 7 - 投影/ビュー マトリックスを追加.....

私はこれでうまくいっていないので、Google のデモからビュー/プロジェクション マトリックスを追加しました。以下のコードを参照してください。 ""gl_position = a_position * uMVPMatrix;" + を頂点シェーダーに入れると空白の画面 ("gl_position = a_position;" + 私のクワッドは少なくとも表示されます.......)

クラスレベルで宣言: (Quad クラス)

    private final float[] rotationMat = new float[16];
    private FloatBuffer flotRotBuf;
    ByteBuffer rotBuf;
    private int muRotationHandle = -1;              // Handle to the rotation matrix in the vertex shader called "uRotate"

クラスレバーで宣言: (レンダラークラス)

    private final float[] mVMatrix = new float[16];
    private final float[] mProjMatrix = new float[16];
    private final float[] mMVPMatrix = new float[16];

テクスチャを設定し、回転を行う (または行うことになっている) ルーチン (これは私の Quad クラスにあります

public void setTexture(GLSurfaceView view, Bitmap imgTexture, float[] mvpMatrix){
        this.imgTexture=imgTexture;

      // get handle to shape's transformation matrix
        mMVPMatrixHandle = GLES20.glGetUniformLocation(iProgId, "uMVPMatrix");

        // Apply the projection and view transformation
        GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);

//      Matrix.setRotateM(rotationMat, 0, 45f, 0, 0, 1.0f);    //Set rotation matrix with angle and (z) axis

//       rotBuf = ByteBuffer.allocateDirect(rotationMat.length * 4);
         // use the device hardware's native byte order
//       rotBuf.order(ByteOrder.nativeOrder());
         // create a floating point buffer from the ByteBuffer
//       flotRotBuf = rotBuf.asFloatBuffer();
         // add the coordinates to the FloatBuffer
//       flotRotBuf.put(rotationMat);
         // set the buffer to read the first coordinate
//       flotRotBuf.position(0);

//       muRotationHandle = GLES20.glGetUniformLocation(iProgId, "uRotation");  // grab the variable from the shader
//       GLES20.glUniformMatrix4fv(muRotationHandle, 1, false, flotRotBuf); //Pass floatbuffer contraining rotation matrix info into vertex shader
         //GLES20.glUniformMatrix4fv(muRotationHandle, 1, false, rotationMat, 1); //Also tried this ,not use floatbuffer

        //Vertex shader
        String strVShader =  
            //    "uniform mat4 uRotation;" +
                  "uniform mat4 uMVPMatrix;" +
                  "attribute vec4 a_position;\n"+
                  "attribute vec2 a_texCoords;" +
                  "varying vec2 v_texCoords;" +
                  "void main()\n" +
                  "{\n" +
                  "gl_Position = a_Position * uMVPMatrix;"+  //This is where it all goes wrong....         
                  "v_texCoords = a_texCoords;" +
                  "}";

        //Fragment shader

        String strFShader =
            "precision mediump float;" +
            "varying vec2 v_texCoords;" +
            "uniform sampler2D u_baseMap;" +
            "void main()" +
            "{" +
            "gl_FragColor = texture2D(u_baseMap, v_texCoords);" +
            "}";


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

    }

私のレンダラークラスから:

public void onSurfaceChanged(GL10 gl, int width, int height) {
    // TODO Auto-generated method stub

    //Set viewport size based on screen dimensions      
    GLES20.glViewport(0, 0, width, height);

    float ratio = (float) width / height;
    Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);

}

    public void onDrawFrame(GL10 gl) {
    // TODO Auto-generated method stub

    //Paint the screen the colour defined in onSurfaceCreated
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

    // Set the camera position (View matrix)
    Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);


    // Calculate the projection and view transformation
    Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);

    quad1.setTexture(curView, myBitmap, mMVPMatrix);  //SetTexture now modified to take a float array (See above) - Note I know it's not a good idea to have this in my onDrawFrame method - will move it once I have it working!

    quad1.drawBackground(); 
}

回転に関連するものをすべて削除し、頂点シェーダーで uMVPMatrix を適用した後、静的クワッドを表示しようとしています。しかし、まだ何もありません:-(

その行を単に「デフォルト」に戻すと、次のようになります。

    "gl_Position = a_position;\n"+

次に、少なくともテクスチャクワッドを表示します(明らかに回転はなく、それを期待しています)。

また、指摘しておくと、mvpMatrix は間違いなく setTexture メソッドにそのまま受信されていることは有効です (Google 開発者コードから mvpMatrix の内容をログに記録したときに表示されるものと同じデータが含まれています)。シェーダーがそれをそのまま受け取っているかどうかを確認する方法がわかりませんか? そうではないと信じる理由はありません。

本当に感謝しており、すべての助けが必要です-私はどこかで非常に間違っているに違いありませんが、それを見つけることができません. ありがとうございました!

編集 2 : この質問に賞金を追加したので、テクスチャ付きクワッド スプライト (2D) を回転させる方法を知りたいだけです。コードをベースとしてレンダリングする必要があります。(つまり、回転させるために何を追加する必要があるのか​​、またその理由)。ありがとう!

編集 3該当なし

EDIT 4言い換え/簡略化された質問

EDIT 5エラーのスクリーンショットを追加

ここに画像の説明を入力

4

2 に答える 2

0

編集: Android SDK を使用して Java をサポートするように編集されました。

Tobias が示したように、OpenGL での頂点変換に対する慣用的な解決策は、行列演算を使用することによって実現されます。OpenGL を使用した開発を継続する場合は、行列演算に関連する基礎となる線形代数を (最終的には) 理解することが重要ですが、線形代数の計算をより読みやすい形式に抽象化するために数学ライブラリを利用することが最善の方法であることがよくあります。Android 環境では、[matrix][1] クラスで float 配列を操作して、次のような回転行列を作成する必要があります。

// initialize rotation matrix
float[16] rotationMat; 
Matrix.setIdentityM(rotationMat,0); 

// angle in degrees to rotate
float angle = 90;

// axis to rotate about (z axis in your case)
float[3] axis = { 0.0,0.0,1.0};

// For your case, rotate angle (in degrees) about the z axis. 
Matrix.rotateM(rotationMat,0,angle,axis[0],axis[1],axis[2]);

次に、次のように、回転マトリックスをシェーダー プログラムにバインドできます。

// assuming shader program is currently bound ...
GLES20.glUniformMatrix4fv(GLES20.glGetUniformLocation(shaderProgramID, "uRotation"), 1, GL_FALSE, rotationMat);

(渡されるプログラムの) 頂点シェーダーは次のrotationMatようになります。

precision mediump float;
uniform mat4 uMVPMatrix;
uniform mat4 uRotation;
attribute vec2 a_texCoords;
attribute vec3 a_position;
varying v_texCoord;

void main(void)
{
    v_texCoord = a_texCoords;
    gl_Position = uMVPMatrix* uRotation * vec4(a_position,1.0f);
}

または、このシェーダー プログラムの外部で事前乗算uMVPMatrix* uRotationを行い、その結果をシェーダー プログラムに渡して、過度の重複計算を回避することもできます。

行列演算用のこの高レベル API の使用に慣れたら、 Nicol Bolasによって書かれたこのすばらしいチュートリアルを読んで、内部演算がどのように実行されるかを調べることができます。

于 2013-03-31T06:12:29.933 に答える
0

z を中心とした回転の回転行列:

cos a -sin a 0
sin a  cos a 0
    0      0 1

構成方法を覚える方法:
a はラジアン単位の角度です。a = 0 の場合、行列は恒等行列を生成します。cos は対角線上になければなりません。1 つの sin の前に 1 つの記号がなければならず、記号を切り替えると回転の方向が逆になります。

同様に、x と y を中心とした回転を構築できます。

1      0     0
0  cos a sin a
0 -sin a cos a

 cos a 0 sin a
     0 1     0
-sin a 0 cos a

行列演算に慣れていない場合は、次のコードを参照してください。

for (int i=0; i<4; i++) {
    vertices_new[i*5+0] = cos(a) * vertices[i*5+0] - sin(a) * vertices[i*5+1]; // cos(a) * v[i].x - sin(a) * v[i].y + 0 * v[i].z
    vertices_new[i*5+1] = sin(a) * vertices[i*5+0] + cos(a) * vertices[i*5+1]; // sin(a) * v[i].x + cos(a) * v[i].y + 0 * v[i].z
    vertices_new[i*5+2] = vertices[i*5+2]; // 0 * v[i].x + 0 * v[i].y + 1 * v[i].z
    vertices_new[i*5+3] = vertices[i*5+3]; // copy texture u
    vertices_new[i*5+4] = vertices[i*5+4]; // copy texture v
}
于 2013-03-25T23:44:51.600 に答える