Beispiel #1
0
        protected override void OnDisposing(bool manually)
        {
            base.OnDisposing(manually);

            // Dispose unmanaged Resources
            if (this.nativeTex != null)
            {
                this.nativeTex.Dispose();
                this.nativeTex = null;
            }

            // Get rid of big data references, so the GC can collect them.
            this.basePixmap.Detach();
        }
Beispiel #2
0
 /// <summary>
 /// Retrieves the textures pixel data from video memory in the Rgba8 format.
 /// As a storage array type, either byte or <see cref="ColorRgba"/> is recommended.
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="texture"></param>
 /// <param name="target">The buffer to store pixel values into.</param>
 /// <param name="dataLayout">The desired color layout of the specified buffer.</param>
 /// <param name="dataElementType">The desired color element type of the specified buffer.</param>
 public static void GetData <T>(
     this INativeTexture texture,
     T[] target,
     ColorDataLayout dataLayout,
     ColorDataElementType dataElementType)
 {
     using (PinnedArrayHandle pinned = new PinnedArrayHandle(target))
     {
         texture.GetData(
             pinned.Address,
             dataLayout,
             dataElementType);
     }
 }
Beispiel #3
0
        /// <summary>
        /// Sets up the Textures OpenGL resources, clearing previously uploaded pixel data.
        /// </summary>
        protected void SetupNativeRes()
        {
            if (this.nativeTex == null)
            {
                this.nativeTex = DualityApp.GraphicsBackend.CreateTexture();
            }

            this.nativeTex.SetupEmpty(
                this.pixelformat,
                this.texWidth, this.texHeight,
                this.filterMin, this.filterMag,
                this.wrapX, this.wrapY,
                this.anisoFilter ? 4 : 0,
                this.HasMipmaps);
        }
Beispiel #4
0
 /// <summary>
 /// Uploads the specified pixel data in RGBA format to video memory. A call to <see cref="INativeTexture.SetupEmpty"/>
 /// is to be considered required for this.
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="texture"></param>
 /// <param name="format">The textures internal format.</param>
 /// <param name="width"></param>
 /// <param name="height"></param>
 /// <param name="data">The block of pixel data to transfer.</param>
 /// <param name="dataLayout">The color layout of the specified data block.</param>
 /// <param name="dataElementType">The color element type of the specified data block.</param>
 public static void LoadData <T>(
     this INativeTexture texture,
     TexturePixelFormat format,
     int width, int height,
     T[] data,
     ColorDataLayout dataLayout,
     ColorDataElementType dataElementType) where T : struct
 {
     using (PinnedArrayHandle pinned = new PinnedArrayHandle(data))
     {
         texture.LoadData(
             format,
             width,
             height,
             pinned.Address,
             dataLayout,
             dataElementType);
     }
 }
Beispiel #5
0
        /// <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();
            }
        }