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

            天行健 君子當自強而不息

            紋理映射基礎(4)

            最近點采樣

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

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

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

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

             

            線性紋理過濾

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

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

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

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

             

            各項異性紋理過濾

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

            要使用各項異性紋理過濾,還應當設置最大各項異性程度值。通過將函數IDirect3DDevive9::SetSamplerState()的第一個參數設為紋理層索引,第二個參數設為D3DSAMP_MAXANISOTOPY,第三個參數設為大于1的任何值,可以完成最大各項異性程度值的設置。下面的示例代碼指定了最大各項異性值為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時,表示禁用各項異性過濾。一般說來,其值越大,圖像效果越好,計算量越大,速度越慢。需要注意的是,在設置最大各項異性之前,應調用IDirect3D9::GetDeviceCaps()函數,查詢當前設備支持的Direct3D特性,獲取當前設備支持的最大各項異性度的取值范圍,具體代碼如下:

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

             

            紋理過濾方式示例程序

            按下數字鍵“1”使用最近點采樣紋理過濾方式,按下數字鍵“2”使用線性紋理過濾方式,按下數字鍵“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: 紋理映射基礎(4) 2009-12-22 12:58 dujid

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

            公告

            導航

            統計

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關鏈接

            搜索

            最新評論

            午夜精品久久久久久影视777| 奇米影视7777久久精品| 亚洲午夜精品久久久久久浪潮 | 久久久噜噜噜久久中文字幕色伊伊 | 久久国产三级无码一区二区 | 久久久无码精品亚洲日韩按摩 | 一本一本久久aa综合精品| 久久国产乱子伦精品免费强| 国产一区二区三精品久久久无广告| 亚洲伊人久久综合中文成人网| 久久香综合精品久久伊人| 国内精品久久久久久久影视麻豆| 国产精品内射久久久久欢欢| 色偷偷久久一区二区三区| 久久久精品免费国产四虎| 久久精品一本到99热免费| 99久久综合国产精品二区| 久久天天躁狠狠躁夜夜avapp| 欧美精品久久久久久久自慰| 99久久精品免费看国产免费| 久久久无码一区二区三区| 久久WWW免费人成—看片| 久久久久久久97| 亚洲乱码日产精品a级毛片久久| 国产精品久久久久久一区二区三区| 蜜臀久久99精品久久久久久小说 | 亚洲精品蜜桃久久久久久| 欧美黑人激情性久久| 狠狠人妻久久久久久综合蜜桃| 亚洲AV日韩AV天堂久久| 欧美粉嫩小泬久久久久久久| 国内精品久久久久影院亚洲| 久久99精品免费一区二区| 51久久夜色精品国产| 国产精品无码久久久久久| 国产精品久久久久久久久免费| 狠狠精品久久久无码中文字幕| 亚洲国产视频久久| 久久99精品久久久久久动态图 | 午夜精品久久久久久99热| 亚洲精品国产自在久久|