Shaders for Game Programmers and Artists代码实现Chapter_0402

  前一篇中提到本书中用到的模型为Microsoft DirectX SDK (March 2009)/Samples/Media/misc目录下的teapot.x,在写第二个例子是发现dx提供的模型中没有纹理坐标,所以此处的模型改为RenderMonkey自带的模型,不过RenderMonkey自带的模型为.3ds格式的,需要用3DMax将其转化为.x。

   Shaders for Game Programmers and Artists代码实现Chapter_0402_第1张图片

 

#include <d3dx9.h> //----------------------------------------------------------------------------- // Desc: 全局变量 //----------------------------------------------------------------------------- LPDIRECT3D9 g_pD3D = NULL; //Direct3D对象 LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; //Direct3D设备对象 LPD3DXMESH g_pMeshTeapot = NULL; //网格模型对象 LPDIRECT3DTEXTURE9 g_pMeshTeapotTexture = NULL; //网格模型纹理 DWORD g_dwTeapotNumMaterials = 0L; //网格模型材质数量 ID3DXEffect* g_pEffect = NULL; //效果指针 //常量句柄 D3DXHANDLE hWVPMatrixHandle = NULL; //变换矩阵 D3DXHANDLE hTex0 = NULL; //纹理 D3DXHANDLE hTech0 = NULL; //技术句柄 #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_TEX1) //----------------------------------------------------------------------------- // Desc: 设置世界矩阵 //----------------------------------------------------------------------------- VOID SetWorldMatrix() { //创建并设置世界矩阵 D3DXMATRIXA16 matWorld, matRotateX, matRotateY; D3DXMatrixIdentity(&matWorld); D3DXMatrixIdentity(&matRotateX); D3DXMatrixIdentity(&matRotateY); D3DXMatrixRotationX( &matRotateX, D3DX_PI / 3.0 ); D3DXMatrixRotationY( &matRotateY, -D3DX_PI / 8.0 ); D3DXMatrixMultiply(&matWorld, &matRotateX, &matRotateY); g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld ); } //----------------------------------------------------------------------------- // Desc: 设置观察矩阵和投影矩阵 //----------------------------------------------------------------------------- VOID SetViewAndProjMatrix() { //创建并设置观察矩阵 D3DXVECTOR3 vEyePt( 0.0f, 0.0f,-250.0f ); D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f ); D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f ); D3DXMATRIXA16 matView; D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec ); g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView ); //创建并设置投影矩阵 D3DXMATRIXA16 matProj; D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 1000.0f ); g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj ); } //----------------------------------------------------------------------------- // Desc: 初始化Direct3D //----------------------------------------------------------------------------- HRESULT InitD3D( HWND hWnd ) { //创建Direct3D对象, 该对象用于创建Direct3D设备对象 if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) ) return E_FAIL; //设置D3DPRESENT_PARAMETERS结构, 准备创建Direct3D设备对象 D3DPRESENT_PARAMETERS d3dpp; ZeroMemory( &d3dpp, sizeof(d3dpp) ); d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; d3dpp.EnableAutoDepthStencil = TRUE; d3dpp.AutoDepthStencilFormat = D3DFMT_D16; //创建Direct3D设备对象 if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice ) ) ) { return E_FAIL; } //创建Effect ID3DXBuffer* errBuffer = NULL; if (FAILED(D3DXCreateEffectFromFile(g_pd3dDevice, L"0401.fx", NULL, NULL, D3DXSHADER_DEBUG | D3DXSHADER_SKIPOPTIMIZATION, NULL, &g_pEffect, &errBuffer))) { if (errBuffer) { MessageBox(0, (LPCTSTR)errBuffer->GetBufferPointer(), 0, 0); errBuffer->Release(); } return E_FAIL; } //获取常量句柄 hWVPMatrixHandle = g_pEffect->GetParameterByName(0, "matWVP"); hTex0 = g_pEffect->GetParameterByName(0, "Tex0"); hTech0 = g_pEffect->GetTechniqueByName("Basic01"); //设置环境光 g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0xffffffff ); //设置观察矩阵和投影矩阵 SetViewAndProjMatrix(); return S_OK; } //----------------------------------------------------------------------------- // Desc: 从绝对路径中提取纹理文件名 //----------------------------------------------------------------------------- void RemovePathFromFileName(LPSTR fullPath, LPWSTR fileName) { //先将fullPath的类型变换为LPWSTR WCHAR wszBuf[MAX_PATH]; MultiByteToWideChar( CP_ACP, 0, fullPath, -1, wszBuf, MAX_PATH ); wszBuf[MAX_PATH-1] = L'/0'; WCHAR* wszFullPath = wszBuf; //从绝对路径中提取文件名 LPWSTR pch=wcsrchr(wszFullPath,'//'); if (pch) lstrcpy(fileName, ++pch); else lstrcpy(fileName, wszFullPath); } //----------------------------------------------------------------------------- // Desc: 创建场景图形 //----------------------------------------------------------------------------- HRESULT InitGeometry() { LPD3DXBUFFER pD3DXMtrlBuffer; //存储网格模型材质的缓冲区对象 //从磁盘文件加载网格模型 if( FAILED( D3DXLoadMeshFromX( L"teapot.x", D3DXMESH_MANAGED, g_pd3dDevice, NULL, &pD3DXMtrlBuffer, NULL, &g_dwTeapotNumMaterials, &g_pMeshTeapot ) ) ) { MessageBox(NULL, L"Could not find airplane.x", L"Mesh", MB_OK); return E_FAIL; } //加载纹理 HRESULT hr = D3DXCreateTextureFromFile(g_pd3dDevice, L"Fieldstone.tga", &g_pMeshTeapotTexture); if (FAILED(hr)) { return E_FAIL; } //释放在加载模型文件时创建的保存模型材质和纹理数据的缓冲区对象 pD3DXMtrlBuffer->Release(); return S_OK; } //----------------------------------------------------------------------------- // Desc: 释放创建的对象 //----------------------------------------------------------------------------- VOID Cleanup() { //释放网格模型纹理 if( g_pMeshTeapotTexture ) { g_pMeshTeapotTexture->Release(); } //释放网格模型对象 if( g_pMeshTeapot != NULL ) g_pMeshTeapot->Release(); if (g_pEffect != NULL) { g_pEffect->Release(); } //释放Direct3D设备对象 if( g_pd3dDevice != NULL ) g_pd3dDevice->Release(); //释放Direct3D对象 if( g_pD3D != NULL ) g_pD3D->Release(); } //----------------------------------------------------------------------------- // Desc: 渲染场景 //----------------------------------------------------------------------------- VOID Render() { // 清除缓冲区 g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0 ); //开始渲染场景 if( SUCCEEDED( g_pd3dDevice->BeginScene() ) ) { SetWorldMatrix(); //设置世界矩阵 g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX); D3DXMATRIX matWorld, matView, matProj; g_pd3dDevice->GetTransform(D3DTS_WORLD, &matWorld); g_pd3dDevice->GetTransform(D3DTS_VIEW, &matView); g_pd3dDevice->GetTransform(D3DTS_PROJECTION, &matProj); D3DXMATRIX matWVP = matWorld * matView * matProj; g_pEffect->SetMatrix(hWVPMatrixHandle, &matWVP); g_pEffect->SetTexture(hTex0, g_pMeshTeapotTexture); // 设置要使用的Technique g_pEffect->SetTechnique(hTech0); //遍历技术中包含的所有过程进行多次渲染 UINT numPasses = 0; g_pEffect->Begin(&numPasses, 0); for (int i = 0; i < numPasses; i++) { g_pEffect->BeginPass(i); //逐块渲染网格模型 for( DWORD i=0; i<g_dwTeapotNumMaterials; i++ ) { //渲染模型 g_pMeshTeapot->DrawSubset( i ); } g_pEffect->EndPass(); } g_pEffect->End(); //场景渲染结束 g_pd3dDevice->EndScene(); } //在屏幕上显示场景 g_pd3dDevice->Present( NULL, NULL, NULL, NULL ); } //----------------------------------------------------------------------------- // Desc: 窗口过程, 处理消息 //----------------------------------------------------------------------------- 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 ); } //----------------------------------------------------------------------------- // Desc: 入口函数 //----------------------------------------------------------------------------- INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT ) { //注册窗口类 WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, L"ClassName", NULL }; RegisterClassEx( &wc ); //创建窗口 HWND hWnd = CreateWindow( L"ClassName", L"Effect 实现", WS_OVERLAPPEDWINDOW, 200, 100, 500, 500, GetDesktopWindow(), NULL, wc.hInstance, NULL ); //初始化Direct3D if( SUCCEEDED( InitD3D( hWnd ) ) ) { //创建场景图形 if( SUCCEEDED( InitGeometry() ) ) { //显示窗口 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( L"ClassName", wc.hInstance ); return 0; }

 

Effect代码:

/******************************** * Author: rabbit729 * E-mail: [email protected] * Date: 2011-04-24 ********************************/ //------------------------------ // 顶点着色器 //------------------------------ matrix matWVP; struct VS_OUTPUT { float4 Pos: POSITION; float2 Txr1: TEXCOORD0; }; VS_OUTPUT vs_main( float4 inPos: POSITION, float2 Txr1: TEXCOORD0 ) { VS_OUTPUT Out; Out.Pos = mul(inPos, matWVP); Out.Txr1 = Txr1; return Out; } //------------------------------ // 像素着色器 //------------------------------ Texture2D Tex0; sampler2D TexMap { Texture = <Tex0>; }; float4 ps_main( float4 inPosition: COLOR0, float2 inTxr1: TEXCOORD0 ) : COLOR0 { return tex2D(TexMap,inTxr1); } //------------------------------ // 效果框架 //------------------------------ technique Basic01 { pass P0 { VertexShader = compile vs_3_0 vs_main(); PixelShader = compile ps_3_0 ps_main(); } }

你可能感兴趣的:(Shaders for Game Programmers and Artists代码实现Chapter_0402)