ファイル選択メニューを設定する

ファイルメニューから選択された X FILE を描画します。

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

プロジェクトの作成

  1. ファイル選択メニューを設定して、選ばれた X FILE を描画します。
    DirectX のメニューの基礎は 終了メニューを設定する を参照して下さい。
    X FILE の描画は X_file Object Class を参照して下さい。
    空の新規プロジェクト(Main)を作成して下さい。
    このページからソースコード(Main.cpp)を取得して、プロジェクトのフォルダーに格納して下さい。
    また X_FILE Object Class を使うので X_FILE.cpp と X_FILE.h もプロジェクトのフォルダーに格納して下さい。
  2. プログラムのメニューを設定します。
    [プロジェクト][リソースの追加][Menu][新規作成] で、親のメニュー「ファイル(&F)」を作成して下さい。
    [ファイル(&F)]の下の[ここへ入力]に「開く(&O)」とタイプします。
    「開く(&O)」を右クリックしてプロパティを選びます。
    キャプションに「開く(&O)」を、ID に ID_OPEN をタイプします。
    [開く(&O)]の下の[ここへ入力]に「アプリケーションの終了(&X)」とタイプします。
    「アプリケーションの終了(&X)」を右クリックしてプロパティを選びます。
    キャプションに「アプリケーションの終了(&X)」を、ID に IDM_EXIT をタイプします。
    メニューの ID は次のようになります。
    メニュー IDR_MENU1(規定値)
    ファイル(&F)
    開く(&O) ID_OPEN
    アプリケーションの終了(&X) IDM_EXIT
  3. リソースを登録するとプロジェクトのフォルダーに Main.rc と resource.h が作成されます。
    Main.rc の Main はプロジェクトの名前です。
    resource.h を #include して下さい。
        #include    "resource.h"
        

