Ejemplo n.º 1
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);
        }
Ejemplo n.º 2
0
        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      = new IntPtr(ptr.ToInt32() + image.mip[level].mipStride);
                width  >>= 1;
                height >>= 1;
                depth  >>= 1;
            }

done_close_file:
            f.Close();
        }
Ejemplo n.º 3
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 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);
        }