您的位置:首页 > 其它

Shader 学习笔记 (1)

2010-11-20 00:44 330 查看

Assembly-Language shader:硬件汇编着色程序.

推荐读物:Microsoft® DirectX® 9 Programmable Graphics Pipeline

“好记性不如烂笔头,留给自己~方便他人!!” -- Baesky


使用汇编着色器的步骤为:

1.声明一个字符串形式的着色代码;

2.汇编该着色代码;

3.获得shader对象;

4.声明物体顶点;

5.填充顶点缓冲;

6.创建顶点结构声明对象;

7.设置渲染状态;

8.设置其他相关变量与变换矩阵。

----------------------------------------------------------------------------------------

★声明字符串形式的着色代码

const char* strVertexShader =

"vs_1_1 \n"

"dcl_position v0 \n"

"m4x4 v0, c0 \n"

";\n"

"";

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

★汇编该着色代码

LPD3DXBUFFER pShader = NULL;

hr = D3DXAssembleShader(

strVertexShader,

(UINT)strlen(strVertexShader),

NULL,

NULL,

D3DXSHADER_DEBUG,

&pShader,

NULL

);

if (FAILED(hr))

{

SAFE_RELEASE(pShader);

return hr;

}

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

★获得shader对象

d3dDevice->CreateVertexShader(

(DWORD*)pShader->GetBufferPoint(), &vsObj);

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

★声明物体顶点 & 填充顶点缓冲

struct CUSTOMVETEX

{

float x,y,z;

}

CUSTOMVETEX vertices[] =

{

{0,1,1},

{1,0,1},

{-1,0,1},

}

d3dDevice->CreateVertexBuffer(

3*sizeof(CUSTOMVETEX), 0, 0, D3DPOOL_DEFAULT,

&p_vb, NULL);

VOID* pVertex;

p_vb->Lock(0, sizeof(vertices), (VOID**)&pVertex, 0);

memcpy(pVertex, vertices, sizeof(vertices));

p_vb->Unlock();

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

★创建顶点结构声明对象

D3DVERTEXELEMENT9 decl[] =

{

{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,

D3DDECLUSAGE_POSITION, 0},

D3DDECL_END()

}

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

设置渲染状态与相关参数略。

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

下面是源代码:

#include <d3d9.h>
#include <D3Dx9Shader.h>

#define SAFE_RELEASE(p) { if ( (p) ) { (p)->Release(); (p) = 0; } }

LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_pD3dDevice = NULL;
LPDIRECT3DVERTEXSHADER9 m_pAsm_VS;
LPDIRECT3DVERTEXDECLARATION9 m_pVetexDel;
D3DXMATRIX m_matWorld, m_matProj, m_matView;
LPDIRECT3DVERTEXBUFFER9 vb;
D3DXVECTOR3* eye;
D3DXVECTOR3* at = new D3DXVECTOR3(0,0,0);
D3DXVECTOR3* up = new D3DXVECTOR3(0,1,0);
struct CUSTOMVERTEX
{
float x,y,z;
};

HRESULT InitShader()
{
const char* strAssemblyShader =
"vs_1_1        //version \n"
"dcl_position v0 //define  \n"
"m4x4 oPos, v0, c0 //transform \n"
";\n"
"";

LPD3DXBUFFER pShader = NULL;
HRESULT hr = D3DXAssembleShader(strAssemblyShader, (UINT)strlen(strAssemblyShader),
NULL,NULL,D3DXSHADER_DEBUG, &pShader, NULL);
if(FAILED(hr))
{
SAFE_RELEASE(pShader);
return hr;
}
hr = g_pD3dDevice->CreateVertexShader((DWORD*)pShader->GetBufferPointer(), &m_pAsm_VS);
if (FAILED(hr))
{
SAFE_RELEASE(pShader);
SAFE_RELEASE(m_pAsm_VS);
return hr;
}
SAFE_RELEASE(pShader);

CUSTOMVERTEX vertices[] =
{
{1,0,1},
{0,1,1},
{-1, 0,1},
};

if (FAILED(hr = g_pD3dDevice->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX), 0, 0, D3DPOOL_DEFAULT, &vb, NULL)))
{
SAFE_RELEASE(vb);
return hr;
}

VOID* pVertex;
if (FAILED(hr = vb->Lock(0, sizeof(vertices), (VOID**)&pVertex, 0)))
{
return hr;
}
memcpy(pVertex, vertices, sizeof(vertices));
vb->Unlock();
D3DVERTEXELEMENT9 decl[] =
{
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
D3DDECL_END()
};

if (FAILED(hr = g_pD3dDevice->CreateVertexDeclaration(decl, &m_pVetexDel)))
{
SAFE_RELEASE(m_pVetexDel);
return hr;
}

g_pD3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

D3DXMatrixIdentity(&m_matWorld);
D3DXMatrixPerspectiveFovLH(&m_matProj, D3DX_PI/4, 1.0f, 0.1f, 100.0f);

return S_OK;
}

HRESULT InitD3D(HWND hWnd)
{
if ( (g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)) == NULL )
{
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;
}

if (FAILED(InitShader()))
{
return E_FAIL;
}

return S_OK;

}

VOID CleanUp()
{
if (g_pD3D)
{
g_pD3D->Release();
g_pD3D = NULL;
}
if (g_pD3dDevice)
{
g_pD3dDevice->Release();
g_pD3dDevice = NULL;
}
}

VOID Render()
{
if (NULL==g_pD3dDevice)
return;
eye = new D3DXVECTOR3(0,0,-3);
D3DXMatrixLookAtLH(&m_matView, eye,at, up);
g_pD3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(128,128,180), 1.0f, 0);
if (SUCCEEDED(g_pD3dDevice->BeginScene()))
{

//TODO:render scene
if (vb)
{
D3DXMATRIX mat;
D3DXMatrixMultiply(&mat, &m_matWorld, &m_matView);
D3DXMatrixMultiply(&mat, &mat, &m_matProj);
D3DXMatrixTranspose(&mat, &mat);

g_pD3dDevice->SetVertexShaderConstantF(0, (float*)&mat, 4);
g_pD3dDevice->SetVertexDeclaration(m_pVetexDel);
g_pD3dDevice->SetVertexShader(m_pAsm_VS);
g_pD3dDevice->SetStreamSource(0, vb, 0, sizeof(CUSTOMVERTEX));
g_pD3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,1);
g_pD3dDevice->SetVertexShader(NULL);
}

g_pD3dDevice->EndScene();
}
g_pD3dDevice->Present(NULL, NULL, NULL, NULL);

}

LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}

break;
}

return DefWindowProc(hWnd, msg, wParam, lParam);
}

INT WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR cmdLine, int ShowCmd)
{
WNDCLASSEX wc =
{
sizeof( WNDCLASSEX ), CS_CLASSDC, MsgProc, 0L, 0L,
GetModuleHandle( NULL ), NULL, NULL, NULL, NULL,
L"baesky", NULL
};
RegisterClassEx( &wc );

// Create the application's window
HWND hWnd = CreateWindow( L"baesky", L"我写的很乱 >_<",
WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,
NULL, NULL, wc.hInstance, NULL );
if (SUCCEEDED(InitD3D(hWnd)))
{
ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd);

// Enter the message loop
MSG msg;
ZeroMemory( &msg, sizeof( msg ) );
while( msg.message != WM_QUIT )
{
if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
Render();
}

}
CleanUp();
UnregisterClass(L"baesky", hInstance);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: