public override void Unload() { if (!OfflineCompilation) { foreach (var effectMesh in effectMeshes) { RenderSystem.GlobalMeshes.RemoveMesh(effectMesh); } effectMeshes.Clear(); } RenderPass.RemovePass(boundingBoxPass); RenderPass.RemovePass(heatShimmerPass); RenderPass.RemovePass(heatShimmerComposePass); base.Unload(); }
public override void Unload() { RenderPass.RemovePass(PostPass); base.Unload(); }
private void OnFrameUpdate(ThreadContext context) { updatePasses.Enabled = true; //!RenderContext.IsPaused; // Add new updater to the current list foreach (var particleUpdater in Updaters) { ParticleUpdaterState particleUpdaterState = null; foreach (ParticleUpdaterState state in currentUpdaters) { if (ReferenceEquals(state.UserState, particleUpdater)) { particleUpdaterState = state; break; } } if (particleUpdaterState == null) { currentUpdaters.Add(new ParticleUpdaterState() { UserState = particleUpdater, StructureSize = StructureSize }); } } // Get updater to remove from current list foreach (var particleUpdater in currentUpdaters) { ParticleEmitterComponent particleUpdaterState = null; foreach (ParticleEmitterComponent state in Updaters) { if (ReferenceEquals(state, particleUpdater.UserState)) { particleUpdaterState = state; break; } } if (particleUpdaterState == null) { updatersToRemove.Add(particleUpdater); } } // Remove from the current list foreach (var particleUpdaterState in updatersToRemove) { currentUpdaters.Remove(particleUpdaterState); // Remove the mesh to be rendered meshesToRender.RemoveMesh(particleUpdaterState.MeshUpdater); // Dispose the previous particule updater as it is no longer used particleUpdaterState.DisposeBuffers(); } // Reallocate global buffers if needed if (updatersCount > capacityCount) { CapacityCount = updatersCount; OnCapacityCountChange(); } int particleUpdaterIndex = 1; currentParticleCount = 0; // Update start index into global buffers for all CPU/GPU static buffers. int startIndex = 0; for (int i = 0; i < currentUpdaters.Count; i++) { var currentState = currentUpdaters[i]; var userState = currentState.UserState; if (!userState.IsDynamicEmitter) { // If there is a change from dynamic type to CPU/GPU static buffer, we need to deallocate previous Append/ConsumeBuffers if (currentState.IsDynamicEmitter) { currentState.DisposeBuffers(); } } else if (userState.Count > currentState.Count) { // This is a dynamic buffer and the new buffer is larger than previous one // or we simply need to allocate new consume/append buffers currentState.AllocateBuffers(context.GraphicsDevice); } // Create Effect shader if (!ReferenceEquals(userState.Shader, currentState.Shader) || currentState.Count != userState.Count) { // Remove the effect pass updatePasses.RemovePass(currentState.EffectPass); // Dispose previous effects currentState.DisposeEffects(); // Remove mesh if (currentState.MeshUpdater != null) { meshesToRender.RemoveMesh(currentState.MeshUpdater); currentState.MeshUpdater = null; } // Compile new shader if (userState.Shader != null) { string name = userState.Name ?? string.Format("{0}{1}", userState.Shader.ClassName, particleUpdaterIndex++); currentState.EffectPass = new RenderPass(name); updatePasses.AddPass(currentState.EffectPass); // Calculate the best dispatch thread count int dispatchCount = MaximumThreadPerGroup; while (dispatchCount > 0) { // If the maximum count is a multiple of the current dispatchCount use it if ((userState.Count & (dispatchCount - 1)) == 0) { break; } dispatchCount >>= 1; } // Compile the new shader for this count currentState.EffectUpdater = this.EffectSystemOld.BuildEffect(name).Using( new ComputeShaderPlugin(userState.Shader, dispatchCount, 1, 1) { RenderPass = currentState.EffectPass, Macros = { new ShaderMacro("PARTICLE_STRUCT", StructureName) } }); // Instantiate the mesh updater var meshParams = new ParameterCollection(name); currentState.MeshUpdater = new EffectMesh(currentState.EffectUpdater, new Mesh { Parameters = meshParams }).Dispatch(userState.Count / dispatchCount, 1, 1); currentState.MeshUpdater.Parameters.AddSources(Parameters); currentState.MeshUpdater.Parameters.AddSources(MainPlugin.ViewParameters); currentState.MeshUpdater.Parameters.AddSources(userState.Parameters); // Setup Append/Consume if (userState.IsDynamicEmitter) { currentState.MeshUpdater.Parameters.Set(ParticleBaseKeys.ParticleInputBuffer, currentState.ConsumeBuffer); currentState.MeshUpdater.Parameters.Set(ParticleBaseKeys.ParticleOutputBuffer, currentState.AppendBuffer); currentState.MeshUpdater.Parameters.Set(ParticleBaseKeys.ParticleStartIndex, (uint)0); } else { // Setup update on global buffer currentState.MeshUpdater.Parameters.Set(ParticleBaseKeys.ParticleGlobalBuffer, globalBuffer); currentState.MeshUpdater.Parameters.Set(ParticleBaseKeys.ParticleStartIndex, (uint)startIndex); } // Add this updater to the rendering list meshesToRender.AddMesh(currentState.MeshUpdater); } } // Setup Append/Consume if (currentState.MeshUpdater != null && !userState.IsDynamicEmitter && currentState.StartIndex != startIndex) { // Setup update on global buffer currentState.MeshUpdater.Parameters.Set(ParticleBaseKeys.ParticleStartIndex, (uint)startIndex); } // Transfer CPU buffer to GPU if (!ReferenceEquals(userState.ParticleData, currentState.ParticleData) || userState.UpdateNextBuffer || userState.Type == ParticleEmitterType.CpuDynamic || currentState.StartIndex != startIndex || currentState.Count != userState.Count ) { // Update the data if necessary userState.OnUpdateData(); if (userState.ParticleData != null) { var handle = GCHandle.Alloc(userState.ParticleData, GCHandleType.Pinned); globalBuffer.SetData(context.GraphicsDevice, new DataPointer(handle.AddrOfPinnedObject(), userState.Count * StructureSize), startIndex * StructureSize); handle.Free(); } userState.UpdateNextBuffer = false; } // Replicate the shader to the current state currentState.Type = userState.Type; currentState.Shader = userState.Shader; currentState.Count = userState.Count; currentState.ParticleElementSize = userState.ParticleElementSize; currentState.ParticleData = userState.ParticleData; currentState.StartIndex = startIndex; // Copy Maximum count to current state currentParticleCount += userState.Count; // Update start index startIndex += userState.Count; } // Add mesh to the render list if (updatersCount > 0) { if (!isParticleRenderingEnabled) { isParticleRenderingEnabled = true; meshesToRender.AddMesh(effectMeshRender); meshesToRender.AddMesh(effectMeshCopyToSortBuffer); } } else { isParticleRenderingEnabled = false; meshesToRender.RemoveMesh(effectMeshRender); meshesToRender.RemoveMesh(effectMeshCopyToSortBuffer); } // Prepare mesh for rendering PrepareForRendering(); }