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); }
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); }
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); }