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

📄 demo.cpp

📁 java实现的简单的分形树。简单易学!是学习分形知识的很好的例子。其java语法简单
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		processInput();

	// animate
	float camFov = D3DX_PI * 0.25f;
	if( mBenchMode || mAnimate ) {
		float sunTheta;
		mCameraAnim->animate( relTime, camFov, sunTheta );
		mSun.setParams( sunTheta, mSun.getPhi(), mSun.getIntensity() );
	}
	mSunColorDivBetaSum = mSun.getColorMulIntensity();
	mSunColorDivBetaSum.x *= mAtmosphere.getMulInvBetaRayMieSum().x;
	mSunColorDivBetaSum.y *= mAtmosphere.getMulInvBetaRayMieSum().y;
	mSunColorDivBetaSum.z *= mAtmosphere.getMulInvBetaRayMieSum().z;
	
	// quad offset
	CD3DDevice& dx = CD3DDevice::getInstance();
	float pixX = 1.0f / dx.getBackBufferWidth();
	float pixY = 1.0f / dx.getBackBufferHeight();
	mQuadOffset.set( pixX * 0.5f, -pixY * 0.5f, 0.0f, 0.0f );

	dx.getDevice().SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );

	// light dir from sun
	mLightDirNeg = mSun.getDirection();

	// move clouds
	/*
	for( int c = 0; c < mCloudMeshes.size(); ++c ) {
		SMatrix4x4& m = mCloudMeshes[c]->mMatrix;
		SVector3& o = m.getOrigin();
		SVector3 v;
		v.x = -10.0f + (170 - o.y) * 0.20f;
		v.y = 0.0f;
		v.z = -2.0f + (170 - o.y) * 0.02f;
		v *= mElapsedTime;
		o += v;
		if( o.x > 400 ) o.x = -400;
		else if( o.x < -400 ) o.x = 400;
		if( o.z > 400 ) o.z = -400;
		else if( o.z < -400 ) o.z = 400;
	}
	*/

	// shadow map
	renderShadowMap();

	// camera
	CRenderCamera& camera = G_RENDERCTX->getCamera();
	SMatrix4x4 proj;
	float aspect = dx.getBackBufferAspect();
	D3DXMatrixPerspectiveFovLH( &proj, camFov, aspect, 0.1f, 1200.0f );
	camera.setCameraMatrix( mMatCamera );
	camera.setProjectionMatrix( proj );

	// lake reflection
	renderLakeRefl();

	// camera
	camera.setCameraMatrix( mMatCamera );
	CProjector::computeTextureProjection( mMatCamera, mMatTexProj );

	SVector3 lookDir = camera.getCameraMatrix().getAxisZ();
	lookDir.y = 0.0f;
	lookDir.normalize();
	float phi = atan2f( lookDir.z, lookDir.x );
	mBleedOffsetX = -phi/(camFov*aspect);
	const float bleedVDist = 50.0f;
	SVector3 target = camera.getCameraMatrix().getOrigin() + camera.getCameraMatrix().getAxisZ() * bleedVDist;
	mBleedOffsetY = -target.y / (bleedVDist * tanf(camFov));
	
	// base
	renderBase();

	dx.setZStencil( NULL );

	// build small RT
	computeSmallRT();

	//// RGB->HSV
	//fullscreenPass( RID_QUANTIZED, *mQuadRGB2HSV );
	// compute bleeds
	fullscreenPass( RID_BLEEDACC, *mQuadBleed );
	//// back to RGB
	//fullscreenPass( RID_FIXEDRT512, *mQuadHSV2RGB );

	// detect edges
	fullscreenPass( RID_EDGES, *mQuadEdges );


	// final composite
	dx.sceneBegin();
	dx.setDefaultRenderTarget();
	G_RENDERCTX->directBegin();
	G_RENDERCTX->directRender( *mQuadFinal );
	G_RENDERCTX->directEnd();

	// some text
	dx.resetCachedState();

	CD3DFont& font = getFont();
	char buf[300];
	if( mBenchMode ) {
		D3DCOLOR textColor = 0xFFC00000;
		sprintf( buf, "BENCHMARK MODE. %ix%i", mBackBuffer.Width, mBackBuffer.Height );
		font.drawText( 5, 5+16*0, textColor, buf );
		if( !skipElapsed ) {
			font.drawText( 5, 5+16*1, textColor, "WARMING UP..." );
		} else if( mBenchOver ) {
			sprintf( buf, "BENCHMARK OVER. SCORE %i", mRenderedFrames );
			font.drawText( 5, 5+16*1, textColor, buf );
		} else {
			sprintf( buf, "%i%% completed", (int)(relTime*100.0) );
			font.drawText( 5, 5+16*1, textColor, buf );
		}
	} else {
		const CRenderStats& stats = dx.getStats();
		D3DCOLOR textColor = 0xA0101010;
		font.drawText( 5, 5+16*0, textColor, mFrameStats );
		font.drawText( 5, 5+16*1, textColor, mDeviceStats );
		char buf[200];
		sprintf( buf,
			"%.1f Mprims/s;  %i DI/DIPs;  %i RTchanges;  %.1f Kverts;  %.1f Kprims",
			(stats.getPrimsRendered() * mFPS) / 1000000.0f,
			stats.getDrawCalls(),
			stats.changes.renderTarget,
			stats.getVerticesRendered() / 1000.0f,
			stats.getPrimsRendered() / 1000.0f );
		font.drawText( 5, 5+16*2, textColor, buf );
	}
	dx.sceneEnd();

	if( !mBenchOver )
		++mRenderedFrames;
}

