示例#1
0
        [Test] public void VertexAccess()
        {
            VertexBatch <VertexC1P3> typedBatch    = new VertexBatch <VertexC1P3>();
            IVertexBatch             abstractBatch = typedBatch;

            typedBatch.Vertices.Add(new VertexC1P3 {
                Color = new ColorRgba(0)
            });
            typedBatch.Vertices.Add(new VertexC1P3 {
                Color = new ColorRgba(1)
            });
            typedBatch.Vertices.Add(new VertexC1P3 {
                Color = new ColorRgba(2)
            });
            typedBatch.Vertices.Add(new VertexC1P3 {
                Color = new ColorRgba(3)
            });

            Assert.AreEqual(4, typedBatch.Count);
            Assert.AreEqual(4, typedBatch.Vertices.Count);
            Assert.AreEqual(new ColorRgba(0), typedBatch.Vertices[0].Color);
            Assert.AreEqual(new ColorRgba(1), typedBatch.Vertices[1].Color);
            Assert.AreEqual(new ColorRgba(2), typedBatch.Vertices[2].Color);
            Assert.AreEqual(new ColorRgba(3), typedBatch.Vertices[3].Color);

            Assert.AreEqual(4, abstractBatch.Count);

            typedBatch.Clear();

            Assert.AreEqual(0, typedBatch.Count);
            Assert.AreEqual(0, typedBatch.Vertices.Count);
            Assert.AreEqual(0, abstractBatch.Count);
        }
        public override void Draw(IVertexBatch vertexBatch)
        {
            updateVertexBatch();

            // Prefer to use own vertex batch instead of the parent-owned one.
            if (Shared.VertexBatch != null)
            {
                vertexBatch = Shared.VertexBatch;
            }

            base.Draw(vertexBatch);

            drawEdgeEffect();
            if (MaskingInfo != null)
            {
                GLWrapper.PushMaskingInfo(MaskingInfo.Value);
            }

            if (Children != null)
            {
                foreach (DrawNode child in Children)
                {
                    child.Draw(vertexBatch);
                }
            }

            if (MaskingInfo != null)
            {
                GLWrapper.PopMaskingInfo();
            }
        }
示例#3
0
        /// <summary>
        /// Sets the last vertex batch used for drawing.
        /// <para>
        /// This is done so that various methods that change GL state can force-draw the batch
        /// before continuing with the state change.
        /// </para>
        /// </summary>
        /// <param name="batch">The batch.</param>
        internal static void SetActiveBatch(IVertexBatch batch)
        {
            if (lastActiveBatch == batch)
            {
                return;
            }

            FlushCurrentBatch();

            lastActiveBatch = batch;
        }
示例#4
0
        [Test] public void EmptyArray()
        {
            VertexBatch <VertexC1P3> typedBatch    = new VertexBatch <VertexC1P3>();
            IVertexBatch             abstractBatch = typedBatch;

            Assert.AreEqual(0, typedBatch.Count);
            Assert.AreEqual(VertexDeclaration.Get <VertexC1P3>(), typedBatch.Declaration);
            Assert.IsNotNull(typedBatch.Vertices);
            Assert.AreEqual(0, typedBatch.Vertices.Count);

            Assert.AreEqual(0, abstractBatch.Count);
            Assert.AreEqual(VertexDeclaration.Get <VertexC1P3>(), abstractBatch.Declaration);
        }
示例#5
0
        /// <summary>
        /// Sets the last vertex batch used for drawing.
        /// <para>
        /// This is done so that various methods that change GL state can force-draw the batch
        /// before continuing with the state change.
        /// </para>
        /// </summary>
        /// <param name="batch">The batch.</param>
        internal static void SetActiveBatch(IVertexBatch batch)
        {
            if (lastActiveBatch == batch)
            {
                return;
            }

            batch_reset_list.Add(batch);

            FlushCurrentBatch();

            lastActiveBatch = batch;
        }
