Help us understand the problem. What is going on with this article?

D言語でDXライブラリを使ってD言語くんを降臨させる

More than 5 years have passed since last update.

みなさん、今日は何の日かご存じですか?
そう、イエス・キリストがこの世に降誕したと言われるクリスマスです。
それに因んでクリスマスまでのカウントダウンカレンダーをAdvent(降臨) Calendarと呼ぶ風習がキリスト教国で出来ました。
そして、その風習がエンジニアに見つかってしまった結果、12月は色々なもの[1][2]が降臨する月となりました。
このD言語 Advent Calendarもその一つです。
最終日となる今日は、D言語を書いてD言語くんを降臨させましょう

D言語くんとは

D言語の公式マスコットです。
こんな形をしています。
D

ちなみに日本語訳版サイトだとトゲトゲしい粗い画像になってます。
D言語くん

D言語くんはD Ver.0.x時代から存在しているので、おそらく後から本家の方がハイレゾに差し替わったんだと思います。
下のD言語くんが日本で広く知られている方のD言語くんの姿ですね。

三次元と化したD言語くん

D言語くんの二次元画像は昔から存在していましたが、
ポリゴンモデルは長い間ありませんでした。
ですが先週唐突に3Dモデルが誕生しました。



D言語くん

モデルもMetasequoiaフォーマット(.mqo)とMiku Miku Dance用フォーマット(.pmd)で公開されています。skydrive

今回はこれを使ってD言語くんを降臨させます。

使用ライブラリ

最初の課題

Derelict3に含まれているOpen Asset Import Library(Assimp3)GLFW3を使って実装しようかと思いましたが、非常に大きな問題がありました。

  1. .mqoと.pmdに対応していない
    なんとAssimp3は日本で圧倒的なアマチュア人気を誇るMetasequoiaとMiku Miku Danceに対応していません。
    Blender等でCOLLADAかFBXにエクスポートしてやれば使えますが、 ただただ面倒くさい(フォーマット変換が万能というわけでもないし)
  2. Assimp3→GLFW3変換が面倒
    Assimp3は多くのモデルファイルを読み込めますが、読み込むだけでOpenGL等で表示するためには更に一手間蓋手間必要となります。
    そうなるとAssimp3とGLFW3のコード量が増えD言語の記事では無くなるので今回はやめにしました。
    この記事を書こうと決めたこと自体たった5日前だし

なので今回は

  1. メタセコイア形式もMiku Miku Danceモデルも読める
  2. 高機能APIなのでサンプルコードがシンプル

DXライブラリを使ってD言語くんを表示します。
D言語はC言語とバイナリ互換なので 、C言語製のライブラリをちゃっちゃと弄ればD言語プログラムの中で関数や変数や構造体を使うことも出来ます。
今回は羽流布さんが公開しているD言語版DXライブラリ3.11を用います。vector

コードを書く

初めてDXライブラリを書いたので良く分かってませんがこういうコードでMMDモデルを表示できるみたいです。
PMDファイルとVMDファイルは事前に用意したものを置いておけば1行で読み込めるみたいです

main.d
module main;
import dx4d;
import string;
import std.file;

void main()
{
  int count, x, y;

  try
  {
    int mHandle;
    VECTOR Camera;
    dx_ChangeWindowMode(TRUE);

    if (dx_DxLib_Init() < 0 )
    {
      throw new Exception("DXライブラリの初期化に失敗");
    }

    if ((mHandle = dx_MV1LoadModel("data/Mr_D.pmd")) == -1)
    {
      throw new Exception("モデルの読み込みに失敗");
    }

    Camera.x = 0.0f;
    Camera.y = 10.0f;
    Camera.z = -20.0f;

    dx_SetBackgroundColor(0, 0, 255);
    dx_ClearDrawScreen();
    dx_SetCameraNearFar(1.0f, 150.0f);
    dx_SetCameraPositionAndTarget_UpVecY(Camera, dx_VGet(0.0f, 10.0f, 0.0f));

    if (dx_MV1AttachAnim(mHandle, 0, -1, FALSE) == -1)
    {
      throw new Exception("アニメーションの再生に失敗");
    }
    dx_MV1SetAttachAnimTime(mHandle, 0, 0.0f);

    if (dx_MV1DrawModel(mHandle) == -1)
    {
      throw new Exception("モデルの描画に失敗");
    }

    dx_WaitKey();
  }
  catch( Exception e )
  {
    std.file.write( "error.log", e.msg );
  }
  finally
  {
    dx_DxLib_End();
  }
}

できました。
スクリーンショット 0025-12-25 22.35.13.png

くぅ~疲れましたw これにて完結です!

まとめ

DXライブラリってスゴイ。初めてそう思った。

yasei_no_otoko
同人ゲームを作りつつRubyCity松江でソフトウェアエンジニアをやっています
http://www.circle-hydrangea.net
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away