原文:http://msdn.microsoft.com/en-us/library/bb219690%28v=vs.85%29.aspx
是关于在direct3d9中,对于屏幕空间中,将贴图映射到像素的问题
以下是pixel shader源代码(aaa.ps.txt)
texture MyTexture; sampler2D MySampler = sampler_state { Texture = <MyTexture>; MinFilter = LINEAR; MagFilter = LINEAR; AddressU = Clamp; AddressV = Clamp; }; float4 TextureLookupPS(float2 vTexCoord : TEXCOORD0) : COLOR { return tex2D(MySampler, vTexCoord); }以下是主程序代码(main.cpp)
#include <d3d9.h> #include <d3dx9.h> #pragma comment(lib, "d3d9.lib") #pragma comment(lib, "d3dx9.lib") LPDIRECT3D9 g_pD3D = NULL; LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; LPDIRECT3DTEXTURE9 g_pTexture = NULL; LPDIRECT3DPIXELSHADER9 g_pPS = NULL; LPD3DXCONSTANTTABLE g_pPSConstantTable; #define SAFE_RELEASE(p) if(p) {p->Release();} struct CUSTOMVERTEX { FLOAT x, y, z, rhw; FLOAT tu, tv; }; #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_TEX1) HRESULT Init(HWND hWnd) { if(NULL == (g_pD3D = Direct3DCreate9(D3D_SDK_VERSION))) return E_FAIL; D3DPRESENT_PARAMETERS d3dpp = {0}; d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice))) return E_FAIL; if(FAILED(D3DXCreateTextureFromFile(g_pd3dDevice, L"aaa.bmp", &g_pTexture))) return E_FAIL; LPD3DXBUFFER pShader; LPD3DXBUFFER pErrorMsgs; if(FAILED(D3DXCompileShaderFromFile(L"aaa.ps.txt", NULL, NULL, "TextureLookupPS", "ps_2_0", 0, &pShader, &pErrorMsgs, &g_pPSConstantTable))) { MessageBoxA(NULL, (LPSTR)pErrorMsgs->GetBufferPointer(), "Error", MB_OK); SAFE_RELEASE(pErrorMsgs); return E_FAIL; } if(FAILED(g_pd3dDevice->CreatePixelShader((DWORD *)pShader->GetBufferPointer(), &g_pPS))) return E_FAIL; SAFE_RELEASE(pShader); SAFE_RELEASE(pErrorMsgs); return S_OK; } VOID Render(void) { HRESULT hres; hres = g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 255 ), 1.0f, 0); if(SUCCEEDED(hres = g_pd3dDevice->BeginScene())) { CUSTOMVERTEX vertices[] = { {0.0f, 0.0f, 0.5f, 1.0f, 0.0f, 0.0f}, {4.0f, 0.0f, 0.5f, 1.0f, 1.0f, 0.0f}, {4.0f, 4.0f, 0.5f, 1.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 0.5f, 1.0f, 0.0f, 0.0f}, {4.0f, 4.0f, 0.5f, 1.0f, 1.0f, 1.0f}, {0.0f, 4.0f, 0.5f, 1.0f, 0.0f, 1.0f}, }; //for(int i = 0; i < sizeof(vertices) / sizeof(CUSTOMVERTEX); i++) //{ // vertices[i].x -= 0.5f; // vertices[i].y -= 0.5f; //} hres = g_pd3dDevice->SetPixelShader(g_pPS); UINT TextureSamplerIndex = g_pPSConstantTable->GetSamplerIndex("MySampler"); hres = g_pd3dDevice->SetTexture(TextureSamplerIndex, g_pTexture); hres = g_pd3dDevice->SetSamplerState(TextureSamplerIndex, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); hres = g_pd3dDevice->SetSamplerState(TextureSamplerIndex, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); hres = g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX); hres = g_pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, vertices, sizeof(CUSTOMVERTEX)); hres = g_pd3dDevice->EndScene(); } hres = g_pd3dDevice->Present(NULL, NULL, NULL, NULL); } VOID Cleanup(void) { SAFE_RELEASE(g_pPSConstantTable); SAFE_RELEASE(g_pPS); SAFE_RELEASE(g_pTexture); SAFE_RELEASE(g_pd3dDevice); SAFE_RELEASE(g_pD3D); } LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch( msg ) { case WM_DESTROY: Cleanup(); PostQuitMessage( 0 ); return 0; } return DefWindowProc(hWnd, msg, wParam, lParam); } INT WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, INT) { WNDCLASSEX wc = {sizeof( WNDCLASSEX ), CS_CLASSDC, MsgProc, 0L, 0L, GetModuleHandle( NULL ), NULL, NULL, NULL, NULL, L"MappingTexels", NULL}; RegisterClassEx(&wc); HWND hWnd = CreateWindow(L"MappingTexels", L"MappingTexels", WS_OVERLAPPEDWINDOW, 100, 100, 300, 300, NULL, NULL, wc.hInstance, NULL); if(SUCCEEDED(Init(hWnd))) { ShowWindow(hWnd, SW_SHOWDEFAULT); UpdateWindow(hWnd); MSG msg = {0}; while(msg.message != WM_QUIT) { if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } else Render(); } } UnregisterClass(L"MappingTexels", wc.hInstance); return 0; }