【PTAM(2/3)】 PTAMにモデル描画
PTAMに目玉ではなく自分でモデルを描画してみよう。
変更するファイルはEyeGame.ccだ。
void EyeGame::DrawStuff(Vector<3> v3CameraPos) の中に描画するコードを書けばいい。
とりあえず
for(int i=0; i<4; i++)
から
glDisable(GL_TEXTURE_2D);
はコメントアウトしておこう。
glMatrixMode(GL_MODELVIEW);
の下に以下を追加。
glLineWidth(10.0f); glColor3f(1.0f, 0.0f, 0.0f); glBegin( GL_LINES ); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(100.0f, 0.0f, 0.0f); glEnd(); glColor3f(0.0f, 1.0f, 0.0f); glBegin( GL_LINES ); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(0.0f, 100.0f, 0.0f); glEnd(); glColor3f(0.0f, 0.0f, 1.0f); glBegin( GL_LINES ); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(0.0f, 0.0f, 100.0f); glEnd();
ここでの座標系は、右方向にX軸、奥行き方向にY軸、上方向にZ軸だとわかる。
右手系のようだ。
これだけでは面白くないので、MMD(MikuMikuDance)モデルを描画してみよう。
ARTK_MMD (http://ppyy.if.land.to/)
- artk_mmd_src_no_bullet.zipをダウンロード。
- \ARTK_MMD_src\Src\MMD を丸ごとC:\PTAM\includeへ。
- PTAMプロジェクトに、C:\PTAM\include\MMD 内の全ファイルを追加
- このライブラリ内のMatrixクラスの名前が他のライブラリとぶつかってしまうので、MMD_Matrixとでも全置換しておこう。
- C:\PTAM\model に適当なMMDモデルを入れておく
- C:\PTAM\motion に適当なモーションファイルを入れておく
EyeGame.ccを以下に差し替え。
#include "EyeGame.h" #include "OpenGL.h" #include <cvd/convolution.h> #include <mmsystem.h> #include "MMD/PMDModel.h" #include "MMD/VMDMotion.h" using namespace CVD; cPMDModel g_clPMDModel; cVMDMotion g_clVMDMotion; float g_fPrevFrame = 0.0f; DWORD g_dwStartTime = 0; EyeGame::EyeGame() { mbInitialised = false; SetCurrentDirectory( "C:\\PTAM\\Model" ); g_clPMDModel.load("C:\\PTAM\\Model\\初音ミク.pmd"); g_clVMDMotion.load("C:\\PTAM\\motion\\適当なモーションファイル.vmd"); g_clPMDModel.setMotion( &g_clVMDMotion, true ); g_dwStartTime = timeGetTime(); g_fPrevFrame = 0.0f; } void EyeGame::DrawStuff(Vector<3> v3CameraPos) { if(!mbInitialised) Init(); mnFrameCounter ++; DWORD time; float fDiffFrame; time = timeGetTime() - g_dwStartTime; fDiffFrame= (float)time / 30.0f - g_fPrevFrame; g_clPMDModel.updateMotion(fDiffFrame); g_clPMDModel.updateSkinning(); g_fPrevFrame += fDiffFrame; glEnable( GL_CULL_FACE ); glEnable( GL_ALPHA_TEST ); glEnable( GL_BLEND ); glFrontFace(GL_CW); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_NORMALIZE); GLfloat af[4]; af[0]=0.7; af[1]=0.7; af[2]=0.7; af[3]=1.0; glLightfv(GL_LIGHT0, GL_AMBIENT, af); glLightfv(GL_LIGHT0, GL_DIFFUSE, af); af[0]=1.0; af[1]=-2.0; af[2]=1.0; af[3]=0.0; glLightfv(GL_LIGHT0, GL_POSITION, af); af[0]=1.0; af[1]=1.0; af[2]=1.0; af[3]=1.0; glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, af); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 50.0); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glScalef( 0.05f, 0.05f, -0.05f); glRotatef(-90.0, 1.0, 0.0, 0.0); g_clPMDModel.render(); glPopMatrix(); glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); }; void EyeGame::Reset() { mnFrameCounter = 0; g_dwStartTime = timeGetTime(); g_fPrevFrame = 0.0f; g_clPMDModel.setMotion( &g_clVMDMotion, true ); }; void EyeGame::Init() { if(mbInitialised) return; mbInitialised = true; };
ね、簡単でしょ!