Вершинная сфера DirectX 9

0

Я пытаюсь создать сферу, которая работает со следующим кодом, используя C++ и DirectX:

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(). Я получил странные результаты, показанные ниже. Что я делаю не так?

Изображение 174551Изображение 174551

Вот результат, который я хочу:

Изображение 174551

ОБНОВИТЬ:

Я попробовал еще несколько образцов, но он работает неправильно. Я попытался добавить 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);

Результат:

Изображение 174551Изображение 174551

  • 0
    Мне нужно создать что-то вроде этого 2ch.hk/sn/src/1366328787385.png
  • 0
    @ Крис это? backgroundsy.com/file/matte-white-sphere.jpg
Показать ещё 4 комментария
Теги:
directx
directx-9

2 ответа

0
Лучший ответ

Я решил эту проблему, я должен использовать DrawIndexedPrimitive. Не DrawPrimitive.

1

На скриншоте, который вы публикуете, кажется, вы используете каркас в качестве режима заполнения, вы должны использовать твердый режим, который является D3DFILL_SOLID. и вы должны дать ему белый цвет для ожидаемого результата.

Редактировать:

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню