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