2013-12-23 6 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 this? 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. и вы должны дать ему белый цвет для ожидаемого результата.

Edit:

Попробуйте установить режим отбрасывания невидимых граней в D3DCULL_NONE, эта опция убедитесь, что все треугольники будут оказаны.

+0

Нет, я использую режим сплошной заливки. Когда я использую wireframe, это выглядит так: http://cs425222.vk.me/v425222027/7b6b/0U05t0q2YaI.jpg –

+0

см. Мое редактирование о режиме отбраковки. – zdd

+0

cull mode уже установлен на D3DCULL_NONE :( –