public void RegisterToRenderLoop() { if (!isDirty) { return; } foreach ((uint key, _) in renderActions) { RenderLoop.Loop.Remove(key); } renderActions.Clear(); Renderer renderer = RenderLoop.Render; for (uint i = 0; i < RenderLists.Count; i++) { RenderList list = RenderLists.Array[i]; if (list == null || RenderLoop.Loop.ContainsKey(i)) { continue; } Action <Camera2D> action = cam => renderer.ProcessRenderList(cam, list); renderActions.Add(i, action); RenderLoop.Add(i, action); } isDirty = false; }
public void ProcessRenderList(Camera2D camera, RenderList renderList) { if (renderList == null || renderList.Data.Count < 1) { return; } for (int i = 0; i < renderList.Data.Count; i++) { ThreadSafeList <IRenderable> data = renderList.Data.Array[i]; Effect effect = DrawCallDatabase.LookupArray.Array[i].Effect; switch (renderList.Mode) { case BlendMode.Opaque: ChangeDrawCall( SpriteSortMode.Deferred, camera.ScaleMatrix, BlendState.Opaque, SamplerState.PointClamp, DepthStencilGreater, null, effect); break; case BlendMode.Transparent: data.Sort(new DepthComparer()); ChangeDrawCall( SpriteSortMode.Deferred, camera.ScaleMatrix, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilGreater, null, effect); break; case BlendMode.Additive: data.Sort(new DepthComparer()); ChangeDrawCall( SpriteSortMode.Deferred, camera.ScaleMatrix, BlendState.Additive, SamplerState.PointClamp, DepthStencilGreater, null, effect); break; default: throw new ArgumentOutOfRangeException(nameof(renderList.Mode), renderList.Mode, null); } IRenderable[] renderArray = data.Array; for (int z = 0; z < data.Count; z++) { renderArray[z].Render(camera, Space.World); } } }
public void Add(IRenderable renderObj, bool threadSafe = false) { // Determine if the sprite ignores light or not. bool ignoreLight = true; if (renderObj is ILit lit) { ignoreLight = lit.IgnoreLight; } // Index of the specific RenderList the sprite should be added to. int renderIndex = (int)(ignoreLight ? RenderLoop.LoopEnum.AfterLighting : RenderLoop.LoopEnum.DuringLighting); // Determine if the sprite is transparent. BlendMode blendMode = renderObj.BlendMode; switch (blendMode) { case BlendMode.Opaque: renderIndex += 100; break; case BlendMode.Transparent: renderIndex += 1000; break; case BlendMode.Additive: renderIndex += 2000; break; default: throw new ArgumentOutOfRangeException(); } while (RenderLists.Count < renderIndex + 1) { RenderLists.Add(null); } // Add the sprite to the correct RenderList. RenderList list = RenderLists.Array[renderIndex]; if (list != null) { if (threadSafe) { list.AddThreaded(renderObj.DrawCallID, renderObj); } else { list.Add(renderObj.DrawCallID, renderObj); } } else { if (threadSafe) { lock (RenderLists) { //if (RenderLists.ContainsKey(renderIndex)) // return; RenderList newList = new RenderList(renderIndex, renderObj.BlendMode); newList.AddThreaded(renderObj.DrawCallID, renderObj); RenderLists.Array[renderIndex] = newList; } } else { RenderList newList = new RenderList(renderIndex, renderObj.BlendMode); newList.Add(renderObj.DrawCallID, renderObj); RenderLists.Array[renderIndex] = newList; } isDirty = true; } }