Ejemplo n.º 1
0
        internal void SetWithResize <T>(ParameterCollection parameterCollection, ParameterKey <T> key, T resourceValue) where T : IReferencable
        {
            parameterCollection.Set(key, resourceValue);
            if (currentAction == null)
            {
                throw new InvalidOperationException("Tried to use SetWithResize outside of a SetupResize callback.");
            }

            currentAction.ParameterLocations.Add(new ParameterLocation {
                ParameterCollection = parameterCollection, ParameterKey = key, Value = resourceValue
            });
        }
Ejemplo n.º 2
0
 public static void EnableFixedAmbientLight(ParameterCollection parameters, bool enable)
 {
     if (parameters == null)
     {
         throw new ArgumentNullException("parameters");
     }
     if (enable)
     {
         parameters.Set(EnvironmentLights, DefaultAmbientLighting);
     }
     else
     {
         parameters.Remove(EnvironmentLights);
     }
 }
Ejemplo n.º 3
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);
                    }
                }
            }
        }