示例#1
0
        /// <summary>
        /// </summary>
        /// <param name="gl">
        /// </param>
        /// <param name="ext">
        /// </param>
        /// <param name="arrayBuffer">
        /// </param>
        /// <param name="info">
        /// </param>
        /// <param name="loadMipmaps">
        /// </param>
        /// <param name="faces">
        /// </param>
        public static void UploadDDSLevels(
            WebGLRenderingContext gl, WEBGL_compressed_texture_s3tc ext, byte[] arrayBuffer, DDSInfo info, bool loadMipmaps, int faces)
        {
            var header = ArrayConvert.AsInt(arrayBuffer, 0, headerLengthInt);
            int fourCC;
            var blockBytes     = 0;
            var internalFormat = 0;
            int width;
            int height;
            int dataLength;
            int dataOffset;

            byte[] byteArray;
            int    mipmapCount;
            int    i;

            if (header[off_magic] != DDS_MAGIC)
            {
                Tools.Error("Invalid magic number in DDS header");
                return;
            }

            if (!info.isFourCC && !info.isRGB && !info.isLuminance)
            {
                Tools.Error("Unsupported format, must contain a FourCC, RGB or LUMINANCE code");
                return;
            }

            if (info.isFourCC)
            {
                fourCC = header[off_pfFourCC];
                switch (fourCC)
                {
                case FOURCC_DXT1:
                    blockBytes     = 8;
                    internalFormat = ext.COMPRESSED_RGBA_S3TC_DXT1_EXT;
                    break;

                case FOURCC_DXT3:
                    blockBytes     = 16;
                    internalFormat = ext.COMPRESSED_RGBA_S3TC_DXT3_EXT;
                    break;

                case FOURCC_DXT5:
                    blockBytes     = 16;
                    internalFormat = ext.COMPRESSED_RGBA_S3TC_DXT5_EXT;
                    break;

                default:
                    Tools.Error(string.Format("Unsupported FourCC code: {0}", fourCC));
                    return;
                }
            }

            mipmapCount = 1;
            if ((header[off_flags] & DDSD_MIPMAPCOUNT) > 0 && loadMipmaps)
            {
                mipmapCount = Math.Max(1, header[off_mipmapCount]);
            }

            var bpp = header[off_RGBbpp];

            for (var face = 0; face < faces; face++)
            {
                var sampler = (faces == 1) ? Gl.TEXTURE_2D : (Gl.TEXTURE_CUBE_MAP_POSITIVE_X + face);
                width      = header[off_width];
                height     = header[off_height];
                dataOffset = header[off_size] + 4;
                for (i = 0; i < mipmapCount; ++i)
                {
                    if (info.isRGB)
                    {
                        if (bpp == 24)
                        {
                            dataLength = width * height * 3;
                            byteArray  = GetRGBArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer);
                            gl.texImage2D(sampler, i, Gl.RGB, width, height, 0, Gl.RGB, Gl.UNSIGNED_BYTE, byteArray);
                        }
                        else
                        {
                            dataLength = width * height * 4;
                            byteArray  = GetRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer);
                            gl.texImage2D(sampler, i, Gl.RGBA, width, height, 0, Gl.RGBA, Gl.UNSIGNED_BYTE, byteArray);
                        }
                    }
                    else if (info.isLuminance)
                    {
                        var unpackAlignment = (int)gl.getParameter(Gl.UNPACK_ALIGNMENT);
                        var unpaddedRowSize = width;
                        var paddedRowSize   = (int)Math.Floor((double)(width + unpackAlignment - 1) / unpackAlignment) * unpackAlignment;
                        dataLength = paddedRowSize * (height - 1) + unpaddedRowSize;
                        byteArray  = GetLuminanceArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer);
                        gl.texImage2D(sampler, i, Gl.LUMINANCE, width, height, 0, Gl.LUMINANCE, Gl.UNSIGNED_BYTE, byteArray);
                    }
                    else
                    {
                        dataLength = Math.Max(4, width) / 4 * Math.Max(4, height) / 4 * blockBytes;
                        byteArray  = ArrayConvert.AsByte(arrayBuffer, dataOffset, dataLength);
                        gl.compressedTexImage2D(sampler, i, internalFormat, width, height, 0, byteArray);
                    }

                    dataOffset += dataLength;
                    width      /= 2;
                    height     /= 2;
                    width       = Math.Max(1, width);
                    height      = Math.Max(1, height);
                }
            }
        }
