public OpenGLCubemapTexture( IntPtr pixelsFront, IntPtr pixelsBack, IntPtr pixelsLeft, IntPtr pixelsRight, IntPtr pixelsTop, IntPtr pixelsBottom, int width, int height, PixelFormat format) : base(TextureTarget.TextureCubeMap, width, height) { _internalFormat = OpenGLFormats.MapPixelInternalFormat(format); _format = OpenGLFormats.MapPixelFormat(format); _type = OpenGLFormats.MapPixelType(format); Bind(); GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMinFilter, (int)TextureMagFilter.Linear); GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge); GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge); GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapR, (int)TextureWrapMode.ClampToEdge); SetFacePixels(0, pixelsRight); SetFacePixels(1, pixelsLeft); SetFacePixels(2, pixelsTop); SetFacePixels(3, pixelsBottom); SetFacePixels(4, pixelsBack); SetFacePixels(5, pixelsFront); }
public void updateData() { GL.Enable(EnableCap.Texture2D); bind(); OGL.PixelInternalFormat pif = OGL.PixelInternalFormat.Rgba; OGL.PixelFormat pf = OGL.PixelFormat.Rgba; OGL.PixelType pt = OGL.PixelType.UnsignedByte; GL.TexImage2D <Byte>(target, 0, pif, myWidth, myHeight, 0, pf, pt, myData); unbind(); }
public Texture(int texWidth, int texHeight, OGL.PixelInternalFormat pif = PixelInternalFormat.Rgba8, PixelData pixels = null, bool generateMipmaps = false) { target = TextureTarget.Texture2D; myWidth = texWidth; myHeight = texHeight; myPixelFormat = pif; GL.GenTextures(1, out myId); bind(); if (pixels != null) { myData = pixels.data; myDataType = pixels.dataType; GL.TexImage2D(target, 0, myPixelFormat, myWidth, myHeight, 0, pixels.pixelFormat, myDataType, myData); } else { myData = null; OGL.PixelFormat pf; findPixelType(myPixelFormat, out pf, out myDataType); GL.TexImage2D(target, 0, myPixelFormat, myWidth, myHeight, 0, pf, myDataType, myData); } GL.TexParameter(target, TextureParameterName.TextureBaseLevel, 0); if (generateMipmaps == false) { GL.TexParameter(target, TextureParameterName.TextureMaxLevel, 0); //needed since no mip maps are created setMinMagFilters(TextureMinFilter.Nearest, TextureMagFilter.Nearest); } setWrapping(TextureWrapMode.Repeat, TextureWrapMode.Repeat); if (myData == null) { Info.print("Created empty texture with id: " + myId); } else { Info.print("Created user defined texture with id: " + myId); } if (generateMipmaps) { createMipMaps(); setMinMagFilters(TextureMinFilter.LinearMipmapLinear, TextureMagFilter.Linear); } unbind(); }
protected void findPixelType(OGL.PixelInternalFormat pif, out OGL.PixelFormat pf, out OGL.PixelType pt) { switch (myPixelFormat) { case PixelInternalFormat.DepthComponent32f: pt = PixelType.Float; pf = OGL.PixelFormat.DepthComponent; break; case PixelInternalFormat.DepthComponent: pt = PixelType.Float; pf = OGL.PixelFormat.DepthComponent; break; case PixelInternalFormat.R32f: pt = PixelType.Float; pf = OGL.PixelFormat.Red; break; case PixelInternalFormat.Rgb32f: pt = PixelType.Float; pf = OGL.PixelFormat.Rgb; break; case PixelInternalFormat.Rgba32f: pt = PixelType.Float; pf = OGL.PixelFormat.Rgba; break; case PixelInternalFormat.Rgb8: pt = PixelType.Byte; pf = OGL.PixelFormat.Rgb; break; case PixelInternalFormat.Rgba8: pt = PixelType.Byte; pf = OGL.PixelFormat.Rgba; break; default: pt = PixelType.Byte; pf = OGL.PixelFormat.Rgba; break; } }
public void evalBitmap(Bitmap bm, out OGL.PixelInternalFormat pif, out OGL.PixelFormat pf, out OGL.PixelType pt) { switch (bm.PixelFormat) { case System.Drawing.Imaging.PixelFormat.Format8bppIndexed: // misses glColorTable setup pif = OGL.PixelInternalFormat.Rgb8; pf = OGL.PixelFormat.ColorIndex; pt = OGL.PixelType.Bitmap; break; case System.Drawing.Imaging.PixelFormat.Format16bppArgb1555: case System.Drawing.Imaging.PixelFormat.Format16bppRgb555: // does not work pif = OGL.PixelInternalFormat.Rgb5A1; pf = OGL.PixelFormat.Bgr; pt = OGL.PixelType.UnsignedShort5551Ext; hasAlpha = true; break; /* case System.Drawing.Imaging.PixelFormat.Format16bppRgb565: * pif = OGL.PixelInternalFormat.R5G6B5IccSgix; * pf = OGL.PixelFormat.R5G6B5IccSgix; * pt = OGL.PixelType.UnsignedByte; * break; */ case System.Drawing.Imaging.PixelFormat.Format24bppRgb: // works pif = OGL.PixelInternalFormat.Rgb8; pf = OGL.PixelFormat.Bgr; pt = OGL.PixelType.UnsignedByte; break; case System.Drawing.Imaging.PixelFormat.Format32bppRgb: // has alpha too? wtf? case System.Drawing.Imaging.PixelFormat.Canonical: case System.Drawing.Imaging.PixelFormat.Format32bppArgb: // works pif = OGL.PixelInternalFormat.Rgba; pf = OGL.PixelFormat.Bgra; pt = OGL.PixelType.UnsignedByte; hasAlpha = true; break; default: throw new ArgumentException("ERROR: Unsupported Pixel Format " + bm.PixelFormat); } }
public CubemapTexture(int width, int height, OGL.PixelInternalFormat pif) { target = TextureTarget.TextureCubeMap; myPixelFormat = pif; OGL.PixelFormat pf; findPixelType(myPixelFormat, out pf, out myDataType); myWidth = width; myHeight = height; GL.GenTextures(1, out myId); GL.BindTexture(target, myId); GL.TexParameter(target, TextureParameterName.TextureBaseLevel, 0); GL.TexParameter(target, TextureParameterName.TextureMaxLevel, 0); //needed since no mip maps are created GL.TexParameter(target, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest); //nearest since no mip maps are created GL.TexParameter(target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest); //nearest since no mip maps are created GL.TexParameter(target, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge); GL.TexParameter(target, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge); for (int i = 0; i < 6; i++) { GL.TexImage2D(myFaces[i], 0, myPixelFormat, myWidth, myHeight, 0, pf, myDataType, IntPtr.Zero); } }
public Bitmap loadBitmap(string filename, out OGL.PixelInternalFormat pif, out OGL.PixelFormat pf, out OGL.PixelType pt) { filename = Path.GetFullPath(filename); if (File.Exists(filename) == false) { throw new Exception("File " + filename + " does not exist"); } Bitmap CurrentBitmap = null; try // Exceptions will be thrown if any Problem occurs while working on the file. { if (Path.GetExtension(filename) == ".pcx") { CurrentBitmap = PCX.load(filename); } else { CurrentBitmap = new Bitmap(filename); } evalBitmap(CurrentBitmap, out pif, out pf, out pt); //flip the image since it's backwards from what opengl expects if (myFlip == true) { CurrentBitmap.RotateFlip(RotateFlipType.RotateNoneFlipY); } return(CurrentBitmap); } catch (Exception e) { throw new Exception("Texture Loading Error: Failed to read file " + filename + ": " + e.Message); } }
private static UInt32[] dwReserved2; // 3 = 2 + 1 UInt32 #endif #region Methods /// <summary> /// This function will generate, bind and fill a Texture Object with a DXT1/3/5 compressed Texture in .dds Format. /// MipMaps below 4x4 Pixel Size are discarded, because DXTn's smallest unit is a 4x4 block of Pixel data. /// It will set correct MipMap parameters, Filtering, Wrapping and EnvMode for the Texture. /// The only call inside this function affecting OpenGL State is GL.BindTexture(); /// </summary> /// <param name="filename">The name of the file you wish to load, including path and file extension.</param> /// <param name="texturehandle">0 if invalid, otherwise a Texture Object usable with GL.BindTexture().</param> /// <param name="dimension">0 if invalid, will output what was loaded (typically Texture1D/2D/3D or Cubemap)</param> public static void LoadFromStream(byte[] _RawDataFromFile, out int texturehandle, out OpenTK.Graphics.OpenGL.TextureTarget dimension, out int oWidth, out int oHeight) { #region Prep data // invalidate whatever it was before dimension = (OGL.TextureTarget)0; texturehandle = 0; ErrorCode GLError = ErrorCode.NoError; _IsCompressed = false; _Width = 0; _Height = 0; _Depth = 0; _MipMapCount = 0; _BytesForMainSurface = 0; _BytesPerBlock = 0; _PixelInternalFormat = OGL.PixelInternalFormat.Rgba8; #endregion #region Try try // Exceptions will be thrown if any Problem occurs while working on the file. { #region Translate Header to less cryptic representation ConvertDX9Header(ref _RawDataFromFile); // The first 128 Bytes of the file is non-image data // start by checking if all forced flags are present. Flags indicate valid fields, but aren't written by every tool ..... if (idString != "DDS " || // magic key dwSize != 124 || // constant size of struct, never reused pfSize != 32 || // constant size of struct, never reused !CheckFlag(dwFlags, (uint)eDDSD.CAPS) || // must know it's caps !CheckFlag(dwFlags, (uint)eDDSD.PIXELFORMAT) || // must know it's format !CheckFlag(dwCaps1, (uint)eDDSCAPS.TEXTURE) // must be a Texture ) throw new ArgumentException("ERROR: File has invalid signature or missing Flags."); #region Examine Flags if (CheckFlag(dwFlags, (uint)eDDSD.WIDTH)) _Width = (int)dwWidth; else throw new ArgumentException("ERROR: Flag for Width not set."); if (CheckFlag(dwFlags, (uint)eDDSD.HEIGHT)) _Height = (int)dwHeight; else throw new ArgumentException("ERROR: Flag for Height not set."); oWidth = _Width; oHeight = _Height; if (CheckFlag(dwFlags, (uint)eDDSD.DEPTH) && CheckFlag(dwCaps2, (uint)eDDSCAPS2.VOLUME)) { dimension = OGL.TextureTarget.Texture3D; // image is 3D Volume _Depth = (int)dwDepth; throw Unfinished; } else {// image is 2D or Cube if (CheckFlag(dwCaps2, (uint)eDDSCAPS2.CUBEMAP)) { dimension = OGL.TextureTarget.TextureCubeMap; _Depth = 6; } else { dimension = OGL.TextureTarget.Texture2D; _Depth = 1; } } // these flags must be set for mipmaps to be included if (CheckFlag(dwCaps1, (uint)eDDSCAPS.MIPMAP) && CheckFlag(dwFlags, (uint)eDDSD.MIPMAPCOUNT)) _MipMapCount = (int)dwMipMapCount; // image contains MipMaps else _MipMapCount = 1; // only 1 main image // Should never happen if (CheckFlag(dwFlags, (uint)eDDSD.PITCH) && CheckFlag(dwFlags, (uint)eDDSD.LINEARSIZE)) throw new ArgumentException("INVALID: Pitch AND Linear Flags both set. Image cannot be uncompressed and DTXn compressed at the same time."); // This flag is set if format is uncompressed RGB RGBA etc. if (CheckFlag(dwFlags, (uint)eDDSD.PITCH)) { // _BytesForMainSurface = (int) dwPitchOrLinearSize; // holds bytes-per-scanline for uncompressed _IsCompressed = false; throw Unfinished; } // This flag is set if format is compressed DXTn. if (CheckFlag(dwFlags, (uint)eDDSD.LINEARSIZE)) { _BytesForMainSurface = (int)dwPitchOrLinearSize; _IsCompressed = true; } #endregion Examine Flags if (CheckFlag(pfFlags, (uint)eDDPF.FOURCC)) { switch ((eFOURCC)pfFourCC) { case eFOURCC.DXT1: _PixelInternalFormat = (OGL.PixelInternalFormat)ExtTextureCompressionS3tc.CompressedRgbS3tcDxt1Ext; _BytesPerBlock = 8; _IsCompressed = true; break; //case eFOURCC.DXT2: case eFOURCC.DXT3: _PixelInternalFormat = (OGL.PixelInternalFormat)ExtTextureCompressionS3tc.CompressedRgbaS3tcDxt3Ext; _BytesPerBlock = 16; _IsCompressed = true; break; //case eFOURCC.DXT4: case eFOURCC.DXT5: _PixelInternalFormat = (OGL.PixelInternalFormat)ExtTextureCompressionS3tc.CompressedRgbaS3tcDxt5Ext; _BytesPerBlock = 16; _IsCompressed = true; break; default: throw Unfinished; // handle uncompressed formats } } else { /* sourceFormat = convertPixelFormat(header.pixelFormat.rgbBits, header.pixelFormat.redMask, header.pixelFormat.greenMask, header.pixelFormat.blueMask, header.pixelFormat.flags & DDPF_ALPHAPIXELS ? header.pixelFormat.alphaMask : 0); */ throw Unfinished; } // Works, but commented out because some texture authoring tools don't set this flag. /* Safety Check, if file is only 1x 2D surface without mipmaps, eDDSCAPS.COMPLEX should not be set if ( CheckFlag( dwCaps1, (uint) eDDSCAPS.COMPLEX ) ) { if ( result == eTextureDimension.Texture2D && _MipMapCount == 1 ) // catch potential problem Trace.WriteLine( "Warning: Image is declared complex, but contains only 1 surface." ); }*/ #endregion Translate Header to less cryptic representation #region send the Texture to GL #region Generate and Bind Handle GL.GenTextures(1, out texturehandle); GL.BindTexture(dimension, texturehandle); #endregion Generate and Bind Handle int Cursor = HeaderSizeInBytes; // foreach face in the cubemap, get all it's mipmaps levels. Only one iteration for Texture2D for (int Slices = 0; Slices < _Depth; Slices++) { int trueMipMapCount = _MipMapCount - 1; int Width = _Width; int Height = _Height; for (int Level = 0; Level < _MipMapCount; Level++) // start at base image { #region determine Dimensions int BlocksPerRow = (Width + 3) >> 2; int BlocksPerColumn = (Height + 3) >> 2; int SurfaceBlockCount = BlocksPerRow * BlocksPerColumn; // // DXTn stores Texels in 4x4 blocks, a Color block is 8 Bytes, an Alpha block is 8 Bytes for DXT3/5 int SurfaceSizeInBytes = SurfaceBlockCount * _BytesPerBlock; // this check must evaluate to false for 2D and Cube maps, or it's impossible to determine MipMap sizes. #endregion determine Dimensions // skip mipmaps smaller than a 4x4 Pixels block, which is the smallest DXTn unit. if (Width > 2 && Height > 2) { // Note: there could be a potential problem with non-power-of-two cube maps #region Prepare Array for TexImage byte[] RawDataOfSurface = new byte[SurfaceSizeInBytes]; //if (!TextureLoaderParameters.FlipImages) { // no changes to the image, copy as is Array.Copy(_RawDataFromFile, Cursor, RawDataOfSurface, 0, SurfaceSizeInBytes); } #endregion Prepare Array for TexImage #region Create TexImage switch (dimension) { case OGL.TextureTarget.Texture2D: GL.CompressedTexImage2D(OGL.TextureTarget.Texture2D, Level, _PixelInternalFormat, Width, Height, 0, SurfaceSizeInBytes, RawDataOfSurface); break; case OGL.TextureTarget.TextureCubeMap: GL.CompressedTexImage2D(OGL.TextureTarget.TextureCubeMapPositiveX + Slices, Level, _PixelInternalFormat, Width, Height, 0, SurfaceSizeInBytes, RawDataOfSurface); break; case OGL.TextureTarget.Texture1D: // Untested case OGL.TextureTarget.Texture3D: // Untested default: throw new ArgumentException("ERROR: Use DXT for 2D Images only. Cannot evaluate " + dimension); } GL.Finish(); #endregion Create TexImage #region Query Success int width, height, internalformat, compressed; switch (dimension) { case OGL.TextureTarget.Texture1D: case OGL.TextureTarget.Texture2D: case OGL.TextureTarget.Texture3D: GL.GetTexLevelParameter(dimension, Level, GetTextureParameter.TextureWidth, out width); GL.GetTexLevelParameter(dimension, Level, GetTextureParameter.TextureHeight, out height); GL.GetTexLevelParameter(dimension, Level, GetTextureParameter.TextureInternalFormat, out internalformat); GL.GetTexLevelParameter(dimension, Level, GetTextureParameter.TextureCompressed, out compressed); break; case OGL.TextureTarget.TextureCubeMap: GL.GetTexLevelParameter(OGL.TextureTarget.TextureCubeMapPositiveX + Slices, Level, GetTextureParameter.TextureWidth, out width); GL.GetTexLevelParameter(OGL.TextureTarget.TextureCubeMapPositiveX + Slices, Level, GetTextureParameter.TextureHeight, out height); GL.GetTexLevelParameter(OGL.TextureTarget.TextureCubeMapPositiveX + Slices, Level, GetTextureParameter.TextureInternalFormat, out internalformat); GL.GetTexLevelParameter(OGL.TextureTarget.TextureCubeMapPositiveX + Slices, Level, GetTextureParameter.TextureCompressed, out compressed); break; default: throw Unfinished; } GLError = GL.GetError(); if (GLError != ErrorCode.NoError || compressed == 0 || width == 0 || height == 0 || internalformat == 0) { GL.DeleteTextures(1, ref texturehandle); throw new ArgumentException("ERROR: Something went wrong after GL.CompressedTexImage(); Last GL Error: " + GLError.ToString()); } #endregion Query Success } else { if (trueMipMapCount > Level) trueMipMapCount = Level - 1; // The current Level is invalid } #region Prepare the next MipMap level Width /= 2; if (Width < 1) Width = 1; Height /= 2; if (Height < 1) Height = 1; Cursor += SurfaceSizeInBytes; #endregion Prepare the next MipMap level } #region Set States properly GL.TexParameter(dimension, (TextureParameterName)All.TextureBaseLevel, 0); GL.TexParameter(dimension, (TextureParameterName)All.TextureMaxLevel, trueMipMapCount); int TexMaxLevel; GL.GetTexParameter(dimension, GetTextureParameter.TextureMaxLevel, out TexMaxLevel); #endregion Set States properly } #region Set Texture Parameters GL.TexParameter(OGL.TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat); GL.TexParameter(OGL.TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat); GLError = GL.GetError(); if (GLError != ErrorCode.NoError) { throw new ArgumentException("Error setting Texture Parameters. GL Error: " + GLError); } #endregion Set Texture Parameters // If it made it here without throwing any Exception the result is a valid Texture. return; // success #endregion send the Texture to GL } catch (Exception e) { dimension = (OGL.TextureTarget)0; texturehandle = 0; throw new ArgumentException("ERROR: Exception caught when attempting to load file " + ".\n" + e + "\n" + GetDescriptionFromFile()); // return; // failure } finally { _RawDataFromFile = null; // clarity, not really needed } #endregion Try }
public PixelFormatMap(Imaging.PixelFormat Format, OpenGL.PixelFormat GLFormat, OpenGL.PixelInternalFormat numbytes) { this.PixelFormat = Format; this.OpenGLPixelFormat = GLFormat; this.InternalFormat = numbytes; }