游戏开发论坛

 找回密码
 立即注册
搜索
查看: 1492|回复: 0

自己做了个球体类,可是画出来后发现多处一个位置随机

[复制链接]

1

主题

1

帖子

5

积分

新手上路

Rank: 1

积分
5
发表于 2010-5-27 15:20:00 | 显示全部楼层 |阅读模式
如题,我做了个球体类

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,这俩文件我传附件啦

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-6-9 18:22

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表