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; } }
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)); }
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 ); } }
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(); }