Exemple #1
0
        public OpenGlModel(OpenGlContext context, ImagesModel images)
        {
            Debug.Assert(context.GlEnabled);
            Vao               = new VertexArray();
            CheckersShader    = new CheckersShader();
            samplerLinear     = new Sampler(TextureMinFilter.Linear, TextureMagFilter.Linear);
            samplerLinearMip  = new Sampler(TextureMinFilter.LinearMipmapLinear, TextureMagFilter.Linear);
            samplerNearest    = new Sampler(TextureMinFilter.Nearest, TextureMagFilter.Nearest);
            samplerNearestMip = new Sampler(TextureMinFilter.NearestMipmapNearest, TextureMagFilter.Nearest);
            TextureCache      = new TextureCacheModel(images, context);
            GetPixelShader    = new PixelValueShader();
            SrgbShader        = new SrgbShader();
            ExportShader      = new PixelExportShader();

            LinearMaxStatistics = new MaxStatistics(false);
            SrgbMaxStatistics   = new MaxStatistics(true);
            LinearMinStatistics = new MinStatistics(false);
            SrgbMinStatistics   = new MinStatistics(true);
            LinearAvgStatistics = new AverageStatistics(false, images);
            SrgbAvgStatistics   = new AverageStatistics(true, images);
        }
Exemple #2
0
        /// <summary>
        /// reads (sub) data from a single image layer and a single image mipmap with the specified format and type
        /// </summary>
        /// <param name="layer">image layer</param>
        /// <param name="mipmap">image mipmap</param>
        /// <param name="format">destination format</param>
        /// <param name="type">destination type</param>
        /// <param name="toSrgb">indicates if data should be converted into srgb space</param>
        /// <param name="useCropping">indicates if the source image should be cropped</param>
        /// <param name="xOffset">if useCropping: x pixel offset</param>
        /// <param name="yOffset">if useCropping: y pixel offset</param>
        /// <param name="width">if useCropping: width of destination image. Will be set to the exported image width</param>
        /// <param name="height">if useCropping: height of destination image. Will be set to the exported image height</param>
        /// <param name="exportShader">shader required for srgb conversion and cropping</param>
        /// <param name="bufferSize"> Expected size of buffer in bytes. If bufferSize = 0 the buffer size will be calculated based the pixel type size times the number of pixel components (this only works for simple formats)</param>
        /// <returns></returns>
        public byte[] GetData(int layer, int mipmap, ImageLoader.ImageFormat format, bool useCropping,
                              int xOffset, int yOffset, ref int width, ref int height, PixelExportShader exportShader, int bufferSize = 0)
        {
            Debug.Assert(!format.IsCompressed);

            // retrieve width and height of the mipmap
            GL.BindTexture(TextureTarget.Texture2DArray, id);
            GL.GetTexLevelParameter(TextureTarget.Texture2DArray, mipmap, GetTextureParameter.TextureWidth, out int maxWidth);
            GL.GetTexLevelParameter(TextureTarget.Texture2DArray, mipmap, GetTextureParameter.TextureHeight, out int maxHeight);

            Debug.Assert(layer < nLayer);
            Debug.Assert(mipmap < nMipmaps);
            if (useCropping)
            {
                Debug.Assert(xOffset + width <= maxWidth);
                Debug.Assert(yOffset + height <= maxHeight);
            }
            else
            {
                xOffset = 0;
                yOffset = 0;
                width   = maxWidth;
                height  = maxHeight;
            }


            int bs = bufferSize;

            // try to calculate the buffer size (only for simple formats)
            if (bs == 0)
            {
                bs = width * height * GetPixelTypeSize(format.Type) * GetPixelFormatCount(format.Format);
            }
            byte[] buffer = new byte[bs];

            //if (format.IsSrgb || useCropping)
            // This needs to be used due to some export bug with certain formats (e.g. RGBA4_UNORM_PACK16)
            {
                // create temporary texture and convert data
                var tmpTex = GL.GenTexture();
                GL.BindTexture(TextureTarget.Texture2D, tmpTex);
                GL.TexStorage2D(TextureTarget2d.Texture2D, 1, SizedInternalFormat.Rgba32f, width, height);

                // use crop/srgb shader
                GL.BindImageTexture(exportShader.GetDestinationTextureLocation(), tmpTex, 0, false, 0, TextureAccess.WriteOnly, SizedInternalFormat.Rgba32f);
                BindAsTexture2D(exportShader.GetSourceTextureLocation(), layer, mipmap);

                exportShader.Use(xOffset, yOffset, width, height, format.IsSrgb);

                // obtain data
                GL.BindTexture(TextureTarget.Texture2D, tmpTex);
                GL.GetTexImage(TextureTarget.Texture2D, 0, format.Format, format.Type, buffer);

                // cleanup
                GL.DeleteTexture(tmpTex);
            }
            //else
            //{
            //    // read directly (NOT POSSIBLE DUE TO EXPORT BUG e.g. RGBA4_UNORM_PACK16)
            //    BindAsTexture2D(0, layer, mipmap);
            //    GL.GetTexImage(TextureTarget.Texture2D, 0, format.Format, format.Type, buffer);
            //}

            return(buffer);
        }