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

📄 cue.cpp

📁 C++台球游戏代码
💻 CPP
字号:
#include "Cue.h"
#define SPHERE_RADIUS 1.2f

CCue::CCue(LPDIRECT3DDEVICE8 pD3DDevice,float fHeight,float fRadius,int iSegments)
{
	m_pD3DDevice=pD3DDevice;
	m_pVertexBuffer=NULL;
	m_pSideTexture=NULL;
	m_pEndTexture=NULL;

	m_fHeight=fHeight;
    m_fRadius=fRadius;
	m_iSegments=iSegments;

	//Setup counts for cue
	m_dwNumOfVertices=((m_iSegments+1)*4)+2;
	m_dwNumOfSidePolygons=m_iSegments*2;
	m_dwNumOfEndPolygons=m_iSegments;

	//Set material default values
	D3DCOLORVALUE rgbaDiffuse  = {1.0, 1.0, 1.0, 0.0};
	D3DCOLORVALUE rgbaAmbient  = {1.0, 1.0, 1.0, 0.0};
	D3DCOLORVALUE rgbaSpecular = {0.0, 0.0, 0.0, 0.0};
	D3DCOLORVALUE rgbaEmissive = {0.0, 0.0, 0.0, 0.0};

	SetMaterial(rgbaDiffuse,rgbaAmbient,rgbaSpecular,rgbaEmissive,0);

	//Initialize vertex buffer
	if(CreateVertexBuffer())
	{
		if(UpdateVertices())
		{
			LogInfo("<li>Cue create OK");
			return;
		}
	}
	LogError("<li>Cue failed to create");
}

CCue::~CCue()
{
	SafeRelease(m_pSideTexture);
	SafeRelease(m_pEndTexture);
	SafeRelease(m_pVertexBuffer);

	LogInfo("<li>Cue destroyed OK");
}

DWORD CCue::Render()
{
	m_pD3DDevice->SetStreamSource(0, m_pVertexBuffer, sizeof(CUE_CUSTOMVERTEX));
	m_pD3DDevice->SetVertexShader(CUE_D3DFVF_CUSTOMVERTEX);

	if(m_pSideTexture!=NULL)
	{
		//A texture has been set. I want texture to be shaded based
		//on the current light levels, so used D3DTOP_MODULATE.
		m_pD3DDevice->SetTexture(0,m_pSideTexture);
		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);
	
	//Render polygons from vertex buffer - Sides
	m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,m_dwNumOfSidePolygons);
	m_pD3DDevice->SetTexture(0,0);
	

	if(m_pEndTexture!=NULL)
	{
		//A texture has been set. I want texture to be shaded based
		//on the current light levels, so used D3DTOP_MODULATE.
		m_pD3DDevice->SetTexture(0,m_pEndTexture);
		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);
	}

	//Render polygons from vertex buffer - Top
	m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLEFAN,((m_iSegments+1)*2),m_dwNumOfEndPolygons);
	
	//Render polygons from vertex buffer - Bottom
	m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLEFAN,((m_iSegments+1)*3)+1,m_dwNumOfEndPolygons);
	
	m_pD3DDevice->SetTexture(0,0);
	m_pD3DDevice->SetStreamSource(0,0,0);

	//Return the number of polygons rendered
	return m_dwNumOfSidePolygons+(2*m_dwNumOfEndPolygons);
}

bool CCue::CreateVertexBuffer()
{
    //Create the vertex buffer from device.
    if(FAILED(m_pD3DDevice->CreateVertexBuffer(m_dwNumOfVertices*sizeof(CUE_CUSTOMVERTEX),
                                               0,CUE_D3DFVF_CUSTOMVERTEX,
                                               D3DPOOL_DEFAULT,&m_pVertexBuffer)))
    {
        LogError("<li>CCue:Unable to create vertex buffer.");
		return FALSE;
    }
    return TRUE;
}

bool CCue::SetSideTexture(const char *szTextureFilePath)
{
	if(FAILED(D3DXCreateTextureFromFile(m_pD3DDevice,szTextureFilePath,&m_pSideTexture)))
	{
		return FALSE;
	}
	return TRUE;
}

bool CCue::SetEndTexture(const char *szTextureFilePath)
{
	if(FAILED(D3DXCreateTextureFromFile(m_pD3DDevice,szTextureFilePath,&m_pEndTexture)))
	{
		return FALSE;
	}
	return TRUE;
}

