반응형

http://ergate.tistory.com/117

 

 



Directx 에서 지원하는 Sphere함수를 구현해보았습니다.

Slices는 나누어질 삼각형의 갯수 이며 Stack은 사진에서 Y축으로 나누어질 갯수 입니다.

Radius는 반지름의 값이며 Slices Stack Radius 의 값을 조정하시면 그 값에 맞게 Sphere가 그려집니다.

그리는 방식은 Vertices로 각 위치의 Point를 찍어주며 이것을 index buffer르 사용하여 사과의 껍질을 벗겨내는 형식으로 

각포인트를 이어서 삼각형을 만들어 주시면 됩니다.




 

#include <Windows.h>
#include <mmsystem.h>
#include <d3dx9.h>

//-----------------------------------------------------------------------------
// Global variables
//-----------------------------------------------------------------------------
LPDIRECT3D9             g_pD3D = NULL; 
LPDIRECT3DDEVICE9       g_pd3dDevice = NULL; 
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL;
LPD3DXMESH                  g_pMesh   = NULL; 
LPDIRECT3DINDEXBUFFER9      g_pIndexVB = NULL;

struct CUSTOMVERTEX
{
 FLOAT x, y, z;     
 DWORD color;       
};

#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)


struct INDEX
{
 WORD _0, _1, _2;
};

int Slices = 6;
int Stack = 4;
int numvertex = (Slices+1)*2+((Stack-3)*Slices);
int numface = (Slices*2)+((Stack-2)*2)*Slices;

 


//-----------------------------------------------------------------------------
// Name: InitD3D()
//-----------------------------------------------------------------------------
HRESULT InitD3D( HWND hWnd )
{
 if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
  return E_FAIL;

 D3DPRESENT_PARAMETERS d3dpp;
 ZeroMemory( &d3dpp, sizeof( d3dpp ) );
 d3dpp.Windowed = TRUE;
 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
 d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;

 if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
  D3DCREATE_SOFTWARE_VERTEXPROCESSING,
  &d3dpp, &g_pd3dDevice ) ) )
 {
  return E_FAIL;
 }

 g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

 g_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_WIREFRAME  );

 g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );

 return S_OK;
}

 

//-----------------------------------------------------------------------------
// Name: InitGeometry()
//-----------------------------------------------------------------------------
HRESULT InitGeometry()
{

 D3DXCreateSphere( g_pd3dDevice, 2.0f, 5, 4, &g_pMesh, NULL );  

 float Radius = 2.0f;

 CUSTOMVERTEX *g_Vertices = new CUSTOMVERTEX[numvertex];


 g_Vertices[0].x = 0.0f;
 g_Vertices[0].y = Radius; 
 g_Vertices[0].z = 0.0f;
 g_Vertices[0].color = 0xffffffff;

 for( int i=0+1, k=1; i<Stack; ++i )
 {
  D3DXVECTOR3 tmp( 0.0f, Radius * cosf( ( D3DX_PI / Stack ) * i ), Radius * sinf( ( D3DX_PI / Stack ) * i ));
  for( int j=0; j<Slices; ++j, ++k )
  {
   float temp = Radius - ( Radius - tmp.z );
   g_Vertices[k].x = temp * cosf(D3DXToRadian( (360/Slices) * j ));
   g_Vertices[k].y = tmp.y;
   g_Vertices[k].z = temp * sinf(D3DXToRadian( (360/Slices) * j ));
   g_Vertices[k].color = 0xffffffff;
  }
 }


 g_Vertices[numvertex-1].x = 0.0f;
 g_Vertices[numvertex-1].y = -Radius;     
 g_Vertices[numvertex-1].z = 0.0;
 g_Vertices[numvertex-1].color = 0xffffffff;


 if( FAILED( g_pd3dDevice->CreateVertexBuffer( numvertex * sizeof( CUSTOMVERTEX ),
  0, D3DFVF_CUSTOMVERTEX,
  D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )
 {
  return E_FAIL;
 }

 VOID* pVertices;
 if( FAILED( g_pVB->Lock( 0, sizeof( g_Vertices ), ( void** )&pVertices, 0 ) ) )
  return E_FAIL;
 memcpy( pVertices, g_Vertices, sizeof( CUSTOMVERTEX ) * numvertex);
 g_pVB->Unlock();


 int j=0;
 int z=0;

 INDEX *index = new INDEX[numface];

 for(z=0; z<Slices; ++z)
 {   
  index[z]._0 = 0;
  index[z]._1 = z+1;
  index[z]._2 = z+2-j;
  if( z == Slices - 2 )
  {
   j = Slices;
  }
 }

 int t = z;
 int tmp = 0;
 int tmp2 = 0;
 int a = 0;


 for( int i=0; i<Stack - 2; ++i )
 {
  tmp = (Slices + 1) + ( i * Slices );
  tmp2 = 2 + ( i * Slices ); 
  for( int j=0; j<Slices; ++j )
  {
   if( j == (Slices - 1) )
   {
    a = Slices;
   }
   index[t]._0 = tmp2 + j - a;         
   index[t]._1 = tmp2 + j - 1;         
   index[t]._2 = tmp2 + j + Slices - a;       

   index[t+1]._0 = tmp + j + 1 - a;                
   index[t+1]._1 = tmp + j - ( Slices );   
   index[t+1]._2 = tmp + j;    
   t+=2;
  }
  a = 0;
 }

 int b;

 b = t;

 int q = 0;
 for( int i=0; i<Slices; ++i )
 {
  index[b]._0 = tmp + i;
  index[b]._1 = tmp + Slices;
  index[b]._2 = tmp + i + 1 - q;
  if( i  == Slices - 2 )
  {
   q = Slices - i;
  }
  b++;
 }

 

 if( FAILED( g_pd3dDevice->CreateIndexBuffer( numface * sizeof(INDEX), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &g_pIndexVB, NULL ) ) )
 {
  return E_FAIL;
 }

 VOID* pIndices;
 if( FAILED( g_pIndexVB->Lock( 0, sizeof(INDEX)*numface, (void**)&pIndices, 0 ) ) )
  return E_FAIL;
 memcpy( pIndices, index, sizeof(INDEX)*numface );
 g_pIndexVB->Unlock();


 return S_OK;
}


//-----------------------------------------------------------------------------
// Name: Cleanup()
//-----------------------------------------------------------------------------
VOID Cleanup()
{


 if( g_pIndexVB != NULL )
  g_pIndexVB->Release();

 if( g_pMesh != NULL )
  g_pMesh->Release();

 if( g_pVB != NULL )
  g_pVB->Release();

 if( g_pd3dDevice != NULL )
  g_pd3dDevice->Release();

 if( g_pD3D != NULL )
  g_pD3D->Release();
}

 

//-----------------------------------------------------------------------------
// Name: SetupMatrices()
//-----------------------------------------------------------------------------
VOID SetupMatrices()
{
 D3DXMATRIXA16 matWorld;


 UINT iTime = timeGetTime() % 9000;
 FLOAT fAngle = iTime * ( 2.0f * D3DX_PI ) / 9000.0f;
 D3DXMatrixRotationY( &matWorld, fAngle );
 g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );


 D3DXVECTOR3 vEyePt( 0.0f, 0.0f,-10.0f );
 D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
 D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );

 D3DXMATRIXA16 matView;
 D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
 g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );


 D3DXMATRIXA16 matProj;
 D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI / 4, 1.0f, 1.0f, 100.0f );
 g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}

 

