/// <summary> /// Binds a texture to draw with. /// </summary> /// <param name="textureId">The texture to bind.</param> /// <param name="unit">The texture unit to bind it to.</param> /// <param name="wrapModeS">The texture wrap mode in horizontal direction.</param> /// <param name="wrapModeT">The texture wrap mode in vertical direction.</param> /// <returns>true if the provided texture was not already bound (causing a binding change).</returns> public static bool BindTexture(int textureId, TextureUnit unit = TextureUnit.Texture0, WrapMode wrapModeS = WrapMode.None, WrapMode wrapModeT = WrapMode.None) { var index = GetTextureUnitId(unit); if (wrapModeS != CurrentWrapModeS) { GlobalPropertyManager.Set(GlobalProperty.WrapModeS, (int)wrapModeS); CurrentWrapModeS = wrapModeS; } if (wrapModeT != CurrentWrapModeT) { GlobalPropertyManager.Set(GlobalProperty.WrapModeT, (int)wrapModeT); CurrentWrapModeT = wrapModeT; } if (last_bound_texture[index] == textureId) { return(false); } FlushCurrentBatch(); GL.ActiveTexture(unit); GL.BindTexture(TextureTarget.Texture2D, textureId); last_bound_texture[index] = textureId; last_bound_texture_is_atlas[GetTextureUnitId(unit)] = false; FrameStatistics.Increment(StatisticsCounterType.TextureBinds); return(true); }
private static void setMaskingInfo(MaskingInfo maskingInfo, bool isPushing, bool overwritePreviousScissor) { FlushCurrentBatch(); GlobalPropertyManager.Set(GlobalProperty.MaskingRect, new Vector4( maskingInfo.MaskingRect.Left, maskingInfo.MaskingRect.Top, maskingInfo.MaskingRect.Right, maskingInfo.MaskingRect.Bottom)); GlobalPropertyManager.Set(GlobalProperty.ToMaskingSpace, maskingInfo.ToMaskingSpace); GlobalPropertyManager.Set(GlobalProperty.CornerRadius, maskingInfo.CornerRadius); GlobalPropertyManager.Set(GlobalProperty.BorderThickness, maskingInfo.BorderThickness / maskingInfo.BlendRange); if (maskingInfo.BorderThickness > 0) { GlobalPropertyManager.Set(GlobalProperty.BorderColour, new Vector4( maskingInfo.BorderColour.Linear.R, maskingInfo.BorderColour.Linear.G, maskingInfo.BorderColour.Linear.B, maskingInfo.BorderColour.Linear.A)); } GlobalPropertyManager.Set(GlobalProperty.MaskingBlendRange, maskingInfo.BlendRange); GlobalPropertyManager.Set(GlobalProperty.AlphaExponent, maskingInfo.AlphaExponent); GlobalPropertyManager.Set(GlobalProperty.EdgeOffset, maskingInfo.EdgeOffset); GlobalPropertyManager.Set(GlobalProperty.DiscardInner, maskingInfo.Hollow); RectangleI actualRect = maskingInfo.ScreenSpaceAABB; actualRect.X += Viewport.X; actualRect.Y += Viewport.Y; // Ensure the rectangle only has positive width and height. (Required by OGL) if (actualRect.Width < 0) { actualRect.X += actualRect.Width; actualRect.Width = -actualRect.Width; } if (actualRect.Height < 0) { actualRect.Y += actualRect.Height; actualRect.Height = -actualRect.Height; } if (isPushing) { scissor_rect_stack.Push(overwritePreviousScissor ? actualRect : RectangleI.Intersect(scissor_rect_stack.Peek(), actualRect)); } else { Trace.Assert(scissor_rect_stack.Count > 1); scissor_rect_stack.Pop(); } UpdateScissorToCurrentViewportAndOrtho(); }
private static void setMaskingInfo(MaskingInfo maskingInfo, bool isPushing, bool overwritePreviousScissor) { FlushCurrentBatch(); GlobalPropertyManager.Set(GlobalProperty.MaskingRect, new Vector4( maskingInfo.MaskingRect.Left, maskingInfo.MaskingRect.Top, maskingInfo.MaskingRect.Right, maskingInfo.MaskingRect.Bottom)); GlobalPropertyManager.Set(GlobalProperty.ToMaskingSpace, maskingInfo.ToMaskingSpace); GlobalPropertyManager.Set(GlobalProperty.CornerRadius, maskingInfo.CornerRadius); GlobalPropertyManager.Set(GlobalProperty.CornerExponent, maskingInfo.CornerExponent); GlobalPropertyManager.Set(GlobalProperty.BorderThickness, maskingInfo.BorderThickness / maskingInfo.BlendRange); if (maskingInfo.BorderThickness > 0) { GlobalPropertyManager.Set(GlobalProperty.BorderColour, new Vector4( maskingInfo.BorderColour.Linear.R, maskingInfo.BorderColour.Linear.G, maskingInfo.BorderColour.Linear.B, maskingInfo.BorderColour.Linear.A)); } GlobalPropertyManager.Set(GlobalProperty.MaskingBlendRange, maskingInfo.BlendRange); GlobalPropertyManager.Set(GlobalProperty.AlphaExponent, maskingInfo.AlphaExponent); GlobalPropertyManager.Set(GlobalProperty.EdgeOffset, maskingInfo.EdgeOffset); GlobalPropertyManager.Set(GlobalProperty.DiscardInner, maskingInfo.Hollow); if (maskingInfo.Hollow) { GlobalPropertyManager.Set(GlobalProperty.InnerCornerRadius, maskingInfo.HollowCornerRadius); } if (isPushing) { // When drawing to a viewport that doesn't match the projection size (e.g. via framebuffers), the resultant image will be scaled Vector2 viewportScale = Vector2.Divide(Viewport.Size, Ortho.Size); Vector2 location = (maskingInfo.ScreenSpaceAABB.Location - ScissorOffset) * viewportScale; Vector2 size = maskingInfo.ScreenSpaceAABB.Size * viewportScale; RectangleI actualRect = new RectangleI( (int)Math.Floor(location.X), (int)Math.Floor(location.Y), (int)Math.Ceiling(size.X), (int)Math.Ceiling(size.Y)); PushScissor(overwritePreviousScissor ? actualRect : RectangleI.Intersect(scissor_rect_stack.Peek(), actualRect)); } else { PopScissor(); } }
/// <summary> /// Applies a new orthographic projection rectangle. /// </summary> /// <param name="ortho">The orthographic projection rectangle.</param> public static void PushOrtho(RectangleF ortho) { FlushCurrentBatch(); ortho_stack.Push(ortho); if (Ortho == ortho) { return; } Ortho = ortho; ProjectionMatrix = Matrix4.CreateOrthographicOffCenter(Ortho.Left, Ortho.Right, Ortho.Bottom, Ortho.Top, -1, 1); GlobalPropertyManager.Set(GlobalProperty.ProjMatrix, ProjectionMatrix); }
/// <summary> /// Applies the last orthographic projection rectangle. /// </summary> public static void PopOrtho() { Trace.Assert(ortho_stack.Count > 1); FlushCurrentBatch(); ortho_stack.Pop(); RectangleF actualRect = ortho_stack.Peek(); if (Ortho == actualRect) { return; } Ortho = actualRect; ProjectionMatrix = Matrix4.CreateOrthographicOffCenter(Ortho.Left, Ortho.Right, Ortho.Bottom, Ortho.Top, -1, 1); GlobalPropertyManager.Set(GlobalProperty.ProjMatrix, ProjectionMatrix); }
/// <summary> /// Binds a framebuffer. /// </summary> /// <param name="frameBuffer">The framebuffer to bind.</param> public static void UnbindFrameBuffer(int frameBuffer) { if (frameBuffer == -1) { return; } if (frame_buffer_stack.Peek() != frameBuffer) { return; } frame_buffer_stack.Pop(); FlushCurrentBatch(); GL.BindFramebuffer(FramebufferTarget.Framebuffer, frame_buffer_stack.Peek()); GlobalPropertyManager.Set(GlobalProperty.GammaCorrection, UsingBackbuffer); }
/// <summary> /// Binds a framebuffer. /// </summary> /// <param name="frameBuffer">The framebuffer to bind.</param> public static void BindFrameBuffer(int frameBuffer) { if (frameBuffer == -1) { return; } bool alreadyBound = frame_buffer_stack.Count > 0 && frame_buffer_stack.Peek() == frameBuffer; frame_buffer_stack.Push(frameBuffer); if (!alreadyBound) { FlushCurrentBatch(); GL.BindFramebuffer(FramebufferTarget.Framebuffer, frameBuffer); } GlobalPropertyManager.Set(GlobalProperty.GammaCorrection, UsingBackbuffer); }