예제 #1
0
void C3DCanvas::Draw(float fDeltaTime)
{
	CBaseObject* pActor = GetActor();
	if(!IsEnabled() || pActor==0)
		return;
	if(m_bNeedUpdate == false)
		return;

	if(!m_bInitialized)
	{
		InitDeviceObjects();
		RestoreDeviceObjects();
	}
	if(m_pCanvasSurface == 0 || m_pDepthStencilSurface==0)
		return;

	if(m_bAutoRotate)
	{
		m_camera.Rotate(0,0.3f*fDeltaTime, 0);
	}

	m_bNeedUpdate = false;
	
	EffectManager* pEffectManager = CGlobals::GetEffectManager();
	LPDIRECT3DDEVICE9 pd3dDevice = CGlobals::GetRenderDevice();

	LPDIRECT3DSURFACE9 pOldRenderTarget =  CGlobals::GetDirectXEngine().GetRenderTarget();
	CGlobals::GetDirectXEngine().SetRenderTarget(0, m_pCanvasSurface);

	// save old render origin
	Vector3 vOldRenderOrigin = CGlobals::GetScene()->GetRenderOrigin();

	// set depth surface
	LPDIRECT3DSURFACE9 pOldZBuffer = NULL;
	if(FAILED(pd3dDevice->GetDepthStencilSurface(&pOldZBuffer)))
		return;
	pd3dDevice->SetDepthStencilSurface( m_pDepthStencilSurface );

	// save old actor position
	pActor->PushParam();

	pActor->SetPosition(m_vActorPosition);
	pActor->SetFacing(m_fActorFacing);
	

	// animate the camera and push result to transformation stack
	m_camera.FrameMove(fDeltaTime);

	CGlobals::GetProjectionMatrixStack().push(*m_camera.GetProjMatrix());
	CGlobals::GetViewMatrixStack().push(*m_camera.GetViewMatrix());
	CGlobals::GetEffectManager()->UpdateD3DPipelineTransform(true,true, true);

	// clear 
	pd3dDevice->Clear(0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, COLOR_RGBA(0, 0, 0, 0), 1.0f, 0L);

	// disable fog
	pEffectManager->EnableFog(false);

	
	if(pEffectManager->BeginEffect(pActor->GetPrimaryTechniqueHandle(), &(CGlobals::GetSceneState()->m_pCurrentEffect)))
	{
		/** draw the main stage object */
		pActor->Draw(CGlobals::GetSceneState());
		CGlobals::GetSceneState()->GetFaceGroups()->Clear();
	}
	

	if(m_pMask!=0 && pEffectManager->BeginEffect(TECH_GUI, &(CGlobals::GetSceneState()->m_pCurrentEffect)))
	{
		/** draw the mask square in front of the screen. */
		CEffectFile* pEffectFile = CGlobals::GetEffectManager()->GetCurrentEffectFile();
		if(pEffectFile == 0)
		{
			//////////////////////////////////////////////////////////////////////////
			// fixed programming pipeline
			float sx = (float)m_nTextureWidth,sy = (float)m_nTextureHeight;
			
			DXUT_SCREEN_VERTEX v[10];
			v[0].x = 0;  v[0].y = sy; v[0].tu = 0;  v[0].tv = 1.0f;
			v[1].x = 0;  v[1].y = 0;  v[1].tu = 0;  v[1].tv = 0;
			v[2].x = sx; v[2].y = sy; v[2].tu = 1.f; v[2].tv = 1.f;
			v[3].x = sx; v[3].y = 0;  v[3].tu = 1.f; v[3].tv = 0;

			DWORD dwColor = LinearColor(1.f,1.f,1.f,1.f);
			int i;
			for(i=0;i<4;i++)
			{
				v[i].color = dwColor;
				v[i].z = 0;
				v[i].h = 1.0f;
			}
			CGlobals::GetRenderDevice()->SetTexture(0, m_pMask->GetTexture());
			RenderDevice::DrawPrimitiveUP( CGlobals::GetRenderDevice(), RenderDevice::DRAW_PERF_TRIANGLES_UI, D3DPT_TRIANGLESTRIP, 2, v, sizeof(DXUT_SCREEN_VERTEX) );
		}
	}
	
	//////////////////////////////////////////////////////////////////////////
	// Restore state for the normal pipeline

	// enable fog
	pEffectManager->EnableFog(CGlobals::GetScene()->IsFogEnabled());

	// restore old actor position
	pActor->PopParam();
	
	// restore transformations
	CGlobals::GetProjectionMatrixStack().pop();
	CGlobals::GetViewMatrixStack().pop();
	CGlobals::GetEffectManager()->UpdateD3DPipelineTransform(true,true, true);

	// restore old depth surface
	pd3dDevice->SetDepthStencilSurface( pOldZBuffer);
	SAFE_RELEASE(pOldZBuffer);
	// Restore the old render target: i.e. the backbuffer
	HRESULT hr = CGlobals::GetDirectXEngine().SetRenderTarget(0, pOldRenderTarget);
	assert(hr == D3D_OK);

	// restore render origin
	CGlobals::GetScene()->RegenerateRenderOrigin(vOldRenderOrigin);

#ifdef _DEBUG
	//SaveToFile("E:\\cavas_obj.png");
#endif

}
예제 #2
0
void CMiniSceneGraph::Draw_Internal(float fDeltaTime)
{
	PERF1("MiniSceneGraph_Draw");
	SceneState& sceneState = m_sceneState;
	m_sceneState.m_pd3dDevice = CGlobals::GetRenderDevice();
	RenderDevicePtr pd3dDevice = m_sceneState.m_pd3dDevice;

	EffectManager* pEffectManager = CGlobals::GetEffectManager();
	bool old_IsLocalLightEnabled = pEffectManager->IsLocalLightingEnabled();

	IScene * pOldScene = pEffectManager->GetScene();
	pEffectManager->SetScene(this);

	//////////////////////////////////////////////////////////////////////////
	// Set some initial states for the normal pipeline
	LinearColor fogColor = GetSunLight().ComputeFogColor();
	fogColor.r *= GetFogColorFactor().r;
	fogColor.g *= GetFogColorFactor().g;
	fogColor.b *= GetFogColorFactor().b;
	SetFogColor(fogColor);
	pEffectManager->EnableFog(IsFogEnabled());
	pEffectManager->SetD3DFogState();
#ifdef USE_DIRECTX_RENDERER
	pd3dDevice->SetMaterial((D3DMATERIAL9*)&(sceneState.GetGlobalMaterial()));
#elif defined(USE_OPENGL_RENDERER)
	if (!IsSunLightEnabled())
	{
		// sun light can not be disabled in shader, so we will fake it here. Remove this when shader support turn off global sun light. 
		GetSunLight().SetSunAmbient(LinearColor::White);
		GetSunLight().SetSunDiffuse(LinearColor::Black);
	}
#endif
	
	// disable local lights on bipeds
	if(old_IsLocalLightEnabled)
		pEffectManager->EnableLocalLighting(false);

	// end previous effects, since they may serve different IScene instance.
	pEffectManager->EndEffect();

	// copy the main scene's state
	sceneState.m_pCurrentEffect = pEffectManager->GetCurrentEffectFile();
	
	// rebuild scene state
	sceneState.dTimeDelta = fDeltaTime;
	PrepareRender(m_pCamera, &sceneState);
	
	{
		// all render code goes here

		/**
		All potentially visible scene objects in the scene state are put to three major post rendering lists for rendering.
		Each list is sorted according to object-to-camera distance. And then they will be rendered in the following order:
		- solid object list: sorted from front to back. In mesh report, it will display "F->B:%d". Their bounding boxes will be rendered as red boxes.
		- transparent object list: sorted from back to front. In mesh report, it will display "B->F:%d(%d1)".
		where %d is the total number of meshes rendered and that %d1 is the number of meshes that has been occluded during occlusion testing.
		Their bounding boxes will be rendered as blue boxes.
		- Biped list: sorted by primary asset. In mesh report, it will display "Biped:%d". Their bounding boxes will be rendered as green boxes.
		*/
		{
			// so that mesh and character that contains translucent faces are sorted and rendered later on. 
			if(!sceneState.GetFaceGroups()->IsEmpty())
			{
				sceneState.GetFaceGroups()->Clear();
			}
			sceneState.m_bEnableTranslucentFaceSorting = true;

			// object num in potentially visible set from current view point
			int nPVSCount = 0; 

			//////////////////////////////////////////////////////////////////////////
			/// Draw SkyBox 
			RenderSelection(RENDER_SKY_BOX);

			//////////////////////////////////////////////////////////////////////////
			/// draw solid object rendering list from front to back.
			if(!sceneState.listPRSolidObject.empty())
			{
				RenderSelection(RENDER_MESH_FRONT_TO_BACK);
			}

			//////////////////////////////////////////////////////////////////////////
			// draw smaller object rendering list from back to front.
			if(!sceneState.listPRSmallObject.empty())
			{
				nPVSCount = RenderSelection(RENDER_MESH_BACK_TO_FRONT);
			}
			
			//////////////////////////////////////////////////////////////////////////
			/// Draw queued bipeds
			/// we draw biped after its shadow, because we do not want biped to cast shadows on its own
			if(!sceneState.listPRBiped.empty())
			{
				RenderSelection(RENDER_CHARACTERS);
			}

			//////////////////////////////////////////////////////////////////////////
			// draw transparent object rendering list from back to front.it is rendered after ocean to prevent the ocean color over the particles. 
			if(!sceneState.listPRTransparentObject.empty())
			{
				RenderSelection(RENDER_MESH_TRANSPARENT);
			}

			//////////////////////////////////////////////////////////////////////////
			// render translucent face groups.
			if(!sceneState.GetFaceGroups()->IsEmpty())
			{
				// translucent faces are ignored. 
				RenderSelection(RENDER_TRANSLUCENT_FACE_GROUPS);
				sceneState.GetFaceGroups()->Clear();
			}

			//////////////////////////////////////////////////////////////////////////
			/// render all particle system instances after most of the scene have been rendered.
			/// it is rendered after ocean to prevent the ocean color over the particles. since all particles are z write disabled.
			{
				int nParticlesCount = RenderSelection(RENDER_PARTICLES, fDeltaTime);
			}

			//////////////////////////////////////////////////////////////////////////
			// bounding box
			if(CGlobals::GetScene()->IsShowBoundingBox())
				RenderSelection(RENDER_BOUNDINGBOX);

			//////////////////////////////////////////////////////////////////////////
			// portal 
			if(CGlobals::GetScene()->IsPortalSystemShown())
				RenderSelection(RENDER_PORTAL_SYSTEM);
		}
	}
#ifdef USE_DIRECTX_RENDERER
	if(m_pMask!=0 && pEffectManager->BeginEffect(TECH_GUI, &(m_sceneState.m_pCurrentEffect)))
	{
		/** draw the mask square in front of the screen. */
		CEffectFile* pEffectFile = CGlobals::GetEffectManager()->GetCurrentEffectFile();
		if(pEffectFile == 0)
		{
			//////////////////////////////////////////////////////////////////////////
			// fixed programming pipeline
			float sx = (float)m_nTextureWidth,sy = (float)m_nTextureHeight;

			DXUT_SCREEN_VERTEX v[10];
			v[0].x = 0;  v[0].y = sy; v[0].tu = 0;  v[0].tv = 1.0f;
			v[1].x = 0;  v[1].y = 0;  v[1].tu = 0;  v[1].tv = 0;
			v[2].x = sx; v[2].y = sy; v[2].tu = 1.f; v[2].tv = 1.f;
			v[3].x = sx; v[3].y = 0;  v[3].tu = 1.f; v[3].tv = 0;

			DWORD dwColor = LinearColor(1.f,1.f,1.f,1.f);
			int i;
			for(i=0;i<4;i++)
			{
				v[i].color = dwColor;
				v[i].z = 0;
				v[i].h = 1.0f;
			}
			//pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1 );		// modulate operation
			//pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_SELECTARG2 );
			//
			//pd3dDevice->SetRenderState( D3DRS_COLORWRITEENABLE,
			//	D3DCOLORWRITEENABLE_RED  | D3DCOLORWRITEENABLE_GREEN |
			//	D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA );

			pd3dDevice->SetRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA );

			pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);	
			pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
			pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCALPHA);

			/*pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP,D3DTOP_SELECTARG2);
			pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1,D3DTA_TEXTURE);
			pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2,D3DTA_CURRENT);

			pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP,D3DTOP_SELECTARG1);
			pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1,D3DTA_TEXTURE);
			pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2,D3DTA_CURRENT);*/

			pd3dDevice->SetTexture(0, m_pMask->GetTexture());
			RenderDevice::DrawPrimitiveUP( pd3dDevice, RenderDevice::DRAW_PERF_TRIANGLES_MESH, D3DPT_TRIANGLESTRIP, 2, v, sizeof(DXUT_SCREEN_VERTEX) );

			/*pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP,D3DTOP_MODULATE);
			pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1,D3DTA_TEXTURE);
			pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2,D3DTA_CURRENT);

			pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP,D3DTOP_SELECTARG1);
			pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1,D3DTA_TEXTURE);
			pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2,D3DTA_CURRENT);*/

			pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
			pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

			pd3dDevice->SetRenderState( D3DRS_COLORWRITEENABLE,
					D3DCOLORWRITEENABLE_RED  | D3DCOLORWRITEENABLE_GREEN |
					D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA );
		}
	}
#endif

	// draw the head on display GUI
	RenderHeadOnDisplay();

	//////////////////////////////////////////////////////////////////////////
	// Restore state for the normal pipeline

	pEffectManager->SetScene(pOldScene);

	// enable fog
	pEffectManager->EnableFog(CGlobals::GetScene()->IsFogEnabled());

	// restore the main scene's state
	CGlobals::GetSceneState()->m_pCurrentEffect = sceneState.m_pCurrentEffect;

	if(old_IsLocalLightEnabled)
		pEffectManager->EnableLocalLighting(old_IsLocalLightEnabled);
}