トップページ > 記事閲覧
3Dモデルの表示について
名前:しょしんしゃまる 日時: 2019/10/14 23:56

初めましてしょしんしゃまると申します。 DXライブラリの3Dサンプルプログラムを使ってゲーム制作の練習をしています。 しかし、モデルの表示がうまくいかず出鼻をくじかれてしまいました。 どのような状態かというと、 一瞬正常にモデルが表示されるのですが、次の更新(?)でモデルの一部分が表示されない状態です。 ブレークポイントで調べてみたら、ScreenFlip()を通過したら表示が崩れてしまうことまでは分かりました。 しかし、その後どのように修正したらいいのか分からず困っています。 解決方法を教えていただきたく書き込みをさせていただきました。ご回答宜しくお願い致します。 下記はプログラムのコードです。 #include "DxLib.h" #include <math.h> //スクリーンサイズ #define SCREEN_W 1920 #define SCREEN_H 1080 // 移動速度 #define MOVESPEED 10.0f // DxChara.x での走りアニメーションの番号 #define ANIM_RUN 1 // カメラの回転速度 #define CAMERA_ANGLE_SPEED 3.0f // カメラの注視点の高さ #define CAMERA_LOOK_AT_HEIGHT 60.0f // カメラと注視点の距離 #define CAMERA_LOOK_AT_DISTANCE 70.0f // ラインを描く範囲 #define LINE_AREA_SIZE 10000.0f // ラインの数 #define LINE_NUM 50 int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { int ModelHandle; VECTOR Position; int MoveFlag; float Angle; float CameraHAngle; float CameraVAngle; VECTOR MoveVector; float SinParam; float CosParam; float x = 0.1f; float y = 2000.0f; // 白の色コードを保存 unsigned int Cr = GetColor(255, 255, 255); int MaterialNum; float DotWidth; // ウインドウモードで起動 ChangeWindowMode(TRUE); // 画面モードのセット SetGraphMode(SCREEN_W, SCREEN_H, 32); // 描画先を裏画面にする SetDrawScreen(DX_SCREEN_BACK); // DXライブラリの初期化 if (DxLib_Init() == -1) return -1; // 3Dモデルの読み込み ModelHandle = MV1LoadModel("Img/MMD/Yuko/有子(ローポリver1.01).pmx"); // カメラの向きを初期化 CameraHAngle = 0.0f; CameraVAngle = -60.0f; // 向きを初期化 Angle = 0.0f; // 3Dモデルの座標を初期化 Position = VGet(0.0f, 0.0f, 0.0f); // 3Dモデルのスケールを2.5倍にする MV1SetScale(ModelHandle, VGet(2.5f, 2.5f, 2.5f)); // 背景の色を灰色にする SetBackgroundColor(128, 128, 128); // Zバッファを有効にする。 SetUseZBuffer3D(TRUE); // Zバッファへの書き込みを有効にする。 SetWriteZBuffer3D(TRUE); //奥行0.1〜1000までをカメラの描画範囲とする SetCameraNearFar(10.0f, 1200.0f); // メインループ(何かキーが押されたらループを抜ける) while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0) { // 画面のクリア ClearDrawScreen(); // 移動ベクトルを初期化 MoveVector = VGet(0.0f, 0.0f, 0.0f); // 位置関係が分かるように地面にラインを描画する { VECTOR Pos1; VECTOR Pos2; SetUseZBufferFlag(TRUE); Pos1 = VGet(-LINE_AREA_SIZE / 2.0f, 0.0f, -LINE_AREA_SIZE / 2.0f); Pos2 = VGet(-LINE_AREA_SIZE / 2.0f, 0.0f, LINE_AREA_SIZE / 2.0f); for (int i = 0; i <= LINE_NUM; i++) { DrawLine3D(Pos1, Pos2, GetColor(255, 255, 255)); Pos1.x += LINE_AREA_SIZE / LINE_NUM; Pos2.x += LINE_AREA_SIZE / LINE_NUM; } Pos1 = VGet(-LINE_AREA_SIZE / 2.0f, 0.0f, -LINE_AREA_SIZE / 2.0f); Pos2 = VGet(LINE_AREA_SIZE / 2.0f, 0.0f, -LINE_AREA_SIZE / 2.0f); for (int i = 0; i < LINE_NUM; i++) { DrawLine3D(Pos1, Pos2, GetColor(255, 255, 255)); Pos1.z += LINE_AREA_SIZE / LINE_NUM; Pos2.z += LINE_AREA_SIZE / LINE_NUM; } SetUseZBufferFlag(TRUE); } // 方向入力に従ってキャラクターの移動ベクトルと向きを設定 if (CheckHitKey(KEY_INPUT_LEFT) == 1) { Angle = 90.0f - CameraHAngle; MoveFlag = TRUE; MoveVector.x = -MOVESPEED; } if (CheckHitKey(KEY_INPUT_RIGHT) == 1) { Angle = -90.0f - CameraHAngle; MoveFlag = TRUE; MoveVector.x = MOVESPEED; } if (CheckHitKey(KEY_INPUT_DOWN) == 1) { Angle = 0.0f - CameraHAngle; MoveFlag = TRUE; MoveVector.z = -MOVESPEED; } if (CheckHitKey(KEY_INPUT_UP) == 1) { Angle = 180.0f - CameraHAngle; MoveFlag = TRUE; MoveVector.z = MOVESPEED; } // 移動した場合は、カメラの水平角度を考慮した方向に座標を移動する if (MoveFlag == TRUE) { VECTOR TempMoveVector; // カメラの角度に合わせて移動ベクトルを回転してから加算 SinParam = (float)sin(CameraHAngle / 180.0f * DX_PI_F); CosParam = (float)cos(CameraHAngle / 180.0f * DX_PI_F); TempMoveVector.x = MoveVector.x * CosParam - MoveVector.z * SinParam; TempMoveVector.y = 0.0f; TempMoveVector.z = MoveVector.x * SinParam + MoveVector.z * CosParam; Position = VAdd(Position, TempMoveVector); } // 新しい向きをセット MV1SetRotationXYZ(ModelHandle, VGet(0.0f, Angle / 180.0f * DX_PI_F, 0.0f)); // 3Dモデルに新しい座標をセット MV1SetPosition(ModelHandle, Position); // カメラの位置と向きを設定 { VECTOR TempPosition1; VECTOR TempPosition2; VECTOR CameraPosition; VECTOR CameraLookAtPosition; // 注視点はキャラクターモデルの座標から CAMERA_LOOK_AT_HEIGHT 分だけ高い位置 CameraLookAtPosition = Position; CameraLookAtPosition.y += CAMERA_LOOK_AT_HEIGHT; // カメラの位置はカメラの水平角度と垂直角度から算出 // 最初に垂直角度を反映した位置を算出 SinParam = (float)sin(CameraVAngle / 180.0f * DX_PI_F); CosParam = (float)cos(CameraVAngle / 180.0f * DX_PI_F); TempPosition1.x = 0.0f; TempPosition1.y = (SinParam * CAMERA_LOOK_AT_DISTANCE) + 55; TempPosition1.z = (-CosParam * CAMERA_LOOK_AT_DISTANCE) - 100; // 次に水平角度を反映した位置を算出 SinParam = (float)sin(CameraHAngle / 180.0f * DX_PI_F); CosParam = (float)cos(CameraHAngle / 180.0f * DX_PI_F); TempPosition2.x = CosParam * TempPosition1.x - SinParam * TempPosition1.z; TempPosition2.y = TempPosition1.y; TempPosition2.z = SinParam * TempPosition1.x + CosParam * TempPosition1.z; // 算出した座標に注視点の位置を加算したものがカメラの位置 CameraPosition = VAdd(TempPosition2, CameraLookAtPosition); // カメラの設定に反映する SetCameraPositionAndTarget_UpVecY(CameraPosition, CameraLookAtPosition); } // マテリアルの数を取得 MaterialNum = MV1GetMaterialNum(ModelHandle); for (int i = 0; i < MaterialNum; i++) { // マテリアルの元々の輪郭線の太さを取得 DotWidth = MV1GetMaterialOutLineDotWidth(ModelHandle, i); // マテリアルの輪郭線の太さを2.5にする MV1SetMaterialOutLineDotWidth(ModelHandle, i, DotWidth / 2.5f); } // 3Dモデルの描画 MV1DrawModel(ModelHandle); // 裏画面の内容を表画面に反映 ScreenFlip(); } // モデルの削除 MV1DeleteModel(ModelHandle); // DXライブラリの後始末 DxLib_End(); // ソフトの終了 return 0; }
メンテ