void CDemo::justRenderBaseNoLakes( eRenderMode mode, int terrainLod )
{
	CD3DDevice& dx = CD3DDevice::getInstance();

	mTerrain->render( terrainLod, mode );
	if( mode != NORMALZ )
		mSky->render();

	// clouds
	assert( !mCloudMeshes.empty() );
	for( int i = 0; i < mCloudMeshes.size(); ++i )
		mCloudMeshes[i]->render( mode );

	// static meshes
	renderStaticMeshes( mode );
}


void CDemo::renderBase()
{
	CD3DDevice& dx = CD3DDevice::getInstance();
	bool haveMRT = (dx.getMRTCount() >= 2);
	if( !mUseMRT )
		haveMRT = false;

	// clear color for normal/z to match negative light direction
	D3DXCOLOR clearColor;
	clearColor.r = (mLightDirNeg.x + 1.0f) * 0.5f;
	clearColor.g = (mLightDirNeg.y + 1.0f) * 0.5f;
	clearColor.b = (mLightDirNeg.z + 1.0f) * 0.5f;
	clearColor.a = 1.0f;

	dx.getDevice().SetRenderState( D3DRS_FILLMODE, mWireframe ? D3DFILL_WIREFRAME : D3DFILL_SOLID );

	dx.setDefaultZStencil();
	dx.setRenderTarget( RGET_S_SURF(RID_BASERT), 0 );

	if( haveMRT ) {
		// set normal/Z RT1
		dx.setRenderTarget( RGET_S_SURF(RID_NORMALZ), 1 );
		dx.clearTargets( true, true, false, clearColor, 1.0f, 0L );
		dx.sceneBegin();
		justRenderBaseNoLakes( BASE, 0 );
		renderWater( BASE );
		G_RENDERCTX->perform();
		dx.setRenderTarget( NULL, 1 );
		dx.sceneEnd();
	} else {
		// fallback to separate passes
		// color pass
		dx.clearTargets( false, true, false, clearColor, 1.0f, 0L );
		dx.sceneBegin();
		justRenderBaseNoLakes( COLOR, 0 );
		renderWater( COLOR );
		G_RENDERCTX->perform();
		dx.sceneEnd();
		// normal/Z pass
		dx.setRenderTarget( RGET_S_SURF(RID_NORMALZ), 0 );
		//dx.setRenderTarget( RGET_S_SURF(RID_BASERT), 0 );
		dx.clearTargets( true, true, false, clearColor/*0xFF000000*/, 1.0f, 0L );
		dx.sceneBegin();
		justRenderBaseNoLakes( NORMALZ, 0 );
		renderWater( NORMALZ );
		G_RENDERCTX->perform();
		dx.sceneEnd();
	}

	dx.getDevice().SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
}

void CDemo::renderWater( eRenderMode mode )
{
	//CD3DDevice::getInstance().getDevice().SetFVF( D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1 );

	assert( !mWaterMeshes.empty() );
	int n = mWaterMeshes.size();
	for( int i = 0; i < n; ++i )
		mWaterMeshes[i]->render( mode );
}

