void AnimationController::Interpolate( float dt ) {
	timeSinceStart += dt;
	Anim anim = *anims[currentAnim];
	float animCurrentTime = fmod( timeSinceStart, anim.totalTime );
	for( Bone* bone:anim.boneSet ) {
		XMMATRIX rotMat, scaleMat, translateMat;

		// Interpolate Rotation
		auto rotSetIt = anim.rotChannels.find( bone );
		if( rotSetIt==anim.rotChannels.end() ) {
			rotMat = XMMatrixIdentity();
		} else {
			keySet_t rotKeySet = rotSetIt->second;
			auto itLow = rotKeySet.lower_bound( animCurrentTime );
			if( itLow==rotKeySet.begin() ) {
				itLow = rotKeySet.end();
			}
			--itLow;
			auto itHigh = rotKeySet.upper_bound( animCurrentTime );
			if( itHigh==rotKeySet.end() ) {
				itHigh = rotKeySet.begin();
			}
			float factor = (animCurrentTime-itLow->first)/(itHigh->first-itLow->first);
			XMVECTOR low = XMLoadFloat4( &itLow->second );
			XMVECTOR high = XMLoadFloat4( &itHigh->second );
			XMVECTOR interp = XMQuaternionSlerp( low, high, factor );
			XMVECTOR normalized = XMQuaternionNormalize( interp );
			rotMat = XMMatrixRotationQuaternion( interp );
		}

		// Interpolate Scale
		auto scaleSetIt = anim.scaleChannels.find( bone );
		if( scaleSetIt==anim.scaleChannels.end() ) {
			scaleMat = XMMatrixIdentity();
		} else {
			keySet_t scaleKeySet = scaleSetIt->second;
			auto itLow = scaleKeySet.lower_bound( animCurrentTime );
			if( itLow==scaleKeySet.begin() ) {
				itLow = scaleKeySet.end();
			}
			--itLow;
			auto itHigh = scaleKeySet.upper_bound( animCurrentTime );
			if( itHigh==scaleKeySet.end() ) {
				itHigh = scaleKeySet.begin();
			}
			float factor = (animCurrentTime-itLow->first)/(itHigh->first-itLow->first);
			XMFLOAT4 lowVec = itLow->second;
			XMFLOAT4 highVec = itHigh->second;
			scaleMat = XMMatrixScaling(
				lowVec.x+factor*(highVec.x-lowVec.x),
				lowVec.y+factor*(highVec.y-lowVec.y),
				lowVec.z+factor*(highVec.z-lowVec.z) );
		}

		// Interpolate Position
		auto posSetIt = anim.posChannels.find( bone );
		if( posSetIt==anim.posChannels.end() ) {
			translateMat = XMMatrixIdentity();
		} else {
			keySet_t posKeySet = posSetIt->second;
			auto itLow = posKeySet.lower_bound( animCurrentTime );
			if( itLow==posKeySet.begin() ) {
				itLow = posKeySet.end();
			}
			--itLow;
			auto itHigh = posKeySet.upper_bound( animCurrentTime );
			if( itHigh==posKeySet.end() ) {
				itHigh = posKeySet.begin();
			}
			float factor = (animCurrentTime-itLow->first)/(itHigh->first-itLow->first);
			XMFLOAT4 lowVec = itLow->second;
			XMFLOAT4 highVec = itHigh->second;
			translateMat = XMMatrixTranslation(
				lowVec.x+factor*(highVec.x-lowVec.x),
				lowVec.y+factor*(highVec.y-lowVec.y),
				lowVec.z+factor*(highVec.z-lowVec.z) );
		}

		// Conversion Matrix - this converts imported coords to DirectX
		XMMATRIX reflectX = XMMatrixReflect( XMLoadFloat3( &XMFLOAT3( 1.f, 0.f, 0.f ) ) );
		XMMATRIX reflectY = XMMatrixReflect( XMLoadFloat3( &XMFLOAT3( 0.f, 1.f, 0.f ) ) );
		XMMATRIX reflectZ = XMMatrixReflect( XMLoadFloat3( &XMFLOAT3( 0.f, 0.f, 1.f ) ) );
		XMMATRIX rotX = XMMatrixRotationX( XM_PIDIV2 );
		XMMATRIX rotY = XMMatrixRotationY( XM_PIDIV2 );
		XMMATRIX rotZ = XMMatrixRotationZ( XM_PIDIV2 );
		int foo = 17; //DELETEME
		XMMATRIX flip = XMLoadFloat4x4( &XMFLOAT4X4(
			1.f, 0.f, 0.f, 0.f,
			0.f, 1.f, 0.f, 0.f,
			0.f, 0.f, 1.f, 0.f,
			0.f, 0.f, 0.f, 1.f
			) );

		XMMATRIX finalMat = scaleMat * rotMat * translateMat;
		XMFLOAT4X4 transform;
		XMStoreFloat4x4( &transform, finalMat );
		finalTransform[bone] = transform;
	}
}
Пример #2
0
void MirrorApp::DrawScene()
{
	md3dImmediateContext->ClearRenderTargetView(mRenderTargetView, reinterpret_cast<const float*>(&Colors::Black));
	md3dImmediateContext->ClearDepthStencilView(mDepthStencilView, D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL, 1.0f, 0);

	md3dImmediateContext->IASetInputLayout(InputLayouts::Basic32);
    md3dImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
 
	float blendFactor[] = {0.0f, 0.0f, 0.0f, 0.0f};

	UINT stride = sizeof(Vertex::Basic32);
    UINT offset = 0;
 
	XMMATRIX view  = XMLoadFloat4x4(&mView);
	XMMATRIX proj  = XMLoadFloat4x4(&mProj);
	XMMATRIX viewProj = view*proj;

	// Set per frame constants.
	Effects::BasicFX->SetDirLights(mDirLights);
	Effects::BasicFX->SetEyePosW(mEyePosW);
	Effects::BasicFX->SetFogColor(Colors::Black);
	Effects::BasicFX->SetFogStart(2.0f);
	Effects::BasicFX->SetFogRange(40.0f);
 
	// Skull doesn't have texture coordinates, so we can't texture it.
	ID3DX11EffectTechnique* activeTech;
	ID3DX11EffectTechnique* activeSkullTech;

	switch(mRenderOptions)
	{
	case RenderOptions::Lighting:
		activeTech = Effects::BasicFX->Light3Tech;
		activeSkullTech = Effects::BasicFX->Light3Tech;
		break;
	case RenderOptions::Textures:
		activeTech = Effects::BasicFX->Light3TexTech;
		activeSkullTech = Effects::BasicFX->Light3Tech;
		break;
	case RenderOptions::TexturesAndFog:
		activeTech = Effects::BasicFX->Light3TexFogTech;
		activeSkullTech = Effects::BasicFX->Light3FogTech;
		break;
	}

	D3DX11_TECHNIQUE_DESC techDesc;

	//
	// Draw the floor and walls to the back buffer as normal.
	//
	
	activeTech->GetDesc( &techDesc );
	for(UINT p = 0; p < techDesc.Passes; ++p)
    {
		ID3DX11EffectPass* pass = activeTech->GetPassByIndex( p );

		md3dImmediateContext->IASetVertexBuffers(0, 1, &mRoomVB, &stride, &offset);

		// Set per object constants.
		XMMATRIX world = XMLoadFloat4x4(&mRoomWorld);
		XMMATRIX worldInvTranspose = MathHelper::InverseTranspose(world);
		XMMATRIX worldViewProj = world*view*proj;
		
		Effects::BasicFX->SetWorld(world);
		Effects::BasicFX->SetWorldInvTranspose(worldInvTranspose);
		Effects::BasicFX->SetWorldViewProj(worldViewProj);
		Effects::BasicFX->SetTexTransform(XMMatrixIdentity());
		Effects::BasicFX->SetMaterial(mRoomMat);

		// Floor
		Effects::BasicFX->SetDiffuseMap(mFloorDiffuseMapSRV);
		pass->Apply(0, md3dImmediateContext);
		md3dImmediateContext->Draw(6, 0);

		// Wall
		Effects::BasicFX->SetDiffuseMap(mWallDiffuseMapSRV);
		pass->Apply(0, md3dImmediateContext);
		md3dImmediateContext->Draw(18, 6);
	}

	//
	// Draw the skull to the back buffer as normal.
	//

	activeSkullTech->GetDesc( &techDesc );
	for(UINT p = 0; p < techDesc.Passes; ++p)
    {
		ID3DX11EffectPass* pass = activeSkullTech->GetPassByIndex( p );

		md3dImmediateContext->IASetVertexBuffers(0, 1, &mSkullVB, &stride, &offset);
		md3dImmediateContext->IASetIndexBuffer(mSkullIB, DXGI_FORMAT_R32_UINT, 0);

		XMMATRIX world = XMLoadFloat4x4(&mSkullWorld);
		XMMATRIX worldInvTranspose = MathHelper::InverseTranspose(world);
		XMMATRIX worldViewProj = world*view*proj;

		Effects::BasicFX->SetWorld(world);
		Effects::BasicFX->SetWorldInvTranspose(worldInvTranspose);
		Effects::BasicFX->SetWorldViewProj(worldViewProj);
		Effects::BasicFX->SetMaterial(mSkullMat);

		pass->Apply(0, md3dImmediateContext);
		md3dImmediateContext->DrawIndexed(mSkullIndexCount, 0, 0);
	}

	//
	// Draw the mirror to stencil buffer only.
	//

	activeTech->GetDesc( &techDesc );
	for(UINT p = 0; p < techDesc.Passes; ++p)
    {
		ID3DX11EffectPass* pass = activeTech->GetPassByIndex( p );

		md3dImmediateContext->IASetVertexBuffers(0, 1, &mRoomVB, &stride, &offset);

		// Set per object constants.
		XMMATRIX world = XMLoadFloat4x4(&mRoomWorld);
		XMMATRIX worldInvTranspose = MathHelper::InverseTranspose(world);
		XMMATRIX worldViewProj = world*view*proj;
		
		Effects::BasicFX->SetWorld(world);
		Effects::BasicFX->SetWorldInvTranspose(worldInvTranspose);
		Effects::BasicFX->SetWorldViewProj(worldViewProj);
		Effects::BasicFX->SetTexTransform(XMMatrixIdentity());

		// Do not write to render target.
		md3dImmediateContext->OMSetBlendState(RenderStates::NoRenderTargetWritesBS, blendFactor, 0xffffffff);

		// Render visible mirror pixels to stencil buffer.
		// Do not write mirror depth to depth buffer at this point, otherwise it will occlude the reflection.
		md3dImmediateContext->OMSetDepthStencilState(RenderStates::MarkMirrorDSS, 1);
		
		pass->Apply(0, md3dImmediateContext);
		md3dImmediateContext->Draw(6, 24);

		// Restore states.
		md3dImmediateContext->OMSetDepthStencilState(0, 0);
		md3dImmediateContext->OMSetBlendState(0, blendFactor, 0xffffffff);
	}


	//
	// Draw the skull reflection.
	//
	activeSkullTech->GetDesc( &techDesc );
	for(UINT p = 0; p < techDesc.Passes; ++p)
    {
		ID3DX11EffectPass* pass = activeSkullTech->GetPassByIndex( p );

		md3dImmediateContext->IASetVertexBuffers(0, 1, &mSkullVB, &stride, &offset);
		md3dImmediateContext->IASetIndexBuffer(mSkullIB, DXGI_FORMAT_R32_UINT, 0);

		XMVECTOR mirrorPlane = XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f); // xy plane
		XMMATRIX R = XMMatrixReflect(mirrorPlane);
		XMMATRIX world = XMLoadFloat4x4(&mSkullWorld) * R;
		XMMATRIX worldInvTranspose = MathHelper::InverseTranspose(world);
		XMMATRIX worldViewProj = world*view*proj;

		Effects::BasicFX->SetWorld(world);
		Effects::BasicFX->SetWorldInvTranspose(worldInvTranspose);
		Effects::BasicFX->SetWorldViewProj(worldViewProj);
		Effects::BasicFX->SetMaterial(mSkullMat);

		// Cache the old light directions, and reflect the light directions.
		XMFLOAT3 oldLightDirections[3];
		for(int i = 0; i < 3; ++i)
		{
			oldLightDirections[i] = mDirLights[i].Direction;

			XMVECTOR lightDir = XMLoadFloat3(&mDirLights[i].Direction);
			XMVECTOR reflectedLightDir = XMVector3TransformNormal(lightDir, R);
			XMStoreFloat3(&mDirLights[i].Direction, reflectedLightDir);
		}

		Effects::BasicFX->SetDirLights(mDirLights);

		// Cull clockwise triangles for reflection.
		md3dImmediateContext->RSSetState(RenderStates::CullClockwiseRS);

		// Only draw reflection into visible mirror pixels as marked by the stencil buffer. 
		md3dImmediateContext->OMSetDepthStencilState(RenderStates::DrawReflectionDSS, 1);
		pass->Apply(0, md3dImmediateContext);
		md3dImmediateContext->DrawIndexed(mSkullIndexCount, 0, 0);

		// Restore default states.
		md3dImmediateContext->RSSetState(0);	
		md3dImmediateContext->OMSetDepthStencilState(0, 0);	

		// Restore light directions.
		for(int i = 0; i < 3; ++i)
		{
			mDirLights[i].Direction = oldLightDirections[i];
		}

		Effects::BasicFX->SetDirLights(mDirLights);
	}

	//
	// Draw the mirror to the back buffer as usual but with transparency
	// blending so the reflection shows through.
	// 

	activeTech->GetDesc( &techDesc );
	for(UINT p = 0; p < techDesc.Passes; ++p)
    {
		ID3DX11EffectPass* pass = activeTech->GetPassByIndex( p );

		md3dImmediateContext->IASetVertexBuffers(0, 1, &mRoomVB, &stride, &offset);

		// Set per object constants.
		XMMATRIX world = XMLoadFloat4x4(&mRoomWorld);
		XMMATRIX worldInvTranspose = MathHelper::InverseTranspose(world);
		XMMATRIX worldViewProj = world*view*proj;
		
		Effects::BasicFX->SetWorld(world);
		Effects::BasicFX->SetWorldInvTranspose(worldInvTranspose);
		Effects::BasicFX->SetWorldViewProj(worldViewProj);
		Effects::BasicFX->SetTexTransform(XMMatrixIdentity());
		Effects::BasicFX->SetMaterial(mMirrorMat);
		Effects::BasicFX->SetDiffuseMap(mMirrorDiffuseMapSRV);

		// Mirror
		md3dImmediateContext->OMSetBlendState(RenderStates::TransparentBS, blendFactor, 0xffffffff);
		pass->Apply(0, md3dImmediateContext);
		md3dImmediateContext->Draw(6, 24);
	}

	//
	// Draw the skull shadow.
	//
	activeSkullTech->GetDesc( &techDesc );
	for(UINT p = 0; p < techDesc.Passes; ++p)
    {
		ID3DX11EffectPass* pass = activeSkullTech->GetPassByIndex( p );

		md3dImmediateContext->IASetVertexBuffers(0, 1, &mSkullVB, &stride, &offset);
		md3dImmediateContext->IASetIndexBuffer(mSkullIB, DXGI_FORMAT_R32_UINT, 0);

		XMVECTOR shadowPlane = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f); // xz plane
		XMVECTOR toMainLight = -XMLoadFloat3(&mDirLights[0].Direction);
		XMMATRIX S =  XMMatrixShadow(shadowPlane, toMainLight);
		XMMATRIX shadowOffsetY = XMMatrixTranslation(0.0f, 0.001f, 0.0f);

		// Set per object constants.
		XMMATRIX world = XMLoadFloat4x4(&mSkullWorld)*S*shadowOffsetY;
		XMMATRIX worldInvTranspose = MathHelper::InverseTranspose(world);
		XMMATRIX worldViewProj = world*view*proj;
		
		Effects::BasicFX->SetWorld(world);
		Effects::BasicFX->SetWorldInvTranspose(worldInvTranspose);
		Effects::BasicFX->SetWorldViewProj(worldViewProj);
		Effects::BasicFX->SetMaterial(mShadowMat);

		md3dImmediateContext->OMSetDepthStencilState(RenderStates::NoDoubleBlendDSS, 0);
		pass->Apply(0, md3dImmediateContext);
		md3dImmediateContext->DrawIndexed(mSkullIndexCount, 0, 0);

		// Restore default states.
		md3dImmediateContext->OMSetBlendState(0, blendFactor, 0xffffffff);
		md3dImmediateContext->OMSetDepthStencilState(0, 0);
	}

	HR(mSwapChain->Present(0, 0));
}
Пример #3
0
void SuperSolarSystemApp::DrawIceCube( )
{
	float blendFactor[] ={ 0.0f, 0.0f, 0.0f, 0.0f };
	ID3DX11EffectTechnique *activeTech;
	D3DX11_TECHNIQUE_DESC techDesc;

	//
	// 画冰立方, 仅将其渲染到模板缓冲
	//

	mD3dImmediateContext->IASetInputLayout( InputLayouts::NormalObjLayout );
	mD3dImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );

	activeTech = Effects::NormalObjFX->NormalObjTech;
	activeTech->GetDesc( &techDesc );

	UINT stride = sizeof( Vertex::NormalObjVertex );
	UINT offset = 0;
	mD3dImmediateContext->IASetVertexBuffers( 0, 1, &mLightTexVB, &stride, &offset );
	mD3dImmediateContext->IASetIndexBuffer( mLightTexIB, DXGI_FORMAT_R32_UINT, 0 );

	for ( UINT p = 0; p < techDesc.Passes; p++ )
	{
		XMMATRIX world             = XMLoadFloat4x4( &mWorld[ICECUBE] );
		XMMATRIX worldViewProj     = XMMatrixMultiply( world, mCamera.GetViewProj( ) );
		XMMATRIX worldInvTranspose = MathHelper::InverseTranspose( world );

		// 设置effect中的常量缓冲
		Effects::NormalObjFX->SetWorldViewProj( worldViewProj );
		Effects::NormalObjFX->SetWorld( world );
		Effects::NormalObjFX->SetWorldInvTranspose( worldInvTranspose );
		Effects::NormalObjFX->SetTexTransform( XMLoadFloat4x4( &mTexTransform[ICECUBE] ) );

		// 设置纹理和材质
		Effects::NormalObjFX->SetDiffuseMap( mDiffuseMapSRV[ICECUBE] );
		Effects::NormalObjFX->SetMaterial( mMat[ICECUBE] );

		// 禁止对缓冲目标写操作
		mD3dImmediateContext->OMSetBlendState( RenderStates::NoRenderTargetWritesBS,
			blendFactor, 0xffffffff );

		// 将镜子的可见像素渲染到模板缓冲
		// 但是不能将镜子的深度信息写到深度缓存, 否则将阻塞镜像

		// 这里将镜子可见像素的 stencil value 设置为1, 当做标记了镜子像素
		mD3dImmediateContext->OMSetDepthStencilState( RenderStates::MirrorDSS, 1 );

		activeTech->GetPassByIndex( p )->Apply( 0, mD3dImmediateContext );
		mD3dImmediateContext->DrawIndexed(
			mLTIndexCount[LTVT_ICECUBE],
			mLTIndexOffset[LTVT_ICECUBE],
			mLTVertexOffset[LTVT_ICECUBE]
			);

		//
		// 恢复措施
		//

		mD3dImmediateContext->OMSetDepthStencilState( 0, 0 );
		mD3dImmediateContext->OMSetBlendState( 0, blendFactor, 0xffffffff );
	}

	//
	// 画天体的镜像
	//

	stride = sizeof( Vertex::NormalObjVertex );
	offset = 0;
	mD3dImmediateContext->IASetVertexBuffers( 0, 1, &mLightTexVB, &stride, &offset );
	mD3dImmediateContext->IASetIndexBuffer( mLightTexIB, DXGI_FORMAT_R32_UINT, 0 );

	activeTech = Effects::NormalObjFX->NormalObjTech;
	activeTech->GetDesc( &techDesc );

	for ( UINT p = 0; p < techDesc.Passes; ++p )
	{
		// 对每一个冰面镜面确定成像内容
		for ( int planeID = 0; planeID < 6; planeID++ )
		{
			// 未经过世界坐标变换的镜面
			XMVECTOR mirrorPlane = XMVectorSet(
				mIceCubeNormals[planeID].x,
				mIceCubeNormals[planeID].y,
				mIceCubeNormals[planeID].z,
				1.0f
				);

			// 将平面依据世界矩阵做变换
			mirrorPlane = XMPlaneNormalize( mirrorPlane );
			mirrorPlane = XMPlaneTransform( mirrorPlane, MathHelper::InverseTranspose( XMLoadFloat4x4( &mWorld[ICECUBE] ) ) );

			XMMATRIX R = XMMatrixReflect( mirrorPlane );

			for ( int starID = SUN; starID < STARNUMBER; starID++ )
			{
				if ( ICECUBE == starID )
				{
					continue;
				}

				XMVECTOR target = XMVectorSet( mWorld[starID]._41, mWorld[starID]._42, mWorld[starID]._43, 1.0f );

				// 在镜子后面的物体不做镜像
				if ( MathHelper::PointPlanePosRelation( target, mirrorPlane ) == MathHelper::BEHIND_THE_PLANE )
				{
					continue;
				}

				// 设置转换矩阵
				XMMATRIX world             = XMLoadFloat4x4( &mWorld[starID] ) * R;
				XMMATRIX worldViewProj     = XMMatrixMultiply( world, mCamera.GetViewProj( ) );
				XMMATRIX worldInvTranspose = MathHelper::InverseTranspose( world );

				// 设置effect中的常量缓冲
				Effects::NormalObjFX->SetWorldViewProj( worldViewProj );
				Effects::NormalObjFX->SetWorld( world );
				Effects::NormalObjFX->SetWorldInvTranspose( worldInvTranspose );
				Effects::NormalObjFX->SetTexTransform( XMLoadFloat4x4( &mTexTransform[starID] ) );

				// 设置纹理和材质
				Effects::NormalObjFX->SetDiffuseMap( mDiffuseMapSRV[starID] );
				Effects::NormalObjFX->SetMaterial( mMat[starID] );

				// 设置RenderStates
				if ( WIREFENCE == starID )
				{
					mD3dImmediateContext->RSSetState( RenderStates::NoCullRS );
				}

				// 处理镜面反射的光线方向, 待解决

				// 改变正面的判定方式
				mD3dImmediateContext->RSSetState( RenderStates::CullClockwiseRS );

				// 只在模板缓冲中标记为可见的镜面像素中写入镜像信息
				mD3dImmediateContext->OMSetDepthStencilState( RenderStates::DrawReflectionDSS, 1 );

				activeTech->GetPassByIndex( p )->Apply( 0, mD3dImmediateContext );
				mD3dImmediateContext->DrawIndexed(
					mLTIndexCount[LTVT_STAR],
					mLTIndexOffset[LTVT_STAR],
					mLTVertexOffset[LTVT_STAR]
					);

				//
				// 恢复措施
				//

				mD3dImmediateContext->RSSetState( 0 );
				mD3dImmediateContext->OMSetDepthStencilState( 0, 0 );
			}
		}
	}

	//
	// 最后将冰立方渲染至背面缓存, 但是要经过 blending 透明化处理
	//

	mD3dImmediateContext->IASetInputLayout( InputLayouts::NormalObjLayout );
	mD3dImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );

	activeTech = Effects::NormalObjFX->NormalObjTech;
	activeTech->GetDesc( &techDesc );

	stride = sizeof( Vertex::NormalObjVertex );
	offset = 0;
	mD3dImmediateContext->IASetVertexBuffers( 0, 1, &mLightTexVB, &stride, &offset );
	mD3dImmediateContext->IASetIndexBuffer( mLightTexIB, DXGI_FORMAT_R32_UINT, 0 );

	for ( UINT p = 0; p < techDesc.Passes; p++ )
	{
		XMMATRIX world            = XMLoadFloat4x4( &mWorld[ICECUBE] );
		XMMATRIX worldViewProj    = XMMatrixMultiply( world, mCamera.GetViewProj( ) );
		XMMATRIX worldInvTranspose = MathHelper::InverseTranspose( world );

		// 设置effect中的常量缓冲
		Effects::NormalObjFX->SetWorldViewProj( worldViewProj );
		Effects::NormalObjFX->SetWorld( world );
		Effects::NormalObjFX->SetWorldInvTranspose( worldInvTranspose );
		Effects::NormalObjFX->SetTexTransform( XMLoadFloat4x4( &mTexTransform[ICECUBE] ) );

		// 设置纹理和材质
		Effects::NormalObjFX->SetDiffuseMap( mDiffuseMapSRV[ICECUBE] );
		Effects::NormalObjFX->SetMaterial( mMat[ICECUBE] );

		mD3dImmediateContext->OMSetBlendState( RenderStates::TransparentBS, blendFactor, 0xffffffff );

		activeTech->GetPassByIndex( p )->Apply( 0, mD3dImmediateContext );
		mD3dImmediateContext->DrawIndexed(
			mLTIndexCount[LTVT_ICECUBE],
			mLTIndexOffset[LTVT_ICECUBE],
			mLTVertexOffset[LTVT_ICECUBE]
			);

		//恢复设置
		mD3dImmediateContext->OMSetDepthStencilState( 0, 0 );
		mD3dImmediateContext->OMSetBlendState( 0, blendFactor, 0xffffffff );
	}
}
Пример #4
0
void ForwardRenderer::DrawScene()
{
    DrawShadowMap();

    RendererCore::Instance()->SetOriginalRenderTargetDepth();

    float blendFactor[] = { 0.0f, 0.0f, 0.0f, 0.0f };

    // Set constants
    XMMATRIX view = XMLoadFloat4x4( RendererCore::Instance()->GetView() );
    XMMATRIX proj = XMLoadFloat4x4( RendererCore::Instance()->GetProj() );

    XMMATRIX shadowTransform = XMLoadFloat4x4( &m_ShadowTransform );


    int iCount = m_vDrawElements.size();
    for ( int i = 0; i < iCount; ++i )
    {
        DrawElement* pElem = m_vDrawElements[i];
        if ( !pElem )
            continue;

        UINT stride = pElem->stride;
        UINT offset = pElem->offset;

        GetD3D11DeviceImmContext()->IASetInputLayout( pElem->m_pInputLayout );
        GetD3D11DeviceImmContext()->IASetPrimitiveTopology( pElem->ePrimitiveTopology );

        pElem->m_spShader->SetDirLight( m_DirLights[0] );
        pElem->m_spShader->SetDirLights( m_DirLights );
        pElem->m_spShader->SetPointLight( m_PointLight );
        pElem->m_spShader->SetSpotLight( m_SpotLight );
        pElem->m_spShader->SetEyePosW( RendererCore::Instance()->GetEyePosW() );
        pElem->m_spShader->SetFogStart( 15.0f );
        pElem->m_spShader->SetFogRange( 300.0f );
        pElem->m_spShader->SetFogColor( Colors::Silver );

        for ( auto itor = pElem->m_vecSubElement.begin(); itor != pElem->m_vecSubElement.end() ; ++itor )
        {
            ID3DX11EffectTechnique* pTech = pElem->m_spShader->GetTech( (*itor).m_iTechIndex );
            if ( !pTech )
                continue;


            ID3D11Buffer* pVB = pElem->m_spVB->GetVB();
            GetD3D11DeviceImmContext()->IASetVertexBuffers( 0, 1, &pVB, &stride, &offset );

            if ( pElem->m_spIB )
                GetD3D11DeviceImmContext()->IASetIndexBuffer( pElem->m_spIB->GetIB(), DXGI_FORMAT_R32_UINT, 0 );

            if ( pElem->m_pRasterS )
                GetD3D11DeviceImmContext()->RSSetState( pElem->m_pRasterS );
            if ( pElem->m_pBlendS )
                GetD3D11DeviceImmContext()->OMSetBlendState( pElem->m_pBlendS, blendFactor, 0xffffffff );
            if ( pElem->m_pDepthStencilS )
                GetD3D11DeviceImmContext()->OMSetDepthStencilState( pElem->m_pDepthStencilS, pElem->m_uiStencilRef );

            XMMATRIX world;
            XMFLOAT3 oldLightDirections;
            if ( pElem->m_bStencilReflect )
            {
                XMVECTOR mirrorPlane = XMVectorSet( 0.0f, 0.0f, 1.0f, 0.0f ); // xy plane
                XMMATRIX R = XMMatrixReflect( mirrorPlane );
                world = XMLoadFloat4x4( &pElem->m_vecSubElement[0].m_World ) * R;

                oldLightDirections = m_DirLights[0].Direction;

                XMVECTOR lightDir = XMLoadFloat3( &m_DirLights[0].Direction );
                XMVECTOR reflectedLightDir = XMVector3TransformNormal( lightDir, R );
                XMStoreFloat3( &m_DirLights[0].Direction, reflectedLightDir );

                //ÀӽùæÆí
                pElem->m_spShader->SetDirLight( m_DirLights[0] );
            }
            else if ( pElem->m_bShadowmap )
            {
                XMVECTOR shadowPlane = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f ); // xz plane
                XMVECTOR toMainLight = -XMLoadFloat3( &m_DirLights[0].Direction );
                XMMATRIX S = XMMatrixShadow( shadowPlane, toMainLight );
                XMMATRIX shadowOffsetY = XMMatrixTranslation( 0.0f, 0.001f, 0.0f );

                world = XMLoadFloat4x4( &pElem->m_vecSubElement[0].m_World )*S*shadowOffsetY;
            }
            else
            {
                world = XMLoadFloat4x4( &pElem->m_vecSubElement[0].m_World );
            }

            TexturePtr spDiffuseMap = (*itor).m_spDiffuseMap;
            TexturePtr spCubeMap = (*itor).m_spCubeMap;
            TexturePtr spNormalMap = (*itor).m_spNormalMap;
            TexturePtr spShadowMap = (*itor).m_spShadowMap;

            world = XMLoadFloat4x4( &(*itor).m_World );

            XMMATRIX worldInvTranspose = MathHelper::InverseTranspose( world );
            XMMATRIX viewProj = view*proj;
            XMMATRIX worldViewProj = world*view*proj;

            XMMATRIX texTransform = XMLoadFloat4x4( &(*itor).m_TexTransform );

            D3DX11_TECHNIQUE_DESC techDesc;
            pTech->GetDesc( &techDesc );

            for ( UINT p = 0; p < techDesc.Passes; ++p )
            {

                pElem->m_spShader->SetWorld( world );
                pElem->m_spShader->SetWorldViewProj( worldViewProj );
                pElem->m_spShader->SetViewProj( viewProj );
                pElem->m_spShader->SetWorldInvTranspose( worldInvTranspose );
                pElem->m_spShader->SetTexTransform( texTransform );
                pElem->m_spShader->SetShadowTransform( world*shadowTransform );
                pElem->m_spShader->SetMaterial( (*itor).m_mat );

                if ( spDiffuseMap )
                {
                    if ( !spDiffuseMap->IsArray() )
                        pElem->m_spShader->SetDiffuseMap( spDiffuseMap->GetSRV() );
                    else
                        pElem->m_spShader->SetDiffuseMapArray( spDiffuseMap->GetSRV() );
                }

                if ( spCubeMap )
                {
                    pElem->m_spShader->SetCubeMap( spCubeMap->GetSRV() );
                }

                if ( spNormalMap )
                {
                    pElem->m_spShader->SetNormalMap( spNormalMap->GetSRV() );
                }

                if ( spShadowMap )
                {
                    pElem->m_spShader->SetShadowMap( spShadowMap->GetSRV() );
                }

                pTech->GetPassByIndex( p )->Apply( 0, GetD3D11DeviceImmContext() );

                if ( pElem->m_bDrawIndex )
                {

                    GetD3D11DeviceImmContext()->DrawIndexed( (*itor).m_IndexCount, (*itor).m_StartIndexLocation, (*itor).m_BaseVertexLocation );
                }
                else
                {
                    GetD3D11DeviceImmContext()->Draw( (*itor).m_VertexCount, (*itor).m_StartVertexLocation );
                }
            }


            if ( pElem->m_bStencilReflect )
            {
                m_DirLights[0].Direction = oldLightDirections;
            }
        }
    }

    DrawScreenQuad();
}