D3DXMesh 以及 D3DXPMesh都是从ID3DXBaseMesh类中集成,mesh基本是对三角单元进行操作

ID3DXBaseMesh主要函数:

HRESULT DrawSubset( DWORD AttribId);

HRESULT GetIndexBuffer( LPDIRECT3DINDEXBUFFER9 * ppIB);

HRESULT GetVertexBuffer( LPDIRECT3DVERTEXBUFFER9 * ppVB);

HRESULT LockIndexBuffer( DWORD Flags, LPVOID * ppData);

HRESULT UnlockIndexBuffer();

HRESULT CloneMesh( DWORD Options, CONST D3DVERTEXELEMENT9 * pDeclaration, LPDIRECT3DDEVICE9pDevice, LPD3DXMESH * ppCloneMesh);

HRESULT CloneMeshFVF( DWORD Options, DWORD FVF, LPDIRECT3DDEVICE9 pDevice, LPD3DXMESH * ppCloneMesh);

DWORD GetOptions();获得当前网格的选项

DWORD GetFVF();

DWORD GetNumVertices();

DWORD GetNumBytesPerVertex();

DWORD GetNumFaces();

 

1 子集和属性缓存

子集:mesh由子集构成,一个子集是网格中相同属性的三角新单元,每个子集有子集属性ID

属性缓存:三角形单元属性ID存储位置,和网格索引中三角形单元的数目相同,属性缓存项与网格索引缓存中的数据一一对应。

获得索引的办法:

HRESULT LockAttributeBuffer( DWORD Flags, DWORD ** ppData);

HRESULT UnlockAttributeBuffer();

2绘制

HRESULT DrawSubset( DWORD AttribId);

3优化

对网格中的索引和顶点进行重组

HRESULT OptimizeInplace(
DWORD Flags, 优化标记
CONST DWORD * pAdjacencyIn, 指向未经优化的网格临街信息数组的指针
DWORD * pAdjacencyOut, 指向优化后的网格临街信息数组的指针 3 *  GetNumFaces()
DWORD * pFaceRemap, 优化过程中 原始面片被移动到新的面片位置 GetNumFaces()
LPD3DXBUFFER * ppVertexRemap 顶点被移动到新的顶点位置 GetNumFaces()
);
//优化标记
typedef enum D3DXMESHOPT
{
D3DXMESHOPT_COMPACT = 0x01000000,移除没用的顶点和索引
D3DXMESHOPT_ATTRSORT = 0x02000000, 根据属性重新排序
D3DXMESHOPT_VERTEXCACHE = 0x04000000, 提高顶点高速缓存的命中率
D3DXMESHOPT_STRIPREORDER = 0x08000000, 对索引进行重组
D3DXMESHOPT_IGNOREVERTS = 0x10000000,
D3DXMESHOPT_DONOTSPLIT = 0x20000000,
D3DXMESHOPT_DEVICEINDEPENDENT = 0x40000000,
} D3DXMESHOPT, *LPD3DXMESHOPT;
另一个优化函数:会修改原始网格数据
HRESULT Optimize(  DWORD Flags,  CONST
DWORD * pAdjacencyIn, DWORD *
pAdjacencyOut, DWORD * pFaceRemap,
LPD3DXBUFFER * ppVertexRemap, LPD3DXMESH *
ppOptMesh);

4属性表

属性表经过D3DXMESHOPT_ATTRSORT标志排序后,相同属性的三角形面片的属性信息和顶点列表就会存储在连续的区域中,可以通过 函数:

HRESULT GetAttributeTable( D3DXATTRIBUTERANGE * pAttribTable, DWORD * pAttribTableSize)

来获得网格中属性信息列表,属性信息列表的结构:

