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 ...
随机推荐
- 使用HtmlAgilityPack抓取网页数据
XPath 使用路径表达式来选取 XML 文档中的节点或节点集.节点是通过沿着路径 (path) 或者步 (steps) 来选取的. 下面列出了最有用的路径表达式: nodename:选取此节点的所有 ...
- win32_11gR2_database安装教程
- 三种方法实现js跨域访问
转自:http://narutolby.iteye.com/blog/1464436 javascript跨域访问是web开发者经常遇到的问题,什么是跨域,一个域上加载的脚本获取或操作另一个域上的文档 ...
- 【GruntMate】一个让你更方便使用Grunt的工具
GruntMate是什么? 一个基于Grunt的项目管理可视化工具(还不知道Grunt是什么?可以谷歌一下就知道了!) GruntMate有哪些功能? 方便的管理基于Grunt的项目 方便统一管理Gr ...
- android 自定义弹出框AlertDialog ,很炫的哦
于是就小小的模仿了下自己写了这个这样的效果,主要代码如下:dlg = new AlertDialog.Builder(context).create();dlg.show();dlg.getWin ...
- android 文字写在图片上
在linearlayout中直接设置背景图片,背景图片会被拉伸.. 我们来试一下imagebutton 但是imagebutton无法添加文字.. button能同时添加文字和图片但是图片比例没法控制 ...
- vi总结
vi常用命令整理 ★命令模式 移动光标 h 或 向左方向键(←) → 光标向左移动一个字元 j 或 向下方向鍵(↓) → 光标向下移动一个字元 k 或 向上方向鍵(↑) → 光标向上移动一个字元 l ...
- javascript的window.onload()方法和jQuery的$(document).ready()的对比
jQuery中$(document).ready()的作用类似于传统JavaScript中的window.onload方法,不过与window.onload方法还是有区别的. 1.执行时间 windo ...
- MVC ActionResult视图结果
摘要 MVC框架针对HttpResponse进行抽象与多态,使HttpResponse均可表示为ActionResult.那么,抽象和多态表现在哪里呢? //封装一个Action的结果. public ...
- JQuery LazyLoad实现图片延迟加载-探究
对于大量图片的网站,图片延迟加载是提高速度和性能的好方法. 目前图片延迟加载主要分两大块,一是触发加载(根据滚动条位置加载图片):二是自动预加载(加载完首屏后n秒后自动加载其他位置的图片).大体常用的 ...