protected override async Task LoadContent()
        {
            await base.LoadContent();

            wireframeState = RasterizerState.New(GraphicsDevice, new RasterizerStateDescription(CullMode.Back) { FillMode = FillMode.Wireframe });

            simpleEffect = new Effect(GraphicsDevice, SpriteEffect.Bytecode);
            parameterCollection = new ParameterCollection();
            parameterCollectionGroup = new EffectParameterCollectionGroup(GraphicsDevice, simpleEffect, new [] { parameterCollection });
            parameterCollection.Set(TexturingKeys.Texture0, UVTexture);

            primitives = new List<GeometricPrimitive>();

            // Creates all primitives
            primitives = new List<GeometricPrimitive>
                             {
                                 GeometricPrimitive.Plane.New(GraphicsDevice),
                                 GeometricPrimitive.Cube.New(GraphicsDevice),
                                 GeometricPrimitive.Sphere.New(GraphicsDevice),
                                 GeometricPrimitive.GeoSphere.New(GraphicsDevice),
                                 GeometricPrimitive.Cylinder.New(GraphicsDevice),
                                 GeometricPrimitive.Torus.New(GraphicsDevice),
                                 GeometricPrimitive.Teapot.New(GraphicsDevice),
                                 GeometricPrimitive.Capsule.New(GraphicsDevice, 0.5f, 0.3f),
                                 GeometricPrimitive.Cone.New(GraphicsDevice)
                             };


            view = Matrix.LookAtRH(new Vector3(0, 0, 5), new Vector3(0, 0, 0), Vector3.UnitY);

            Window.AllowUserResizing = true;
        }
Пример #2
0
        protected override async Task LoadContent()
        {
            await base.LoadContent();

            var view = Matrix.LookAtRH(new Vector3(2,2,2), new Vector3(0, 0, 0), Vector3.UnitY);
            var projection = Matrix.PerspectiveFovRH((float)Math.PI / 4.0f, (float)GraphicsDevice.BackBuffer.ViewWidth / GraphicsDevice.BackBuffer.ViewHeight, 0.1f, 100.0f);
            worldViewProjection = Matrix.Multiply(view, projection);

            geometry = GeometricPrimitive.Cube.New(GraphicsDevice);
            simpleEffect = new Effect(GraphicsDevice, SpriteEffect.Bytecode);
            parameterCollection = new ParameterCollection();
            parameterCollectionGroup = new EffectParameterCollectionGroup(GraphicsDevice, simpleEffect, new[] { parameterCollection });
            parameterCollection.Set(TexturingKeys.Texture0, UVTexture);
            
            // TODO DisposeBy is not working with device reset
            offlineTarget0 = Texture.New2D(GraphicsDevice, 512, 512, PixelFormat.R8G8B8A8_UNorm, TextureFlags.ShaderResource | TextureFlags.RenderTarget).DisposeBy(this);

            offlineTarget1 = Texture.New2D(GraphicsDevice, 512, 512, PixelFormat.R8G8B8A8_UNorm, TextureFlags.ShaderResource | TextureFlags.RenderTarget).DisposeBy(this);
            offlineTarget2 = Texture.New2D(GraphicsDevice, 512, 512, PixelFormat.R8G8B8A8_UNorm, TextureFlags.ShaderResource | TextureFlags.RenderTarget).DisposeBy(this);

            depthBuffer = Texture.New2D(GraphicsDevice, 512, 512, PixelFormat.D16_UNorm, TextureFlags.DepthStencil).DisposeBy(this);

            width = GraphicsDevice.BackBuffer.ViewWidth;
            height = GraphicsDevice.BackBuffer.ViewHeight;
        }
Пример #3
0
        public void Apply(GraphicsDevice graphicsDevice, EffectParameterResourceBinding[] bindings, EffectParameterCollectionGroup parameterCollectionGroup, ref EffectStateBindings effectStateBindings, bool applyEffectStates)
        {
            // Apply shader parameters
            for (int i = 0; i < bindings.Length; i++)
            {
                bindings[i].ApplyParameterWithUpdater(graphicsDevice, ref bindings[i].Description, parameterCollectionGroup);
            }

            if (applyEffectStates)
            {
                // Apply graphics states
                var rasterizerState = parameterCollectionGroup.GetValue<RasterizerState>(effectStateBindings.RasterizerStateKeyIndex);
                if (rasterizerState != null)
                {
                    graphicsDevice.SetRasterizerState(rasterizerState);
                }

                var depthStencilState = parameterCollectionGroup.GetValue<DepthStencilState>(effectStateBindings.DepthStencilStateKeyIndex);
                if (depthStencilState != null)
                {
                    graphicsDevice.SetDepthStencilState(depthStencilState);
                }

                var blendState = parameterCollectionGroup.GetValue<BlendState>(effectStateBindings.BlendStateKeyIndex);
                if (blendState != null)
                {
                    graphicsDevice.SetBlendState(blendState);
                }
            }
        }
