Direct3D と OpenGL は座標系が違います。
そのためデータの Exporter を作るときは、どのプラットフォームにも対応できるよう
いつも両対応で作っています。
Direct3D から見ると両対応は簡単です。
というのも、Maya や XSI など多くのツールが OpenGL の右手座標系なので、
D3D の左手系に合わせるにはもともと座標系の変換処理が必要だからです。
OpenGL に対応するには反転しなければ良いだけ。
ただ OpenGLES 2.0 の場合ジオメトリもライティングもシェーダーだけで行いますし
演算式も任意です。汎用化された GPU では実装に任されているので、座標系の
違いをあまり意識しなくても良いのかもしれません。
普段使っているライブラリやシェーダーを流用することを考えて、Direct3D の
左手座標系でそのまま使ってみました。いつもの感覚でシェーダーやマトリクスの
セットを行っていたら自然にそうなりました。
OpenGL の場合も Depth Buffer の初期値はデフォルトで 1.0 を設定するようです。
比較関数も初期値は GL_LESS なので D3D と違いはありません。
Matrix の設定もモデルデータもシェーダーも D3D と同じパラメータで良いようです。
唯一変更したのは下記の設定のみ。
デフォルトは GL_CCW なので GL から見るとカリングが逆になります。
glFrontFace( GL_CW );
あとはデータもシェーダーも matrix も D3D 互換で使えます。
シェーダーはまだ GLSL のテストをしている状態です。
アニメーションはまだ未確認。
// vsh
uniform mat4 pmatrix;
attribute vec3 vposition;
attribute vec3 vnormal;
attribute vec2 vtexcoord;
varying vec4 ocolor;
varying vec2 otexcoord;
void main()
{
gl_Position= pmatrix * vec4( vposition.xyz, 1 );
vec3 lightdir= vec3( 0.0, 0.0, -1.0 );
ocolor= vec4( 1.0, 1.0, 1.0, 1.0 ) * clamp( dot( vnormal, lightdir ), 0.0, 1.0 ) + 0.2;
otexcoord= vtexcoord;
}
// fsh
precision mediump float;
varying vec4 ocolor;
varying vec2 otexcoord;
uniform sampler2D texture0;
void main()
{
vec4 tcol= texture2D( texture0, otexcoord );
gl_FragColor= ocolor * tcol;
}
// cpp
struct v_type3 {
float x, y, z;
};
struct v_type2 {
float x, y;
};
static const v_type3 vdata_p[]= {
{ -1.0f, 1.0f, 0.0f, },
{ 1.0f, 1.0f, 0.0f, },
{ -1.0f, -1.0f, 0.0f, },
{ 1.0f, -1.0f, 0.0f, },
};
static const v_type3 vdata_n[]= {
{ 0.0f, 0.0f, -1.0f, },
{ 0.0f, 0.0f, -1.0f, },
{ 0.0f, 0.0f, -1.0f, },
{ 0.0f, 0.0f, -1.0f, },
};
static const v_type2 vdata_t[]= {
{ 0.0f, 0.0f, },
{ 1.0f, 0.0f, },
{ 0.0f, 1.0f, },
{ 1.0f, 1.0f, },
};
glVertexAttribPointer( attr_vposition, 3, GL_FLOAT, GL_FALSE, sizeof(v_type3), vdata_p );
glVertexAttribPointer( attr_vnormal, 3, GL_FLOAT, GL_FALSE, sizeof(v_type3), vdata_n );
glVertexAttribPointer( attr_vtexcoord, 2, GL_FLOAT, GL_FALSE, sizeof(v_type2), vdata_t );
glEnableVertexAttribArray( attr_vposition );
glEnableVertexAttribArray( attr_vnormal );
glEnableVertexAttribArray( attr_vtexcoord );
static unsigned short idata[]= {
0, 1, 2,
2, 1, 3,
};
MatrixF projection;
MatrixF view;
MatrixF world;
projection.SetProjection( ScreenWidth, ScreenHeight, 1.0f, 5000.0f, DEGtoRAD( 30.0f ) );
view.SetIdentity();
view.Translation( 0.0f, 0.0f, 20.0f );
world.SetIdentity();
world.RotationY( rotang );
MatrixF mat;
mat.Mul( projection, view );
mat.Mul( world );
glUniformMatrix4fv( attr_pmatrix, 1, GL_FALSE, &mat._11 );
glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, idata );
関連エントリ
・OpenGLES2.0 シェーダー管理