private void DrawPushPopManual(DrawState state) { //manual render state, using Push/Pop render state //push the render state //pusing/popping the render state is *very* fast, no memory is allocated. Internally just 4 ints are assigned. state.PushRenderState(); //change the alpha blend state (and only the alpha blend state) manually... state.RenderState.AlphaBlend = new AlphaBlendState(); //set blending... state.RenderState.AlphaBlend.Enabled = true; state.RenderState.AlphaBlend.SourceBlend = Blend.SourceAlpha; state.RenderState.AlphaBlend.DestinationBlend = Blend.InverseSourceAlpha; //draw the sphere DrawGeometry(state); //pop the render state (sets the render stack back to the pushed state) state.PopRenderState(); }
public void Draw(DrawState state) { SetupShadowShader(state); //set render mode to shadow map state.PushDrawFlag(new ModelInstance.ShaderProviderFlag(this.shaderProvider)); state.PushDrawFlag(TutorialRenderMode.DrawShadow); //Push the shadow map camera as a post-culler. //This way, anything not within the frustum of the shadow map //camera will not be drawn with the shadow shader state.PushPostCuller(this.shadowMapTarget.Camera); //set an additive blending mode state.PushRenderState(); state.RenderState.AlphaBlend = AlphaBlendState.Additive; state.RenderState.DepthColourCull.DepthWriteEnabled = false; //draw the shadowed scene scene.Draw(state); state.PopRenderState(); state.PopPostCuller(); state.PopDrawFlag <TutorialRenderMode>(); state.PopDrawFlag <ModelInstance.ShaderProviderFlag>(); }
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(); }
/// <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(); } }
private void DrawPushPopStored(DrawState state) { //push render state and replace it with a precalculateed render state. //Note this sets *every* render state, not just alpha blending //this is the most efficient way to set the entire render state state.PushRenderState(ref alphaRenderState); //draw the sphere DrawGeometry(state); //pop the render state state.PopRenderState(); }
private void DrawPushPopStatic(DrawState state) { //use a static alpha blend render state, using Push/Pop render state //push the render state state.PushRenderState(); //change the alpha blend state (and only the alpha blend state) using a static blend state... //AlphaBlendState.Alpha is a static already setup with alpha blending state.RenderState.AlphaBlend = AlphaBlendState.Alpha; //draw the sphere DrawGeometry(state); //pop the render state state.PopRenderState(); }
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; }
//draws on CPU particle systems /// <summary> /// draws the particles from a CPU system /// </summary> protected override void DrawCpuParticles(DrawState state, Content.ParticleSystemTypeData particleType, uint particleCount, AlphaBlendState blendMode, Vector4[] positionSize, Vector4[] velocityRotation, Vector4[] colourData, Vector4[] userValues) { //this is very similar to the billboard drawer (see it for reference) Vector2 targetSize = state.DrawTarget.Size; state.PushRenderState(); state.RenderState.AlphaBlend = blendMode; state.RenderState.DepthColourCull.DepthWriteEnabled = false; Texture2D displayTexture = particleType.Texture ?? Xen.Ex.Material.WhiteTexture.GetTexture(state); BillboardParticles2DElement.GenerateBillboardVertices(state, ref this.vertices, ref this.indices); int count = (int)particleCount; DrawVelocityParticles_BillboardCpu shaderNoColour = null; DrawVelocityParticlesColour_BillboardCpu shaderColour = null; if (colourData != null) { shaderColour = state.GetShader <DrawVelocityParticlesColour_BillboardCpu>(); } else { shaderNoColour = state.GetShader <DrawVelocityParticles_BillboardCpu>(); } Vector2 velScale = new Vector2(velocityScale, 0); if (this.useRotationToScaleVelocityEffect) { velScale = new Vector2(0, velocityScale); } int drawn = 0; while (count > 0) { int drawCount; drawCount = Math.Min(count, 80); if (colourData != null) { shaderColour.PositionData.SetArray(positionSize, drawn); shaderColour.VelocityData.SetArray(velocityRotation, drawn); shaderColour.ColourData.SetArray(colourData, drawn); shaderColour.DisplayTexture = displayTexture; shaderColour.SetVelocityScale(ref velScale); shaderColour.Bind(state); } else { shaderNoColour.PositionData.SetArray(positionSize, drawn); shaderNoColour.VelocityData.SetArray(velocityRotation, drawn); shaderNoColour.DisplayTexture = displayTexture; shaderNoColour.SetVelocityScale(ref velScale); shaderNoColour.Bind(state); } vertices.Draw(state, indices, PrimitiveType.TriangleList, drawCount * 2, 0, 0); count -= drawCount; drawn += drawCount; } state.PopRenderState(); }
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(); } }
/// <summary> /// implements the method to draw gpu particles /// </summary> protected override void DrawGpuParticles(DrawState state, Content.ParticleSystemTypeData particleType, uint particleCount, AlphaBlendState blendMode, Texture2D positionTex, Texture2D velocityRotation, Texture2D colourTex, Texture2D userValues, bool usesUserValuesPositionBuffer) { Vector2 targetSize = state.DrawTarget.Size; state.PushRenderState(); state.RenderState.AlphaBlend = blendMode; state.RenderState.DepthColourCull.DepthWriteEnabled = false; //get the display texture, or a white texture if none exists Texture2D displayTexture = particleType.Texture ?? Xen.Ex.Material.WhiteTexture.GetTexture(state); //get / create the shared vertices and indices for drawing billboard particles BillboardParticles2DElement.GenerateBillboardVertices(state, ref vertices, ref indices); int count = (int)particleCount; //instances of the two possible shaders DrawVelocityBillboardParticles_GpuTex3D shaderNoColour = null; DrawVelocityBillboardParticlesColour_GpuTex3D shaderColour = null; //user variantes DrawVelocityBillboardParticles_GpuTex3D_UserOffset shaderNoColour_UO = null; DrawVelocityBillboardParticlesColour_GpuTex3D_UserOffset shaderColour_UO = null; float resolutionXF = (float)positionTex.Width; float resolutionYF = (float)positionTex.Height; Vector2 invTextureSize = new Vector2(1.0f / resolutionXF, 1.0f / resolutionYF); Matrix cameraMatrix; state.Camera.GetCameraMatrix(out cameraMatrix); Vector3 worldSpaceYAxis = new Vector3(cameraMatrix.M21, cameraMatrix.M22, cameraMatrix.M23); Vector2 velScale = new Vector2(velocityScale, 0); if (this.useRotationToScaleVelocityEffect) { velScale = new Vector2(0, velocityScale); } IShader shader; if (!usesUserValuesPositionBuffer) { if (colourTex != null) // does this particle system use colours? { //get the shader shaderColour = state.GetShader <DrawVelocityBillboardParticlesColour_GpuTex3D>(); //set the samplers shaderColour.PositionTexture = positionTex; shaderColour.ColourTexture = colourTex; shaderColour.VelocityTexture = velocityRotation; shaderColour.DisplayTexture = displayTexture; shaderColour.SetWorldSpaceYAxis(ref worldSpaceYAxis); shaderColour.SetVelocityScale(ref velScale); shader = shaderColour; } else { shaderNoColour = state.GetShader <DrawVelocityBillboardParticles_GpuTex3D>(); shaderNoColour.PositionTexture = positionTex; shaderNoColour.VelocityTexture = velocityRotation; shaderNoColour.DisplayTexture = displayTexture; shaderNoColour.SetWorldSpaceYAxis(ref worldSpaceYAxis); shaderNoColour.SetVelocityScale(ref velScale); shader = shaderNoColour; } } else { if (colourTex != null) // does this particle system use colours? { //get the shader shaderColour_UO = state.GetShader <DrawVelocityBillboardParticlesColour_GpuTex3D_UserOffset>(); //set the samplers shaderColour_UO.PositionTexture = positionTex; shaderColour_UO.ColourTexture = colourTex; shaderColour_UO.VelocityTexture = velocityRotation; shaderColour_UO.UserTexture = userValues; shaderColour_UO.DisplayTexture = displayTexture; shaderColour_UO.SetWorldSpaceYAxis(ref worldSpaceYAxis); shaderColour_UO.SetVelocityScale(ref velScale); shader = shaderColour_UO; } else { shaderNoColour_UO = state.GetShader <DrawVelocityBillboardParticles_GpuTex3D_UserOffset>(); shaderNoColour_UO.PositionTexture = positionTex; shaderNoColour_UO.VelocityTexture = velocityRotation; shaderNoColour_UO.UserTexture = userValues; shaderNoColour_UO.DisplayTexture = displayTexture; shaderNoColour_UO.SetWorldSpaceYAxis(ref worldSpaceYAxis); shaderNoColour_UO.SetVelocityScale(ref velScale); shader = shaderNoColour_UO; } } int drawn = 0; while (count > 0) { //draw upto vertices.Count / 4 (4 vertices per quad) int drawCount = Math.Min(count, vertices.Count / 4); //set the inverse texture size, and the start offset value, then bind the shader if (!usesUserValuesPositionBuffer) { if (colourTex != null) { shaderColour.InvTextureSizeOffset = new Vector3(invTextureSize, (float)drawn); } else { shaderNoColour.InvTextureSizeOffset = new Vector3(invTextureSize, (float)drawn); } } else { if (colourTex != null) { shaderColour_UO.InvTextureSizeOffset = new Vector3(invTextureSize, (float)drawn); } else { shaderNoColour_UO.InvTextureSizeOffset = new Vector3(invTextureSize, (float)drawn); } } //bind shader.Bind(state); //draw! vertices.Draw(state, indices, PrimitiveType.TriangleList, drawCount * 2, 0, 0); count -= drawCount; drawn += drawCount; } //and done. state.PopRenderState(); }
/// <summary> /// implements the method to draw cpu processed particles /// </summary> protected override void DrawCpuParticles(DrawState state, Content.ParticleSystemTypeData particleType, uint particleCount, AlphaBlendState blendMode, Vector4[] positionSize, Vector4[] velocityRotation, Vector4[] colourData, Vector4[] userValues) { //this is a bit more complex, but mostly the same as the GPU draw method Vector2 targetSize = state.DrawTarget.Size; state.PushRenderState(); state.RenderState.AlphaBlend = blendMode; state.RenderState.DepthColourCull.DepthWriteEnabled = false; Texture2D displayTexture = particleType.Texture ?? Xen.Ex.Material.WhiteTexture.GetTexture(state); BillboardParticles2DElement.GenerateBillboardVertices(state, ref this.vertices, ref this.indices); Matrix cameraMatrix; state.Camera.GetCameraMatrix(out cameraMatrix); Vector3 worldSpaceYAxis = new Vector3(cameraMatrix.M21, cameraMatrix.M22, cameraMatrix.M23); Vector2 velScale = new Vector2(velocityScale, 0); if (this.useRotationToScaleVelocityEffect) { velScale = new Vector2(0, velocityScale); } int count = (int)particleCount; DrawVelocityBillboardParticles_BillboardCpu3D shaderNoColour = null; DrawVelocityBillboardParticlesColour_BillboardCpu3D shaderColour = null; if (colourData != null) { shaderColour = state.GetShader <DrawVelocityBillboardParticlesColour_BillboardCpu3D>(); shaderColour.SetWorldSpaceYAxis(ref worldSpaceYAxis); shaderColour.SetVelocityScale(ref velScale); } else { shaderNoColour = state.GetShader <DrawVelocityBillboardParticles_BillboardCpu3D>(); shaderNoColour.SetWorldSpaceYAxis(ref worldSpaceYAxis); shaderNoColour.SetVelocityScale(ref velScale); } int drawn = 0; while (count > 0) { int drawCount; drawCount = Math.Min(count, 75); if (colourData != null) { shaderColour.PositionData.SetArray(positionSize, drawn); shaderColour.VelocityData.SetArray(velocityRotation, drawn); shaderColour.ColourData.SetArray(colourData, drawn); shaderColour.DisplayTexture = displayTexture; shaderColour.Bind(state); } else { shaderNoColour.PositionData.SetArray(positionSize, drawn); shaderNoColour.VelocityData.SetArray(velocityRotation, drawn); shaderNoColour.DisplayTexture = displayTexture; shaderNoColour.Bind(state); } vertices.Draw(state, indices, PrimitiveType.TriangleList, drawCount * 2, 0, 0); count -= drawCount; drawn += drawCount; } state.PopRenderState(); }
/// <summary> /// implements the method to draw cpu particles /// </summary> protected override void DrawCpuParticles(DrawState state, Content.ParticleSystemTypeData particleType, uint particleCount, AlphaBlendState blendMode, Vector4[] positionSize, Vector4[] velocityRotation, Vector4[] colourData, Vector4[] userValues) { //this is a bit more complex, but mostly the same as the GPU draw method Vector2 targetSize = state.DrawTarget.Size; state.PushRenderState(); state.RenderState.AlphaBlend = blendMode; state.RenderState.DepthColourCull.DepthWriteEnabled = false; Texture2D displayTexture = particleType.Texture ?? Xen.Ex.Material.WhiteTexture.GetTexture(state); GenerateBillboardVertices(state, ref this.vertices, ref this.indices); int count = (int)particleCount; DrawBillboardParticles_BillboardCpu shaderNoColour = null; DrawBillboardParticlesColour_BillboardCpu shaderColour = null; if (positionBuffer == null) { positionBuffer = GetPositionBuffer(state, positionBuffer); } if (colourData != null) { shaderColour = state.GetShader <DrawBillboardParticlesColour_BillboardCpu>(); } else { shaderNoColour = state.GetShader <DrawBillboardParticles_BillboardCpu>(); } int drawn = 0; while (count > 0) { int drawCount; drawCount = Math.Min(count, 120); //the only major difference from the GPU drawer is here for (int i = 0; i < drawCount; i++) { //copy position xy and w (size), and velocity.w (rotation) positionBuffer[i] = positionSize[drawn + i]; positionBuffer[i].Z = velocityRotation[drawn + i].W; } if (colourData != null) { shaderColour.PositionData.SetArray(positionBuffer, 0); shaderColour.ColourData.SetArray(colourData, drawn); shaderColour.DisplayTexture = displayTexture; shaderColour.Bind(state); } else { shaderNoColour.PositionData.SetArray(positionBuffer, 0); shaderNoColour.DisplayTexture = displayTexture; shaderNoColour.Bind(state); } vertices.Draw(state, indices, PrimitiveType.TriangleList, drawCount * 2, 0, 0); count -= drawCount; drawn += drawCount; } state.PopRenderState(); }
/// <summary> /// Draw the predicate, and if the predicate draws at least <see cref="MinimumPixelCount"/> pixels, the 'complex' object will be drawn /// </summary> /// <param name="state"></param> public void Draw(DrawState state) { int frame = state.FrameIndex; if (!supported || frame == frameIndex) { if (item.CullTest(state)) { item.Draw(state); } return; } if (resetOnCullChange && frameIndex != frame - 1) { //XNA requires IsComplete to be checked. if (query != null) { queryInProgress = query.IsComplete; } queryInProgress = false; //reset the query queryPixelCount = ushort.MaxValue; } if (queryInProgress && query.IsComplete) { queryInProgress = false; this.queryPixelCount = (ushort)query.PixelCount; } if (!queryInProgress) { GraphicsDevice device = state.BeginGetGraphicsDevice(Xen.Graphics.State.StateFlag.None); //run the query if (query == null) { query = new OcclusionQuery(device); if (query.IsSupported == false) { supported = false; query.Dispose(); query = null; if (item.CullTest(state)) { item.Draw(state); } return; } } query.Begin(); state.PushRenderState(); state.RenderState.DepthColourCull.DepthWriteEnabled = false; state.RenderState.DepthColourCull.ColourWriteMask = ColorWriteChannels.None; state.RenderState.AlphaBlend = new AlphaBlendState(); predicate.Draw(state); state.PopRenderState(); query.End(); queryInProgress = true; state.EndGetGraphicsDevice(); } frameIndex = frame; if (queryPixelCount >= pixelCount && item.CullTest(state)) { item.Draw(state); } }
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(); } }
/// <summary> /// draws the particles on a GPU system /// </summary> protected override void DrawGpuParticles(DrawState state, Content.ParticleSystemTypeData particleType, uint particleCount, AlphaBlendState blendMode, Texture2D positionTex, Texture2D velocityRotation, Texture2D colourTex, Texture2D userValues, bool usesUserValuesPositionBuffer) { //this is very similar to the billboard drawer (see it for reference) Vector2 targetSize = state.DrawTarget.Size; state.PushRenderState(); state.RenderState.AlphaBlend = blendMode; state.RenderState.DepthColourCull.DepthWriteEnabled = false; Texture2D displayTexture = particleType.Texture ?? Xen.Ex.Material.WhiteTexture.GetTexture(state); //get the shared vertice BillboardParticles2DElement.GenerateBillboardVertices(state, ref vertices, ref indices); int count = (int)particleCount; DrawVelocityParticles_GpuTex shaderNoColour = null; DrawVelocityParticlesColour_GpuTex shaderColour = null; //user variants DrawVelocityParticles_GpuTex_UserOffset shaderNoColour_UO = null; DrawVelocityParticlesColour_GpuTex_UserOffset shaderColour_UO = null; float resolutionXF = (float)positionTex.Width; float resolutionYF = (float)positionTex.Height; Vector2 invTextureSize; Vector2 velScale = new Vector2(velocityScale, 0); if (this.useRotationToScaleVelocityEffect) { velScale = new Vector2(0, velocityScale); } invTextureSize = new Vector2(1.0f / resolutionXF, 1.0f / resolutionYF); IShader shader; if (!usesUserValuesPositionBuffer) { if (colourTex != null) { shader = shaderColour = state.GetShader <DrawVelocityParticlesColour_GpuTex>(); shaderColour.PositionTexture = positionTex; shaderColour.ColourTexture = colourTex; shaderColour.VelocityTexture = velocityRotation; shaderColour.DisplayTexture = displayTexture; shaderColour.SetVelocityScale(ref velScale); } else { shader = shaderNoColour = state.GetShader <DrawVelocityParticles_GpuTex>(); shaderNoColour.PositionTexture = positionTex; shaderNoColour.VelocityTexture = velocityRotation; shaderNoColour.DisplayTexture = displayTexture; shaderNoColour.SetVelocityScale(ref velScale); } } else { if (colourTex != null) { shader = shaderColour_UO = state.GetShader <DrawVelocityParticlesColour_GpuTex_UserOffset>(); shaderColour_UO.PositionTexture = positionTex; shaderColour_UO.ColourTexture = colourTex; shaderColour_UO.VelocityTexture = velocityRotation; shaderColour_UO.UserTexture = userValues; shaderColour_UO.DisplayTexture = displayTexture; shaderColour_UO.SetVelocityScale(ref velScale); } else { shader = shaderNoColour_UO = state.GetShader <DrawVelocityParticles_GpuTex_UserOffset>(); shaderNoColour_UO.PositionTexture = positionTex; shaderNoColour_UO.VelocityTexture = velocityRotation; shaderNoColour_UO.UserTexture = userValues; shaderNoColour_UO.DisplayTexture = displayTexture; shaderNoColour_UO.SetVelocityScale(ref velScale); } } int drawn = 0; while (count > 0) { int drawCount = Math.Min(count, vertices.Count / 4); if (!usesUserValuesPositionBuffer) { if (colourTex != null) { shaderColour.TextureSizeOffset = new Vector3(invTextureSize, (float)drawn); } else { shaderNoColour.TextureSizeOffset = new Vector3(invTextureSize, (float)drawn); } } else { if (colourTex != null) { shaderColour_UO.TextureSizeOffset = new Vector3(invTextureSize, (float)drawn); } else { shaderNoColour_UO.TextureSizeOffset = new Vector3(invTextureSize, (float)drawn); } } //bind shader.Bind(state); vertices.Draw(state, indices, PrimitiveType.TriangleList, drawCount * 2, 0, 0); count -= drawCount; drawn += drawCount; } state.PopRenderState(); }
//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> /// draws the particles from a CPU system /// </summary> protected override void DrawCpuParticles(DrawState state, Content.ParticleSystemTypeData particleType, uint particleCount, AlphaBlendState blendMode, Vector4[] positionSize, Vector4[] velocityRotation, Vector4[] colourData, Vector4[] userValues) { Vector2 targetSize = state.DrawTarget.Size; state.PushRenderState(); state.RenderState.AlphaBlend = blendMode; state.RenderState.DepthColourCull.DepthWriteEnabled = false; VelocityLineParticles2DElement.GenerateLinesVertices(state, ref this.vertices); int count = (int)particleCount; DrawVelocityParticles_LinesCpu shaderNoColour = null; DrawVelocityParticlesColour_LinesCpu shaderColour = null; if (colourData != null) { shaderColour = state.GetShader <DrawVelocityParticlesColour_LinesCpu>(); } else { shaderNoColour = state.GetShader <DrawVelocityParticles_LinesCpu>(); } Vector2 velScale = new Vector2(velocityScale, 0); if (this.useRotationToScaleVelocityEffect) { velScale = new Vector2(0, velocityScale); } int drawn = 0; while (count > 0) { int drawCount; drawCount = Math.Min(count, 80); if (colourData != null) { shaderColour.PositionData.SetArray(positionSize, drawn); shaderColour.VelocityData.SetArray(velocityRotation, drawn); shaderColour.ColourData.SetArray(colourData, drawn); shaderColour.SetVelocityScale(ref velScale); shaderColour.Bind(state); } else { shaderNoColour.PositionData.SetArray(positionSize, drawn); shaderNoColour.VelocityData.SetArray(velocityRotation, drawn); shaderNoColour.SetVelocityScale(ref velScale); shaderNoColour.Bind(state); } vertices.Draw(state, null, PrimitiveType.LineList, drawCount, 0, 0); count -= drawCount; drawn += drawCount; } state.PopRenderState(); }