⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ddsloader.java

📁 java 3d game jme 工程开发源代码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
                    } else if (pitchOrSize_ != size) {
                        logger.warning("Expected size = " + size + ", real = " + pitchOrSize_);
                    }
                } else {
                    pitchOrSize_ = size;
                }
            }
        }

        /**
         * Computes the sizes of each mipmap level in bytes, and stores it in sizes_[].
         */
        private void loadSizes() {
            int width = width_;
            int height = height_;

            sizes_ = new int[mipMapCount_];

            for (int i = 0; i < mipMapCount_; i++) {
                int size;

                if (compressed_) {
                    size = ((width + 3) / 4) * ((height + 3) / 4) * bpp_ * 2;
                } else {
                    size = width * height * bpp_ / 8;
                }

                sizes_[i] = ((size + 3) / 4) * 4;

                width = Math.max(width / 2, 1);
                height = Math.max(height / 2, 1);
            }
        }

        /**
         * Flips the given image data on the Y axis.
         * @param data Data array containing image data (without mipmaps)
         * @param scanlineSize Size of a single scanline = width * bytesPerPixel
         * @param height Height of the image in pixels
         * @return The new data flipped by the Y axis
         */
        public byte[] flipData(byte[] data, int scanlineSize, int height){
            byte[] newData = new byte[data.length];

            for (int y = 0; y < height; y++){
                System.arraycopy(data, y * scanlineSize, 
                                 newData, (height-y-1) * scanlineSize, 
                                 scanlineSize);
            }

            return newData;
        }
        
        /**
         * Reads a grayscale image with mipmaps from the InputStream
         * @param flip Flip the loaded image by Y axis
         * @param totalSize Total size of the image in bytes including the mipmaps
         * @return A ByteBuffer containing the grayscale image data with mips.
         * @throws java.io.IOException If an error occured while reading from InputStream
         */
        public ByteBuffer readGrayscale2D(boolean flip, int totalSize) throws IOException{
            ByteBuffer buffer = BufferUtils.createByteBuffer(totalSize);
            
            if (bpp_ == 8)
                logger.finest("Source image format: R8");
            
            assert bpp_ / 8 == Image.getEstimatedByteSize(pixelFormat_);
            
            int width = width_;
            int height = height_;
            
            for (int mip = 0; mip < mipMapCount_; mip++){
                byte[] data = new byte[sizes_[mip]];
                in_.readFully(data);
                if (flip) data = flipData(data, width * bpp_ / 8, height);
                buffer.put(data);
                
                width = Math.max(width / 2, 1);
                height = Math.max(height / 2, 1);
            }

            return buffer;
        }
        
        /**
         * Reads an uncompressed RGB or RGBA image.
         * 
         * @param flip Flip the image on the Y axis
         * @param totalSize Size of the image in bytes including mipmaps
         * @return ByteBuffer containing image data with mipmaps in the format specified by pixelFormat_
         * @throws java.io.IOException If an error occured while reading from InputStream
         */
        public ByteBuffer readRGB2D(boolean flip, int totalSize) throws IOException{
            int redCount = count(redMask_),
                blueCount = count(blueMask_),
                greenCount = count(greenMask_),
                alphaCount = count(alphaMask_);
            
            if (redMask_     == 0x00FF0000
             && greenMask_  == 0x0000FF00
             && blueMask_   == 0x000000FF){
                if (alphaMask_ == 0xFF000000 && bpp_ == 32){
                    logger.finest("Data source format: BGRA8");
                }else if (bpp_ == 24){
                    logger.finest("Data source format: BGR8");
                }
            }
            
            int sourcebytesPP = bpp_ / 8;
            int targetBytesPP = Image.getEstimatedByteSize(pixelFormat_);
  
            ByteBuffer dataBuffer = BufferUtils.createByteBuffer(totalSize);
            
            int width = width_;
            int height = height_;
            
            int offset = 0;
            for (int mip = 0; mip < mipMapCount_; mip++){
                for (int y = 0; y < height; y++) {
                    for (int x = 0; x < width; x++) {
                        byte[] b = new byte[sourcebytesPP];
                        in_.readFully(b);

                        int i = byte2int(b);
                        
                        byte red = (byte) (((i & redMask_) >> redCount));
                        byte green = (byte) (((i & greenMask_) >> greenCount));
                        byte blue = (byte) (((i & blueMask_) >> blueCount));
                        byte alpha = (byte) (((i & alphaMask_) >> alphaCount));
                        
                        if (flip)
                            dataBuffer.position(offset + ((height-y-1) * width + x) * targetBytesPP);
                        //else
                        //    dataBuffer.position(offset + (y * width + x) * targetBytesPP);
                            
                        if (alphaMask_ == 0){
                            dataBuffer.put(red).put(green).put(blue);
                        }else{
                            dataBuffer.put(red).put(green).put(blue).put(alpha);
                        }
                    }
                }
                
                offset += width * height * targetBytesPP;
                
                width = Math.max(width / 2, 1);
                height = Math.max(height / 2, 1);
            }
            
            return dataBuffer;
        }
        
        /**
         * Reads a DXT compressed image from the InputStream
         * 
         * @param totalSize Total size of the image in bytes, including mipmaps
         * @return ByteBuffer containing compressed DXT image in the format specified by pixelFormat_
         * @throws java.io.IOException If an error occured while reading from InputStream
         */
        public ByteBuffer readDXT2D(int totalSize) throws IOException{
            byte[] data = new byte[totalSize];
            in_.readFully(data);

            logger.finest("Source image format: DXT");
            
            ByteBuffer buffer = BufferUtils.createByteBuffer(totalSize);
            buffer.put(data);
            buffer.rewind();

            return buffer;
        }

        /**
         * Reads the image data from the InputStream in the required format.
         * If the file contains a cubemap image, it is loaded as 6 ByteBuffers
         * (potentially containing mipmaps if they were specified), otherwise
         * a single ByteBuffer is returned for a 2D image.
         * 
         * @param flip Flip the image data or not. 
         *        For cubemaps, each of the cubemap faces is flipped individually. 
         *        If the image is DXT compressed, no flipping is done.
         * @return An ArrayList containing a single ByteBuffer for a 2D image, or 6 ByteBuffers for a cubemap.
         *         The cubemap ByteBuffer order is PositiveX, NegativeX, PositiveY, NegativeY, PositiveZ, NegativeZ.
         * 
         * @throws java.io.IOException If an error occured while reading from the stream.
         */
        public ArrayList<ByteBuffer> readData(boolean flip) throws IOException {
            int totalSize = 0;

            for (int i = 0; i < sizes_.length; i++) {
                totalSize += sizes_[i];
            }

            ArrayList<ByteBuffer> allMaps = new ArrayList<ByteBuffer>();
            if (is(caps2_, DDSCAPS2_CUBEMAP)) {
                for (int i = 0; i < 6; i++){
                    if (compressed_){
                        allMaps.add( readDXT2D(totalSize));
                    }else if (grayscaleOrAlpha_){
                        allMaps.add( readGrayscale2D(flip, totalSize));
                    }else{
                        allMaps.add( readRGB2D(flip, totalSize));
                    }
                }
            }else{
                if (compressed_){
                    allMaps.add( readDXT2D(totalSize));
                }else if (grayscaleOrAlpha_){
                    allMaps.add( readGrayscale2D(flip, totalSize));
                }else{
                    allMaps.add( readRGB2D(flip, totalSize));
                }
            }
            
            return allMaps;
        }

        /**
         * Checks if flags contains the specified mask
         */
        private static final boolean is(int flags, int mask) {
            return (flags & mask) == mask;
        }

        /**
         * Counts the amount of bits needed to shift till bitmask n is at zero
         * @param n Bitmask to test
         */
        private static int count(int n) {
            if (n == 0)
                return 0;
            
            int i = 0;
            while ((n & 0x1) == 0) {
                n = n >> 1;
                i++;
                if (i > 32)
                    throw new RuntimeException(Integer.toHexString(n));
            }

            return i;
        }
        
        /**
         * Converts a 1 to 4 sized byte array to an integer
         */
        private static int byte2int(byte[] b){
            if (b.length == 1)
                return b[0] & 0xFF;
            else if (b.length == 2)
                return (b[0] & 0xFF)
                     | ((b[1] & 0xFF) << 8);
            else if (b.length == 3)
                return (b[0] & 0xFF)
                     | ((b[1] & 0xFF) << 8)
                     | ((b[2] & 0xFF) << 16);
            else if (b.length == 4)
                return (b[0] & 0xFF)
                     | ((b[1] & 0xFF) << 8)
                     | ((b[2] & 0xFF) << 16)
                     | ((b[3] & 0xFF) << 24);
            else
                return 0;
        }

        /**
         * Converts a int representing a FourCC into a String
         */
        private static final String string(int value) {
            StringBuffer buf = new StringBuffer();

            buf.append((char) (value & 0xFF));
            buf.append((char) ((value & 0xFF00) >> 8));
            buf.append((char) ((value & 0xFF0000) >> 16));
            buf.append((char) ((value & 0xFF00000) >> 24));

            return buf.toString();
        }
    }

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -