2013-12-23 175 views
0

我想画一个球体用C++其做用下面的代码工作和DirectX:DirectX 9的顶点球

struct Vertex 
{ 
D3DXVECTOR3 position; //float x, y, z; 
DWORD color; 
}; 


void myApp::createAndFillVertexBuffer(){ 
int radius = 1; 
float slices = 50; 
float stacks = 50; 
float sliceStep = 2*D3DX_PI/slices; 
float stackStep = D3DX_PI/stacks; 
int vertexCount = slices * (stacks - 1) + 2; 
primitiveCount = slices * (stacks - 1) * 2; 

m_D3DDev->CreateVertexBuffer(
sizeof(Vertex)*vertexCount, 
D3DUSAGE_WRITEONLY, 
D3DFVF_M_VERTEX,     
D3DPOOL_DEFAULT, 
&m_VB,    
NULL); 

Vertex *m_MVB; 
HRESULT hRes = m_VB->Lock(0,0,(void**)&m_MVB,0); 
if (hRes == D3D_OK) 
{ 
    int currentVertex = 0; 
    m_MVB[currentVertex++].position = D3DXVECTOR3(0.0f, -radius, 0.0f); 
    float stackAngle = D3DX_PI - stackStep; 

    for (int i = 0; i < stacks - 1; i++) 
    { 
      float sliceAngle = 0; 
      for (int j = 0; j < slices; j++) 
      { 

       float x = (float)(radius * sinf(stackAngle) * cosf(sliceAngle)); 
       float y = (float)(radius * cosf(stackAngle)); 
       float z = (float)(radius * sinf(stackAngle) * sinf(sliceAngle)); 
       m_MVB[currentVertex].position = D3DXVECTOR3(x,y,z); 
       m_MVB[currentVertex].color = D3DCOLOR_XRGB(255,200,100); 
       currentVertex++; 
       sliceAngle += sliceStep; 
     } 
     stackAngle -= stackStep; 
    } 
    m_MVB[currentVertex++].position = D3DXVECTOR3(0.0f, radius, 0.0f); 
    m_VB->Unlock(); 
} 
} 

我创建一个使用顶点球,我应该只使用顶点做到这一点,不是D3DXCreateSphere()方法。 我得到了下面显示的奇怪结果。我究竟做错了什么?

Current 1 Current 2

这是我想要的结果:

Wanted

UPDATE:

我尝试了一些更多的样本,但它的工作是错误的。 我试图添加indexBuffer到我的算法。这里产生的算法,但它也工作错误:

int number_of_vertices, number_of_faces; 
int slices= 20; 
int stacks = 20; 
float phi_step, phi_start; 
float theta_step, theta, sin_theta, cos_theta; 
int vertex, face; 
int slice, stack; 
number_of_vertices = 2 + slices * (stacks-1); 
number_of_faces = 2 * slices + (stacks - 2) * (2 * slices); 

primitiveCount = number_of_faces; 

m_D3DDev->CreateVertexBuffer(
    sizeof(Vertex)*number_of_vertices, 
    D3DUSAGE_WRITEONLY, 
    D3DFVF_M_VERTEX,     
    D3DPOOL_DEFAULT, 
    &m_VB,    
    NULL); 

m_D3DDev->CreateIndexBuffer(sizeof(int) * number_of_faces*3, 
    D3DUSAGE_WRITEONLY, 
    D3DFMT_INDEX32, 
    D3DPOOL_DEFAULT, 
    &pIbuf, 
    NULL); 

Vertex *vertices; 
HRESULT hRes = m_VB->Lock(0,0,(void**)&vertices,0); 


WORD *faces; 
HRESULT hRes2 = pIbuf->Lock(0, 0, (void**)&faces, 0); 

if (FAILED(hRes2)) { 
     return; 
} 

phi_step = -2 * D3DX_PI/slices; 
phi_start = D3DX_PI/2; 

theta_step = D3DX_PI/stacks; 
theta = theta_step; 

vertex = 0; 
face = 0; 
stack = 0; 

vertices[vertex].position.x = 0.0f; 
vertices[vertex].position.y = 0.0f; 
vertices[vertex].position.z = radius; 
vertices[vertex].color = D3DCOLOR_XRGB(255,200,100); 
vertex++; 

