/// <summary> /// Renders the mesh with the specified transformation. This alternate render method /// supplements the base class rendering to provide part-by-part texturing support. /// </summary> /// <param name="modelTransform"></param> public void Render(Matrix3D modelTransform) { // setup rasterization RasterizerDescription rasterizerDescription = new RasterizerDescription() { FillMode = FillMode.Solid, CullMode = CullMode.Back, FrontCounterclockwise = false, DepthBias = 0, DepthBiasClamp = 0, SlopeScaledDepthBias = 0, DepthClipEnable = true, ScissorEnable = false, MultisampleEnable = true, AntiAliasedLineEnable = true }; try { solidRasterizerState = this.manager.device.CreateRasterizerState(rasterizerDescription); rasterizerDescription.FillMode = FillMode.Wireframe; wireframeRasterizerState = this.manager.device.CreateRasterizerState(rasterizerDescription); base.Render(modelTransform.ToMatrix4x4F()); } finally { if (solidRasterizerState != null) { solidRasterizerState.Dispose(); solidRasterizerState = null; } if (wireframeRasterizerState != null) { wireframeRasterizerState.Dispose(); wireframeRasterizerState = null; } currentRasterizerState = null; } }
private void RenderPart(Part part, Matrix3D parentMatrix, ShaderResourceView parentTextureOverride) { // set part transform Transform3DGroup partGroup = new Transform3DGroup(); partGroup.Children.Add(new MatrixTransform3D(PartAnimation(part.name))); partGroup.Children.Add(new MatrixTransform3D(part.partTransform.ToMatrix3D())); partGroup.Children.Add(new MatrixTransform3D(parentMatrix)); parentMatrix = partGroup.Value; ShaderResourceView textureOverride = UpdateRasterizerStateForPart(part); if (textureOverride == null) { textureOverride = parentTextureOverride; } else { parentTextureOverride = textureOverride; } if (part.vertexBuffer != null) { EffectTechnique technique; if (textureOverride != null) { technique = this.manager.techniqueRenderTexture; this.manager.diffuseVariable.Resource = textureOverride; } else if (part.material == null) { technique = this.manager.techniqueRenderVertexColor; } else { if (part.material.textureResource != null) { technique = this.manager.techniqueRenderTexture; this.manager.diffuseVariable.Resource = part.material.textureResource; } else { technique = this.manager.techniqueRenderMaterialColor; this.manager.materialColorVariable.FloatVector = part.material.materialColor; } } this.manager.worldVariable.Matrix = parentMatrix.ToMatrix4x4F(); //set up vertex buffer and index buffer uint stride = (uint)Marshal.SizeOf(typeof(XMeshVertex)); uint offset = 0; this.manager.device.IA.SetVertexBuffers(0, new D3DBuffer[] { part.vertexBuffer }, new uint[] { stride }, new uint[] { offset }); //Set primitive topology this.manager.device.IA.PrimitiveTopology = PrimitiveTopology.TriangleList; TechniqueDescription techDesc = technique.Description; for (uint p = 0; p < techDesc.Passes; ++p) { technique.GetPassByIndex(p).Apply(); PassDescription passDescription = technique.GetPassByIndex(p).Description; using (InputLayout inputLayout = this.manager.device.CreateInputLayout( part.dataDescription, passDescription.InputAssemblerInputSignature, passDescription.InputAssemblerInputSignatureSize)) { // set vertex layout this.manager.device.IA.InputLayout = inputLayout; // draw part this.manager.device.Draw((uint)part.vertexCount, 0); // Note: In Direct3D 10, the device will not retain a reference // to the input layout, so it's important to reset the device's // input layout before disposing the object. Were this code // using Direct3D 11, the device would in fact retain a reference // and so it would be safe to go ahead and dispose the input // layout without resetting it; in that case, there could be just // a single assignment to null outside the 'for' loop, or even // no assignment at all. this.manager.device.IA.InputLayout = null; } } } foreach (Part childPart in part.parts) { RenderPart(childPart, parentMatrix, parentTextureOverride); } }