示例#6
0
        [Test] public void Locking()
        {
            VertexBatch <VertexC1P3> typedBatch    = new VertexBatch <VertexC1P3>();
            IVertexBatch             abstractBatch = typedBatch;

            typedBatch.Vertices.Add(new VertexC1P3 {
                Color = new ColorRgba(0)
            });
            typedBatch.Vertices.Add(new VertexC1P3 {
                Color = new ColorRgba(1)
            });
            typedBatch.Vertices.Add(new VertexC1P3 {
                Color = new ColorRgba(2)
            });
            typedBatch.Vertices.Add(new VertexC1P3 {
                Color = new ColorRgba(3)
            });

            // Assert that we can retrieve all data via unmanaged pointer access
            VertexDeclaration layout = typedBatch.Declaration;
            int vertexSize           = layout.Size;
            int colorElementIndex    = layout.Elements.IndexOfFirst(item => item.FieldName == VertexDeclaration.ShaderFieldPrefix + "Color");
            int colorOffset          = (int)layout.Elements[colorElementIndex].Offset;

            using (PinnedArrayHandle locked = typedBatch.Lock())
            {
                Assert.AreEqual(new ColorRgba(0), ReadColor(locked.Address, vertexSize * 0 + colorOffset));
                Assert.AreEqual(new ColorRgba(1), ReadColor(locked.Address, vertexSize * 1 + colorOffset));
                Assert.AreEqual(new ColorRgba(2), ReadColor(locked.Address, vertexSize * 2 + colorOffset));
                Assert.AreEqual(new ColorRgba(3), ReadColor(locked.Address, vertexSize * 3 + colorOffset));
            }
            using (PinnedArrayHandle locked = abstractBatch.Lock())
            {
                Assert.AreEqual(new ColorRgba(0), ReadColor(locked.Address, vertexSize * 0 + colorOffset));
                Assert.AreEqual(new ColorRgba(1), ReadColor(locked.Address, vertexSize * 1 + colorOffset));
                Assert.AreEqual(new ColorRgba(2), ReadColor(locked.Address, vertexSize * 2 + colorOffset));
                Assert.AreEqual(new ColorRgba(3), ReadColor(locked.Address, vertexSize * 3 + colorOffset));
            }

            // Make sure that our locks released properly, i.e. allowing the array to be garbage collected
            WeakReference weakRefToLockedData = new WeakReference(typedBatch.Vertices.Data);

            Assert.IsTrue(weakRefToLockedData.IsAlive);
            typedBatch    = null;
            abstractBatch = null;
            GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
            GC.WaitForPendingFinalizers();
            Assert.IsFalse(weakRefToLockedData.IsAlive);
        }
        private void drawChildren(IVertexBatch vertexBatch, Vector2 frameBufferSize)
        {
            // Fill the frame buffer with drawn children
            using (bindFrameBuffer(currentFrameBuffer, frameBufferSize))
            {
                // We need to draw children as if they were zero-based to the top-left of the texture.
                // We can do this by adding a translation component to our (orthogonal) projection matrix.
                GLWrapper.PushOrtho(ScreenSpaceDrawRectangle);

                GLWrapper.ClearColour(BackgroundColour);
                base.Draw(vertexBatch);

                GLWrapper.PopOrtho();
            }
        }
