• <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)自強而不息

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

            紋理尋址模式

            Direct3D應(yīng)用程序可以為任何圖元的任何頂點指定紋理坐標(biāo),通常使用的 u、v 紋理坐標(biāo)的取值范圍是[0.0, 1.0],但是通過設(shè)置該范圍外的坐標(biāo)值,可以得到紋理映射的特殊效果。

            雖然系統(tǒng)允許紋理坐標(biāo)取[0.0, 1.0]范圍外的值,但硬件極限常常影響紋理坐標(biāo)的取值范圍。當(dāng)調(diào)用函數(shù)IDirect3DDevice9::GetDeviceCaps()得到設(shè)備性能后,一個渲染設(shè)備將此極限值放在結(jié)構(gòu)D3DCAPS的成員MaxTextureRepeat中。這個成員的值表示該設(shè)備能允許的紋理坐標(biāo)取值范圍。例如,該值是128,那么輸入的紋理坐標(biāo)必須在范圍[-128, 128]中,使用這個范圍之外的紋理坐標(biāo)是無效的。

            對MaxTextureRepeat的解釋也受D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE的影響。當(dāng)設(shè)置了該標(biāo)志位,那么結(jié)構(gòu)D3DCAPS9的成員MaxTextureRepeat的使用就像前面所講的一樣;但如果沒有設(shè)置該標(biāo)志位,紋理坐標(biāo)范圍就根據(jù)紋理的大小和MaxTextureRepeat的值而定。假定一個紋理的大小為32 x 32像素,MaxTextureRepeat的值是512,那么512/32 = 16,有效的紋理坐標(biāo)范圍就是[-16, 16]。

            Direct3D定義了4種紋理尋址模式來處理紋理坐標(biāo)超出[0, 1]范圍的紋理映射方法,它們分別是重疊映射尋址(wrap texture address mode)、鏡像紋理尋址(mirror texture address mode)、夾取紋理尋址(clamp texture address mode)、邊框顏色紋理尋址(border color texture address mode)。

             

            重疊紋理尋址模式

            使用重疊紋理尋址模式時,Direct3D會在每個整數(shù)紋理坐標(biāo)連接處自動重復(fù)紋理。例如,應(yīng)用程序創(chuàng)建了一個正方形圖元,并指定4個頂點的紋理坐標(biāo)為(0.0, 0.0)、(0.0, 3.0)、(3.0, 3.0)、(3.0, 0.0)。使用重疊紋理尋址,Direct3D就會在u、v方向各復(fù)制3遍原始紋理,如下圖所示:

            可以調(diào)用函數(shù)IDirect3DDevice9::SetSamplerState()設(shè)置紋理尋址模式。設(shè)置第一個參數(shù)為紋理層序號,第二個參數(shù)為D3DSAMP_ADDRESSU或D3DSAMP_ADDRESSV,表示對紋理的u方向或v方向設(shè)置紋理尋址模式,第三個參數(shù)設(shè)為相應(yīng)的紋理尋址模式,可以取枚舉類型D3DTEXTUREADDRESS中的一個。

            Defines constants that describe the supported texture-addressing modes.

            typedef enum D3DTEXTUREADDRESS
            {
            D3DTADDRESS_WRAP = 1,
            D3DTADDRESS_MIRROR = 2,
            D3DTADDRESS_CLAMP = 3,
            D3DTADDRESS_BORDER = 4,
            D3DTADDRESS_MIRRORONCE = 5,
            D3DTADDRESS_FORCE_DWORD = 0x7fffffff,
            } D3DTEXTUREADDRESS, *LPD3DTEXTUREADDRESS;

            Constants

            D3DTADDRESS_WRAP
            Tile the texture at every integer junction. For example, for u values between 0 and 3, the texture is repeated three times; no mirroring is performed.
            D3DTADDRESS_MIRROR
            Similar to D3DTADDRESS_WRAP, except that the texture is flipped at every integer junction. For u values between 0 and 1, for example, the texture is addressed normally; between 1 and 2, the texture is flipped (mirrored); between 2 and 3, the texture is normal again; and so on.
            D3DTADDRESS_CLAMP
            Texture coordinates outside the range [0.0, 1.0] are set to the texture color at 0.0 or 1.0, respectively.
            D3DTADDRESS_BORDER
            Texture coordinates outside the range [0.0, 1.0] are set to the border color.
            D3DTADDRESS_MIRRORONCE
            Similar to D3DTADDRESS_MIRROR and D3DTADDRESS_CLAMP. Takes the absolute value of the texture coordinate (thus, mirroring around 0), and then clamps to the maximum value. The most common usage is for volume textures, where support for the full D3DTADDRESS_MIRRORONCE texture-addressing mode is not necessary, but the data is symmetric around the one axis.
            D3DTADDRESS_FORCE_DWORD
            Forces this enumeration to compile to 32 bits in size. Without this value, some compilers would allow this enumeration to compile to a size other than 32 bits. This value is not used.

            下列示例代碼設(shè)置紋理層0的u, v方向?qū)ぶ纺J綖橹丿B紋理尋址。

            g_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
            g_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);

            重疊紋理尋址是Direct3D中缺省的尋址模式,也是三維系統(tǒng)中最常用的尋址模式之一。在渲染具有諸如磚墻之類紋理的物體時,如果使用包含一整張磚墻的紋理貼圖會占用較多的內(nèi)存,通常只需載入一張具有一塊或多塊磚瓦的較小的紋理貼圖,再把它按照重疊紋理尋址模式在物體表面映射多次,就可以達到和使用整張磚墻貼圖同樣的效果。

             

            鏡像紋理尋址模式

            使用鏡像紋理尋址模式時,Direct3D會在每個整數(shù)紋理坐標(biāo)連接處自動復(fù)制并翻轉(zhuǎn)紋理。例如,應(yīng)用程序創(chuàng)建了一個正方形圖元,并指定4個頂點的紋理坐標(biāo)為(0.0, 0.0)、(0.0, 3.0)、(3.0, 3.0)、(3.0, 0.0)。采用鏡像紋理尋址模式,Direct3D就會在u、v方向各復(fù)制3遍并翻轉(zhuǎn)原始紋理圖,所有的行和列都是前一行或列的鏡像,如下圖所示:

            用枚舉類型D3DTEXTUREADDRESS的成員D3DTADDRESS_MIRROR指定鏡像紋理尋址模式。下面的示例代碼設(shè)置紋理層0的u、v方向?qū)ぶ纺J綖殓R像紋理尋址模式:

            g_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR);
            g_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR);

             

            夾取紋理尋址模式

            夾取紋理尋址模式將紋理坐標(biāo)夾取在[0.0, 1.0]范圍之內(nèi)。也就是說,它將紋理復(fù)制一遍,然后將紋理邊緣像素的顏色延伸。例如,應(yīng)用程序創(chuàng)建了一個正方形圖元,并指定4個頂點的紋理坐標(biāo)為(0.0, 0.0)、(0.0, 3.0)、(3.0, 3.0)、(3.0, 0.0)。將u、v方向上的紋理尋址模式都設(shè)置為夾取紋理尋址模式時的效果如下圖所示:

            原紋理

            使用夾取紋理尋址模式后的效果圖

            用枚舉類型D3DTEXTUREADDRESS的成員D3DTADDRESS_CLAMP指定夾取紋理尋址模式。下面的示例代碼設(shè)置紋理層0的u、v方向?qū)ぶ纺J綖閵A取紋理尋址模式:

            g_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
            g_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);

             

            邊框顏色紋理尋址模式

            邊框顏色紋理尋址模式用枚舉類型D3DTEXTUREADDRESS的成員D3DTADDRESS_BORDER指定,當(dāng)紋理坐標(biāo)超出[0.0, 1.0]范圍時,Direct3D使用邊框顏色代替紋理顏色。

            邊框顏色通過調(diào)用函數(shù)IDirect3DDevice9::SetSamplerState()設(shè)置,第一個參數(shù)設(shè)為紋理層序號,第二個參數(shù)設(shè)為D3DSAMP_BORDERCOLOR,第三個參數(shù)設(shè)為所需的邊框顏色,為D3DCOLOR類型,以32位整數(shù)表示A、R、G、B顏色。下面的示例代碼指定邊框顏色為紅色,并設(shè)置紋理層0的u、v方向?qū)ぶ纺J綖檫吙蝾伾y理尋址模式。

            g_device->SetSamplerState(0, D3DSAMP_BORDERCOLOR, 0xFFFF0000);
            g_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
            g_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);

            渲染的結(jié)果如下圖所示:

            原紋理

            使用邊框顏色紋理尋址模式后的效果圖

             

            紋理尋址模式示例程序

            示例程序演示了重疊紋理尋址、鏡像紋理尋址、夾取紋理尋址和邊框顏色紋理尋址4種不同的紋理尋址模式的效果,其效果圖如上面貼圖所示。

            #include <d3dx9.h>

            #pragma warning(disable : 
            4127)

            #define TEXTURE_ADDRESS_WRAP    1
            #define TEXTURE_ADDRESS_MIRROR    2
            #define TEXTURE_ADDRESS_CLAMP    3
            #define TEXTURE_ADDRESS_BORDER    4

            #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_texture1;
            IDirect3DTexture9
            *        g_texture2;
            int                        g_texture_address_mode = TEXTURE_ADDRESS_WRAP;

            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-10.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, "texture1.bmp"&g_texture1)))
                {
                    MessageBox(NULL, 
            "Create texture failed!""ERROR", MB_OK);
                    
            return false;
                }

                
            if(FAILED(D3DXCreateTextureFromFile(g_device, "texture2.bmp"&g_texture2)))
                {
                    MessageBox(NULL, 
            "Create texture failed!""ERROR", MB_OK);
                    
            return false;
                }

                sCustomVertex vertices[] 
            =
                {
                    { 
            -3,   -3,  0.0f,  0.0f3.0f},   
                    { 
            -3,    3,  0.0f,  0.0f0.0f},    
                    {  
            3,   -3,  0.0f,  3.0f3.0f},    
                    {  
            3,    3,  0.0f,  3.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);
                g_device
            ->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
                
                
            return true;
            }

            void cleanup()
            {
                release_com(g_texture1);
                release_com(g_texture2);
                release_com(g_vertex_buffer);
                release_com(g_device);
                release_com(g_d3d);
            }

            void setup_texture()
            {
                
            switch(g_texture_address_mode)
                {
                
            case TEXTURE_ADDRESS_WRAP:
                    g_device
            ->SetTexture(0, g_texture1);
                    g_device
            ->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
                    g_device
            ->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
                    
            break;

                
            case TEXTURE_ADDRESS_MIRROR:
                    g_device
            ->SetTexture(0, g_texture1);
                    g_device
            ->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR);
                    g_device
            ->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR);
                    
            break;

                
            case TEXTURE_ADDRESS_CLAMP:
                    g_device
            ->SetTexture(0, g_texture2);
                    g_device
            ->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
                    g_device
            ->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
                    
            break;

                
            case TEXTURE_ADDRESS_BORDER:
                    g_device
            ->SetTexture(0, g_texture2);
                    g_device
            ->SetSamplerState(0, D3DSAMP_BORDERCOLOR, 0xFFFF0000);
                    g_device
            ->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
                    g_device
            ->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
                    
            break;        
                }
            }

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

                g_device
            ->BeginScene();

                setup_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"
                        g_texture_address_mode = TEXTURE_ADDRESS_WRAP;
                        
            break;

                    
            case 50:    // press key "2"
                        g_texture_address_mode = TEXTURE_ADDRESS_MIRROR;
                        
            break;

                    
            case 51:    // press key "3"
                        g_texture_address_mode = TEXTURE_ADDRESS_CLAMP;
                        
            break;

                    
            case 52:    // press key "4"
                        g_texture_address_mode = TEXTURE_ADDRESS_BORDER;
                        
            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, 200100480480,
                                         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 14:03 lovedday 閱讀(3856) 評論(0)  編輯 收藏 引用


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


            公告

            導(dǎo)航

            統(tǒng)計

            常用鏈接

            隨筆分類(178)

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

            搜索

            最新評論

            久久国产精品二国产精品| 99久久精品久久久久久清纯| 免费一级欧美大片久久网| 久久久久国色AV免费观看| 亚洲国产成人精品无码久久久久久综合 | 久久人人爽人人爽人人片AV东京热| 色欲综合久久躁天天躁| 久久久久亚洲av成人网人人软件 | 久久精品国产影库免费看| 精品久久久久久无码人妻热| 要久久爱在线免费观看| 久久精品国产亚洲AV香蕉| 精品久久综合1区2区3区激情| 久久99九九国产免费看小说| 久久久久久人妻无码| 国产亚洲美女精品久久久| 久久综合久久美利坚合众国| 99久久免费国产特黄| 久久国产福利免费| 国产人久久人人人人爽| 少妇久久久久久被弄到高潮 | 久久综合色区| 91精品国产综合久久香蕉| 一级做a爰片久久毛片毛片| 久久国产一区二区| 久久夜色精品国产噜噜亚洲AV| 国产精品成人精品久久久| 久久亚洲AV成人无码国产| 欧美激情精品久久久久久久| 久久96国产精品久久久| 久久亚洲中文字幕精品有坂深雪| 国内精品久久久久久久亚洲| 国产Av激情久久无码天堂| 久久久久高潮综合影院| 香港aa三级久久三级老师2021国产三级精品三级在| 久久婷婷激情综合色综合俺也去| 久久久久国色AV免费观看| 欧美伊人久久大香线蕉综合69| 久久亚洲av无码精品浪潮| 午夜视频久久久久一区| 韩国三级中文字幕hd久久精品 |