Пример #4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="PrimitiveQuad" /> class with a particular effect.
 /// </summary>
 /// <param name="graphicsDevice">The graphics device.</param>
 /// <param name="effect">The effect.</param>
 public PrimitiveQuad(GraphicsDevice graphicsDevice, Effect effect)
 {
     GraphicsDevice = graphicsDevice;
     simpleEffect = effect;
     parameters = new ParameterCollection();
     parameters.Set(SpriteBaseKeys.MatrixTransform, Matrix.Identity);
     parameterCollectionGroup = new EffectParameterCollectionGroup(graphicsDevice, simpleEffect, new[] { parameters });
     sharedData = GraphicsDevice.GetOrCreateSharedData(GraphicsDeviceSharedDataType.PerDevice, "PrimitiveQuad::VertexBuffer", d => new SharedData(GraphicsDevice, simpleEffect.InputSignature));
 }
        /// <summary>
        /// Draws a fullscreen quad with the specified effect and parameters.
        /// </summary>
        /// <param name="device">The device.</param>
        /// <param name="effect">The effect.</param>
        /// <param name="effectParameterCollectionGroup">The shader parameter updater.</param>
        /// <exception cref="System.ArgumentNullException">effect</exception>
        public static void DrawQuad(this GraphicsDevice device, Effect effect, EffectParameterCollectionGroup effectParameterCollectionGroup)
        {
            if (effect == null) throw new ArgumentNullException("effect");

            // Apply the effect
            effect.Apply(device, effectParameterCollectionGroup, false);

            // Draw a full screen quad
            device.DrawQuad();

            // Unapply
            effect.UnbindResources(device);
        }
        public void Update(GraphicsDevice graphicsDevice, EffectParameterCollectionGroup parameterCollectionGroup)
        {
            var threadIndex = graphicsDevice.ThreadIndex;
            bool dataChanged = constantBufferDatas[threadIndex].Update(parameterCollectionGroup);

            // Check if update is really needed
            if (forceDataChanged)
                forceDataChanged = false;
            else if (!dataChanged)
                return;

            // Upload data to constant buffer
            Buffer.SetData(graphicsDevice, dataStreams[threadIndex]);
        }
Пример #7
0
        private void DrawCustomEffect()
        {
            GraphicsDevice.Clear(GraphicsDevice.BackBuffer, Color.Black);
            GraphicsDevice.Clear(GraphicsDevice.DepthStencilBuffer, DepthStencilClearOptions.DepthBuffer);
            GraphicsDevice.SetDepthAndRenderTarget(GraphicsDevice.DepthStencilBuffer, GraphicsDevice.BackBuffer);

            effectParameters.Set(MyCustomShaderKeys.ColorFactor2, (Vector4)Color.Red);
            effectParameters.Set(CustomShaderKeys.SwitchEffectLevel, switchEffectLevel);
            effectParameters.Set(TexturingKeys.Texture0, UVTexture);
            switchEffectLevel++; // TODO: Add switch Effect to test and capture frames
            dynamicEffectCompiler.Update(effectInstance, null);
            parameterCollection = new EffectParameterCollectionGroup(GraphicsDevice, effectInstance.Effect, new[] { effectParameters });

            GraphicsDevice.DrawQuad(effectInstance.Effect, parameterCollection);
        }
Пример #8
0
        protected override async Task LoadContent()
        {
            await base.LoadContent();

            var vertices = new Vertex[4];
            vertices[0] = new Vertex { Position = new Vector3(-1, -1, 0.5f), TexCoords = new Vector2(0, 0) };
            vertices[1] = new Vertex { Position = new Vector3(-1, 1, 0.5f), TexCoords = new Vector2(3, 0) };
            vertices[2] = new Vertex { Position = new Vector3(1, 1, 0.5f), TexCoords = new Vector2(3, 3) };
            vertices[3] = new Vertex { Position = new Vector3(1, -1, 0.5f), TexCoords = new Vector2(0, 3) };

            var indices = new short[] { 0, 1, 2, 0, 2, 3 };

            var vertexBuffer = Buffer.Vertex.New(GraphicsDevice, vertices, GraphicsResourceUsage.Default);
            var indexBuffer = Buffer.Index.New(GraphicsDevice, indices, GraphicsResourceUsage.Default);
            var meshDraw = new MeshDraw
            {
                DrawCount = 4,
                PrimitiveType = PrimitiveType.TriangleList,
                VertexBuffers = new[]
                {
                    new VertexBufferBinding(vertexBuffer,
                        new VertexDeclaration(VertexElement.Position<Vector3>(),
                            VertexElement.TextureCoordinate<Vector2>()),
                        4)
                },
                IndexBuffer = new IndexBufferBinding(indexBuffer, false, indices.Length),
            };

            var mesh = new Mesh
            {
                Draw = meshDraw,
            };

            simpleEffect = new Effect(GraphicsDevice, SpriteEffect.Bytecode);
            parameterCollection = new ParameterCollection();
            parameterCollectionGroup = new EffectParameterCollectionGroup(GraphicsDevice, simpleEffect, new[] { parameterCollection });
            parameterCollection.Set(TexturingKeys.Texture0, UVTexture);

            vao = VertexArrayObject.New(GraphicsDevice, mesh.Draw.IndexBuffer, mesh.Draw.VertexBuffers);

            myDraws = new DrawOptions[3];
            myDraws[0] = new DrawOptions { Sampler = GraphicsDevice.SamplerStates.LinearClamp, Transform = Matrix.Multiply(Matrix.Scaling(0.4f), Matrix.Translation(-0.5f, 0.5f, 0f)) };
            myDraws[1] = new DrawOptions { Sampler = GraphicsDevice.SamplerStates.LinearWrap, Transform = Matrix.Multiply(Matrix.Scaling(0.4f), Matrix.Translation(0.5f, 0.5f, 0f)) };
            myDraws[2] = new DrawOptions { Sampler = SamplerState.New(GraphicsDevice, new SamplerStateDescription(TextureFilter.Linear, TextureAddressMode.Mirror)), Transform = Matrix.Multiply(Matrix.Scaling(0.4f), Matrix.Translation(0.5f, -0.5f, 0f)) };
            //var borderDescription = new SamplerStateDescription(TextureFilter.Linear, TextureAddressMode.Border) { BorderColor = Color.Purple };
            //var border = SamplerState.New(GraphicsDevice, borderDescription);
            //myDraws[3] = new DrawOptions { Sampler = border, Transform = Matrix.Multiply(Matrix.Scale(0.3f), Matrix.Translation(-0.5f, -0.5f, 0f)) };
        }
