• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            天行健 君子當自強而不息

            初始化Direct3D(4)

            新建網頁 1

            1.5初始化Direct3D實例

            在本例程中,初始化了一個Direct3D應用程序并用黑色填充顯示窗口(如圖1.7)。

             

                                                      1.7

             

            所有的應用程序都包含了d3dUtility.hd3dUtility.cpp這兩個文件,它們所包含的函數實現了所有Direct3D應用程序都要去做的一些常見的功能。例如:創建一個窗口、初始化Direct3D、進入程序的消息循環等。

            1.5.1d3dUtility.h/cpp

            讓我們先熟悉一下d3dUtility.h/cpp所提供的函數。d3dUtility.h如下:

                #include <d3dx9.h>
               
                template<typename T>
               
            void safe_release(T obj)
                {
                    
            if(obj == NULL)
                        
            return;
               
                    obj->Release();
                    obj = NULL;
                }
               
                template<typename T>
               
            void safe_delete(T obj)
                {
                    
            if(obj == NULL)
                        
            return;
               
                    delete obj;
                    obj = NULL;
                }
               
               
            ///////////////////////////////////////////////////////////////////////////////////
               

                typedef 
            bool (*DISPLAY_FUNC_PTR)(float timeDelta);
               
               
            bool init_d3d(HINSTANCE instance,            // application instance
               
                          int width, int height,        // backbuffer dimensions
               
                          bool is_window,                // true - windowed mode, false - full screen mode.
               
                          D3DDEVTYPE device_type,        // HAL or REF
               
                              IDirect3DDevice9** device);    // the create device
               

               
            int enter_msg_loop(DISPLAY_FUNC_PTR display);
               
                LRESULT CALLBACK wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

            init_d3d——初始化一個應用程序主窗口并進行Direct3D的初始化。如果成功,則輸出IDirect3DDevice9接口指針。從它的參數我們可以發現,我們能夠設置窗口的大小和以窗口模式運行還是全屏模式運行。要知道它實現的細節,請看示例代碼。

                //-----------------------------------------------------------------------
                // Initialize windows and direct 3D.
                //-----------------------------------------------------------------------
               
            bool init_d3d(HINSTANCE instance,            // application instance
               
                          int width, int height,        // backbuffer dimensions
               
                          bool is_window,                // true - windowed mode, false - full screen mode.
               
                          D3DDEVTYPE device_type,        // HAL or REF
               
                              IDirect3DDevice9** device)    // the create device
               
            {
                    
            const char* classname = "Direct3D9App";
               
                    WNDCLASS wc;
                    
                    wc.style         = CS_HREDRAW | CS_VREDRAW;
                    wc.lpfnWndProc   = wnd_proc;
                    wc.cbClsExtra    = 0;
                    wc.cbWndExtra    = 0;
                    wc.hInstance     = instance;
                    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
                    wc.hCursor         = LoadCursor(NULL, IDC_ARROW);
                    wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
                    wc.lpszMenuName  = NULL;
                    wc.lpszClassName = classname;
               
                    
            if(! RegisterClass(&wc))
                    {
                        MessageBox(NULL, "RegisterClass() - failed.", NULL, MB_OK);
                        
            return false;
                    }
               
                    HWND hwnd = CreateWindow(classname, "Direct3D9App", WS_EX_TOPMOST, 
                                             0, 0, width, height, NULL, NULL, instance, NULL);
                    
                    
            if(hwnd == NULL)
                    {
                        MessageBox(NULL, "CreateWindow() - failed.", NULL, MB_OK);
                        
            return false;
                    }
               
                    ShowWindow(hwnd, SW_SHOW);
                    UpdateWindow(hwnd);
               
                    
            // initialize D3D
               
                    // step 1: Create the IDirect3D9 object.
               

                    IDirect3D9* d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
               
                    
            if(d3d9 == NULL)
                    {
                        MessageBox(NULL, "Direct3DCreate9() - failed.", NULL, MB_OK);
                        
            return false;
                    }
               
                    
            // step 2: check for hardware vertex presentation.
               
                
                    D3DCAPS9 caps;    
                    d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, device_type, &caps);
                    
                    
            int vp = 0;
                    
            if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
                        vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
                    
            else
                        vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
               
                    
            // step 3: fill out the D3DPRESENT_PARAMETERS structure.
               

                    D3DPRESENT_PARAMETERS d3dpp;
               
                    d3dpp.BackBufferWidth                = width;
                    d3dpp.BackBufferHeight                = height;
                    d3dpp.BackBufferFormat                = D3DFMT_A8R8G8B8;
                    d3dpp.BackBufferCount                = 1;
                    d3dpp.MultiSampleType                = D3DMULTISAMPLE_NONE;
                    d3dpp.MultiSampleQuality            = 0;
                    d3dpp.SwapEffect                    = D3DSWAPEFFECT_DISCARD;
                    d3dpp.hDeviceWindow                    = hwnd;
                    d3dpp.Windowed                        = is_window;
                    d3dpp.EnableAutoDepthStencil        = 
            true;
                    d3dpp.AutoDepthStencilFormat        = D3DFMT_D24S8;
                    d3dpp.Flags                            = 0;
                    d3dpp.FullScreen_RefreshRateInHz    = D3DPRESENT_RATE_DEFAULT;
                    d3dpp.PresentationInterval            = D3DPRESENT_INTERVAL_IMMEDIATE;
               
                    
            // step 4: create the device.
               

                    
            if(FAILED(d3d9->CreateDevice(D3DADAPTER_DEFAULT, device_type, hwnd, vp, &d3dpp, device)))
                    {
                        
            // try again using a 16-bit depth buffer
               
                        d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
               
                        
            if(FAILED(d3d9->CreateDevice(D3DADAPTER_DEFAULT, device_type, hwnd, vp, &d3dpp, device)))
                        {
                            d3d9->Release();    
            // done with d3d9 object
               
                        MessageBox(NULL, "CreateDevice() - failed.", NULL, MB_OK);
                            
            return false;
                        }
                    }
               
                    d3d9->Release();        
            // done with d3d9 object
               
                return true;
                }

            enter_msg_loop——這個函數封裝了應用程序的消息循環。它需要輸入一個顯示函數的函數指針,顯示函數為程序中繪制圖形的代碼塊,這樣做是為了使顯示函數能夠在空閑的時候被調用并顯示場景,它的實現如下:

                //-----------------------------------------------------------------------
                // Enter windows message loop and render game frames if there is no message 
                // comes from thread message queue.
                //-----------------------------------------------------------------------
               
            int enter_msg_loop(DISPLAY_FUNC_PTR display)
                {
                    MSG msg;
                    ZeroMemory(&msg, 
            sizeof(MSG));
                    
                    
            // The timeGetTime function retrieves the system time, in milliseconds. 
                    // The system time is the time elapsed since Windows was started.    
               
                static float last_time = (float) timeGetTime();
               
                    
            while(msg.message != WM_QUIT)
                    {
                        
            // The PeekMessage function dispatches incoming sent messages, checks the thread message queue for a 
                        // posted message, and retrieves the message (if any exist).
                        //
                        // If a message is available, the return value is nonzero.
                        // If no messages are available, the return value is zero. 
               

                        
            if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
                        {
                            TranslateMessage(&msg);
                            DispatchMessage(&msg);
                        }
                        
            else
                        {
                            
            float curr_time  = (float) timeGetTime();
                            
            float time_delta = (curr_time - last_time) * 0.001f;
               
                            display(time_delta);
               
                            last_time = curr_time;
                        }
                    }
               
                    
            return (int) msg.wParam;
                }

            與“time”有關的代碼用于計算每次調用顯示函數的時間間隔,即是每幀的時間。

            safe_release——這個模版函數能方便的釋放COM接口并將它們的值設為NULL

            safe_delete——這個模版函數能方便的刪除一個對象并將指向其的指針設為NULL

            wnd_proc——應用程序主窗口的回調函數

             

            1.5.2 實例框架

            通過例框架,我們形成了一種通用的方法去構造示例程序。每一個例程都含有三個函數的實現,當然這不包括回調函數和WinMain主函數。這三個函數用特定的代碼實現特定的功能。這三個函數是:

            bool setup()——在這個函數里,我們將準備一切該程序需要用到的東西,包括資源的分配,檢查設備能力,設置應用程序的狀態

            void clearup()——這個函數將釋放Setup()中分配的資源,如分配的內存。

            bool display(float time_delta)這個函數包含所有與我們繪圖和顯示有關的代碼。參數timeDelta為每一幀的間隔時間,用來控制每秒的幀數。

             

            這個示例程序將創建并初始化一個Direct3D應用程序,并用黑色填充屏幕。注意,我們使用了通用函數簡化了初始化過程。

                /*********************************************************************************
                PURPOISE:
                    Demonstrates how to initialize Direct3D, how to use framework functions, 
                    and how to clear the screen to black.     
                *********************************************************************************/

               
                #include "D3DUtility.h"
               
                IDirect3DDevice9* g_device = NULL;
               
               
            bool setup()
                {
                    
            // nothing to setup in this sample
               

                    
            return true;
                }
               
               
            void cleanup()
                {
                    
            // nothing to cleanup in this sample
               
            }
               
               
            bool display(float timeDelta)
                {
                    
            // Only use Device methods if we have a valid device.
               
                if(g_device == NULL)
                        
            return false;
               
                    
            // Instruct the device to set each pixel on the back buffer black - D3DCLEAR_TARGET: 0x00000000 (black);
                    // and to set each pixel on the depth buffer to a value of 1.0 - D3DCLEAR_ZBUFFER: 1.0f.
               
                g_device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
               
                    
            // swap the back and front buffers
               
                g_device->Present(NULL, NULL, NULL, NULL);
               
                    
            return true;
                }
               
                LRESULT CALLBACK wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
                {
                    
            switch(msg)
                    {
                    
            case WM_DESTROY:
                        PostQuitMessage(0);
                        
            break;
               
                    
            case WM_KEYDOWN:
                        
            if(wParam == VK_ESCAPE)
                            DestroyWindow(hwnd);
                        
            break;
                    }
               
                    
            return DefWindowProc(hwnd, msg, wParam, lParam);
                }
               
               
            int WINAPI WinMain(HINSTANCE inst, HINSTANCE, PSTR cmd_line, int cmd_show)
                {
                    
            if(! init_d3d(inst, 640, 480, true, D3DDEVTYPE_HAL, &g_device))
                    {
                        MessageBox(NULL, "init_d3d() - failed.", 0, MB_OK);
                        
            return 0;
                    }
               
                    
            if(! setup())
                    {
                        MessageBox(NULL, "Steup() - failed.", 0, MB_OK);
                        
            return 0;
                    }
               
                    enter_msg_loop(display);
               
                    cleanup();
                    g_device->Release();
               
                    
            return 0;
                }

            Display方法調用了IDirect3DDevice::Clear方法,分別用黑色和1.0填充后備表面和深度/模版緩沖。如果應用程序不停止的話,我們會一直執行這個操作。IDirect3DDevice::Clear聲明如下:

            HRESULT Clear( DWORD Count, CONST D3DRECT * pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil );



            Count——pRects   組中的矩形的個數

            pRects——將要清除的屏幕矩形的數組,這使我們可以清除屏幕的某一部分

            Flags——指定在哪些表面上執行清除表面的操作

                     D3DCLEAR_TARGET——目的表面,通常為后備表面

                     D3DCLEAR_ZBUFFER——深度緩沖

                     D3DCLEAR_STENCIL——模版緩沖

            Color——使用什么顏色填充清除的表面

             Z——設置深度緩沖的值

            Stencil——設置模版緩沖的值

            屏幕被填充后,要調用IDirecte3DDevice9::Present方法進行后備表面的交換。

             

            Windows 回調函數為一組事件集,即,我們可按ESC鍵讓程序退出。

             最后,WinMain按如下步驟運行:

            1.        初始化主顯示窗口和Direct3D

            2.        調用setup進行程序的準備工作

            3.        使用display函數作為參數進入消息循環

            4.        清除應用程序最后釋放IDirecte3DDevice9對象

             

            注意:不要忘了在你的工程中加入d3d9.libd3dx9.libwinmm.lib這三個庫!

             

            下載源碼

            posted on 2008-03-13 13:36 lovedday 閱讀(984) 評論(0)  編輯 收藏 引用

            公告

            導航

            統計

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關鏈接

            搜索

            最新評論

            久久无码av三级| 国产福利电影一区二区三区,免费久久久久久久精 | 日韩AV无码久久一区二区| 无码精品久久久天天影视| 99久久免费国产精精品| 国产午夜电影久久| 日本道色综合久久影院| 伊人色综合久久天天人守人婷| 狠狠色噜噜色狠狠狠综合久久| 91精品国产综合久久四虎久久无码一级 | 久久一区二区三区免费| 亚洲精品午夜国产VA久久成人| 久久国产乱子精品免费女| 亚洲性久久久影院| 国产成人综合久久久久久| 午夜久久久久久禁播电影| 久久中文字幕无码专区| 99久久久精品| 久久综合九色综合网站| 亚洲色欲久久久久综合网| 久久青青草原国产精品免费| 婷婷综合久久中文字幕蜜桃三电影| 国产成人久久精品麻豆一区| 久久精品亚洲精品国产色婷| 亚洲国产天堂久久久久久| 精品一久久香蕉国产线看播放| 99久久精品日本一区二区免费| 色8久久人人97超碰香蕉987| 亚洲国产成人精品91久久久 | 久久国产视频99电影| 久久九九全国免费| 91久久精品91久久性色| 久久成人国产精品| 亚洲AV无码久久精品蜜桃| 久久精品免费一区二区| 国内精品伊人久久久影院| 亚州日韩精品专区久久久| 亚洲国产高清精品线久久| 亚洲欧洲精品成人久久曰影片| 久久久久久国产a免费观看不卡| 狠狠久久综合|