📄 sphere.cpp
字号:
#include "Sphere.h"
#define SPHERE_RADIUS 1.1f
CSphere::CSphere(LPDIRECT3DDEVICE8 pD3DDevice,int iRings,int iSegments)
{
m_pD3DDevice=pD3DDevice;
m_pVertexBuffer=NULL;
m_pIndexBuffer=NULL;
m_pTexture=NULL;
m_pSphereState=new(SPHERE_STATE);
m_pSphereState->sVector.x=0.0f;
m_pSphereState->sVector.y=0.0f;
m_pSphereState->sVector.z=0.0f;
m_pSphereState->vVector.x=1.0f;
m_pSphereState->vVector.y=0.001f;
m_pSphereState->vVector.z=0.001f;
m_pSphereState->v=0.0f;
m_vecSphereRotationAxis=m_pSphereState->vVector;
m_fTotalDis=0.0f;
m_bSphereInUse=TRUE;
//Warning: m_vecSavePosition and sVector must have same first value.
m_vecSavePosition=m_pSphereState->sVector;
m_vecSavePosition2=m_pSphereState->sVector;
m_iRings=iRings;
m_iSegments=iSegments;
//Setup counts for object
m_dwNumOfVertices=(m_iRings+1)*(m_iSegments+1);
m_dwNumOfIndices=2*m_iRings*(m_iSegments+1);
m_dwNumOfPolygons=m_dwNumOfIndices-2;
//Set material default values ( R G B A)
D3DCOLORVALUE rgbaDiffuse = {1.0, 1.0, 1.0, 0.0};
D3DCOLORVALUE rgbaAmbient = {1.0, 1.0, 1.0, 0.0};
D3DCOLORVALUE rgbaSpecular = {1.0, 1.0, 1.0, 0.0};
D3DCOLORVALUE rgbaEmissive = {0.0, 0.0, 0.0, 0.0};
SetMaterial(rgbaDiffuse,rgbaAmbient,rgbaSpecular,rgbaEmissive,30.0f);
//Initilize Vertex Buffer
if(CreateVertexBuffer())
{
if(CreateIndexBuffer())
{
if(UpdateVertices())
{
LogInfo("<li>Sphere create OK");
return;
}
}
}
LogError("<li>Sphere failed to create");
}
CSphere::~CSphere()
{
SafeRelease(m_pTexture);
SafeRelease(m_pIndexBuffer);
SafeRelease(m_pVertexBuffer);
SafeDelete(m_pSphereState);
LogInfo("<li>Sphere destroyed OK");
}
BOOL CSphere::CreateVertexBuffer()
{
if(FAILED(m_pD3DDevice->CreateVertexBuffer(m_dwNumOfVertices * sizeof(SPHERE_CUSTOMVERTEX),
0,SPHERE_D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT,&m_pVertexBuffer)))
{
LogError("<li>CSphere: Unable to create vertex buffer.");
return FALSE;
}
return TRUE;
}
BOOL CSphere::CreateIndexBuffer()
{
if(FAILED(m_pD3DDevice->CreateIndexBuffer(m_dwNumOfIndices * sizeof(WORD),
0,D3DFMT_INDEX16,D3DPOOL_MANAGED,
&m_pIndexBuffer)))
{
LogError("<li>CSphere: Unable to create index buffer.");
return FALSE;
}
return TRUE;
}
BOOL CSphere::UpdateVertices()
{
WORD *pIndices;
SPHERE_CUSTOMVERTEX *pVertex;
WORD wVertexIndex=0;
int iCurrentRing;
int iCurrentSegment;
D3DXVECTOR3 vNormal;
//Lock the vertex buffer
if(FAILED(m_pVertexBuffer->Lock(0,0,(BYTE**)&pVertex,0)))
{
LogError("<li>CSphere: Unable to lock vertex buffer.");
return FALSE;
}
//Lock the index buffer
if(FAILED(m_pIndexBuffer->Lock(0,m_dwNumOfIndices,(BYTE**)&pIndices,0)))
{
LogError("<li>CSphere: Unable to lock index buffer.");
return FALSE;
}
//Establish constants used in sphere generation
float rDeltaRingAngle=(D3DX_PI/m_iRings);
float rDeltaSegAngle=(2.0f*D3DX_PI/m_iSegments);
//Generate the group of rings for the sphere
for(iCurrentRing=0;iCurrentRing<m_iRings+1;iCurrentRing++)
{
float r0=SPHERE_RADIUS*sinf(iCurrentRing*rDeltaRingAngle);
float y0=SPHERE_RADIUS*cosf(iCurrentRing*rDeltaRingAngle);
//Generate the group of segments for the current ring
for(iCurrentSegment=0;iCurrentSegment<m_iSegments+1;iCurrentSegment++)
{
float x0=r0*sinf(iCurrentSegment*rDeltaSegAngle);
float z0=r0*cosf(iCurrentSegment*rDeltaSegAngle);
vNormal.x=x0;
vNormal.y=y0;
vNormal.z=z0;
D3DXVec3Normalize(&vNormal,&vNormal);
pVertex->x=x0;
pVertex->y=y0;
pVertex->z=z0;
pVertex->nx=vNormal.x;
pVertex->ny=vNormal.y;
pVertex->nz=vNormal.z;
pVertex->tu=2.0f*(float)iCurrentSegment/(float)m_iSegments;
pVertex->tv=(float)iCurrentRing/(float)m_iRings;
pVertex++;
//Add two indices except for the last ring
if(iCurrentRing!=m_iRings)
{
*pIndices=wVertexIndex;
pIndices++;
*pIndices=wVertexIndex+(WORD)(m_iSegments+1);
pIndices++;
wVertexIndex++;
}
}
}
if(FAILED(m_pIndexBuffer->Unlock()))
{
LogError("<li>CSphere: Unable to unlock index buffer.");
return FALSE;
}
if(FAILED(m_pVertexBuffer->Unlock()))
{
LogError("<li>CSphere: Unable to unlock vertex buffer.");
return FALSE;
}
return TRUE;
}
BOOL CSphere::SetTexture(const char *szTextureFilePath)
{
if(FAILED(D3DXCreateTextureFromFile(m_pD3DDevice,szTextureFilePath,&m_pTexture)))
return FALSE;
return TRUE;
}
BOOL CSphere::SetMaterial(D3DCOLORVALUE rgbaDiffuse,D3DCOLORVALUE rgbaAmbient,
D3DCOLORVALUE rgbaSpecular,D3DCOLORVALUE rgbaEmissive,float rPower)
{
//diffuse light reflected from this material.
m_matMaterial.Diffuse=rgbaDiffuse;
//ambient light reflected from this material.
m_matMaterial.Ambient=rgbaAmbient;
//Set the color and sharpness of specular hightlights for the material.
m_matMaterial.Specular=rgbaSpecular;
m_matMaterial.Power=rPower;
//light emitted from this material.
m_matMaterial.Emissive=rgbaEmissive;
return TRUE;
}
DWORD CSphere::Render()
{
m_pD3DDevice->SetStreamSource(0,m_pVertexBuffer,sizeof(SPHERE_CUSTOMVERTEX));
m_pD3DDevice->SetVertexShader(SPHERE_D3DFVF_CUSTOMVERTEX);
if(m_pTexture!=NULL)
{
//A texture has been set. We want our texture to be shaded based
//on the current light levels, so used D3DTOP_MODULATE.
m_pD3DDevice->SetTexture(0,m_pTexture);
m_pD3DDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE);
m_pD3DDevice->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE);
m_pD3DDevice->SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_CURRENT);
}
else
{
//No texture has been set
m_pD3DDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_SELECTARG2);
m_pD3DDevice->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE);
m_pD3DDevice->SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_CURRENT);
}
//Select the material to use
m_pD3DDevice->SetMaterial(&m_matMaterial);
//Select index buffer
m_pD3DDevice->SetIndices(m_pIndexBuffer,0);
//Render polygons from index buffer
m_pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP,0,m_dwNumOfVertices,0,m_dwNumOfPolygons);
m_pD3DDevice->SetTexture(0,0);
m_pD3DDevice->SetStreamSource(0,0,0);
m_pD3DDevice->SetIndices(0,0);
//Return the number of polygons rendered
return m_dwNumOfPolygons;
}
void CSphere::MoveSphere()
{
//Update sphere position.
UpdateSpherePosition();
//Translation sphere.
TransformSphere();
//Friction will reduse sphere velocity.
FrictionReduseVelocity();
}
void CSphere::TransformSphere()
{
D3DXMATRIX matWorld,matMove,matRotationAboutAxis;
m_vecSphereRotationAxis.x=m_pSphereState->vVector.z;
m_vecSphereRotationAxis.z=-m_pSphereState->vVector.x;
m_fTotalDis+=m_pSphereState->v/SPHERE_RADIUS;
D3DXMatrixRotationAxis(&matRotationAboutAxis,&m_vecSphereRotationAxis,m_fTotalDis);
D3DXMatrixTranslation(&matMove,m_pSphereState->sVector.x,
m_pSphereState->sVector.y,
m_pSphereState->sVector.z);
D3DXMatrixMultiply(&matWorld,&matRotationAboutAxis,&matMove);
m_pD3DDevice->SetTransform(D3DTS_WORLD,&matWorld);
}
void CSphere::UpdateSpherePosition()
{
D3DXVec3Normalize(&m_pSphereState->vVector,&m_pSphereState->vVector);
m_pSphereState->sVector+=m_pSphereState->v*m_pSphereState->vVector;
}
void CSphere::FrictionReduseVelocity()
{
if(m_pSphereState->v>0.00001f)
{
float v=m_pSphereState->v;
float a=0.0f;
if(0.8f<v && v<=CUEMAXSPEED)
a=0.02f;
else if(0.6f<v && v<=0.8f)
a=0.01f;
else if(0.5f<v && v<=0.6f)
a=0.005f;
else if(0.4f<v && v<=0.5f)
a=0.001f;
else if(0.3f<v && v<=0.4f)
a=0.0008f;
else if(0.1f<v && v<=0.3f)
a=0.0007f;
else
a=0.0006f;
m_pSphereState->v=m_pSphereState->v-a;
}
else if(m_pSphereState->v != 0.0f)
m_pSphereState->v=0.0f;
}
void CSphere::SetSphereVelocityAt_Y_NegativeAxis()
{
m_pSphereState->vVector.y=-2.0f;
m_pSphereState->v=1.0f;
}
void CSphere::TransformSphereForUser()
{
D3DXMATRIX matWorld;
D3DXMatrixTranslation(&matWorld,m_pSphereState->sVector.x,
0.0f,
m_pSphereState->sVector.z);
m_pD3DDevice->SetTransform(D3DTS_WORLD,&matWorld);
}
void CSphere::MoveSphereForUser(float x,float z)
{
m_pSphereState->sVector.x=x;
m_pSphereState->sVector.y=0.0f;
m_pSphereState->sVector.z=z;
TransformSphereForUser();
}
void CSphere::MirrorVAoubtAxis(D3DXVECTOR3 &n)
{
D3DXVECTOR3 N=n;
N.y=0.0f;
D3DXVec3Normalize(&N,&N);
m_pSphereState->vVector=2*(D3DXVec3Dot(&-m_pSphereState->vVector,&N))*
N+m_pSphereState->vVector;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -