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 ...
随机推荐
- hdu 3336 kmp+next数组应用
分析转自:http://972169909-qq-com.iteye.com/blog/1114968 十分易懂 题意:求字串中[前缀+跟前缀相同的子串]的个数? Sample Input 1 4 a ...
- CC2540开发板学习笔记(九)—— BLE协议简介
一.BLE协议简介 1.协议是什么? 协议是一系列的通信标准,双方需要共同按照这进行正常数据 协议是一系列的通信标准,双方需要共同按照这进行正常数据发射和 接收.协议栈是的具体实现形式,通俗点来理解就 ...
- Android中动画
两种动画 view动画 属性动画 (也可以使用xml描述动画) view 4动画 补间动画 渐变 AlphaAnimation 缩放 ScaleAnimation 平移 TranslateAnima ...
- sql2005-数据库备份方案 (转载)
sql2005数据库备份一般情况分为二种:一是手工备份.二是自动备份.以下是二种方法的步骤: 一.手工备份 打开数据库,选择要备份数据库,右键选择[任务]->[备份],打开备份数据库页面,在[源 ...
- Codeforces Round #294 (Div. 2)
水 A. A and B and Chess /* 水题 */ #include <cstdio> #include <algorithm> #include <iost ...
- html5 header和group
<html> <head> <meta charset="UTF-8" /> <meta name="generator&quo ...
- BZOJ4298 : [ONTAK2015]Bajtocja
设f[i][j]为第i张图中j点所在连通块的编号,加边时可以通过启发式合并在$O(dn\log n)$的时间内维护出来. 对于每个点,设h[i]为f[j][i]的hash值,若两个点hash值相等,则 ...
- BZOJ3808 : Neerc2012 Labyrinth of the Minotaur
左上角和右下角不四连通等价于左下角和右上角八连通 枚举正方形的左上角,先二分出最大的边长,使得里面不含障碍物 然后再二分出最小的边长,使得两部分连通,用前缀和判断 这题WA了好久…一直对拍都没问题…于 ...
- 哈希表工作原理 (并不特指Java中的HashTable)
1. 引言 哈希表(Hash Table)的应用近两年才在NOI中出现,作为一种高效的数据结构,它正在竞赛中发挥着越来越重要的作用. 哈希表最大的优点,就是把数据的存储和查找消耗的时 ...
- Java多线程编程详解
转自:http://programming.iteye.com/blog/158568 线程的同步 由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题.Ja ...