void CALLBACK OnD3D9FrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
HRESULT hr;
// Clear the render target and the zbuffer
V( pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB( 0, 0, 0, 0 ), 1.0f, 0 ) );
pd3dDevice->SetRenderState(D3DRS_ZENABLE, true);
pd3dDevice->SetRenderState( D3DRS_LIGHTING, false );
// Render the scene
if( SUCCEEDED( pd3dDevice->BeginScene() ) )
{
D3DMATERIAL9 Mtrls;
Mtrls.Diffuse.r = 0.3;
Mtrls.Diffuse.g = 0.1;
Mtrls.Diffuse.b = 0.5;
Mtrls.Diffuse.a = 0.9;
Mtrls.Ambient = Mtrls.Diffuse;
pd3dDevice->SetMaterial(&Mtrls);
hr = pd3dDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_CW);
D3DXMATRIX matWorld;
D3DXMatrixRotationY(&matWorld, g_mThetaY);
pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
g_Objects.at(0)->Draw();
V( pd3dDevice->EndScene() );
g_mThetaY+=0.1;
}
}
HRESULT hr;
hr = m_pDevice->SetStreamSource(0,m_pVB,0,sizeof(MESHVERTEX));
hr = m_pDevice->SetFVF(D3DFVF_MESHVERTEX);
hr = m_pDevice->SetIndices(m_pIB);
hr = m_pDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,iVQuantity,0,iTQuantity);
HRESULT CALLBACK OnD3D9CreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc,
void* pUserContext )
{
HRESULT result;
g_pCamera = new CFirstPersonCamera();
// Setup the camera's view parameters
D3DXVECTOR3 vecEye( -20, 10.0f, 0.0f );
D3DXVECTOR3 vecAt ( 0.0f, 0.0f, 0.0f );
g_pCamera->SetViewParams( &vecEye, &vecAt );
// Setup the camera's project parameters
g_pCamera->SetProjParams(D3DX_PI/2.0,4.0/3.0,1.0,2000);//fov,aspect,near,far
pd3dDevice->SetTransform(D3DTS_VIEW, g_pCamera->GetViewMatrix());
pd3dDevice->SetTransform(D3DTS_PROJECTION, g_pCamera->GetProjMatrix());
SphereMesh* Sphere01 = new SphereMesh(4,4,30,D3DXVECTOR3(0,0,0), pd3dDevice);
g_Objects.push_back(Sphere01);
}
#define D3DFVF_MESHVERTEX (D3DFVF_XYZ| D3DFVF_NORMAL| D3DFVF_DIFFUSE)
struct MESHVERTEX
{
float x, y, z;
float nx, ny, nz;
D3DXCOLOR rgba;
};
SphereMesh::SphereMesh(int iYSamples, int iRadialSamples, float fRadius, D3DXVECTOR3 Pos, IDirect3DDevice9* pDevice){
m_pDevice = pDevice;
m_Pos = Pos;
int iYSm1 = iYSamples-1, iYSm2 = iYSamples-2, iYSm3 = iYSamples-3;
int iRSp1 = iRadialSamples+1;
iVQuantity = iYSm2*iRSp1 + 2;
iTQuantity = 2*iYSm2*iRadialSamples;
MESHVERTEX* SphereVerts = new MESHVERTEX[iVQuantity];
// Generate geometry
float fInvRS = 1.0f/(float)iRadialSamples;
float fYFactor = 2.0f/(float)iYSm1;
int iR, iY, iYStart, i;
// Generate points on the unit circle to be used in computing the mesh
// points on a cylinder slice.
float* afSin = new float[iRSp1];
float* afCos = new float[iRSp1];
for (iR = 0; iR < iRadialSamples; iR++)
{
float fAngle = 2*D3DX_PI*fInvRS*iR;
afCos[iR] = cos(fAngle);
afSin[iR] = sin(fAngle);
}
afSin[iRadialSamples] = afSin[0];
afCos[iRadialSamples] = afCos[0];
// Generate the cylinder itself
for (iY = 1, i = 0; iY < iYSm1; iY++)
{
float fYFraction = -1.0f + fYFactor*iY; // in (-1,1)
float fY = fRadius*fYFraction;
// Compute center of slice
D3DXVECTOR3 kSliceCenter(0.0f,fY,0.0f);
// Compute radius of slice
float fSliceRadius = sqrt(fabs(fRadius*fRadius-fY*fY));
// Compute slice vertices with duplication at end point
D3DXVECTOR3 kNormal;
int iSave = i;
for (iR = 0; iR < iRadialSamples; iR++)
{
//float fRadialFraction = iR*fInvRS; // in [0,1)
D3DXVECTOR3 kRadial(afCos[iR],0.0f,afSin[iR]);
SphereVerts.x = kSliceCenter.x + fSliceRadius*kRadial.x;
SphereVerts.y = kSliceCenter.y + fSliceRadius*kRadial.y;
SphereVerts.z = kSliceCenter.z + fSliceRadius*kRadial.z;
kNormal.x = SphereVerts.x;
kNormal.y = SphereVerts.y;
kNormal.z = SphereVerts.z;
D3DXVec3Normalize(&kNormal,&kNormal);
SphereVerts.nx = kNormal.x;
SphereVerts.ny = kNormal.y;
SphereVerts.nz = kNormal.z;
SphereVerts.rgba = D3DXCOLOR(0.5,0.5,0.5,0.5);
i++;
}
SphereVerts = SphereVerts[iSave];
i++;
}
// South pole
SphereVerts.x = 0;
SphereVerts.y = -fRadius;
SphereVerts.z = 0;
SphereVerts.nx = 0;
SphereVerts.ny = -1;
SphereVerts.nz = 0;
SphereVerts.rgba = D3DXCOLOR(0.5,0.5,0.5,0.5);
i++;
// North pole
SphereVerts.x = 0;
SphereVerts.y = fRadius;
SphereVerts.z = 0;
SphereVerts.nx = 0;
SphereVerts.ny = 1;
SphereVerts.nz = 0;
SphereVerts.rgba = D3DXCOLOR(0.5,0.5,0.5,0.5);
i++;
assert( i == iVQuantity );
int a = sizeof(DWORD);
BYTE* lpVertices;
m_pDevice->CreateVertexBuffer(iVQuantity * sizeof(MESHVERTEX), D3DUSAGE_WRITEONLY,D3DFVF_MESHVERTEX,D3DPOOL_MANAGED,&m_pVB,0);
m_pVB->Lock( 0, iVQuantity*sizeof(MESHVERTEX), (void**)&lpVertices, 0 );
memcpy( lpVertices, &SphereVerts[0], iVQuantity*sizeof(MESHVERTEX) );
m_pVB->Unlock();
// generate connectivity
int iIQuantity = 3*iTQuantity;
m_aiIndex = new int[iIQuantity];
int* aiLocalIndex = m_aiIndex;
for (iY = 0, iYStart = 0; iY < iYSm3; iY++)
{
int i0 = iYStart;
int i1 = i0 + 1;
iYStart += iRSp1;
int i2 = iYStart;
int i3 = i2 + 1;
for (i = 0; i < iRadialSamples; i++, aiLocalIndex += 6)
{
aiLocalIndex[0] = i0++;
aiLocalIndex[1] = i1;
aiLocalIndex[2] = i2;
aiLocalIndex[3] = i1++;
aiLocalIndex[4] = i3++;
aiLocalIndex[5] = i2++;
}
}
// south pole triangles
int iVQm2 = iVQuantity-2;
for (i = 0; i < iRadialSamples; i++, aiLocalIndex += 3)
{
aiLocalIndex[0] = i;
aiLocalIndex[1] = iVQm2;
aiLocalIndex[2] = i+1;
}
// north pole triangles
int iVQm1 = iVQuantity-1, iOffset = iYSm3*iRSp1;
for (i = 0; i < iRadialSamples; i++, aiLocalIndex += 3)
{
aiLocalIndex[0] = i+iOffset;
aiLocalIndex[1] = i+1+iOffset;
aiLocalIndex[2] = iVQm1;
}
unsigned int uiBufferLength = (unsigned int)(iIQuantity*sizeof(short));
m_pDevice->CreateIndexBuffer(uiBufferLength,
D3DUSAGE_WRITEONLY,D3DFMT_INDEX16,D3DPOOL_MANAGED,&m_pIB,0);
void* pbIndices;
m_pIB->Lock(0,uiBufferLength,&pbIndices,0);
memcpy( pbIndices, m_aiIndex, iIQuantity*sizeof(short) );
m_pIB->Unlock();
delete[] afCos;
delete[] afSin;
delete[] SphereVerts;
delete[] m_aiIndex;
There are two places I suspect.
1. Do vertex buffer and index buffer properly copy the mesh data?
2. Unproper material setting or lose material
Additionally the sphere index are built up as counter clockwise while you are watching through the screen, which is why I use hr = pd3dDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_CW).