最早学习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);
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);