Example #1
0
        public DisplayDevice(DisplayResolution currentResolution, bool primary,
                             IEnumerable <DisplayResolution> availableResolutions, Rectangle bounds)
            : this()
        {
#warning "Consolidate current resolution with bounds? Can they fall out of sync right now?"
            this.current_resolution = currentResolution;
            IsPrimary = primary;
            this.available_resolutions.AddRange(availableResolutions);
            this.bounds = bounds == Rectangle.Empty ? currentResolution.Bounds : bounds;
            Debug.Print("DisplayDevice {0} ({1}) supports {2} resolutions.",
                        available_displays.Count, primary ? "primary" : "secondary", available_resolutions.Count);
        }
Example #2
0
        public DisplayDevice(DisplayResolution currentResolution, bool primary,
            IEnumerable<DisplayResolution> availableResolutions, Rectangle bounds)
            : this()
        {
#warning "Consolidate current resolution with bounds? Can they fall out of sync right now?"
            this.current_resolution = currentResolution;
            IsPrimary = primary;
            this.available_resolutions.AddRange(availableResolutions);
            this.bounds = bounds == Rectangle.Empty ? currentResolution.Bounds : bounds;
            Debug.Print("DisplayDevice {0} ({1}) supports {2} resolutions.",
                available_displays.Count, primary ? "primary" : "secondary", available_resolutions.Count);
        }
