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(); }
/// <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); } }
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(); }
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(); } }
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); } }
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(); }
/// <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); } } } }