トップページ > 過去ログ > 記事閲覧
サンプルプログラム(影表現基本)について
名前:埴輪 日時: 2012/07/27 08:58

お世話になっております。 以前、ご教授いただきましたように (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);

Page: 1 |

Re: サンプルプログラム(影表現基本)について ( No.1 )
名前:いっち 日時:2012/07/27 19:26

以下のスレッドがご参考になると思います。 > h t t p://hpcgi2.nifty.com/natupaji/bbs/patio.cgi?mode=view&no=1759
Re: サンプルプログラム(影表現基本)について ( No.2 )
名前:管理人 日時:2012/07/29 20:43

頂点バッファやインデックスバッファを使用する「シェーダーを使ったポリゴン描画」を行う関数が 無かったので追加しました、こちらに追加したバージョンをアップしましたので よろしければダウンロードしてください http://homepage2.nifty.com/natupaji/DxLib/DxLibVCTest.exe // VisualC++ 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibBCCTest.exe // BorlandC++ 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibGCC_DevCppTest.exe // Dev-C++ 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibGCC_MinGWTest.exe // MinGW 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibMakeTest.exe // ソース (中身を既存のライブラリのファイルに上書きして、BCCをお使いの 場合は『再構築』を、VCをお使いの場合は『リビルド』を、 Dev-C++をお使いの方は「Rebuild All(Ctrl+F11)」をして下さい) 追加した関数はこちらです // シェーダーを使って3Dポリゴンを描画する( 頂点バッファ使用版 ) int DrawPolygon3DToShader_UseVertexBuffer( int VertexBufHandle ) ; // シェーダーを使って3Dポリゴンを描画する( 頂点バッファとインデックスバッファ使用版 ) int DrawPolygonIndexed3DToShader_UseVertexBuffer( int VertexBufHandle, int IndexBufHandle ) ; 頂点バッファを使用しない元の関数との違いは DrawPolygonIndexed3D_UseVertexBuffer と同じで、 引数に頂点配列のアドレスや頂点の数を渡す代わりに頂点バッファハンドルやインデックスバッファハンドルを渡します もし不明な点がありましたらお訊ねください m(_ _)m
Re: サンプルプログラム(影表現基本)について ( No.3 )
名前:埴輪 日時:2012/07/31 00:00

対応ありがとうございます。 サンプルを呼んでいて 剛体メッシュとスキニングメッシュの違い、 なぜステージとキャラクタで使い分けるのか 調べてもよくわからなかったので ご教授いただけると助かります。
Re: サンプルプログラム(影表現基本)について ( No.4 )
名前:管理人 日時:2012/08/06 00:56

一つのメッシュに付き複数のフレーム(ボーン)の影響を受けるメッシュがスキニングメッシュ、 一つのメッシュが一つのフレーム(ボーン)の影響を受けるメッシュが剛体メッシュです 最近の人型モデルの作成手順は分かれ目の無い全身を一つのメッシュとして作成して、 それに対して腰、首、肩、肘、膝などのボーンを仕込んで、メッシュの各頂点がどの ボーンにどれだけの影響を受けるかを設定します( 一つの頂点が複数のボーンの影響を 受けるように設定することもできます ) そしてそれぞれのボーンを動かしてアニメーションさせるという方式ですので、 一つのメッシュ( 全身のメッシュ )が複数のボーン( フレーム )の影響を受ける、 ということでスキニングメッシュになります 逆に建物や地面などは人型モデルとは違い各オブジェクトが別々のメッシュとして作成します アニメーションさせる場合も一つのメッシュに複数のボーンを仕込むということはせず、 大抵一つのメッシュが一つのボーン( フレーム )の影響を受ける剛体メッシュになります 大は小を兼ねるという感じで剛体メッシュもスキニングメッシュとして扱うこともできますが、 一つのメッシュが複数のフレームの影響を受けるスキニングメッシュの方が負荷が高いので 一つのフレームの影響しか受けないメッシュと複数のフレームの影響を受けるメッシュで 扱いを分けています
Re: サンプルプログラム(影表現基本)について ( No.5 )
名前:埴輪(解決) 日時:2012/08/07 08:53

なるほど。そういう違いがあったのですか! わかりやすく教えていただいてありがとうございます。

Page: 1 |