bool CCue::SetMaterial(D3DCOLORVALUE rgbaDiffuse,D3DCOLORVALUE rgbaAmbient,
					   D3DCOLORVALUE rgbaSpecular,D3DCOLORVALUE rgbaEmissive,float rPower)
{
	//Set the RGBA for diffuse light reflected from this material. 
	m_matMaterial.Diffuse=rgbaDiffuse; 

	//Set the RGBA for ambient light reflected from this material. 
	m_matMaterial.Ambient=rgbaAmbient; 

	//Set the color and sharpness of specular highlights for the material. 
	m_matMaterial.Specular=rgbaSpecular; 
	m_matMaterial.Power=rPower;

	//Set the RGBA for light emitted from this material. 
	m_matMaterial.Emissive=rgbaEmissive;

	return TRUE;
}

bool CCue::UpdateVertices()
{
	CUE_CUSTOMVERTEX *pVertex;
	WORD wVertexIndex=0;
	int iCurrentSegment;

	//Lock the vertex buffer
	if(FAILED(m_pVertexBuffer->Lock(0,0,(BYTE**)&pVertex,0)))
	{
		LogError("<li>CCue: Unable to lock vertex buffer.");
		return FALSE;
	}

	float fDeltaSegAngle=2.0f*D3DX_PI/m_iSegments;
	float fSegmentLength=1.0f/(float)m_iSegments;

	//Create the sides triangle strip
	for(iCurrentSegment=0;iCurrentSegment<=m_iSegments;iCurrentSegment++)
	{
		float z0=m_fRadius*sinf(iCurrentSegment*fDeltaSegAngle);
		float y0=m_fRadius*cosf(iCurrentSegment*fDeltaSegAngle)+0.7f;

		pVertex->z=0.5f*z0;
		pVertex->y=0.5f*y0;
		pVertex->x=0.0f+SPHERE_RADIUS;
		pVertex->nz=z0;
		pVertex->ny=y0;
		pVertex->nx=0.0f;
		pVertex->tu=0.0f;
		pVertex->tv=1.0f-fSegmentLength*(float)iCurrentSegment;

		pVertex++;

		pVertex->z=z0;
		pVertex->y=y0+2.0f;
		pVertex->x=m_fHeight+SPHERE_RADIUS;
		pVertex->nz=z0;
		pVertex->ny=y0;
		pVertex->nx=0.0f;
		pVertex->tu=1.0f;
		pVertex->tv=1.0f-fSegmentLength*(float)iCurrentSegment;
		pVertex++;
	}

	//Create the top triangle fan:Center
	pVertex->x=0.0f+SPHERE_RADIUS;
	pVertex->y=(0.0f+0.7f)*0.5f;
	pVertex->z=0.0f;
	pVertex->nx=-1.0f;
	pVertex->ny=0.0f;
	pVertex->nz=0.0f;
	pVertex->tu=0.5f;
	pVertex->tv=0.5f;
	pVertex++;

	//Create the top triangle fan: Edges
	for(iCurrentSegment=0;iCurrentSegment<=m_iSegments;iCurrentSegment++)
	{
		float z0=m_fRadius*sinf(iCurrentSegment*fDeltaSegAngle);
		float y0=m_fRadius*cosf(iCurrentSegment*fDeltaSegAngle)+0.7f;

		pVertex->z=0.5f*z0;
		pVertex->y=0.5f*y0;
		pVertex->x=0.0f+SPHERE_RADIUS;
		pVertex->nx=-1.0f;
		pVertex->ny=0.0f;
		pVertex->nz=0.0f;

		float tu0=(0.5f*sinf(iCurrentSegment*fDeltaSegAngle))+0.5f;
		float tv0=(0.5f*cosf(iCurrentSegment*fDeltaSegAngle))+0.5f;

		pVertex->tu=tu0;
		pVertex->tv=tv0;
		pVertex++;
	}

	//Create the bottom triangle fan:Center
	pVertex->x=m_fHeight+SPHERE_RADIUS;
	pVertex->y=0.0f+0.7f+2.0f;
	pVertex->z=0.0f;
	pVertex->nx=1.0f;
	pVertex->ny=0.0f;
	pVertex->nz=0.0f;
	pVertex->tu=0.5f;
	pVertex->tv=0.5f;

	pVertex++;

	//Create the bottom triangle fan:Edges
	for(iCurrentSegment=0;iCurrentSegment<=m_iSegments;iCurrentSegment++)
	{
		float z0=m_fRadius*sinf(iCurrentSegment*fDeltaSegAngle);
		float y0=m_fRadius*cosf(iCurrentSegment*fDeltaSegAngle)+0.7f;

		pVertex->x=m_fHeight+SPHERE_RADIUS;
		pVertex->y=y0+2.0f;
		pVertex->z=z0;
		pVertex->nx=1.0f;
		pVertex->ny=0.0f;
		pVertex->nz=0.0f;

		float tu0=(0.5f*sinf(iCurrentSegment*fDeltaSegAngle))+0.5f;
		float tv0=(0.5f*cosf(iCurrentSegment*fDeltaSegAngle))+0.5f;

		pVertex->tu=tu0;
		pVertex->tv=tv0;

		pVertex++;
	}

	if(FAILED(m_pVertexBuffer->Unlock()))
	{
		LogError("<li>CCue:Unable to unlock vertex buffer.");
		return FALSE;
	}

	return TRUE;
}

