|
如题,我做了个球体类
class mysphere {
private:
point3 center;
float radio;
int fineness;
DWORD color;
#ifdef NORMAL
vertex3Normal *vertices;
#else
vertex3 *vertices;
#endif
tri<DWORD> *triangle;
DWORD *index;
DWORD numVerts;
DWORD numIndex;
DWORD numTri;
void fill ();
public:
mysphere(float const &Radio, point3 const &Center = point3(0.0f, 0.0f, 0.0f), int const &Fineness = 12, DWORD const &Color = 0XFFFFFFFF):
center(Center), radio(Radio), fineness(Fineness), color(Color){
fill();
};
~mysphere(){
SAFE_FREE(vertices);
SAFE_FREE(triangle);
SAFE_FREE(index);
}
void prepare(IDirect3DDevice9 *p_D3DDevice,
IDirect3DVertexBuffer9 **g_vb,
IDirect3DIndexBuffer9 **g_ib,
UINT const &offset_v = 0,
UINT const &offset_i = 0) {
HRESULT hr;
void *vb_vertex;
void *ib_index;
if (*g_vb == NULL) {
#ifdef NORMAL
hr = p_D3DDevice->CreateVertexBuffer( numVerts*sizeof (vertex3Normal),
D3DUSAGE_WRITEONLY,
D3D9T_CUSTOMVERTEX,
D3DPOOL_MANAGED,
g_vb,
NULL
);
#else
hr = p_D3DDevice->CreateVertexBuffer( numVerts*sizeof (vertex3),
D3DUSAGE_WRITEONLY,
D3D9T_CUSTOMVERTEX,
D3DPOOL_MANAGED,
g_vb,
NULL
);
#endif
hr = (*g_vb)->Lock(0, 0, (void **)&vb_vertex, D3DLOCK_DISCARD);
}
else {
#ifdef NORMAL
hr = (*g_vb)->Lock(offset_v, numVerts*sizeof(vertex3Normal), (void **)&vb_vertex, D3DLOCK_NOOVERWRITE);
#else
hr = (*g_vb)->Lock(offset_v, numVerts*sizeof(vertex3), (void **)&vb_vertex, D3DLOCK_NOOVERWRITE);
#endif
}
#ifdef NORMAL
memcpy (vb_vertex, vertices, numVerts*sizeof (vertex3Normal));
#else
memcpy (vb_vertex, vertices, numVerts*sizeof (vertex3));
#endif
hr = (*g_vb)->Unlock();
if (*g_ib == NULL) {
hr = p_D3DDevice->CreateIndexBuffer( numIndex*sizeof(DWORD),
D3DUSAGE_WRITEONLY,
D3DFMT_INDEX32,
D3DPOOL_DEFAULT,
g_ib,
NULL
);
hr = (*g_ib)->Lock(0, 0, (void **)&ib_index, D3DLOCK_DISCARD);
}
else {
hr = (*g_ib)->Lock(offset_i, numIndex*sizeof(DWORD), (void **)&ib_index, D3DLOCK_NOOVERWRITE);
}
memcpy (ib_index, index, numIndex*sizeof (DWORD));
hr = (*g_ib)->Unlock();
};
void draw(IDirect3DDevice9 *p_D3DDevice, D3DXMATRIX const &matWorld, IDirect3DVertexBuffer9 * g_vb, IDirect3DIndexBuffer9 * g_ib){
#ifdef NORMAL
p_D3DDevice ->SetStreamSource(0, g_vb, 0, sizeof (vertex3Normal));
#else
p_D3DDevice ->SetStreamSource(0, g_vb, 0, sizeof (vertex3));
#endif
p_D3DDevice ->SetIndices(g_ib);
p_D3DDevice ->SetTransform(D3DTS_WORLD, &matWorld);
p_D3DDevice ->DrawIndexedPrimitive (D3DPT_TRIANGLESTRIP, 0, 0, numVerts, 0, numIndex - 2);
};
};
void mysphere::fill() {
short flag = fineness%2;
float fDsin = sinf(2*D3DX_PI/fineness);
float fDcos = cosf(2*D3DX_PI/fineness);
float fsin = 0.0f;
float fcos = 1.0f;
float fZsin = 1.0f;
float fZcos = 0.0f;
float fZsin_t;
float fZcos_t;
float fsin_t;
float fcos_t;
float z;
float fr;
int num = 0;
int numindex = 0;
DWORD count_v= ((int)(fineness>>1) + flag - 1)*fineness + 2;
DWORD count_i= 2*((int)(fineness>>1) + flag - 1)*fineness + ((int)(fineness>>1) + flag - 1) + 2*fineness + 1;
#ifdef NORMAL
vertices = (vertex3Normal*)malloc(count_v*sizeof(vertex3Normal));
vertices[num++] = vertex3Normal(0, 0, radio, point3(0, 0, 1), color);
#else
vertices = (vertex3*)malloc(count_v*sizeof(vertex3));
vertices[0] = vertex3(0, 0, radio, color);
#endif
index = (DWORD*)malloc(count_i*sizeof(DWORD));
fZsin_t = fZsin*fDcos + fZcos*fDsin;
fZcos_t = fZcos*fDcos - fZsin*fDsin;
fZsin = fZsin_t;
fZcos = fZcos_t;
//填充开始
//画经度
for (int i = 1; i < (int)(fineness>>1) + flag; i ++) {
z = radio*fZsin;
fr = radio*fZcos;
fZsin_t = fZsin*fDcos + fZcos*fDsin;
fZcos_t = fZcos*fDcos - fZsin*fDsin;
fZsin = fZsin_t;
fZcos = fZcos_t;
//画维度
for (int j = 0; j < fineness; j ++) {
//填充索引
index[numindex++] = (DWORD)(i == 1?0:num - fineness);
index[numindex++] = (DWORD)num;
//填充顶点
#ifdef NORMAL
vertices[num++] = vertex3Normal((center + point3(fr*fcos, fr*fsin, z)), fr*fcos, fr*fsin, z, color);
#else
vertices[num++] = vertex3((center + point3(fr*fcos, fr*fsin, z)), color);
#endif
fsin_t = fsin*fDcos + fcos*fDsin;
fcos_t = fcos*fDcos - fsin*fDsin;
fsin = fsin_t;
fcos = fcos_t;
}
//闭合索引
index[numindex++] = (DWORD)(i == 1?0:num-(fineness<<2));
}
#ifdef NORMAL
vertices[num++] = vertex3Normal((center + point3(0, 0, -radio)), point3(0, 0, -1), color);
#else
vertices[num++] = vertex3((center + point3(0, 0, -radio)), color);
#endif
numVerts = num;
for (int i = 0; i < fineness; i ++) {
index[numindex++] = (DWORD)(num - 1 - fineness + i);
index[numindex++] = (DWORD)(num - 1);
}
index[numindex++] = (DWORD)(num - 1 - fineness);
numIndex = numindex;
numTri = 2*fineness*((DWORD)(fineness/2));
};
此外还画了2个box,第一个的顶点数据是直接初始化数组,另一个是从自己建的一个box类画的。光画2个box发现没出现问题,加上那个球后,就会从球体上多出一个点(此点连着球上的两个点,所以组成一个很不和谐的三角面),并且这个点时而跑到屏幕左上角,时而又跟着另两个box转动。后来我之去掉一个box,发现这点还存在,然后再去掉一个box,发现就正常了~~~,所以怀疑是顶点缓冲或是索引缓冲和流什么的设错了。但是我三个几何体的顶点缓冲都是分开设的,索引也是分开的,流也是设置一次画一次(StreamSource。。。draw。。。StreamSource。。。draw。。。StreamSource。。。draw。。。)所以实在搞不懂是怎么回事了。还有个问题,我设的球体类在初始化时能设置经纬线的数量,好像对于不同显卡,这个数量设置到一定大小后,球就画不出来了,这是怎么回事?我家里电脑设置到1550还能画出来,3550球就不见了。
[em17]本人是新手中的新手,接触DirectX 3D没多久,之前都不知道DirectX已经内置了球体的形状~~~,不过既然已经自己做了个球体类,就不想半途而废,所以请各位达人帮帮忙~~~
对了,我画球体是用D3DPT_TRIANGLESTRIP画的,所以法线是一个面正下一个面反,所以如果看到这球缺一块少一块,关掉背面剔除就行了,对于怎么设置法线我目前为止还是一知半解的,不过希望先把这个问题搞定。
调试时发现numIndex和numVerts的数量都没错
程序就用到一个cpp和一个h文件,用的是Direct9,这俩文件我传附件啦
 |
|