1

編集コードが追加されました。以下を参照してください

編集 2 - 説明とともに下部に含まれるデバイスのスクリーンショット

編集 3 - 新しいコードが追加されました

レンダリングされたクラスとカスタムの「クワッド」クラスの2つのクラスがあります。

これらをレンダラー クラスのクラス レベルで宣言しました。

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

そして、私の onSurfaceChanged メソッドには次のものがあります。

@Override public void onSurfaceChanged(GL10 gl, int width, int height) {

    GLES20.glViewport(0, 0, width, height);

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

}

と....

    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    // TODO Auto-generated method stub

    myBitmap = BitmapFactory.decodeResource(curView.getResources(), R.drawable.box);

        //Create new Dot objects

        dot1 = new Quad();
        dot1.setTexture(curView, myBitmap);
        dot1.setSize(300,187);    //These numbers are the size but are redundant/not used at the moment.

        myBitmap.recycle();


           //Set colour to black
           GLES20.glClearColor(0, 0, 0, 1);

}

最後に、このクラス onDrawFrame から:

@Override
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) so looking from the front
   Matrix.setLookAtM(mVMatrix, 0, 0, 0, 3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

    // Combine
   Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);

    dot1.rotateQuad(0,0,45, mMVPMatrix); //x,y,angle and matrix passed in

}

次に、私のクワッドクラスで:

これはクラスレベルで宣言されています:

        private float[] mRotationMatrix = new float[16];        
    private final float[] mMVPMatrix = new float[16];
    private final float[] mProjMatrix = new float[16];
    private final float[] mVMatrix = new float[16];
    private int mMVPMatrixHandle;
    private int mPositionHandle;
    private int mRotationHandle;
//Create our vertex shader
    String strVShader =  
              "uniform mat4 uMVPMatrix;" +
              "uniform mat4 uRotate;" +
              "attribute vec4 a_position;\n"+
              "attribute vec2 a_texCoords;" +
              "varying vec2 v_texCoords;" +
              "void main()\n" +
              "{\n" +
         //     "gl_Position = a_position * uRotate;\n"+
         //          "gl_Position = uRotate * a_position;\n"+
               "gl_Position = a_position * uMVPMatrix;\n"+  
        //        "gl_Position = uMVPMatrix * a_position;\n"+  
                  "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);" +
        "}";

次に、テクスチャを設定する方法(ただし、これはこの問題に関連しているとは思わないでください!!)

    public void setTexture(GLSurfaceView view, Bitmap imgTexture){
        this.imgTexture=imgTexture;

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

    }

そして最後に、私の 'rotateQuad' メソッド (現在、クワッドを描画して回転させることになっています)。

public void rotateQuad(float x, float y, int angle, float[] mvpMatrix){

Matrix.setRotateM(mRotationMatrix, 0, angle, 0, 0, 0.1f);

//  Matrix.translateM(mRotationMatrix, 0, 0, 0, 0);  //Removed temporarily

// Combine the rotation matrix with the projection and camera view
   Matrix.multiplyMM(mvpMatrix, 0, mRotationMatrix, 0, mvpMatrix, 0);

float[] vertices = {

        -.5f,.5f,0, 0,0,
        .5f,.5f,0, 1,0,
        -.5f,-.5f,0, 0,1,
        .5f,-.5f,0, 1,1

        };

 vertexBuf = ByteBuffer.allocateDirect(vertices.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
 vertexBuf.put(vertices).position(0);

//Bind the correct texture
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texID);      
//Use program
GLES20.glUseProgram(iProgId);
// 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);
    // get handle to shape's rotation matrix
mRotationHandle = GLES20.glGetUniformLocation(iProgId, "uRotate");
  // Apply the projection and view transformation
  GLES20.glUniformMatrix4fv(mRotationHandle, 1, false, mRotationMatrix, 0);

//Set starting position for vertices
vertexBuf.position(0);
//Specify attributes for vertex
GLES20.glVertexAttribPointer(iPosition, 3, GLES20.GL_FLOAT, false, 5 * 4, vertexBuf);
//Enable attribute for position
GLES20.glEnableVertexAttribArray(iPosition);
//Set starting position for texture
vertexBuf.position(3);
//Specify attributes for vertex
GLES20.glVertexAttribPointer(iTexCoords, 2, GLES20.GL_FLOAT, false, 5 * 4, vertexBuf);
//Enable attribute for texture
GLES20.glEnableVertexAttribArray(iTexCoords);
//Draw it
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
}

編集 2 の場合。

これは、画面の中央に描かれた私のクワッドです。回転なし。

ここに画像の説明を入力

これは、コード「gl_Position = a_position * uMVPMatrix;」を使用して +45 度回転させた同じクワッドです。+ 私の頂点シェーダー (現在は別のプロジェクトのものなので、シェーダー変数は vPosition ではなく a_position です) では、正しいように見えます!

ここに画像の説明を入力

ただし、これは 2 つのシェーダー変数を切り替えて +45 度回転させた同じクワッドです (つまり、"gl_Position = uMVPMatrix * a_position;" と表示されます)。

また、四角形は対称であるため、ここでは表示できませんが、各方法は他の方法とは反対方向に回転します....

ここに画像の説明を入力

どんな助けでも感謝します。

4

3 に答える 3

1

これら 2 つの変数に何を渡そうとしているのかわからないため、これを判断することは本当に不可能です。

OpenGL は列優先の形式であるため、vPositionが実際にはベクトルであり、uMVPMatrixが行列である場合、これがシェーダーにある場合は最初のオプションが正しいです。

これがシェーダーではなくプログラム コードにある場合は、十分な情報がありません。

最初のオプションを使用しても予期しない結果が得られる場合は、行列が正しく計算されていないか、正しい頂点が渡されていない可能性があります。

于 2013-04-05T15:12:01.923 に答える
0

助けてくれてありがとう。

問題を追跡することができました(ほとんどの場合)。私がしたことをお見せします。

次の行でした。

Matrix.multiplyMM(mvpMatrix, 0, mvpMatrix, 0, mRotationMatrix, 0);

ご覧のとおり、行列を乗算して、乗算で使用していた行列に格納し直していました。

そこで、mvpMatrix2 という新しいマトリックスを作成し、その中に結果を保存しました。次に、それを頂点シェーダーに渡しました。

//Multiply matrices
Matrix.multiplyMM(mvpMatrix2, 0, mvpMatrix, 0, mRotationMatrix, 0);

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

//Give to vertex shader variable
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix2, 0);

これを適用した後、歪みはありません (また、ここでの私の他の質問に関しては、Matrix を使用しています。OpenGL ES 2.0 で回転させると、クワッドの中心を移動できます)。「大部分」と言ったのは、回転させると逆方向に回転するからです (したがって、+45 度回転 (時計回り) と言うと、実際にはクワッドが -45 度 (反時計回り) 回転します)。

しかし、うまくいけば、これは将来同様の問題を抱えている人を助けるでしょう.

于 2013-04-06T16:16:37.887 に答える