📄 demo.cpp
字号:
#include "stdafx.h"
#include "Demo.h"
#include <dingus/math/Plane.h>
#include "Terrain.h"
#include "SkyMesh.h"
#include "CloudMesh.h"
#include "../anim/CameraAnim.h"
#include "Projector.h"
#include "Resources.h"
#include "ColorOps.h"
#include <dingus/console/Console.h>
#include "../resource.h"
#include <dingus/dxutils/D3DFont.h>
CDemo::CDemo()
: mTerrain(0), mSky(0)
{
mBenchMode = false;
//mStartFullscreen = true;
mUseMRT = false;
mWindowTitle = "Shaderey - Beyond3D/ATI DX9 competition entry by Aras 'NeARAZ' Pranckevicius";
}
CDemo::~CDemo()
{
}
bool CDemo::appCheckDevice( const D3DCAPS9& caps, DWORD behavior, D3DFORMAT format ) const
{
// if doesn't support VS1.1, fail with HW VP
if( (caps.VertexShaderVersion < D3DVS_VERSION(1,1)) && (behavior & D3DCREATE_HARDWARE_VERTEXPROCESSING) )
return false;
// fail if no PS2.0
if( caps.PixelShaderVersion < D3DPS_VERSION(2,0) )
return false;
// fail if REF
if( caps.DeviceType != D3DDEVTYPE_HAL )
return false;
return true;
}
void CDemo::customSettingsInit( HWND dlg )
{
CheckDlgButton( dlg, IDC_CHK_BENCHMARK, BST_UNCHECKED );
CheckDlgButton( dlg, IDC_CHK_MRT, BST_UNCHECKED );
}
void CDemo::customSettingsOK( HWND dlg )
{
mBenchMode = IsDlgButtonChecked(dlg,IDC_CHK_BENCHMARK) ? true : false;
mUseMRT = IsDlgButtonChecked(dlg,IDC_CHK_MRT) ? true : false;
if( mBenchMode )
mVSyncFullscreen = false;
}
CConsoleChannel& CON_INFO = CConsole::getChannel("info");
void CDemo::appInitialize()
{
mWireframe = false;
mCamYawPitchRoll.set( D3DX_PI/2, 0.15f, 0.0f );
mCamPosition.set(-50.0f,35.0f,-120.0f);
//mCamPosition.set(-54.0865f,31.3442f,-100.094f);
//mCamYawPitchRoll.set(2.24454f,-0.562182f,0.0f);
//mCamPosition.set(74.4553f,27.936f,-8.52147f);
//mCamYawPitchRoll.set(0.6699f,-0.409292f,0.0f);
D3DXMatrixRotationYawPitchRoll( &mMatCamera, mCamYawPitchRoll.x, mCamYawPitchRoll.y, mCamYawPitchRoll.z );
mMatCamera.getOrigin() = mCamPosition;
mCameraAnim = new CCameraAnim( mMatCamera );
mCameraAnim->load( "data/camera.txt" );
mSun.setParams( D3DX_PI*0.15f, 0.0f, 100.0f );
// global params
CON_INFO.write( "creating global params..." );
CRenderCamera& camera = G_RENDERCTX->getCamera();
CEffectParams& globalep = G_RENDERCTX->getGlobalParams();
globalep.addMatrix4x4Ref( "mShadowProj0", mMatProjShadow[0] );
globalep.addMatrix4x4Ref( "mShadowProj1", mMatProjShadow[1] );
globalep.addMatrix4x4Ref( "mShadowProj2", mMatProjShadow[2] );
globalep.addMatrix4x4Ref( "mShadowProj3", mMatProjShadow[3] );
globalep.addMatrix4x4Ref( "mTexProj", mMatTexProj );
globalep.addVector3Ref( "vLightDir", mLightDirNeg );
globalep.addVector4Ref( "vQuadOffset", mQuadOffset );
globalep.addVector3Ref( "vScatterBetaR", mAtmosphere.getMulBetaRay() );
globalep.addVector3Ref( "vScatterBetaM", mAtmosphere.getMulBetaMie() );
globalep.addVector3Ref( "vScatterBetaSum", mAtmosphere.getMulBetaRayMieSum() );
globalep.addVector3Ref( "vScatterBetaR_", mAtmosphere.getMulBetaRay_() );
globalep.addVector3Ref( "vScatterBetaM_", mAtmosphere.getMulBetaMie_() );
globalep.addVector4Ref( "vScatterHGg", mAtmosphere.getHGg() );
globalep.addVector3Ref( "vScatterSunColor", mSun.getColorMulIntensity() );
globalep.addVector3Ref( "vScatterSunColorDivBetaSum", mSunColorDivBetaSum );
globalep.addFloatRef( "fScatterExtMult", &mAtmosphere.getExtinctionMult() );
globalep.addFloatRef( "fScatterInscatMult", &mAtmosphere.getInscatteringMult() );
globalep.addFloatRef( "fTime", &mFloatTime );
// shadow maps
initShadowMaps();
// water maps
initWaterMaps();
// other RTs
initOtherSurfaces();
// quantize maps
initQuantizeMaps();
// terrain
CON_INFO.write( "creating terrain..." );
mTerrain = new CTerrain( RID_HEIGHTMAP, 60.0f );
mTerrain->getParams(BASE).setEffect( *RGET_FX("terrain") );
mTerrain->getParams(BASE).addTexture( "tBase0", *RGET_TEX("grassA") );
mTerrain->getParams(BASE).addTexture( "tBase1", *RGET_TEX("grassB") );
mTerrain->getParams(BASE).addTexture( "tBase2", *RGET_TEX("dirtA") );
mTerrain->getParams(BASE).addTexture( "tShadowMap", *RGET_S_TEX(RID_SHADOWMAP) );
mTerrain->getParams(BASE).addTexture( "tNoise0", *RGET_TEX("noise0") );
mTerrain->getParams(COLOR).setEffect( *RGET_FX("terrainColorOnly") );
mTerrain->getParams(COLOR).addTexture( "tBase0", *RGET_TEX("grassA") );
mTerrain->getParams(COLOR).addTexture( "tBase1", *RGET_TEX("grassB") );
mTerrain->getParams(COLOR).addTexture( "tBase2", *RGET_TEX("dirtA") );
mTerrain->getParams(COLOR).addTexture( "tShadowMap", *RGET_S_TEX(RID_SHADOWMAP) );
mTerrain->getParams(COLOR).addTexture( "tNoise0", *RGET_TEX("noise0") );
mTerrain->getParams(NORMALZ).setEffect( *RGET_FX("terrainNormalZOnly") );
mTerrain->getParams(NORMALZ).addTexture( "tShadowMap", *RGET_S_TEX(RID_SHADOWMAP) );
// sky
CON_INFO.write( "creating sky..." );
mSky = new CSkyMesh();
// processing screen quads
CON_INFO.write( "creating postprocessing fxs..." );
mQuadEdges = new CQuadMesh( "imgEdgeDetect" );
mQuadEdges->getParams().addTexture( "tBase", *RGET_S_TEX(RID_NORMALZ) );
mQuadEdges->getParams().addTexture( "tHatch", *RGET_TEX("hatch") );
mQuadBleed = new CQuadMesh( "imgBleed" );
mQuadBleed->getParams().addTexture( "tBase", *RGET_S_TEX(RID_FIXEDRT512) );
mQuadBleed->getParams().addTexture( "tBleedB", *RGET_TEX("bleedB") );
mQuadBleed->getParams().addTexture( "tBleedC", *RGET_TEX("bleedC") );
mQuadBleed->getParams().addVolumeTexture( "tRGB2HSV", *RGET_S_VOLTEX(RID_RGB2HSV) );
mQuadBleed->getParams().addVolumeTexture( "tHSV2RGB", *RGET_S_VOLTEX(RID_HSV2RGB) );
mQuadBleed->getParams().addFloatRef( "fOffsetX", &mBleedOffsetX );
mQuadBleed->getParams().addFloatRef( "fOffsetY", &mBleedOffsetY );
mQuadFinal = new CQuadMesh( "imgComposite" );
mQuadFinal->getParams().addTexture( "tBase", *RGET_S_TEX(RID_BASERT) );
mQuadFinal->getParams().addTexture( "tBleed", *RGET_S_TEX(RID_BLEEDACC) );
mQuadFinal->getParams().addTexture( "tEdges", *RGET_S_TEX(RID_EDGES) );
// static level
CON_INFO.write( "creating objects..." );
initLevel();
mRenderedFrames = 0;
mBenchOver = false;
mAnimate = true;
CON_INFO.write( "initialized" );
}
void CDemo::initOtherSurfaces()
{
CON_INFO.write( "creating other RTs..." );
CSharedTextureBundle& stb = CSharedTextureBundle::getInstance();
CSharedSurfaceBundle& ssb = CSharedSurfaceBundle::getInstance();
ITextureCreator* creatorBase = new CScreenBasedTextureCreator(1.0f, 1.0f, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT );
ITextureCreator* creator512 = new CFixedTextureCreator(512, 512, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT );
stb.registerTexture( RID_BASERT, creatorBase );
stb.registerTexture( RID_FIXEDRT512, creator512 );
stb.registerTexture( RID_QUANTIZED, creator512 );
stb.registerTexture( RID_BLEEDACC, creator512 );
stb.registerTexture( RID_NORMALZ, creatorBase );
stb.registerTexture( RID_EDGES, creatorBase );
ssb.registerSurface( RID_BASERT, new CTextureLevelSurfaceCreator( *RGET_S_TEX(RID_BASERT) ) );
ssb.registerSurface( RID_FIXEDRT512, new CTextureLevelSurfaceCreator( *RGET_S_TEX(RID_FIXEDRT512) ) );
ssb.registerSurface( RID_QUANTIZED, new CTextureLevelSurfaceCreator( *RGET_S_TEX(RID_QUANTIZED) ) );
ssb.registerSurface( RID_BLEEDACC, new CTextureLevelSurfaceCreator( *RGET_S_TEX(RID_BLEEDACC) ) );
ssb.registerSurface( RID_NORMALZ, new CTextureLevelSurfaceCreator( *RGET_S_TEX(RID_NORMALZ) ) );
ssb.registerSurface( RID_EDGES, new CTextureLevelSurfaceCreator( *RGET_S_TEX(RID_EDGES) ) );
ssb.registerSurface( RID_LAKEREFL, new CTextureLevelSurfaceCreator( *RGET_S_TEX(RID_LAKEREFL) ) );
}
void CDemo::initShadowMaps()
{
CON_INFO.write( "creating shadowmap RTs..." );
CSharedTextureBundle& stb = CSharedTextureBundle::getInstance();
CSharedSurfaceBundle& ssb = CSharedSurfaceBundle::getInstance();
// register shadow map RT
stb.registerTexture( RID_SHADOWMAP,
new CFixedTextureCreator( SHADOW_MAP_SIZE, SHADOW_MAP_SIZE, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A4R4G4B4, D3DPOOL_DEFAULT ) );
ssb.registerSurface( RID_SHADOWMAP,
new CTextureLevelSurfaceCreator( *RGET_S_TEX(RID_SHADOWMAP), 0 ) );
}
void CDemo::initWaterMaps()
{
CON_INFO.write( "creating reflection RTs..." );
CSharedTextureBundle& stb = CSharedTextureBundle::getInstance();
CSharedSurfaceBundle& ssb = CSharedSurfaceBundle::getInstance();
stb.registerTexture( RID_LAKEREFL, new CFixedTextureCreator(LAKE_REFL_SIZE, LAKE_REFL_SIZE, 1, D3DUSAGE_RENDERTARGET /*| D3DUSAGE_AUTOGENMIPMAP*/, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT ) );
ssb.registerSurface( RID_LAKEREFLZ, new CFixedSurfaceCreator( LAKE_REFL_SIZE, LAKE_REFL_SIZE, true, D3DFMT_D16 ) );
}
class CVolumeFuncCreator : public CFixedVolumeCreator {
public:
CVolumeFuncCreator( int size, LPD3DXFILL3D func )
: CFixedVolumeCreator(size,size,size, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED ), mFunc(func) { }
virtual IDirect3DVolumeTexture9* createTexture() {
IDirect3DVolumeTexture9* tex = CFixedVolumeCreator::createTexture();
D3DXFillVolumeTexture( tex, mFunc, 0 );
return tex;
}
private:
LPD3DXFILL3D mFunc;
};
void CDemo::initQuantizeMaps()
{
CON_INFO.write( "creating volume textures..." );
CSharedVolumeBundle& svb = CSharedVolumeBundle::getInstance();
const int VOL_SIZE = 32;
// create volume RGB->HSV and HSV->RGB textures
svb.registerVolume( RID_RGB2HSV, new CVolumeFuncCreator( VOL_SIZE, gVolumeFillerRGB2HSV ) );
svb.registerVolume( RID_HSV2RGB, new CVolumeFuncCreator( VOL_SIZE, gVolumeFillerHSV2RGB ) );
}
void CDemo::initLevel()
{
int i;
//
// read scene file and create meshes
FILE* f = fopen( "data/scene.txt", "rt" );
assert( f );
int count;
fscanf( f, "count = %i\n", &count );
for( i = 0; i < count; ++i ) {
char name[100];
SVector3 pos; SQuaternion rot;
fscanf( f, "name=%s pos=%f %f %f rot=%f %f %f %f\n", name, &pos.x, &pos.y, &pos.z, &rot.x, &rot.y, &rot.z, &rot.w );
std::string sname = name;
CSimpleMesh* mesh = 0;
if( sname=="Pusis1" || sname=="Pusis2" ) {
mesh = new CSimpleMesh( sname );
const char* tex0[] = { "medisA", "medisB" };
const char* tex1[] = { "lapaiA", "lapaiC", "lapaiC" };
mesh->addMeshPart( 0, tex0[rand()%2] );
mesh->addMeshPart( 1, tex1[rand()%3] );
} else if( sname=="Medis1" ) {
mesh = new CSimpleMesh( sname );
const char* tex0[] = { "medisA", "medisB" };
const char* tex1[] = { "lapaiA", "lapaiB" };
mesh->addMeshPart( 0, tex0[rand()%2] );
mesh->addMeshPart( 1, tex1[rand()%2] );
} else if( sname=="Pusis3" ) {
mesh = new CSimpleMesh( sname );
const char* tex1[] = { "medisA", "medisB" };
mesh->addMeshPart( 1, tex1[rand()%2] );
mesh->addMeshPart( 0, "lapaiC" );
} else if( sname=="House1" ) {
mesh = new CSimpleMesh( sname );
mesh->addMeshPart( 0, "medisB" );
mesh->addMeshPart( 1, "siaudai" );
} else if( sname=="Lake1" || sname=="Lake2" || sname=="Lake3" || sname=="Lake4" || sname=="Lake5" ) {
CWaterMesh* wmesh = new CWaterMesh( sname );
wmesh->mMatrix = SMatrix4x4( pos, rot );
mWaterMeshes.push_back( wmesh );
}
if( mesh ) {
mesh->mMatrix = SMatrix4x4( pos, rot );
mSimpleMeshes.push_back( mesh );
}
}
fclose( f );
//
// create some clouds
const int CLOUD_COUNT = 20;
mCloudMeshes.reserve( CLOUD_COUNT );
const char* cnames[2] = { "CloudA", "CloudB" };
for( i = 0; i < CLOUD_COUNT; ++i ) {
CResourceId meshID = cnames[rand()%2];
CCloudMesh* cloud = new CCloudMesh( meshID );
cloud->mMatrix.identify();
cloud->mMatrix.getOrigin().set(
(rand()%600)-300,
130 + (rand()&25),
(rand()%600)-300 );
mCloudMeshes.push_back( cloud );
}
}
void CDemo::appShutdown()
{
safeDelete( mTerrain );
safeDelete( mSky );
}
void CDemo::processInput()
{
//
// hacky keyboard
const float dt = mElapsedTime;
const float d_move = 12.0f * dt;
const float d_rise = 6.0f * dt;
const float d_turn = D3DX_PI*0.4f * dt;
float oldY = mCamPosition.y;
if( GetAsyncKeyState(VK_UP) ) {
mCamPosition += mMatCamera.getAxisZ() * d_move;
mCamPosition.y = oldY;
}
if( GetAsyncKeyState(VK_DOWN) ) {
mCamPosition -= mMatCamera.getAxisZ() * d_move;
mCamPosition.y = oldY;
}
if( GetAsyncKeyState('A') )
mCamPosition.y += d_rise;
if( GetAsyncKeyState('Z') )
mCamPosition.y -= d_rise;
if( GetAsyncKeyState(VK_LEFT) )
mCamYawPitchRoll.x -= d_turn;
if( GetAsyncKeyState(VK_RIGHT) )
mCamYawPitchRoll.x += d_turn;
if( GetAsyncKeyState('S') )
mCamYawPitchRoll.y -= d_turn*0.5;
if( GetAsyncKeyState('X') )
mCamYawPitchRoll.y += d_turn*0.5;
float sunTheta = mSun.getTheta();
if( GetAsyncKeyState(VK_NEXT) )
sunTheta += 0.5f*dt;
if( GetAsyncKeyState(VK_PRIOR) )
sunTheta -= 0.5f*dt;
if( sunTheta < -D3DX_PI*0.48f )
sunTheta = -D3DX_PI*0.48f;
if( sunTheta > D3DX_PI*0.48f )
sunTheta = D3DX_PI*0.48f;
mSun.setParams( sunTheta, mSun.getPhi(), mSun.getIntensity() );
static bool justPressedW = false;
if( GetAsyncKeyState('W') ) {
if( !justPressedW )
mWireframe = !mWireframe;
justPressedW = true;
} else
justPressedW = false;
static bool justPressedQ = false;
if( GetAsyncKeyState('Q') ) {
if( !justPressedQ )
mAnimate = !mAnimate;
justPressedQ = true;
} else
justPressedQ = false;
D3DXMatrixRotationYawPitchRoll( &mMatCamera, mCamYawPitchRoll.x, mCamYawPitchRoll.y, mCamYawPitchRoll.z );
mMatCamera.getOrigin() = mCamPosition;
// dump camera params
static bool justPressedP = false;
if( GetAsyncKeyState('P') ) {
if( !justPressedP ) {
CON_INFO << "camera pos " << mCamPosition.x << " " << mCamPosition.y << " " << mCamPosition.z << endl;
CON_INFO << "camera rot " << mCamYawPitchRoll.x << " " << mCamYawPitchRoll.y << " " << mCamYawPitchRoll.z << endl;
}
justPressedP = true;
} else
justPressedP = false;
}
void CDemo::appPerform()
{
static int initSkipFrames = 0;
const int SKIP_FRAMES = 20;
bool skipElapsed = true;
static double startTime = 0.0;
if( initSkipFrames < SKIP_FRAMES ) {
if( mBenchMode || initSkipFrames==0 ) {
startTime = mTime;
mRenderedFrames = 0;
}
++initSkipFrames;
skipElapsed = false;
}
double timeFromStart = mTime - startTime;
double duration = mBenchMode ? 20.0 : 160.0;
double relTime = timeFromStart / duration;
if( relTime > 1.0f )
mBenchOver = true;
mFloatTime = mTime;
// input
if( !mBenchMode )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -