public int ApplyViewParameters_PopulateParameterLightsOrig()
        {
            int sum = 0;

            for (int ii = 0; ii < N; ii++)
            {
                for (int viewIndex = 0; viewIndex < lightRanges.Length; viewIndex++)
                {
                    var lightRange = lightRanges[viewIndex];
                    PopulateLightsInRange(ref lights, lightRange, ref currentLights);

                    lightsData.Clear();
                    // ----- Test
                    foreach (var lightEntry in currentLights)
                    {
                        var light = lightEntry.Light;
                        lightsData.Add(new DirectionalLightData
                        {
                            DirectionWS = light.Direction,
                            Color       = light.Color,
                        });
                    }

                    // ----- End Test
                    sum += lightsData.Count;
                }
            }
            return(sum);
        }
            public override void ApplyViewParameters(RenderDrawContext context, int viewIndex, ParameterCollection parameters)
            {
                CurrentLights.Clear();
                var lightRange = LightRanges[viewIndex];

                for (int i = lightRange.Start; i < lightRange.End; ++i)
                {
                    CurrentLights.Add(Lights[i]);
                }

                base.ApplyViewParameters(context, viewIndex, parameters);

                foreach (var lightEntry in CurrentLights)
                {
                    var light = lightEntry.Light;
                    lightsData.Add(new DirectionalLightData
                    {
                        DirectionWS = light.Direction,
                        Color       = light.Color,
                    });
                }

                parameters.Set(countKey, lightsData.Count);
                parameters.Set(lightsKey, lightsData.Count, ref lightsData.Items[0]);
                lightsData.Clear();
            }
示例#3
0
        /// <summary>
        /// Updates the dynamic effect if the shader code has changed
        /// </summary>
        /// <param name="graphicsDevice">The current <see cref="GraphicsDevice"/></param>
        private void UpdateEffect(GraphicsDevice graphicsDevice)
        {
            if (effectCompilationAttemptCountdown > 0)
            {
                effectCompilationAttemptCountdown--;
                return;
            }

            try
            {
                effectCompiler.Update(effectInstance, null);
            }
            catch (Exception)
            {
                // If the compilation fails do not update the current effect and try again later
                effectCompilationAttemptCountdown = 30; // Try again in 30 frames
                VertexLayoutHasChanged            = false;
                return;
            }

            effect = effectInstance.Effect;

            NewParameterCollections.Clear();
            NewParameterCollections.AddRange(ParameterCollections.ToArray());

            // Get or create parameter collection
            if (parameterCollectionGroup == null || parameterCollectionGroup.Effect != effect || !ArrayExtensions.ArraysReferenceEqual(ref OldParameterCollections, ref NewParameterCollections))
            {
                // It is quite inefficient if user is often switching effect without providing a matching ParameterCollectionGroup
                parameterCollectionGroup = new EffectParameterCollectionGroup(graphicsDevice, effect, ParameterCollections.ToArray());

                OldParameterCollections.Clear();
                OldParameterCollections.AddRange(NewParameterCollections);
            }
        }
示例#4
0
 public void Dispose()
 {
     for (int i = 0; i < RenderMeshesPerEffectSlot.Count; i++)
     {
         ReleaseSlot(i);
     }
     RenderMeshesPerEffectSlot.Clear();
 }
            public override void ApplyDrawParameters(RenderDrawContext context, int viewIndex, ParameterCollection parameters, ref BoundingBoxExt boundingBox)
            {
                if (currentLights.Items == null)
                {
                    currentLights = new FastListStruct <LightDynamicEntry>(8);
                }
                else
                {
                    currentLights.Clear();
                }
                if (lightsData.Items == null)
                {
                    lightsData = new FastListStruct <SpotLightData>(8);
                }

                var lightRange = lightRanges[viewIndex];

                for (int i = lightRange.Start; i < lightRange.End; ++i)
                {
                    currentLights.Add(lights[i]);
                }

                base.ApplyDrawParameters(context, viewIndex, parameters, ref boundingBox);

                // TODO: Octree structure to select best lights quicker
                var boundingBox2 = (BoundingBox)boundingBox;

                for (int i = 0; i < currentLights.Count; i++)
                {
                    var light = currentLights[i].Light;

                    if (light.BoundingBox.Intersects(ref boundingBox2))
                    {
                        var spotLight = (LightSpot)light.Type;
                        lightsData.Add(new SpotLightData
                        {
                            PositionWS  = light.Position,
                            DirectionWS = light.Direction,
                            AngleOffsetAndInvSquareRadius = new Vector3(spotLight.LightAngleScale, spotLight.LightAngleOffset, spotLight.InvSquareRange),
                            Color = light.Color,
                        });

                        // Did we reach max number of simultaneous lights?
                        // TODO: Still collect everything but sort by importance and remove the rest?
                        if (lightsData.Count >= LightCurrentCount)
                        {
                            break;
                        }
                    }
                }

                parameters.Set(countKey, lightsData.Count);
                parameters.Set(lightsKey, lightsData.Count, ref lightsData.Items[0]);

                TextureProjectionShaderGroupData?.ApplyDrawParameters(context, parameters, currentLights, ref boundingBox);

                lightsData.Clear();
            }