示例#8
0
        /// <summary>
        /// Sets the last vertex batch used for drawing.
        /// <para>
        /// This is done so that various methods that change GL state can force-draw the batch
        /// before continuing with the state change.
        /// </para>
        /// </summary>
        /// <param name="batch">The batch.</param>
        internal static void SetActiveBatch(IVertexBatch batch)
        {
            if (lastActiveBatch == batch)
            {
                return;
            }

            FlushCurrentBatch();

            if (batch != null && !thisFrameBatches.Contains(batch))
            {
                thisFrameBatches.Add(batch);
            }

            lastActiveBatch = batch;
        }
        public override void Draw(IVertexBatch vertexBatch)
        {
            Vector2 frameBufferSize = new Vector2((float)Math.Ceiling(ScreenSpaceDrawRectangle.Width), (float)Math.Ceiling(ScreenSpaceDrawRectangle.Height));

            if (UpdateVersion > DrawVersion.Value || frameBufferSize != FrameBuffers[0].Size)
            {
                DrawVersion.Value = UpdateVersion;

                using (establishFrameBufferViewport(frameBufferSize))
                {
                    drawChildren(vertexBatch, frameBufferSize);

                    // Blur post-processing in case a blur radius is defined.
                    int radiusX = BlurSigma.X > 0 ? findBlurRadius(BlurSigma.X) : 0;
                    int radiusY = BlurSigma.Y > 0 ? findBlurRadius(BlurSigma.Y) : 0;

                    if (radiusX > 0 || radiusY > 0)
                    {
                        GL.Disable(EnableCap.ScissorTest);

                        if (radiusX > 0)
                        {
                            drawBlurredFrameBuffer(radiusX, BlurSigma.X, BlurRotation);
                        }
                        if (radiusY > 0)
                        {
                            drawBlurredFrameBuffer(radiusY, BlurSigma.Y, BlurRotation + 90);
                        }

                        GL.Enable(EnableCap.ScissorTest);
                    }
                }

                finalizeFrameBuffer();
            }

            RectangleF drawRectangle = FilteringMode == All.Nearest ?
                                       new RectangleF(ScreenSpaceDrawRectangle.X, ScreenSpaceDrawRectangle.Y, frameBufferSize.X, frameBufferSize.Y) :
                                       ScreenSpaceDrawRectangle;

            // Blit the final framebuffer to screen.
            GLWrapper.SetBlend(DrawInfo.Blending);

            Shader.Bind();
            drawFrameBufferToBackBuffer(FrameBuffers[0], drawRectangle, DrawInfo.Colour);
            Shader.Unbind();
        }
示例#10
0
        /// <summary>
        /// Uploads all dynamically gathered vertex data to the GPU using the internal <see cref="vertexBuffers"/> pool.
        /// </summary>
        private void UploadVertexData()
        {
            // Note that there is a 1:1 mapping between gathered vertex batches and vertex buffers.
            // We'll keep all buffers around until the drawdevice is disposed, in case we might need
            // them again later.
            this.vertexBuffers.Count = Math.Max(this.vertexBuffers.Count, this.drawVertices.TypeIndexCount);
            for (int typeIndex = 0; typeIndex < this.drawVertices.TypeIndexCount; typeIndex++)
            {
                // Filter out unused vertex types
                IReadOnlyList <IVertexBatch> batches = this.drawVertices.GetBatches(typeIndex);
                if (batches == null)
                {
                    continue;
                }
                if (batches.Count == 0)
                {
                    continue;
                }

                // Upload all vertex batches for this vertex type
                if (this.vertexBuffers[typeIndex] == null)
                {
                    this.vertexBuffers[typeIndex] = new RawList <VertexBuffer>();
                }
                this.vertexBuffers[typeIndex].Count = Math.Max(this.vertexBuffers[typeIndex].Count, batches.Count);
                for (int batchIndex = 0; batchIndex < batches.Count; batchIndex++)
                {
                    IVertexBatch vertexBatch = batches[batchIndex];

                    // Generate a VertexBuffer for this vertex type and batch index, if it didn't exist yet
                    if (this.vertexBuffers[typeIndex][batchIndex] == null)
                    {
                        this.vertexBuffers[typeIndex][batchIndex] = new VertexBuffer();
                    }

                    // Upload the vertex batch to
                    using (PinnedArrayHandle pinned = vertexBatch.Lock())
                    {
                        this.vertexBuffers[typeIndex][batchIndex].LoadVertexData(
                            vertexBatch.Declaration,
                            pinned.Address,
                            vertexBatch.Count);
                    }
                }
            }
        }
        public override void Draw(IVertexBatch vertexBatch)
        {
            if (ForceRedraw.Reset() > 0)
            {
                Vector2 frameBufferSize = new Vector2((float)Math.Ceiling(ScreenSpaceDrawRectangle.Width), (float)Math.Ceiling(ScreenSpaceDrawRectangle.Height));

                using (establishFrameBufferViewport(frameBufferSize))
                {
                    drawChildren(vertexBatch, frameBufferSize);

                    // Blur post-processing in case a blur radius is defined.
                    int radiusX = BlurSigma.X > 0 ? findBlurRadius(BlurSigma.X) : 0;
                    int radiusY = BlurSigma.Y > 0 ? findBlurRadius(BlurSigma.Y) : 0;

                    if (radiusX > 0 || radiusY > 0)
                    {
                        GL.Disable(EnableCap.ScissorTest);

                        if (radiusX > 0)
                        {
                            drawBlurredFrameBuffer(radiusX, BlurSigma.X, BlurRotation);
                        }
                        if (radiusY > 0)
                        {
                            drawBlurredFrameBuffer(radiusY, BlurSigma.Y, BlurRotation + 90);
                        }

                        GL.Enable(EnableCap.ScissorTest);
                    }
                }

                finalizeFrameBuffer();
            }

            // Blit the final framebuffer to screen.
            GLWrapper.SetBlend(DrawInfo.Blending);

            Shader.Bind();
            drawFrameBufferToBackBuffer(FrameBuffers[0], ScreenSpaceDrawRectangle);
            Shader.Unbind();
        }