Example #3
0
        private Window2DTest()
            : base(800, 600, "TriEngine2D Test")
        {
            Services.Provide(new InputManager(this), new AudioManager());
            _controlManager = new ControlManager();
            ResourceManager.LoadSong("unknown1", "menu1.ogg");
            ResourceManager.LoadSong("call", "menu2.ogg");
            ResourceManager.LoadSong("pirates", "menu3.ogg").IsLooped = true;
            ResourceManager.LoadSound("test", "test1.wav");
            ResourceManager.LoadSound("test2", "test2.wav");
            //Services.Audio.LoadSong("unknown2", "menu4.ogg");
            _font = ResourceManager.LoadFont("Anon", "Anonymous.ttf", 32);
            _control = new Label
            {
                Rectangle = new Rectangle(100, 100, 250, 250),
                Color = Color.Green,
                Alignment = QFontAlignment.Left,
                Text = "Test"
            };
            ((Label) _control).SetFont(_font);
            _control.Clicked += ControlClicked;
            _controlManager.AddControl(_control);
            _text = new TextObject("Hello, World!", _font, new Point<int>(100, 50), QFontAlignment.Left);
            _label = new Label();
            _label.SetFont(_font);
            _label.Position = new Point<int>(250, 300);
            _label.Text = "Foo Bar Baz";
            _label.Alignment = QFontAlignment.Right;
            _controlManager.AddControl(_label);
            _link = new LinkLabel();
            _link.SetFont(_font);
            _link.Position = new Point<int>(300, 500);

            _link.Text = "Go to google";
            _link.Alignment = QFontAlignment.Centre;
            _link.Url = "http://www.google.com/";
            _controlManager.AddControl(_link);

            _triangle = new Triangle(new Point<int>(100, 25), new Point<int>(50, 100), new Point<int>(150, 100));
            _rectangle = new Graphics.Rectangle(new Rectangle(200, 100, 100, 200));
        }
 private bool IntersectsWithInclusive(Rectangle r)
 {
     return !((Left > r.Right) || (Right < r.Left) ||
         (Top > r.Bottom) || (Bottom < r.Top));
 }
        /// <summary>
        ///	IntersectsWith Method
        /// </summary>
        ///
        /// <remarks>
        ///	Checks if a Rectangle intersects with this one.
        /// </remarks>

        public bool IntersectsWith(Rectangle rect)
        {
            return !((Left >= rect.Right) || (Right <= rect.Left) ||
                (Top >= rect.Bottom) || (Bottom <= rect.Top));
        }
        /// <summary>
        ///	Contains Method
        /// </summary>
        ///
        /// <remarks>
        ///	Checks if a Rectangle lies entirely within this 
        ///	Rectangle.
        /// </remarks>

        public bool Contains(Rectangle rect)
        {
            return (rect == Intersect(this, rect));
        }
        /// <summary>
        ///	Round Shared Method
        /// </summary>
        ///
        /// <remarks>
        ///	Produces a Rectangle structure from a RectangleF by
        ///	rounding the X, Y, Width, and Height properties.
        /// </remarks>

        //public static Rectangle Round(RectangleF value)
        //{
        //    int x, y, w, h;
        //    checked
        //    {
        //        x = (int)Math.Round(value.X);
        //        y = (int)Math.Round(value.Y);
        //        w = (int)Math.Round(value.Width);
        //        h = (int)Math.Round(value.Height);
        //    }

        //    return new Rectangle(x, y, w, h);
        //}

        /// <summary>
        ///	Truncate Shared Method
        /// </summary>
        ///
        /// <remarks>
        ///	Produces a Rectangle structure from a RectangleF by
        ///	truncating the X, Y, Width, and Height properties.
        /// </remarks>

        // LAMESPEC: Should this be floor, or a pure cast to int?

        //public static Rectangle Truncate(RectangleF value)
        //{
        //    int x, y, w, h;
        //    checked
        //    {
        //        x = (int)value.X;
        //        y = (int)value.Y;
        //        w = (int)value.Width;
        //        h = (int)value.Height;
        //    }

        //    return new Rectangle(x, y, w, h);
        //}

        /// <summary>
        ///	Union Shared Method
        /// </summary>
        ///
        /// <remarks>
        ///	Produces a new Rectangle from the union of 2 existing 
        ///	Rectangles.
        /// </remarks>

        public static Rectangle Union(Rectangle a, Rectangle b)
        {
            return FromLTRB(Math.Min(a.Left, b.Left),
                     Math.Min(a.Top, b.Top),
                     Math.Max(a.Right, b.Right),
                     Math.Max(a.Bottom, b.Bottom));
        }
        /// <summary>
        ///	Intersect Method
        /// </summary>
        ///
        /// <remarks>
        ///	Replaces the Rectangle with the intersection of itself
        ///	and another Rectangle.
        /// </remarks>

        public void Intersect(Rectangle rect)
        {
            this = Rectangle.Intersect(this, rect);
        }
        /// <summary>
        ///	Intersect Shared Method
        /// </summary>
        ///
        /// <remarks>
        ///	Produces a new Rectangle by intersecting 2 existing 
        ///	Rectangles. Returns null if there is no	intersection.
        /// </remarks>

        public static Rectangle Intersect(Rectangle a, Rectangle b)
        {
            // MS.NET returns a non-empty rectangle if the two rectangles
            // touch each other
            if (!a.IntersectsWithInclusive(b))
                return Empty;
            return Rectangle.FromLTRB(
                Math.Max(a.Left, b.Left),
                Math.Max(a.Top, b.Top),
                Math.Min(a.Right, b.Right),
                Math.Min(a.Bottom, b.Bottom));
        }
        /// <summary>
        ///	Inflate Shared Method
        /// </summary>
        ///
        /// <remarks>
        ///	Produces a new Rectangle by inflating an existing 
        ///	Rectangle by the specified coordinate values.
        /// </remarks>

        public static Rectangle Inflate(Rectangle rect, int x, int y)
        {
            Rectangle r = new Rectangle(rect.Location, rect.Size);
            r.Inflate(x, y);
            return r;
        }
        internal void CopyScaler2D(Texture sourceTexture, Texture destTexture, Rectangle sourceRectangle, Rectangle destRectangle, bool flipY = false)
        {
            // Use rendering
            GL.Viewport(0, 0, destTexture.Description.Width, destTexture.Description.Height);
            GL.BindFramebuffer(FramebufferTarget.Framebuffer, GraphicsDevice.FindOrCreateFBO(destTexture));

            var sourceRegionSize = new Vector2(sourceRectangle.Width, sourceRectangle.Height);
            var destRegionSize = new Vector2(destRectangle.Width, destRectangle.Height);

            // Source
            var sourceSize = new Vector2(sourceTexture.Width, sourceTexture.Height);
            var sourceRegionLeftTop = new Vector2(sourceRectangle.Left, sourceRectangle.Top);
            var sourceScale = new Vector2(sourceRegionSize.X / sourceSize.X, sourceRegionSize.Y / sourceSize.Y);
            var sourceOffset = new Vector2(sourceRegionLeftTop.X / sourceSize.X, sourceRegionLeftTop.Y / sourceSize.Y);

            // Dest
            var destSize = new Vector2(destTexture.Width, destTexture.Height);
            var destRegionLeftTop = new Vector2(destRectangle.X, flipY ? destRectangle.Bottom : destRectangle.Y);
            var destScale = new Vector2(destRegionSize.X / destSize.X, destRegionSize.Y / destSize.Y);
            var destOffset = new Vector2(destRegionLeftTop.X / destSize.X, destRegionLeftTop.Y / destSize.Y);

            if (flipY)
                destScale.Y = -destScale.Y;

            var enabledColors = new bool[4];
            GL.GetBoolean(GetPName.ColorWritemask, enabledColors);
            var isDepthTestEnabled = GL.IsEnabled(EnableCap.DepthTest);
            var isCullFaceEnabled = GL.IsEnabled(EnableCap.CullFace);
            var isBlendEnabled = GL.IsEnabled(EnableCap.Blend);
            var isStencilEnabled = GL.IsEnabled(EnableCap.StencilTest);
            GL.Disable(EnableCap.DepthTest);
            GL.Disable(EnableCap.CullFace);
            GL.Disable(EnableCap.Blend);
            GL.Disable(EnableCap.StencilTest);
            GL.ColorMask(true, true, true, true);

            // TODO find a better way to detect if sRGB conversion is needed (need to detect if main frame buffer is sRGB or not at init time)
#if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES
            // If we are copying from an SRgb texture to a non SRgb texture, we use a special SRGb copy shader
            bool needSRgbConversion = sourceTexture.Description.Format.IsSRgb() && destTexture == GraphicsDevice.WindowProvidedRenderTexture;
#else
            bool needSRgbConversion = false;
#endif
            int offsetLocation, scaleLocation;
            var program = GraphicsDevice.GetCopyProgram(needSRgbConversion, out offsetLocation, out scaleLocation);

            GL.UseProgram(program);

            activeTexture = 0;
            GL.ActiveTexture(TextureUnit.Texture0);
            GL.BindTexture(TextureTarget.Texture2D, sourceTexture.TextureId);
            boundShaderResourceViews[0] = null;
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge);
            sourceTexture.BoundSamplerState = GraphicsDevice.SamplerStates.PointClamp;

            vboDirty = true;
            enabledVertexAttribArrays |= 1 << 0;
            GL.EnableVertexAttribArray(0);
            GL.BindBuffer(BufferTarget.ArrayBuffer, GraphicsDevice.GetSquareBuffer().BufferId);
            GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, 0, 0);
            GL.Uniform4(offsetLocation, sourceOffset.X, sourceOffset.Y, destOffset.X, destOffset.Y);
            GL.Uniform4(scaleLocation, sourceScale.X, sourceScale.Y, destScale.X, destScale.Y);
            GL.Viewport(0, 0, destTexture.Width, destTexture.Height);
            GL.DrawArrays(PrimitiveTypeGl.TriangleStrip, 0, 4);
            GL.UseProgram(boundProgram);

            // Restore context
            if (isDepthTestEnabled)
                GL.Enable(EnableCap.DepthTest);
            if (isCullFaceEnabled)
                GL.Enable(EnableCap.CullFace);
            if (isBlendEnabled)
                GL.Enable(EnableCap.Blend);
            if (isStencilEnabled)
                GL.Enable(EnableCap.StencilTest);
            GL.ColorMask(enabledColors[0], enabledColors[1], enabledColors[2], enabledColors[3]);

            // Restore FBO and viewport
            GL.BindFramebuffer(FramebufferTarget.Framebuffer, boundFBO);
            GL.Viewport((int)viewports[0].X, (int)viewports[0].Y, (int)viewports[0].Width, (int)viewports[0].Height);
        }
        /// <summary>
        /// Copy a region of a <see cref="GraphicsResource"/> into another.
        /// </summary>
        /// <param name="source">The source from which to copy the data</param>
        /// <param name="regionSource">The region of the source <see cref="GraphicsResource"/> to copy.</param>
        /// <param name="destination">The destination into which to copy the data</param>
        /// <remarks>This might alter some states such as currently bound texture.</remarks>
        public void CopyRegion(GraphicsResource source, int sourceSubresource, ResourceRegion? regionSource, GraphicsResource destination, int destinationSubResource, int dstX = 0, int dstY = 0, int dstZ = 0)
        {
#if DEBUG
            GraphicsDevice.EnsureContextActive();
#endif
            var sourceTexture = source as Texture;
            var destTexture = destination as Texture;

            if (sourceTexture == null || destTexture == null)
            {
                throw Internal.Refactor.NewNotImplementedException("Copy is only implemented for Texture objects.");
            }

            // Get parent texture
            if (sourceTexture.ParentTexture != null)
                sourceTexture = sourceTexture.ParentTexture;
            if (destTexture.ParentTexture != null)
                destTexture = sourceTexture.ParentTexture;

            var sourceWidth = Texture.CalculateMipSize(sourceTexture.Description.Width, sourceSubresource % sourceTexture.MipLevels);
            var sourceHeight = Texture.CalculateMipSize(sourceTexture.Description.Height, sourceSubresource % sourceTexture.MipLevels);
            var sourceDepth = Texture.CalculateMipSize(sourceTexture.Description.Depth, sourceSubresource % sourceTexture.MipLevels);

            var sourceRegion = regionSource.HasValue ? regionSource.Value : new ResourceRegion(0, 0, 0, sourceWidth, sourceHeight, sourceDepth);
            var sourceRectangle = new Rectangle(sourceRegion.Left, sourceRegion.Top, sourceRegion.Right - sourceRegion.Left, sourceRegion.Bottom - sourceRegion.Top);

            if (sourceRectangle.Width == 0 || sourceRectangle.Height == 0)
                return;


            if (destTexture.Description.Usage == GraphicsResourceUsage.Staging)
            {
                if (sourceTexture.Description.Usage == GraphicsResourceUsage.Staging)
                {
                    // Staging => Staging
                    if (sourceRegion.Left != 0 || sourceRegion.Top != 0 || sourceRegion.Front != 0
                        || sourceRegion.Right != sourceWidth || sourceRegion.Bottom != sourceHeight || sourceRegion.Back != sourceDepth)
                    {
                        throw new NotSupportedException("ReadPixels from staging texture to staging texture only support full copy of subresource");
                    }

#if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES
                    if (GraphicsDevice.IsOpenGLES2)
                    {
                        Utilities.CopyMemory(destTexture.StagingData + destTexture.ComputeBufferOffset(destinationSubResource, 0),
                            sourceTexture.StagingData + sourceTexture.ComputeBufferOffset(sourceSubresource, 0),
                            destTexture.ComputeSubresourceSize(destinationSubResource));
                    }
                    else
#endif
                    {
                        GL.BindBuffer(BufferTarget.CopyReadBuffer, sourceTexture.PixelBufferObjectId);
                        GL.BindBuffer(BufferTarget.CopyWriteBuffer, destTexture.PixelBufferObjectId);
                        GL.CopyBufferSubData(BufferTarget.CopyReadBuffer, BufferTarget.CopyWriteBuffer,
                            (IntPtr)sourceTexture.ComputeBufferOffset(sourceSubresource, 0),
                            (IntPtr)destTexture.ComputeBufferOffset(destinationSubResource, 0),
                            (IntPtr)destTexture.ComputeSubresourceSize(destinationSubResource));
                    }
                }
                else
                {
                    // GPU => Staging
                    if (dstX != 0 || dstY != 0 || dstZ != 0)
                        throw new NotSupportedException("ReadPixels from staging texture using non-zero destination is not supported");

                    GL.Viewport(0, 0, sourceWidth, sourceHeight);

                    var isDepthBuffer = Texture.InternalIsDepthStencilFormat(sourceTexture.Format);

                    GL.BindFramebuffer(FramebufferTarget.Framebuffer, isDepthBuffer ? GraphicsDevice.CopyDepthSourceFBO : GraphicsDevice.CopyColorSourceFBO);
                    var attachmentType = FramebufferAttachment.ColorAttachment0;

                    for (int depthSlice = sourceRegion.Front; depthSlice < sourceRegion.Back; ++depthSlice)
                    {
                        attachmentType = GraphicsDevice.UpdateFBO(FramebufferTarget.Framebuffer, new GraphicsDevice.FBOTexture(sourceTexture, sourceSubresource / sourceTexture.MipLevels + depthSlice, sourceSubresource % sourceTexture.MipLevels));

#if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES
                        if (GraphicsDevice.IsOpenGLES2)
                        {
                            var format = destTexture.TextureFormat;
                            var type = destTexture.TextureType;

                            var srcFormat = sourceTexture.Description.Format;
                            var destFormat = destTexture.Description.Format;

                            if (srcFormat == destFormat && destFormat.SizeInBytes() == 4)   // in this case we just want to copy the data we don't care about format conversion. 
                            {                                                               // RGBA/Unsigned-byte is always a working combination whatever is the internal format (sRGB, etc...)
                                format = PixelFormatGl.Rgba;
                                type = PixelType.UnsignedByte;
                            }

                            GL.ReadPixels(sourceRectangle.Left, sourceRectangle.Top, sourceRectangle.Width, sourceRectangle.Height, format, type, destTexture.StagingData + destTexture.ComputeBufferOffset(destinationSubResource, depthSlice));
                        }
                        else
#endif
                        {
                            GL.BindBuffer(BufferTarget.PixelPackBuffer, destTexture.PixelBufferObjectId);
                            GL.ReadPixels(sourceRectangle.Left, sourceRectangle.Top, sourceRectangle.Width, sourceRectangle.Height, destTexture.TextureFormat, destTexture.TextureType, (IntPtr)destTexture.ComputeBufferOffset(destinationSubResource, depthSlice));
                            GL.BindBuffer(BufferTarget.PixelPackBuffer, 0);

                            destTexture.PixelBufferFrame = GraphicsDevice.FrameCounter;
                        }
                    }

                    // Unbind attachment
                    GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, attachmentType, TextureTarget2d.Texture2D, 0, 0);

                    // Restore FBO and viewport
                    GL.BindFramebuffer(FramebufferTarget.Framebuffer, boundFBO);
                    GL.Viewport((int)viewports[0].X, (int)viewports[0].Y, (int)viewports[0].Width, (int)viewports[0].Height);
                }
                return;
            }

            // GPU => GPU
            {
                var isDepthBuffer = Texture.InternalIsDepthStencilFormat(sourceTexture.Format);

                // Use our temporary mutable FBO
                GL.BindFramebuffer(FramebufferTarget.Framebuffer, isDepthBuffer ? GraphicsDevice.CopyDepthSourceFBO : GraphicsDevice.CopyColorSourceFBO);

                var attachmentType = FramebufferAttachment.ColorAttachment0;

                if (activeTexture != 0)
                {
                    activeTexture = 0;
                    GL.ActiveTexture(TextureUnit.Texture0);
                }

                GL.Viewport(0, 0, sourceWidth, sourceHeight);

                GL.BindTexture(destTexture.TextureTarget, destTexture.TextureId);

                for (int depthSlice = sourceRegion.Front; depthSlice < sourceRegion.Back; ++depthSlice)
                {
                    // Note: In practice, either it's a 2D texture array and its arrayslice can be non zero, or it's a 3D texture and it's depthslice can be non-zero, but not both at the same time
                    attachmentType = GraphicsDevice.UpdateFBO(FramebufferTarget.Framebuffer, new GraphicsDevice.FBOTexture(sourceTexture, sourceSubresource / sourceTexture.MipLevels + depthSlice, sourceSubresource % sourceTexture.MipLevels));

                    var arraySlice = destinationSubResource / destTexture.MipLevels;
                    var mipLevel = destinationSubResource % destTexture.MipLevels;

                    switch (destTexture.TextureTarget)
                    {
#if !SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES
                        case TextureTarget.Texture1D:
                            GL.CopyTexSubImage1D(TextureTarget2d.Texture1D, mipLevel, dstX, sourceRectangle.Left, sourceRectangle.Top, sourceRectangle.Width);
                            break;
#endif
                        case TextureTarget.Texture2D:
                            GL.CopyTexSubImage2D(TextureTarget2d.Texture2D, mipLevel, dstX, dstY, sourceRectangle.Left, sourceRectangle.Top, sourceRectangle.Width, sourceRectangle.Height);
                            break;
                        case TextureTarget.Texture2DArray:
                            GL.CopyTexSubImage3D(TextureTarget3d.Texture2DArray, mipLevel, dstX, dstY, arraySlice, sourceRectangle.Left, sourceRectangle.Top, sourceRectangle.Width, sourceRectangle.Height);
                            break;
                        case TextureTarget.Texture3D:
                            GL.CopyTexSubImage3D(TextureTarget3d.Texture3D, mipLevel, dstX, dstY, depthSlice, sourceRectangle.Left, sourceRectangle.Top, sourceRectangle.Width, sourceRectangle.Height);
                            break;
                        case TextureTarget.TextureCubeMap:
                            GL.CopyTexSubImage2D(Texture.GetTextureTargetForDataSet2D(destTexture.TextureTarget, arraySlice), mipLevel, dstX, dstY, sourceRectangle.Left, sourceRectangle.Top, sourceRectangle.Width, sourceRectangle.Height);
                            break;
                        default:
                            throw new NotSupportedException("Invalid texture target: " + destTexture.TextureTarget);
                    }
                }

                // Unbind texture and force it to be set again next draw call
                GL.BindTexture(destTexture.TextureTarget, 0);
                boundShaderResourceViews[0] = null;

                // Unbind attachment
                GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, attachmentType, TextureTarget2d.Texture2D, 0, 0);

                // Restore FBO and viewport
                GL.BindFramebuffer(FramebufferTarget.Framebuffer, boundFBO);
                GL.Viewport((int)viewports[0].X, (int)viewports[0].Y, (int)viewports[0].Width, (int)viewports[0].Height);
            }
        }
 private void UpdateScissor(Rectangle scissorRect)
 {
     GL.Scissor(scissorRect.Left, scissorRect.Top, scissorRect.Width, scissorRect.Height);
 }