void CCue::TransformCue(D3DXVECTOR3 vecCuePosition,D3DXVECTOR3 vecCueDirection,int iMouseY)
{
	float theta=0.0f,fIncreaseX=0.0f,fIncreaseZ=0.0f,fIncreaseY=0.0f;

	if(vecCueDirection.x != 0.0f && vecCueDirection.z != 0.0f)
	{
		theta=atanf(fabsf(vecCueDirection.z)/fabsf(vecCueDirection.x));
		
		if(vecCueDirection.x < 0.0f && vecCueDirection.z > 0.0f)
		{
			fIncreaseX=-cosf(theta)*iMouseY;
			fIncreaseZ=sinf(theta)*iMouseY;
			theta=-(D3DX_PI-theta);
		}
		else if(vecCueDirection.x < 0.0f && vecCueDirection.z < 0.0f)
		{
			fIncreaseX=-cosf(theta)*iMouseY;
			fIncreaseZ=-sinf(theta)*iMouseY;
			theta=-(D3DX_PI+theta);
		}
		else if(vecCueDirection.x > 0.0f && vecCueDirection.z < 0.0f)
		{
			fIncreaseX=cosf(theta)*iMouseY;
			fIncreaseZ=-sinf(theta)*iMouseY;
			theta=-(2.0f*D3DX_PI-theta);
		}
		else if(vecCueDirection.x > 0.0f && vecCueDirection.z > 0.0f)
		{
			fIncreaseX=cosf(theta)*iMouseY;
			fIncreaseZ=sinf(theta)*iMouseY;
			theta=-theta;
		}
	}		
	else if(vecCueDirection.x > 0.0f && vecCueDirection.z == 0.0f)
	{
		fIncreaseX=(float)iMouseY;
		theta=0.0f;
	}
	else if(vecCueDirection.x == 0.0f && vecCueDirection.z > 0.0f)
	{   
		fIncreaseZ=(float)iMouseY;
		theta=D3DX_PI/2.0f;
	}
	else if(vecCueDirection.x < 0.0f && vecCueDirection.z == 0.0f)
	{
		fIncreaseX=(float)-iMouseY;
		theta=D3DX_PI;
	}
	else if(vecCueDirection.x == 0.0f && vecCueDirection.z < 0.0f)
	{  
		fIncreaseZ=(float)-iMouseY;
		theta=1.5f*D3DX_PI;
	}
    
	//*****************************************************************
	//Note:2.0f/25.0f=0.08f. 
	// "2" is fall between Cue top and Cue bottom
	// "25" describe the Cue Height.
	fIncreaseY=sqrtf(fIncreaseX*fIncreaseX+fIncreaseZ*fIncreaseZ)*0.08f;
	//******************************************************************


	D3DXMATRIX matWorld,matRationAxisY,matTranslation;

	D3DXMatrixRotationY(&matRationAxisY,theta);
	D3DXMatrixTranslation(&matTranslation,vecCuePosition.x+fIncreaseX,
		                                  fIncreaseY,
										  vecCuePosition.z+fIncreaseZ);
	D3DXMatrixMultiply(&matWorld,&matRationAxisY,&matTranslation);
	m_pD3DDevice->SetTransform(D3DTS_WORLD,&matWorld);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -