private Texture2D CreateTexture(DrawState state) { Texture2D texture; ushort[] pixels = new ushort[Resolution * Resolution * 2]; Random rand = new Random(); for (int i = 0; i < pixels.Length;) { //gpu shaders will vary the random numbers by +/- 1/256 //first values are linear rand ushort linearRand = (ushort)(rand.Next(ushort.MaxValue - 512) + 256); //second are non linear int randBase = rand.Next(ushort.MaxValue - 512) + 256; //get a non-linear squared version.. int rand0 = randBase - ushort.MaxValue / 2; rand0 = (rand0 * Math.Abs(rand0)) / (ushort.MaxValue / 2) + ushort.MaxValue / 2; //then average it with the original linear //so it's half linear, half squared non-linear rand0 = (rand0 + randBase) >> 1; ushort nonLinearRand = (ushort)rand0; #if !XBOX360 pixels[i++] = linearRand; pixels[i++] = nonLinearRand; #else //on the xbox, storage order is reversed. Thanks to Arc for spotting this. pixels[i++] = nonLinearRand; pixels[i++] = linearRand; #endif } GraphicsDevice device = state.BeginGetGraphicsDevice(StateFlag.None); texture = new Texture2D(device, Resolution, Resolution, 1, TextureUsage.None, SurfaceFormat.Rg32); texture.SetData(pixels); state.EndGetGraphicsDevice(); return(texture); }
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> /// Draw the statistics /// </summary> /// <param name="state"></param> public void Draw(DrawState state) { #if DEBUG float fade = 8 - state.TotalTimeSeconds * 0.5f; if (fade > 1) { fade = 1; } if (fade < 0) { fade = 0; } if (!enabled) { if (toggleTextDisplay != null && fade > 0) { this.toggleTextDisplay.ColourFloat = new Vector4(1, 1, 1, fade); toggleTextDisplay.Draw(state); AlignElements(state); } return; } if (fillRateQuery == null) { GraphicsDevice device = state.BeginGetGraphicsDevice(StateFlag.None); fillRateQuery = new OcclusionQuery(device); state.EndGetGraphicsDevice(); if (fillRateQuery.IsSupported) { fillRateQuery.Begin(); fillRateQueryActive = true; } } if (fillRateQuery.IsSupported) { if (fillRateQueryActive) { fillRateQuery.End(); fillRateQueryActive = false; } } DrawStatistics stats; state.GetPreviousFrameStatistics(out stats); stats -= previousFrameOverhead; if (graphs == null) { const int width = 210; const int height = 128; const int fontPix = 20; List <Call> calls = new List <Call>(); List <bool> visibleList = new List <bool>(); Callback <Graph, string, Call, bool, float> add = delegate(string name, Call call, bool visible, float good) { calls.Add(call); visibleList.Add(visible); return(new Graph(name, width, height, width - fontPix / 2, fontPix, 0, font, -good)); }; Callback <Graph, string, Call, bool, float> addHalf = delegate(string name, Call call, bool visible, float good) { calls.Add(call); visibleList.Add(visible); return(new Graph(name, width / 2, height, width / 2 - fontPix / 2, fontPix, 0, font, -good)); }; Callback <Graph, string, Call, bool, float> addHalfMin1 = delegate(string name, Call call, bool visible, float good) { calls.Add(call); visibleList.Add(visible); return(new Graph(name, width / 2, height, width / 2 - fontPix / 2, fontPix, 1, font, -good)); }; graphs = new Graph[] { add("Frame Rate (Approx)", delegate(ref DrawStatistics s, DrawState dstate) { return((float)dstate.ApproximateFrameRate); }, true, -20), add("Frame Draw Time (Ticks)", delegate(ref DrawStatistics s, DrawState dstate) { return(s.ApproximateDrawTimeTicks); }, false, 1.0f / 20.0f), addHalf("Draw Target Passes", delegate(ref DrawStatistics s, DrawState dstate) { return((float)s.DrawTargetsPassCount); }, false, 10), add("Primitives Drawn", delegate(ref DrawStatistics s, DrawState dstate) { return((float)(s.TrianglesDrawn + s.LinesDrawn + s.PointsDrawn)); }, true, 1000000), #if XBOX360 addHalf("Pixels Drawn\n(Approx)", delegate(ref DrawStatistics s, DrawState dstate) { return(Math.Max(0, pixelsFillled - (float)s.XboxPixelFillBias)); }, true, 20000000), // not accurate #else addHalf("Pixels Drawn", delegate(ref DrawStatistics s, DrawState dstate) { return(Math.Max(0, pixelsFillled)); }, true, 18000000), #endif addHalf("Lines Drawn", delegate(ref DrawStatistics s, DrawState dstate) { return((float)(s.LinesDrawn)); }, false, 1000000), addHalf("Points Drawn", delegate(ref DrawStatistics s, DrawState dstate) { return((float)(s.PointsDrawn)); }, false, 1000000), addHalf("Draw Calls", delegate(ref DrawStatistics s, DrawState dstate) { return((float)(s.DrawIndexedPrimitiveCallCount + s.DrawPrimitivesCallCount)); }, true, 300), addHalf("Draw Calls (Indexed)", delegate(ref DrawStatistics s, DrawState dstate) { return((float)(s.DrawIndexedPrimitiveCallCount)); }, false, 300), addHalf("Instances Drawn", delegate(ref DrawStatistics s, DrawState dstate) { return((float)(s.InstancesDrawn)); }, false, 1000), addHalf("Inst.Batch Size (Avg)", delegate(ref DrawStatistics s, DrawState dstate) { return(Avg(s.InstancesDrawn, s.InstancesDrawBatchCount)); }, false, 1000), addHalf("Set Camera Count", delegate(ref DrawStatistics s, DrawState dstate) { return((float)s.SetCameraCount); }, false, 1000), addHalf("Shader Bind Count", delegate(ref DrawStatistics s, DrawState dstate) { return((float)s.ShaderBindCount); }, false, 1000), addHalf("Shader Constant Bytes", delegate(ref DrawStatistics s, DrawState dstate) { return((float)(s.VertexShaderConstantBytesSetTotalCount + s.PixelShaderConstantBytesSetTotalCount)); }, false, 2000000), addHalf("VS Constant Bytes (Avg)", delegate(ref DrawStatistics s, DrawState dstate) { return(Avg(s.VertexShaderConstantBytesSetTotalCount, s.VertexShaderConstantBytesSetCount)); }, false, 1000), addHalf("PS Constant Bytes (Avg)", delegate(ref DrawStatistics s, DrawState dstate) { return(Avg(s.PixelShaderConstantBytesSetTotalCount, s.PixelShaderConstantBytesSetCount)); }, false, 1000), addHalf("VS Complexity (Avg)", delegate(ref DrawStatistics s, DrawState dstate) { return(Avg(s.VertexShaderApproximateInstructionsTotal, s.VertexShaderBoundWithKnownInstructionsCount)); }, false, 64), addHalf("PS Complexity (Avg)", delegate(ref DrawStatistics s, DrawState dstate) { return(Avg(s.PixelShaderApproximateInstructionsTotal, s.PixelShaderBoundWithKnownInstructionsCount)); }, false, 32), addHalf("VS Preshader Complexity (Avg)", delegate(ref DrawStatistics s, DrawState dstate) { return(Avg(s.VertexShaderApproximatePreshaderInstructionsTotal, s.VertexShaderBoundWithKnownInstructionsCount)); }, false, 512), addHalf("PS Preshader Complexity (Avg)", delegate(ref DrawStatistics s, DrawState dstate) { return(Avg(s.PixelShaderApproximatePreshaderInstructionsTotal, s.PixelShaderBoundWithKnownInstructionsCount)); }, false, 512), addHalf("Dirty Render State Count", delegate(ref DrawStatistics s, DrawState dstate) { return((float)s.DirtyRenderStateCount); }, false, 2), add("Vertex Bytes Copied", delegate(ref DrawStatistics s, DrawState dstate) { return((float)(s.VertexBufferByesCopied + s.DynamicVertexBufferByesCopied)); }, false, 1000000), add("Index Bytes Copied", delegate(ref DrawStatistics s, DrawState dstate) { return((float)(s.IndexBufferByesCopied + s.DynamicIndexBufferByesCopied)); }, false, 1000000), add("Resource Device Bytes (Tracked)", delegate(ref DrawStatistics s, DrawState dstate) { return((float)(Resource.GetAllAllocatedDeviceBytes())); }, false, 100000000), addHalf("Resource Count (Tracked)", delegate(ref DrawStatistics s, DrawState dstate) { return((float)(Resource.GetResourceCount())); }, false, 50), addHalf("Resource Managed Bytes (Tracked)", delegate(ref DrawStatistics s, DrawState dstate) { return((float)(Resource.GetAllAllocatedManagedBytes())); }, false, 100000000), addHalf("Unused Resources (Tracked)", delegate(ref DrawStatistics s, DrawState dstate) { return((float)(Resource.CountResourcesNotUsedByDevice())); }, false, 10), addHalfMin1("Culler Efficiency (Sphere)", delegate(ref DrawStatistics s, DrawState dstate) { return(1 - Avg(s.DefaultCullerTestSphereCulledCount, s.DefaultCullerTestSphereCount)); }, false, 1000), addHalfMin1("Culler Efficiency (Box)", delegate(ref DrawStatistics s, DrawState dstate) { return(1 - Avg(s.DefaultCullerTestBoxCulledCount, s.DefaultCullerTestBoxCount)); }, false, 1000), addHalf("AlphaBlend State Changed", delegate(ref DrawStatistics s, DrawState dstate) { return((float)(s.RenderStateAlphaBlendChangedCount)); }, false, 300), addHalf("AlphaTest State Changed", delegate(ref DrawStatistics s, DrawState dstate) { return((float)(s.RenderStateAlphaTestChangedCount)); }, false, 300), addHalf("StencilTest State Changed", delegate(ref DrawStatistics s, DrawState dstate) { return((float)(s.RenderStateStencilTestChangedCount)); }, false, 300), addHalf("Depth/FrustumCull State Changed", delegate(ref DrawStatistics s, DrawState dstate) { return((float)(s.RenderStateDepthColourCullChangedCount)); }, false, 300), addHalf("Tex Sampler Address Changed", delegate(ref DrawStatistics s, DrawState dstate) { return((float)(s.TextureSamplerAddressStateChanged)); }, false, 200), addHalf("Tex Sampler Filter Changed", delegate(ref DrawStatistics s, DrawState dstate) { return((float)(s.TextureSamplerFilterStateChanged)); }, false, 200), addHalf("Texture Changed", delegate(ref DrawStatistics s, DrawState dstate) { return((float)(s.TextureUnitTextureChanged)); }, false, 100), addHalf("Vertex Texture Changed", delegate(ref DrawStatistics s, DrawState dstate) { return((float)(s.VertexTextureUnitTextureChanged)); }, false, 50), add("Bound Textures (Avg)", delegate(ref DrawStatistics s, DrawState dstate) { return(Avg(s.BoundTextureCount, s.BoundTextureCountTotalSamples)); }, false, 4), addHalf("Vertex Textures (Avg)", delegate(ref DrawStatistics s, DrawState dstate) { return(Avg(s.BoundVertexTextureCount, s.BoundTextureCountTotalSamples)); }, false, 1), addHalf("Garbage Collected", delegate(ref DrawStatistics s, DrawState dstate) { if (garbageTracker.Target == null) { garbageTracker.Target = new object(); return(1); } return(0); }, true, 0), #if XBOX360 addHalfMin1("CPU Usage\n(Primary)", delegate(ref DrawStatistics s, DrawState dstate) { return(threads[0].Usage); }, true, -0.5f), addHalfMin1("CPU Usage\n(Task Threads)", delegate(ref DrawStatistics s, DrawState dstate) { return((threads[1].Usage + threads[2].Usage + threads[3].Usage) / 3.0f); }, true, -0.25f), #endif }; this.graphVisible = visibleList.ToArray(); this.setGraphCalls = calls.ToArray(); } for (int i = 0; i < graphs.Length; i++) { if (graphVisible[i] || this.displayAll) { graphs[i].SetGraphValue(setGraphCalls[i](ref stats, state)); graphs[i].Visible = true; } else { graphs[i].Visible = false; } } AlignElements(state); DrawStatistics currentPreDraw; state.GetCurrentFrameStatistics(out currentPreDraw); for (int i = 0; i < graphs.Length; i++) { if (graphs[i].Visible) { graphs[i].Draw(state); } } DrawStatistics currentPostDraw; state.GetCurrentFrameStatistics(out currentPostDraw); previousFrameOverhead = currentPostDraw - currentPreDraw; if (fillRateQuery.IsSupported) { if (fillRateQuery.IsComplete) { pixelsFillled = (float)fillRateQuery.PixelCount; fillRateQuery.Begin(); fillRateQueryActive = true; } } else { pixelsFillled = -1; } #endif }
/// <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); } }