Пример #9
0
 public void UpdateParameters(GraphicsDevice graphicsDevice, EffectParameterCollectionGroup parameterCollectionGroup, EffectParameterUpdaterDefinition parameterUpdaterDefinition)
 {
     parameterCollectionGroup.Update(graphicsDevice, parameterUpdaterDefinition);
 }
Пример #10
0
 private static void UpdateUnorderedAccessView(GraphicsDevice graphicsDevice, ref EffectParameterResourceData binding, EffectParameterCollectionGroup parameterCollectionGroup)
 {
     var unorderedAccessView = (GraphicsResource)parameterCollectionGroup.GetObject(binding.Param.KeyIndex);
     graphicsDevice.SetUnorderedAccessView(binding.Stage, binding.SlotStart, unorderedAccessView);
 }
Пример #11
0
 private static void UpdateSampler(GraphicsDevice graphicsDevice, ref EffectParameterResourceData binding, EffectParameterCollectionGroup parameterCollectionGroup)
 {
     var samplerState = (SamplerState)parameterCollectionGroup.GetObject(binding.Param.KeyIndex);
     graphicsDevice.SetSamplerState(binding.Stage, binding.SlotStart, samplerState);
 }
Пример #12
0
        private static void UpdateConstantBuffer(GraphicsDevice graphicsDevice, ref EffectParameterResourceData binding, EffectParameterCollectionGroup parameterCollectionGroup)
        {
            var constantBufferHelper = parameterCollectionGroup.GetValue<ParameterConstantBuffer>(binding.Param.KeyIndex);
            
            // Update constant buffer content (if required)
            constantBufferHelper.Update(graphicsDevice, parameterCollectionGroup);

            graphicsDevice.SetConstantBuffer(binding.Stage, binding.SlotStart, constantBufferHelper.Buffer);
        }
Пример #13
0
        /// <summary>
        /// Updates the specified parameter updater.
        /// </summary>
        /// <param name="parameterCollectionGroup">The parameter updater.</param>
        /// <returns></returns>
        public unsafe bool Update(EffectParameterCollectionGroup parameterCollectionGroup)
        {
            bool dataChanged = false;
            Matrix tempMatrix;

            //fixed (BoundConstantBufferParam* paramReferences = &this.constantBufferParams[0])
            if (constantBufferParams.Length > 0)
            {
                var shaderVariable = Interop.Pin(ref Desc.Members[0]);
                for (int i = 0; i < this.constantBufferParams.Length; ++i, shaderVariable = Interop.IncrementPinned(shaderVariable))
                {
                    if (shaderVariable.Param.KeyIndex == -1)
                    {
                        throw new InvalidOperationException();
                    }

                    var paramReference = constantBufferParams[i];

                    var internalValue = parameterCollectionGroup.GetInternalValue(shaderVariable.Param.KeyIndex);

                    // TODO: Comparing Counter+DataPointer is not enough (if realloc on same address)
                    if (internalValue == paramReference.Value
                        && internalValue.Counter == paramReference.DirtyCount)
                        continue;

                    constantBufferParams[i] = new ParameterCollectionGroup.BoundInternalValue
                    {
                        Value = internalValue,
                        DirtyCount = internalValue.Counter
                    };

                    var destination = (byte*)(Data + shaderVariable.Offset);

                    int sourceOffset = 0;

                    float* variableData = (float*)destination; // + shaderVariable.Offset);

                    switch (shaderVariable.Param.Class)
                    {
                        case EffectParameterClass.Struct:
                            internalValue.ReadFrom((IntPtr)variableData, sourceOffset, shaderVariable.Size);
                            break;
                        case EffectParameterClass.Scalar:
                            for (int elt = 0; elt < shaderVariable.Count; ++elt)
                            {
                                internalValue.ReadFrom((IntPtr)variableData, sourceOffset, sizeof(float));
                                //*variableData = *source++;
                                sourceOffset += 4;
                                variableData += 4; // 4 floats
                            }
                            break;
                        case EffectParameterClass.Vector:
                        case EffectParameterClass.Color:
                            for (int elt = 0; elt < shaderVariable.Count; ++elt)
                            {
                                //Framework.Utilities.CopyMemory((IntPtr)variableData, (IntPtr)source, (int)(shaderVariable.ColumnCount * sizeof(float)));
                                internalValue.ReadFrom((IntPtr)variableData, sourceOffset, (int)(shaderVariable.ColumnCount * sizeof(float)));
                                sourceOffset += (int)shaderVariable.ColumnCount * 4;
                                variableData += 4;
                            }
                            break;
                        case EffectParameterClass.MatrixColumns:
                            for (int elt = 0; elt < shaderVariable.Count; ++elt)
                            {
                                //fixed (Matrix* p = &tempMatrix)
                                {
                                    internalValue.ReadFrom((IntPtr)(byte*)&tempMatrix, sourceOffset, (int)(shaderVariable.ColumnCount * shaderVariable.RowCount * sizeof(float)));
                                    ((Matrix*)variableData)->CopyMatrixFrom((float*)&tempMatrix, unchecked((int)shaderVariable.ColumnCount), unchecked((int)shaderVariable.RowCount));
                                    sourceOffset += (int)(shaderVariable.ColumnCount * shaderVariable.RowCount) * 4;
                                    variableData += 4 * shaderVariable.RowCount;
                                }
                            }
                            break;
                        case EffectParameterClass.MatrixRows:
                            for (int elt = 0; elt < shaderVariable.Count; ++elt)
                            {
                                //fixed (Matrix* p = &tempMatrix)
                                {
                                    internalValue.ReadFrom((IntPtr)(byte*)&tempMatrix, sourceOffset, (int)(shaderVariable.ColumnCount * shaderVariable.RowCount * sizeof(float)));
                                    ((Matrix*)variableData)->TransposeMatrixFrom((float*)&tempMatrix, unchecked((int)shaderVariable.ColumnCount), unchecked((int)shaderVariable.RowCount));
                                    //source += shaderVariable.ColumnCount * shaderVariable.RowCount;
                                    sourceOffset += (int)(shaderVariable.ColumnCount * shaderVariable.RowCount) * 4;
                                    variableData += 4 * shaderVariable.RowCount;
                                }
                            }
                            break;
                    }

                    dataChanged = true;
                }
            }
            return dataChanged;
        }
