お世話になっております。
以前、ご教授いただきましたように
(hpcgi2.nifty.com/natupaji/bbs/patio.cgi?mode=view&no=2694)
DrawPolygonIndexed3D_UseVertexBuffer()を用いての描画を行っております。
また、MV1DrawModel()によるモデル描画も少し行っています。
レースゲームなのですが、
コースの地面は、DrawPolygonIndexed3D_UseVertexBuffer()で、
車体モデルをMV1DrawModel()で描画しています。
やはり影を付けたいと思って
homepage2.nifty.com/natupaji/DxLib/program/dxprogram_3DAction_DepthShadow.html
(とそこにあるサンプル)を拝見したのですが、
キャラクタもステージもモデルになっていますよね。
リファレンスの方では、DrawPolygon2DToShader()
を使用していますが、このまま
DrawPolygonIndexed3D_UseVertexBuffer()は使えないのでしょうか。
よろしくお願いします。
関連部分のソースを抜粋してみました。
//コースの一部分(これを数十個描画してコースを形成しています。)
class CPart
{
public:
VERTEX3D vertex[DIV];
VECTOR center;//そのパーツの中心座標
VECTOR block[2];//block[0]は各成分の最小値、block[1]は最大値
int vtx_buffer;//頂点バッファのハンドル
};
class CMachine
{
public:
int model,fmodel;//f〜はアフターバーナー用(本体とは別で加算ブレンド描画をする)
VECTOR pos,incline;
int place;//どのパーツ上にいるか。
double dist;
double angle,speed;
CFire *fire;//アフターバーナー用テクスチャを生成するクラス
CMachine(char *modelfile,char *fmodelfile)
{
model=MV1LoadModel(modelfile);
fmodel=MV1LoadModel(fmodelfile);
MV1SetWriteZBuffer(fmodel,false);
pos=VGet(0,0,0);
incline=VGet(0,1,0);
angle=speed=0.0;
gfire=MakeScreen(64,64);
}
void CMachine::Draw(CCourse *course)
{
MATRIX rotate=GetMatrix4Machine(this,course);
MV1SetMatrix(model,rotate);
MV1SetMatrix(fmodel,rotate);
MV1SetTextureGraphHandle(fmodel,0,gfire,false);
MV1SetMaterialDrawBlendMode(fmodel,0,DX_BLENDMODE_ADD);
MV1SetMaterialDrawBlendParam(fmodel,0,255);
MV1DrawModel(model);
MV1DrawModel(fmodel);
}
};
//コースは内側に反ったものなので、直線か曲線か、や向きによって
//場合分けをして、描画用の行列を生成します。
MATRIX GetMatrix4Machine(CMachine *machine,CCourse *course)
{
VECTOR axis,axis2;
double dist,incline;
double offset;
for(int i=0;i<=course->Npart;i++)
{
if(i==course->Npart)
{
machine->courseout=1;
break;
}
machine->place=i;
if(course->part[i].block[1].y-1 < machine->pos.y || course->part[i].block[0].y-1 < machine->pos.y)
{
if(course->part[i].block[1].x < machine->pos.x && machine->pos.x < course->part[i].block[0].x)
{
if(course->part[i].block[1].z < machine->pos.z && machine->pos.z < course->part[i].block[0].z)
{
if(course->part[i].type!=0)//曲線
{
VECTOR rpos=VSub(machine->pos,course->part[i].center);
double a=atan2(rpos.z,rpos.x);
dist=sqrt(rpos.x*rpos.x + rpos.z*rpos.z)-(course->part[i].type%2==0 ? 5.0 : 15.0);
incline=-atan2(4.0*pow(dist*1.25,3.0)/512.0,1);
axis=VNorm(VGet(cos(a)*sin(incline),1.0,sin(a)*sin(incline)));
axis2=VGet(0,1,0);
if(machine->courseout==0)machine->pos.y=course->part[i].block[0].y;
}
else
{
axis2=VGet(0,1,0);
double cs=cos(course->part[i].angle);
if(fabs(cs)>0.9)
{
dist=course->part[i].center.x-machine->pos.x;
incline=atan2(4.0*pow(dist*1.25,3.0)/512.0,1);
axis=VGet(-cos(incline+Pi/2.0),1.0,0.0);
double slope=course->part[i].block[1].y-course->part[i].block[0].y;
double adv=machine->pos.z-course->part[i].center.z;
if(machine->courseout==0)
{
if(cs>0.9)
{
if(fabs(course->part[i].block[0].y-course->part[i].center.y)<0.1)
{
machine->pos.y=slope*adv/10.0+course->part[i].block[0].y;
if(fabs(course->part[i].block[0].y-course->part[i].block[1].y)>INCLINE/2)axis2=VGet(0,1,INCLINE);
}
else
{
machine->pos.y=-slope*adv/10.0+course->part[i].block[1].y;
if(fabs(course->part[i].block[0].y-course->part[i].block[1].y)>INCLINE/2)axis2=VGet(0,1,-INCLINE);
}
}
else
{
if(fabs(course->part[i].block[0].y-course->part[i].center.y)<0.1)
{
machine->pos.y=-slope*adv/10.0+course->part[i].block[0].y;
if(fabs(course->part[i].block[0].y-course->part[i].block[1].y)>INCLINE/2)axis2=VGet(0,1,-INCLINE);
}
else
{
machine->pos.y=slope*adv/10.0+course->part[i].block[1].y;
if(fabs(course->part[i].block[0].y-course->part[i].block[1].y)>INCLINE/2)axis2=VGet(0,1,INCLINE);
}
}
}
}
else
{
dist=course->part[i].center.z-machine->pos.z;
incline=atan2(4.0*pow(dist*1.25,3.0)/512.0,1);
axis=VGet(0.0,1.0,-cos(incline+Pi/2.0));
double slope=course->part[i].block[1].y-course->part[i].block[0].y;
double adv=machine->pos.x-course->part[i].center.x;
if(machine->courseout==0)
{
if(sin(course->part[i].angle)>0.9)
{
if(fabs(course->part[i].block[0].y-course->part[i].center.y)<0.1)
{
machine->pos.y=-slope*adv/10.0+course->part[i].block[0].y;
if(fabs(course->part[i].block[0].y-course->part[i].block[1].y)>INCLINE/2)axis2=VGet(-INCLINE,1,0);
}
else
{
machine->pos.y=slope*adv/10.0+course->part[i].block[1].y;
if(fabs(course->part[i].block[0].y-course->part[i].block[1].y)>INCLINE/2)axis2=VGet(INCLINE,1,0);
}
}
else
{
if(fabs(course->part[i].block[0].y-course->part[i].center.y)<0.1)
{
machine->pos.y=slope*adv/10.0+course->part[i].block[0].y;
if(fabs(course->part[i].block[0].y-course->part[i].block[1].y)>INCLINE/2)axis2=VGet(INCLINE,1,0);
}
else
{
machine->pos.y=-slope*adv/10.0+course->part[i].block[1].y;
if(fabs(course->part[i].block[0].y-course->part[i].block[1].y)>INCLINE/2)axis2=VGet(-INCLINE,1,0);
}
}
}
}
}
if(fabs(dist)<=4.8)
{
offset=pow(dist*1.25,4.0)/512.0*cos(incline);
MATRIX ret;
ret=MGetRotY(machine->angle+Pi);
ret=MMult(ret,MGetScale(VGet(MACHINE_ZOOM,MACHINE_ZOOM,MACHINE_ZOOM)));
ret=MMult(ret,MGetTranslate(VGet(0,offset,0)));
ret=MMult(ret,MGetRotVec2(VGet(0,1,0),axis2));
ret=MMult(ret,MGetRotVec2(VGet(0,1,0),axis));
ret=MMult(ret,MGetTranslate(machine->pos));
machine->courseout=0;
machine->dist=dist;
return ret;
}
}
}
}
}
MATRIX ret;
ret=MGetRotY(machine->angle+Pi);
ret=MMult(ret,MGetScale(VGet(MACHINE_ZOOM,MACHINE_ZOOM,MACHINE_ZOOM)));
ret=MMult(ret,MGetTranslate(machine->pos));
return ret;
}
//メインループ内抜粋
GetMatrix4Machine(machine[0],course);
if(machine[0]->courseout==0)cam_target=VAdd(machine[0]->pos,VGet(cos(-machine[0]->angle-Pi/2.0)*3.0,1.5,3.0*sin(-machine[0]->angle-Pi/2.0)));
SetCameraPositionAndTarget_UpVecY(cam_target,VAdd(machine[0]->pos,VGet(0,0.5,0)));
VECTOR view=VAdd(machine[0]->pos,VGet(cos(-machine[0]->angle-Pi/2.0)*20.0,1.5,20.0*sin(-machine[0]->angle-Pi/2.0)));
for(int i=0;i<course->Npart;i++)
{
DrawPolygonIndexed3D_UseVertexBuffer(course->part[i].vtx_buffer,ib,G,false);//コース描画
}
for(int i=0;i<NMachine;i++)machine[i]->Draw(course);