Direct 3D で Torus を描画する

Command Line の環境で Direct 3D で Torus を回転しながら描画します。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プロジェクトの設定

  1. C++/CLI で Direct 3D で Torus を回転しながら描画します。
    VC++ のプロジェクトで作成すると非常に多くのファイルが自動的に作成されるのですが、今回作成するファイルは dxtorus.cpp の一本だけです。
    コンパイルと実行の方法は Command Line から DirectX を動かす を参照して下さい。
    ファイル名 説明
    DXTorus.cpp Torus を描画
  2. #using で実行に必要な DLL(Dynamic Link Library) をリンクします。
    using namespace は名前空間の設定で、修飾しなくても Class を参照できるようにしています。
        #using <System.dll>
        #using <System.Windows.Forms.dll>
        #using <System.Drawing.dll>
        #using <Microsoft.DirectX.dll>
        #using <Microsoft.DirectX.Direct3D.dll>
        #using <Microsoft.DirectX.Direct3DX.dll>
    
        using namespace System;
        using namespace System::Windows::Forms;
        using namespace System::Drawing;
        using namespace Microsoft::DirectX;
        using namespace Microsoft::DirectX::Direct3D;
        
  3. D3DModel は Direct 3D のフォーム(Window) を生成するクラスです。
    ^device は Direct 3D のデバイスで ^ はポインタを意味します。
    ^mesh にはトーラスのメッシュ(3Dモデル)を格納します。
    pause はウインドウが描画できる状態か否かのフラグです。
    device と mesh に初期値として null を設定しています。
    this->ClientSize に Form の大きさを設定します。
    this->Text は caption の設定です。
        ref class D3DModel : public System::Windows::Forms::Form
        {
            Microsoft::DirectX::Direct3D::Device  ^device;      // rendering device
            Microsoft::DirectX::Direct3D::Mesh    ^mesh;        // mesh object
            bool pause;
    
          public:
            // Constructor
            D3DModel()
            {
                device = nullptr;
                mesh = nullptr;
                pause = false;
                // Window のサイズを設定
                this->ClientSize = System::Drawing::Size(400,400);
                // caption の設定
                this->Text = "Direct3D Model";
            }
        
  4. Direct 3D の初期化を行う InitializeGraphics() メソッドです。
    ^presentParams にパラメータを設定して gcnew Device() でデバイスを生成します。
    DeviceReset にイベントハンドラを設定します。
    OnResetDevice() メソッドでトーラスをロードして、描画の準備を整えます。
    pause を false にして準備完了です。
        bool InitializeGraphics()
        {
            PresentParameters ^presentParams = gcnew PresentParameters();
            presentParams->Windowed = true;
            presentParams->SwapEffect = SwapEffect::Discard;
            presentParams->EnableAutoDepthStencil = true;
            presentParams->AutoDepthStencilFormat = DepthFormat::D16;
    
            // Create the D3DDevice
            device = gcnew Device(0, DeviceType::Hardware, this, CreateFlags::SoftwareVertexProcessing, presentParams);
            if (device==nullptr)
            {   MessageBox::Show("Create Direct3D Device Error.");
                return false; 
            }
            device->DeviceReset += gcnew System::EventHandler(this, &D3DModel::OnResetDevice);
            this->OnResetDevice(device, nullptr);
            pause = false;
            return true;
        }
        
  5. トーラスをロードして、描画の準備をする OnResetDevice() メソッドです。
    3Dモデルをレンダリングするために ZBuffer を true にして、Lighting を設定します。
        void OnResetDevice(Object^ sender, EventArgs^ e)
        {
            device->RenderState->ZBufferEnable = true;  // Turn on the zbuffer
            device->RenderState->Lighting = true;       // make sure lighting is enabled
            //☆ トーラスメッシュの生成
            mesh = Mesh::Torus(device, 16.0f, 40.0f, 32, 32);
        }
        
  6. 描画環境を設定する SetupMatrices() メソッドです。
    ワールド座標をY軸を中心に回転しながら描画します。
    View で View 座標(カメラの座標)を設定します。
    Projection でレンダリング環境を設定します。
        void SetupMatrices()
        {
            device->Transform->World = Matrix::RotationY(Environment::TickCount / 1000.0f);
            device->Transform->View = Matrix::LookAtLH(Vector3(0.0f, 3.0f, -200.0f),
                    Vector3(0.0f, 0.0f, 0.0f), Vector3(0.0f, 1.0f, 0.0f));
            device->Transform->Projection = Matrix::PerspectiveFovLH((float)(Math::PI/4), 1.0f, 1.0f, 500.0f);
        }
        
  7. 光源を設定する SetupLights() メソッドです。
    光源の色と座標を設定します。
    Yellow でモデルの色が決まります。
    DarkTurquoise や Red に変えて試してみて下さい。
        void SetupLights()
        {
            System::Drawing::Color col = System::Drawing::Color::White;
            Direct3D::Material mtrl = Direct3D::Material();
            mtrl.Diffuse = col;
            mtrl.Ambient = col;
            device->Material = mtrl;
    
            device->Lights[0]->Type = LightType::Directional;
            device->Lights[0]->Diffuse = System::Drawing::Color::Yellow;
            //device->Lights[0]->Diffuse = System::Drawing::Color::DarkTurquoise;
            //device->Lights[0]->Diffuse = System::Drawing::Color::Red;
            //☆ ライトの座標を設定する
            device->Lights[0]->Direction = Vector3(50.0f, -40.0f, 100.0f);
            device->Lights[0]->Enabled = true;
            device->RenderState->Ambient = System::Drawing::Color::FromArgb(0x202020);
        }
        
  8. モデルを描画する Render メソッドです。
    Clear でウインドウと ZBuffer をクリアします。
    SetupLights() と SetupMatrices() でライトとマテリアルを設定します。
    mesh->DrawSubset(0) でトーラスを描画します。
        void Render()
        {
            if (device==nullptr)    return;
            if (pause)              return;
    
            device->Clear(ClearFlags::Target | ClearFlags::ZBuffer, System::Drawing::Color::Blue, 1.0f, 0);
            device->BeginScene();
    
            // Rendering of scene objects can happen here
            SetupLights();
            SetupMatrices();
            mesh->DrawSubset(0);
    
            device->EndScene();
            device->Present();
        }
        
  9. 後は、全ソースコードを参照して下さい。
    プログラムを実行するとトーラスが回転しながら描画されます。
    C# でも同様のプログラムを作成しています。
    「超初心者のプログラム入門(C#)/トーラスをライトで照らして描画する」を参照して下さい。
    トーラスをライトで照らして描画する

超初心者のプログラム入門(C/C++)