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