DX中使用顶点缓存和索引缓存绘制图形

最早学习3D的时候,大概都是将数据存在内存中,然后调用相应的函数绘制。

例如:(OpenGL的例子)

glClear(GL_COLOR_BUFFER_BIT) ;
 glColor3f(1.0, 1.0, 1.0) ; 
 glBegin(GL_LINES) ;
 	glVertex3f(1.0, 1.0, 0.0) ;
 	glVertex3f(2.0, 2.0, 0.0) ;
 glEnd() ;
 glFlush();

但是对于某些固定的物体的绘制,如果将这些物体的信息放在显存中,再进行绘制,会获得更快的速度。

3D空间中绘制一个物体,要知道的信息有,物体的顶点信息和顶点的顺序信息(索引信息)。将这些信息存在显存中即可完成绘制的准备工作。


下面就是DX中定义的数据结构:

IDirect3DVertexBuffer9* VB = 0;
 IDirect3DIndexBuffer9*  IB = 0;

如果要绘制一个金字塔的四个面(底面不绘制),那么可以按照以下的流程:


一,定义顶点的结构

如果不需要颜色可以定义为

struct vertex
 {
 	float m_pos[3];
 };

需要颜色可以定义为

struct Vertex_VC
 {
 	float m_Position[3];
 	// R,G,B,A in OpenGL
 	// B,G,R,A in Direct3D 9
 	// Direct3D 10可以是两种其中之1, 看设置而定.
 	unsigned char m_RGBA[4];
 };

需要光照什么的也可以添加相关的信息。

总之顶点的结构是灵活的。选择很多

#define D3DFVF_RESERVED0        0x001
 #define D3DFVF_POSITION_MASK    0x400E
 #define D3DFVF_XYZ              0x002
 #define D3DFVF_XYZRHW           0x004
 #define D3DFVF_XYZB1            0x006
 #define D3DFVF_XYZB2            0x008
 #define D3DFVF_XYZB3            0x00a
 #define D3DFVF_XYZB4            0x00c
 #define D3DFVF_XYZB5            0x00e
 #define D3DFVF_XYZW             0x4002
 
 #define D3DFVF_NORMAL           0x010
 #define D3DFVF_PSIZE            0x020
 #define D3DFVF_DIFFUSE          0x040
 #define D3DFVF_SPECULAR         0x080
 
 #define D3DFVF_TEXCOUNT_MASK    0xf00
 #define D3DFVF_TEXCOUNT_SHIFT   8
 #define D3DFVF_TEX0             0x000
 #define D3DFVF_TEX1             0x100
 #define D3DFVF_TEX2             0x200
 #define D3DFVF_TEX3             0x300
 #define D3DFVF_TEX4             0x400
 #define D3DFVF_TEX5             0x500
 #define D3DFVF_TEX6             0x600
 #define D3DFVF_TEX7             0x700
 #define D3DFVF_TEX8             0x800
 
 #define D3DFVF_LASTBETA_UBYTE4   0x1000
 #define D3DFVF_LASTBETA_D3DCOLOR 0x8000
 
 #define D3DFVF_RESERVED2         0x6000  // 2 reserved bits
 

例如:

device->SetFVF(D3DFVF_XYZ|D3DFVF_DIFFUSE); 
是设置顶点格式为位置和颜色


二、创建索引

一般创建的索引为静态缓存,放置在显卡中。

D3DUSAGE_DYNAMIC 为动态缓存,放置在AGP存储区中


创建定点缓存

HRESULT hr = device->CreateVertexBuffer(
 			5 * sizeof(vertex),
 			0,
 			D3DFVF_XYZ,
 			D3DPOOL_DEFAULT,
 			&g_vb,
 			0);
 

使用Lock来给缓存加数据,这里使用的顶点结构只有xyz,反正顶点在内存中就是3个float排列表示顶点位置

vertex	*vs;
 g_vb->Lock(0, 0, (void**)&vs, 0);
 
 //top
 vs[0].m_pos[0] = 0.0;
 vs[0].m_pos[1] = 1.0;
 vs[0].m_pos[2] = 0.0;
 
 vs[1].m_pos[0] = -0.5;
 vs[1].m_pos[1] = 0.0;
 vs[1].m_pos[2] = 0.5;
 
 vs[2].m_pos[0] = 0.5;
 vs[2].m_pos[1] = 0.0;
 vs[2].m_pos[2] = 0.5;
 
 vs[3].m_pos[0] = 0.5;
 vs[3].m_pos[1] = 0.0;
 vs[3].m_pos[2] = -0.5;
 
 vs[4].m_pos[0] = -0.5;
 vs[4].m_pos[1] = 0.0;
 vs[4].m_pos[2] = -0.5;
 
 g_vb->Unlock();

创建索引缓存

hr = device->CreateIndexBuffer(
 	12 * sizeof(WORD),
 	0,
 	D3DFMT_INDEX16,
 	D3DPOOL_DEFAULT,
 	&g_ib,
 	0);
 

加入数值

unsigned short *index = NULL;
 g_ib->Lock(0, 0, (void**)&index, 0);
 index[0] = 0;
 index[1] = 1;
 index[2] = 2;
 index[3] = 0;
 index[4] = 2;
 index[5] = 3;
 index[6] = 0;
 index[7] = 3;
 index[8] = 4;
 index[9] = 0;
 index[10] = 4;
 index[11] = 1;
 g_ib->Unlock();
 

三、绘制

绘制之前,设置好投影,目标位置等

然后指定数据输入源,顶点格式,索引缓存

device->SetStreamSource(0, g_vb, 0, sizeof(vertex));
 device->SetFVF(D3DFVF_XYZ);
 device->SetIndices(g_ib);
 

开始绘制:

device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0,0,5,0,4);
 


绘制部分代码:

Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
 Device->BeginScene();
 
 Device->SetStreamSource(0, VB, 0, sizeof(Vertex));
 Device->SetIndices(IB);
 Device->SetFVF(D3DFVF_XYZ);
 
 // Draw cube.
 Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 5, 0, 4);
 
 Device->EndScene();
 Device->Present(0, 0, 0, 0);
 





你可能感兴趣的:(DX中使用顶点缓存和索引缓存绘制图形)