示例#1
0
        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);
        }