www.pudn.com > dx9_texture_filtering.zip > dx9_texture_filtering.cpp
//----------------------------------------------------------------------------- // Name: dx9_texture_filtering.cpp // Author: Kevin Harris (kevin@codesampler.com) // Last Modified: 10/04/04 // Description: This sample demonstrates how to filter textures with // Direct3D. // // Direct3D texture filtering is controlled by calling // SetSamplerState() and setting either D3DSAMP_MINFILTER, // D3DSAMP_MAGFILTER, or D3DSAMP_MIPFILTER to one of the // following filtering modes: // // D3DTEXF_NONE // D3DTEXF_POINT // D3DTEXF_LINEAR // D3DTEXF_ANISOTROPIC // D3DTEXF_FLATCUBIC // D3DTEXF_GAUSSIANCUBIC // // Control Keys: F1 - Change Minification filter // F2 - Change Magnification filter // F3 - Change Mip-Map filter // F4 - Increase Mip-Map LOD Bias // F5 - Decrease Mip-Map LOD Bias // F6 - Increase Max Anisotropy value // F7 - Decrease Max Anisotropy value // // Note: This sample doesn't support Mip-Mapping yet, so F4 - F6 will have no // noticeable effect. They're only listed here for completeness and // future expansion. // // ---------------------------------------------------------------------------- // // D3DSAMP_MINFILTER // // Accepted Values: // // D3DTEXF_NONE ? // D3DTEXF_POINT // D3DTEXF_LINEAR // D3DTEXF_ANISOTROPIC // // Default Value: // // D3DTEXF_POINT // // ---------------------------------------------------------------------------- // // D3DSAMP_MAGFILTER // // Accepted Values: // // D3DTEXF_NONE ? // D3DTEXF_POINT // D3DTEXF_LINEAR // D3DTEXF_ANISOTROPIC // D3DTEXF_FLATCUBIC (not covered in this sample) // D3DTEXF_GAUSSIANCUBIC (not covered in this sample) // // Default Value: // // D3DTEXF_POINT // // ---------------------------------------------------------------------------- // // D3DSAMP_MIPFILTER // // Accepted Values: // // D3DTEXF_NONE // D3DTEXF_POINT // D3DTEXF_LINEAR // D3DTEXF_ANISOTROPIC // // Default Value: // // D3DTEXF_NONE //----------------------------------------------------------------------------- #define STRICT #define WIN32_LEAN_AND_MEAN #include#include #include "resource.h" //----------------------------------------------------------------------------- // GLOBALS //----------------------------------------------------------------------------- HWND g_hWnd = NULL; LPDIRECT3D9 g_pD3D = NULL; LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; LPDIRECT3DVERTEXBUFFER9 g_pVertexBuffer = NULL; LPDIRECT3DTEXTURE9 g_pTexture = NULL; float g_fElpasedTime; double g_dCurrentTime; double g_dLastTime; #define D3DFVF_CUSTOMVERTEX ( D3DFVF_XYZ | D3DFVF_TEX1 ) struct Vertex { float x, y, z; float tu, tv; }; Vertex g_quadVertices[] = { {-1.0f, 1.0f, 0.0f, 0.0f,0.0f }, { 1.0f, 1.0f, 0.0f, 1.0f,0.0f }, {-1.0f,-1.0f, 0.0f, 0.0f,1.0f }, { 1.0f,-1.0f, 0.0f, 1.0f,1.0f } }; enum FilterTypes { FILTER_TYPE_NONE = 0, FILTER_TYPE_POINT, FILTER_TYPE_LINEAR, FILTER_TYPE_ANISOTROPIC }; int g_MinFilterType = FILTER_TYPE_NONE; int g_MagFilterType = FILTER_TYPE_NONE; int g_mipFilterType = FILTER_TYPE_NONE; int g_nAnisotropy = 1; float g_fMipMapLodBias = 0.0f; bool g_bChangeFilters = true; //----------------------------------------------------------------------------- // PROTOTYPES //----------------------------------------------------------------------------- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow); LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); void loadTexture(void); void init(void); void shutDown(void); void render(void); void setMagnificationFilter(void); void setMinificationFilter(void); void setMipMapFilter(void); //----------------------------------------------------------------------------- // Name: WinMain() // Desc: The application's entry point //----------------------------------------------------------------------------- int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { WNDCLASSEX winClass; MSG uMsg; memset(&uMsg,0,sizeof(uMsg)); winClass.lpszClassName = "MY_WINDOWS_CLASS"; winClass.cbSize = sizeof(WNDCLASSEX); winClass.style = CS_HREDRAW | CS_VREDRAW; winClass.lpfnWndProc = WindowProc; winClass.hInstance = hInstance; winClass.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_DIRECTX_ICON); winClass.hIconSm = LoadIcon(hInstance, (LPCTSTR)IDI_DIRECTX_ICON); winClass.hCursor = LoadCursor(NULL, IDC_ARROW); winClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); winClass.lpszMenuName = NULL; winClass.cbClsExtra = 0; winClass.cbWndExtra = 0; if( !RegisterClassEx(&winClass) ) return E_FAIL; g_hWnd = CreateWindowEx( NULL, "MY_WINDOWS_CLASS", "Direct3D (DX9) - Texturing Filtering", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 640, 480, NULL, NULL, hInstance, NULL ); if( g_hWnd == NULL ) return E_FAIL; ShowWindow( g_hWnd, nCmdShow ); UpdateWindow( g_hWnd ); init(); while( uMsg.message != WM_QUIT ) { if( PeekMessage( &uMsg, NULL, 0, 0, PM_REMOVE ) ) { TranslateMessage( &uMsg ); DispatchMessage( &uMsg ); } else { g_dCurrentTime = timeGetTime(); g_fElpasedTime = (float)((g_dCurrentTime - g_dLastTime) * 0.001); g_dLastTime = g_dCurrentTime; render(); } } shutDown(); UnregisterClass( "MY_WINDOWS_CLASS", winClass.hInstance ); return uMsg.wParam; } //----------------------------------------------------------------------------- // Name: WindowProc() // Desc: The window's message handler //----------------------------------------------------------------------------- LRESULT CALLBACK WindowProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) { switch( msg ) { case WM_KEYDOWN: { switch( wParam ) { case VK_ESCAPE: PostQuitMessage(0); break; case 112: // F1 ++g_MinFilterType; if(g_MinFilterType > 3) g_MinFilterType = 0; g_bChangeFilters = true; break; case 113: // F2 ++g_MagFilterType; if(g_MagFilterType > 3) g_MagFilterType = 0; g_bChangeFilters = true; break; case 114: // F3 ++g_mipFilterType; if(g_mipFilterType > 3) g_mipFilterType = 0; g_bChangeFilters = true; break; case 115: // F4 g_fMipMapLodBias += 1.0f; g_bChangeFilters = true; break; case 116: // F5 g_fMipMapLodBias -= 1.0f; g_bChangeFilters = true; break; case 117: // F6 g_nAnisotropy += 1; g_bChangeFilters = true; break; case 118: // F7 g_nAnisotropy -= 1; g_bChangeFilters = true; break; } } break; case WM_CLOSE: { PostQuitMessage(0); } case WM_DESTROY: { PostQuitMessage(0); } break; default: { return DefWindowProc( hWnd, msg, wParam, lParam ); } break; } return 0; } //----------------------------------------------------------------------------- // Name: loadTexture() // Desc: //----------------------------------------------------------------------------- void loadTexture(void) { D3DXCreateTextureFromFile( g_pd3dDevice, "testpattern.bmp", &g_pTexture ); g_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_NONE); g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_NONE); } //----------------------------------------------------------------------------- // Name: init() // Desc: //----------------------------------------------------------------------------- void init( void ) { g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ); D3DDISPLAYMODE d3ddm; g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ); D3DPRESENT_PARAMETERS d3dpp; ZeroMemory( &d3dpp, sizeof(d3dpp) ); d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = d3ddm.Format; d3dpp.EnableAutoDepthStencil = TRUE; d3dpp.AutoDepthStencilFormat = D3DFMT_D16; d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice ); loadTexture(); g_pd3dDevice->CreateVertexBuffer( 4*sizeof(Vertex), D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVertexBuffer, NULL ); void *pVertices = NULL; g_pVertexBuffer->Lock( 0, sizeof(g_quadVertices), (void**)&pVertices, 0 ); memcpy( pVertices, g_quadVertices, sizeof(g_quadVertices) ); g_pVertexBuffer->Unlock(); D3DXMATRIX matProj; D3DXMatrixPerspectiveFovLH( &matProj, D3DXToRadian( 45.0f ), 640.0f / 480.0f, 0.1f, 100.0f ); g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj ); g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE); g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); } //----------------------------------------------------------------------------- // Name: shutDown() // Desc: //----------------------------------------------------------------------------- void shutDown( void ) { if( g_pTexture != NULL ) g_pTexture->Release(); if( g_pVertexBuffer != NULL ) g_pVertexBuffer->Release(); if( g_pd3dDevice != NULL ) g_pd3dDevice->Release(); if( g_pD3D != NULL ) g_pD3D->Release(); } //----------------------------------------------------------------------------- // Name: render() // Desc: //----------------------------------------------------------------------------- void render( void ) { g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f), 1.0f, 0 ); static float fXrot = 0.0f; static float fYrot = 0.0f; static float fZrot = 0.0f; fXrot += 10.1f * g_fElpasedTime; fYrot += 10.2f * g_fElpasedTime; fZrot += 10.3f * g_fElpasedTime; D3DXMATRIX matWorld; D3DXMATRIX matTrans; D3DXMATRIX matRot; D3DXMatrixTranslation( &matTrans, 0.0f, 0.0f, 4.0f ); D3DXMatrixRotationYawPitchRoll( &matRot, D3DXToRadian(fXrot), D3DXToRadian(fYrot), D3DXToRadian(fZrot) ); matWorld = matRot * matTrans; g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld ); g_pd3dDevice->BeginScene(); if( g_bChangeFilters == true ) { setMinificationFilter(); setMagnificationFilter(); setMipMapFilter(); g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAXANISOTROPY, g_nAnisotropy ); g_pd3dDevice->SetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, *((LPDWORD)(&g_fMipMapLodBias))); g_bChangeFilters = false; } g_pd3dDevice->SetTexture( 0, g_pTexture ); g_pd3dDevice->SetStreamSource( 0, g_pVertexBuffer, 0, sizeof(Vertex) ); g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX ); g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 ); g_pd3dDevice->EndScene(); g_pd3dDevice->Present( NULL, NULL, NULL, NULL ); } //----------------------------------------------------------------------------- // Name : setMinificationFilter() // Desc : //----------------------------------------------------------------------------- void setMinificationFilter( void ) { if( g_MinFilterType == 0 ) g_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_NONE); if( g_MinFilterType == 1 ) g_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); if( g_MinFilterType == 2 ) g_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); if( g_MinFilterType == 3 ) g_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC); } //----------------------------------------------------------------------------- // Name : setMagnificationFilter() // Desc : //----------------------------------------------------------------------------- void setMagnificationFilter( void ) { if( g_MagFilterType == 0 ) g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_NONE); if( g_MagFilterType == 1 ) g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); if( g_MagFilterType == 2 ) g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); if( g_MagFilterType == 3 ) g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC); } //----------------------------------------------------------------------------- // Name : setMipMapFilter() // Desc : //----------------------------------------------------------------------------- void setMipMapFilter( void ) { if( g_mipFilterType == 0 ) g_pd3dDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); if( g_mipFilterType == 1 ) g_pd3dDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT); if( g_mipFilterType == 2 ) g_pd3dDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); if( g_mipFilterType == 3 ) g_pd3dDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_ANISOTROPIC); }