結果を示す
混合色の回転 3D キューブ
I. 概要
OpenGLES の実際の開発に関する以前のブログ投稿は、カメラ フィルターの実装やグラフィックスの描画など、すべて 2D ラチチュードで行われています。
このブログ投稿から、OpenGLES を使用して 3D 世界に入ります。
このブログ投稿では、色のグラデーションと回転を備えた 3D 立方体を実装します。
ダイナミックな 3D グラフィックスを描画するには、基本的な線形代数(ベクトル、行列)と空間座標系変換関連の知識が必要です。ここでは理論科学の普及は行いません。まず自分で学習する必要があります。詳細については、を参照してください。説明については、OpenGL 公式 Web サイトの次の 3 章を参照してください。
2.GLRender: 変数定義
2.1 一般的な変数の定義
//shader程序/渲染器
private int shaderProgram;
private int vPosition;
private int aColor;
private int mvpMatrix;
//suface宽高比
private float ratio;
2.2 頂点、色、インデックス配列、バッファーを定義する
この立方体描画では、最初に頂点、色、インデックス配列を定義し、次にインデックス バッファーを直接描画して立方体を描画します。
3 つの配列とバッファーは次のように定義されます。
private FloatBuffer vertexBuffer;
private FloatBuffer colorBuffer;
private ShortBuffer indexBuffer;
private float vertexData[] = {
-1.0f, 1.0f, 1.0f, //正面左上0
-1.0f, -1.0f, 1.0f, //正面左下1
1.0f, -1.0f, 1.0f, //正面右下2
1.0f, 1.0f, 1.0f, //正面右上3
-1.0f, 1.0f, -1.0f, //反面左上4
-1.0f, -1.0f, -1.0f, //反面左下5
1.0f, -1.0f, -1.0f, //反面右下6
1.0f, 1.0f, -1.0f, //反面右上7
};
//八个顶点的颜色,与顶点坐标一一对应
private float colorData[] = {
1.0f, 1.0f, 0.0f, // v0 Yellow
1.0f, 0.0f, 1.0f, // v1 Magenta 粉红
1.0f, 0.0f, 0.0f, // v2 Red
1.0f, 1.0f, 1.0f, // v3 White
0.0f, 0.0f, 1.0f, // v4 Blue
0.0f, 1.0f, 1.0f, // v5 Cyan 蓝绿
0.0f, 1.0f, 0.0f, // v6 Green
0.0f, 0.0f, 0.0f, // v7 Black
};
private short indexData[] = {
6, 7, 4, 6, 4, 5, //后面
6, 3, 7, 6, 2, 3, //右面
6, 5, 1, 6, 1, 2, //下面
0, 3, 2, 0, 2, 1, //正面
0, 1, 5, 0, 5, 4, //左面
0, 7, 3, 0, 4, 7, //上面
};
2.3 MVP マトリックスの定義
//MVP矩阵
private float[] mMVPMatrix = new float[16];
3. GLRender: シェーダ、メモリ割り当てなど。
3.1 シェーダの作成、リンク、および使用
3.2 シェーダ属性の取得と割り当て
3.3 3 つのバッファ メモリの割り当て
これらの部分のコード実装は、基本的には 2D 円描画に関する前回の記事と同じです。
以前のブログ投稿「OpenGLES: カラー グラデーションで円を描画する」を参照してください。
コードを再度表示しない
4. GLRender: 描画
描画プロセスは基本的に前の 2D 描画プロセスと同じですが、注意すべき違いが 2 つあります。
4.1 MVP マトリックスの割り当て
//填充MVP矩阵
mMVPMatrix = TransformUtils.getCubeMVPMatrix(ratio);
//设置MVP变换矩阵到着色器程序/渲染器
glUniformMatrix4fv(mvpMatrix, 1, false, mMVPMatrix, 0);
//计算MVP变换矩阵
public static float[] getCubeMVPMatrix(float ratio) {
//初始化modelMatrix, viewMatrix, projectionMatrix
float[] modelMatrix = getIdentityMatrix(16, 0); //模型变换矩阵
float[] viewMatrix = getIdentityMatrix(16, 0); //观测变换矩阵/相机矩阵
float[] projectionMatrix = getIdentityMatrix(16, 0); //投影变换矩阵
//获取modelMatrix, viewMatrix, projectionMatrix
mCubeRotateAgree = (mCubeRotateAgree + 1) % 360;
Matrix.rotateM(modelMatrix, 0, mCubeRotateAgree, -1, -1, 1); //获取模型旋转变换矩阵
Matrix.setLookAtM(viewMatrix, 0, 0, 5, 10, 0, 0, 0, 0, 1, 0); //获取观测变换矩阵,设置相机位置
Matrix.frustumM(projectionMatrix, 0, -ratio, ratio, -1, 1, 3, 20); //获取透视投影变换矩阵,正交投影:Matrix.orthoM(...)
//计算MVP变换矩阵: mvpMatrix = projectionMatrix * viewMatrix * modelMatrix
float[] tempMatrix = new float[16];
float[] mvpMatrix = new float[16];
Matrix.multiplyMM(tempMatrix, 0, viewMatrix, 0, modelMatrix, 0);
Matrix.multiplyMM(mvpMatrix, 0, projectionMatrix, 0, tempMatrix, 0);
return mvpMatrix;
}
4.2 インデックスバッファの描画
//索引法绘制正方体
glDrawElements(GL_TRIANGLES, indexData.length, GL_UNSIGNED_SHORT, indexBuffer);
5. シェーダコード
シェーダー コードは実際には前の 2D 円描画と同じです。
重要なポイントを強調するためにもう一度表示します
次のように:
(1).cube_vertex_shader.glsl
#version 300 es
layout (location = 0) in vec4 vPosition;
layout (location = 1) in vec4 aColor;
uniform mat4 mvpMatrix;
out vec4 vColor;
void main() {
gl_Position = mvpMatrix * vPosition;
vColor = aColor;
}
(2).cube_fragment_shader.glsl
#version 300 es
#extension GL_OES_EGL_image_external_essl3 : require
precision mediump float;
in vec4 vColor;
out vec4 outColor;
void main(){
outColor = vColor;
}
6. 結論
以上で、3D立方体を回転させる混色実装手順の説明を終了します。
最終的な効果は、ブログ投稿の冒頭に示したとおりです。