0

編集2:完全で機能するサンプルについては、このGitHubプロジェクトのTriangle2dサンプルをご覧ください。

編集:オルトグラフィックマトリックスがどのように機能するかについての適切な説明を含むリンクについては、受け入れられた回答を参照してください。最後に、提供されたコードを少し調整しました。

  float[] mvp = {
     2f/width,   0f,         0f, 0f,
     0f,        -2f/height,  0f, 0f,
     0f,         0f,         0f, 0f,
    -1f,         1f,         0f, 1f
   };

私のzは0に固定され、wは1に固定されていることに注意してください。このマトリックスは、画面の左下に原点(0,0)を作成します。左上の原点が必要な場合は、次を試してください。

  float[] mvp = {
     2f/width,   0f,         0f, 0f,
     0f,         2f/height,  0f, 0f,
     0f,         0f,         0f, 0f,
    -1f,        -1f,         0f, 1f
   };

GLES20.glUniformMatrix4fvもう1つの問題は、私が変更した呼び出しでした。

FloatBuffer b = ByteBuffer.allocateDirect(mvp.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
b.put(mvp).position(0);
GLES20.glUniformMatrix4fv(uMvpPos, b.limit() / mvp.length, false, b);

これを少しいじりたい場合は、このオンライン計算機を試してください。ソースファイルの行は電卓の列になることを覚えておいてください。

元の問題: AndroidでOpenGLES 2.0を使用して2D三角形を描画しようとしていますが、これまでのところ、あまり成功していません。これらは私のシェーダーです:

(Vertex shader)
uniform mat4    uMvp;
attribute vec3 aPosition;
attribute vec3 aColor;
varying vec4 vColor;
void main() {
  vColor = vec4(aColor.xyz, 1.0);
  vec4 position = vec4(aPosition.xyz, 1.0);
  gl_Position = uMvp * position;
};

(Fragment shader)
precision mediump float;
varying vec4 vColor;
void main(void)
{
  gl_FragColor = vColor;
};

次に、GLSurfaceView.RendererのonSurfaceChangedメソッドに、次のように配置します。

public void onSurfaceChanged(GL10 gl, int width, int height)
{
  // here I load and compile the shaders and link the program.
  // in the end, I use GLES20.glUseProgram(programHandle);
  // (code omitted)

  // create the matrix for the uniform
  int uMvpPos = GLES20.glGetUniformLocation(programHandle, "uMvp");
  float[] mvp = {width, 0f, 0f, 0f,
                 0f, -height, 0f, 0f,
                 0f, 0f, -2f, 0f,
                 -1f, 1, -1f, 1};
  GLES20.glUniformMatrix4fv(uMvpPos, mvp.length * 4, false, mvp, 0);

  // set viewport and clear color to white
  GLES20.glViewport(0, 0, width, height);
  GLES20.glClearColor(1f, 1f, 1f,1.0f);
}

この質問で示されたマトリックスの値を使用しました。ここでの私の意図は、キャンバスが機能するのと同じ方法で座標を操作することです。画面の左上に(0,0)、右下に(幅、高さ)があります。

最後になりましたが、これはonDrawFrameのコードです。

public void onDrawFrame(GL10 gl)
{
  int aPos = GLES20.glGetAttribLocation(programHandle,"aPosition");
  int aColor = GLES20.glGetAttribLocation(programHandle,"aColor");

  // assuming I correctly set up my coordinate system,
  // these are the triangle coordinates and color
  float[] data =
      {
        // XYZ, RGB
        100f, 100f, 0f,
        1f, 0f, 0f,

        50f, 50f, 0f,
        1f, 0f, 0f,

        150f, 50f, 0f,
        1f, 0f, 0f,
      };

  // put all my data into a float buffer
  // the '* 4' is because a float has 4 bytes
  FloatBuffer dataVertex = ByteBuffer.allocateDirect(data.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
  dataVertex.put(data).position(0);

  // set the POSITION values
  // attribute, dataSize(number of elements), data type, normalized?, size(bytes), data
  GLES20.glEnableVertexAttribArray(aPos);
  GLES20.glVertexAttribPointer(aPos, 3, GLES20.GL_FLOAT, false, 6 * 4, dataVertex);

  // set the COLOR values
  dataVertex.position(3); // offset
  GLES20.glEnableVertexAttribArray(aColor);
  GLES20.glVertexAttribPointer(aColor, 3, GLES20.GL_FLOAT, false, 6 * 4, dataVertex);

  // put a white background
  GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

  // and finally draw the triangle!
  GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
}

最終結果は...三角形のない退屈な白い画面です。私は非常に単純な間違いを犯していると思いますが、それを見つけることができません。何かご意見は?

4

1 に答える 1

1

正射影行列が間違っています。 正投影は次のように定義されます(列の主要な順序で):

2/(r-l), 0, 0, 0,
0, 2/(t-b), 0, 0,
0, 0, 2/(f-n), 0,
(r+l)/(l-r), (t+b)/(b-t), (f+n)/(n-f), 1

あなたの場合r=0, l=width, t=height, b=0, f=1, n=0、あなたは以下を得る:

-2/width, 0, 0, 0,
0, 2/height, 0, 0,
0, 0, 2, 0,
1, -1, -1, 1
于 2013-01-07T20:56:06.477 に答える