DirectX基础学习系列8 渐进网格以及外接体
1 IUnknown--> ID3DXBUFFER D3D泛型接口:
Retrieves a pointer to the data in the buffer.
Retrieves the total size of the data in the buffer.
使用完之后需要进行释放:Release()
2XFILE
//从文件中加载xfile文件
HRESULT D3DXLoadMeshFromX(
__in LPCTSTR pFilename, //xfile文件名
__in DWORD Options, //加载可选项
__in LPDIRECT3DDEVICE9 pD3DDevice, //设备
__out LPD3DXBUFFER *ppAdjacency, //临街信息,DWORD数组
__out LPD3DXBUFFER *ppMaterials, //材质信息
__out LPD3DXBUFFER *ppEffectInstances, //
__out DWORD *pNumMaterials, //材质数目
__out LPD3DXMESH *ppMesh
);
//材质结构:ppMaterials结构中第I项 对应第I个子集
typedef struct D3DXMATERIAL {
D3DMATERIAL9 MatD3D;
LPSTR pTextureFilename;
} D3DXMATERIAL, *LPD3DXMATERIAL;
加载时,首先加载XFILE文件,然后遍历纹理数据,将纹理数据加载,在渲染的时候,先设置纹理和纹理
3生成顶点法线
方便使用光照,网格的法向量计算方法
HRESULT D3DXComputeNormals(
__inout LPD3DXBASEMESH pMesh, //输出的网格数据
__in const DWORD *pAdjacency //临街数据
);
pMesh参数中顶点格式必须包含D3DFVF_NORMAL,所以需要从原先的mesh数据copy一份过来
4.渐进网格
类似于渐进纹理数据,通过边折叠技术对网格进行简化,并且这种操作时可逆转的
渐进网格从已有的网格数据中产生:
D3DXGeneratePMesh(
LPD3DXMESH pMesh,
CONST DWORD* pAdjacency, //邻接信息dword数组
CONST D3DXATTRIBUTEWEIGHTS *pVertexAttributeWeights, //指定相应顶点属性权值 涉及被移除的概率
CONST FLOAT *pVertexWeights, //指定顶点权值,涉及被移除的概率
DWORD MinValue, //面片简化的最少值,如果设置为1 表示尽可能的少
DWORD Options, //决定上面的参数为定点数或者面片数
LPD3DXPMESH* ppPMesh);
D3DXATTRIBUTEWEIGHTS 顶点属相权值结构,暂且使用默认值
D3DXPMesh提供的操作接口:
GetMaxFaces() //最多的面片数目上限
GetMinFaces() //最少的面片数目下限
GetMaxVertexs() //最多的顶点数目上限
GetMinVertexs() //最少的顶点数目下限
SetNumFaces() // 设置面片数目,
SetNumVertexs() //设置顶点数目
trimByFaces(newfacemin , newfacemax, --- ., --) // 重新设置顶点的最大,最小限制
trimByVetex(newfacemin , newfacemax, --- ., --) // 重新设置顶点的最大,最小限制
5外接体:可以用于检测碰撞以及可见性
//外接球
D3DXComputeBoundingSphere(
CONST D3DXVECTOR3 *pFirstPosition, // pointer to first position 指向顶点的第一个位置
DWORD NumVertices, 数组中顶点数目
DWORD dwStride, // count in bytes to subsequent position vectors 每个顶点字节数
D3DXVECTOR3 *pCenter, 外界球中心
FLOAT *pRadius); 外接球半径
// 外界体
D3DXComputeBoundingBox(
CONST D3DXVECTOR3 *pFirstPosition, // pointer to first position,指向顶点的第一个位置
DWORD NumVertices, //顶点数组中的顶点数目
DWORD dwStride, // count in bytes to subsequent position vectors 每个顶点的字节数
D3DXVECTOR3 *pMin, //返回的
D3DXVECTOR3 *pMax);
//////////////////////////////////////////////////////////////////////////////////////////////////
//
// File: boundingvolumes.cpp
//
// Author: Frank Luna (C) All Rights Reserved
//
// System: AMD Athlon 1800+ XP, 512 DDR, Geforce 3, Windows XP, MSVC++ 7.0
//
// Desc: Demonstrates how to use D3DXComputeBoundingSphere and D3DXComputeBoundingBox.
//
// -The spacebar key switches between rendering the mesh's bounding sphere and box.
//
////////////////////////////////////////////////////////////////////////////////////////////////// #include "d3dUtility.h"
#include <vector> //
// Globals
// IDirect3DDevice9* Device = ; const int Width = ;
const int Height = ; ID3DXMesh* Mesh = ;
ID3DXPMesh* pMesh = ;
std::vector<D3DMATERIAL9> Mtrls();
std::vector<IDirect3DTexture9*> Textures(); ID3DXMesh* SphereMesh = ;
ID3DXMesh* BoxMesh = ; bool RenderBoundingSphere = true; //
// Prototypes
// bool ComputeBoundingSphere(ID3DXMesh* mesh, d3d::BoundingSphere* sphere);
bool ComputeBoundingBox(ID3DXMesh* mesh, d3d::BoundingBox* box); //
// Framework functions
//
bool Setup()
{
HRESULT hr = ; //
// Load the XFile data.
//
ID3DXBuffer* adjBuffer = ;
ID3DXBuffer* mtrlBuffer = ;
DWORD numMtrls = ; hr = D3DXLoadMeshFromX(
"bigship1.x",
D3DXMESH_MANAGED,
Device,
&adjBuffer,
&mtrlBuffer,
,
&numMtrls,
&Mesh); if(FAILED(hr))
{
::MessageBox(, "D3DXLoadMeshFromX() - FAILED", , );
return false;
} //
// Extract the materials, load textures.
// if( mtrlBuffer != && numMtrls != )
{
D3DXMATERIAL* mtrls = (D3DXMATERIAL*)mtrlBuffer->GetBufferPointer(); for(int i = ; i < numMtrls; i++)
{
// the MatD3D property doesn't have an ambient value set
// when its loaded, so set it now:
mtrls[i].MatD3D.Ambient = mtrls[i].MatD3D.Diffuse; // save the ith material
Mtrls.push_back( mtrls[i].MatD3D ); // check if the ith material has an associative texture
if( mtrls[i].pTextureFilename != )
{
// yes, load the texture for the ith subset
IDirect3DTexture9* tex = ;
D3DXCreateTextureFromFile(
Device,
mtrls[i].pTextureFilename,
&tex); // save the loaded texture
Textures.push_back( tex );
}
else
{
// no texture for the ith subset
Textures.push_back( );
}
}
}
d3d::Release<ID3DXBuffer*>(mtrlBuffer); // done w/ buffer //
// Optimize the mesh.
// hr = Mesh->OptimizeInplace(
D3DXMESHOPT_ATTRSORT |
D3DXMESHOPT_COMPACT |
D3DXMESHOPT_VERTEXCACHE,
(DWORD*)adjBuffer->GetBufferPointer(),
, , ); d3d::Release<ID3DXBuffer*>(adjBuffer); // done w/ buffer if(FAILED(hr))
{
::MessageBox(, "OptimizeInplace() - FAILED", , );
return false;
} //
// Compute Bounding Sphere and Bounding Box.
// d3d::BoundingSphere boundingSphere;
d3d::BoundingBox boundingBox; ComputeBoundingSphere(Mesh, &boundingSphere);
ComputeBoundingBox(Mesh, &boundingBox); D3DXCreateSphere(
Device,
boundingSphere._radius,
,
,
&SphereMesh,
); D3DXCreateBox(
Device,
boundingBox._max.x - boundingBox._min.x,
boundingBox._max.y - boundingBox._min.y,
boundingBox._max.z - boundingBox._min.z,
&BoxMesh,
); //
// Set texture filters.
// Device->SetSamplerState(, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
Device->SetSamplerState(, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
Device->SetSamplerState(, D3DSAMP_MIPFILTER, D3DTEXF_POINT); //
// Set Lights.
// D3DXVECTOR3 dir(1.0f, -1.0f, 1.0f);
D3DXCOLOR col(1.0f, 1.0f, 1.0f, 1.0f);
D3DLIGHT9 light = d3d::InitDirectionalLight(&dir, &col); Device->SetLight(, &light);
Device->LightEnable(, true);
Device->SetRenderState(D3DRS_NORMALIZENORMALS, true);
Device->SetRenderState(D3DRS_SPECULARENABLE, true); //
// Set camera.
// D3DXVECTOR3 pos(4.0f, 12.0f, -20.0f);
D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 up(0.0f, 1.0f, 0.0f); D3DXMATRIX V;
D3DXMatrixLookAtLH(
&V,
&pos,
&target,
&up); Device->SetTransform(D3DTS_VIEW, &V); //
// Set projection matrix.
// D3DXMATRIX proj;
D3DXMatrixPerspectiveFovLH(
&proj,
D3DX_PI * 0.5f, // 90 - degree
(float)Width / (float)Height,
1.0f,
1000.0f);
Device->SetTransform(D3DTS_PROJECTION, &proj); return true;
} void Cleanup()
{
d3d::Release<ID3DXMesh*>(Mesh); for(int i = ; i < Textures.size(); i++)
d3d::Release<IDirect3DTexture9*>( Textures[i] ); d3d::Release<ID3DXMesh*>(SphereMesh);
d3d::Release<ID3DXMesh*>(BoxMesh);
} bool Display(float timeDelta)
{
if( Device )
{
//
// Update: Rotate the mesh.
// static float y = 0.0f;
D3DXMATRIX yRot;
D3DXMatrixRotationY(&yRot, y);
y += timeDelta; if( y >= 6.28f )
y = 0.0f; D3DXMATRIX World = yRot; Device->SetTransform(D3DTS_WORLD, &World); //
// Render
// Device->Clear(, , D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, );
Device->BeginScene(); // draw the mesh
for(int i = ; i < Mtrls.size(); i++)
{
Device->SetMaterial( &Mtrls[i] );
Device->SetTexture(, Textures[i]);
Mesh->DrawSubset(i);
} //
// Draw bounding volume in blue and at 10% opacity
D3DMATERIAL9 blue = d3d::BLUE_MTRL;
blue.Diffuse.a = 0.10f; // 10% opacity Device->SetMaterial(&blue);
Device->SetTexture(, ); // disable texture Device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); if( RenderBoundingSphere )
SphereMesh->DrawSubset();
else
BoxMesh->DrawSubset(); Device->SetRenderState(D3DRS_ALPHABLENDENABLE, false); Device->EndScene();
Device->Present(, , , );
}
return true;
} //
// WndProc
//
LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch( msg )
{
case WM_DESTROY:
::PostQuitMessage();
break; case WM_KEYDOWN:
if( wParam == VK_ESCAPE )
::DestroyWindow(hwnd); if( wParam == VK_SPACE )
RenderBoundingSphere = !RenderBoundingSphere; break;
}
return ::DefWindowProc(hwnd, msg, wParam, lParam);
} //
// WinMain
//
int WINAPI WinMain(HINSTANCE hinstance,
HINSTANCE prevInstance,
PSTR cmdLine,
int showCmd)
{
if(!d3d::InitD3D(hinstance,
Width, Height, true, D3DDEVTYPE_HAL, &Device))
{
::MessageBox(, "InitD3D() - FAILED", , );
return ;
} if(!Setup())
{
::MessageBox(, "Setup() - FAILED", , );
return ;
} d3d::EnterMsgLoop( Display ); Cleanup(); Device->Release(); return ;
} bool ComputeBoundingSphere(ID3DXMesh* mesh, d3d::BoundingSphere* sphere)
{
HRESULT hr = ; BYTE* v = ;
mesh->LockVertexBuffer(, (void**)&v); hr = D3DXComputeBoundingSphere(
(D3DXVECTOR3*)v,
mesh->GetNumVertices(),
D3DXGetFVFVertexSize(mesh->GetFVF()),
&sphere->_center,
&sphere->_radius); mesh->UnlockVertexBuffer(); if( FAILED(hr) )
return false; return true;
} bool ComputeBoundingBox(ID3DXMesh* mesh, d3d::BoundingBox* box)
{
HRESULT hr = ; BYTE* v = ;
mesh->LockVertexBuffer(, (void**)&v); hr = D3DXComputeBoundingBox(
(D3DXVECTOR3*)v,
mesh->GetNumVertices(),
D3DXGetFVFVertexSize(mesh->GetFVF()),
&box->_min,
&box->_max); mesh->UnlockVertexBuffer(); if( FAILED(hr) )
return false; return true;
}
DirectX基础学习系列8 渐进网格以及外接体的更多相关文章
- directX基础学习系列7 网格(自己创建)
D3DXMesh 以及 D3DXPMesh都是从ID3DXBaseMesh类中集成,mesh基本是对三角单元进行操作 ID3DXBaseMesh主要函数: HRESULT DrawSubset( DW ...
- DirectX 基础学习系列5 纹理映射
1 纹理坐标 类似BMP图像坐标系,左上为原点 纹理坐标为了规范化,范围限定在[0,1]之间,使用纹理的时候,需要修改顶点结构 struct ColorVetex { float x, y,z; fl ...
- DirectX基础学习系列1
1.3 基础 1.3.1表面 表面接口: IDirect3DSurface9 获得表面信息:GetDesc(D3DSURFACE_DESC) 获得表面接口指针 :LockRect( D3DLO ...
- DirectX 基础学习系列6 字体
DIRECTX9自带ID3DXFONT类 内部调用GDI的接口,效率一般,但能够处理一些复杂的字体 HRESULT D3DXCreateFontIndirect( LPDIRECT3DDEVICE9 ...
- DirectX基础学习系列5 融合技术
7.1融合方程 1概念 融合技术将当前光栅化像素的颜色与以前已光栅化并处于同一个位置的像素颜色进行合成,即将当前要进行光栅化的三角形单元与已写入后台的像素进行融合 2需要遵循的原则: (1)先绘制不需 ...
- DirectX基础学习系列4 颜色和光照
4.1颜色表示 RGB颜色:D3DCOLOR 可以用宏D3DCOLOR_ARGB(a,r,g,b) D3DCOLOR_XRGB(255,r,g,b) 另外一种浮点表示:D3DCOLORVALUE, ...
- DirectX基础学习系列2
补充第一章矩阵内容 向量 1 3D空间向量,包含浮点数类型坐标 D3DXVECTOR-->D3DXVECTOR3 2向量的长度 D3DXVector3Length(const D3DXVECTO ...
- Linux基础学习系列目录导航
Linux基础学习-通过VM安装RHEL7.4 Linux基础学习-命令行与图形界面切换 Linux基础学习-基本命令 Linux基础学习-RHEL7.4之YUM更换CentOS源 Linux基础学习 ...
- Bootstrap基础学习 ---- 系列文章
[Bootstrap基础学习]05 Bootstrap学习总结 [Bootstrap基础学习]04 Bootstrap的HTML和CSS编码规范 [Bootstrap基础学习]03 Bootstrap ...
随机推荐
- oracle的关闭过程(各个模式关闭)
关闭数据库与实例 与数据库启动一下,关闭数据库与实例也分为3步:关闭数据库-->实例卸载数据库--->终止实例. 1.Nomal(正常关闭方式) 命令:shutdown nomal 讲解: ...
- canvas 在线画图
canvas 在线画图 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&qu ...
- mysql事务处理的意义
MySQL的事务支持不是绑定在MySQL服务器本身,而是与存储引擎相关 1.MyISAM:不支持事务,用于只读程序提高性能 .InnoDB:支持ACID事务.行级锁.并发 .Berkeley DB:支 ...
- VS2010编写动态链接库DLL及单元测试用例,调用DLL测试正确性
转自:http://blog.csdn.net/testcs_dn/article/details/27237509 本文将创建一个简单的动态链接库,并编写一个控制台应用程序使用该动态链接库,该动态链 ...
- 在MongoDB中使用JOIN操作
SQL与NoSQL最大的不同之一就是不支持JOIN,在传统的数据库中,SQL JOIN子句允许你使用普通的字段,在两个或者是更多表中的组合表中的每行数据.例如,如果你有表books和publisher ...
- 简单几何(线段相交) POJ 1066 Treasure Hunt
题目传送门 题意:从四面任意点出发,有若干障碍门,问最少要轰掉几扇门才能到达终点 分析:枚举入口点,也就是线段的两个端点,然后选取与其他线段相交点数最少的 + 1就是答案.特判一下n == 0的时候 ...
- ZOJ2588 Burning Bridges(割边模板)
题目要输出一个无向图的所有割边.用Tarjan算法: 一遍DFS,构造出一颗深度优先生成树,在原无向图中边分成了两种:树边(生成树上的边)和反祖边(非生成树上的边). 顺便求出每个结点的DFS序dfn ...
- BZOJ3733 : [Pa2013]Iloczyn
首先将$n$的约数从小到大排序,设$dfs(x,y,z)$表示当前可以选第$x$个到第$m$个约数,还要选$y$个,之前选的乘积为$z$是否可能. 爆搜的时候,如果从$x$开始最小的$y$个相乘也超过 ...
- BZOJ4158 : [POI2007]Railway
论文题. 随便取个关键点,求出最短路树. 求出所有关键点组成的虚树,将两端都在虚树上的边保留. 对剩下的边求出最小生成树即可得到一组可行解. #include<cstdio> #inclu ...
- null VS undefined
null VS undefined “null与undefined的区别?” 以前去淘宝面试的时候被问过这个问题,当时只是粗略的按照犀牛书上的答案讲了下,但具体的并没有深入去了解. 后来有机会去问问身 ...