示例#12
0
        public override void Draw(IVertexBatch vertexBatch)
        {
            base.Draw(vertexBatch);

            if (Texture == null || Texture.IsDisposed)
            {
                return;
            }


            Shader shader = NeedsRoundedShader ? RoundedTextureShader : TextureShader;

            if (InflationAmount != Vector2.Zero)
            {
                // The shader currently cannot deal with negative width and height.
                RectangleF drawRect = DrawRectangle.WithPositiveExtent;
                RoundedTextureShader.GetUniform <Vector4>(@"g_DrawingRect").Value = new Vector4(
                    drawRect.Left,
                    drawRect.Top,
                    drawRect.Right,
                    drawRect.Bottom);

                RoundedTextureShader.GetUniform <Matrix3>(@"g_ToDrawingSpace").Value    = DrawInfo.MatrixInverse;
                RoundedTextureShader.GetUniform <Vector2>(@"g_DrawingBlendRange").Value = InflationAmount;
            }

            shader.Bind();

            Texture.TextureGL.WrapMode = WrapTexture ? TextureWrapMode.Repeat : TextureWrapMode.ClampToEdge;
            Texture.Draw(ScreenSpaceDrawQuad, DrawInfo.Colour, null, vertexBatch as VertexBatch <TexturedVertex2D>,
                         new Vector2(InflationAmount.X / DrawRectangle.Width, InflationAmount.Y / DrawRectangle.Height));

            shader.Unbind();

            if (InflationAmount != Vector2.Zero)
            {
                RoundedTextureShader.GetUniform <Vector2>(@"g_DrawingBlendRange").Value = Vector2.Zero;
            }
        }
        public override void Draw(IVertexBatch vertexBatch)
        {
            updateVertexBatch();

            // Prefer to use own vertex batch instead of the parent-owned one.
            if (Shared.VertexBatch != null)
            {
                vertexBatch = Shared.VertexBatch;
            }

            base.Draw(vertexBatch);

            drawEdgeEffect();
            if (MaskingInfo != null)
            {
                MaskingInfo info = MaskingInfo.Value;
                if (info.BorderThickness > 0)
                {
                    info.BorderColour *= DrawInfo.Colour.AverageColour;
                }

                GLWrapper.PushMaskingInfo(info);
            }

            if (Children != null)
            {
                foreach (DrawNode child in Children)
                {
                    child.Draw(vertexBatch);
                }
            }

            if (MaskingInfo != null)
            {
                GLWrapper.PopMaskingInfo();
            }
        }
