代码:
#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 hPos = NULL; //位置句柄 D3DXHANDLE hTech0 = NULL; //技术句柄 #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_TEX1) //----------------------------------------------------------------------------- // Desc: 设置世界矩阵 //----------------------------------------------------------------------------- VOID SetWorldMatrix() { //创建并设置世界矩阵 D3DXMATRIXA16 matWorld, matRotateX, matRotateY; D3DXMATRIXA16 matScale; D3DXMatrixIdentity(&matScale); matScale._11 = matScale._22 = matScale._33 = 0.5f; D3DXMatrixIdentity(&matWorld); D3DXMatrixIdentity(&matRotateX); D3DXMatrixIdentity(&matRotateY); D3DXMatrixRotationX( &matRotateX, D3DX_PI / 3.0 ); D3DXMatrixRotationY( &matRotateY, -D3DX_PI / 8.0 ); D3DXMatrixMultiply(&matWorld, &matRotateX, &matRotateY); D3DXMatrixMultiply(&matWorld, &matScale, &matWorld); 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"); hPos = g_pEffect->GetParameterByName(0, "vPos"); 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 teapot.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(); } void RenderByPass0() { // 设置要使用的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(); } VOID RenderByTechnique() { D3DXVECTOR4 vPos(100.f, -64.f, 100.f, 0.f); g_pEffect->SetValue(hPos, vPos, D3DX_DEFAULT); RenderByPass0(); } //----------------------------------------------------------------------------- // 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); RenderByTechnique(); //场景渲染结束 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: wlq_729@163.com * Date: 2011-05-04 ********************************/ //------------------------------ // 顶点着色器 //------------------------------ matrix matWVP; float4 vPos; struct VS_OUTPUT { float4 Pos: POSITION; float2 Txr1: TEXCOORD0; }; VS_OUTPUT vs_mainPass0( 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_mainPass0( float4 inPosition: COLOR0, float2 inTxr1: TEXCOORD0 ) : COLOR0 { return tex2D(TexMap,inTxr1); } //------------------------------ // 顶点着色器 //------------------------------ struct VS_OUTPUTP1 { float4 Pos: POSITION; }; VS_OUTPUTP1 vs_mainPass1(float4 inPos: POSITION) { VS_OUTPUTP1 Out; Out.Pos = mul(inPos + vPos, matWVP); return Out; } //------------------------------ // 像素着色器 //------------------------------ float4 ps_mainPass1(float4 inDiffuse: COLOR0): COLOR0 { float4 color; color[0] = color[3] = 1.0; color[1] = color[2] = 0.0; return color; } //------------------------------ // 效果框架 //------------------------------ technique Basic01 { pass P0 { VertexShader = compile vs_3_0 vs_mainPass0(); PixelShader = compile ps_3_0 ps_mainPass0(); } pass P1 { VertexShader = compile vs_3_0 vs_mainPass1(); PixelShader = compile ps_3_0 ps_mainPass1(); } }