private static BlendState _CreateBlendState(DrawSystem.D3DData d3d, DrawSystem.RenderMode mode) { switch (mode) { case DrawSystem.RenderMode.Opaque: { var blendDesc = BlendStateDescription.Default(); return(new BlendState(d3d.Device, blendDesc)); } case DrawSystem.RenderMode.Transparency: { var blendDesc = new BlendStateDescription() { AlphaToCoverageEnable = false, IndependentBlendEnable = false, }; blendDesc.RenderTarget[0] = new RenderTargetBlendDescription(true, BlendOption.SourceAlpha, BlendOption.InverseSourceAlpha, BlendOperation.Add, BlendOption.One, BlendOption.Zero, BlendOperation.Add, ColorWriteMaskFlags.All); return(new BlendState(d3d.Device, blendDesc)); } default: return(null); } }
virtual public void DrawModel(Matrix worldTrans, Color4 color, DrawSystem.MeshData mesh, MaterialBase material, DrawSystem.RenderMode renderMode, Matrix[] boneMatrices) { _SetModelParams(mesh, material, renderMode); // update vertex shader resouce var vdata = new _VertexShaderConst_Main() { // hlsl is column-major memory layout, so we must transpose matrix worldMat = Matrix.Transpose(worldTrans), }; m_context.UpdateSubresource(ref vdata, m_mainVtxConst); // update pixel shader resouce var pdata = new _PixelShaderConst_Main() { instanceColor = color }; m_context.UpdateSubresource(ref pdata, m_mainPixConst); // update a bone constant buffer if (boneMatrices != null) { // UpdateSubresouce supports only to upate entire of resource. // so, we must copy boneMatrices to m_tmpBoneMatrices. // It seems inefficient. we search for better solutions. Debug.Assert(boneMatrices.Length <= m_tmpBoneMatrices.Length); for (int i = 0; i < boneMatrices.Length; ++i) { m_tmpBoneMatrices[i] = boneMatrices[i]; m_tmpBoneMatrices[i].Transpose(); } m_context.UpdateSubresource <Matrix>(m_tmpBoneMatrices, m_boneVtxConst); } else { // low performance @todo for (int i = 0; i < m_tmpBoneMatrices.Length; ++i) { m_tmpBoneMatrices[i] = Matrix.Identity; } m_context.UpdateSubresource <Matrix>(m_tmpBoneMatrices, m_boneVtxConst); } // draw m_context.Draw(mesh.VertexCount, 0); m_drawCallCount++; }
private void _SetModelParams(DrawSystem.MeshData mesh, MaterialBase material, DrawSystem.RenderMode renderMode) { // update texture slot DrawSystem.TextureData tex; bool bModelPixConstChanged = false; for (int index = 0; index < m_lastTextureSlots.Count(); ++index) { int slotIndex = m_lastTextureSlots[index].SlotIndex; if (material == null) { tex = DrawSystem.TextureData.Null(); } else { material.GetTextureDataBySlotIndex(slotIndex, out tex); } // update resouce if (m_lastTextureSlots[index].Texture.Resource != tex.Resource) { // update resource if (tex.Resource != null) { m_context.PixelShader.SetShaderResource(slotIndex, tex.Resource.View); m_context.PixelShader.SetSampler(slotIndex, tex.Resource.SamplerState); } else { // set null texture m_context.PixelShader.SetShaderResource(slotIndex, null); m_context.PixelShader.SetSampler(slotIndex, null); } m_lastTextureSlots[index].Texture.Resource = tex.Resource; } // update texture uv scale if (!m_lastTextureSlots[index].Texture.UvScale.Equals(tex.UvScale)) { bModelPixConstChanged = true; m_lastTextureSlots[index].Texture.UvScale = tex.UvScale; } } if (bModelPixConstChanged) { var modelPixConst = new _PixelShaderConst_Model() { uvScale1 = m_lastTextureSlots[0].Texture.UvScale, uvScale2 = m_lastTextureSlots[1].Texture.UvScale, }; m_context.UpdateSubresource(ref modelPixConst, m_modelPixConst); } // update model vertex shader param bool isEnableSkinning = mesh.Buffers.Count() == 3; if (m_lastEnableSkinning == null || !m_lastEnableSkinning.Value.Equals(isEnableSkinning)) { var modelVtxConst = new _VertexShaderConst_Model() { isEnableSkinning = isEnableSkinning, }; m_context.UpdateSubresource(ref modelVtxConst, m_modelVtxConst); m_lastEnableSkinning = isEnableSkinning; } // update material MaterialBase.MaterialTypes materialType = material == null ? MaterialBase.MaterialTypes.Debug : material.Type; if (m_materialType == null || m_materialType != materialType) { switch (materialType) { case MaterialBase.MaterialTypes.Standard: { Effect effect = null; effect = m_initParam.Repository.FindResource <Effect>("Std"); m_context.InputAssembler.InputLayout = effect.Layout; m_context.VertexShader.Set(effect.VertexShader); m_context.PixelShader.Set(effect.PixelShader); } break; case MaterialBase.MaterialTypes.Minimap: { Effect effect = null; effect = m_initParam.Repository.FindResource <Effect>("Minimap"); m_context.InputAssembler.InputLayout = effect.Layout; m_context.VertexShader.Set(effect.VertexShader); m_context.PixelShader.Set(effect.PixelShader); // update material shader param var mtl = material as MinimapMaterial; m_context.PixelShader.SetConstantBuffer(3, m_modelMinimapPixConst); var tmpConst = new _PixelShaderConst_ModelMinimap(); tmpConst.width = mtl.GetMapWidth(); tmpConst.height = mtl.GetMapHeight(); int[] mapTable = mtl.GetMapTable(); unsafe { // copy map table Marshal.Copy(mapTable, 0, new IntPtr(tmpConst.map), tmpConst.width * tmpConst.height); } m_context.UpdateSubresource(ref tmpConst, m_modelMinimapPixConst); } break; case MaterialBase.MaterialTypes.Debug: { Effect effect = null; effect = m_initParam.Repository.FindResource <Effect>("Debug"); m_context.InputAssembler.InputLayout = effect.Layout; m_context.VertexShader.Set(effect.VertexShader); m_context.PixelShader.Set(effect.PixelShader); } break; case MaterialBase.MaterialTypes.Marker: Debug.Assert(false, "unsupported material"); break; } m_materialType = materialType; } // update render mode if (m_lastRenderMode == null || m_lastRenderMode != renderMode) { m_context.OutputMerger.BlendState = m_initParam.BlendStates[(int)renderMode]; m_context.OutputMerger.DepthStencilState = m_initParam.DepthStencilStates[(int)renderMode]; m_lastRenderMode = renderMode; } // update input assembler if (m_lastTopology == null || m_lastTopology != mesh.Topology) { m_context.InputAssembler.PrimitiveTopology = mesh.Topology; m_lastTopology = mesh.Topology; } if (m_lastVertexBuffers == null || m_lastVertexBuffers != mesh.Buffers) { m_context.InputAssembler.SetVertexBuffers(0, mesh.Buffers); m_lastVertexBuffers = mesh.Buffers; m_lastVertexCount = mesh.VertexCount; } }
virtual public void BeginDrawInstance(DrawSystem.MeshData mesh, MaterialBase material, DrawSystem.RenderMode renderMode) { Debug.Assert(material.IsEnableInstanceRendering(), "this material does not support instance rendering"); _SetModelParams(mesh, material, renderMode); }
virtual public void DrawDebugModel(Matrix worldTrans, DrawSystem.MeshData mesh, DrawSystem.RenderMode renderMode) { _SetModelParams(mesh, null, renderMode); // update vertex shader resouce { var vdata = new _VertexShaderConst_Main() { // hlsl is column-major memory layout, so we must transpose matrix worldMat = Matrix.Transpose(worldTrans), }; m_context.UpdateSubresource(ref vdata, m_mainVtxConst); } // update pixel shader resouce { var pdata = new _PixelShaderConst_Main() { instanceColor = Color4.White, }; m_context.UpdateSubresource(ref pdata, m_mainPixConst); } // do not use bone matrices // m_context.UpdateSubresource<Matrix>(m_tmpBoneMatrices, m_boneVtxConst); // draw m_context.Draw(mesh.VertexCount, 0); m_drawCallCount++; }
public void BeginDrawInstance(DrawSystem.MeshData mesh, MaterialBase material, DrawSystem.RenderMode renderMode) { m_isContextDirty = true; m_context.BeginDrawInstance(mesh, material, renderMode); }
public void DrawDebugModel(Matrix worldTrans, DrawSystem.MeshData mesh, DrawSystem.RenderMode renderMode) { m_isContextDirty = true; m_context.DrawDebugModel(worldTrans, mesh, renderMode); }
public void DrawModel(Matrix worldTrans, Color4 color, DrawSystem.MeshData mesh, MaterialBase material, DrawSystem.RenderMode renderMode, Matrix[] boneMatrices) { m_isContextDirty = true; m_context.DrawModel(worldTrans, color, mesh, material, renderMode, boneMatrices); }
private static DepthStencilState _CreateDepthStencilState(DrawSystem.D3DData d3d, DrawSystem.RenderMode mode) { switch (mode) { case DrawSystem.RenderMode.Opaque: { return(new DepthStencilState(d3d.Device, new DepthStencilStateDescription() { BackFace = new DepthStencilOperationDescription() { // Stencil operations if pixel is back-facing DepthFailOperation = StencilOperation.Decrement, FailOperation = StencilOperation.Keep, PassOperation = StencilOperation.Keep, Comparison = SharpDX.Direct3D11.Comparison.Always, }, FrontFace = new DepthStencilOperationDescription() { // Stencil operations if pixel is front-facing DepthFailOperation = StencilOperation.Increment, FailOperation = StencilOperation.Keep, PassOperation = StencilOperation.Keep, Comparison = SharpDX.Direct3D11.Comparison.Always, }, IsDepthEnabled = true, IsStencilEnabled = false, StencilReadMask = 0xff, StencilWriteMask = 0xff, DepthComparison = Comparison.Less, DepthWriteMask = DepthWriteMask.All, })); } case DrawSystem.RenderMode.Transparency: { return(new DepthStencilState(d3d.Device, new DepthStencilStateDescription() { BackFace = new DepthStencilOperationDescription() { // Stencil operations if pixel is back-facing DepthFailOperation = StencilOperation.Decrement, FailOperation = StencilOperation.Keep, PassOperation = StencilOperation.Keep, Comparison = SharpDX.Direct3D11.Comparison.Always, }, FrontFace = new DepthStencilOperationDescription() { // Stencil operations if pixel is front-facing DepthFailOperation = StencilOperation.Increment, FailOperation = StencilOperation.Keep, PassOperation = StencilOperation.Keep, Comparison = SharpDX.Direct3D11.Comparison.Always, }, IsDepthEnabled = false, // disable depth IsStencilEnabled = false, StencilReadMask = 0xff, StencilWriteMask = 0xff, DepthComparison = Comparison.Less, DepthWriteMask = DepthWriteMask.All, })); } default: return(null); } }