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

            天行健 君子當自強而不息

            紋理映射基礎(chǔ)(4)

            最近點采樣

            最近點采樣是4種過濾方式中速度最快但效果最差的過濾方式。Direct3D計算得到的紋理元素地址通常是一個浮點數(shù)值,而非整數(shù)的紋理下標值,當使用最近點采樣時,Direct3D會復制與這個浮點值地址最接近的整數(shù)地址的紋理元素的顏色。

            設(shè)置最近點采樣的具體方法如下:調(diào)用IDirect3DDevice9::SetSamplerState(),可分別設(shè)置紋理過濾的放大過濾器和縮小過濾器。將第一個參數(shù)設(shè)置為紋理過濾器關(guān)聯(lián)的紋理層序號(0~7)。如果要設(shè)置放大過濾器,第二個參數(shù)設(shè)為D3DSAMP_MAGFILTER,如果要設(shè)置縮小過濾器,第二個參數(shù)設(shè)為D3DSAMP_MINFILTER。第三個參數(shù)可設(shè)為表示最近點采樣的枚舉常量D3DTEXF_POINT。下列代碼將紋理層0的紋理過濾方式設(shè)置為最近點采樣。

            g_device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
            g_device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);

            如果紋理的大小和屏幕圖元的實際大小將近,那么采用最近點采樣方法對圖像質(zhì)量的影響不大。但是,如果大小相差太多,就會降低圖像精度,從而影響圖像質(zhì)量,出現(xiàn)色塊或閃爍的失真現(xiàn)象。

             

            線性紋理過濾

            線性紋理過濾是目前使用最廣泛的紋理過濾方法。它與最近點采樣相比,能有效地提高圖像的顯示質(zhì)量,并且對系統(tǒng)性能影響不大。線性紋理過濾取得與計算得到的紋理元素的浮點地址最接近的上、下、左、右4個紋理元素,對這4個紋理元素進行加權(quán)平均,得到最終顯示的顏色值。

            與設(shè)置最近點采樣的方法相似,調(diào)用函數(shù)IDirect3DDevice9::SetSamplerState()設(shè)置線性紋理過濾,所不同的是第三個參數(shù)設(shè)置為D3DTEXF_LINEAR。下面的代碼將紋理層0的放大和縮小過濾器設(shè)置為線性紋理過濾。

            g_device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
            g_device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);

            因為是在單一紋理層上的線性過濾,而且是x、y方向上的線性過濾,所以稱為雙線性紋理過濾。目前大多數(shù)顯卡都為線性紋理過濾進行了優(yōu)化,所以使用線性紋理過濾一方面可以獲得較好的圖形質(zhì)量,另一方面對程序性能影響不大。

             

            各項異性紋理過濾

            當三維物體表面與投影平面不平行時,它在屏幕上的投影會有拉長或扭曲,這種現(xiàn)象稱為各項異性(anisotropy)。當一個各向異性圖元的像素映射到紋理元素時,它的形狀發(fā)生扭曲。Direct3D根據(jù)屏幕像素反向轉(zhuǎn)換到紋理元素的延長度,決定各項異性程度。

            要使用各項異性紋理過濾,還應當設(shè)置最大各項異性程度值。通過將函數(shù)IDirect3DDevive9::SetSamplerState()的第一個參數(shù)設(shè)為紋理層索引,第二個參數(shù)設(shè)為D3DSAMP_MAXANISOTOPY,第三個參數(shù)設(shè)為大于1的任何值,可以完成最大各項異性程度值的設(shè)置。下面的示例代碼指定了最大各項異性值為4。

            g_device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC);
            g_device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC);
            g_device->SetSamplerState(0, D3DSAMP_MAXANISOTROPY, 4);

            最大各項異性程度值D3DSAMP_MAXANISOTROPY為1時,表示禁用各項異性過濾。一般說來,其值越大,圖像效果越好,計算量越大,速度越慢。需要注意的是,在設(shè)置最大各項異性之前,應調(diào)用IDirect3D9::GetDeviceCaps()函數(shù),查詢當前設(shè)備支持的Direct3D特性,獲取當前設(shè)備支持的最大各項異性度的取值范圍,具體代碼如下:

            DWORD get_max_anisotropy(IDirect3DDevice9* device)
            {
            D3DCAPS9 caps;
            device->GetDeviceCaps(&caps);
            	return caps.MaxAnisotropy;
            }

             

            紋理過濾方式示例程序

            按下數(shù)字鍵“1”使用最近點采樣紋理過濾方式,按下數(shù)字鍵“2”使用線性紋理過濾方式,按下數(shù)字鍵“3”使用各項異性紋理過濾方式。

             

            源程序:

            #include <d3dx9.h>

            #pragma warning(disable : 
            4127)

            #define CLASS_NAME    "GameApp"

            #define release_com(p)    do { if(p) { (p)->Release(); (p) = NULL; } } while(0)

            IDirect3D9
            *                g_d3d;
            IDirect3DDevice9
            *        g_device;
            IDirect3DVertexBuffer9
            * g_vertex_buffer;
            IDirect3DTexture9
            *        g_texture;

            struct sCustomVertex
            {
                
            float x, y, z;
                
            float u, v;
            };

            #define D3DFVF_CUSTOM_VERTEX (D3DFVF_XYZ | D3DFVF_TEX1) 

            void setup_matrices()
            {
                
            // build world matrix
                
                D3DXMATRIX mat_world;
                D3DXMatrixIdentity(
            &mat_world);
                g_device
            ->SetTransform(D3DTS_WORLD, &mat_world);

                
            // setup view matrix

                D3DXVECTOR3 eye(
            0.0f0.0f-8.0f);
                D3DXVECTOR3 at(
            0.0f0.0f0.0f);
                D3DXVECTOR3 up(
            0.0f1.0f0.0f);

                D3DXMATRIX mat_view;
                D3DXMatrixLookAtLH(
            &mat_view, &eye, &at, &up);
                g_device
            ->SetTransform(D3DTS_VIEW, &mat_view);

                
            // setup projection matrix

                D3DXMATRIX mat_proj;
                D3DXMatrixPerspectiveFovLH(
            &mat_proj, D3DX_PI/41.0f1.0f100.0f);
                g_device
            ->SetTransform(D3DTS_PROJECTION, &mat_proj);
            }

            bool init_graphics()
            {    
                
            if(FAILED(D3DXCreateTextureFromFile(g_device, "texture.jpg"&g_texture)))
                {
                    MessageBox(NULL, 
            "Create texture failed!""ERROR", MB_OK);
                    
            return false;
                }

                sCustomVertex vertices[] 
            =
                {
                    { 
            -3,   -3,  0.0f,  0.0f1.0f},   
                    { 
            -3,    3,  0.0f,  0.0f0.0f},    
                    {  
            3,   -3,  0.0f,  1.0f1.0f},    
                    {  
            3,    3,  0.0f,  1.0f0.0f }

                };

                g_device
            ->CreateVertexBuffer(sizeof(vertices), 0, D3DFVF_CUSTOM_VERTEX, D3DPOOL_MANAGED, &g_vertex_buffer, NULL);

                
            void* ptr;

                g_vertex_buffer
            ->Lock(00, (void**)&ptr, 0);
                memcpy(ptr, vertices, 
            sizeof(vertices));    
                g_vertex_buffer
            ->Unlock();

                
            return true;
            }

            bool init_d3d(HWND hwnd)
            {
                g_d3d 
            = Direct3DCreate9(D3D_SDK_VERSION);

                
            if(g_d3d == NULL)
                    
            return false;

                D3DPRESENT_PARAMETERS d3dpp;
                ZeroMemory(
            &d3dpp, sizeof(d3dpp));

                d3dpp.Windowed            
            = TRUE;
                d3dpp.SwapEffect        
            = D3DSWAPEFFECT_DISCARD;
                d3dpp.BackBufferFormat    
            = D3DFMT_UNKNOWN;

                
            if(FAILED(g_d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                              
            &d3dpp, &g_device)))
                {
                    
            return false;
                }
                
                
            if(! init_graphics())
                    
            return false;

                setup_matrices();

                g_device
            ->SetRenderState(D3DRS_LIGHTING, FALSE);    
                
                
            return true;
            }

            void cleanup()
            {
                release_com(g_texture);
                release_com(g_vertex_buffer);
                release_com(g_device);
                release_com(g_d3d);
            }

            void render()
            {
                g_device
            ->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(555), 1.0f0);

                g_device
            ->BeginScene();

                g_device
            ->SetTexture(0, g_texture);

                g_device
            ->SetStreamSource(0, g_vertex_buffer, 0sizeof(sCustomVertex));
                g_device
            ->SetFVF(D3DFVF_CUSTOM_VERTEX);
                g_device
            ->DrawPrimitive(D3DPT_TRIANGLESTRIP, 02);

                g_device
            ->EndScene();

                g_device
            ->Present(NULL, NULL, NULL, NULL);
            }

            LRESULT WINAPI WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
            {
                
            switch(msg)
                {
                
            case WM_KEYDOWN:
                    
            switch(wParam)
                    {
                    
            case VK_ESCAPE:
                        DestroyWindow(hwnd);
                        
            break;

                    
            case 49:    // press key "1", use nearest point texture filter mode
                        g_device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
                        g_device
            ->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
                        
            break;

                    
            case 50:    // press key "2", use linear texture filter mode
                        g_device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
                        g_device
            ->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
                        
            break;

                    
            case 51:    // press key "3", use anisotropy texture filter mode            
                        g_device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC);
                        g_device
            ->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC);
                        g_device
            ->SetSamplerState(0, D3DSAMP_MAXANISOTROPY, 8);
                        
            break;
                    }        
                        
                    
            break;    

                
            case WM_DESTROY:        
                    PostQuitMessage(
            0);
                    
            return 0;
                }

                
            return DefWindowProc(hwnd, msg, wParam, lParam);
            }

            int WINAPI WinMain(HINSTANCE inst, HINSTANCE, LPSTR, INT)
            {
                WNDCLASSEX wc;

                wc.cbSize            
            = sizeof(WNDCLASSEX);
                wc.style            
            = CS_CLASSDC;
                wc.lpfnWndProc        
            = WinProc;
                wc.cbClsExtra        
            = 0;
                wc.cbWndExtra        
            = 0;
                wc.hInstance        
            = inst;
                wc.hIcon            
            = NULL;
                wc.hCursor            
            = NULL;
                wc.hbrBackground    
            = NULL;
                wc.lpszMenuName        
            = NULL;
                wc.lpszClassName    
            = CLASS_NAME;
                wc.hIconSm            
            = NULL;

                
            if(! RegisterClassEx(&wc))
                    
            return -1;

                HWND hwnd 
            = CreateWindow(CLASS_NAME, "Direct3D App", WS_OVERLAPPEDWINDOW, 200100800600,
                                         NULL, NULL, wc.hInstance, NULL);    

                
            if(hwnd == NULL)
                    
            return -1;

                
            if(init_d3d(hwnd))
                {
                    ShowWindow(hwnd, SW_SHOWDEFAULT);
                    UpdateWindow(hwnd);

                    MSG msg;
                    ZeroMemory(
            &msg, sizeof(msg));

                    
            while(msg.message != WM_QUIT)
                    {
                        
            if(PeekMessage(&msg, NULL, 00, PM_REMOVE))
                        {
                            TranslateMessage(
            &msg);
                            DispatchMessage(
            &msg);
                        }
                            
                        render();
                        Sleep(
            10);
                    }
                }

                cleanup();
                UnregisterClass(CLASS_NAME, wc.hInstance);    

                
            return 0;
            }

             

            posted on 2008-05-07 09:05 lovedday 閱讀(2930) 評論(1)  編輯 收藏 引用

            評論

            # re: 紋理映射基礎(chǔ)(4) 2009-12-22 12:58 dujid

            LZ這篇文章寫得非常好!像這么條理清晰格式優(yōu)雅的文章太少了,內(nèi)容講述也很到位,對我有很大幫助。謝謝,加油!  回復  更多評論   

            公告

            導航

            統(tǒng)計

            常用鏈接

            隨筆分類(178)

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

            搜索

            最新評論

            国产69精品久久久久99| 热re99久久精品国产99热| 久久久精品波多野结衣| 久久久久久国产精品免费免费| 超级碰久久免费公开视频| 久久久黄片| 久久久久亚洲AV无码网站| 国产99久久久国产精品~~牛| 午夜精品久久久久成人| 国内精品九九久久久精品| 久久精品国产亚洲7777| 国产毛片欧美毛片久久久| 国产无套内射久久久国产| 国内精品伊人久久久久777| 久久精品成人国产午夜| 久久精品卫校国产小美女| 26uuu久久五月天| 少妇精品久久久一区二区三区| 久久久久国产精品嫩草影院 | 亚洲国产欧洲综合997久久| 日本精品久久久中文字幕| 国产成人精品综合久久久久| 国产精品久久久99| 精品久久久久久国产| 久久天天躁狠狠躁夜夜2020一| 久久精品无码一区二区三区免费| 奇米综合四色77777久久| 伊人久久一区二区三区无码| 精品水蜜桃久久久久久久| 91性高湖久久久久| 久久亚洲欧美日本精品| 99久久精品国产麻豆| 日产精品久久久一区二区| 五月丁香综合激情六月久久| 久久99久国产麻精品66| 国产精品成人久久久| 狠狠色丁香婷婷久久综合| 亚洲国产成人精品久久久国产成人一区二区三区综 | 久久国产成人| 成人亚洲欧美久久久久 | 亚洲一区中文字幕久久|