Пример #14
0
 /// <summary>
 /// Begins a sprite batch rendering using the specified sorting mode and blend state, sampler, depth stencil, rasterizer state objects, plus a custom effect and a 2D transformation matrix. Passing null for any of the state objects selects the default default state objects (BlendState.AlphaBlend, DepthStencilState.Default, RasterizerState.CullCounterClockwise, SamplerState.LinearClamp). Passing a null effect selects the default SpriteBatch Class shader.
 /// </summary>
 /// <param name="viewMatrix">The view matrix to use for the batch session</param>
 /// <param name="sortMode">The sprite drawing order to use for the batch session</param>
 /// <param name="blendState">The blending state to use for the batch session</param>
 /// <param name="samplerState">The sampling state to use for the batch session</param>
 /// <param name="depthStencilState">The depth stencil state to use for the batch session</param>
 /// <param name="rasterizerState">The rasterizer state to use for the batch session</param>
 /// <param name="effect">The effect to use for the batch session</param>
 /// <param name="parameterCollectionGroup">The parameter collection group.</param>
 /// <param name="stencilValue">The value of the stencil buffer to take as reference for the batch session</param>
 public void Begin(Matrix viewMatrix, SpriteSortMode sortMode = SpriteSortMode.Deferred, BlendState blendState = null, SamplerState samplerState = null, DepthStencilState depthStencilState = null, RasterizerState rasterizerState = null, Effect effect = null, EffectParameterCollectionGroup parameterCollectionGroup = null, int stencilValue = 0)
 {
     UpdateDefaultProjectionMatrix();
     Begin(viewMatrix, defaultProjectionMatrix, sortMode, blendState, samplerState, depthStencilState, rasterizerState, effect, parameterCollectionGroup, stencilValue);
 }
