/// <summary> /// TextureDesc constructor for a texture using a fixed scaling /// </summary> /// <param name="scale">RTHandle scale used for this texture</param> /// <param name="dynamicResolution">Use dynamic resolution</param> /// <param name="xrReady">Set this to true if the Texture is a render texture in an XR setting.</param> public TextureDesc(Vector2 scale, bool dynamicResolution = false, bool xrReady = false) : this() { // Size related init sizeMode = TextureSizeMode.Scale; this.scale = scale; // Important default values not handled by zero construction in this() msaaSamples = MSAASamples.None; dimension = TextureDimension.Tex2D; InitDefaultValues(dynamicResolution, xrReady); }
/// <summary> /// TextureDesc constructor for a texture using explicit size /// </summary> /// <param name="width">Texture width</param> /// <param name="height">Texture height</param> /// <param name="dynamicResolution">Use dynamic resolution</param> /// <param name="xrReady">Set this to true if the Texture is a render texture in an XR setting.</param> public TextureDesc(int width, int height, bool dynamicResolution = false, bool xrReady = false) : this() { // Size related init sizeMode = TextureSizeMode.Explicit; this.width = width; this.height = height; // Important default values not handled by zero construction in this() msaaSamples = MSAASamples.None; InitDefaultValues(dynamicResolution, xrReady); }
/// <summary> /// Creates a new Texture based on a <see cref="Duality.Resources.Pixmap"/>. /// </summary> /// <param name="basePixmap">The <see cref="Duality.Resources.Pixmap"/> to use as source for pixel data.</param> /// <param name="sizeMode">Specifies behaviour in case the source data has non-power-of-two dimensions.</param> /// <param name="filterMag">The OpenGL filter mode for drawing the Texture bigger than it is.</param> /// <param name="filterMin">The OpenGL fitler mode for drawing the Texture smaller than it is.</param> /// <param name="wrapX">The OpenGL wrap mode on the texel x axis.</param> /// <param name="wrapY">The OpenGL wrap mode on the texel y axis.</param> /// <param name="format">The format in which OpenGL stores the pixel data.</param> public Texture(ContentRef <Pixmap> basePixmap, TextureSizeMode sizeMode = TextureSizeMode.Default, TextureMagFilter filterMag = TextureMagFilter.Linear, TextureMinFilter filterMin = TextureMinFilter.LinearMipmapLinear, TextureWrapMode wrapX = TextureWrapMode.Clamp, TextureWrapMode wrapY = TextureWrapMode.Clamp, TexturePixelFormat format = TexturePixelFormat.Rgba) { this.filterMag = filterMag; this.filterMin = filterMin; this.wrapX = wrapX; this.wrapY = wrapY; this.pixelformat = format; this.LoadData(basePixmap, sizeMode); }
/// <summary> /// Creates a new empty Texture with the specified size. /// </summary> /// <param name="width">The Textures width.</param> /// <param name="height">The Textures height</param> /// <param name="sizeMode">Specifies behaviour in case the specified size has non-power-of-two dimensions.</param> /// <param name="filterMag">The OpenGL filter mode for drawing the Texture bigger than it is.</param> /// <param name="filterMin">The OpenGL fitler mode for drawing the Texture smaller than it is.</param> /// <param name="wrapX">The OpenGL wrap mode on the texel x axis.</param> /// <param name="wrapY">The OpenGL wrap mode on the texel y axis.</param> /// <param name="format">The format in which OpenGL stores the pixel data.</param> public Texture(int width, int height, TextureSizeMode sizeMode = TextureSizeMode.Default, TextureMagFilter filterMag = TextureMagFilter.Linear, TextureMinFilter filterMin = TextureMinFilter.LinearMipmapLinear, TextureWrapMode wrapX = TextureWrapMode.Clamp, TextureWrapMode wrapY = TextureWrapMode.Clamp, TexturePixelFormat format = TexturePixelFormat.Rgba) { this.filterMag = filterMag; this.filterMin = filterMin; this.wrapX = wrapX; this.wrapY = wrapY; this.pixelformat = format; this.texSizeMode = sizeMode; this.AdjustSize(width, height); this.SetupNativeRes(); }
/// <summary> /// Loads the specified <see cref="Duality.Resources.Pixmap">Pixmaps</see> pixel data. /// </summary> /// <param name="basePixmap">The <see cref="Duality.Resources.Pixmap"/> that is used as pixel data source.</param> /// <param name="sizeMode">Specifies behaviour in case the source data has non-power-of-two dimensions.</param> public void LoadData(ContentRef <Pixmap> basePixmap, TextureSizeMode sizeMode) { if (this.nativeTex == null) { this.nativeTex = DualityApp.GraphicsBackend.CreateTexture(); } this.needsReload = false; this.basePixmap = basePixmap; this.texSizeMode = sizeMode; if (!this.basePixmap.IsExplicitNull) { PixelData pixelData = null; Pixmap basePixmapRes = this.basePixmap.IsAvailable ? this.basePixmap.Res : null; if (basePixmapRes != null) { pixelData = basePixmapRes.MainLayer; bool hasAtlas = (basePixmapRes.Atlas != null && basePixmapRes.Atlas.Count > 0); this.atlas = hasAtlas ? basePixmapRes.Atlas.ToArray() : null; } if (pixelData == null) { pixelData = Pixmap.Checkerboard.Res.MainLayer; } this.AdjustSize(pixelData.Width, pixelData.Height); this.SetupNativeRes(); if (this.texSizeMode != TextureSizeMode.NonPowerOfTwo && (this.pxWidth != this.texWidth || this.pxHeight != this.texHeight)) { if (this.texSizeMode == TextureSizeMode.Enlarge) { PixelData oldData = pixelData; pixelData = oldData.CloneResize(this.texWidth, this.texHeight); // Fill border pixels manually - that's cheaper than ColorTransparentPixels here. oldData.DrawOnto(pixelData, BlendMode.Solid, this.pxWidth, 0, 1, this.pxHeight, this.pxWidth - 1, 0); oldData.DrawOnto(pixelData, BlendMode.Solid, 0, this.pxHeight, this.pxWidth, 1, 0, this.pxHeight - 1); } else { pixelData = pixelData.CloneRescale(this.texWidth, this.texHeight, ImageScaleFilter.Linear); } } // Load pixel data to video memory this.nativeTex.LoadData( this.pixelformat, pixelData.Width, pixelData.Height, pixelData.Data, ColorDataLayout.Rgba, ColorDataElementType.Byte); // Adjust atlas to represent UV coordinates if (this.atlas != null) { Vector2 scale; scale.X = this.uvRatio.X / this.pxWidth; scale.Y = this.uvRatio.Y / this.pxHeight; for (int i = 0; i < this.atlas.Length; i++) { this.atlas[i].X *= scale.X; this.atlas[i].W *= scale.X; this.atlas[i].Y *= scale.Y; this.atlas[i].H *= scale.Y; } } } else { this.atlas = null; this.AdjustSize(this.size.X, this.size.Y); this.SetupNativeRes(); } }
internal static (Rect rect, Rect uvs) Size(Texture texture, Vector2 c, float size, TextureSizeMode mode) { float aspect = texture.width / (float)texture.height; switch (mode) { case TextureSizeMode.Width: return(FitWidth(c, size, aspect)); case TextureSizeMode.Height: return(FitHeight(c, size, aspect)); case TextureSizeMode.LongestSide: return(aspect < 1 ? FitHeight(c, size, aspect) : FitWidth(c, size, aspect)); case TextureSizeMode.ShortestSide: return(aspect < 1 ? FitWidth(c, size, aspect) : FitHeight(c, size, aspect)); case TextureSizeMode.PixelsPerMeter: return(TexelSized(texture, c, size)); case TextureSizeMode.Radius: return(FitRadius(texture, c, size)); default: throw new ArgumentOutOfRangeException(nameof(mode), mode, null); } }