• <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>

            天行健 君子當自強而不息

            D3D中的模板緩存(3)

            8.3實例程序:平面陰影

            在場景中被燈光照射的地方會產生陰影,這將使場景變的更真實。在這一部分我們將演示怎樣實現平面陰影,即在平面上的陰影(如圖8.5)。

            使用這種陰影只是一種權宜之計,雖然它增強了場景的真實效果,但是這并不是現實中的陰影。

            為了實現平面陰影,我們首先必須找到物體投射到平面上的陰影并進行幾何建模以便我們能夠渲染它,用一些3D數學就能很容易的實現它,然后我們用50%透明度的黑色材質來渲染描述陰影的多邊形。渲染陰影時可能出現“雙倍混合”,我們將用一小部分進行解釋,并使用模板緩存來防止雙倍混合發生。

             

            8.3.1平行光陰影

            圖8.6顯示了物體在平行光照射下得到的陰影。光線是從平行光源放射出的,它的方向是L,通過頂點p得到r(t) = p + tL。光線r(t)和平面n * p + d = 0 相交得到 s

            An intersection point s is easily found with a ray/plane intersection test:

            8.3.2點光源陰影

            圖8.7顯示了物體在點光源照射下得到的陰影。點光源的位置是L。光線通過頂點p,則得到 r(t) = p + t ( pL )。光線r(t)和平面n * p + d = 0 相交得到 s 。用8.3.1同樣的方法我們可以得到s

            注意:在點光源和平行光中的L是不同的。對于點光源,我們用L來表示點光源的位置。而對于平行光,我們則是用L來表示平行光的照射方向。

             

            8.3.3陰影矩陣

            注意圖8.6中所示的平行光,影子本質上是把物體按照燈光照射方向平行地投射到平面n*p+d=0之上。同樣的,圖8.7中所示的點光源,影子本質上是把物體按照透視畫法從光源投射到平面n*p+d=0之上。

            我們能夠使用一個矩陣來表示從一個頂點p變換到平面n*p=d=0上的s的變化。而且,我們能夠用同一個矩陣來表現正交投影和透視投影。

            我們用一個4D向量(nx, ny, nz, d)來表示將要用于投射陰影平面的平面等式中的各個系數。讓4D向量L=(Lx, Ly, Lz, Lw)來表示平行光的照射方向或點光源的位置。我們用w來區別:

            1.假如w=0,那么L表示平行光的照射方向。

            2.假如w=1 ,那么L表示點光源的位置。

            假定平面的法向量已經單位化,我們讓k=(nx, ny, nz, d)*(Lx, Ly, Lz, Lw)= nxLx+nyLy+nzLz+dLw

            那么我們就可得到表示點p到點s的變換矩陣,即陰影矩陣:

            因為在其他地方已經被推導出來了,對于我們來說推導它并沒有重大的意義,在這里我們就不再演示推導怎樣得到這個矩陣的過程了。但是對與感興趣的讀者可以自己到網上查找相應的信息。

            D3DX庫中已經給我們提供了一個建立陰影矩陣的函數。其中當w=0時表示平行光,當w=1時表示點光源:

            Builds a matrix that flattens geometry into a plane.

            D3DXMATRIX * D3DXMatrixShadow(
            D3DXMATRIX * pOut,
            CONST D3DXVECTOR4 * pLight,
            CONST D3DXPLANE * pPlane
            );

            Parameters

            pOut
            [in, out] Pointer to the D3DXMATRIX structure that is the result of the operation.
            pLight
            [in] Pointer to a D3DXVECTOR4 structure describing the light's position.
            pPlane
            [in] Pointer to the source D3DXPLANE structure.

            Return Values

            Pointer to a D3DXMATRIX structure that flattens geometry into a plane.

            Remarks

            The D3DXMatrixShadow function flattens geometry into a plane, as if casting a shadow from a light.

            The return value for this function is the same value returned in the pOut parameter. In this way, the D3DXMatrixShadow function can be used as a parameter for another function.

            This function uses the following formula to compute the returned matrix.

            P = normalize(Plane);
            L = Light;
            d = dot(P, L)

            P.a * L.x + d P.a * L.y P.a * L.z P.a * L.w
            P.b * L.x P.b * L.y + d P.b * L.z P.b * L.w
            P.c * L.x P.c * L.y P.c * L.z + d P.c * L.w
            P.d * L.x P.d * L.y P.d * L.z P.d * L.w + d

            If the light's w-component is 0, the ray from the origin to the light represents a directional light. If it is 1, the light is a point light.

            8.3.4用模板緩存防止雙倍混合

            幾何學上,當我們將一個物體投影到一個平面上時,很可能會有兩個或者更多的投影三角形被重疊到一起。若我們就這樣渲染,那么有重疊三角形的地方就會被多次混合以至這些地方將會變得更黑。圖8.8就是這種情況。

            使用模板緩存來解決這個問題,設置模板測試為允許像素第一次被渲染。即,當把影子像素渲染到后臺緩存時,我們同時在模板緩存中做好標記。然后,如果試圖把像素向一個已經渲染過的地方寫,那么模板測試將會失敗。這樣,我們就防止了重復寫像素也就是防止了二次融合的發生。

             

            8.3.5代碼和解釋

            下面的代碼就是講解影子例子。本例的相關代碼都在RenderShadow函數中。注意我們假設模板緩存都已經被清除為0了。

            首先設置模板渲染狀態。將模板比較運算設為D3DCMP_EQUAL且將D3DRS_STENCILREF渲染狀態設置為0x0,因此假如在模板緩存中相應的值為0x0,那么就指定渲染陰影到后臺緩存中。

            因為模板緩存是被清除為0x0的,所以我們第一次將影子像素寫入的時候總是正確的;不過因為我們設置D3DRS_STENCILPASS為D3DSTENCILOP_INCR,假如你試圖將已經寫過的像素寫入的話,這個測試將會失敗。在第一次寫入的時候模板像素已經被寫成了0x1,因此假如你再一次寫入,模板測試將會失敗。因此,我們避免了重復寫像素,也避免了二次融合。

            void RenderShadow()

            {

                   Device->SetRenderState(D3DRS_STENCILENABLE, true);

                   Device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL);

                   Device->SetRenderState(D3DRS_STENCILREF, 0x0);

                   Device->SetRenderState(D3DRS_STENCILMASK, 0xffffffff);

                   Device->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff);

                   Device->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);

                   Device->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);

            Device->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCR);

             

            下一步,我們計算陰影變換并將它放置到場景中適當的位置。

                   // compute the transformation to flatten the teapot into a shadow.

                   D3DXVECTOR4 lightDirection(0.707f, -0.707f, 0.707f, 0.0f);

                   D3DXPLANE groundPlane(0.0f, -1.0f, 0.0f, 0.0f);

                   D3DXMATRIX S;

                   D3DXMatrixShadow(&S, &lightDirection, &groundPlane);

                   D3DXMATRIX T;

                   D3DXMatrixTranslation(&T, TeapotPosition.x, TeapotPosition.y, TeapotPosition.z);

                   D3DXMATRIX W = T * S;

            Device->SetTransform(D3DTS_WORLD, &W);

             

            最后,我們設置一個50%透明度的黑色材質,關閉深度測試,渲染陰影,然后開啟深度緩存同時關閉alpha混合和模板測試。我們關閉深度緩存來防止z-fighting,它是當兩個不同的表面在深度緩存中有同樣的深度值時出現的現象;深度緩存不知道那一個是在前面,此時就會產生討厭的閃動。因為陰影和地板是在同一個平面上,z-fighting很可能就會出現。通過先渲染地板然后禁用深度測試并繪制陰影,這樣我們就能夠保證陰影將繪制在地面只之上。

                   Device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);

                   Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);

                   Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

                   D3DMATERIAL9 mtrl = d3d::InitMtrl(d3d::BLACK, d3d::BLACK,

                   d3d::BLACK, d3d::BLACK, 0.0f);

                   mtrl.Diffuse.a = 0.5f; // 50% transparency.

                   // Disable depth buffer so that z-fighting doesn't occur when we

                   // render the shadow on top of the floor.

                   Device->SetRenderState(D3DRS_ZENABLE, false);

                   Device->SetMaterial(&mtrl);

                   Device->SetTexture(0, 0);

                   Teapot->DrawSubset(0);

                   Device->SetRenderState(D3DRS_ZENABLE, true);

                   Device->SetRenderState(D3DRS_ALPHABLENDENABLE, false);

                   Device->SetRenderState(D3DRS_STENCILENABLE, false);

            }//end RenderShadow()

             

            主程序:

             

            /**************************************************************************************
              Demonstrates shadows with stencils.  
              Use the arrow keys and the 'A' and 'S' key to navigate the scene and translate the teapot. 
             *************************************************************************************
            */

            #include 
            "d3dUtility.h"

            #pragma warning(disable : 
            4100)

            class cTextureVertex
            {
            public:
                
            float _x, _y, _z;
                
            float _nx, _ny, _nz;
                
            float _u, _v;

                cTextureVertex() { }

                cTextureVertex(
            float x, float y, float z, 
                               
            float nx, float ny, float nz,
                               
            float u, float v)
                {
                    _x  
            = x;  _y  = y;  _z  = z;
                    _nx 
            = nx; _ny = ny; _nz = nz;
                    _u  
            = u;  _v  = v;
                }    
            };

            const DWORD TEXTURE_VERTEX_FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;

            ////////////////////////////////////////////////////////////////////////////////////////////////////

            const int WIDTH  = 640;
            const int HEIGHT = 480;

            IDirect3DDevice9
            *        g_d3d_device;
            IDirect3DVertexBuffer9
            *    g_vertex_buffer;

            IDirect3DTexture9
            *        g_floor_texture;
            IDirect3DTexture9
            *        g_wall_texture;
            IDirect3DTexture9
            *        g_mirror_texture;

            D3DMATERIAL9    g_floor_material  
            = WHITE_MATERIAL;
            D3DMATERIAL9    g_wall_material   
            = WHITE_MATERIAL;
            D3DMATERIAL9    g_mirror_material 
            = WHITE_MATERIAL;

            ID3DXMesh
            *        g_teapot_mesh;
            D3DXVECTOR3        g_teapot_pos(
            0.0f3.0f-7.5f);
            D3DMATERIAL9    g_teapot_material 
            = YELLOW_MATERIAL;

            void render_scene();
            void render_shadow();

            ////////////////////////////////////////////////////////////////////////////////////////////////////

            bool setup()
            {    
                
            // make walls have low specular reflectance - 20%
                g_wall_material.Specular = WHITE * 0.2f;    

                D3DXCreateTeapot(g_d3d_device, 
            &g_teapot_mesh, NULL);

                
            // Create and specify geometry.  For this sample we draw a floor and a wall with a mirror on it.  
                
            // We put the floor, wall, and mirror geometry in one vertex buffer.
                
            //
                
            //   |----|----|----|
                
            //   |Wall|Mirr|Wall|
                
            //   |    | or |    |
                
            //   /--------------/
                
            //  /   Floor      /
                
            // /--------------/

                g_d3d_device
            ->CreateVertexBuffer(24 * sizeof(cTextureVertex), 0, TEXTURE_VERTEX_FVF, D3DPOOL_MANAGED,
                                                 
            &g_vertex_buffer, NULL);

                cTextureVertex
            * v;

                g_vertex_buffer
            ->Lock(00, (void**)&v, 0);

                
            // floor
                v[0= cTextureVertex(-7.5f0.0f-10.0f0.0f1.0f0.0f0.0f1.0f);
                v[
            1= cTextureVertex(-7.5f0.0f,   0.0f0.0f1.0f0.0f0.0f0.0f);
                v[
            2= cTextureVertex( 7.5f0.0f,   0.0f0.0f1.0f0.0f1.0f0.0f);
                
                v[
            3= cTextureVertex(-7.5f0.0f-10.0f0.0f1.0f0.0f0.0f1.0f);
                v[
            4= cTextureVertex( 7.5f0.0f,   0.0f0.0f1.0f0.0f1.0f0.0f);
                v[
            5= cTextureVertex( 7.5f0.0f-10.0f0.0f1.0f0.0f1.0f1.0f);

                
            // wall
                v[6]  = cTextureVertex(-7.5f0.0f0.0f0.0f0.0f-1.0f0.0f1.0f);
                v[
            7]  = cTextureVertex(-7.5f5.0f0.0f0.0f0.0f-1.0f0.0f0.0f);
                v[
            8]  = cTextureVertex(-2.5f5.0f0.0f0.0f0.0f-1.0f1.0f0.0f);
                
                v[
            9]  = cTextureVertex(-7.5f0.0f0.0f0.0f0.0f-1.0f0.0f1.0f);
                v[
            10= cTextureVertex(-2.5f5.0f0.0f0.0f0.0f-1.0f1.0f0.0f);
                v[
            11= cTextureVertex(-2.5f0.0f0.0f0.0f0.0f-1.0f1.0f1.0f);

                
            // Note: We leave gap in middle of walls for mirror

                v[
            12= cTextureVertex(2.5f0.0f0.0f0.0f0.0f-1.0f0.0f1.0f);
                v[
            13= cTextureVertex(2.5f5.0f0.0f0.0f0.0f-1.0f0.0f0.0f);
                v[
            14= cTextureVertex(7.5f5.0f0.0f0.0f0.0f-1.0f1.0f0.0f);
                
                v[
            15= cTextureVertex(2.5f0.0f0.0f0.0f0.0f-1.0f0.0f1.0f);
                v[
            16= cTextureVertex(7.5f5.0f0.0f0.0f0.0f-1.0f1.0f0.0f);
                v[
            17= cTextureVertex(7.5f0.0f0.0f0.0f0.0f-1.0f1.0f1.0f);

                
            // mirror
                v[18= cTextureVertex(-2.5f0.0f0.0f0.0f0.0f-1.0f0.0f1.0f);
                v[
            19= cTextureVertex(-2.5f5.0f0.0f0.0f0.0f-1.0f0.0f0.0f);
                v[
            20= cTextureVertex( 2.5f5.0f0.0f0.0f0.0f-1.0f1.0f0.0f);
                
                v[
            21= cTextureVertex(-2.5f0.0f0.0f0.0f0.0f-1.0f0.0f1.0f);
                v[
            22= cTextureVertex( 2.5f5.0f0.0f0.0f0.0f-1.0f1.0f0.0f);
                v[
            23= cTextureVertex( 2.5f0.0f0.0f0.0f0.0f-1.0f1.0f1.0f);

                g_vertex_buffer
            ->Unlock();

                
            // create the texture and set filters

                D3DXCreateTextureFromFile(g_d3d_device, 
            "checker.jpg",    &g_floor_texture);
                D3DXCreateTextureFromFile(g_d3d_device, 
            "brick0.jpg",    &g_wall_texture);
                D3DXCreateTextureFromFile(g_d3d_device, 
            "ice.bmp",        &g_mirror_texture);

                g_d3d_device
            ->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
                g_d3d_device
            ->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
                g_d3d_device
            ->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);

                
            // lights

                D3DXVECTOR3 light_dir(
            0.707f-0.707f0.707f);
                D3DXCOLOR color(
            1.0f1.0f1.0f1.0f);
                D3DLIGHT9 light 
            = init_directional_light(&light_dir, &color);

                g_d3d_device
            ->SetLight(0&light);
                g_d3d_device
            ->LightEnable(0, TRUE);

                g_d3d_device
            ->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE);
                g_d3d_device
            ->SetRenderState(D3DRS_SPECULARENABLE, TRUE);

                
            // set the projection matrix
                D3DXMATRIX proj;
                D3DXMatrixPerspectiveFovLH(
            &proj, D3DX_PI/4.0f, (float)WIDTH/HEIGHT, 1.0f1000.0f);
                g_d3d_device
            ->SetTransform(D3DTS_PROJECTION, &proj);
                
                
            return true;
            }

            ///////////////////////////////////////////////////////////////////////////////////////////////////////

            void cleanup()
            {    
                safe_release
            <IDirect3DVertexBuffer9*>(g_vertex_buffer);
                safe_release
            <IDirect3DTexture9*>(g_floor_texture);
                safe_release
            <IDirect3DTexture9*>(g_wall_texture);
                safe_release
            <IDirect3DTexture9*>(g_mirror_texture);
                safe_release
            <ID3DXMesh*>(g_teapot_mesh);    
            }

            ///////////////////////////////////////////////////////////////////////////////////////////////////////

            bool display(float time_delta)
            {
                
            // update the scene

                
            if(GetAsyncKeyState(VK_LEFT) & 0x80000f)
                    g_teapot_pos.x 
            -= 3.0f * time_delta;

                
            if(GetAsyncKeyState(VK_RIGHT) & 0x80000f)
                    g_teapot_pos.x 
            += 3.0f * time_delta;

                
            static float radius = 20.0f;

                
            if(GetAsyncKeyState(VK_UP) & 0x80000f)
                    radius 
            -= 2.0f * time_delta;

                
            if(GetAsyncKeyState(VK_DOWN) & 0x80000f)
                    radius 
            += 2.0f * time_delta;

                
            static float angle = (3.0f * D3DX_PI) / 2.0f;

                
            if(GetAsyncKeyState('A'& 0x80000f)
                    angle 
            -= 0.5f * time_delta;

                
            if(GetAsyncKeyState('S'& 0x80000f)
                    angle 
            += 0.5f * time_delta;

                D3DXVECTOR3 position(cosf(angle) 
            * radius, 3.0f, sinf(angle) * radius);
                D3DXVECTOR3 target(
            0.0f0.0f0.0f);
                D3DXVECTOR3 up(
            0.0f1.0f0.0f);

                D3DXMATRIX view_matrix;
                D3DXMatrixLookAtLH(
            &view_matrix, &position, &target, &up);
                g_d3d_device
            ->SetTransform(D3DTS_VIEW, &view_matrix);

                
            // render now

                g_d3d_device
            ->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, 0xff0000001.0f0);

                g_d3d_device
            ->BeginScene();
                render_scene();
                render_shadow();
                g_d3d_device
            ->EndScene();

                g_d3d_device
            ->Present(NULL, NULL, NULL, NULL);

                
            return true;
            }

            ///////////////////////////////////////////////////////////////////////////////////////////////////////

            void render_scene()
            {
                D3DXMATRIX identity_matrix;
                D3DXMatrixIdentity(
            &identity_matrix);
                g_d3d_device
            ->SetTransform(D3DTS_WORLD, &identity_matrix);

                g_d3d_device
            ->SetStreamSource(0, g_vertex_buffer, 0sizeof(cTextureVertex));
                g_d3d_device
            ->SetFVF(TEXTURE_VERTEX_FVF);

                
            // draw the floor
                g_d3d_device->SetMaterial(&g_floor_material);
                g_d3d_device
            ->SetTexture(0, g_floor_texture);
                g_d3d_device
            ->DrawPrimitive(D3DPT_TRIANGLELIST, 02);

                
            // draw the walls
                g_d3d_device->SetMaterial(&g_wall_material);
                g_d3d_device
            ->SetTexture(0, g_wall_texture);
                g_d3d_device
            ->DrawPrimitive(D3DPT_TRIANGLELIST, 64);

                
            // draw the mirror
                g_d3d_device->SetMaterial(&g_mirror_material);
                g_d3d_device
            ->SetTexture(0, g_mirror_texture);
                g_d3d_device
            ->DrawPrimitive(D3DPT_TRIANGLELIST, 182);

                
            // draw teapot

                g_d3d_device
            ->SetMaterial(&g_teapot_material);
                g_d3d_device
            ->SetTexture(0, NULL);

                D3DXMATRIX world_matrix;
                D3DXMatrixTranslation(
            &world_matrix, g_teapot_pos.x, g_teapot_pos.y, g_teapot_pos.z);
                g_d3d_device
            ->SetTransform(D3DTS_WORLD, &world_matrix);

                g_teapot_mesh
            ->DrawSubset(0);
            }

            ///////////////////////////////////////////////////////////////////////////////////////////////////////

            void render_shadow()
            {    
                g_d3d_device
            ->SetRenderState(D3DRS_STENCILENABLE,        TRUE);
                g_d3d_device
            ->SetRenderState(D3DRS_STENCILFUNC,            D3DCMP_EQUAL);
                g_d3d_device
            ->SetRenderState(D3DRS_STENCILREF,            0x0);
                g_d3d_device
            ->SetRenderState(D3DRS_STENCILMASK,            0xffffffff);
                g_d3d_device
            ->SetRenderState(D3DRS_STENCILWRITEMASK,    0xffffffff);
                g_d3d_device
            ->SetRenderState(D3DRS_STENCILZFAIL,        D3DSTENCILOP_KEEP);
                g_d3d_device
            ->SetRenderState(D3DRS_STENCILFAIL,            D3DSTENCILOP_KEEP);
                g_d3d_device
            ->SetRenderState(D3DRS_STENCILPASS,            D3DSTENCILOP_INCR);    // increment to 1

                
            // position shadow
                D3DXVECTOR4 light_dir(0.707f-0.707f0.707f0.0f);
                D3DXPLANE    ground_plane(
            0.0f-1.0f0.0f0.0f);    // xz plane

                D3DXMATRIX shadow_matrix;
                D3DXMatrixShadow(
            &shadow_matrix, &light_dir, &ground_plane);

                D3DXMATRIX tran_matrix;
                D3DXMatrixTranslation(
            &tran_matrix, g_teapot_pos.x, g_teapot_pos.y, g_teapot_pos.z);

                D3DXMATRIX world_matrix 
            = tran_matrix * shadow_matrix;
                g_d3d_device
            ->SetTransform(D3DTS_WORLD, &world_matrix);

                
            // alpha blend the shadow
                g_d3d_device->SetRenderState(D3DRS_ALPHABLENDENABLE,    TRUE);
                g_d3d_device
            ->SetRenderState(D3DRS_SRCBLEND,            D3DBLEND_SRCALPHA);
                g_d3d_device
            ->SetRenderState(D3DRS_DESTBLEND,            D3DBLEND_INVSRCALPHA);

                D3DMATERIAL9 material 
            = init_material(BLACK, BLACK, BLACK, BLACK, 0.0f);
                material.Diffuse.a 
            = 0.5f;    // 50% transparancy

                
            // disable depth buffer so that z-fighting doesn't occur when we render the shadow
                
            // on top of the floor.
                g_d3d_device->SetRenderState(D3DRS_ZENABLE, FALSE);
                
                g_d3d_device
            ->SetMaterial(&material);
                g_d3d_device
            ->SetTexture(0, NULL);

                g_teapot_mesh
            ->DrawSubset(0);

                
            // restore render states
                g_d3d_device->SetRenderState(D3DRS_ZENABLE, TRUE);
                g_d3d_device
            ->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
                g_d3d_device
            ->SetRenderState(D3DRS_STENCILENABLE,     FALSE);    
            }

            ///////////////////////////////////////////////////////////////////////////////////////////////////////

            LRESULT CALLBACK wnd_proc(HWND hwnd, UINT msg, WPARAM word_param, LPARAM long_param)
            {
                
            switch(msg)
                {
                
            case WM_DESTROY:
                    PostQuitMessage(
            0);
                    
            break;

                
            case WM_KEYDOWN:
                    
            if(word_param == VK_ESCAPE)
                        DestroyWindow(hwnd);
                    
            break;
                }

                
            return DefWindowProc(hwnd, msg, word_param, long_param);
            }

            ///////////////////////////////////////////////////////////////////////////////////////////////////////

            int WINAPI WinMain(HINSTANCE inst, HINSTANCE, PSTR cmd_line, int cmd_show)
            {
                
            if(! init_d3d(inst, WIDTH, HEIGHT, true, D3DDEVTYPE_HAL, &g_d3d_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_d3d_device
            ->Release();

                
            return 0;
            }

             

            下載源程序


            posted on 2008-03-25 10:37 lovedday 閱讀(1802) 評論(0)  編輯 收藏 引用

            公告

            導航

            統計

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關鏈接

            搜索

            最新評論

            国产精品日韩深夜福利久久| 久久er99热精品一区二区| 久久综合综合久久97色| 99久久www免费人成精品| 久久99精品久久久久久秒播| 狠狠色狠狠色综合久久| 伊人久久大香线蕉影院95| 久久99这里只有精品国产| 99热成人精品热久久669| 久久99这里只有精品国产| 狠狠狠色丁香婷婷综合久久俺| 亚洲国产高清精品线久久 | 久久久久久久亚洲Av无码| 久久99国产综合精品免费| 久久精品中文字幕第23页| 成人妇女免费播放久久久| 久久午夜无码鲁丝片午夜精品| 国产精品久久久久久久久| 亚洲中文久久精品无码| 色欲综合久久躁天天躁| 久久久久久久综合日本亚洲| 久久AV无码精品人妻糸列| 无码人妻久久一区二区三区蜜桃| 精品九九久久国内精品| 久久综合给合久久国产免费| 欧美日韩久久中文字幕| 久久久久久av无码免费看大片| 国产精品女同久久久久电影院| 精品国产乱码久久久久软件| 久久久受www免费人成| 国产精品欧美久久久久无广告| 国产一级做a爰片久久毛片| 久久亚洲精品中文字幕| 久久综合国产乱子伦精品免费| 国产美女亚洲精品久久久综合| 国产精品久久久久久久久久影院| 少妇久久久久久被弄到高潮| 午夜精品久久影院蜜桃| 91麻豆国产精品91久久久| 日韩人妻无码一区二区三区久久99 | 国产精品久久国产精品99盘 |