2013-12-23 106 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 :( –