zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    (转)Java任务调度框架Quartz入门教程指南(二) 使用job、trigger、schedule调用定时任务
    (转)Quartz任务调度(1)概念例析快速入门
    如何解决Win10预览版一闪而过的disksnapshot.exe进程?
    【转】SSH中 整合spring和proxool 连接池
    datatables 配套bootstrap3样式使用小结(1)
    PowerDesigner16逆向工程生成PDM列注释(My Sql5.0模版)
    PowerDesigner连接mysql逆向生成pdm
    Power Designer逆向操作(从mysql5.0生成数据库的物理模型)
    范仁义js课程---53、匿名函数应用
    范仁义js课程---52、匿名函数
  • 原文地址:https://www.cnblogs.com/Baesky/p/1882323.html
Copyright © 2011-2022 走看看