typedef struct D3DXATTRIBUTERANGE {
DWORD AttribId; 属性ID
DWORD FaceStart; 索引缓存中的其实位置 3* FaceStart
DWORD FaceCount; 面片数目
DWORD VertexStart;顶点缓存其实位置
DWORD VertexCount;
} D3DXATTRIBUTERANGE, *LPD3DXATTRIBUTERANGE;
属性表获取:
GetAttributeTable(0,&num);
D3DXATTRIBUTERANGE table = new D3DXATTRIBUTERANGE[num];
GetAttributeTable(table ,&num);
设置属性表:
HRESULT SetAttributeTable(  CONST D3DXATTRIBUTERANGE *
pAttribTable, DWORD cAttribTableSize);
5邻接信息
每个三角形面片有三个边,最多三个邻接信息,无效邻接信息为-1或者ULONG_MAX
邻接数组大小为Get FaceNun*3
获得邻接数据函数:
HRESULT GenerateAdjacency(  FLOAT Epsilon,  DWORD * pAdjacency);
Epsilon:指定两个点距离多近可以算作同一个点
pAdjacency:DWORD数组
6网格顶点复制
HRESULT CloneMeshFVF( DWORD Options, DWORD FVF, LPDIRECT3DDEVICE9 pDevice, LPD3DXMESH * ppCloneMesh);
Options:创建网格副本是的可选项
FVF:灵活顶点格式
DWORD GetOptions();获得当前网格的选项
7创建网格
HRESULT D3DXCreateMesh(  DWORD NumFaces,
DWORD NumVertices, DWORD Options,
CONST LPD3DVERTEXELEMENT9 * pDeclaration,
LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXMESH *
ppMesh);
HRESULT D3DXCreateMeshFVF(  DWORD NumFaces,
DWORD NumVertices, DWORD Options,
DWORD FVF, LPDIRECT3DDEVICE9
pD3DDevice, LPD3DXMESH * ppMesh);
typedef struct D3DVERTEXELEMENT9 {
WORD Stream;
WORD Offset;
BYTE Type;
BYTE Method;
BYTE Usage;
BYTE UsageIndex;
} D3DVERTEXELEMENT9, *LPD3DVERTEXELEMENT9;

8网格创建与绘制
1创建网格对象
2将面片数据写入网格缓存
3指定每个面片所属的子集
4生成邻接信息,优化网格
5绘制网格
 