示例#2
0
        /// <summary>
        /// </summary>
        /// <param name="gl">
        /// </param>
        /// <param name="data">
        /// </param>
        public static void UploadContent(WebGLRenderingContext gl, byte[] data)
        {
            if (data.Length < 19)
            {
                Tools.Error("Unable to load TGA file - Not enough data to contain header");
                return;
            }

            var offset = 18;
            var header = GetTGAHeader(data);

            if (header.id_length + offset > data.Length)
            {
                Tools.Error("Unable to load TGA file - Not enough data");
                return;
            }

            offset += header.id_length;
            var use_rle  = false;
            var use_pal  = false;
            var use_rgb  = false;
            var use_grey = false;

            switch (header.image_type)
            {
            case _TYPE_RLE_INDEXED:
                use_rle = true;
                use_pal = true;
                break;

            case _TYPE_INDEXED:
                use_pal = true;
                break;

            case _TYPE_RLE_RGB:
                use_rle = true;
                use_rgb = true;
                break;

            case _TYPE_RGB:
                use_rgb = true;
                break;

            case _TYPE_RLE_GREY:
                use_rle  = true;
                use_grey = true;
                break;

            case _TYPE_GREY:
                use_grey = true;
                break;
            }

            byte[] pixel_data;
            var    numAlphaBits = header.flags & 0xf;
            var    pixel_size   = header.pixel_size << 3;
            var    pixel_total  = header.width * header.height * pixel_size;

            byte[] palettes = null;
            if (use_pal)
            {
                palettes = ArrayConvert.AsByte(data, offset, header.colormap_length * (header.colormap_size << 3));
            }

            if (use_rle)
            {
                pixel_data = new byte[pixel_total];
                byte c;
                int  count;
                int  i;
                var  localOffset = 0;
                var  pixels      = new byte[pixel_size];
                while (offset < pixel_total)
                {
                    c     = data[offset++];
                    count = (c & 0x7f) + 1;
                    if ((c & 0x80) > 0)
                    {
                        for (i = 0; i < pixel_size; ++i)
                        {
                            pixels[i] = data[offset++];
                        }

                        for (i = 0; i < count; ++i)
                        {
                            pixel_data = ArrayConvert.AsByte(pixels, localOffset, i * pixel_size);
                        }

                        localOffset += pixel_size * count;
                    }
                    else
                    {
                        count *= pixel_size;
                        for (i = 0; i < count; ++i)
                        {
                            pixel_data[localOffset + i] = data[offset++];
                        }

                        localOffset += count;
                    }
                }
            }
            else
            {
                pixel_data = ArrayConvert.AsByte(data, offset, (use_pal) ? header.width * header.height : pixel_total);
            }

            int x_start;
            int y_start;
            int x_step;
            int y_step;
            int y_end;
            int x_end;

            switch ((header.flags & _ORIGIN_MASK) << _ORIGIN_SHIFT)
            {
            default:
            case _ORIGIN_UL:
                x_start = 0;
                x_step  = 1;
                x_end   = header.width;
                y_start = 0;
                y_step  = 1;
                y_end   = header.height;
                break;

            case _ORIGIN_BL:
                x_start = 0;
                x_step  = 1;
                x_end   = header.width;
                y_start = header.height - 1;
                y_step  = -1;
                y_end   = -1;
                break;

            case _ORIGIN_UR:
                x_start = header.width - 1;
                x_step  = -1;
                x_end   = -1;
                y_start = 0;
                y_step  = 1;
                y_end   = header.height;
                break;

            case _ORIGIN_BR:
                x_start = header.width - 1;
                x_step  = -1;
                x_end   = -1;
                y_start = header.height - 1;
                y_step  = -1;
                y_end   = -1;
                break;
            }

            byte[] imageData = null;

            if (use_grey)
            {
                switch (header.pixel_size)
                {
                case 8:
                    imageData = _getImageDataGrey8bits(header, palettes, pixel_data, y_start, y_step, y_end, x_start, x_step, x_end);
                    break;

                case 16:
                    imageData = _getImageDataGrey16bits(header, palettes, pixel_data, y_start, y_step, y_end, x_start, x_step, x_end);
                    break;
                }
            }
            else
            {
                switch (header.pixel_size)
                {
                case 8:
                    imageData = _getImageData8bits(header, palettes, pixel_data, y_start, y_step, y_end, x_start, x_step, x_end);
                    break;

                case 16:
                    imageData = _getImageData16bits(header, palettes, pixel_data, y_start, y_step, y_end, x_start, x_step, x_end);
                    break;

                case 24:
                    imageData = _getImageData24bits(header, palettes, pixel_data, y_start, y_step, y_end, x_start, x_step, x_end);
                    break;

                case 32:
                    imageData = _getImageData32bits(header, palettes, pixel_data, y_start, y_step, y_end, x_start, x_step, x_end);
                    break;
                }
            }

            gl.texImage2D(Gl.TEXTURE_2D, 0, Gl.RGBA, header.width, header.height, 0, Gl.RGBA, Gl.UNSIGNED_BYTE, imageData);
        }