/// <summary> /// End the modifier (This method is called by the DrawTarget) /// </summary> /// <param name="state"></param> public void End(DrawState state) { if (enabledBuffer) { state.PopPostCuller(); } if (cubes.Count > 0 || spheres.Count > 0) { state.PushCamera(camera); state.PushRenderState(); state.RenderState.DepthColourCull.DepthWriteEnabled = false; state.RenderState.AlphaBlend = AlphaBlendState.Alpha; Xen.Ex.Shaders.FillSolidColour shader = state.GetShader <Xen.Ex.Shaders.FillSolidColour>(); shader.FillColour = new Vector4(1, 1, 1, 0.25f); shader.Bind(state); GenCubeVS(state); GenSphereVS(state); Matrix mat; for (int i = 0; i < cubes.Count; i++) { mat = cubes[i]; state.PushWorldMatrix(ref mat); cubeVS.Draw(state, null, PrimitiveType.LineList); state.PopWorldMatrix(); } mat = Matrix.Identity; Vector4 v; for (int i = 0; i < spheres.Count; i++) { v = spheres[i]; mat.M11 = v.W; mat.M22 = v.W; mat.M33 = v.W; mat.M41 = v.X; mat.M42 = v.Y; mat.M43 = v.Z; state.PushWorldMatrix(ref mat); sphereVS.Draw(state, null, PrimitiveType.LineList); state.PopWorldMatrix(); } state.PopRenderState(); state.PopCamera(); } }
public void Draw(DrawState state) { state.PushWorldMatrix(ref worldMatrix); //ModelInstances automatically setup the default material shaders //Custom shaders can be used with model.SetShaderOverride(...) //ModelData stores accurate bounding box information //the ModelInstance uses this to cull the model if (model.CullTest(state)) { model.Draw(state); } state.PopWorldMatrix(); }
//draw all the instances //Note this class must be added after all the instances, to keep drawing in //the correct order. Otherwise instance culling may appear a frame delayed. public void Draw(DrawState state) { if (state.SupportsHardwareInstancing) { //get the instancing shader and bind it Shader.Tutorial16_Instance shader = state.GetShader <Shader.Tutorial16_Instance>(); shader.Bind(state); //in this case, Xen.Ex.Geometry.Sphere implements IDrawBatch - allowing drawing a batch easily //otherwise, a call to: //state.DrawBatch(Vertices, Indices, PrimitiveType, DrawCallback, instanceMatrices, instanceCount); //can be made (internally, the Sphere does exactly this) //the 'DrawCallback' parametre of the DrawBatch method is an optional delegate callback to cull //instances. In this case culling has already been done so it's not needed (it's null). //Note that MaterialShader also supports hardware instancing, and could be used //in place of the custom shader geometry.DrawBatch(state, null, instanceMatrices, instanceCount); } else { //bind the non-instancing version of the shader Shader.Tutorial16 shader = state.GetShader <Shader.Tutorial16>(); shader.Bind(state); //just draw the instances one by one (much slower) for (int i = 0; i < instanceCount; i++) { state.PushWorldMatrix(ref instanceMatrices[i]); geometry.Draw(state); state.PopWorldMatrix(); } } //reset the counter for the next frame instanceCount = 0; }
/// <summary></summary> /// <param name="state"></param> protected sealed override void DrawElement(DrawState state) { if (state.SupportsHardwareInstancing && instanceCount > HardwareInstancingMinimum) { Matrix identity = Matrix.Identity; state.PushWorldMatrix(ref identity); state.DrawBatch(vertices, indices, PrimitiveType.TriangleList, null, instances, instanceCount); state.PopWorldMatrix(); } else { Graphics2D.NonInstancingSprite shader = state.GetShader <Graphics2D.NonInstancingSprite>(); for (int i = 0; i < instanceCount; i += NonInstancingRenderCount) { int count = Math.Min(NonInstancingRenderCount, (instanceCount - i)); shader.Instances.SetArray(this.instances, i); this.verticesSI.Draw(state, this.indicesSI, PrimitiveType.TriangleList, 2 * count, 0, 0); } } }
//NEW CODE private void DrawBoundingBoxes(DrawState state) { //First, get the animated bone transforms of the model. //These transforms are in 'bone-space', not in world space. ReadOnlyArrayCollection <Transform> boneAnimationTransforms = model.GetAnimationController().GetTransformedBones(state); //Get a simple shader from Xen.Ex that fills a solid colour Xen.Ex.Shaders.FillSolidColour shader = state.GetShader <Xen.Ex.Shaders.FillSolidColour>(); shader.FillColour = Color.White.ToVector4(); shader.Bind(state); //push the render state... state.PushRenderState(); //disable back face culling state.RenderState.DepthColourCull.CullMode = CullMode.None; //set to wireframe state.RenderState.DepthColourCull.FillMode = FillMode.WireFrame; //loop through all the geometry data in the model.. //(note, the sample model has only 1 geometry instance) Xen.Ex.Graphics.Content.SkeletonData modelSkeleton = model.ModelData.Skeleton; Matrix matrix; int boxIndex = 0; foreach (Xen.Ex.Graphics.Content.MeshData meshData in model.ModelData.Meshes) { foreach (Xen.Ex.Graphics.Content.GeometryData geometry in meshData.Geometry) { //now loop through all bones used by this geometry for (int geometryBone = 0; geometryBone < geometry.BoneIndices.Length; geometryBone++) { //index of the bone (a piece of geometry may not use all the bones in the model) int boneIndex = geometry.BoneIndices[geometryBone]; //get the base transform of the bone (the transform when not animated) Transform boneTransform = modelSkeleton.BoneWorldTransforms[boneIndex]; //multiply the transform with the animation bone-local transform //it would be better to use Transform.Multiply() here to save data copying on the xbox boneTransform *= boneAnimationTransforms[boneIndex]; //Get the transform as a matrix boneTransform.GetMatrix(out matrix); //push the matrix state.PushWorldMatrix(ref matrix); //draw the box if (boundingBoxes[boxIndex].CullTest(state)) { boundingBoxes[boxIndex].Draw(state); } boxIndex++; //pop the world matrix state.PopWorldMatrix(); } } } //pop the render state state.PopRenderState(); }