public void BuildMipmap(ref GenericImage image, uint mipmap) { uint x = (uint)Math.Max(1, ((int)image.width >> (int)mipmap)); uint y = (uint)Math.Max(1, ((int)image.height >> (int)mipmap)); uint z = (uint)Math.Max(1, ((int)image.depth >> (int)mipmap)); uint x2 = (uint)Math.Max(1, ((int)image.width >> (int)(mipmap - 1))); uint y2 = (uint)Math.Max(1, ((int)image.height >> (int)(mipmap - 1))); uint z2 = (uint)Math.Max(1, ((int)image.depth >> (int)(mipmap - 1))); uint dX = x2 / x; uint dY = y2 / y; uint dZ = z2 / z; uint valueCount = x * y * z * image.arrays * image.channels; image.mipmapLevels[mipmap].pixels = new double[valueCount]; for (uint l = 0; l < image.arrays; ++l) { for (uint d = 0; d < z; ++d) { for (uint h = 0; h < y; ++h) { for (uint w = 0; w < x; ++w) { for (uint c = 0; c < image.channels; ++c) { image.SetPixelChannel(mipmap, l, d, h, w, c, ApplyFilter(w, h, d, mipmap, l, c, ref image)); } } } } } }
public TGAImage(GenericImage image) { IDLength = 0; ColorMapType = 0; // currently only uncomrepssed export is supported ImageType = 2; ColorMapOffset = 0; ColorMapEntryCount = 0; ColorMapBitsPerPixel = 0; XOrigin = 0; YOrigin = 0; Width = (ushort)image.width; Height = (ushort)image.height; int channelCount = (int)Math.Max(3, Math.Min(4, image.channels)); BitsPerPixel = (byte)(channelCount * 8); DiscriptioField = 0; ImageID = new byte[0]; ColorMap = new byte[0]; ImageData = new byte[Width * Height * channelCount]; for (int y = 0; y < Height; ++y) { for (int x = 0; x < Width; ++x) { for (int c = 0; c < channelCount; ++c) { ImageData[c + channelCount * (x + y * Width)] = (byte)(image.GetPixelChannel(0, 0, 0, (uint)y, (uint)x, (uint)c) * 255); } } } }
public CoreTexture ToCoreTexture(GenericImage image, IGLDataFormat dataFormat) { CoreTexture texture = new CoreTexture(); texture.glType = dataFormat.Value; texture.glFormat = Value; texture.glTypeSize = 1; texture.pixelWidth = image.width; texture.pixelHeight = image.height; texture.pixelDepth = image.depth == 1 ? 0 : image.depth; texture.numberOfFaces = image.faces; texture.numberOfArrayElements = image.arrays == 1 ? 0 : image.arrays; texture.mipmapLevels = new CoreTextureMipmapLevel[image.mipmapLevels.Length]; for (int mip = 0; mip < texture.mipmapLevels.Length; ++mip) { CoreTextureMipmapLevel mipTexture = new CoreTextureMipmapLevel(); mipTexture.pixels = ToCoreMipTexture(image, dataFormat, mip).ToArray(); texture.mipmapLevels[mip] = mipTexture; } texture.keyValuePairs = new CoreTextureKeyValuePair[1] { new CoreTextureKeyValuePair("FileGenerator", "KTXToolkit by Tiemo Jung") }; return(texture); }
public void Store(string path, CoreTexture texture, GenericImage image) { if (image.depth > 1) { MessageBox.Show("The image is a volumetric image, the container format can not store volumetric images" , "Inconpatible image type" , MessageBoxButtons.OK , MessageBoxIcon.Error); return; } if (image.arrays > 1) { MessageBox.Show("The image is a array of images, the container format can not store an array of images" , "Inconpatible image type" , MessageBoxButtons.OK , MessageBoxIcon.Error); return; } if (image.faces > 1) { MessageBox.Show("The image is a cubemap image, the container format can not store a cubemap image" , "Inconpatible image type" , MessageBoxButtons.OK , MessageBoxIcon.Error); return; } if (image.mipmapLevels.Length > 1) { MessageBox.Show("The image has multiple mipmap levels, the container format does not support mipmap images, ony the first mipmap image is store" , "Container can't store mipmaps" , MessageBoxButtons.OK , MessageBoxIcon.Information); } int[] buf = new int[] { 0, 0, 0, 255 }; System.Drawing.Imaging.PixelFormat pfm = System.Drawing.Imaging.PixelFormat.Canonical; if (image.channels <= 3) { pfm = System.Drawing.Imaging.PixelFormat.Format24bppRgb; } Bitmap bitmap = new Bitmap((int)texture.pixelWidth, (int)texture.pixelHeight, pfm); for (int y = 0; y < bitmap.Height; ++y) { for (int x = 0; x < bitmap.Width; ++x) { for (int c = 0; c < image.channels; ++c) { buf[c] = (byte)((image.mipmapLevels[0].pixels[(x + y * image.width) * image.channels + c]) * 255); } bitmap.SetPixel(x, y, Color.FromArgb(buf[3], buf[0], buf[1], buf[2])); } } bitmap.Save(path); }
public uint MipmapCount(GenericImage image) { uint max = Math.Max(image.width, Math.Max(image.height, image.depth)); uint level = 1; while (((int)max >> (int)level) > 0) { ++level; } return(level); }
protected List <byte> ToCoreMipTexturePixel(GenericImage image, IGLDataFormat dataFormat, int mipIndex, int pixelIndex) { List <byte> byteBuffer = new List <byte>(); for (int channel = 0; channel < Channels; ++channel) { byteBuffer.AddRange(ToCoreMipTexturePixelAtIndex(image, dataFormat, mipIndex, pixelIndex, channel)); } return(byteBuffer); }
public void Store(string path, CoreTexture texture, GenericImage image) { FileStream file = new FileStream(path, FileMode.Create, FileAccess.Write); if (file == null) { return; } BinaryWriter fileWriter = new BinaryWriter(file); WriteToBinaryWriter(fileWriter, texture); file.Flush(); file.Dispose(); }
public void BuildMipmaps(ref GenericImage image) { uint levels = MipmapCount(image); if (image.mipmapLevels.Length != levels) { GenericImageMipmapLevel[] newLevels = new GenericImageMipmapLevel[levels]; newLevels[0] = image.mipmapLevels[0]; image.mipmapLevels = newLevels; } for (uint m = 1; m < image.mipmapLevels.Length; ++m) { image.mipmapLevels[m] = new GenericImageMipmapLevel(); BuildMipmap(ref image, m); } }
override protected byte[] ToCoreMipTexturePixelAtIndex(GenericImage image, IGLDataFormat dataFormat, int mipIndex, int pixelIndex, int channelIndex) { long offset = pixelIndex * image.channels; if (channelIndex == 0) { return(dataFormat.ToCoreFormat(image.mipmapLevels[mipIndex].pixels, (int)offset, 2, (int)image.channels)); } else if (channelIndex == 2) { return(dataFormat.ToCoreFormat(image.mipmapLevels[mipIndex].pixels, (int)offset, 0, (int)image.channels)); } else { return(dataFormat.ToCoreFormat(image.mipmapLevels[mipIndex].pixels, (int)offset, channelIndex, (int)image.channels)); } }
protected List <byte> ToCoreMipTexture(GenericImage image, IGLDataFormat dataFormat, int mipIndex) { int x = (int)image.width >> (int)mipIndex; int y = (int)image.height >> (int)mipIndex; int z = (int)image.depth >> (int)mipIndex; x = x < 1 ? 1 : x; y = y < 1 ? 1 : y; z = z < 1 ? 1 : z; int pixels = (int)(image.faces * image.arrays * x * y * z); List <byte> byteBuffer = new List <byte>(); for (int pixel = 0; pixel < pixels; ++pixel) { byteBuffer.AddRange(ToCoreMipTexturePixel(image, dataFormat, mipIndex, pixel)); } return(byteBuffer); }
public CoreTexture ToCoreTexture(GenericImage image, IGLPixelFormat pixelFormat, IGLDataFormat dataFormat) { CoreTexture tex = pixelFormat.ToCoreTexture(image, dataFormat); if (tex != null) { tex.glInternalFormat = Value; switch (GLValue) { case Values.GL_RED: tex.glBaseInternalFormat = (UInt32)Values.GL_RED; break; case Values.GL_RGB: case Values.GL_R3_G3_B2: case Values.GL_RGB4: case Values.GL_RGB5: case Values.GL_RGB8: case Values.GL_RGB10: case Values.GL_RGB12: case Values.GL_RGB16: tex.glBaseInternalFormat = (UInt32)Values.GL_RGB; break; case Values.GL_RGBA: case Values.GL_RGBA2: case Values.GL_RGBA4: case Values.GL_RGB5_A1: case Values.GL_RGBA8: case Values.GL_RGB10_A2: case Values.GL_RGBA12: case Values.GL_RGBA16: tex.glBaseInternalFormat = (UInt32)Values.GL_RGBA; break; } } return(tex); }
public GenericImage ToGenericImage(CoreTexture texture, IGLDataFormat dataFormat) { GenericImage image = null; if (texture.glFormat == Value && dataFormat.Value == texture.glType) { image = new GenericImage(); image.channels = (uint)Channels; image.width = texture.pixelWidth; image.height = texture.pixelHeight; image.depth = texture.pixelDepth != 0 ? texture.pixelDepth : 1; image.arrays = texture.numberOfArrayElements != 0 ? texture.numberOfArrayElements : 1; image.faces = texture.numberOfFaces; image.mipmapLevels = new GenericImageMipmapLevel[texture.mipmapLevels.Length]; for (int level = 0; level < texture.mipmapLevels.Length; ++level) { image.mipmapLevels[level] = new GenericImageMipmapLevel(); image.mipmapLevels[level].pixels = ToGenericMipImage(texture, dataFormat, level).ToArray(); } } return(image); }
private void UpdateGenericImage() { IGLDataFormat dataFormat = GetDataFormat(texture.glType); IGLPixelFormat pixelFormat = GetPixelFormat(texture.glFormat); IGLInteralPixelFormat internalPixelFormat = GetInternalPixelFormat(texture.glInternalFormat); genericTexture = null; if (internalPixelFormat != null) { genericTexture = internalPixelFormat.ToGenericImage(texture, pixelFormat, dataFormat); } if (genericTexture == null) { MessageBox.Show(this, "Unsupported format ( 0x" + texture.glType.ToString("X4") + ", 0x" + texture.glFormat.ToString("X4") + ", 0x" + texture.glInternalFormat.ToString("X4") + ")", "Unsupported Format", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
// texture and image contain the same image, for some containers its easyer to use image instead of texture public void Store(string path, CoreTexture texture, GenericImage image) { TGAImage tga = new TGAImage(image); tga.Save(path); }
protected override double ApplyFilter(uint x_, uint y_, uint z_, uint mipmap, uint layer, uint channel, ref GenericImage image) { uint x = (uint)Math.Max(1, ((int)image.width >> (int)mipmap)); uint y = (uint)Math.Max(1, ((int)image.height >> (int)mipmap)); uint z = (uint)Math.Max(1, ((int)image.depth >> (int)mipmap)); uint x2 = (uint)Math.Max(1, ((int)image.width >> (int)(mipmap - 1))); uint y2 = (uint)Math.Max(1, ((int)image.height >> (int)(mipmap - 1))); uint z2 = (uint)Math.Max(1, ((int)image.depth >> (int)(mipmap - 1))); uint dX = x2 / x; uint dY = y2 / y; uint dZ = z2 / z; double value = 0; uint count = 0; for (uint d = 0; d < dZ; ++d) { for (uint h = 0; h < dY; ++h) { for (uint w = 0; w < dX; ++w) { ++count; value += image.GetPixelChannel(mipmap - 1, layer, z_ * dZ + d, y_ * dY + h, x_ * dX + w, channel); } } } if (count > 0) { return(value / count); } else { return(0); } }
protected abstract double ApplyFilter(uint x, uint y, uint z, uint mipmap, uint layer, uint channel, ref GenericImage image);
virtual protected byte[] ToCoreMipTexturePixelAtIndex(GenericImage image, IGLDataFormat dataFormat, int mipIndex, int pixelIndex, int channelIndex) { long offset = pixelIndex * image.channels; return(dataFormat.ToCoreFormat(image.mipmapLevels[mipIndex].pixels, (int)offset, channelIndex, (int)image.channels)); }