📄 cue.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 + -