⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sphere.cpp

📁 C++台球游戏代码
💻 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 + -