Shader 学习笔记 (1)

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;

}

你可能感兴趣的:(学习笔记)