http://blog.csdn.net/rabbit729/article/details/6583712
代码如下:说明代码中用到的.x模型下载地址:http://download.csdn.net/source/3416898
- /********************************
- * Author: rabbit729
- * E-mail: wlq_729@163.com
- * Date: 2011-07-04
- * Description: 四视图
- ********************************/
- #include <d3dx9.h>
- //-----------------------------------------------------------------------------
- // Desc: 全局变量
- //-----------------------------------------------------------------------------
- #define WIDTH 800
- #define HEIGHT 600
- LPDIRECT3D9 g_pD3D = NULL; //Direct3D对象
- LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; //Direct3D设备对象
- LPD3DXFONT g_pFont = NULL; //Direct3D字体对象
- LPD3DXLINE g_pLine = NULL; //Direct3D画线对象
- LPD3DXMESH g_pMesh = NULL; //网格模型对象
- D3DMATERIAL9* g_pMeshMaterials = NULL; //网格模型材质
- LPDIRECT3DTEXTURE9* g_pMeshTextures = NULL; //网格模型纹理
- DWORD g_dwNumMaterials = 0L; //网格模型材质数量
- D3DXVECTOR2* g_vHorArr = NULL; //水平分割线
- D3DXVECTOR2* g_vVerArr = NULL; //垂直分割线
- D3DVIEWPORT9 g_MainViewport; // 主视图
- D3DVIEWPORT9 g_ProViewport; // 俯视图视口
- D3DVIEWPORT9 g_FrontViewport; // 前视图视口
- D3DVIEWPORT9 g_TopViewport; // 顶视图视口
- D3DVIEWPORT9 g_LeftViewport; // 左视图视口
- //-----------------------------------------------------------------------------
- // Desc: 设置世界矩阵
- //-----------------------------------------------------------------------------
- VOID SetWorldMatrix()
- {
- //创建并设置世界矩阵
- D3DXMATRIXA16 matWorld;
- D3DXMatrixIdentity(&matWorld);
- g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
- }
- //-----------------------------------------------------------------------------
- // Desc: 设置俯视图矩阵
- //-----------------------------------------------------------------------------
- VOID SeProViewMatrix()
- {
- //创建并设置观察矩阵
- D3DXVECTOR3 vEyePt( 0.0f, 20.0f,-20.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 );
- }
- //-----------------------------------------------------------------------------
- // Desc: 设置前视图矩阵
- //-----------------------------------------------------------------------------
- VOID SetFrontViewMatrix()
- {
- //创建并设置观察矩阵
- D3DXVECTOR3 vEyePt( 0.0f, 0.0f,-20.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 );
- }
- //-----------------------------------------------------------------------------
- // Desc: 设置顶视图矩阵
- //-----------------------------------------------------------------------------
- VOID SetTopViewMatrix()
- {
- //创建并设置观察矩阵
- D3DXVECTOR3 vEyePt( 0.0f, 20.0f,0.0f );
- D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
- D3DXVECTOR3 vUpVec( 0.0f, 0.0f, 1.0f );
- D3DXMATRIXA16 matView;
- D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
- g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
- }
- //-----------------------------------------------------------------------------
- // Desc: 设置左视图矩阵
- //-----------------------------------------------------------------------------
- VOID SetLeftViewMatrix()
- {
- //创建并设置观察矩阵
- D3DXVECTOR3 vEyePt( -20.0f, 0.0f,0.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 );
- }
- //-----------------------------------------------------------------------------
- // Desc: 设置投影矩阵
- //-----------------------------------------------------------------------------
- VOID SetProjMatrix()
- {
- //创建并设置投影矩阵
- D3DXMATRIXA16 matProj;
- D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 100.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;
- }
- //创建字体对象
- if (FAILED(D3DXCreateFont(g_pd3dDevice, 0, 0, 0, 0, 0, 0, 0, 0, 0, L"Arial", &g_pFont)))
- {
- return E_FAIL;
- }
- //创建画线对象
- if (FAILED(D3DXCreateLine(g_pd3dDevice, &g_pLine)))
- {
- return E_FAIL;
- }
- //设置环境光
- g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0xffffffff );
- //设置观察矩阵和投影矩阵
- SetProjMatrix();
- // 计算四视图视口尺寸
- g_pd3dDevice->GetViewport(&g_MainViewport);
- g_LeftViewport.Width = g_TopViewport.Width =
- g_FrontViewport.Width = g_ProViewport.Width = g_MainViewport.Width / 2;
- g_LeftViewport.Height = g_TopViewport.Height =
- g_FrontViewport.Height = g_ProViewport.Height = g_MainViewport.Height / 2;
- g_LeftViewport.X = g_FrontViewport.X = 0;
- g_LeftViewport.Y = g_TopViewport.Y = 0;
- g_FrontViewport.Y = g_ProViewport.Y = g_MainViewport.Height / 2;
- g_TopViewport.X = g_ProViewport.X = g_MainViewport.Width / 2;
- g_LeftViewport.MinZ = g_TopViewport.MinZ =
- g_FrontViewport.MinZ = g_ProViewport.MinZ = 0.f;
- g_LeftViewport.MaxZ = g_TopViewport.MaxZ =
- g_FrontViewport.MaxZ = g_ProViewport.MaxZ = 1.0f;
- 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"airplane.x", D3DXMESH_MANAGED,
- g_pd3dDevice, NULL,
- &pD3DXMtrlBuffer, NULL, &g_dwNumMaterials,
- &g_pMesh ) ) )
- {
- MessageBox(NULL, L"Could not find airplane.x", L"Mesh", MB_OK);
- return E_FAIL;
- }
- //从网格模型中提取材质属性和纹理文件名
- D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
- g_pMeshMaterials = new D3DMATERIAL9[g_dwNumMaterials];
- if( g_pMeshMaterials == NULL )
- return E_OUTOFMEMORY;
- g_pMeshTextures = new LPDIRECT3DTEXTURE9[g_dwNumMaterials];
- if( g_pMeshTextures == NULL )
- return E_OUTOFMEMORY;
- //逐块提取网格模型材质属性和纹理文件名
- for( DWORD i=0; i<g_dwNumMaterials; i++ )
- {
- //材料属性
- g_pMeshMaterials[i] = d3dxMaterials[i].MatD3D;
- //设置模型材料的环境光反射系数, 因为模型材料本身没有设置环境光反射系数
- g_pMeshMaterials[i].Ambient = g_pMeshMaterials[i].Diffuse;
- g_pMeshTextures[i] = NULL;
- if( d3dxMaterials[i].pTextureFilename != NULL &&
- strlen(d3dxMaterials[i].pTextureFilename) > 0 )
- {
- //获取纹理文件名
- WCHAR filename[256];
- RemovePathFromFileName(d3dxMaterials[i].pTextureFilename, filename);
- //创建纹理
- if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, filename,
- &g_pMeshTextures[i] ) ) )
- {
- MessageBox(NULL, L"Could not find texture file", L"Mesh", MB_OK);
- }
- }
- }
- //释放在加载模型文件时创建的保存模型材质和纹理数据的缓冲区对象
- pD3DXMtrlBuffer->Release();
- //填充水平垂直分割线
- g_vHorArr = new D3DXVECTOR2[2];
- g_vHorArr[0].x = 0;
- g_vHorArr[0].y = g_vHorArr[1].y = HEIGHT / 2;
- g_vHorArr[1].x = WIDTH;
- //填充垂直分割线
- g_vVerArr = new D3DXVECTOR2[2];
- g_vVerArr[0].y = 0;
- g_vVerArr[0].x = g_vVerArr[1].x = WIDTH / 2;
- g_vVerArr[1].y = HEIGHT;
- return S_OK;
- }
- //-----------------------------------------------------------------------------
- // Desc: 释放创建的对象
- //-----------------------------------------------------------------------------
- VOID Cleanup()
- {
- //释放网格模型材质
- if( g_pMeshMaterials != NULL )
- delete[] g_pMeshMaterials;
- //释放网格模型纹理
- if( g_pMeshTextures )
- {
- for( DWORD i = 0; i < g_dwNumMaterials; i++ )
- {
- if( g_pMeshTextures[i] )
- g_pMeshTextures[i]->Release();
- }
- delete[] g_pMeshTextures;
- }
- //释放网格模型对象
- if( g_pMesh != NULL )
- g_pMesh->Release();
- //释放画线对象
- if (g_pLine != NULL)
- {
- g_pLine->Release();
- }
- delete[] g_vHorArr;
- g_vHorArr = NULL;
- delete[] g_vVerArr;
- g_vVerArr = NULL;
- //释放字体对象
- if(g_pFont != NULL)
- g_pFont->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(43,43,43), 1.0f, 0 );
- //开始渲染场景
- if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
- {
- SetWorldMatrix(); //设置世界矩阵
- // 渲染左视图
- SetLeftViewMatrix();
- g_pd3dDevice->SetViewport(&g_LeftViewport);
- //逐块渲染网格模型
- for( DWORD i=0; i<g_dwNumMaterials; i++ )
- {
- //设置材料和纹理
- g_pd3dDevice->SetMaterial( &g_pMeshMaterials[i] );
- g_pd3dDevice->SetTexture( 0, g_pMeshTextures[i] );
- //渲染模型
- g_pMesh->DrawSubset( i );
- }
- // 渲染顶视图
- SetTopViewMatrix();
- g_pd3dDevice->SetViewport(&g_TopViewport);
- //逐块渲染网格模型
- for( DWORD i=0; i<g_dwNumMaterials; i++ )
- {
- //设置材料和纹理
- g_pd3dDevice->SetMaterial( &g_pMeshMaterials[i] );
- g_pd3dDevice->SetTexture( 0, g_pMeshTextures[i] );
- //渲染模型
- g_pMesh->DrawSubset( i );
- }
- // 渲染前视图
- SetFrontViewMatrix();
- g_pd3dDevice->SetViewport(&g_FrontViewport);
- //逐块渲染网格模型
- for( DWORD i=0; i<g_dwNumMaterials; i++ )
- {
- //设置材料和纹理
- g_pd3dDevice->SetMaterial( &g_pMeshMaterials[i] );
- g_pd3dDevice->SetTexture( 0, g_pMeshTextures[i] );
- //渲染模型
- g_pMesh->DrawSubset( i );
- }
- // 渲染俯视图
- SeProViewMatrix();
- g_pd3dDevice->SetViewport(&g_ProViewport);
- //逐块渲染网格模型
- for( DWORD i=0; i<g_dwNumMaterials; i++ )
- {
- //设置材料和纹理
- g_pd3dDevice->SetMaterial( &g_pMeshMaterials[i] );
- g_pd3dDevice->SetTexture( 0, g_pMeshTextures[i] );
- //渲染模型
- g_pMesh->DrawSubset( i );
- }
- //绘制分割线
- g_pd3dDevice->SetViewport(&g_MainViewport);
- g_pLine->SetWidth(4.f);
- g_pLine->SetAntialias(TRUE);
- g_pLine->SetPattern(0xffffffff);
- g_pLine->Draw(g_vHorArr, 2, 0xffffffff);
- g_pLine->Draw(g_vVerArr, 2, 0xffffffff);
- // 绘制描述信息
- RECT rtText;
- rtText.left = g_LeftViewport.X;
- rtText.top = g_LeftViewport.Y;
- rtText.right = rtText.left + 200;
- rtText.bottom = rtText.top + 50;
- g_pFont->DrawText(0, L"Left View", -1, &rtText, DT_LEFT, 0xffffffff );
- rtText.left = g_TopViewport.X + 6;
- rtText.top = g_TopViewport.Y;
- rtText.right = rtText.left + 200;
- rtText.bottom = rtText.top + 50;
- g_pFont->DrawText(0, L"Top View", -1, &rtText, DT_LEFT, 0xffffffff );
- rtText.left = g_FrontViewport.X;
- rtText.top = g_FrontViewport.Y + 20;
- rtText.right = rtText.left + 200;
- rtText.bottom = rtText.top + 50;
- g_pFont->DrawText(0, L"Front View", -1, &rtText, DT_LEFT, 0xffffffff );
- rtText.left = g_ProViewport.X + 6;
- rtText.top = g_ProViewport.Y + 20;
- rtText.right = rtText.left + 200;
- rtText.bottom = rtText.top + 50;
- g_pFont->DrawText(0, L"Project View", -1, &rtText, DT_LEFT, 0xffffffff );
- //场景渲染结束
- 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"四视图",
- WS_OVERLAPPEDWINDOW, 100, 100, WIDTH, HEIGHT,
- 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;
- }