#include "d3dUtility.h"
#include <fstream>
#include <vector> //
// Globals
// IDirect3DDevice9* Device = 0; const int Width = 640;
const int Height = 480; ID3DXMesh* Mesh = 0;
const DWORD NumSubsets = 3;
IDirect3DTexture9* Textures[3] = {0, 0, 0};// texture for each subset std::ofstream OutFile; // used to dump mesh data to file //
// Prototypes
// void dumpVertices(std::ofstream& outFile, ID3DXMesh* mesh);
void dumpIndices(std::ofstream& outFile, ID3DXMesh* mesh);
void dumpAttributeBuffer(std::ofstream& outFile, ID3DXMesh* mesh);
void dumpAdjacencyBuffer(std::ofstream& outFile, ID3DXMesh* mesh);
void dumpAttributeTable(std::ofstream& outFile, ID3DXMesh* mesh); //
// Classes and Structures
//
struct Vertex
{
Vertex(){}
Vertex(float x, float y, float z,
float nx, float ny, float nz, float u, float v)
{
_x = x; _y = y; _z = z;
_nx = nx; _ny = ny; _nz = nz;
_u = u; _v = v;
} float _x, _y, _z, _nx, _ny, _nz, _u, _v; static const DWORD FVF;
};
const DWORD Vertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1; //
// Framework functions
//
bool Setup()
{
HRESULT hr = 0; //
// We are going to fill the empty mesh with the geometry of a box,
// so we need 12 triangles and 24 vetices.
// hr = D3DXCreateMeshFVF(
12,
24,
D3DXMESH_MANAGED,
Vertex::FVF,
Device,
&Mesh); if(FAILED(hr))
{
::MessageBox(0, "D3DXCreateMeshFVF() - FAILED", 0, 0);
return false;
} //
// Fill in vertices of a box
//
Vertex* v = 0;
Mesh->LockVertexBuffer(0, (void**)&v); // fill in the front face vertex data
v[0] = Vertex(-1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);
v[1] = Vertex(-1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);
v[2] = Vertex( 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f);
v[3] = Vertex( 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f); // fill in the back face vertex data
v[4] = Vertex(-1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
v[5] = Vertex( 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f);
v[6] = Vertex( 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f);
v[7] = Vertex(-1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f); // fill in the top face vertex data
v[8] = Vertex(-1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
v[9] = Vertex(-1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f);
v[10] = Vertex( 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f);
v[11] = Vertex( 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f); // fill in the bottom face vertex data
v[12] = Vertex(-1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f);
v[13] = Vertex( 1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f);
v[14] = Vertex( 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f);
v[15] = Vertex(-1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f); // fill in the left face vertex data
v[16] = Vertex(-1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f);
v[17] = Vertex(-1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f);
v[18] = Vertex(-1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f);
v[19] = Vertex(-1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f); // fill in the right face vertex data
v[20] = Vertex( 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f);
v[21] = Vertex( 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f);
v[22] = Vertex( 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f);
v[23] = Vertex( 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f); Mesh->UnlockVertexBuffer(); //
// Define the triangles of the box
//
WORD* i = 0;
Mesh->LockIndexBuffer(0, (void**)&i); // fill in the front face index data
i[0] = 0; i[1] = 1; i[2] = 2;
i[3] = 0; i[4] = 2; i[5] = 3; // fill in the back face index data
i[6] = 4; i[7] = 5; i[8] = 6;
i[9] = 4; i[10] = 6; i[11] = 7; // fill in the top face index data
i[12] = 8; i[13] = 9; i[14] = 10;
i[15] = 8; i[16] = 10; i[17] = 11; // fill in the bottom face index data
i[18] = 12; i[19] = 13; i[20] = 14;
i[21] = 12; i[22] = 14; i[23] = 15; // fill in the left face index data
i[24] = 16; i[25] = 17; i[26] = 18;
i[27] = 16; i[28] = 18; i[29] = 19; // fill in the right face index data
i[30] = 20; i[31] = 21; i[32] = 22;
i[33] = 20; i[34] = 22; i[35] = 23; Mesh->UnlockIndexBuffer(); //
// Specify the subset each triangle belongs to, in this example
// we will use three subsets, the first two faces of the cube specified
// will be in subset 0, the next two faces will be in subset 1 and
// the the last two faces will be in subset 2.
//
DWORD* attributeBuffer = 0;
Mesh->LockAttributeBuffer(0, &attributeBuffer); for(int a = 0; a < 4; a++)
attributeBuffer[a] = 0; for(int b = 4; b < 8; b++)
attributeBuffer[b] = 1; for(int c = 8; c < 12; c++)
attributeBuffer[c] = 2; Mesh->UnlockAttributeBuffer(); //
// Optimize the mesh to generate an attribute table.
// std::vector<DWORD> adjacencyBuffer(Mesh->GetNumFaces() * 3);
Mesh->GenerateAdjacency(0.0f, &adjacencyBuffer[0]); hr = Mesh->OptimizeInplace(
D3DXMESHOPT_ATTRSORT |
D3DXMESHOPT_COMPACT |
D3DXMESHOPT_VERTEXCACHE,
&adjacencyBuffer[0],
0, 0, 0); //
// Dump the Mesh Data to file.
// OutFile.open("Mesh Dump.txt"); dumpVertices(OutFile, Mesh);
dumpIndices(OutFile, Mesh);
dumpAttributeTable(OutFile, Mesh);
dumpAttributeBuffer(OutFile, Mesh);
dumpAdjacencyBuffer(OutFile, Mesh); OutFile.close(); //
// Load the textures and set filters.
// D3DXCreateTextureFromFile(
Device,
"brick0.jpg",
&Textures[0]); D3DXCreateTextureFromFile(
Device,
"brick1.jpg",
&Textures[1]); D3DXCreateTextureFromFile(
Device,
"checker.jpg",
&Textures[2]); Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT); //
// Disable lighting.
// Device->SetRenderState(D3DRS_LIGHTING, false); //
// Set camera.
// D3DXVECTOR3 pos(0.0f, 0.f, -4.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);
d3d::Release<IDirect3DTexture9*>(Textures[0]);
d3d::Release<IDirect3DTexture9*>(Textures[1]);
d3d::Release<IDirect3DTexture9*>(Textures[2]);
} bool Display(float timeDelta)
{
if( Device )
{
//
// Update: Rotate the cube.
// D3DXMATRIX xRot;
D3DXMatrixRotationX(&xRot, D3DX_PI * 0.2f); static float y = 0.0f;
D3DXMATRIX yRot;
D3DXMatrixRotationY(&yRot, y);
y += timeDelta; if( y >= 6.28f )
y = 0.0f; D3DXMATRIX World = xRot * yRot; Device->SetTransform(D3DTS_WORLD, &World); //
// Render
// Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
Device->BeginScene(); for(int i = 0; i < NumSubsets; i++)
{
Device->SetTexture( 0, Textures[i] );
Mesh->DrawSubset( i );
} Device->EndScene();
Device->Present(0, 0, 0, 0);
}
return true;
}