示例#6
0
            public override void ApplyDrawParameters(RenderDrawContext context, int viewIndex, ParameterCollection parameters, ref BoundingBoxExt boundingBox)
            {
                if (currentLights.Items == null)
                {
                    currentLights = new FastListStruct <LightDynamicEntry>(8);
                }
                else
                {
                    currentLights.Clear();
                }
                if (lightsData.Items == null)
                {
                    lightsData = new FastListStruct <PointLightData>(8);
                }

                var lightRange = lightRanges[viewIndex];

                for (int i = lightRange.Start; i < lightRange.End; ++i)
                {
                    currentLights.Add(lights[i]);
                }

                base.ApplyDrawParameters(context, viewIndex, parameters, ref boundingBox);

                // TODO: Since we cull per object, we could maintain a higher number of allowed light than the shader support (i.e. 4 lights active per object even though the scene has many more of them)
                // TODO: Octree structure to select best lights quicker
                var boundingBox2 = (BoundingBox)boundingBox;

                foreach (var lightEntry in currentLights)
                {
                    var light = lightEntry.Light;

                    if (light.BoundingBox.Intersects(ref boundingBox2))
                    {
                        var pointLight = (LightPoint)light.Type;
                        lightsData.Add(new PointLightData
                        {
                            PositionWS      = light.Position,
                            InvSquareRadius = pointLight.InvSquareRadius,
                            Color           = light.Color,
                        });

                        // Did we reach max number of simultaneous lights?
                        // TODO: Still collect everything but sort by importance and remove the rest?
                        if (lightsData.Count >= LightCurrentCount)
                        {
                            break;
                        }
                    }
                }

                parameters.Set(countKey, lightsData.Count);
                parameters.Set(lightsKey, lightsData.Count, ref lightsData.Items[0]);
                lightsData.Clear();
            }
            public override void ApplyDrawParameters(RenderDrawContext context, int viewIndex, ParameterCollection parameters, ref BoundingBoxExt boundingBox)
            {
                // TODO THREADING: Make CurrentLights and lightData (thread-) local
                lock (applyLock)
                {
                    CurrentLights.Clear();
                    var lightRange = LightRanges[viewIndex];
                    for (int i = lightRange.Start; i < lightRange.End; ++i)
                    {
                        CurrentLights.Add(Lights[i]);
                    }

                    base.ApplyDrawParameters(context, viewIndex, parameters, ref boundingBox);

                    // TODO: Octree structure to select best lights quicker
                    var boundingBox2 = (BoundingBox)boundingBox;
                    for (int i = 0; i < CurrentLights.Count; i++)
                    {
                        var light = CurrentLights[i].Light;

                        if (light.BoundingBox.Intersects(ref boundingBox2))
                        {
                            var spotLight = (LightSpot)light.Type;
                            lightsData.Add(new SpotLightData
                            {
                                PositionWS  = light.Position,
                                DirectionWS = light.Direction,
                                AngleOffsetAndInvSquareRadius = new Vector3(spotLight.LightAngleScale, spotLight.LightAngleOffset, spotLight.InvSquareRange),
                                Color = light.Color,
                            });

                            // Did we reach max number of simultaneous lights?
                            // TODO: Still collect everything but sort by importance and remove the rest?
                            if (lightsData.Count >= LightCurrentCount)
                            {
                                break;
                            }
                        }
                    }

                    parameters.Set(countKey, lightsData.Count);
                    parameters.Set(lightsKey, lightsData.Count, ref lightsData.Items[0]);
                    lightsData.Clear();
                }
            }
示例#8
0
        protected override void DrawCore(RenderContext context, RenderItemCollection renderItemList, int fromIndex, int toIndex)
        {
            if (dynamicEffectCompiler == null)
            {
                throw new InvalidOperationException("This instance is not correctly initialized (no EffectName)");
            }

            // Get all meshes from render models
            meshesToRender.Clear();
            for (int i = fromIndex; i <= toIndex; i++)
            {
                meshesToRender.Add((RenderMesh)renderItemList[i].DrawContext);
            }

            // Slow path there is a callback
            if (Callbacks.UpdateMeshes != null)
            {
                Callbacks.UpdateMeshes(context, ref meshesToRender);
            }

            // Fetch callback on PreRenderGroup
            var preRenderMesh = Callbacks.PreRenderMesh;

            for (int i = 0; i < meshesToRender.Count; i++)
            {
                var renderMesh = meshesToRender[i];

                // If the EntityGroup is changing, call the callback to allow to plug specific parameters for this group
                if (preRenderMesh != null)
                {
                    preRenderMesh(context, renderMesh);
                }

                // Update Effect and mesh
                UpdateEffect(context, renderMesh, context.Parameters);

                // Draw the mesh
                renderMesh.Draw(context);
            }
        }
示例#9
0
            public override void ApplyViewParameters(RenderDrawContext context, int viewIndex, ParameterCollection parameters)
            {
                if (currentLights.Items == null)
                {
                    currentLights = new FastListStruct <LightDynamicEntry>(8);
                }
                else
                {
                    currentLights.Clear();
                }
                if (lightsData.Items == null)
                {
                    lightsData = new FastListStruct <DirectionalLightData>(8);
                }

                var lightRange = lightRanges[viewIndex];

                for (int i = lightRange.Start; i < lightRange.End; ++i)
                {
                    currentLights.Add(lights[i]);
                }

                base.ApplyViewParameters(context, viewIndex, parameters);

                foreach (var lightEntry in currentLights)
                {
                    var light = lightEntry.Light;
                    lightsData.Add(new DirectionalLightData
                    {
                        DirectionWS = light.Direction,
                        Color       = light.Color,
                    });
                }

                parameters.Set(countKey, lightsData.Count);
                parameters.Set(lightsKey, lightsData.Count, ref lightsData.Items[0]);
                lightsData.Clear();
            }
示例#10
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);
                    }
                }
            }
        }