//-----------------------------------------------------------------------------
// Name: Render()
//-----------------------------------------------------------------------------
VOID Render()
{
 g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 0 ), 1.0f, 0 );

 if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
 {
  SetupMatrices();

 

  g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
  g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
  g_pd3dDevice->SetIndices( g_pIndexVB );

  //  g_pd3dDevice->DrawPrimitive( D3DPT_POINTLIST, 0, numvertex );

  g_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, numvertex, 0, numface );


  g_pd3dDevice->EndScene();
 }

 g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}

 


//-----------------------------------------------------------------------------
// Name: MsgProc()
// Desc: The window's message handler
//-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
 switch( msg )
 {
 case WM_DESTROY:
  Cleanup();
  PostQuitMessage( 0 );
  return 0;
 }

 return DefWindowProc( hWnd, msg, wParam, lParam );
}

 


//-----------------------------------------------------------------------------
// Name: WinMain()
//-----------------------------------------------------------------------------
INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT )
{
 UNREFERENCED_PARAMETER( hInst );

 WNDCLASSEX wc =
 {
  sizeof( WNDCLASSEX ), CS_CLASSDC, MsgProc, 0L, 0L,
  GetModuleHandle( NULL ), NULL, NULL, NULL, NULL,
  L"D3D Tutorial", NULL
 };
 RegisterClassEx( &wc );

 HWND hWnd = CreateWindow( L"D3D Tutorial", L"D3D Tutorial 03: Matrices",
  WS_OVERLAPPEDWINDOW, 100, 100, 800, 600,
  NULL, NULL, wc.hInstance, NULL );

 if( SUCCEEDED( InitD3D( hWnd ) ) )
 {
  if( SUCCEEDED( InitGeometry() ) )
  {
   ShowWindow( hWnd, SW_SHOWDEFAULT );
   UpdateWindow( hWnd );

   MSG msg;
   ZeroMemory( &msg, sizeof( msg ) );
   while( msg.message != WM_QUIT )
   {
    if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
    {
     TranslateMessage( &msg );
     DispatchMessage( &msg );
    }
    else
     Render();
   }
  }
 }

 UnregisterClass( L"D3D Tutorial", wc.hInstance );
 return 0;
}

반응형

'그래픽스(Graphics) > DirectX9~12' 카테고리의 다른 글

점 그리기 -크기 변환  (0) 2012.11.02
점그리기  (0) 2012.11.02
디바이스를 잃었을때의 복구 절차  (0) 2012.11.02
그래픽카드 디바이스. D3D_Device  (0) 2012.11.02
Directx3D 에서 2D 점 그리기  (0) 2012.11.02

+ Recent posts