directX基础学习系列7 网格(自己创建)的更多相关文章

  1. DirectX基础学习系列8 渐进网格以及外接体

    1 IUnknown--> ID3DXBUFFER D3D泛型接口: GetBufferPointer Retrieves a pointer to the data in the buffer ...

  2. DirectX 基础学习系列5 纹理映射

    1 纹理坐标 类似BMP图像坐标系,左上为原点 纹理坐标为了规范化,范围限定在[0,1]之间,使用纹理的时候,需要修改顶点结构 struct ColorVetex { float x, y,z; fl ...

  3. DirectX基础学习系列1

    1.3 基础 1.3.1表面 表面接口:     IDirect3DSurface9 获得表面信息:GetDesc(D3DSURFACE_DESC) 获得表面接口指针 :LockRect( D3DLO ...

  4. DirectX基础学习系列4 颜色和光照

    4.1颜色表示 RGB颜色:D3DCOLOR  可以用宏D3DCOLOR_ARGB(a,r,g,b)  D3DCOLOR_XRGB(255,r,g,b) 另外一种浮点表示:D3DCOLORVALUE, ...

  5. DirectX 基础学习系列6 字体

    DIRECTX9自带ID3DXFONT类 内部调用GDI的接口,效率一般,但能够处理一些复杂的字体 HRESULT D3DXCreateFontIndirect( LPDIRECT3DDEVICE9 ...

  6. DirectX基础学习系列5 融合技术

    7.1融合方程 1概念 融合技术将当前光栅化像素的颜色与以前已光栅化并处于同一个位置的像素颜色进行合成,即将当前要进行光栅化的三角形单元与已写入后台的像素进行融合 2需要遵循的原则: (1)先绘制不需 ...

  7. DirectX基础学习系列2

    补充第一章矩阵内容 向量 1 3D空间向量,包含浮点数类型坐标 D3DXVECTOR-->D3DXVECTOR3 2向量的长度 D3DXVector3Length(const D3DXVECTO ...

  8. Linux基础学习系列目录导航

    Linux基础学习-通过VM安装RHEL7.4 Linux基础学习-命令行与图形界面切换 Linux基础学习-基本命令 Linux基础学习-RHEL7.4之YUM更换CentOS源 Linux基础学习 ...

  9. Bootstrap基础学习 ---- 系列文章

    [Bootstrap基础学习]05 Bootstrap学习总结 [Bootstrap基础学习]04 Bootstrap的HTML和CSS编码规范 [Bootstrap基础学习]03 Bootstrap ...

随机推荐

  1. hdu 1556 树状数组+点查询

    树状数组 N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的“小飞鸽"牌电动车从气球a开始到气球b依次给每个气球涂一 ...

  2. Linux 串口编程(转)

    无论那种操作方式,一般都通过四个步骤来完成: (1) 打开串口 (2) 配置串口 (3) 读写串口 (4) 关闭串口 转自

  3. C语言位运算详解(转载)

    转载自:http://www.cnblogs.com/911/archive/2008/05/20/1203477.html 位运算是指按二进制进行的运算.在系统软件中,常常需要处理二进制位的问题.C ...

  4. K-集合 (JXNU第二次周赛1006)set/平衡树

    K-集合 Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other) Total Submissi ...

  5. 设置session失效的几种方法

    转自:http://www.cnblogs.com/linjiqin/archive/2011/06/15/2081673.html 在系统登录后,都会设置一个当前session失效的时间,以确保在用 ...

  6. BZOJ3825 : [Usaco2014 Nov]Marathon

    不跳过任何点的路程=dis(l,l+1)+dis(l+1,l+2)+...+dis(r-2,r-1)+dis(r-1,r) 要跳过一个点i,则要最小化dis(i,i+2)-dis(i,i+1)-dis ...

  7. 编写爬虫程序的神器 - Groovy + Jsoup + Sublime

    写过很多个爬虫小程序了,之前几次主要用C# + Html Agility Pack来完成工作.由于.NET BCL只提供了"底层"的HttpWebRequest和"中层& ...

  8. TYVJ P1012 火柴棒等式 Label:枚举

    背景 NOIP2008年提高组第二题 描述 给你n根火柴棍,你可以拼出多少个形如“A+B=C”的等式?等式中的A.B.C是用火柴棍拼出的整数(若该数非零,则最高位不能是0).用火柴棍拼数字0-9的拼法 ...

  9. 3.22学习理解httpContext与where 1=1

    1.HttpContextHttpContext.Current.Session.RemoveAll();从会话状态集合中移除所有的键和值.(未过期,还存在)HttpContext.Current.S ...

  10. asp.net 微信企业号办公系统-流程设计--流程步骤设置-数据设置

    数据设置是控制在流程处理过程中,当前步骤的数据显示与编辑状态,控制当前步骤哪些字段为只读,隐藏或可编辑.需要配合表单设计器使用.