示例#14
0
 /// <summary>
 /// Begins tracking a <see cref="IVertexBatch"/>, resetting its counters every frame. This should be invoked once for every <see cref="IVertexBatch"/> in use.
 /// </summary>
 /// <param name="batch">The batch to register.</param>
 internal static void RegisterVertexBatch(IVertexBatch batch) => reset_scheduler.Add(() => all_batches.Add(batch));
示例#15
0
 public virtual void Draw(IVertexBatch vertexBatch)
 {
     GLWrapper.SetBlend(DrawInfo.Blending);
 }
示例#16
0
        void IGraphicsBackend.BeginRendering(IDrawDevice device, VertexBatchStore vertexData, RenderOptions options, RenderStats stats)
        {
            DebugCheckOpenGLErrors();
            this.CheckContextCaps();

            this.currentDevice = device;
            this.renderOptions = options;
            this.renderStats   = stats;

            // Upload all vertex data that we'll need during rendering
            if (vertexData != null)
            {
                this.perVertexTypeVBO.Count = Math.Max(this.perVertexTypeVBO.Count, vertexData.Batches.Count);
                for (int typeIndex = 0; typeIndex < vertexData.Batches.Count; typeIndex++)
                {
                    // Filter out unused vertex types
                    IVertexBatch vertexBatch = vertexData.Batches[typeIndex];
                    if (vertexBatch == null)
                    {
                        continue;
                    }
                    if (vertexBatch.Count == 0)
                    {
                        continue;
                    }

                    // Generate a VBO for this vertex type if it didn't exist yet
                    if (this.perVertexTypeVBO[typeIndex] == 0)
                    {
                        GL.GenBuffers(1, out this.perVertexTypeVBO.Data[typeIndex]);
                    }
                    GL.BindBuffer(BufferTarget.ArrayBuffer, this.perVertexTypeVBO[typeIndex]);

                    // Upload all data of this vertex type as a single block
                    int vertexDataLength = vertexBatch.Declaration.Size * vertexBatch.Count;
                    using (PinnedArrayHandle pinned = vertexBatch.Lock())
                    {
                        GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)vertexDataLength, IntPtr.Zero, BufferUsageHint.StreamDraw);
                        GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)vertexDataLength, pinned.Address, BufferUsageHint.StreamDraw);
                    }
                }
            }
            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);

            // Prepare the target surface for rendering
            NativeRenderTarget.Bind(options.Target as NativeRenderTarget);

            // Determine whether masked blending should use alpha-to-coverage mode
            if (this.msaaIsDriverDisabled)
            {
                this.useAlphaToCoverageBlend = false;
            }
            else if (NativeRenderTarget.BoundRT != null)
            {
                this.useAlphaToCoverageBlend = NativeRenderTarget.BoundRT.Samples > 0;
            }
            else if (this.activeWindow != null)
            {
                this.useAlphaToCoverageBlend = this.activeWindow.IsMultisampled;
            }
            else
            {
                this.useAlphaToCoverageBlend = this.defaultGraphicsMode.Samples > 0;
            }

            // Determine the available size on the active rendering surface
            Point2 availableSize;

            if (NativeRenderTarget.BoundRT != null)
            {
                availableSize = new Point2(NativeRenderTarget.BoundRT.Width, NativeRenderTarget.BoundRT.Height);
            }
            else if (this.activeWindow != null)
            {
                availableSize = new Point2(this.activeWindow.Width, this.activeWindow.Height);
            }
            else
            {
                availableSize = this.externalBackbufferSize;
            }

            // Translate viewport coordinates to OpenGL screen coordinates (bottom-left, rising), unless rendering
            // to a texture, which is laid out Duality-like (top-left, descending)
            Rect openGLViewport = options.Viewport;

            if (NativeRenderTarget.BoundRT == null)
            {
                openGLViewport.Y = (availableSize.Y - openGLViewport.H) - openGLViewport.Y;
            }

            // Setup viewport and scissor rects
            GL.Viewport((int)openGLViewport.X, (int)openGLViewport.Y, (int)MathF.Ceiling(openGLViewport.W), (int)MathF.Ceiling(openGLViewport.H));
            GL.Scissor((int)openGLViewport.X, (int)openGLViewport.Y, (int)MathF.Ceiling(openGLViewport.W), (int)MathF.Ceiling(openGLViewport.H));

            // Clear buffers
            ClearBufferMask glClearMask = 0;
            ColorRgba       clearColor  = options.ClearColor;

            if ((options.ClearFlags & ClearFlag.Color) != ClearFlag.None)
            {
                glClearMask |= ClearBufferMask.ColorBufferBit;
            }
            if ((options.ClearFlags & ClearFlag.Depth) != ClearFlag.None)
            {
                glClearMask |= ClearBufferMask.DepthBufferBit;
            }
            GL.ClearColor(clearColor.R / 255.0f, clearColor.G / 255.0f, clearColor.B / 255.0f, clearColor.A / 255.0f);
            GL.ClearDepth((double)options.ClearDepth);             // The "float version" is from OpenGL 4.1..
            GL.Clear(glClearMask);

            // Configure Rendering params
            if (options.RenderMode == RenderMatrix.ScreenSpace)
            {
                GL.Enable(EnableCap.ScissorTest);
                GL.Enable(EnableCap.DepthTest);
                GL.DepthFunc(DepthFunction.Always);
            }
            else
            {
                GL.Enable(EnableCap.ScissorTest);
                GL.Enable(EnableCap.DepthTest);
                GL.DepthFunc(DepthFunction.Lequal);
            }

            OpenTK.Matrix4 openTkModelView;
            Matrix4        modelView = options.ModelViewMatrix;

            GetOpenTKMatrix(ref modelView, out openTkModelView);

            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadMatrix(ref openTkModelView);

            OpenTK.Matrix4 openTkProjection;
            Matrix4        projection = options.ProjectionMatrix;

            GetOpenTKMatrix(ref projection, out openTkProjection);

            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadMatrix(ref openTkProjection);

            if (NativeRenderTarget.BoundRT != null)
            {
                GL.Scale(1.0f, -1.0f, 1.0f);
                if (options.RenderMode == RenderMatrix.ScreenSpace)
                {
                    GL.Translate(0.0f, -device.TargetSize.Y, 0.0f);
                }
            }
        }