for (stack = 0; stack < stacks - 1; stack++) { 
     sin_theta = sinf(theta); 
     cos_theta = cosf(theta); 

     for (slice = 0; slice < slices; slice++) { 
      vertices[vertex].normal.x = sin_theta * cosf(phi_start); 
      vertices[vertex].normal.y = sin_theta * sinf(phi_start); 
      vertices[vertex].normal.z = cos_theta; 
      vertices[vertex].position.x = radius * sin_theta * cosf(phi_start); 
      vertices[vertex].position.y = radius * sin_theta * sinf(phi_start); 
      vertices[vertex].position.z = radius * cos_theta; 
      vertices[vertex].color = D3DCOLOR_XRGB(255,200,100); 
      vertex++; 

      phi_start += phi_step; 

      if (slice > 0){ 
       if (stack == 0){ 
        faces[face++] = 0; 
        faces[face++] = slice + 1; 
        faces[face++] = slice; 
       } else { 
        faces[face++] = sphere_vertex(slices, slice-1, stack-1); 
        faces[face++] = sphere_vertex(slices, slice, stack-1); 
        faces[face++] = sphere_vertex(slices, slice-1, stack); 

        faces[face++] = sphere_vertex(slices, slice, stack-1); 
        faces[face++] = sphere_vertex(slices, slice, stack); 
        faces[face++] = sphere_vertex(slices, slice-1, stack); 
       } 
      } 
     } 

      theta += theta_step; 

      if (stack == 0) { 
       faces[face++] = 0; 
       faces[face++] = 1; 
       faces[face++] = slice; 
     } 
     else { 
      faces[face++] = sphere_vertex(slices, slice-1, stack-1); 
      faces[face++] = sphere_vertex(slices, 0, stack-1); 
      faces[face++] = sphere_vertex(slices, slice-1, stack); 

      faces[face++] = sphere_vertex(slices, 0, stack-1); 
      faces[face++] = sphere_vertex(slices, 0, stack); 
      faces[face++] = sphere_vertex(slices, slice-1, stack); 
     } 
} 

    vertices[vertex].position.x = 0.0f; 
    vertices[vertex].position.y = 0.0f; 
    vertices[vertex].position.z = -radius; 
    vertices[vertex].color = D3DCOLOR_XRGB(255,200,100); 
    vertices[vertex].normal.x = 0.0f; 
    vertices[vertex].normal.y = 0.0f; 
    vertices[vertex].normal.z = -1.0f; 

    for (slice = 1; slice < slices; slice++){ 
     faces[face++] = sphere_vertex(slices, slice-1, stack-1); 
     faces[face++] = sphere_vertex(slices, slice, stack-1); 
     faces[face++] = vertex; 
    } 

    faces[face++] = sphere_vertex(slices, slice-1, stack-1); 
    faces[face++] = sphere_vertex(slices, 0, stack-1); 
    faces[face++] = vertex; 
    m_VB->Unlock(); 
    pIbuf->Unlock(); 

功能spehereVetrex:

static WORD sphere_vertex(UINT slices, int slice, int stack) 
{ 
     return stack*slices+slice+1; 
} 

然后画原语:

m_D3DDev->SetStreamSource(0,m_VB,0,sizeof(Vertex)); 
m_D3DDev->SetIndices(pIbuf); 
m_D3DDev->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,primitiveCount); 

Vetrex:

#define D3DFVF_M_VERTEX (D3DFVF_XYZ |D3DFVF_NORMAL| D3DFVF_DIFFUSE) 

Vetrex结构:

struct Vertex 
{ 
D3DXVECTOR3 position; //float x, y, z; 
D3DXVECTOR3 normal; 
DWORD color; 
}; 
IDirect3DDevice9 *m_D3DDev; 
IDirect3DVertexBuffer9 *m_VB; // Vertex Buffer 
IDirect3DIndexBuffer9 *pIbuf; 

//config D3DDevice 
m_D3DDev->SetRenderState(D3DRS_LIGHTING, false); 
m_D3DDev->SetRenderState(D3DRS_ZENABLE, TRUE); 
m_D3DDev->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE); 
m_D3DDev->SetFVF(D3DFVF_M_VERTEX); 

结果:

current 1 current 2

+0

我需要制作这样的东西http://2ch.hk/sn/src/1366328787385.png –

+0

@chris这个? http://www.backgroundsy.com/file/matte-white-sphere.jpg –

+0

你可以显示你的渲染调用(绘制原语)?看起来几何图形(三角形)没有正确指定。你使用索引缓冲区吗?对于这种类型的阴影,还需要在顶点数据中指定曲面法线。也许你应该遵循这个教程:http://msdn.microsoft.com/en-us/library/windows/desktop/bb153261%28v=vs.85%29.aspx – cdoubleplusgood

回答

0

我解决了这个问题 我应该使用DrawIndexedPrimitive。不DrawPrimitive。

1

从您发布的截图,看来你是使用线框作为填充模式,你应该使用固体模式,这是D3DFILL_SOLID。你应该给它一个白色的颜色,以达到预期的效果。

编辑:

尝试设置扑杀模式D3DCULL_NONE,此选项确保所有的三角形将被渲染。

+0

不,我使用的是实心填充模式。当我使用线框它看起来像这样:http://cs425222.vk.me/v425222027/7b6b/0U05t0q2YaI.jpg –

+0

请参阅我的关于剔除模式的编辑。 – zdd

+0

剔除模式已设置为D3DCULL_NONE :( –