Пример #15
0
        /// <summary>
        /// Draw this effect mesh.
        /// </summary>
        public void Draw(RenderContext context)
        {
            // Retrieve effect parameters
            var graphicsDevice = context.GraphicsDevice;
            var mesh = Mesh;
            var currentRenderData = mesh.Draw;
            var material = Material;
            var vao = vertexArrayObject;
            var drawCount = currentRenderData.DrawCount;
            var primitiveType = currentRenderData.PrimitiveType;

            parameters.Set(TransformationKeys.World, WorldMatrix);

            // TODO: We should clarify exactly how to override rasterizer states. Currently setup here on Context.Parameters to allow Material/ModelComponent overrides, but this is ugly
            // Apply rasterizer
            var rasterizer = RasterizerState; 
            if (!ForceRasterizer && Material.CullMode.HasValue && Material.CullMode.Value != RasterizerState.Description.CullMode)
            {
                switch (Material.CullMode.Value)
                {
                    case CullMode.Back:
                        rasterizer = graphicsDevice.RasterizerStates.CullBack;
                        break;
                    case CullMode.Front:
                        rasterizer = graphicsDevice.RasterizerStates.CullFront;
                        break;
                    case CullMode.None:
                        rasterizer = graphicsDevice.RasterizerStates.CullNone;
                        break;
                }
            }
            context.Parameters.Set(Effect.RasterizerStateKey, rasterizer);

            // Handle picking
            if (context.IsPicking()) // TODO move this code corresponding to picking outside of the runtime code!
            {
                parameters.Set(ModelComponentPickingShaderKeys.ModelComponentId, new Color4(RuntimeIdHelper.ToRuntimeId(RenderModel.ModelComponent)));
                parameters.Set(ModelComponentPickingShaderKeys.MeshId, new Color4(RenderModel.ModelComponent.Model.Meshes.IndexOf(Mesh)));
                parameters.Set(ModelComponentPickingShaderKeys.MaterialId, new Color4(Mesh.MaterialIndex));

                // Don't use the materials blend state on picking targets
                parameters.Set(Effect.BlendStateKey, null);
            }

            if (material != null && material.TessellationMethod != XenkoTessellationMethod.None)
            {
                var tessellationMethod = material.TessellationMethod;

                // adapt the primitive type and index buffer to the tessellation used
                if (tessellationMethod.PerformsAdjacentEdgeAverage())
                {
                    vao = GetOrCreateVertexArrayObjectAEN(context);
                    drawCount = 12 / 3 * drawCount;
                }
                primitiveType = tessellationMethod.GetPrimitiveType();
            }

            //using (Profiler.Begin(ProfilingKeys.PrepareMesh))
            {
                // Order of application of parameters:
                // - RenderPass.Parameters
                // - ModelComponent.Parameters
                // - RenderMesh.Parameters (originally copied from mesh parameters)
                // The order is based on the granularity level of each element and how shared it can be. Material is heavily shared, a model contains many meshes. An renderMesh is unique.
                // TODO: really copy mesh parameters into renderMesh instead of just referencing the meshDraw parameters.

                //var modelComponent = RenderModel.ModelComponent;
                //var hasModelComponentParams = modelComponent != null && modelComponent.Parameters != null;
                
                //var materialParameters = material != null && material.Parameters != null ? material.Parameters : null;

                parameterCollections.Clear();

                parameterCollections.Add(context.Parameters);
                FillParameterCollections(ref parameterCollections);

                // Check if we need to recreate the EffectParameterCollectionGroup
                // TODO: We can improve performance by redesigning FillParameterCollections to avoid ArrayExtensions.ArraysReferenceEqual (or directly check the appropriate parameter collections)
                // This also happens in another place: DynamicEffectCompiler (we probably want to factorize it when doing additional optimizations)
                if (parameterCollectionGroup == null || parameterCollectionGroup.Effect != Effect || !ArrayExtensions.ArraysReferenceEqual(ref previousParameterCollections, ref parameterCollections))
                {
                    previousParameterCollections.Clear();
                    previousParameterCollections.AddRange(parameterCollections);
                    parameterCollectionGroup = new EffectParameterCollectionGroup(context.GraphicsDevice, Effect, previousParameterCollections.Count, previousParameterCollections.Items);
                }

                Effect.Apply(context.GraphicsDevice, parameterCollectionGroup, true);
            }

            //using (Profiler.Begin(ProfilingKeys.RenderMesh))
            {
                if (currentRenderData != null)
                {
                    graphicsDevice.SetVertexArrayObject(vao);

                    if (currentRenderData.IndexBuffer == null)
                    {
                        graphicsDevice.Draw(primitiveType, drawCount, currentRenderData.StartLocation);
                    }
                    else
                    {
                        graphicsDevice.DrawIndexed(primitiveType, drawCount, currentRenderData.StartLocation);
                    }
                }
            }
        }
Пример #16
0
        protected override void DrawCore(RenderContext context)
        {
            if (string.IsNullOrEmpty(ShaderSourceName))
                return;

            Parameters.Set(ComputeEffectShaderKeys.ThreadNumbers, ThreadNumbers);
            Parameters.Set(ComputeEffectShaderKeys.ComputeShaderName, ShaderSourceName);
            Parameters.Set(ComputeShaderBaseKeys.ThreadGroupCountGlobal, ThreadGroupCounts);

            UpdateEffect();

            if (effectParameterCollections == null || effectParameterCollections.Effect != EffectInstance.Effect)
            {
                appliedParameterCollections.Clear();
                if (context != null)
                {
                    appliedParameterCollections.Add(context.Parameters);
                }
                appliedParameterCollections.AddRange(parameterCollections);

                effectParameterCollections = new EffectParameterCollectionGroup(GraphicsDevice, EffectInstance.Effect, appliedParameterCollections);
            }

            // Apply the effect
            EffectInstance.Effect.Apply(GraphicsDevice, effectParameterCollections, false);

            // Draw a full screen quad
            GraphicsDevice.Dispatch(ThreadGroupCounts.X, ThreadGroupCounts.Y, ThreadGroupCounts.Z);

            // Un-apply
            EffectInstance.Effect.UnbindResources(GraphicsDevice);
        }