プログラムの作成

  1. Main.cpp の全ソースコードです。
    /*********************************************/
    /*  DirectX9  メニューを設定する    前田 稔  */
    /*********************************************/
    #define     NAME        "DirectX9 Graphics"
    #define     TITLE       "DirectX9 Tutorial"
    #include    <d3d9.h>
    #include    <d3dx9.h>
    #include    <commdlg.h>
    #include    "X_FILE.h"
    #include    "resource.h"
    
    #pragma     once
    #pragma     comment(lib,"d3d9.lib")
    #pragma     comment(lib,"d3dx9.lib")
    #pragma     comment(lib,"dxguid.lib")
    
    // DirectXオブジェクト
    HWND                g_hWnd= NULL;   // Window Handle
    LPDIRECT3D9         g_pD3D= NULL;   // Direct3D Object
    LPDIRECT3DDEVICE9   g_pDEV= NULL;   // 描写用デバイス
    X_FILE              *xfile= NULL;   // X_FILE Object Class
    
    D3DMATERIAL9        material;       // マテリアル
    D3DLIGHT9           light;          // ライト
    D3DVECTOR           Rot= { 0,0,0 }; // 回転情報
    D3DVECTOR           Mov= { 0,0,0 }; // 移動情報
    
    char                szFile[MAX_PATH];   //ファイル名(パス付き)
    
    // Function Prototype
    LRESULT CALLBACK MsgProc(HWND hWnd,UINT msg,UINT wParam,LONG lParam);
    LRESULT GetOpenFile();
    
    // Direct3D の初期化
    HRESULT Init3DDev()
    {   D3DDISPLAYMODE          d3ddm;
        D3DPRESENT_PARAMETERS   d3dpp;
    
        if (NULL==(g_pD3D=Direct3DCreate9(D3D_SDK_VERSION)))    return E_FAIL;
        if (FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddm)))   return E_FAIL;
        ZeroMemory(&d3dpp,sizeof(d3dpp));
        d3dpp.Windowed                  = TRUE;                     // ウィンドウモード
        d3dpp.SwapEffect                = D3DSWAPEFFECT_DISCARD;    // 映像信号に同期してフリップする
        d3dpp.EnableAutoDepthStencil    = TRUE;                     // デプス(Zバッファ)とステンシルを作成
        d3dpp.AutoDepthStencilFormat    = D3DFMT_D16;               // デプスバッファとして16bitを使う
        d3dpp.BackBufferFormat          = d3ddm.Format;             // カラーモードの指定
    
        if (FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,g_hWnd,
                                 D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp,&g_pDEV)))
            return E_FAIL;
        return S_OK;
    }
    
    // レンダリングステートパラメータの設定
    void SetEnvironment()
    {   //g_pDEV->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);           // カリングを行わない
        g_pDEV->SetRenderState(D3DRS_CULLMODE,D3DCULL_CCW);             // カリングを行う
        g_pDEV->SetRenderState(D3DRS_ZENABLE, TRUE);                    // Zバッファを使用
        g_pDEV->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);           // αブレンドを行う
        g_pDEV->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);      // αソースカラーの指定
        g_pDEV->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);  // αデスティネーションカラーの指定
    
        // サンプラーステートパラメータの設定
        g_pDEV->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP); // テクスチャU値の繰り返し設定
        g_pDEV->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP); // テクスチャV値の繰り返し設定
        g_pDEV->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);  // テクスチャ拡大時の補間設定
        g_pDEV->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);  // テクスチャ縮小時の補間設定
    
        //xfile= new X_FILE(g_pDEV,"tiger.x");    // X_FILE Object Class
    
        //マテリアルの作成
        material.Diffuse.r= material.Diffuse.g= material.Diffuse.b= 1.0f;
        material.Ambient.r= material.Ambient.g= material.Ambient.b= 0.5f;
        material.Specular.r= material.Specular.g= material.Specular.b= 0.0f;
        material.Emissive.r= material.Emissive.g= material.Emissive.b= 0.0f;
        material.Power= 0;
        //光源の作成
        ZeroMemory(&light,sizeof(D3DLIGHT9));
        light.Type = D3DLIGHT_DIRECTIONAL;
        light.Diffuse.r= light.Diffuse.g= light.Diffuse.b= 1.0f;
        light.Specular.r= light.Specular.g= light.Specular.b= 0.2f;
        light.Ambient.r= light.Ambient.g= light.Ambient.b= 0.5f;
        light.Direction = D3DXVECTOR3(10,-20,10);
    
        g_pDEV->SetLight(0,&light);         //ライトの設定
        g_pDEV->LightEnable(0,TRUE);
        g_pDEV->SetMaterial(&material);     //マテリアルの設定
    }
    
    // 終了の処理
    void Cleanup(void)
    {   SAFE_DELETE(xfile);
        SAFE_RELEASE(g_pDEV);
        SAFE_RELEASE(g_pD3D);
    }
    
    // Matrices の設定
    VOID SetupMatrices()
    {
        D3DXMATRIXA16 matWorld,matX,matY,matZ,matT;
        D3DXMatrixRotationX(&matX,Rot.x);
        D3DXMatrixRotationY(&matY,Rot.y);
        D3DXMatrixRotationZ(&matZ,Rot.z);
        D3DXMatrixTranslation(&matT,Mov.x,Mov.y,Mov.z);
        matWorld= matT*matX*matY*matZ;
        g_pDEV->SetTransform(D3DTS_WORLD,&matWorld);
        D3DXVECTOR3 vEyePt( 0.0f, 3.0f,-5.0f );
        D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
        D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
        D3DXMATRIXA16 matView;
        D3DXMatrixLookAtLH(&matView,&vEyePt,&vLookatPt,&vUpVec);
        g_pDEV->SetTransform(D3DTS_VIEW,&matView);
        D3DXMATRIXA16 matProj;
        D3DXMatrixPerspectiveFovLH(&matProj,D3DX_PI/4,1.0f,1.0f,100.0f);
        g_pDEV->SetTransform(D3DTS_PROJECTION,&matProj);
    }
    
    // 描画処理
    void Draw(void)
    {
        if (xfile==NULL)    return;
        g_pDEV->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(150,200,200),1.0f,0);
        if(SUCCEEDED(g_pDEV->BeginScene()))
        {   SetupMatrices();
            xfile->Render();
            g_pDEV->EndScene();
        }
        g_pDEV->Present(NULL,NULL,NULL,NULL);
    }
    
    // ウィンドウ処理
    LRESULT WINAPI MsgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
    {
        switch(msg)
        {   case WM_PAINT:
                Draw();
                break;
            case WM_COMMAND:
                switch(LOWORD(wParam))
                {   case IDM_EXIT:
                        PostMessage(hWnd,WM_CLOSE,0,0);
                        return 0L;
                    case ID_OPEN:
                        if (GetOpenFile()==TRUE)
                        {
                            SAFE_DELETE(xfile);
                            xfile= new X_FILE(g_pDEV,szFile);
                            Rot.x=Rot.y=Rot.z= 0.0f;
                            Mov.x=Mov.y=Mov.z= 0.0f;
                            InvalidateRect(hWnd,NULL,TRUE);
                        }
                        return 0L;
                }
                break;
            case WM_KEYDOWN:
                switch(wParam)
                {   case VK_ESCAPE:
                        PostMessage(hWnd,WM_CLOSE,0,0);
                        return 0L;
                    case VK_LEFT:
                        Rot.y+= 0.1f;
                        InvalidateRect(hWnd,NULL,TRUE);
                        return 0L;
                    case VK_RIGHT:
                        Rot.y-= 0.1f;
                        InvalidateRect(hWnd,NULL,TRUE);
                        return 0L;
                    case VK_UP:
                        Rot.x+= 0.1f;
                        InvalidateRect(hWnd,NULL,TRUE);
                        return 0L;
                    case VK_DOWN:
                        Rot.x-= 0.1f;
                        InvalidateRect(hWnd,NULL,TRUE);
                        return 0L;
                    case 'J':
                        Rot.z+= 0.1f;
                        InvalidateRect(hWnd,NULL,TRUE);
                        return 0L;
                    case 'L':
                        Rot.z-= 0.1f;
                        InvalidateRect(hWnd,NULL,TRUE);
                        return 0L;
                    case 'A':
                        Mov.x-= 0.1f;
                        InvalidateRect(hWnd,NULL,TRUE);
                        return 0L;
                    case 'D':
                        Mov.x+= 0.1f;
                        InvalidateRect(hWnd,NULL,TRUE);
                        return 0L;
                    case 'W':
                        Mov.y+= 0.1f;
                        InvalidateRect(hWnd,NULL,TRUE);
                        return 0L;
                    case 'X':
                        Mov.y-= 0.1f;
                        InvalidateRect(hWnd,NULL,TRUE);
                        return 0L;
                    case 'I':
                        Mov.z+= 0.1f;
                        InvalidateRect(hWnd,NULL,TRUE);
                        return 0L;
                    case 'M':
                        Mov.z-= 0.1f;
                        InvalidateRect(hWnd,NULL,TRUE);
                        return 0L;
                }
                break;
            case WM_DESTROY:
                PostQuitMessage(0);
                return 0L;
        }
        return DefWindowProc(hWnd,msg,wParam,lParam);
    }
    
    //★ WinMain
    INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, INT)
    {   MSG     msg;
    
        WNDCLASSEX wc = { sizeof(WNDCLASSEX),CS_CLASSDC,MsgProc,0L,0L,hInst,
                          NULL,NULL,NULL,MAKEINTRESOURCE(IDR_MENU1),NAME,NULL };
        if (RegisterClassEx(&wc)==0)    return FALSE;
        g_hWnd = CreateWindowEx(0,NAME,TITLE,WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT,CW_USEDEFAULT,400,400,NULL,NULL,hInst,NULL);
        // Initialize Direct3D
        if (FAILED(Init3DDev()))    return FALSE;
        SetEnvironment();
    
        ShowWindow(g_hWnd,SW_SHOWDEFAULT);
        UpdateWindow(g_hWnd);
        ZeroMemory(&msg,sizeof(msg));
        while(msg.message!=WM_QUIT)
        {   if (PeekMessage(&msg,NULL,0U,0U,PM_REMOVE))
            {   TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
        Cleanup();
        UnregisterClass(NAME,wc.hInstance);
        return 0;
    }
    
    // OPENFILENAME 構造体で入力ファイルを設定する
    LRESULT GetOpenFile()
    {   OPENFILENAME    ofn;
    
        szFile[0]= 0;
        memset(&ofn,0,sizeof(OPENFILENAME));
        ofn.lStructSize= sizeof(OPENFILENAME);
        ofn.hwndOwner= NULL;
        ofn.lpstrFilter= "x(*.x)\0*.x\0All files(*.*)\0*.*\0\0";
        ofn.lpstrFile= szFile;
        ofn.lpstrFileTitle= NULL;
        ofn.nMaxFile= MAX_PATH;
        ofn.Flags= OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
        ofn.lpstrDefExt= "x";
        ofn.lpstrTitle= "ファイルオープン!";
    
        if (GetOpenFileName(&ofn)!=TRUE)
        {   MessageBox(NULL,"Open File Name Error","GetOpenFile",MB_OK);
            return FALSE;
        }
        return TRUE;
    }
    
  2. WM_COMMAND: でメニューを検出します。
    IDM_EXIT: が選択されたとき、PostMessage(hWnd,WM_CLOSE,0,0); でプログラムを終了します。
    ID_OPEN: が選択されたときは GetOpenFile() 関数でファイルを選択して描画します。
            case WM_COMMAND:
                switch(LOWORD(wParam))
                {   case IDM_EXIT:
                        PostMessage(hWnd,WM_CLOSE,0,0);
                        return 0L;
                    case ID_OPEN:
                        if (GetOpenFile()==TRUE)
                        {
                            SAFE_DELETE(xfile);
                            xfile= new X_FILE(g_pDEV,szFile);
                            Rot.x=Rot.y=Rot.z= 0.0f;
                            Mov.x=Mov.y=Mov.z= 0.0f;
                            InvalidateRect(hWnd,NULL,TRUE);
                        }
                        return 0L;
                }
                break;
        
  3. WM_KEYDOWN: でモデルを回転/移動します。
    ESCAPE が押されたときはプログラムを終了します。
    上下左右の矢印キーでモデルをX軸&Y軸で回転します。
    J, L キーでモデルをZ軸回転します。
    A, D, W, X キーでモデルを上下左右に移動します。
    I,M キーでモデルをZ方向に移動します。
            case WM_KEYDOWN:
                switch(wParam)
                {   case VK_ESCAPE:
                        PostMessage(hWnd,WM_CLOSE,0,0);
                        return 0L;
                    case VK_LEFT:
                        Rot.y+= 0.1f;
                        InvalidateRect(hWnd,NULL,TRUE);
                        return 0L;
                    case VK_RIGHT:
                          ・・・
        
  4. GetOpenFileName() でファイルを選択する GetOpenFile() 関数です。
        // OPENFILENAME 構造体で入力ファイルを設定する
        LRESULT GetOpenFile()
        {   OPENFILENAME    ofn;
    
            szFile[0]= 0;
            memset(&ofn,0,sizeof(OPENFILENAME));
            ofn.lStructSize= sizeof(OPENFILENAME);
            ofn.hwndOwner= NULL;
            ofn.lpstrFilter= "x(*.x)\0*.x\0All files(*.*)\0*.*\0\0";
            ofn.lpstrFile= szFile;
            ofn.lpstrFileTitle= NULL;
            ofn.nMaxFile= MAX_PATH;
            ofn.Flags= OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
            ofn.lpstrDefExt= "x";
            ofn.lpstrTitle= "ファイルオープン!";
    
            if (GetOpenFileName(&ofn)!=TRUE)
            {   MessageBox(NULL,"Open File Name Error","GetOpenFile",MB_OK);
                return FALSE;
            }
            return TRUE;
        }
        

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

超初心者のプログラム入門(DirectX9 game program)

超初心者のプログラム入門(DirectX10 game program)