/// <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.PushWorldMatrixMultiply(ref worldMatrix); //cull test the sphere if (sphereGeometry.CullTest(state)) { //NEW CODE //compute a scale value that follows a sin wave float scaleValue = (float)Math.Sin(state.TotalTimeSeconds) * 0.5f + 1.0f; //the shader class has been generated in the namespace 'Shader', because the filename is 'shader.fx'. //The only technique in the file is named 'Tutorial03Technique'. //The class that was generated is Shader.Tutorial03Technique: Shader.Tutorial03Technique shader = null; //It is recommended to use the draw state to get a shared static instance of the shader. //Getting shader instances in this way is highly recommended for most shaders, as it reduces //memory usage and live object count. This will boost performance in large projects. shader = state.GetShader <Shader.Tutorial03Technique>(); //Set the scale value (scale is declared in the shader source) shader.Scale = scaleValue; //Bind the custom shader instance //After the call to Bind(), the shader is in use. There is no Begin/End logic required for shaders shader.Bind(state); //draw the sphere geometry sphereGeometry.Draw(state); } state.PopWorldMatrix(); }
public void Draw(DrawState state) { state.PushWorldTranslateMultiply(ref this.position); if (geometry.CullTest(state)) { //draw the geometry shader.Bind(state); geometry.Draw(state); //now, if set, draw the wireframe too if (wireframeShader != null) { wireframeShader.Bind(state); //show the wireframe, disabling depth testing state.PushRenderState(); state.RenderState.DepthColourCull.DepthTestEnabled = false; //also set additive blending state.RenderState.AlphaBlend = AlphaBlendState.Additive; //set wireframe state.RenderState.DepthColourCull.FillMode = FillMode.WireFrame; //draw geometry.Draw(state); state.PopRenderState(); } } state.PopWorldMatrix(); }
public void Draw(DrawState state) { state.PushWorldTranslateMultiply(ref position); DrawSphere(state); state.PopWorldMatrix(); }
public void Draw(DrawState state) { state.PushWorldMatrixMultiply(ref this.worldMatrix); model.Draw(state); state.PopWorldMatrix(); }
public void Draw(DrawState state) { //generate the rotation matrix for the object. Matrix basis = new Matrix(1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1); //xna_dude model is on his side state.PushWorldMatrixMultiply(ref basis); Matrix.CreateRotationZ(RotationAngle, out basis); // generate the rotation. state.PushWorldMatrixMultiply(ref basis); if (item.CullTest(state)) { item.Draw(state); } state.PopWorldMatrix(); state.PopWorldMatrix(); }
public void Draw(DrawState state) { //draw the particles (cull test has passed) state.PushWorldMatrixMultiply(ref worldMatrix); this.particleDrawer.Draw(state); state.PopWorldMatrix(); }
public void Draw(DrawState state) { state.PushWorldTranslateMultiply(ref translation); //add the instance parent.AddInstance(state); state.PopWorldMatrix(); }
public void Draw(DrawState state) { state.PushWorldMatrixMultiply(ref this.worldMatrix); if (instance.CullTest(state)) { instance.Draw(state); } state.PopWorldMatrix(); }
public void Draw(DrawState state) { //make sure the world matrix is up to date UpdateWorldMatrix(); //draw the model state.PushWorldMatrixMultiply(ref this.worldMatrix); model.Draw(state); state.PopWorldMatrix(); }
public void Draw(DrawState state) { //scale the mesh Matrix scaleMatrix; Matrix.CreateScale(this.scale, out scaleMatrix); state.PushWorldMatrixMultiply(ref worldMatrix); state.PushWorldMatrixMultiply(ref scaleMatrix); //setup blending state.PushRenderState(); state.RenderState.DepthColourCull.CullMode = CullMode.None; state.RenderState.AlphaBlend = AlphaBlendState.AdditiveSaturate; state.RenderState.DepthColourCull.DepthWriteEnabled = false; //draw Xen.Ex.Shaders.FillVertexColour shader = state.GetShader <Xen.Ex.Shaders.FillVertexColour>(); shader.Bind(state); vertices.Draw(state, null, PrimitiveType.TriangleFan); state.PopRenderState(); state.PopWorldMatrix(); state.PopWorldMatrix(); //this is a hack :-) //flicker the scale //every so often, target a new scale if (random.Next(100) > 75) { scaleTarget = (float)random.NextDouble() * 0.4f + 0.6f; } //interpolate to the scale target this.scale = this.scale * 0.75f + this.scaleTarget * 0.25f; }
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(); }
public void Draw(DrawState state) { //push the world matrix, multiplying by the current matrix if there is one state.PushWorldMatrixMultiply(ref worldMatrix); //cull test the custom geometry if (geometry.CullTest(state)) { //bind the shader shader.Bind(state); //draw the custom geometry geometry.Draw(state); } //always pop the matrix afterwards 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; }
//draw the sphere private void DrawGeometry(DrawState state) { //animate the material alpha.. (in a sin wave btween 0 and 1) shader.Alpha = (float)Math.Sin(state.TotalTimeSeconds * 2) * 0.5f + 0.5f; //push the world matrix, multiplying by the current matrix if there is one state.PushWorldMatrixMultiply(ref this.worldMatrix); //cull test the sphere if (sphereGeometry.CullTest(state)) { //bind the shader shader.Bind(state); //draw the sphere geometry sphereGeometry.Draw(state); } //always pop the matrix afterwards state.PopWorldMatrix(); }
//draw the sphere (This is the method declared in the IDraw interface) public void Draw(DrawState state) { //the DrawState object controls current drawing state for the application. //The DrawState uses a number of stacks, it is important to understand how pushing/popping a stack works. //First, push the world matrix, multiplying by the current matrix (if there is one). //This is very similar to using openGL glPushMatrix() and then glMultMatrix(). //The DrawState object maintains the world matrix stack, pushing and popping this stack is very fast. state.PushWorldMatrixMultiply(ref this.worldMatrix); //The next line frustum cull tests the sphere //Culltest will return false if the test fails (in this case false would mean the sphere is off screen) //The CullTest method requirs an ICuller to be passed in. Here the state object is used because the //DrawState object implements the ICuller interface (DrawState's culler performs screen culling) //The cull test uses the current world matrix, so make sure you perform the CullTest after applying any //transformations. //The CullTest method is defined by the ICullable interface. Any IDraw object also implements ICullable. if (sphereGeometry.CullTest(state)) { //the sphere is on screen... //bind the shader. //Note that if the sphere was off screen, the shader would never be bound, //which would save valuable CPU time. (The sphere geometry class assumes a shader is bound) //This is why the CullTest() method is separate from the Draw() method. shader.Bind(state); //Once the call to Bind() has been made, the shaders will be active ('bound') //on the graphics card. There is no way to 'unbind' or 'end' the shader. //Once bound, that shader is in use - until the point a different shader is bound. //draw the sphere geometry sphereGeometry.Draw(state); } //always pop the world matrix afterwards state.PopWorldMatrix(); }
/// <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); } } }
private void Draw(DrawState state, Vector2 scale, byte clipDepth) { Element parent = this.parent; Matrix matrix; GraphicsDevice device = null; if (parent == null) { if (state.DrawTarget.MultiSampleType != MultiSampleType.None) { device = state.BeginGetGraphicsDevice(StateFlag.None); device.RenderState.MultiSampleAntiAlias = false; } this.clipTestActive = false; DeviceRenderState rstate = new DeviceRenderState(); rstate.DepthColourCull.DepthWriteEnabled = false; rstate.DepthColourCull.DepthTestEnabled = false; state.PushRenderState(ref rstate); if (camera == null) { camera = state.UserValues[cameraID] as Xen.Camera.Camera2D; if (camera == null) { camera = new Xen.Camera.Camera2D(true); state.UserValues[cameraID] = camera; } } state.PushCamera(camera); } else { this.clipTestActive = parent.clipTestActive | parent.ClipsChildren; } StencilTestState stencilState = new StencilTestState(); if (clipTestActive) { stencilState.Enabled = true; stencilState.ReferenceValue = clipDepth; stencilState.StencilFunction = CompareFunction.Equal; stencilState.StencilPassOperation = StencilOperation.Keep; } bool clearStencil = false; if (this.ClipsChildren) { clearStencil = clipDepth == 255; clipDepth--; if (!clipTestActive) { //check there actually is a stencil buffer #if DEBUG DepthFormat format = state.DrawTarget.SurfaceDepthFormat ?? DepthFormat.Unknown; if (format != DepthFormat.Depth24Stencil8) { throw new InvalidOperationException("ElementRect.ClipChildren requires the DrawTarget has a valid Depth Buffer with an 8bit Stencil Buffer"); } #endif stencilState.Enabled = true; stencilState.ReferenceValue = clipDepth; stencilState.StencilPassOperation = StencilOperation.Replace; } else { stencilState.StencilPassOperation = StencilOperation.Decrement; } } if ((scale.X != 0 && scale.Y != 0)) { Vector2 size = ElementSize; GetDisplayMatrix(out matrix, scale, ref size); state.PushWorldMatrixMultiply(ref matrix); BindShader(state, false); state.RenderState.AlphaBlend = blend; state.RenderState.StencilTest = stencilState; if (!UseSize) { size = new Vector2(1, 1); } else if (IsNormalised) { size *= scale; } PreDraw(size); DrawElement(state); List <Element> children = Children; if (children != null) { foreach (Element child in children) { if (((IDraw)child).CullTest(state)) { child.Draw(state, size, clipDepth); } } } if (clearStencil) { BindShader(state, true); stencilState = new StencilTestState(); stencilState.Enabled = true; stencilState.StencilFunction = CompareFunction.Never; stencilState.StencilFailOperation = StencilOperation.Zero; state.RenderState.StencilTest = stencilState; DrawElement(state); } state.PopWorldMatrix(); } if (parent == null) { state.PopRenderState(); state.PopCamera(); } if (device != null) { device.RenderState.MultiSampleAntiAlias = true; state.EndGetGraphicsDevice(); } }
public void Render(DrawState state, byte clipDepth) { Element parent = _parent; Matrix matrix; DeviceContext context = state.Context; if (parent == null) { _clipTest = false; DeviceRenderState rstate = new DeviceRenderState(); rstate.DepthColourCull.DepthWriteEnabled = false; rstate.DepthColourCull.DepthTestEnabled = false; state.PushRenderState(ref rstate); if (_camera == null) { _camera = new ElementCamera(true); } state.PushCamera(_camera); } else { _clipTest = parent._clipTest | parent.ClipsChildren; } StencilTestState stencilState = new StencilTestState(); if (_clipTest) { stencilState.Enabled = true; stencilState.ReferenceValue = clipDepth; stencilState.StencilFunction = Compare.Equal; stencilState.StencilPassOperation = StencilOperation.Keep; } bool clearStencil = false; if (ClipsChildren) { clearStencil = clipDepth == 255; clipDepth--; if (!_clipTest) { stencilState.Enabled = true; stencilState.ReferenceValue = clipDepth; stencilState.StencilPassOperation = StencilOperation.Replace; } else { stencilState.StencilPassOperation = StencilOperation.Decrement; } } Viewport viewport = context.Viewport; Vector2 scale = new Vector2(viewport.Width, viewport.Height); if ((scale.X != 0 && scale.Y != 0)) { Vector2 size = ElementSize; GetDisplayMatrix(out matrix, scale, ref size); state.PushWorldMatrixMultiply(ref matrix); BindShader(state, false); state.RenderState.AlphaBlend = _blendState; state.RenderState.StencilTest = stencilState; if (!UseSize) { size = new Vector2(1, 1); } else if (IsNormalised) { size.X *= scale.X; size.Y *= scale.Y; } PreDraw(state.Context, size); DrawElement(state); List <Element> children = Children; if (children != null) { foreach (Element child in children) { if (child.CullTest(state)) { child.Render(state, clipDepth); } } } if (clearStencil) { BindShader(state, true); stencilState = new StencilTestState(); stencilState.Enabled = true; stencilState.StencilFunction = Compare.Never; stencilState.StencilFailOperation = StencilOperation.Zero; state.RenderState.StencilTest = stencilState; DrawElement(state); } state.PopWorldMatrix(); } if (parent == null) { state.PopRenderState(); state.PopCamera(); } }
//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(); }
/// <summary> /// Draw all the model batch instances /// </summary> /// <param name="state"></param> public void Draw(DrawState state) { if (modelData == null) { throw new InvalidOperationException("ModelData is null"); } if (geometry == null) { SetupGeometry(); } int geometryIndex = 0; BatchModelShaderProvider shaderProvider = this.shaderProvider; MaterialLightCollection lights = this.lights; ShaderProviderFlag providerFlag; MaterialLightCollection.LightCollectionFlag lightsFlag; state.GetDrawFlag(out providerFlag); if (providerFlag.OverrideShaderProvider) { shaderProvider = providerFlag.ShaderProvider; } state.GetDrawFlag(out lightsFlag); if (lightsFlag.OverrideLightCollection) { lights = lightsFlag.LightCollection; } if (shaderProvider != null) { shaderProvider.BeginDraw(state); } //loop through the model data for (int m = 0; m < modelData.meshes.Length; m++) { MeshData mesh = modelData.meshes[m]; if (shaderProvider != null) { shaderProvider.BeginMesh(state, mesh); } for (int g = 0; g < mesh.geometry.Length; g++) { GeometryData geom = mesh.geometry[g]; GeometrySet set = this.geometry[geometryIndex]; if (set.count > 0) { bool instancing = state.SupportsHardwareInstancing && set.count > 2; if (shaderProvider == null || !shaderProvider.BeginGeometryShaderOverride(state, geom, lights, instancing)) { MaterialShader shader = geom.MaterialShader; shader.AnimationTransforms = null; shader.UseHardwareInstancing = instancing; shader.Lights = lights; shader.Bind(state); } //draw the geometry if (instancing) { state.DrawBatch(geom.Vertices, geom.Indices, PrimitiveType.TriangleList, null, set.instances, set.count); } else { for (int i = 0; i < set.count; i++) { state.PushWorldMatrixMultiply(ref set.instances[i]); geom.Vertices.Draw(state, geom.Indices, PrimitiveType.TriangleList); state.PopWorldMatrix(); } } if (shaderProvider != null) { shaderProvider.EndGeometry(state, geom); } } set.count = 0; geometryIndex++; } if (shaderProvider != null) { shaderProvider.EndMesh(state, mesh); } } if (shaderProvider != null) { shaderProvider.EndDraw(state); } drawCount = 0; }