Пример #17
0
        protected override async Task LoadContent()
        {
            await base.LoadContent();

            var vertices = new Vertex[4];

            vertices[0] = new Vertex {
                Position = new Vector3(-1, -1, 0.5f), TexCoords = new Vector2(0, 0)
            };
            vertices[1] = new Vertex {
                Position = new Vector3(-1, 1, 0.5f), TexCoords = new Vector2(3, 0)
            };
            vertices[2] = new Vertex {
                Position = new Vector3(1, 1, 0.5f), TexCoords = new Vector2(3, 3)
            };
            vertices[3] = new Vertex {
                Position = new Vector3(1, -1, 0.5f), TexCoords = new Vector2(0, 3)
            };

            var indices = new short[] { 0, 1, 2, 0, 2, 3 };

            var vertexBuffer = Buffer.Vertex.New(GraphicsDevice, vertices, GraphicsResourceUsage.Default);
            var indexBuffer  = Buffer.Index.New(GraphicsDevice, indices, GraphicsResourceUsage.Default);
            var meshDraw     = new MeshDraw
            {
                DrawCount     = 4,
                PrimitiveType = PrimitiveType.TriangleList,
                VertexBuffers = new[]
                {
                    new VertexBufferBinding(vertexBuffer,
                                            new VertexDeclaration(VertexElement.Position <Vector3>(),
                                                                  VertexElement.TextureCoordinate <Vector2>()),
                                            4)
                },
                IndexBuffer = new IndexBufferBinding(indexBuffer, false, indices.Length),
            };

            var mesh = new Mesh
            {
                Draw = meshDraw,
            };

            simpleEffect             = new Effect(GraphicsDevice, SpriteEffect.Bytecode);
            parameterCollection      = new ParameterCollection();
            parameterCollectionGroup = new EffectParameterCollectionGroup(GraphicsDevice, simpleEffect, new[] { parameterCollection });
            parameterCollection.Set(TexturingKeys.Texture0, UVTexture);

            vao = VertexArrayObject.New(GraphicsDevice, mesh.Draw.IndexBuffer, mesh.Draw.VertexBuffers);

            myDraws    = new DrawOptions[3];
            myDraws[0] = new DrawOptions {
                Sampler = GraphicsDevice.SamplerStates.LinearClamp, Transform = Matrix.Multiply(Matrix.Scaling(0.4f), Matrix.Translation(-0.5f, 0.5f, 0f))
            };
            myDraws[1] = new DrawOptions {
                Sampler = GraphicsDevice.SamplerStates.LinearWrap, Transform = Matrix.Multiply(Matrix.Scaling(0.4f), Matrix.Translation(0.5f, 0.5f, 0f))
            };
            myDraws[2] = new DrawOptions {
                Sampler = SamplerState.New(GraphicsDevice, new SamplerStateDescription(TextureFilter.Linear, TextureAddressMode.Mirror)), Transform = Matrix.Multiply(Matrix.Scaling(0.4f), Matrix.Translation(0.5f, -0.5f, 0f))
            };
            //var borderDescription = new SamplerStateDescription(TextureFilter.Linear, TextureAddressMode.Border) { BorderColor = Color.Purple };
            //var border = SamplerState.New(GraphicsDevice, borderDescription);
            //myDraws[3] = new DrawOptions { Sampler = border, Transform = Matrix.Multiply(Matrix.Scale(0.3f), Matrix.Translation(-0.5f, -0.5f, 0f)) };
        }
Пример #18
0
        /// <summary>
        /// Begins a sprite batch rendering using the specified sorting mode and blend state, sampler, depth stencil, rasterizer state objects, plus a custom effect and a 2D transformation matrix. Passing null for any of the state objects selects the default default state objects (BlendState.AlphaBlend, DepthStencilState.Default, RasterizerState.CullCounterClockwise, SamplerState.LinearClamp). Passing a null effect selects the default SpriteBatch Class shader.
        /// </summary>
        /// <param name="viewMatrix">The view matrix to use for the batch session</param>
        /// <param name="projectionMatrix">The projection matrix to use for the batch session</param>
        /// <param name="sortMode">The sprite drawing order to use for the batch session</param>
        /// <param name="blendState">The blending state to use for the batch session</param>
        /// <param name="samplerState">The sampling state to use for the batch session</param>
        /// <param name="depthStencilState">The depth stencil state to use for the batch session</param>
        /// <param name="rasterizerState">The rasterizer state to use for the batch session</param>
        /// <param name="effect">The effect to use for the batch session</param>
        /// <param name="parameterCollectionGroup">The parameter collection group.</param>
        /// <param name="stencilValue">The value of the stencil buffer to take as reference for the batch session</param>
        public void Begin(Matrix viewMatrix, Matrix projectionMatrix, SpriteSortMode sortMode = SpriteSortMode.Deferred, BlendState blendState = null, SamplerState samplerState = null, DepthStencilState depthStencilState = null, RasterizerState rasterizerState = null, Effect effect = null, EffectParameterCollectionGroup parameterCollectionGroup = null, int stencilValue = 0)
        {
            CheckEndHasBeenCalled("begin");

            userViewMatrix       = viewMatrix;
            userProjectionMatrix = projectionMatrix;

            Begin(effect, parameterCollectionGroup, sortMode, blendState, samplerState, depthStencilState, rasterizerState, stencilValue);
        }
Пример #19
0
        /// <summary>
        /// Draw this effect mesh.
        /// </summary>
        public void Draw(RenderContext context)
        {
            // Retrieve effect parameters
            var mesh = Mesh;
            var currentRenderData = mesh.Draw;
            var material          = Material;
            var vao       = vertexArrayObject;
            var drawCount = currentRenderData.DrawCount;

            if (context.IsPicking()) // TODO move this code corresponding to picking outside of the runtime code!
            {
                parameters.Set(ModelComponentPickingShaderKeys.ModelComponentId, new Color4(RenderModel.ModelComponent.Id));
                parameters.Set(ModelComponentPickingShaderKeys.MeshId, new Color4(Mesh.NodeIndex));
                parameters.Set(ModelComponentPickingShaderKeys.MaterialId, new Color4(Mesh.MaterialIndex));
            }

            if (material != null && material.TessellationMethod != ParadoxTessellationMethod.None)
            {
                var tessellationMethod = material.TessellationMethod;

                // adapt the primitive type and index buffer to the tessellation used
                if (tessellationMethod.PerformsAdjacentEdgeAverage())
                {
                    vao       = GetOrCreateVertexArrayObjectAEN(context);
                    drawCount = 12 / 3 * drawCount;
                }
                currentRenderData.PrimitiveType = tessellationMethod.GetPrimitiveType();
            }

            //using (Profiler.Begin(ProfilingKeys.PrepareMesh))
            {
                // Order of application of parameters:
                // - RenderPass.Parameters
                // - ModelComponent.Parameters
                // - RenderMesh.Parameters (originally copied from mesh parameters)
                // The order is based on the granularity level of each element and how shared it can be. Material is heavily shared, a model contains many meshes. An renderMesh is unique.
                // TODO: really copy mesh parameters into renderMesh instead of just referencing the meshDraw parameters.

                //var modelComponent = RenderModel.ModelComponent;
                //var hasModelComponentParams = modelComponent != null && modelComponent.Parameters != null;

                //var materialParameters = material != null && material.Parameters != null ? material.Parameters : null;

                parameterCollections.Clear();

                parameterCollections.Add(context.Parameters);
                FillParameterCollections(parameterCollections);

                // Check if we need to recreate the EffectParameterCollectionGroup
                // TODO: We can improve performance by redesigning FillParameterCollections to avoid ArrayExtensions.ArraysReferenceEqual (or directly check the appropriate parameter collections)
                // This also happens in another place: DynamicEffectCompiler (we probably want to factorize it when doing additional optimizations)
                if (parameterCollectionGroup == null || parameterCollectionGroup.Effect != Effect || !ArrayExtensions.ArraysReferenceEqual(previousParameterCollections, parameterCollections))
                {
                    parameterCollectionGroup     = new EffectParameterCollectionGroup(context.GraphicsDevice, Effect, parameterCollections);
                    previousParameterCollections = parameterCollections.ToArray();
                }

                Effect.Apply(context.GraphicsDevice, parameterCollectionGroup, true);
            }

            //using (Profiler.Begin(ProfilingKeys.RenderMesh))
            {
                if (currentRenderData != null)
                {
                    var graphicsDevice = context.GraphicsDevice;

                    graphicsDevice.SetVertexArrayObject(vao);

                    if (currentRenderData.IndexBuffer == null)
                    {
                        graphicsDevice.Draw(currentRenderData.PrimitiveType, drawCount, currentRenderData.StartLocation);
                    }
                    else
                    {
                        graphicsDevice.DrawIndexed(currentRenderData.PrimitiveType, drawCount, currentRenderData.StartLocation);
                    }
                }
            }
        }
