public unsafe RenderBuffer <float> Draw <T>(RenderEntity[] entities, T camera) where T : ICamera { Clear(); int entityCount = entities.Length; BeginRasterize(); SetPerRenderValues(camera); for (int i = 0; i < entityCount; i++) { RenderEntity currentEntity = entities[i]; SetPerObjectValues(currentEntity); Material material = currentEntity.Material ?? DEFAULT_MATERIAL; Model model = currentEntity.Model; #region Vertex Stage //Prepare vertex shader VertexInvoker.ChangeActiveShader(material.ShaderType, material.Shader); //Invoke vertex shader int vertexCount = model.Vertices.Length; Vector2 *coordsOutput = stackalloc Vector2[vertexCount]; ShaderInOutPatternDefault *inoutPtr = stackalloc ShaderInOutPatternDefault[1]; for (int j = 0; j < vertexCount; j++) { VertexInvoker.Invoke(model.ReadVerticesDataAsPattern(j)); VertexInvoker.ActiveOutputMap.Write(inoutPtr); coordsOutput[j] = *(Vector2 *)&inoutPtr->Vertex; } #endregion #region Fragment Stage FragmentInvoker.ChangeActiveShader(material.ShaderType, material.Shader); //Primitive assemble int newPrimitiveCount = AssemblePrimitive(model, coordsOutput); _rasterizedFragments.AddEmpty(newPrimitiveCount); switch (_assembleMode) { case PrimitiveAssembleMode.Line: case PrimitiveAssembleMode.LineTriangle: Rasterize <LinePrimitive, Line>(_linePrimitives.GetPointer(_linePrimitives.Count - newPrimitiveCount), newPrimitiveCount, _rasterizedFragments.GetPointer(_rasterizedFragments.Count - newPrimitiveCount)); break; case PrimitiveAssembleMode.Triangle: Rasterize <TrianglePrimitive, Triangle>(_trianglePrimitives.GetPointer(_trianglePrimitives.Count - newPrimitiveCount), newPrimitiveCount, _rasterizedFragments.GetPointer(_rasterizedFragments.Count - newPrimitiveCount)); break; } for (int j = _rasterizedFragments.Count - newPrimitiveCount; j < _rasterizedFragments.Count; j++) { Fragment *fragment = _rasterizedFragments.GetPointer(j); for (int k = 0; k < fragment->PixelCount; k++) { //Fragment.FragmentData has been tailored to a proper size FragmentInvoker.Invoke((byte *)fragment->FragmentData[k]); FragmentInvoker.ActiveOutputMap.Write(inoutPtr); _renderedColors.Add(inoutPtr->Color); } fragment->FragmentColor = _renderedColors.ArchivePointer(); } #endregion } EndRasterize(); //Octree is so annoying //TODO: View frustum clip, triangle clip, pixel clip //Clipping(); //This is not the proper way to output, rather for debugging for (int i = 0; i < _rasterizedFragments.Count; i++) { Fragment *fragmentPtr = _rasterizedFragments.GetPointer(i); RenderTarget.WritePixel(fragmentPtr->Rasterization, fragmentPtr->PixelCount, fragmentPtr->FragmentColor); } return(RenderTarget); }