void CDemo::renderStaticMeshes( eRenderMode mode )
{
	//CD3DDevice::getInstance().getDevice().SetFVF( D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1 );
	assert( !mSimpleMeshes.empty() );
	for( int i = 0; i < mSimpleMeshes.size(); ++i )
		mSimpleMeshes[i]->render( mode );
}

void CDemo::renderShadowMap()
{
	CRenderCamera& camera = G_RENDERCTX->getCamera();
	CD3DDevice& dx = CD3DDevice::getInstance();

	//
	// setup shadow map transform params

	const float SHADOW_CENTER_FWD = 100.0f;
	const float SHADOW_CENTER_Y = 40.0f;
	const float SHADOW_EYE_DIST = 260.0f;
	const float SHADOW_REGION = 300.0f;
	SVector3 shadowCenter = mMatCamera.getOrigin() + mMatCamera.getAxisZ() * SHADOW_CENTER_FWD;
	shadowCenter.y = SHADOW_CENTER_Y;
	SVector3 shadowEye = shadowCenter + mLightDirNeg * SHADOW_EYE_DIST;

	// camera matrix
	SMatrix4x4 matCam;
	matCam.identify();
	matCam.getOrigin() = shadowEye;
	matCam.getAxisZ() = -mLightDirNeg;
	matCam.getAxisY().set(0,1,0);
	matCam.getAxisX() = matCam.getAxisY().cross( matCam.getAxisZ() ).getNormalized();
	matCam.getAxisY() = matCam.getAxisZ().cross( matCam.getAxisX() ).getNormalized();
	
	// now, set camera origin into "quantized" grid on the camera plane, so as we move,
	// the texels of the shadowmap don't fiddle

	// project point (0,0,0) into camera space. we could do this with view matrix,
	// but that would require inversion, and one more inversion later (when we'll adjust the
	// camera matrix)
	SVector3 line = -shadowEye;
	float projX = matCam.getAxisX().dot( line );
	float projY = matCam.getAxisY().dot( line );
	float projZ = matCam.getAxisZ().dot( line );
	const float TEXEL_QUANTIZE = SHADOW_REGION / (SHADOW_MAP_SIZE-2); // one pixel border
	const float modX = fmodf( projX, TEXEL_QUANTIZE );
	const float modY = fmodf( projY, TEXEL_QUANTIZE );
	const float modZ = fmodf( projZ, TEXEL_QUANTIZE );
	projX -= modX;
	projY -= modY;
	projZ -= modZ;
	SVector3 adjOrigin = matCam.getOrigin();
	adjOrigin += matCam.getAxisX() * projX;
	adjOrigin += matCam.getAxisY() * projY;
	adjOrigin += matCam.getAxisZ() * projZ;
	matCam.getOrigin() -= adjOrigin;

	camera.setCameraMatrix( matCam );
	SMatrix4x4 matProj;
	D3DXMatrixOrthoLH( &matProj, SHADOW_REGION, SHADOW_REGION, 0.1f, SHADOW_EYE_DIST*2.0f );
	camera.setProjectionMatrix( matProj );

	// texture adjustment matrix
	// jitter 4 samples
	float fC1 = -0.1f / SHADOW_MAP_SIZE;
	float fC2 = 0.9f / SHADOW_MAP_SIZE;
	SMatrix4x4 matTexAdj;
	matTexAdj.identify();
	matTexAdj._11 = 0.5f;
	matTexAdj._22 = -0.5f;
	matTexAdj._33 = 0.0f;
	matTexAdj._43 = 1.0f;

	matTexAdj._41 = 0.5f+fC1; matTexAdj._42 = 0.5f+fC1;
	mMatProjShadow[0] = camera.getViewProjMatrix() * matTexAdj;
	matTexAdj._41 = 0.5f+fC1; matTexAdj._42 = 0.5f+fC2;
	mMatProjShadow[1] = camera.getViewProjMatrix() * matTexAdj;
	matTexAdj._41 = 0.5f+fC2; matTexAdj._42 = 0.5f+fC1;
	mMatProjShadow[2] = camera.getViewProjMatrix() * matTexAdj;
	matTexAdj._41 = 0.5f+fC2; matTexAdj._42 = 0.5f+fC2;
	mMatProjShadow[3] = camera.getViewProjMatrix() * matTexAdj;

	//
	// render into shadow RT

	dx.setRenderTarget( RGET_S_SURF(RID_SHADOWMAP), 0 );
	dx.setZStencil( NULL );
	dx.clearTargets( true, false, false, 0xFFffffff, 1.0f, 0L );
	dx.sceneBegin();

	D3DVIEWPORT9 vp;
	vp.X = vp.Y = 1;
	vp.Height = vp.Width = SHADOW_MAP_SIZE-2;
	vp.MinZ = 0.0f;
	vp.MaxZ = 1.0f;
	dx.getDevice().SetViewport( &vp );

	renderStaticMeshes( SHADOW );
	G_RENDERCTX->perform();
	
	dx.sceneEnd();
}

