public void Draw(DrawState state) { //switch rendering mode based on the TutorialRenderMode flag switch (state.GetDrawFlag <TutorialRenderMode>()) { case TutorialRenderMode.DepthOutput: //bind the depth output shader state.GetShader <Xen.Ex.Shaders.NonLinearDepthOutRg>().Bind(state); break; case TutorialRenderMode.DrawShadow: //bind the shadow rendering shader Shader.ShadowShader shader = state.GetShader <Shader.ShadowShader>(); shader.TextureMap = material.TextureMap; shader.TextureSampler = material.TextureMapSampler; shader.Bind(state); break; default: //no flag known specified material.Bind(state); break; } //draw the ground vertices.Draw(state, null, PrimitiveType.TriangleFan); }
private void SetupShadowShader(DrawState state) { ICamera shadowCamera = this.shadowMapTarget.Camera; //compute the view*projection matrix for the shadow map camera... Matrix view, projection, viewProjection; shadowCamera.GetViewMatrix(out view); shadowCamera.GetProjectionMatrix(out projection, this.shadowMapTarget.Size); Matrix.Multiply(ref view, ref projection, out viewProjection); //and the view direction Vector3 viewDirection; shadowCamera.GetCameraViewDirection(out viewDirection); //set the matrix and other constants in the shadow mapping shader instances Shader.ShadowShader shader = state.GetShader <Shader.ShadowShader>(); Shader.ShadowShaderBlend shaderBlend = state.GetShader <Shader.ShadowShaderBlend>(); //non-blending shader shader.ShadowMap = this.shadowMapTarget.GetTexture(); shader.SetShadowMapProjection(ref viewProjection); shader.SetShadowViewDirection(ref viewDirection); //setup the same constants for the blending shader shaderBlend.ShadowMap = this.shadowMapTarget.GetTexture(); shaderBlend.SetShadowMapProjection(ref viewProjection); shaderBlend.SetShadowViewDirection(ref viewDirection); }
protected override void BindShader(DrawState state, bool maskOnly) { Xen.Ex.Graphics2D.Statistics.DrawGraphLine shader = state.GetShader <Xen.Ex.Graphics2D.Statistics.DrawGraphLine>(); if (dirty) { float x = widthScale; for (int i = 0; i < graphData.Length; i++) { int index = (i + this.index) % graphData.Length; float good = 0; if (goodValue != 0) { good = values[index]; good = (good - Math.Abs(goodValue)) / goodValue; } graphData[i] = new Vector4(x, values[index] * maxValueInv, 0, good); x += widthScale; } dirty = false; } shader.SetGraphLine(this.graphData); shader.Bind(state); }
protected override IShader BindShader(DrawState state, bool maskOnly) { Xen.Ex.Graphics2D.Statistics.DrawGraphLine shader = state.GetShader<Xen.Ex.Graphics2D.Statistics.DrawGraphLine>(); if (dirty) { float x = widthScale; for (int i = 0; i < graphData.Length; i++) { int index = (i + this.index) % graphData.Length; float good = 0; if (goodValue != 0) { good = values[index]; good = (good - Math.Abs(goodValue)) / goodValue; } graphData[i] = new Vector4(x, values[index] * maxValueInv, 0, good); x += widthScale; } dirty = false; } shader.GraphLine = this.graphData; return shader; }
protected override void BindShader(DrawState state, bool maskOnly) { SimpleTextureEffect shader = state.GetShader <SimpleTextureEffect>(); shader.Texture = _texture; shader.Bind(state); }
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) { //bind the background filling shader state.GetShader <Shaders.BackgroundFill>().Bind(state); geometry.Draw(state); }
/// <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) { Xen.Ex.Shaders.FillSolidColour shader = state.GetShader <Xen.Ex.Shaders.FillSolidColour>(); shader.FillColour = colour; shader.Bind(state); vertices.Draw(state, null, PrimitiveType.TriangleStrip); }
public void Combine(DrawState state) { CombineShader shader = state.GetShader <CombineShader>(); shader.WorldTexture = _worldRenderTarget; shader.UITexture = _uiRenderTarget; shader.Bind(state); _vertices.Draw(state, null, PrimitiveType.TriangleStrip); }
//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; }
private void DrawSphere(DrawState state) { //draw the geometry with a solid colour shader if (geometry.CullTest(state)) { Xen.Ex.Shaders.FillSolidColour shader = state.GetShader <Xen.Ex.Shaders.FillSolidColour>(); shader.FillColour = lightColour.ToVector4(); shader.Bind(state); geometry.Draw(state); } }
private void Render(DrawState state) { SimpleTextureEffect shader = state.GetShader <SimpleTextureEffect>(); state.PushCamera(camera); shader.Texture = _texture; shader.Bind(state); _vertices.Draw(state, null, PrimitiveType.TriangleStrip); state.PopCamera(); }
/// <summary></summary> /// <param name="state"></param> /// <param name="maskOnly"></param> protected override void BindShader(DrawState state, bool maskOnly) { if (this.texture == null && textureSource != null) { Texture2D tex = textureSource.GetTexture(); if (tex == null) { throw new InvalidOperationException("TexturedElement is trying to use a DrawTargetTexture2D that hasn't been drawn (DrawTargetTexture2D.GetTexture() is null)"); } this.Texture = tex; } FillCustomTexture shader = state.GetShader <FillCustomTexture>(); shader.CustomTexture = texture; shader.CustomTextureSampler = usePointFilter ? pointFilter : bilinearFilter; shader.Bind(state); }
private void DrawLifeAgeToStore(DrawState state) { //both copying and adding are treated the same way //just draw the life / age values directly int copyIndex = 0; while (activeRenderPass.LifeCount - copyIndex > 0) { ParticleStoreLife128 shader = state.GetShader <ParticleStoreLife128>(); shader.InvTargetSize = new Vector2(1.0f / resolutionXF, 1.0f / resolutionYF); shader.Indices128.SetArray(activeRenderPass.LifeData, copyIndex); shader.Bind(state); verticesRenderIndex.Draw(state, null, PrimitiveType.PointList, Math.Min(128, activeRenderPass.LifeCount - copyIndex), 0, 0); copyIndex += 128; } }
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; }
/// <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); } } }
//draws on CPU particle systems /// <summary> /// draws the particles from a CPU system /// </summary> protected override void DrawCpuParticles(DrawState state, Xen.Ex.Graphics.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; using (state.RenderState.Push()) { state.RenderState.CurrentBlendState = blendMode; state.RenderState.CurrentDepthState.DepthWriteEnabled = false; Texture2D displayTexture = particleType.Texture; BillboardParticles2DElement.GenerateBillboardVertices(state, ref this.vertices, ref this.indices); int count = (int)particleCount; DrawVelocityParticles_BillboardCpu shaderNoColour = null; DrawVelocityParticlesColour_BillboardCpu shaderColour = null; Vector2 velScale = new Vector2(velocityScale, 0); if (this.useRotationToScaleVelocityEffect) velScale = new Vector2(0, velocityScale); if (colourData != null) { shaderColour = state.GetShader<DrawVelocityParticlesColour_BillboardCpu>(); shaderColour.DisplayTexture = displayTexture; shaderColour.SetVelocityScale(ref velScale); } else { shaderNoColour = state.GetShader<DrawVelocityParticles_BillboardCpu>(); shaderNoColour.DisplayTexture = displayTexture; shaderNoColour.SetVelocityScale(ref velScale); } int drawn = 0; while (count > 0) { int drawCount; drawCount = Math.Min(count, 80); IShader shader = null; if (colourData != null) { shaderColour.SetPositionData(positionSize, (uint)drawn, 0, (uint)drawCount); shaderColour.SetVelocityData(velocityRotation, (uint)drawn, 0, (uint)drawCount); shaderColour.SetColourData(colourData, (uint)drawn, 0, (uint)drawCount); shader = shaderColour; } else { shaderNoColour.SetPositionData(positionSize, (uint)drawn, 0, (uint)drawCount); shaderNoColour.SetVelocityData(velocityRotation, (uint)drawn, 0, (uint)drawCount); shader = shaderNoColour; } using (state + shader) vertices.Draw(state, indices, PrimitiveType.TriangleList, drawCount * 2, 0, 0); count -= drawCount; drawn += drawCount; } } }
/// <summary></summary> /// <param name="state"></param> /// <param name="maskOnly"></param> protected override sealed void BindShader(DrawState state, bool maskOnly) { if (this.vertices == null) { this.vertices = state.UserValues[GetType().FullName + ".vertices"] as IVertices; this.indices = state.UserValues[GetType().FullName + ".indices"] as Indices <ushort>; this.verticesSI = state.UserValues[GetType().FullName + ".verticesSI"] as IVertices; this.indicesSI = state.UserValues[GetType().FullName + ".indicesSI"] as Indices <ushort>; if (this.vertices == null) { //still null, create the global vertices this.vertices = new Vertices <Vector4>( new Vector4(0, 0, 0, 1), new Vector4(1, 0, 0, 1), new Vector4(1, 1, 0, 1), new Vector4(0, 1, 0, 1)); this.indices = new Indices <ushort>(0, 2, 1, 0, 3, 2); //shader instancing.. List <InstanceVertex> verts = new List <InstanceVertex>(); List <ushort> inds = new List <ushort>(); for (int i = 0; i < NonInstancingRenderCount; i++) { verts.Add(new InstanceVertex(new Vector3(0, 0, 0), (float)i)); verts.Add(new InstanceVertex(new Vector3(1, 0, 0), (float)i)); verts.Add(new InstanceVertex(new Vector3(1, 1, 0), (float)i)); verts.Add(new InstanceVertex(new Vector3(0, 1, 0), (float)i)); inds.Add((ushort)(0 + i * 4)); inds.Add((ushort)(2 + i * 4)); inds.Add((ushort)(1 + i * 4)); inds.Add((ushort)(0 + i * 4)); inds.Add((ushort)(3 + i * 4)); inds.Add((ushort)(2 + i * 4)); } this.verticesSI = new Vertices <InstanceVertex>(verts.ToArray()); this.indicesSI = new Indices <ushort>(inds.ToArray()); state.UserValues[GetType().FullName + ".vertices"] = vertices; state.UserValues[GetType().FullName + ".indices"] = indices; state.UserValues[GetType().FullName + ".verticesSI"] = verticesSI; state.UserValues[GetType().FullName + ".indicesSI"] = indicesSI; } } if (state.SupportsHardwareInstancing && instanceCount > HardwareInstancingMinimum) { Graphics2D.InstancingSprite shader = state.GetShader <Graphics2D.InstancingSprite>(); Matrix world; state.GetWorldMatrix(out world); shader.SetSpriteWorldMatrix(ref world); shader.CustomTexture = texture ?? Xen.Ex.Material.WhiteTexture.GetTexture(state); shader.Bind(state); } else { Graphics2D.NonInstancingSprite shader = state.GetShader <Graphics2D.NonInstancingSprite>(); shader.CustomTexture = texture ?? Xen.Ex.Material.WhiteTexture.GetTexture(state); shader.Bind(state); } }
//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(); }
/// <summary> /// <para>implements the method to draw cpu particles</para> /// </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.RenderState.Push(); state.RenderState.CurrentBlendState = blendMode; state.RenderState.CurrentDepthState.DepthWriteEnabled = false; Texture2D displayTexture = particleType.Texture ?? state.Properties.WhiteTexture; 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); int count = (int)particleCount; DrawBillboardParticles_BillboardCpu3D shaderNoColour = null; DrawBillboardParticlesColour_BillboardCpu3D shaderColour = null; if (colourData != null) { shaderColour = state.GetShader<DrawBillboardParticlesColour_BillboardCpu3D>(); shaderColour.SetWorldSpaceYAxis(ref worldSpaceYAxis); } else { shaderNoColour = state.GetShader<DrawBillboardParticles_BillboardCpu3D>(); shaderNoColour.SetWorldSpaceYAxis(ref worldSpaceYAxis); } int drawn = 0; while (count > 0) { int drawCount; drawCount = Math.Min(count, 75); uint drawCountU = (uint)drawCount; uint drawnU = (uint)drawn; if (colourData != null) { shaderColour.SetPositionData(positionSize, drawnU, 0, drawCountU); shaderColour.SetVelocityData(velocityRotation, drawnU, 0, drawCountU); shaderColour.SetColourData(colourData, drawnU,0,drawCountU); shaderColour.DisplayTexture = displayTexture; state.Shader.Push(shaderColour); } else { shaderNoColour.SetPositionData(positionSize, drawnU, 0, drawCountU); shaderNoColour.SetVelocityData(velocityRotation, drawnU, 0, drawCountU); shaderNoColour.DisplayTexture = displayTexture; state.Shader.Push(shaderNoColour); } vertices.Draw(state, indices, PrimitiveType.TriangleList, drawCount * 2, 0, 0); state.Shader.Pop(); count -= drawCount; drawn += drawCount; } state.RenderState.Pop(); }
/// <summary></summary> /// <param name="state"></param> protected sealed override void DrawElement(DrawState state) { if (state.Properties.SupportsHardwareInstancing && instanceCount > HardwareInstancingMinimum) { using (state.WorldMatrix.PushIdentity()) { vertices.DrawInstances(state, indices, PrimitiveType.TriangleList, state.GetDynamicInstanceBuffer(this.instances, this.instanceCount)); } } else { Graphics2D.NonInstancingSprite shader = state.GetShader<Graphics2D.NonInstancingSprite>(); for (int i = 0; i < instanceCount; i += NonInstancingRenderCount) { int count = Math.Min(NonInstancingRenderCount, (instanceCount - i)); shader.SetInstances(this.instances, (uint)i, 0, (uint)count); this.verticesSI.Draw(state, this.indicesSI, PrimitiveType.TriangleList, 2 * count, 0, 0); } } }
//this is called just before geometry is drawn, //return true to indicate the shader has been set public override bool BeginGeometryShaderOverride(DrawState state, GeometryData geometry, Xen.Ex.Material.MaterialLightCollection lights) { //query the draw flag, switch (state.GetDrawFlag <TutorialRenderMode>()) { case TutorialRenderMode.DrawShadow: { //bind the shadow rendering shader... if (animationBoneData == null) { Shader.ShadowShader shader = state.GetShader <Shader.ShadowShader>(); shader.TextureMap = geometry.MaterialShader.TextureMap; shader.TextureSampler = geometry.MaterialShader.TextureMapSampler; shader.Bind(state); } else { //bind the animating shader, Shader.ShadowShaderBlend shader = state.GetShader <Shader.ShadowShaderBlend>(); //set the blend matrix data if (animationBoneDataDirty) { //use the 'animationBoneDataDirty' bool so animation data is only copied once. //this could happen if a single model has many pieces of geometry. shader.SetBlendMatrices(animationBoneData); animationBoneDataDirty = false; } shader.TextureMap = geometry.MaterialShader.TextureMap; shader.TextureSampler = geometry.MaterialShader.TextureMapSampler; shader.Bind(state); } return(true); //shader was assigned } case TutorialRenderMode.DepthOutput: { //determine if alpha test is being used (in this tutorial it won't be - but do it anyway...) bool alphaTest = state.RenderState.AlphaTest.Enabled; if (alphaTest) { //alpha test is only needed if a texture is set alphaTest &= geometry.MaterialShader.TextureMap != null; } if (alphaTest) { //bind a depth output shader that samples a texture for alpha (for alpha test compatibility) if (this.animationBoneData != null) { //the model is animated //get the shader Xen.Ex.Shaders.NonLinearDepthOutRgTextureAlphaBlend shader = state.GetShader <Xen.Ex.Shaders.NonLinearDepthOutRgTextureAlphaBlend>(); //set animation data (it's possible this is called redundantly, so logic here could be improved) if (animationBoneDataDirty) { shader.SetBlendMatrices(this.animationBoneData); animationBoneDataDirty = false; } //set the texture shader.AlphaTexture = geometry.MaterialShader.TextureMap; shader.AlphaTextureSampler = geometry.MaterialShader.TextureMapSampler; //bind shader.Bind(state); } else { //get the shader Xen.Ex.Shaders.NonLinearDepthOutRgTextureAlpha shader = state.GetShader <Xen.Ex.Shaders.NonLinearDepthOutRgTextureAlpha>(); //set the texture shader.AlphaTexture = geometry.MaterialShader.TextureMap; shader.AlphaTextureSampler = geometry.MaterialShader.TextureMapSampler; shader.Bind(state); // bind the basic depth out shader } } else { //bind a simple depth output shader if (this.animationBoneData != null) { //the model is animated Xen.Ex.Shaders.NonLinearDepthOutRgBlend shader = state.GetShader <Xen.Ex.Shaders.NonLinearDepthOutRgBlend>(); //set animation data (it's possible this is called redundantly, so logic here could be improved) if (animationBoneDataDirty) { shader.SetBlendMatrices(this.animationBoneData); animationBoneDataDirty = false; } //bind shader.Bind(state); } else { state.GetShader <Xen.Ex.Shaders.NonLinearDepthOutRg>().Bind(state); // bind the basic depth out shader } } return(true); //shader was assigned } } //false, because no shader has been bound (will use the model material shader) return(false); }
/// <summary></summary> /// <param name="state"></param> /// <param name="maskOnly"></param> protected override void BindShader(DrawState state, bool maskOnly) { state.GetShader <Shaders.FillVertexColour>().Bind(state); }
/// <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> /// End the modifier (This method is called by the DrawTarget) /// </summary> /// <param name="state"></param> public void End(DrawState state) { if (enabledBuffer) state.Cullers.PopPostCuller(); this.cameras = null; if (cubes.Count > 0 || spheres.Count > 0) { Xen.Ex.Shaders.FillSolidColour shader = state.GetShader<Xen.Ex.Shaders.FillSolidColour>(); shader.FillColour = new Vector4(1,1,1,0.25f); using (state.RenderState.Push()) using (state.Shader.Push(shader)) using (state.Camera.Push()) { ICamera camera = state.Camera.GetCamera(); state.RenderState.CurrentDepthState.DepthWriteEnabled = false; state.RenderState.CurrentDepthState.DepthTestEnabled = EnableDepthTesting; state.RenderState.CurrentBlendState = AlphaBlendState.Alpha; GenCubeVS(state); GenSphereVS(state); Matrix mat; for (int i = 0; i < cubes.Count; i++) { mat = cubes[i].Matrix; if (camera != cubes[i].Camera) { camera = cubes[i].Camera; state.Camera.SetCamera(camera); } using (state.WorldMatrix.Push(ref mat)) { cubeVS.Draw(state, null, PrimitiveType.LineList); } } mat = Matrix.Identity; for (int i = 0; i < spheres.Count; i++) { Vector3 v = spheres[i].Position; float scale = spheres[i].Radius; if (camera != spheres[i].Camera) { camera = spheres[i].Camera; state.Camera.SetCamera(camera); } mat.M11 = scale; mat.M22 = scale; mat.M33 = scale; mat.M41 = v.X; mat.M42 = v.Y; mat.M43 = v.Z; using (state.WorldMatrix.Push(ref mat)) { sphereVS.Draw(state, null, PrimitiveType.LineList); } } } } spheres.Clear(); cubes.Clear(); }
protected override void BindShader(DrawState state, bool maskOnly) { SimpleTextureEffect shader = state.GetShader<SimpleTextureEffect>(); shader.Texture = _texture; shader.Bind(state); }
/// <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.RenderState.Push(); state.RenderState.CurrentBlendState = blendMode; state.RenderState.CurrentDepthState.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); uint drawCountU = (uint)drawCount; uint drawnU = (uint)drawn; if (colourData != null) { shaderColour.SetPositionData(positionSize, drawnU, 0, drawCountU); shaderColour.SetVelocityData(velocityRotation, drawnU, 0, drawCountU); shaderColour.SetColourData(colourData, drawnU, 0, drawCountU); shaderColour.SetVelocityScale(ref velScale); state.Shader.Push(shaderColour); } else { shaderNoColour.SetPositionData(positionSize, drawnU, 0, drawCountU); shaderNoColour.SetVelocityData(velocityRotation, drawnU, 0, drawCountU); shaderNoColour.SetVelocityScale(ref velScale); state.Shader.Push(shaderNoColour); } vertices.Draw(state, null, PrimitiveType.LineList, drawCount, 0, 0); state.Shader.Pop(); count -= drawCount; drawn += drawCount; } state.RenderState.Pop(); }
/// <summary> /// draws the particles on a GPU system /// </summary> protected override void DrawGpuParticles(DrawState state, Xen.Ex.Graphics.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) using (state.RenderState.Push()) { state.RenderState.CurrentBlendState = blendMode; state.RenderState.CurrentDepthState.DepthWriteEnabled = false; Texture2D displayTexture = particleType.Texture; //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 using (state.Shader.Push(shader)) vertices.Draw(state, indices, PrimitiveType.TriangleList, drawCount * 2, 0, 0); count -= drawCount; drawn += drawCount; } } }
/// <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) { Vector2 targetSize = state.DrawTarget.Size; state.RenderState.Push(); state.RenderState.CurrentBlendState = blendMode; state.RenderState.CurrentDepthState.DepthWriteEnabled = false; //get the shared vertice VelocityLineParticles2DElement.GenerateLinesVertices(state, ref vertices); int count = (int)particleCount; DrawVelocityParticles_LinesGpuTex shaderNoColour = null; DrawVelocityParticlesColour_LinesGpuTex shaderColour = null; //user variants DrawVelocityParticles_LinesGpuTex_UserOffset shaderNoColour_UO = null; DrawVelocityParticlesColour_LinesGpuTex_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_LinesGpuTex>(); shaderColour.PositionTexture = positionTex; shaderColour.ColourTexture = colourTex; shaderColour.VelocityTexture = velocityRotation; shaderColour.SetVelocityScale(ref velScale); } else { shader = shaderNoColour = state.GetShader<DrawVelocityParticles_LinesGpuTex>(); shaderNoColour.PositionTexture = positionTex; shaderNoColour.VelocityTexture = velocityRotation; shaderNoColour.SetVelocityScale(ref velScale); } } else { if (colourTex != null) { shader = shaderColour_UO = state.GetShader<DrawVelocityParticlesColour_LinesGpuTex_UserOffset>(); shaderColour_UO.PositionTexture = positionTex; shaderColour_UO.ColourTexture = colourTex; shaderColour_UO.VelocityTexture = velocityRotation; shaderColour_UO.SetVelocityScale(ref velScale); } else { shader = shaderNoColour_UO = state.GetShader<DrawVelocityParticles_LinesGpuTex_UserOffset>(); shaderNoColour_UO.PositionTexture = positionTex; shaderNoColour_UO.VelocityTexture = velocityRotation; 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 using (state.Shader.Push(shader)) { //draw! vertices.Draw(state, null, PrimitiveType.LineList, drawCount, 0, 0); } count -= drawCount; drawn += drawCount; } state.RenderState.Pop(); }
/// <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></summary> /// <param name="state"></param> /// <param name="maskOnly"></param> protected override sealed IShader BindShader(DrawState state, bool maskOnly) { if (this.vertices == null) { this.vertices = state.Application.UserValues[GetType().FullName + ".vertices"] as IVertices; this.indices = state.Application.UserValues[GetType().FullName + ".indices"] as Indices<ushort>; this.verticesSI = state.Application.UserValues[GetType().FullName + ".verticesSI"] as IVertices; this.indicesSI = state.Application.UserValues[GetType().FullName + ".indicesSI"] as Indices<ushort>; if (this.vertices == null) { //still null, create the global vertices this.vertices = new Vertices<Vector4>( new Vector4(0, 0, 0, 1), new Vector4(1, 0, 0, 1), new Vector4(1, 1, 0, 1), new Vector4(0, 1, 0, 1)); this.indices = new Indices<ushort>(0, 2, 1, 0, 3, 2); //shader instancing.. List<InstanceVertex> verts = new List<InstanceVertex>(); List<ushort> inds = new List<ushort>(); for (int i = 0; i < NonInstancingRenderCount; i++) { verts.Add(new InstanceVertex(new Vector3(0, 0, 0), (float)i)); verts.Add(new InstanceVertex(new Vector3(1, 0, 0), (float)i)); verts.Add(new InstanceVertex(new Vector3(1, 1, 0), (float)i)); verts.Add(new InstanceVertex(new Vector3(0, 1, 0), (float)i)); inds.Add((ushort)(0 + i * 4)); inds.Add((ushort)(2 + i * 4)); inds.Add((ushort)(1 + i * 4)); inds.Add((ushort)(0 + i * 4)); inds.Add((ushort)(3 + i * 4)); inds.Add((ushort)(2 + i * 4)); } this.verticesSI = new Vertices<InstanceVertex>(verts.ToArray()); this.indicesSI = new Indices<ushort>(inds.ToArray()); state.Application.UserValues[GetType().FullName + ".vertices"] = vertices; state.Application.UserValues[GetType().FullName + ".indices"] = indices; state.Application.UserValues[GetType().FullName + ".verticesSI"] = verticesSI; state.Application.UserValues[GetType().FullName + ".indicesSI"] = indicesSI; } } if (state.Properties.SupportsHardwareInstancing && instanceCount > HardwareInstancingMinimum) { Graphics2D.InstancingSprite shader = state.GetShader<Graphics2D.InstancingSprite>(); Matrix world; state.WorldMatrix.GetMatrix(out world); shader.SetSpriteWorldMatrix(ref world); shader.CustomTexture = texture ?? state.Properties.WhiteTexture; return shader; } else { Graphics2D.NonInstancingSprite shader = state.GetShader<Graphics2D.NonInstancingSprite>(); shader.CustomTexture = texture ?? state.Properties.WhiteTexture; return shader; } }
/// <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> /// Apply the filter /// </summary> /// <param name="state"></param> public void Draw(DrawState state) { switch (kernelSize) { case 16: Kernel16 shader16 = state.GetShader <Kernel16>(); shader16.Texture = source.GetTexture(); shader16.TextureSize = new Vector2(1.0f / this.source.Size.X, 1.0f / this.source.Size.Y); shader16.SetKernel(this.filter); element.Shader = shader16; break; case 15: Kernel15 shader15 = state.GetShader <Kernel15>(); shader15.Texture = source.GetTexture(); shader15.TextureSize = new Vector2(1.0f / this.source.Size.X, 1.0f / this.source.Size.Y); shader15.SetKernel(this.filter); element.Shader = shader15; break; case 8: Kernel8 shader8 = state.GetShader <Kernel8>(); shader8.Texture = source.GetTexture(); shader8.TextureSize = new Vector2(1.0f / this.source.Size.X, 1.0f / this.source.Size.Y); shader8.SetKernel(this.filter); element.Shader = shader8; break; case 7: Kernel7 shader7 = state.GetShader <Kernel7>(); shader7.Texture = source.GetTexture(); shader7.TextureSize = new Vector2(1.0f / this.source.Size.X, 1.0f / this.source.Size.Y); shader7.SetKernel(this.filter); element.Shader = shader7; break; case 4: Kernel4 shader4 = state.GetShader <Kernel4>(); shader4.Texture = source.GetTexture(); shader4.TextureSize = new Vector2(1.0f / this.source.Size.X, 1.0f / this.source.Size.Y); shader4.SetKernel(this.filter); element.Shader = shader4; break; case 3: Kernel3 shader3 = state.GetShader <Kernel3>(); shader3.Texture = source.GetTexture(); shader3.TextureSize = new Vector2(1.0f / this.source.Size.X, 1.0f / this.source.Size.Y); shader3.SetKernel(this.filter); element.Shader = shader3; break; case 2: Kernel2 shader2 = state.GetShader <Kernel2>(); shader2.Texture = source.GetTexture(); shader2.TextureSize = new Vector2(1.0f / this.source.Size.X, 1.0f / this.source.Size.Y); shader2.SetKernel(this.filter); element.Shader = shader2; break; } targetClone.Draw(state); }
/// <summary></summary> /// <param name="state"></param> /// <param name="maskOnly"></param> protected override IShader BindShader(DrawState state, bool maskOnly) { if (this.texture == null && textureSource != null) { Texture2D tex = textureSource.GetTexture(); if (tex == null) throw new InvalidOperationException("TexturedElement is trying to use a DrawTargetTexture2D that hasn't been drawn (DrawTargetTexture2D.GetTexture() is null)"); this.Texture = tex; } FillCustomTexture shader = state.GetShader<FillCustomTexture>(); shader.CustomTexture = texture; shader.CustomTextureSampler = usePointFilter ? pointFilter : bilinearFilter; return shader; }
/// <summary> /// <para>implements the method to draw gpu particles</para> /// <para>Note: When 'usesUserValuesPositionBuffer' is true, the values 'user1, user2 and user3' (yzw in the UserTexture) store a position offset for the particle</para></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.RenderState.Push(); state.RenderState.CurrentBlendState = blendMode; state.RenderState.CurrentDepthState.DepthWriteEnabled = false; //get the display texture, or a white texture if none exists Texture2D displayTexture = particleType.Texture ?? state.Properties.WhiteTexture; //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 DrawBillboardParticles_GpuTex3D shaderNoColour = null; DrawBillboardParticlesColour_GpuTex3D shaderColour = null; //user offset variants DrawBillboardParticles_GpuTex3D_UserOffset shaderNoColour_UO = null; DrawBillboardParticlesColour_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); IShader shader; if (!usesUserValuesPositionBuffer) { if (colourTex != null) // does this particle system use colours? { //get the shader shaderColour = state.GetShader<DrawBillboardParticlesColour_GpuTex3D>(); //set the samplers shaderColour.PositionTexture = positionTex; shaderColour.ColourTexture = colourTex; shaderColour.VelocityTexture = velocityRotation; shaderColour.DisplayTexture = displayTexture; shaderColour.SetWorldSpaceYAxis(ref worldSpaceYAxis); shader = shaderColour; } else { shaderNoColour = state.GetShader<DrawBillboardParticles_GpuTex3D>(); shaderNoColour.PositionTexture = positionTex; shaderNoColour.VelocityTexture = velocityRotation; shaderNoColour.DisplayTexture = displayTexture; shaderNoColour.SetWorldSpaceYAxis(ref worldSpaceYAxis); shader = shaderNoColour; } } else { if (colourTex != null) // does this particle system use colours? { //get the shader shaderColour_UO = state.GetShader<DrawBillboardParticlesColour_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); shader = shaderColour_UO; } else { shaderNoColour_UO = state.GetShader<DrawBillboardParticles_GpuTex3D_UserOffset>(); shaderNoColour_UO.PositionTexture = positionTex; shaderNoColour_UO.VelocityTexture = velocityRotation; shaderNoColour_UO.UserTexture = userValues; shaderNoColour_UO.DisplayTexture = displayTexture; shaderNoColour_UO.SetWorldSpaceYAxis(ref worldSpaceYAxis); 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! using (state.Shader.Push(shader)) { //draw! vertices.Draw(state, indices, PrimitiveType.TriangleList, drawCount * 2, 0, 0); } count -= drawCount; drawn += drawCount; } //and done. state.RenderState.Pop(); }
/// <summary></summary> /// <param name="state"></param> /// <param name="maskOnly"></param> protected override IShader BindShader(DrawState state, bool maskOnly) { return state.GetShader<Shaders.FillVertexColour>(); }
/// <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(); }
/// <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.RenderState.Push(); state.RenderState.CurrentBlendState = blendMode; state.RenderState.CurrentDepthState.DepthWriteEnabled = false; Texture2D displayTexture = particleType.Texture ?? state.Properties.WhiteTexture; 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); uint drawCountU = (uint)drawCount; uint drawnU = (uint)drawn; //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.SetPositionData(positionBuffer, 0, 0, drawCountU); shaderColour.SetColourData(colourData, drawnU, 0, drawCountU); shaderColour.DisplayTexture = displayTexture; state.Shader.Push(shaderColour); } else { shaderNoColour.SetPositionData(positionBuffer, 0, 0, drawCountU); shaderNoColour.DisplayTexture = displayTexture; state.Shader.Push(shaderNoColour); } vertices.Draw(state, indices, PrimitiveType.TriangleList, drawCount * 2, 0, 0); state.Shader.Pop(); count -= drawCount; drawn += drawCount; } state.RenderState.Pop(); }
//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(); }