wacchoz’s note

プログラミングとか数学について

【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();

f:id:wacchoz:20181106225351j:plain

ここでの座標系は、右方向にX軸、奥行き方向にY軸、上方向にZ軸だとわかる。
右手系のようだ。



これだけでは面白くないので、MMDMikuMikuDance)モデルを描画してみよう。

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;
};

ね、簡単でしょ!
f:id:wacchoz:20181106225711j:plain