示例#17
0
        void IGraphicsBackend.BeginRendering(IDrawDevice device, VertexBatchStore vertexData, RenderOptions options, RenderStats stats)
        {
            DebugCheckOpenGLErrors();

            // ToDo: AA is disabled for now
            //this.CheckContextCaps();

            this.currentDevice = device;
            this.renderOptions = options;
            this.renderStats   = stats;

            // Upload all vertex data that we'll need during rendering
            if (vertexData != null)
            {
                this.perVertexTypeVBO.Count = Math.Max(this.perVertexTypeVBO.Count, vertexData.Batches.Count);
                for (int typeIndex = 0; typeIndex < vertexData.Batches.Count; typeIndex++)
                {
                    // Filter out unused vertex types
                    IVertexBatch vertexBatch = vertexData.Batches[typeIndex];
                    if (vertexBatch == null)
                    {
                        continue;
                    }
                    if (vertexBatch.Count == 0)
                    {
                        continue;
                    }

                    // Generate a VBO for this vertex type if it didn't exist yet
                    if (this.perVertexTypeVBO[typeIndex] == 0)
                    {
                        GL.GenBuffers(1, out this.perVertexTypeVBO.Data[typeIndex]);
                    }
                    GL.BindBuffer(BufferTarget.ArrayBuffer, this.perVertexTypeVBO[typeIndex]);

                    // Upload all data of this vertex type as a single block
                    int vertexDataLength = vertexBatch.Declaration.Size * vertexBatch.Count;
                    using (PinnedArrayHandle pinned = vertexBatch.Lock()) {
                        GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)vertexDataLength, IntPtr.Zero, BufferUsage.StreamDraw);
                        GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)vertexDataLength, pinned.Address, BufferUsage.StreamDraw);
                    }
                }
            }
            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);

            // Prepare the target surface for rendering
            NativeRenderTarget.Bind(options.Target as NativeRenderTarget);

            // Determine the available size on the active rendering surface
            //Point2 availableSize;
            //if (NativeRenderTarget.BoundRT != null) {
            //    availableSize = new Point2(NativeRenderTarget.BoundRT.Width, NativeRenderTarget.BoundRT.Height);
            //} else {
            //    availableSize = this.externalBackbufferSize;
            //}

            Rect openGLViewport = options.Viewport;

            // Setup viewport and scissor rects
            GL.Viewport((int)openGLViewport.X, (int)openGLViewport.Y, (int)MathF.Ceiling(openGLViewport.W), (int)MathF.Ceiling(openGLViewport.H));
            GL.Scissor((int)openGLViewport.X, (int)openGLViewport.Y, (int)MathF.Ceiling(openGLViewport.W), (int)MathF.Ceiling(openGLViewport.H));

            // Clear buffers
            ClearBufferMask glClearMask = 0;
            ColorRgba       clearColor  = options.ClearColor;

            if ((options.ClearFlags & ClearFlag.Color) != ClearFlag.None)
            {
                glClearMask |= ClearBufferMask.ColorBufferBit;
            }
            if ((options.ClearFlags & ClearFlag.Depth) != ClearFlag.None)
            {
                glClearMask |= ClearBufferMask.DepthBufferBit;
            }
            GL.ClearColor(clearColor.R / 255.0f, clearColor.G / 255.0f, clearColor.B / 255.0f, clearColor.A / 255.0f);
            GL.ClearDepth(options.ClearDepth);
            GL.Clear(glClearMask);

            // Configure Rendering params
            if (options.RenderMode == RenderMatrix.ScreenSpace)
            {
                GL.Enable(EnableCap.ScissorTest);
                GL.Enable(EnableCap.DepthTest);
                GL.DepthFunc(DepthFunction.Always);
            }
            else
            {
                GL.Enable(EnableCap.ScissorTest);
                GL.Enable(EnableCap.DepthTest);
                GL.DepthFunc(DepthFunction.Lequal);
            }

            Matrix4 modelView  = options.ModelViewMatrix;
            Matrix4 projection = options.ProjectionMatrix;

            if (NativeRenderTarget.BoundRT != null)
            {
                modelView = Matrix4.CreateScale(new Vector3(1f, -1f, 1f)) * modelView;
                if (options.RenderMode == RenderMatrix.ScreenSpace)
                {
                    modelView = Matrix4.CreateTranslation(new Vector3(0f, -device.TargetSize.Y, 0f)) * modelView;
                }
            }

            // Convert matrices to float arrays
            GetArrayMatrix(ref modelView, ref modelViewData);
            GetArrayMatrix(ref projection, ref projectionData);

            // All EBOs can be used again
            lastUsedEBO = 0;
        }
示例#18
0
 /// <summary>
 /// Sets the last vertex batch used for drawing.
 /// <para>
 /// This is done so that various methods that change GL state can force-draw the batch
 /// before continuing with the state change.
 /// </para>
 /// </summary>
 /// <param name="batch">The batch.</param>
 internal static void SetActiveBatch(IVertexBatch batch)
 {
     lastActiveBatch = batch;
 }