Пример #20
0
        /// <summary>
        /// Draw this effect mesh.
        /// </summary>
        public void Draw(RenderContext context)
        {
            // Retrieve effect parameters
            var mesh = Mesh;
            var currentRenderData = mesh.Draw;
            var material = Material;
            var vao = vertexArrayObject;
            var drawCount = currentRenderData.DrawCount;

            if (context.IsPicking()) // TODO move this code corresponding to picking outside of the runtime code!
            {
                parameters.Set(ModelComponentPickingShaderKeys.ModelComponentId, new Color4(RenderModel.ModelComponent.Id));
                parameters.Set(ModelComponentPickingShaderKeys.MeshId, new Color4(Mesh.NodeIndex));
                parameters.Set(ModelComponentPickingShaderKeys.MaterialId, new Color4(Mesh.MaterialIndex));
            }

            if (material != null && material.TessellationMethod != ParadoxTessellationMethod.None)
            {
                var tessellationMethod = material.TessellationMethod;

                // adapt the primitive type and index buffer to the tessellation used
                if (tessellationMethod.PerformsAdjacentEdgeAverage())
                {
                    vao = GetOrCreateVertexArrayObjectAEN(context);
                    drawCount = 12 / 3 * drawCount;
                }
                currentRenderData.PrimitiveType = tessellationMethod.GetPrimitiveType();
            }

            //using (Profiler.Begin(ProfilingKeys.PrepareMesh))
            {
                // Order of application of parameters:
                // - RenderPass.Parameters
                // - ModelComponent.Parameters
                // - RenderMesh.Parameters (originally copied from mesh parameters)
                // The order is based on the granularity level of each element and how shared it can be. Material is heavily shared, a model contains many meshes. An renderMesh is unique.
                // TODO: really copy mesh parameters into renderMesh instead of just referencing the meshDraw parameters.

                //var modelComponent = RenderModel.ModelComponent;
                //var hasModelComponentParams = modelComponent != null && modelComponent.Parameters != null;
                
                //var materialParameters = material != null && material.Parameters != null ? material.Parameters : null;

                parameterCollections.Clear();

                parameterCollections.Add(context.Parameters);
                FillParameterCollections(parameterCollections);

                // Check if we need to recreate the EffectParameterCollectionGroup
                // TODO: We can improve performance by redesigning FillParameterCollections to avoid ArrayExtensions.ArraysReferenceEqual (or directly check the appropriate parameter collections)
                // This also happens in another place: DynamicEffectCompiler (we probably want to factorize it when doing additional optimizations)
                if (parameterCollectionGroup == null || parameterCollectionGroup.Effect != Effect || !ArrayExtensions.ArraysReferenceEqual(previousParameterCollections, parameterCollections))
                {
                    parameterCollectionGroup = new EffectParameterCollectionGroup(context.GraphicsDevice, Effect, parameterCollections);
                    previousParameterCollections = parameterCollections.ToArray();
                }

                Effect.Apply(context.GraphicsDevice, parameterCollectionGroup, true);
            }

            //using (Profiler.Begin(ProfilingKeys.RenderMesh))
            {
                if (currentRenderData != null)
                {
                    var graphicsDevice = context.GraphicsDevice;

                    graphicsDevice.SetVertexArrayObject(vao);

                    if (currentRenderData.IndexBuffer == null)
                    {
                        graphicsDevice.Draw(currentRenderData.PrimitiveType, drawCount, currentRenderData.StartLocation);
                    }
                    else
                    {
                        graphicsDevice.DrawIndexed(currentRenderData.PrimitiveType, drawCount, currentRenderData.StartLocation);
                    }
                }
            }
        }
