public static int vgl_GetDDSStride(ref DDS_FILE_HEADER header, int width) { if (header.std_header.ddspf.dwFlags == DDSSignal.DDS_DDPF_FOURCC && header.std_header.ddspf.dwFourCC == DDSSignal.DDS_FOURCC_DX10) { if (header.dxt10_header.format < vermilion.NUM_DDS_FORMATS) { DDS_FORMAT_GL_INFO format = InfoTable.gl_info_table[header.dxt10_header.format]; return (format.bits_per_texel * width + 7) / 8; } } else { switch (header.std_header.ddspf.dwFlags) { case DDSSignal.DDS_DDPF_RGB: return width * 3; case (DDSSignal.DDS_DDPF_RGB | DDSSignal.DDS_DDPF_ALPHA): case (DDSSignal.DDS_DDPF_RGB | DDSSignal.DDS_DDPF_ALPHAPIXELS): return width * 4; case DDSSignal.DDS_DDPF_ALPHA: return width; default: break; } } return 0; }
public static int vgl_GetDDSStride(ref DDS_FILE_HEADER header, int width) { if (header.std_header.ddspf.dwFlags == DDSSignal.DDS_DDPF_FOURCC && header.std_header.ddspf.dwFourCC == DDSSignal.DDS_FOURCC_DX10) { if (header.dxt10_header.format < vermilion.NUM_DDS_FORMATS) { DDS_FORMAT_GL_INFO format = InfoTable.gl_info_table[header.dxt10_header.format]; return((format.bits_per_texel * width + 7) / 8); } } else { switch (header.std_header.ddspf.dwFlags) { case DDSSignal.DDS_DDPF_RGB: return(width * 3); case (DDSSignal.DDS_DDPF_RGB | DDSSignal.DDS_DDPF_ALPHA): case (DDSSignal.DDS_DDPF_RGB | DDSSignal.DDS_DDPF_ALPHAPIXELS): return(width * 4); case DDSSignal.DDS_DDPF_ALPHA: return(width); default: break; } } return(0); }
public static uint vgl_GetTargetFromDDSHeader(ref DDS_FILE_HEADER header) { // If the DX10 header is present it's format should be non-zero (unless it's unknown) if (header.dxt10_header.format != 0) { // Check the dimension... switch (header.dxt10_header.dimension) { // Could be a 1D or 1D array texture case DDSSignal.DDS_RESOURCE_DIMENSION_TEXTURE1D: if (header.dxt10_header.array_size > 1) { return GL.GL_TEXTURE_1D_ARRAY; } return GL.GL_TEXTURE_1D; // 2D means 2D, 2D array, cubemap or cubemap array case DDSSignal.DDS_RESOURCE_DIMENSION_TEXTURE2D: if ((header.dxt10_header.misc_flag & DDSSignal.DDS_RESOURCE_MISC_TEXTURECUBE) != 0) { if (header.dxt10_header.array_size > 1) return GL.GL_TEXTURE_CUBE_MAP_ARRAY; return GL.GL_TEXTURE_CUBE_MAP; } if (header.dxt10_header.array_size > 1) return GL.GL_TEXTURE_2D_ARRAY; return GL.GL_TEXTURE_2D; // 3D should always be a volume texture case DDSSignal.DDS_RESOURCE_DIMENSION_TEXTURE3D: return GL.GL_TEXTURE_3D; } return GL.GL_NONE; } // No DX10 header. Check volume texture flag if ((header.std_header.caps2 & DDSSignal.DDSCAPS2_VOLUME) != 0) return GL.GL_TEXTURE_3D; // Could be a cubemap if ((header.std_header.caps2 & DDSSignal.DDSCAPS2_CUBEMAP) != 0) { // This shouldn't happen if the DX10 header is present, but what the hey if (header.dxt10_header.array_size > 1) return GL.GL_TEXTURE_CUBE_MAP_ARRAY; else return GL.GL_TEXTURE_CUBE_MAP; } // Alright, if there's no height, guess 1D if (header.std_header.height <= 1) return GL.GL_TEXTURE_1D; // Last ditch, probably 2D return GL.GL_TEXTURE_2D; }
public static void vglLoadDDS(string filename, ref vglImageData image) { System.IO.FileStream f = new System.IO.FileStream(filename, System.IO.FileMode.Open, System.IO.FileAccess.Read); System.IO.BinaryReader br = new System.IO.BinaryReader(f); //DDS_FILE_HEADER file_header = { 0, }; DDS_FILE_HEADER file_header = new DDS_FILE_HEADER(); //fread(&file_header, sizeof(file_header.magic) + sizeof(file_header.std_header), 1, f); file_header = br.ReadStruct<DDS_FILE_HEADER>(); file_header.dxt10_header.format = 0; file_header.dxt10_header.array_size = 0; f.Position = Marshal.SizeOf(file_header.magic) + Marshal.SizeOf(file_header.std_header); if (file_header.magic != DDSSignal.DDS_MAGIC) { goto done_close_file; } if (file_header.std_header.ddspf.dwFourCC == DDSSignal.DDS_FOURCC_DX10) { //fread(&file_header.dxt10_header, sizeof(file_header.dxt10_header), 1, f); f.Position = Marshal.SizeOf(file_header.magic) + Marshal.SizeOf(file_header.std_header); file_header.dxt10_header = br.ReadStruct<DDS_HEADER_DXT10>(); } if (!vgl_DDSHeaderToImageDataHeader(ref file_header, ref image)) goto done_close_file; image.target = vgl_GetTargetFromDDSHeader(ref file_header); if (image.target == GL.GL_NONE) goto done_close_file; //int current_pos = ftell(f); long current_pos = f.Position; long file_size = f.Length; image.totalDataSize = (int)(file_size - current_pos); var data = new UnmanagedArray<byte>(image.totalDataSize); if (image.mip == null) { image.mip = new vglImageMipData[vermilion.MAX_TEXTURE_MIPS]; } image.mip[0].data = data.Header; //image.mip[0].data = new byte[image.totalDataSize]; //fread(image.mip[0].data, file_size - current_pos, 1, f); for (int i = 0; i < image.totalDataSize; i++) { data[i] = br.ReadByte(); } int level; IntPtr ptr = image.mip[0].data; uint width = file_header.std_header.width; uint height = file_header.std_header.height; uint depth = file_header.std_header.depth; image.sliceStride = 0; if (image.mipLevels == 0) { image.mipLevels = 1; } for (level = 0; level < image.mipLevels; ++level) { image.mip[level].data = ptr; image.mip[level].width = (int)width; image.mip[level].height = (int)height; image.mip[level].depth = (int)depth; image.mip[level].mipStride = (int)(vgl_GetDDSStride(ref file_header, (int)width) * height); image.sliceStride += image.mip[level].mipStride; ptr += image.mip[level].mipStride; width >>= 1; height >>= 1; depth >>= 1; } done_close_file: f.Close(); }
public static void vglLoadDDS(string filename, ref vglImageData image) { System.IO.FileStream f = new System.IO.FileStream(filename, System.IO.FileMode.Open, System.IO.FileAccess.Read); System.IO.BinaryReader br = new System.IO.BinaryReader(f); //DDS_FILE_HEADER file_header = { 0, }; DDS_FILE_HEADER file_header = new DDS_FILE_HEADER(); //fread(&file_header, sizeof(file_header.magic) + sizeof(file_header.std_header), 1, f); file_header = br.ReadStruct <DDS_FILE_HEADER>(); file_header.dxt10_header.format = 0; file_header.dxt10_header.array_size = 0; f.Position = Marshal.SizeOf(file_header.magic) + Marshal.SizeOf(file_header.std_header); if (file_header.magic != DDSSignal.DDS_MAGIC) { goto done_close_file; } if (file_header.std_header.ddspf.dwFourCC == DDSSignal.DDS_FOURCC_DX10) { //fread(&file_header.dxt10_header, sizeof(file_header.dxt10_header), 1, f); f.Position = Marshal.SizeOf(file_header.magic) + Marshal.SizeOf(file_header.std_header); file_header.dxt10_header = br.ReadStruct <DDS_HEADER_DXT10>(); } if (!vgl_DDSHeaderToImageDataHeader(ref file_header, ref image)) { goto done_close_file; } image.target = vgl_GetTargetFromDDSHeader(ref file_header); if (image.target == GL.GL_NONE) { goto done_close_file; } //int current_pos = ftell(f); long current_pos = f.Position; long file_size = f.Length; image.totalDataSize = (int)(file_size - current_pos); var data = new UnmanagedArray <byte>(image.totalDataSize); if (image.mip == null) { image.mip = new vglImageMipData[vermilion.MAX_TEXTURE_MIPS]; } image.mip[0].data = data.Header; //image.mip[0].data = new byte[image.totalDataSize]; //fread(image.mip[0].data, file_size - current_pos, 1, f); for (int i = 0; i < image.totalDataSize; i++) { data[i] = br.ReadByte(); } int level; IntPtr ptr = image.mip[0].data; uint width = file_header.std_header.width; uint height = file_header.std_header.height; uint depth = file_header.std_header.depth; image.sliceStride = 0; if (image.mipLevels == 0) { image.mipLevels = 1; } for (level = 0; level < image.mipLevels; ++level) { image.mip[level].data = ptr; image.mip[level].width = (int)width; image.mip[level].height = (int)height; image.mip[level].depth = (int)depth; image.mip[level].mipStride = (int)(vgl_GetDDSStride(ref file_header, (int)width) * height); image.sliceStride += image.mip[level].mipStride; ptr += image.mip[level].mipStride; width >>= 1; height >>= 1; depth >>= 1; } done_close_file: f.Close(); }
public static bool vgl_DDSHeaderToImageDataHeader(ref DDS_FILE_HEADER header, ref vglImageData image) { image.swizzle = new uint[4]; if (header.std_header.ddspf.dwFlags == DDSSignal.DDS_DDPF_FOURCC && header.std_header.ddspf.dwFourCC == DDSSignal.DDS_FOURCC_DX10) { if (header.dxt10_header.format < vermilion.NUM_DDS_FORMATS) { DDS_FORMAT_GL_INFO format = InfoTable.gl_info_table[header.dxt10_header.format]; image.format = format.format; image.type = format.type; image.internalFormat = format.internalFormat; image.swizzle[0] = format.swizzle_r; image.swizzle[1] = format.swizzle_g; image.swizzle[2] = format.swizzle_b; image.swizzle[3] = format.swizzle_a; image.mipLevels = (int)header.std_header.mip_levels; return true; } } else if (header.std_header.ddspf.dwFlags == DDSSignal.DDS_DDPF_FOURCC) { image.swizzle[0] = GL.GL_RED; image.swizzle[1] = GL.GL_GREEN; image.swizzle[2] = GL.GL_BLUE; image.swizzle[3] = GL.GL_ALPHA; image.mipLevels = (int)header.std_header.mip_levels; switch (header.std_header.ddspf.dwFourCC) { case 116: image.format = GL.GL_RGBA; image.type = GL.GL_FLOAT; image.internalFormat = GL.GL_RGBA32F; /* image.swizzle[0] = GL.GL_ALPHA; image.swizzle[1] = GL.GL_BLUE; image.swizzle[2] = GL.GL_GREEN; image.swizzle[3] = GL.GL_RED; */ return true; default: break; } } else { image.swizzle[0] = GL.GL_RED; image.swizzle[1] = GL.GL_GREEN; image.swizzle[2] = GL.GL_BLUE; image.swizzle[3] = GL.GL_ALPHA; image.mipLevels = (int)header.std_header.mip_levels; switch (header.std_header.ddspf.dwFlags) { case DDSSignal.DDS_DDPF_RGB: image.format = GL.GL_BGR; image.type = GL.GL_UNSIGNED_BYTE; image.internalFormat = GL.GL_RGB8; image.swizzle[3] = GL.GL_ONE; return true; case (DDSSignal.DDS_DDPF_RGB | DDSSignal.DDS_DDPF_ALPHA): case (DDSSignal.DDS_DDPF_RGB | DDSSignal.DDS_DDPF_ALPHAPIXELS): image.format = GL.GL_BGRA; image.type = GL.GL_UNSIGNED_BYTE; image.internalFormat = GL.GL_RGBA8; return true; case DDSSignal.DDS_DDPF_ALPHA: image.format = GL.GL_RED; image.type = GL.GL_UNSIGNED_BYTE; image.internalFormat = GL.GL_R8; image.swizzle[0] = image.swizzle[1] = image.swizzle[2] = GL.GL_ZERO; image.swizzle[3] = GL.GL_RED; return true; case DDSSignal.DDS_DDPF_LUMINANCE: image.format = GL.GL_RED; image.type = GL.GL_UNSIGNED_BYTE; image.internalFormat = GL.GL_R8; image.swizzle[0] = image.swizzle[1] = image.swizzle[2] = GL.GL_RED; image.swizzle[3] = GL.GL_ONE; return true; case (DDSSignal.DDS_DDPF_LUMINANCE | DDSSignal.DDS_DDPF_ALPHA): image.format = GL.GL_RG; image.type = GL.GL_UNSIGNED_BYTE; image.internalFormat = GL.GL_RG8; image.swizzle[0] = image.swizzle[1] = image.swizzle[2] = GL.GL_RED; image.swizzle[3] = GL.GL_GREEN; return true; default: break; } } image.format = image.type = image.internalFormat = GL.GL_NONE; image.swizzle[0] = image.swizzle[1] = image.swizzle[2] = image.swizzle[3] = GL.GL_ZERO; return false; }
public static uint vgl_GetTargetFromDDSHeader(ref DDS_FILE_HEADER header) { // If the DX10 header is present it's format should be non-zero (unless it's unknown) if (header.dxt10_header.format != 0) { // Check the dimension... switch (header.dxt10_header.dimension) { // Could be a 1D or 1D array texture case DDSSignal.DDS_RESOURCE_DIMENSION_TEXTURE1D: if (header.dxt10_header.array_size > 1) { return(GL.GL_TEXTURE_1D_ARRAY); } return(GL.GL_TEXTURE_1D); // 2D means 2D, 2D array, cubemap or cubemap array case DDSSignal.DDS_RESOURCE_DIMENSION_TEXTURE2D: if ((header.dxt10_header.misc_flag & DDSSignal.DDS_RESOURCE_MISC_TEXTURECUBE) != 0) { if (header.dxt10_header.array_size > 1) { return(GL.GL_TEXTURE_CUBE_MAP_ARRAY); } return(GL.GL_TEXTURE_CUBE_MAP); } if (header.dxt10_header.array_size > 1) { return(GL.GL_TEXTURE_2D_ARRAY); } return(GL.GL_TEXTURE_2D); // 3D should always be a volume texture case DDSSignal.DDS_RESOURCE_DIMENSION_TEXTURE3D: return(GL.GL_TEXTURE_3D); } return(GL.GL_NONE); } // No DX10 header. Check volume texture flag if ((header.std_header.caps2 & DDSSignal.DDSCAPS2_VOLUME) != 0) { return(GL.GL_TEXTURE_3D); } // Could be a cubemap if ((header.std_header.caps2 & DDSSignal.DDSCAPS2_CUBEMAP) != 0) { // This shouldn't happen if the DX10 header is present, but what the hey if (header.dxt10_header.array_size > 1) { return(GL.GL_TEXTURE_CUBE_MAP_ARRAY); } else { return(GL.GL_TEXTURE_CUBE_MAP); } } // Alright, if there's no height, guess 1D if (header.std_header.height <= 1) { return(GL.GL_TEXTURE_1D); } // Last ditch, probably 2D return(GL.GL_TEXTURE_2D); }
public static bool vgl_DDSHeaderToImageDataHeader(ref DDS_FILE_HEADER header, ref vglImageData image) { image.swizzle = new uint[4]; if (header.std_header.ddspf.dwFlags == DDSSignal.DDS_DDPF_FOURCC && header.std_header.ddspf.dwFourCC == DDSSignal.DDS_FOURCC_DX10) { if (header.dxt10_header.format < vermilion.NUM_DDS_FORMATS) { DDS_FORMAT_GL_INFO format = InfoTable.gl_info_table[header.dxt10_header.format]; image.format = format.format; image.type = format.type; image.internalFormat = format.internalFormat; image.swizzle[0] = format.swizzle_r; image.swizzle[1] = format.swizzle_g; image.swizzle[2] = format.swizzle_b; image.swizzle[3] = format.swizzle_a; image.mipLevels = (int)header.std_header.mip_levels; return(true); } } else if (header.std_header.ddspf.dwFlags == DDSSignal.DDS_DDPF_FOURCC) { image.swizzle[0] = GL.GL_RED; image.swizzle[1] = GL.GL_GREEN; image.swizzle[2] = GL.GL_BLUE; image.swizzle[3] = GL.GL_ALPHA; image.mipLevels = (int)header.std_header.mip_levels; switch (header.std_header.ddspf.dwFourCC) { case 116: image.format = GL.GL_RGBA; image.type = GL.GL_FLOAT; image.internalFormat = GL.GL_RGBA32F; /* * image.swizzle[0] = GL.GL_ALPHA; * image.swizzle[1] = GL.GL_BLUE; * image.swizzle[2] = GL.GL_GREEN; * image.swizzle[3] = GL.GL_RED; */ return(true); default: break; } } else { image.swizzle[0] = GL.GL_RED; image.swizzle[1] = GL.GL_GREEN; image.swizzle[2] = GL.GL_BLUE; image.swizzle[3] = GL.GL_ALPHA; image.mipLevels = (int)header.std_header.mip_levels; switch (header.std_header.ddspf.dwFlags) { case DDSSignal.DDS_DDPF_RGB: image.format = GL.GL_BGR; image.type = GL.GL_UNSIGNED_BYTE; image.internalFormat = GL.GL_RGB8; image.swizzle[3] = GL.GL_ONE; return(true); case (DDSSignal.DDS_DDPF_RGB | DDSSignal.DDS_DDPF_ALPHA): case (DDSSignal.DDS_DDPF_RGB | DDSSignal.DDS_DDPF_ALPHAPIXELS): image.format = GL.GL_BGRA; image.type = GL.GL_UNSIGNED_BYTE; image.internalFormat = GL.GL_RGBA8; return(true); case DDSSignal.DDS_DDPF_ALPHA: image.format = GL.GL_RED; image.type = GL.GL_UNSIGNED_BYTE; image.internalFormat = GL.GL_R8; image.swizzle[0] = image.swizzle[1] = image.swizzle[2] = GL.GL_ZERO; image.swizzle[3] = GL.GL_RED; return(true); case DDSSignal.DDS_DDPF_LUMINANCE: image.format = GL.GL_RED; image.type = GL.GL_UNSIGNED_BYTE; image.internalFormat = GL.GL_R8; image.swizzle[0] = image.swizzle[1] = image.swizzle[2] = GL.GL_RED; image.swizzle[3] = GL.GL_ONE; return(true); case (DDSSignal.DDS_DDPF_LUMINANCE | DDSSignal.DDS_DDPF_ALPHA): image.format = GL.GL_RG; image.type = GL.GL_UNSIGNED_BYTE; image.internalFormat = GL.GL_RG8; image.swizzle[0] = image.swizzle[1] = image.swizzle[2] = GL.GL_RED; image.swizzle[3] = GL.GL_GREEN; return(true); default: break; } } image.format = image.type = image.internalFormat = GL.GL_NONE; image.swizzle[0] = image.swizzle[1] = image.swizzle[2] = image.swizzle[3] = GL.GL_ZERO; return(false); }