void CDemo::renderLakeRefl()
{
	CRenderCamera& camera = G_RENDERCTX->getCamera();
	CD3DDevice& dx = CD3DDevice::getInstance();

	//
	// find nearest lake to the viewer

	CWaterMesh* lake = 0;
	float		minDistSq = 1.0e10f;
	int			nlakes = mWaterMeshes.size();
	for( int i = 0; i < nlakes; ++i ) {
		CWaterMesh* l = mWaterMeshes[i];
		if( l->mAABB.frustumCull( l->mMatrix, camera.getViewProjMatrix() ) )
			continue;
		SVector3 v = l->mMatrix.getOrigin() - camera.getCameraMatrix().getOrigin();
		float distSq = v.lengthSq();
		if( distSq < minDistSq ) {
			minDistSq = distSq;
			lake = l;
		}
	}
	if( !lake )
		return;

	//
	// find lake's XZ plane, reflect camera, clip plane etc.

	const SMatrix4x4& lakeMat = lake->mMatrix;

	SPlane lakePlane( lakeMat.getOrigin() + SVector3(0,0.5f,0), lakeMat.getAxisY() );

	SMatrix4x4 reflectMat;
	D3DXMatrixReflect( &reflectMat, &lakePlane );
	SMatrix4x4 matCam;
	matCam = camera.getCameraMatrix() * reflectMat;
	camera.setCameraMatrix( matCam );

	SMatrix4x4 matFoo = camera.getViewProjMatrix();
	matFoo.invert();
	matFoo.transpose();
	SPlane clipPlane;
	D3DXPlaneTransform( &clipPlane, &lakePlane, &matFoo );

	dx.getDevice().SetClipPlane( 0, clipPlane );

	//
	// reverse culling, enable clip plane

	dx.getDevice().SetRenderState( D3DRS_CULLMODE, D3DCULL_CW );
	dx.getDevice().SetRenderState( D3DRS_CLIPPLANEENABLE, D3DCLIPPLANE0 );

	//
	// reflection RT

	dx.setRenderTarget( RGET_S_SURF(RID_LAKEREFL), 0 );
	dx.setZStencil( RGET_S_SURF(RID_LAKEREFLZ) );
	dx.clearTargets( false, true, false, 0xFFffffff, 1.0f, 0L );
	dx.sceneBegin();

	justRenderBaseNoLakes( COLOR, 3 );
	G_RENDERCTX->perform();

	dx.sceneEnd();
	
	//
	// restore culling, disable clip planes

	dx.getDevice().SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
	dx.getDevice().SetRenderState( D3DRS_CLIPPLANEENABLE, 0 );
}

void CDemo::computeSmallRT()
{
	CD3DDevice& dx = CD3DDevice::getInstance();

	IDirect3DSurface9* rtBig = RGET_S_SURF(RID_BASERT)->getObject();
	IDirect3DSurface9* rtSmall = RGET_S_SURF(RID_FIXEDRT512)->getObject();
	HRESULT hr = dx.getDevice().StretchRect( rtBig, 0, rtSmall, 0, D3DTEXF_NONE );
}

void CDemo::fullscreenPass( const char* renderTarget, CQuadMesh& quad )
{
	CD3DDevice& dx = CD3DDevice::getInstance();
	dx.setRenderTarget( RGET_S_SURF(renderTarget), 0 );
	dx.sceneBegin();
	G_RENDERCTX->directBegin();
	G_RENDERCTX->directRender( quad );
	G_RENDERCTX->directEnd();
	dx.sceneEnd();
}

⌨️ 快捷键说明

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