Пример #21
0
        protected override void DrawCore(RenderContext context)
        {
            UpdateEffect();

            if (effectParameterCollections == null || EffectInstance.Effect != effectParameterCollections.Effect)
            {
                // Update parameters
                appliedParameterCollections.Clear();
                if (context != null)
                {
                    appliedParameterCollections.Add(context.Parameters);
                }

                foreach (var parameterCollection in parameterCollections)
                {
                    appliedParameterCollections.Add(parameterCollection);
                }

                effectParameterCollections = new EffectParameterCollectionGroup(GraphicsDevice, EffectInstance.Effect, appliedParameterCollections.ToArray());
            }

            // Draw a full screen quad
            GraphicsDevice.DrawQuad(EffectInstance.Effect, effectParameterCollections);
        }
Пример #22
0
        /// <summary>
        /// Draw this effect mesh.
        /// </summary>
        public void Draw(RenderContext context)
        {
            // Retrieve effect parameters
            var graphicsDevice    = context.GraphicsDevice;
            var mesh              = Mesh;
            var currentRenderData = mesh.Draw;
            var material          = Material;
            var vao           = vertexArrayObject;
            var drawCount     = currentRenderData.DrawCount;
            var primitiveType = currentRenderData.PrimitiveType;

            parameters.Set(TransformationKeys.World, WorldMatrix);

            // TODO: We should clarify exactly how to override rasterizer states. Currently setup here on Context.Parameters to allow Material/ModelComponent overrides, but this is ugly
            // Apply rasterizer
            var rasterizer = RasterizerState;

            if (!ForceRasterizer && Material.CullMode.HasValue && Material.CullMode.Value != RasterizerState.Description.CullMode)
            {
                switch (Material.CullMode.Value)
                {
                case CullMode.Back:
                    rasterizer = graphicsDevice.RasterizerStates.CullBack;
                    break;

                case CullMode.Front:
                    rasterizer = graphicsDevice.RasterizerStates.CullFront;
                    break;

                case CullMode.None:
                    rasterizer = graphicsDevice.RasterizerStates.CullNone;
                    break;
                }
            }
            context.Parameters.Set(Effect.RasterizerStateKey, rasterizer);

            // Handle picking
            if (context.IsPicking()) // TODO move this code corresponding to picking outside of the runtime code!
            {
                parameters.Set(ModelComponentPickingShaderKeys.ModelComponentId, new Color4(RenderModel.ModelComponent.Id));
                parameters.Set(ModelComponentPickingShaderKeys.MeshId, new Color4(RenderModel.ModelComponent.Model.Meshes.IndexOf(Mesh)));
                parameters.Set(ModelComponentPickingShaderKeys.MaterialId, new Color4(Mesh.MaterialIndex));

                // Don't use the materials blend state on picking targets
                parameters.Set(Effect.BlendStateKey, null);
            }

            if (material != null && material.TessellationMethod != ParadoxTessellationMethod.None)
            {
                var tessellationMethod = material.TessellationMethod;

                // adapt the primitive type and index buffer to the tessellation used
                if (tessellationMethod.PerformsAdjacentEdgeAverage())
                {
                    vao       = GetOrCreateVertexArrayObjectAEN(context);
                    drawCount = 12 / 3 * drawCount;
                }
                primitiveType = tessellationMethod.GetPrimitiveType();
            }

            //using (Profiler.Begin(ProfilingKeys.PrepareMesh))
            {
                // Order of application of parameters:
                // - RenderPass.Parameters
                // - ModelComponent.Parameters
                // - RenderMesh.Parameters (originally copied from mesh parameters)
                // The order is based on the granularity level of each element and how shared it can be. Material is heavily shared, a model contains many meshes. An renderMesh is unique.
                // TODO: really copy mesh parameters into renderMesh instead of just referencing the meshDraw parameters.

                //var modelComponent = RenderModel.ModelComponent;
                //var hasModelComponentParams = modelComponent != null && modelComponent.Parameters != null;

                //var materialParameters = material != null && material.Parameters != null ? material.Parameters : null;

                parameterCollections.Clear();

                parameterCollections.Add(context.Parameters);
                FillParameterCollections(ref parameterCollections);

                // Check if we need to recreate the EffectParameterCollectionGroup
                // TODO: We can improve performance by redesigning FillParameterCollections to avoid ArrayExtensions.ArraysReferenceEqual (or directly check the appropriate parameter collections)
                // This also happens in another place: DynamicEffectCompiler (we probably want to factorize it when doing additional optimizations)
                if (parameterCollectionGroup == null || parameterCollectionGroup.Effect != Effect || !ArrayExtensions.ArraysReferenceEqual(ref previousParameterCollections, ref parameterCollections))
                {
                    previousParameterCollections.Clear();
                    previousParameterCollections.AddRange(parameterCollections);
                    parameterCollectionGroup = new EffectParameterCollectionGroup(context.GraphicsDevice, Effect, previousParameterCollections.Count, previousParameterCollections.Items);
                }

                Effect.Apply(context.GraphicsDevice, parameterCollectionGroup, true);
            }

            //using (Profiler.Begin(ProfilingKeys.RenderMesh))
            {
                if (currentRenderData != null)
                {
                    graphicsDevice.SetVertexArrayObject(vao);

                    if (currentRenderData.IndexBuffer == null)
                    {
                        graphicsDevice.Draw(primitiveType, drawCount, currentRenderData.StartLocation);
                    }
                    else
                    {
                        graphicsDevice.DrawIndexed(primitiveType, drawCount, currentRenderData.StartLocation);
                    }
                }
            }
        }