directX基础学习系列7 网格(自己创建)
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 网格(自己创建)的更多相关文章
- DirectX基础学习系列8 渐进网格以及外接体
1 IUnknown--> ID3DXBUFFER D3D泛型接口: GetBufferPointer Retrieves a pointer to the data in the buffer ...
- 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基础学习系列4 颜色和光照
4.1颜色表示 RGB颜色:D3DCOLOR 可以用宏D3DCOLOR_ARGB(a,r,g,b) D3DCOLOR_XRGB(255,r,g,b) 另外一种浮点表示:D3DCOLORVALUE, ...
- DirectX 基础学习系列6 字体
DIRECTX9自带ID3DXFONT类 内部调用GDI的接口,效率一般,但能够处理一些复杂的字体 HRESULT D3DXCreateFontIndirect( LPDIRECT3DDEVICE9 ...
- DirectX基础学习系列5 融合技术
7.1融合方程 1概念 融合技术将当前光栅化像素的颜色与以前已光栅化并处于同一个位置的像素颜色进行合成,即将当前要进行光栅化的三角形单元与已写入后台的像素进行融合 2需要遵循的原则: (1)先绘制不需 ...
- 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 操作 - 配置
http://blog.csdn.net/flyingbox/article/details/1823231 http://blog.csdn.net/libingquan008/article/de ...
- Java Hour 56 Spring 和 Hibernate 的集成
上一章节我们完成了一个简单的Spring 的试验品,这章要让Spring 上战场了,不要慌,步骤都是一样的. Spring 对 Hibernate 的支持是很多方面的,第一个战场是SessionFac ...
- POJ 2185 Milking Grid KMP(矩阵循环节)
Milking Grid Time Limit: 3000MS Memory Lim ...
- javascript优化--07模式(对象)02
沙箱模式: 解决空间命名模式的几个缺点: 命名空间模式中无法同时使用一个应用程序或库的两个版本运行在同一个页面中,因为两者需要相同的全局符号: 以点分割,需要输入更长的字符,解析时间也更长: 全局构造 ...
- http://jingyan.baidu.com/article/db55b609aac41e4ba30a2f86.html
http://jingyan.baidu.com/article/db55b609aac41e4ba30a2f86.html
- 模拟 POJ 2996 Help Me with the Game
题目地址:http://poj.org/problem?id=2996 /* 题意:给出白方和黑方的棋子和对应的坐标,输出该副棋盘的样子 模拟题 + 结构体排序:无算法,switch区分读入的字符,按 ...
- C# 序列化(Serialize)与反序列化(Deserialize)ZZ
序列化又称串行化,是.NET运行时环境用来支持用户定义类型的流化的机制.其目的是以某种存储形成使自定义对象持久化,或者将这种对象从一个地方传输到另一个地方. .NET框架提供了两种种串行化的方式:1. ...
- A C[HDU1570]
A C Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
- CodeForces Round 192 Div2
This is the first time I took part in Codeforces Competition.The only felt is that my IQ was contemp ...
- codevs 1060
题目大意: 有2n张票,分别有A,B两类,求最后两个人拿到同种票的概率.n<=1250; 想想这题应该是组合啊..但是到底是组合还是排列..如果是组合, 概率为:1-两种票都取了n-1张的情况, ...