Page: 1 |

Re: 3Dモデルの表示について ( No.1 )
名前:管理人 日時:2019/10/15 00:44

SetDrawScreen は DxLib_Init を呼び出す前に実行しても効果がありませんので、 // 描画先を裏画面にする SetDrawScreen(DX_SCREEN_BACK); を DxLib_Init より後に実行するようにしてみてください m(_ _)m
メンテ
Re: 3Dモデルの表示について ( No.2 )
名前:B.E 日時:2019/10/15 02:00

ちょっと気になったので横から失礼します。 MV1SetMaterialOutLineDotWidthは一回呼べば大丈夫なので、 // マテリアルの数を取得 MaterialNum = MV1GetMaterialNum(ModelHandle); for (int i = 0; i < MaterialNum; i++) { // マテリアルの元々の輪郭線の太さを取得 DotWidth = MV1GetMaterialOutLineDotWidth(ModelHandle, i); // マテリアルの輪郭線の太さを2.5にする MV1SetMaterialOutLineDotWidth(ModelHandle, i, DotWidth / 2.5f); } はモデルを読み込んだ後〜メインループの前のどこかに移動したほうがいいと思います。 『MV1GetMaterialOutLineDotWidth』は3Dモデルのオリジナルの輪郭線の太さが返ってくるのではなく、 『MV1SetMaterialOutLineDotWidth』で指定した現在の太さが返ってくるようなので、 メインループの中に入れると線の太さを毎フレーム変える事になるので、 上記のように『/2.5f』をし続けると、あっとうまに数値が『0』になってしまいます。 あと、MoveFlagが初期化されずに使用されてしまう可能性があるのと、 一度『TRUE』になると『FALSE』にならずにif文の意味が無くなってしまうので、 『MoveFlag = FALSE;』をClearDrawScreen();の次の行辺りに追加したほうがいいと思います。
メンテ
Re: 3Dモデルの表示について ( No.3 )
名前:しょしんしゃまる 日時:2019/10/16 18:37

管理人様 返信が遅くなり申し訳ありません。 無事きちんと表示されました。 ありがとうございます!お世話になりました。
メンテ
Re: 3Dモデルの表示について ( No.4 )
名前:しょしんしゃまる 日時:2019/10/16 18:40

B.E様 マテリアルの線についてとても詳しくアドバイスありがとうございます。 ループではなくてよかったのですね汗 大変勉強になりました。 フラグも忘れていたのでご指摘ありがとうございます。 小さな抜けがないように気をつけていきます!
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存