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

            天行健 君子當(dāng)自強(qiáng)而不息

            D3D中的模板緩存(4)

            該示例演示了如何利用D3D中的模板緩存技術(shù)同時(shí)顯示物體的鏡像和陰影。

            主程序:

            /**************************************************************************************
              Demonstrates mirrors and 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_mirror();
            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_LINEAR);

                
            // 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_mirror();
                render_shadow();

                g_d3d_device
            ->EndScene();

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

                
            return true;
            }

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

            void render_scene()
            {
                
            // 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);

                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);
            }

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

            void render_mirror()
            {
                
            // Draw Mirror quad to stencil buffer ONLY.  In this way only the stencil bits that 
                
            // correspond to the mirror will be on.  Therefore, the reflected teapot can only be 
                
            // rendered where the stencil bits are turned on, and thus on the mirror only.

                g_d3d_device
            ->SetRenderState(D3DRS_STENCILENABLE,        TRUE);
                g_d3d_device
            ->SetRenderState(D3DRS_STENCILFUNC,            D3DCMP_ALWAYS);
                g_d3d_device
            ->SetRenderState(D3DRS_STENCILREF,            0x1);
                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_REPLACE);

                
            // draw the mirror to the stencil buffer

                g_d3d_device
            ->SetStreamSource(0, g_vertex_buffer, 0sizeof(cTextureVertex));
                g_d3d_device
            ->SetFVF(TEXTURE_VERTEX_FVF);
                g_d3d_device
            ->SetMaterial(&g_mirror_material);
                g_d3d_device
            ->SetTexture(0, g_mirror_texture);

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

                g_d3d_device
            ->DrawPrimitive(D3DPT_TRIANGLELIST, 182);
                
                
            // only draw reflected teapot to the pixels where the mirror was drawn to
                g_d3d_device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL);

                
            // clear depth buffer and blend the reflected teapot with the mirror
                g_d3d_device->Clear(0, NULL, D3DCLEAR_ZBUFFER, 01.0f0);
                g_d3d_device
            ->SetRenderState(D3DRS_ALPHABLENDENABLE,    TRUE);
                g_d3d_device
            ->SetRenderState(D3DRS_SRCBLEND,            D3DBLEND_DESTCOLOR);
                g_d3d_device
            ->SetRenderState(D3DRS_DESTBLEND,            D3DBLEND_ZERO);

                
            // position reflection

                D3DXMATRIX world_matrix, translation_matrix, reflect_matrix;

                D3DXPLANE plane(
            0.0f0.0f1.0f0.0f);    // xy plane
                D3DXMatrixReflect(&reflect_matrix, &plane);

                D3DXMatrixTranslation(
            &translation_matrix, g_teapot_pos.x, g_teapot_pos.y, g_teapot_pos.z);

                world_matrix 
            = translation_matrix * reflect_matrix;

                
            // Finally, draw the reflected teapot.
                g_d3d_device->SetTransform(D3DTS_WORLD, &world_matrix);
                g_d3d_device
            ->SetMaterial(&g_teapot_material);
                g_d3d_device
            ->SetTexture(0, NULL);

                
            // reverse cull mode
                g_d3d_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);

                g_teapot_mesh
            ->DrawSubset(0);

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

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

            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;
            }

            運(yùn)行截圖:

            下載源程序


            posted on 2008-03-25 12:26 lovedday 閱讀(1097) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            公告

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關(guān)鏈接

            搜索

            最新評(píng)論

            欧洲国产伦久久久久久久| 曰曰摸天天摸人人看久久久| 青青久久精品国产免费看| 久久一区二区免费播放| 国产精品久久久久久久久软件| 久久大香萑太香蕉av| 人妻无码久久一区二区三区免费 | 99久久精品午夜一区二区| 久久久久无码精品国产| 国产福利电影一区二区三区,免费久久久久久久精 | 国产精品日韩欧美久久综合| 久久精品国产99久久香蕉| 一本大道久久东京热无码AV | 天天影视色香欲综合久久| 一本色综合网久久| 亚洲国产成人久久综合碰碰动漫3d| 久久久久亚洲AV无码专区桃色| 久久精品国产亚洲AV香蕉| 久久青草国产精品一区| 一个色综合久久| 99久久精品免费观看国产| 久久精品国产色蜜蜜麻豆| 99久久婷婷国产一区二区| 久久精品成人欧美大片| 久久精品无码免费不卡| 潮喷大喷水系列无码久久精品| 亚洲国产精品无码久久久久久曰| 久久人人妻人人爽人人爽| 久久综合色区| 99久久亚洲综合精品成人| 色婷婷久久综合中文久久蜜桃av| 久久久久久久综合综合狠狠| 久久精品国产亚洲77777| 久久天天躁夜夜躁狠狠躁2022| 亚洲综合精品香蕉久久网97| 无码AV波多野结衣久久| 一本久久综合亚洲鲁鲁五月天亚洲欧美一区二区 | 国产精品99久久久久久www| 亚洲va久久久噜噜噜久久天堂| 久久精品亚洲精品国产欧美| 99re这里只有精品热久久|