3D研究室

Back to Title Page(OpenLab)タイトルページへ戻る

最終更新日: 1999年 04月 07日 水曜日

ダイアログボックスでも3Dを

 3D研究室へようこそ。ようやく公開できる程度のコードを作成 しましたので早速公開開始することにします。

 今回は、Direct3DRMのエミュレーションモードを使用した ワイヤーフレーム三角形の表示をダイアログボックス内のコントロールに 張り付け表示を行う基本プログラムです。

 今回あえてダイアログボックス形式を選んだのは、多くのサンプル プログラムが標準的なWindowを使用してチャイルドWindows などで表示するサンプルは発表していますが、ダイアログボックスに対し て行っている物はなく、ダイアログボックス形式なら、機能の拡張テスト やパラメータの変更を直感的にインプリメントしやすいため最近の私の ソフトのほとんどはダイアログボックス形式を使用しています。また、 MFCのダイアログボックス形式実行ファイルの作成は新規作成にて 簡単に行えるため、MFCからのDirect3Dの利用をよりはっきり 際だたせることになると思います。

 今回使用しているソースコードのすべてはこちらからダウンロードできます。必要な環境は、

Visual C++ 6.0 Professional Edition
作成時にはVisual Studio 6.0 Enterprizeで行いましたが VC++ 6.0 Proで十分です。
DirectX SDK 6.0 以降
DirectX SDK 6.1 をお勧めします。コンパイラー・リンカーがSDKに含まれる
ヘッダーファイル及びライブラリーを適切に見つけられるようにしておいてください。

 

 サンプルコードを以下に記載しておきます。手動で手を加えた主なところはで表しておきます。ソースコードとにらめっこするときに参考にしてください。

 今回MFCからの利用を前提にして作成しましたので、ソースコードの理解よりもMFCで生成した初期コードへの組み込みやすさを重視したため、行った作業のほとんどはクラスの中で自動的に行われています。特に初期化部分は重要で、今回の課題の一つでした。
 ソースコード自体の読みやすさや汎用性はまだまだこれからのソースですが、Direct3DRMを利用してみようというかたの参考になることと思います。

 よくDirectXはMFCとは会わないからWin32APIの標準Windowで作成すべきだと云う声も聞きますが、MFCの生産効率のよさをかんがえるとMicrosoftが正式にMFCにDirectXを組み込まないからといって利用することがいけないことはないでしょう。実際、DirectXの進歩は早く、MFCの進化よりも早いペースで行われるためMFCに組み込むことが難しいのかもしれません。それでもMFCとDirectXを協調してりようするととても優れたアプリケーションが作成できそうですし、実際MFCを全く使用しないアプリケーション+DirectXよりも開発時間は短縮されることと思います。
 一昔前と異なり、CPUやグラフィクスボードなどのパフォーマンスが飛躍的に上がってきたため、MFCの様に重たいコードを出しやすいものであってもなかなか快適に動作するようになってきましたからもっと積極的に利用しても良いと思います。

 くわしくは、実際にコンパイルして実行しながらソースを眺めてみてください。

 D3D部分については本当に最低限ぐらいしかコードを書いていませんが、それゆえまだ理解しやすい事と思います。実用化はこれからですが...

 具体的なインプリメント例としてソースコードを掲載しておきます。

 

// Test01Dlg.cpp : インプリメンテーション ファイル
//

#include "stdafx.h"
#include "Test01.h"
#include "Test01Dlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CTest01Dlg ダイアログ


CTest01Dlg::CTest01Dlg(CWnd* pParent /*=NULL*/)
    : CDialog(CTest01Dlg::IDD, pParent)
{
    //{{AFX_DATA_INIT(CTest01Dlg)
        // メモ: この位置に ClassWizard によってメンバの初期化が追加されます。
    //}}AFX_DATA_INIT
    // メモ: LoadIcon は Win32 の DestroyIcon のサブシーケンスを要求しません。
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    c3c = NULL;
}

void CTest01Dlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CTest01Dlg)
    DDX_Control(pDX, IDC_STATIC_WINDOW, m_window);
    //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CTest01Dlg, CDialog)
    //{{AFX_MSG_MAP(CTest01Dlg)
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTest01Dlg メッセージ ハンドラ

