📄 scenestate.cpp
字号:
//======================================================================================//
// filename: SceneState.cpp //
// //
// author: Pedro V. Sander //
// ATI Research, Inc. //
// 3D Application Research Group //
// email: psander@ati.com //
// //
// Description: D3D State settings //
// //
//======================================================================================//
// (C) 2003 ATI Research, Inc. All rights reserved. //
//======================================================================================//
#define STRICT
#include <Windows.h>
#include <stdio.h>
#include <D3DX9.h>
#include "DXUtil.h"
#include "D3DEnumeration.h"
#include "D3DSettings.h"
#include "D3DUtil.h"
#include "Effects/FixedFuncShader.fxh"
#include "SceneState.h"
VOID D3DUtil_InitMaterial(D3DMATERIAL9& mtrl, FLOAT r, FLOAT g, FLOAT b, FLOAT a);
//-----------------------------------------------------------------------------
// Name: Set()
// Desc: Sets the D3D render state based on the currently selected options
//-----------------------------------------------------------------------------
void CSceneState::Set(LPDIRECT3DDEVICE9 pd3dDevice, LPD3DXEFFECT pEffect)
{
int i;
if(!m_bInited)
{
InitFromEffects(pEffect);
}
WriteToEffects(pEffect);
//fog settings
switch(m_vfog.iType)
{
case FOG_TYPE_LINEAR:
pd3dDevice->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
pd3dDevice->SetRenderState(D3DRS_FOGSTART, *(DWORD *)(&m_vfog.fStart));
pd3dDevice->SetRenderState(D3DRS_FOGEND, *(DWORD *)(&m_vfog.fEnd));
break;
case FOG_TYPE_EXP:
pd3dDevice->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_EXP);
pd3dDevice->SetRenderState(D3DRS_FOGDENSITY, *(DWORD *)(&m_vfog.fDensity));
break;
case FOG_TYPE_EXP2:
pd3dDevice->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_EXP2);
pd3dDevice->SetRenderState(D3DRS_FOGDENSITY, *(DWORD *)(&m_vfog.fDensity));
break;
}
pd3dDevice->SetRenderState(D3DRS_RANGEFOGENABLE, m_vfog.bRange == TRUE);
//light settings
for(i = 0; i < NUM_LIGHTS; i++)
{
switch(m_iLightType[i])
{
case LIGHT_TYPE_DIRECTIONAL:
m_light[i].Type = D3DLIGHT_DIRECTIONAL;
break;
case LIGHT_TYPE_POINT:
m_light[i].Type = D3DLIGHT_POINT;
break;
case LIGHT_TYPE_SPOT:
m_light[i].Type = D3DLIGHT_SPOT;
break;
}
if(m_iLightType[i] != LIGHT_TYPE_NONE)
{
D3DXVec3Normalize((D3DXVECTOR3*)&m_light[i].Direction, (D3DXVECTOR3*)&m_light[i].Direction);
pd3dDevice->SetLight(i, &m_light[i]);
pd3dDevice->LightEnable(i, TRUE);
}
else
{
pd3dDevice->LightEnable(i, FALSE);
}
}
if(m_tex.iTexGenType == TEXGEN_TYPE_NONE)
{
pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU);
}
else if(m_tex.iTexGenType == TEXGEN_TYPE_CAMERASPACENORMAL)
{
pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACENORMAL);
}
else if(m_tex.iTexGenType == TEXGEN_TYPE_CAMERASPACEPOSITION)
{
pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
}
else if(m_tex.iTexGenType == TEXGEN_TYPE_CAMERASPACEREFLECTIONVECTOR)
{
pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
}
// Setup a material
D3DMATERIAL9 mtrl;
D3DUtil_InitMaterial(mtrl, m_vMaterialColor.r, m_vMaterialColor.g, m_vMaterialColor.b, m_vMaterialColor.a);
mtrl.Power = m_fMaterialPower;
pd3dDevice->SetMaterial(&mtrl);
}
//-----------------------------------------------------------------------------
// Name: InitFromFile()
// Desc: Reads settings from file
//-----------------------------------------------------------------------------
void CSceneState::InitFromFile(FILE *fp,
bool bFull,
D3DXMATRIXA16 *matWorld,
D3DXMATRIXA16 *matView,
D3DXMATRIXA16 *matProj,
D3DXMATRIXA16 *matViewTrans,
D3DXMATRIXA16 *matViewRot,
CD3DArcBall *ArcBall,
float *fTimeRot,
char *strMeshFilename)
{
m_bInited = true;
int iNumLights;
fread(&iNumLights, sizeof(int), 1, fp);
if(iNumLights == NUM_LIGHTS)
{
fread(m_iLightType, sizeof(int)*NUM_LIGHTS, 1, fp);
fread(m_light, sizeof(D3DLIGHT9)*NUM_LIGHTS, 1, fp);
}
else if(iNumLights > NUM_LIGHTS)
{
fread(m_iLightType, sizeof(int)*NUM_LIGHTS, 1, fp);
fseek(fp, sizeof(int)*(iNumLights - NUM_LIGHTS), SEEK_CUR);
fread(m_light, sizeof(D3DLIGHT9)*NUM_LIGHTS, 1, fp);
fseek(fp, sizeof(D3DLIGHT9)*(iNumLights - NUM_LIGHTS), SEEK_CUR);
}
else
{
fread(m_iLightType, sizeof(int)*iNumLights, 1, fp);
fread(m_light, sizeof(D3DLIGHT9)*iNumLights, 1, fp);
for(int i = iNumLights; i < NUM_LIGHTS; i++)
{
m_iLightType[i] = LIGHT_TYPE_NONE;
m_light[i] = m_light[0];
}
}
fread(&m_vfog, sizeof(CVertexFog), 1, fp);
fread(&m_tex, sizeof(CTexture), 1, fp);
int tmp;
fread(&tmp, sizeof(int), 1, fp);
m_bSpecular = (tmp == 1 ? true : false);
fread(&tmp, sizeof(int), 1, fp);
m_bTweening = (tmp == 1 ? true : false);
fread(&m_vAmbientColor, sizeof(D3DCOLORVALUE), 1, fp);
fread(&m_vMaterialColor, sizeof(D3DCOLORVALUE), 1, fp);
fread(&m_fMaterialPower, sizeof(float), 1, fp);
if(bFull)
{
fread(matWorld, sizeof(D3DXMATRIXA16), 1, fp);
fread(matView, sizeof(D3DXMATRIXA16), 1, fp);
fread(matProj, sizeof(D3DXMATRIXA16), 1, fp);
fread(matViewTrans, sizeof(D3DXMATRIXA16), 1, fp);
fread(matViewRot, sizeof(D3DXMATRIXA16), 1, fp);
fread(ArcBall, sizeof(CD3DArcBall), 1, fp);
fread(fTimeRot, sizeof(float), 1, fp);
fread(strMeshFilename, sizeof(char), 512, fp);
}
else
{
fseek(fp,
sizeof(D3DXMATRIXA16)*5
+ sizeof(CD3DArcBall)
+ sizeof(float)
+ sizeof(char)*512,
SEEK_CUR);
}
}
//-----------------------------------------------------------------------------
// Name: SaveToFile()
// Desc: Writes settings to file
//-----------------------------------------------------------------------------
void CSceneState::SaveToFile(FILE *fp,
D3DXMATRIXA16 *matWorld,
D3DXMATRIXA16 *matView,
D3DXMATRIXA16 *matProj,
D3DXMATRIXA16 *matViewTrans,
D3DXMATRIXA16 *matViewRot,
CD3DArcBall *ArcBall,
float *fTimeRot,
char *strMeshFilename)
{
int iNumLights = NUM_LIGHTS;
fwrite(&iNumLights, sizeof(int), 1, fp);
fwrite(m_iLightType, sizeof(int)*NUM_LIGHTS, 1, fp);
fwrite(m_light, sizeof(D3DLIGHT9)*NUM_LIGHTS, 1, fp);
fwrite(&m_vfog, sizeof(CVertexFog), 1, fp);
fwrite(&m_tex, sizeof(CTexture), 1, fp);
int tmp;
tmp = m_bSpecular;
fwrite(&tmp, sizeof(int), 1, fp);
tmp = m_bTweening;
fwrite(&tmp, sizeof(int), 1, fp);
fwrite(&m_vAmbientColor, sizeof(D3DCOLORVALUE), 1, fp);
fwrite(&m_vMaterialColor, sizeof(D3DCOLORVALUE), 1, fp);
fwrite(&m_fMaterialPower, sizeof(float), 1, fp);
fwrite(matWorld, sizeof(D3DXMATRIXA16), 1, fp);
fwrite(matView, sizeof(D3DXMATRIXA16), 1, fp);
fwrite(matProj, sizeof(D3DXMATRIXA16), 1, fp);
fwrite(matViewTrans, sizeof(D3DXMATRIXA16), 1, fp);
fwrite(matViewRot, sizeof(D3DXMATRIXA16), 1, fp);
fwrite(ArcBall, sizeof(CD3DArcBall), 1, fp);
fwrite(fTimeRot, sizeof(float), 1, fp);
fwrite(strMeshFilename, sizeof(char), 512, fp);
}
//-----------------------------------------------------------------------------
// Name: WriteToEffects()
// Desc: Updates the effects settings
//-----------------------------------------------------------------------------
void CSceneState::WriteToEffects(LPD3DXEFFECT pEffect)
{
int i;
char tmp[64];
// Misc
pEffect->SetValue("vAmbientColor", (void*)&m_vAmbientColor, sizeof(D3DCOLORVALUE));
pEffect->SetValue("vMaterialColor", (void*)&m_vMaterialColor, sizeof(D3DCOLORVALUE));
pEffect->SetValue("fMaterialPower", (void*)&m_fMaterialPower, sizeof(FLOAT));
pEffect->SetBool("bSpecular", m_bSpecular);
pEffect->SetBool("bTweening", m_bTweening);
// Fog
pEffect->SetValue("iFogType", (void*)&m_vfog.iType, sizeof(int));
pEffect->SetValue("vFogColor", (void*)&m_vfog.vColor, sizeof(D3DCOLORVALUE));
pEffect->SetValue("fFogStart", (void*)&m_vfog.fStart, sizeof(float));
pEffect->SetValue("fFogEnd", (void*)&m_vfog.fEnd, sizeof(float));
pEffect->SetValue("fFogDensity", (void*)&m_vfog.fDensity, sizeof(float));
pEffect->SetBool("bFogRange", m_vfog.bRange);
int iDirIni=NUM_LIGHTS, iPointIni=NUM_LIGHTS, iSpotIni=NUM_LIGHTS;
int iDirNum=0, iPointNum=0, iSpotNum=0;
// Set up lighting states
for(i = 0; i < NUM_LIGHTS; i++)
{
sprintf(tmp, "lights[%i].iType", i);
pEffect->SetValue(tmp, (void*)&m_iLightType[i], sizeof(int));
switch(m_iLightType[i])
{
case LIGHT_TYPE_DIRECTIONAL:
if(iDirIni > i)
iDirIni = i;
iDirNum++;
break;
case LIGHT_TYPE_POINT:
if(iPointIni > i)
iPointIni = i;
iPointNum++;
break;
case LIGHT_TYPE_SPOT:
if(iSpotIni > i)
iSpotIni = i;
iSpotNum++;
break;
}
sprintf(tmp, "lights[%i].vPos", i);
pEffect->SetValue(tmp, (void*)&m_light[i].Position, sizeof(D3DVECTOR));
sprintf(tmp, "lights[%i].vDir", i);
pEffect->SetValue(tmp, (void*)&m_light[i].Direction, sizeof(D3DVECTOR));
sprintf(tmp, "lights[%i].vAmbient", i);
pEffect->SetValue(tmp, (void*)&m_light[i].Ambient, sizeof(D3DCOLORVALUE));
sprintf(tmp, "lights[%i].vDiffuse", i);
pEffect->SetValue(tmp, (void*)&m_light[i].Diffuse, sizeof(D3DCOLORVALUE));
sprintf(tmp, "lights[%i].vSpecular", i);
pEffect->SetValue(tmp, (void*)&m_light[i].Specular, sizeof(D3DCOLORVALUE));
float vAttenuation[4];
vAttenuation[0] = m_light[i].Attenuation0;
vAttenuation[1] = m_light[i].Attenuation1;
vAttenuation[2] = m_light[i].Attenuation2;
vAttenuation[3] = m_light[i].Range;
sprintf(tmp, "lights[%i].vAttenuation", i);
pEffect->SetValue(tmp, (void*)&vAttenuation, sizeof(float)*4);
float vSpot[3];
vSpot[0] = (float)cos(m_light[i].Theta/2.f);
vSpot[1] = (float)cos(m_light[i].Phi/2.f);
vSpot[2] = m_light[i].Falloff;
sprintf(tmp, "lights[%i].vSpot", i);
pEffect->SetValue(tmp, (void*)&vSpot, sizeof(float)*3);
}
pEffect->SetValue("iLightDirIni", (void*)&iDirIni, sizeof(int));
pEffect->SetValue("iLightDirNum", (void*)&iDirNum, sizeof(int));
pEffect->SetValue("iLightPointIni", (void*)&iPointIni, sizeof(int));
pEffect->SetValue("iLightPointNum", (void*)&iPointNum, sizeof(int));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -