看了MS.Press.DirectX.9.Programmable.Graphics.Pipeline这书。
开启Shader之路吧。
#include <Windows.h>
#include <d3dx9.h>
#include <MMSystem.h>
#define SAFE_RELEASE(p) {if(p){p->Release();p=NULL;}}
#define SAFE_DELETE(p) {if(p){delete p;p=NULL;}}
#define SAFE_DELETE_ARRAY(p) {if(p){delete [](p);p=NULL;}}
LPDIRECT3D9 g_pD3D;
LPDIRECT3DDEVICE9 g_pd3dDevice;
LPDIRECT3DVERTEXBUFFER9 g_pVB;
D3DXMATRIX g_matWorld;
D3DXMATRIX g_matView;
D3DXMATRIX g_matProj;
const char* strAsmVertexShader =
"vs_1_1 // version instruction\n"
"dcl_position v0 // define position data in register v0\n"
"dcl_color v1 // define color data in register v1\n"
"m4x4 oPos, v0, c0 // transform vertices by view/projection matrix\n"
"mov oD0, v1 // output diffuse color\n"
";\n"
"";
LPDIRECT3DVERTEXSHADER9 g_pAsm_VS;
LPDIRECT3DVERTEXDECLARATION9 g_pVertexDeclaration;
struct CUSTOMVERTEX
{
FLOAT x, y, z;
DWORD color;
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)
HRESULT InitObject()
{
// Compile and create the vertex shader
LPD3DXBUFFER pShader = NULL;
HRESULT hr = 0;
hr = D3DXAssembleShader(strAsmVertexShader,(UINT)strlen(strAsmVertexShader),
NULL, // A Null terminated array of D3DXMACROS
NULL, // #include handler
D3DXSHADER_DEBUG,
&pShader,
NULL
);
if (FAILED(hr))
{
SAFE_RELEASE(pShader);
return hr;
}
// Create the vertex shader
hr = g_pd3dDevice->CreateVertexShader(
(DWORD*)pShader->GetBufferPointer(), &g_pAsm_VS);
if (FAILED(hr))
{
SAFE_RELEASE(pShader);
SAFE_RELEASE(g_pAsm_VS);
return hr;
}
SAFE_RELEASE(pShader);
// Initialize three vertices for rendering a triangle
CUSTOMVERTEX triangle[] =
{
{ -1.0f,-1.0f, 0.0f, D3DCOLOR_RGBA(255, 255, 255, 0)},
{ 0.0f, 1.0f, 0.0f, D3DCOLOR_RGBA(0, 0, 255, 0)},
{ 1.0f,-1.0f, 0.0f, D3DCOLOR_RGBA(255, 0, 0, 0)},
};
if (FAILED(g_pd3dDevice->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX),
0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL)))
{
SAFE_RELEASE(g_pVB);
return E_FAIL;
}
VOID* pVertices;
if (FAILED(g_pVB->Lock(0,sizeof(triangle), &pVertices, 0)))
return E_FAIL;
memcpy(pVertices, triangle, sizeof(triangle));
g_pVB->Unlock();
// Create the vertex declaration
D3DVERTEXELEMENT9 decl[] =
{
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,
D3DDECLUSAGE_POSITION, 0},
{0, 12,D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT,
D3DDECLUSAGE_COLOR, 0},
D3DDECL_END()
};
if (FAILED(g_pd3dDevice->CreateVertexDeclaration(decl, &g_pVertexDeclaration)))
{
SAFE_RELEASE(g_pVertexDeclaration);
return E_FAIL;
}
// Set up render states
g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
// Set up the world matrix
D3DXMatrixIdentity(&g_matWorld);
D3DXVECTOR3 vEyePt(0.0f, 3.0f, -5.0f);
D3DXVECTOR3 vLookAtPt(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 vUp(0.0f, 1.0f, 0.0f);
//D3DXMATRIXA16 matView;
D3DXMatrixLookAtLH(&g_matView, &vEyePt, &vLookAtPt, &vUp);
//g_pd3dDevice->SetTransform(D3DTS_VIEW, &g_matView);
D3DXMatrixPerspectiveFovLH(&g_matProj, D3DX_PI/4,
1.0f, 0.1f, 100.0f);
return S_OK;
}
HRESULT InitD3D(HWND hWnd)
{
g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
if (NULL == g_pD3D)
return E_FAIL;
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
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;
}
//g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
// Turn off D3D lighting, since we are providing our own vertex colors
//g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
if (FAILED(InitObject()))
return E_FAIL;
return S_OK;
}
void SetupMatrices()
{
D3DXMATRIX matWorld;
UINT iTime = timeGetTime() % 1000;
FLOAT fAngle = iTime * ( 2.0f * D3DX_PI ) / 1000.0f;
D3DXMatrixRotationY(&matWorld, fAngle);
g_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld);
D3DXVECTOR3 vEyePt(0.0f, 3.0f, -5.0f);
D3DXVECTOR3 vLookAtPt(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 vUp(0.0f, 1.0f, 0.0f);
D3DXMATRIXA16 matView;
D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookAtPt, &vUp);
g_pd3dDevice->SetTransform(D3DTS_VIEW, &matView);
D3DXMATRIX matPoj;
D3DXMatrixPerspectiveFovLH(&matPoj, D3DX_PI/4, 1.0f, 1.0f, 100.0f);
g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matPoj);
}
void Render()
{
g_pd3dDevice->Clear(0,NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
D3DCOLOR_XRGB(0, 0, 255), 1.0f, 0);
g_pd3dDevice->BeginScene();
//SetupMatrices();
// g_pd3dDevice->SetStreamSource(0, g_pVB, 0, sizeof(CUSTOMVERTEX));
// g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
// g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
//
// g_pd3dDevice->EndScene();
if (g_pAsm_VS)
{
D3DXMATRIX compMat;
D3DXMatrixMultiply(&compMat, &g_matWorld, &g_matView);
D3DXMatrixMultiply(&compMat, &compMat, &g_matProj);
D3DXMatrixTranspose(&compMat, &compMat);
g_pd3dDevice->SetVertexShaderConstantF(0, (float*)&compMat, 4);
g_pd3dDevice->SetVertexDeclaration(g_pVertexDeclaration);
g_pd3dDevice->SetVertexShader(g_pAsm_VS);
g_pd3dDevice->SetStreamSource(0, g_pVB, 0, sizeof(CUSTOMVERTEX));
g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
g_pd3dDevice->SetVertexShader(NULL);
}
g_pd3dDevice->EndScene();
g_pd3dDevice->Present(NULL, NULL, NULL, NULL);
}
void Cleanup()
{
if (g_pd3dDevice)
g_pd3dDevice->Release();
if (g_pD3D)
g_pD3D->Release();
if (g_pVB)
g_pVB->Release();
}
LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
ValidateRect(hWnd, NULL);
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
INT WINAPI WinMain(__in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd )
{
WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0, 0,
GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
"Direct3D", NULL};
RegisterClassEx(&wc);
// Create the application window
HWND hWnd = CreateWindow("Direct3D", "Learn", WS_OVERLAPPEDWINDOW,
100, 100, 300, 300,
GetDesktopWindow(), NULL, wc.hInstance, NULL);
//ShowWindow(hWnd, SW_SHOW);
if (SUCCEEDED(InitD3D(hWnd)))
{
ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd);
MSG msg;
ZeroMemory(&msg, sizeof(msg));
while (msg.message != WM_QUIT)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
Render();
}
}
UnregisterClass( "Direct3D", wc.hInstance );
Cleanup();
}