BOOL CTest01Dlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    // このダイアログ用のアイコンを設定します。フレームワークはアプリケーションのメイン
    // ウィンドウがダイアログでない時は自動的に設定しません。
    SetIcon(m_hIcon, TRUE);             // 大きいアイコンを設定
    SetIcon(m_hIcon, FALSE);        // 小さいアイコンを設定
   
    // TODO: 特別な初期化を行う時はこの場所に追加してください。

    c3c = new CDxD3DRm(&m_window); // this

    HRESULT hr = c3c->GetLastErr();
    if(FAILED(hr)){
        AfxMessageBox("D3DRM3インターフェース作成に失敗しました");
        return TRUE;
    }
    //-----------------------
    // MeshBuilder Sample
    {
    D3DVECTOR vertices[ ] = {
        D3DVAL( -1 ), D3DVAL( 0 ), D3DVAL( 0 ),
        D3DVAL( 0 ), D3DVAL( 2 ), D3DVAL( 0 ),
        D3DVAL( 1 ), D3DVAL( 0 ), D3DVAL( 0 ),
    };

    // フェース リスト
    int faces[ ] = {
        3, 0, 1, 2,
        0
    };
        CDxD3DRmMeshBuilder mesh1;
        CDxD3DRmFrame newFrame;
        hr = mesh1.Create(c3c);

        if(FAILED(hr)){     AfxMessageBox("MeshBuilder 作成に失敗しました"); return TRUE;}
        mesh1.AddFaces(3,vertices,0,NULL,(LPDWORD)faces,NULL);
        c3c->CreateFrame(&newFrame);             // 初期フレームから新しいフレーム生成
        newFrame.AddVisual(mesh1.GetObject()); // フレームにメッシュを割り当て
        newFrame.SetPosition(0,0,0);
        newFrame.SetOrientation(0,0,1,0,1,0);
    }
    c3c->ActivateJob();
   
//-----------------------
    return TRUE; // TRUE を返すとコントロールに設定したフォーカスは失われません。
}

// もしダイアログボックスに最小化ボタンを追加するならば、アイコンを描画する
// コードを以下に記述する必要があります。MFC アプリケーションは document/view
// モデルを使っているので、この処理はフレームワークにより自動的に処理されます。

void CTest01Dlg::OnPaint()
{
    if (IsIconic())
    {
        CPaintDC dc(this); // 描画用のデバイス コンテキスト

        SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

        // クライアントの矩形領域内の中央
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;

        // アイコンを描画します。
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
        CDC *p;
        p = m_window.GetDC();
       
        //-----------------------
        c3c->HandlePaintJob(p);
        c3c->ViewportClear();
        c3c->Render();
        c3c->Update();

        //-----------------------
        m_window.ReleaseDC(p);
        CDialog::OnPaint();
    }
}

// システムは、ユーザーが最小化ウィンドウをドラッグしている間、
// カーソルを表示するためにここを呼び出します。
HCURSOR CTest01Dlg::OnQueryDragIcon()
{
    return (HCURSOR) m_hIcon;
}

void CTest01Dlg::OnOK()
{
    // TODO: この位置にその他の検証用のコードを追加してください
    if(c3c!=NULL)delete c3c;
    CDialog::OnOK();
}

void CTest01Dlg::OnCancel()
{
    // TODO: この位置に特別な後処理を追加してください。
    if(c3c!=NULL)delete c3c;
    CDialog::OnCancel();
}

上記クラスのヘッダー部分です。

// Test01Dlg.h : ヘッダー ファイル
//

#if !defined(AFX_TEST01DLG_H__0D547F07_ECDB_11D2_8DD3_0090CCA04D48__INCLUDED_)
#define AFX_TEST01DLG_H__0D547F07_ECDB_11D2_8DD3_0090CCA04D48__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

/////////////////////////////////////////////////////////////////////////////
// CTest01Dlg ダイアログ

#include "..\..\DXD3DRM.h"

class CTest01Dlg : public CDialog
{
// 構築
private:
    CDxD3DRm *c3c;

public:
    CTest01Dlg(CWnd* pParent = NULL);    // 標準のコンストラクタ

// ダイアログ データ
    //{{AFX_DATA(CTest01Dlg)
    enum { IDD = IDD_TEST01_DIALOG };
    CButton    m_window;
    //}}AFX_DATA

    // ClassWizard は仮想関数のオーバーライドを生成します。
    //{{AFX_VIRTUAL(CTest01Dlg)
    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV のサポート
    //}}AFX_VIRTUAL

// インプリメンテーション
protected:
    HICON m_hIcon;

    // 生成されたメッセージ マップ関数
    //{{AFX_MSG(CTest01Dlg)
    virtual BOOL OnInitDialog();
    afx_msg void OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    virtual void OnOK();
    virtual void OnCancel();
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ は前行の直前に追加の宣言を挿入します。

#endif // !defined(AFX_TEST01DLG_H__0D547F07_ECDB_11D2_8DD3_0090CCA04D48__INCLUDED_)


Copyright (C) Kitaro 1999