Beispiel #1
0
        public void Perform(PrimitiveType type)
        {
            //Make sure the render target is binded
            RenderTarget.Bind(Target);

            //Set render target
            if (state.Target != Target)
            {
                state.Target = Target;
                if (Target != null)
                {
                    GL.Viewport(0, 0, Target.Width, Target.Height);
                }
                else
                {
                    GL.Viewport(0, 0, Screen.DrawWidth, Screen.DrawHeight);
                }
            }

            //Set blend mode
            if (Blend)
            {
                if (!state.Blend || !BlendMode.Equals(ref state.BlendMode))
                {
                    if (!state.Blend)
                    {
                        state.Blend = true;
                        GL.Enable(EnableCap.Blend);
                    }
                    state.BlendMode = BlendMode;
                    GL.BlendEquation(BlendMode.Eq);
                    GL.BlendFunc(BlendMode.Src, BlendMode.Dst);
                }
            }
            else if (state.Blend)
            {
                state.Blend = false;
                GL.Disable(EnableCap.Blend);
            }

            //TODO: might be nice if clipping actually used proper coordinates,
            //but we'll have to make it *always* update, and use the Target's height

            //Set clipping
            if (Clip)
            {
                if (!state.Clip)
                {
                    state.Clip = true;
                    GL.Enable(EnableCap.ScissorTest);
                }
                //GL.Scissor(ClipRect.X, ClipRect.Y, ClipRect.W, ClipRect.H);
                GL.Scissor(ClipRect.X, (Target != null ? Target.Height : Screen.DrawHeight) - ClipRect.MaxY, ClipRect.W, ClipRect.H);
            }
            else if (state.Clip)
            {
                state.Clip = false;
                GL.Disable(EnableCap.ScissorTest);
            }

            //We need a material and a valid mesh in order to draw
            if (Mesh == null || Material == null || Mesh.uploadedIndexCount == 0 || Mesh.uploadedVertexCount == 0)
            {
                return;
            }

            //Sync the shader's state with the material
            bool uploadAll = false;

            if (state.Material != Material)
            {
                if (state.Material == null || state.Material.Shader != Material.Shader)
                {
                    GL.UseProgram(Material.Shader.id);
                    uploadAll = true;
                }
                state.Material = Material;
            }
            Material.Upload(uploadAll);

            //Bind the vertex array
            if (state.Mesh != Mesh || Mesh.dirty)
            {
                GL.BindVertexArray(Mesh.vaoID);
                GL.BindBuffer(BufferTarget.Array, Mesh.arrayID);
                GL.BindBuffer(BufferTarget.ElementArray, Mesh.elementID);
                state.Mesh = Mesh;
                Mesh.dirty = false;
            }

            //Draw the mesh triangles
            GL.DrawElements(type, Mesh.uploadedIndexCount, IndexType.UnsignedInt, IntPtr.Zero);
        }