aboutsummaryrefslogtreecommitdiffstats
path: root/src/classes/com/sun/opengl/impl/glu/mipmap/BuildMipmap.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/classes/com/sun/opengl/impl/glu/mipmap/BuildMipmap.java')
-rw-r--r--src/classes/com/sun/opengl/impl/glu/mipmap/BuildMipmap.java1595
1 files changed, 1595 insertions, 0 deletions
diff --git a/src/classes/com/sun/opengl/impl/glu/mipmap/BuildMipmap.java b/src/classes/com/sun/opengl/impl/glu/mipmap/BuildMipmap.java
new file mode 100644
index 000000000..878eeabe7
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/glu/mipmap/BuildMipmap.java
@@ -0,0 +1,1595 @@
+/*
+ * License Applicability. Except to the extent portions of this file are
+ * made subject to an alternative license as permitted in the SGI Free
+ * Software License B, Version 1.1 (the "License"), the contents of this
+ * file are subject only to the provisions of the License. You may not use
+ * this file except in compliance with the License. You may obtain a copy
+ * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+ * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+ *
+ * http://oss.sgi.com/projects/FreeB
+ *
+ * Note that, as provided in the License, the Software is distributed on an
+ * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+ * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+ * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+ *
+ * NOTE: The Original Code (as defined below) has been licensed to Sun
+ * Microsystems, Inc. ("Sun") under the SGI Free Software License B
+ * (Version 1.1), shown above ("SGI License"). Pursuant to Section
+ * 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+ * you under an alternative license ("Alternative License"). This
+ * Alternative License includes all of the provisions of the SGI License
+ * except that Section 2.2 and 11 are omitted. Any differences between
+ * the Alternative License and the SGI License are offered solely by Sun
+ * and not by SGI.
+ *
+ * Original Code. The Original Code is: OpenGL Sample Implementation,
+ * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+ * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+ * Copyright in any portions created by third parties is as indicated
+ * elsewhere herein. All Rights Reserved.
+ *
+ * Additional Notice Provisions: The application programming interfaces
+ * established by SGI in conjunction with the Original Code are The
+ * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+ * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+ * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+ * Window System(R) (Version 1.3), released October 19, 1998. This software
+ * was created using the OpenGL(R) version 1.2.1 Sample Implementation
+ * published by SGI, but has not been independently verified as being
+ * compliant with the OpenGL(R) version 1.2.1 Specification.
+ */
+
+package com.sun.opengl.impl.glu.mipmap;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2;
+import javax.media.opengl.glu.GLU;
+import com.sun.opengl.impl.Debug;
+import java.nio.*;
+import java.io.*;
+
+/**
+ *
+ * @author Administrator
+ */
+public class BuildMipmap {
+
+ private static final boolean DEBUG = Debug.debug("BuildMipmap");
+ private static final boolean VERBOSE = Debug.verbose();
+
+ /** Creates a new instance of BuildMipmap */
+ public BuildMipmap() {
+ }
+
+ public static int gluBuild1DMipmapLevelsCore( GL gl, int target, int internalFormat,
+ int width, int widthPowerOf2, int format, int type, int userLevel,
+ int baseLevel, int maxLevel, ByteBuffer data ) {
+ int newwidth;
+ int level, levels;
+ ShortBuffer newImage = null;
+ int newImage_width;
+ ShortBuffer otherImage = null;
+ ShortBuffer imageTemp = null;
+ int memreq;
+ int maxsize;
+ int cmpts;
+ PixelStorageModes psm = new PixelStorageModes();
+
+ assert( Mipmap.checkMipmapArgs( internalFormat, format, type ) == 0 );
+ assert( width >= 1 );
+
+ newwidth = widthPowerOf2;
+ levels = Mipmap.computeLog( newwidth );
+
+ levels += userLevel;
+
+ Mipmap.retrieveStoreModes( gl, psm );
+ try {
+ newImage = ByteBuffer.allocateDirect( Mipmap.image_size( width, 1, format,
+ GL2.GL_UNSIGNED_SHORT ) ).order( ByteOrder.nativeOrder() ).asShortBuffer();
+ } catch( OutOfMemoryError ome ) {
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+ newImage_width = width;
+
+ Image.fill_image( psm, width, 1, format, type, Mipmap.is_index( format ), data, newImage );
+ cmpts = Mipmap.elements_per_group( format, type );
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, 2 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, 0 );
+
+ // if swap_bytes was set, swapping occurred in fill_image
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, GL2.GL_FALSE );
+
+ for( level = userLevel; level <= levels; level++ ) {
+ if( newImage_width == newwidth ) {
+ // user newimage for this level
+ if( baseLevel <= level && level <= maxLevel ) {
+ gl.getGL2().glTexImage1D( target, level, internalFormat, newImage_width, 0, format,
+ GL2.GL_UNSIGNED_SHORT, newImage );
+ }
+ } else {
+ if( otherImage == null ) {
+ memreq = Mipmap.image_size( newwidth, 1, format, GL2.GL_UNSIGNED_SHORT );
+ try {
+ otherImage = ByteBuffer.allocateDirect( memreq ).order( ByteOrder.nativeOrder() ).asShortBuffer();
+ } catch( OutOfMemoryError ome ) {
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, (psm.getUnpackSwapBytes() ? 1 : 0) );
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+ }
+ ScaleInternal.scale_internal( cmpts, newImage_width, 1, newImage, newwidth, 1, otherImage );
+ // swap newImage and otherImage
+ imageTemp = otherImage;
+ otherImage = newImage;
+ newImage = imageTemp;
+
+ newImage_width = newwidth;
+ if( baseLevel <= level && level <= maxLevel ) {
+ gl.getGL2().glTexImage1D( target, level, internalFormat, newImage_width, 0,
+ format, GL2.GL_UNSIGNED_SHORT, newImage );
+ }
+ }
+ if( newwidth > 1 ) {
+ newwidth /= 2;
+ }
+ }
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, (psm.getUnpackSwapBytes() ? 1 : 0) );
+
+ return( 0 );
+ }
+
+ public static int bitmapBuild2DMipmaps( GL gl, int target, int internalFormat,
+ int width, int height, int format, int type, ByteBuffer data ) {
+ int newwidth[] = new int[1];
+ int newheight[] = new int[1];
+ int level, levels;
+ ShortBuffer newImage = null;
+ int newImage_width;
+ int newImage_height;
+ ShortBuffer otherImage = null;
+ ShortBuffer tempImage = null;
+ int memreq;
+ int maxsize;
+ int cmpts;
+ PixelStorageModes psm = new PixelStorageModes();
+
+ Mipmap.retrieveStoreModes( gl, psm );
+
+ Mipmap.closestFit( gl, target, width, height, internalFormat, format, type, newwidth, newheight );
+
+ levels = Mipmap.computeLog( newwidth[0] );
+ level = Mipmap.computeLog( newheight[0] );
+ if( level > levels ) {
+ levels = level;
+ }
+
+ try {
+ newImage = ByteBuffer.allocateDirect( Mipmap.image_size( width, height,
+ format, GL2.GL_UNSIGNED_SHORT ) ).order( ByteOrder.nativeOrder() ).asShortBuffer();
+ } catch( OutOfMemoryError ome ) {
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+ newImage_width = width;
+ newImage_height = height;
+
+ Image.fill_image( psm, width, height, format, type, Mipmap.is_index( format ), data, newImage );
+
+ cmpts = Mipmap.elements_per_group( format, type );
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, 2 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, 0 );
+
+ // if swap_bytes is set, swapping occurred in fill_image
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, GL2.GL_FALSE );
+
+ for( level = 0; level < levels; level++ ) {
+ if( newImage_width == newwidth[0] && newImage_height == newheight[0] ) {
+ newImage.rewind();
+ gl.glTexImage2D( target, level, internalFormat, newImage_width,
+ newImage_height, 0, format, GL2.GL_UNSIGNED_SHORT, newImage );
+ } else {
+ if( otherImage == null ) {
+ memreq = Mipmap.image_size( newwidth[0], newheight[0], format, GL2.GL_UNSIGNED_SHORT );
+ try {
+ otherImage = ByteBuffer.allocateDirect( memreq ).order( ByteOrder.nativeOrder() ).asShortBuffer();
+ } catch( OutOfMemoryError ome ) {
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, (psm.getUnpackSwapBytes() ? 1 : 0) );
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+ }
+ ScaleInternal.scale_internal( cmpts, newImage_width, newImage_height,
+ newImage, newwidth[0], newheight[0], otherImage );
+ // swap newImage and otherImage
+ tempImage = otherImage;
+ otherImage = newImage;
+ newImage = tempImage;
+
+ newImage_width = newwidth[0];
+ newImage_height = newheight[0];
+ newImage.rewind();
+ gl.glTexImage2D( target, level, internalFormat, newImage_width, newImage_height,
+ 0, format, GL2.GL_UNSIGNED_SHORT, newImage );
+ }
+ if( newheight[0] > 1 ) {
+ newwidth[0] /= 2;
+ }
+ if( newheight[0] > 1 ) {
+ newheight[0] /= 2;
+ }
+ }
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, (psm.getUnpackSwapBytes() ? 1 : 0) );
+
+ return( 0 );
+ }
+
+ public static int gluBuild2DMipmapLevelsCore( GL gl, int target, int internalFormat,
+ int width, int height, int widthPowerOf2, int heightPowerOf2,
+ int format, int type, int userLevel, int baseLevel, int maxLevel,
+ ByteBuffer data ) { // PointerWrapper data
+ int newwidth;
+ int newheight;
+ int level, levels;
+ int usersImage;
+ ByteBuffer srcImage = null;
+ ByteBuffer dstImage = null;
+ ByteBuffer tempImage = null;
+ int newImage_width;
+ int newImage_height;
+ short[] SWAP_IMAGE = null;
+ int memreq;
+ int maxsize;
+ int cmpts;
+
+ boolean myswap_bytes;
+ int groups_per_line, element_size, group_size;
+ int rowsize, padding;
+ PixelStorageModes psm = new PixelStorageModes();
+
+ assert( Mipmap.checkMipmapArgs( internalFormat, format, type ) == 0 );
+ assert( width >= 1 && height >= 1 );
+
+ if( type == GL2.GL_BITMAP ) {
+ return( bitmapBuild2DMipmaps( gl, target, internalFormat, width, height, format, type, data ) );
+ }
+
+ newwidth = widthPowerOf2;
+ newheight = heightPowerOf2;
+ levels = Mipmap.computeLog( newwidth );
+ level = Mipmap.computeLog( newheight );
+ if( level > levels ) {
+ levels = level;
+ }
+
+ levels += userLevel;
+
+ Mipmap.retrieveStoreModes( gl, psm );
+ myswap_bytes = psm.getUnpackSwapBytes();
+ cmpts = Mipmap.elements_per_group( format, type );
+ if( psm.getUnpackRowLength() > 0 ) {
+ groups_per_line = psm.getUnpackRowLength();
+ } else {
+ groups_per_line = width;
+ }
+
+ element_size = Mipmap.bytes_per_element( type );
+ group_size = element_size * cmpts;
+ if( element_size == 1 ) {
+ myswap_bytes = false;
+ }
+
+ rowsize = groups_per_line * group_size;
+ padding = ( rowsize % psm.getUnpackAlignment() );
+ if( padding != 0 ) {
+ rowsize += psm.getUnpackAlignment() - padding;
+ }
+
+ data.position( psm.getUnpackSkipRows() * rowsize + psm.getUnpackSkipPixels() * group_size );
+ data.mark();
+
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, 0 );
+
+ level = userLevel;
+
+ // already power of two square
+ if( width == newwidth && height == newheight ) {
+ // use usersImage for level userLevel
+ if( baseLevel <= level && level <= maxLevel ) {
+ data.rewind();
+ gl.glTexImage2D( target, level, internalFormat, width, height, 0, format, type, data );
+ }
+ if( levels == 0 ) { /* we're done. clean up and return */
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, (psm.getUnpackSwapBytes() ? 1 : 0) );
+ return( 0 );
+ }
+ int nextWidth = newwidth / 2;
+ int nextHeight = newheight / 2;
+
+ // clamp to 1
+ if( nextWidth < 1 ) {
+ nextWidth = 1;
+ }
+ if( nextHeight < 1 ) {
+ nextHeight = 1;
+ }
+ memreq = Mipmap.image_size( nextWidth, nextHeight, format, type );
+
+ try {
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE ):
+ case( GL2.GL_BYTE ):
+ case( GL2.GL_UNSIGNED_SHORT ):
+ case( GL2.GL_SHORT ):
+ case( GL2.GL_UNSIGNED_INT ):
+ case( GL2.GL_INT ):
+ case( GL2.GL_FLOAT ):
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ dstImage = ByteBuffer.allocateDirect( memreq ).order( ByteOrder.nativeOrder() );
+ break;
+ default:
+ return( GLU.GLU_INVALID_ENUM );
+ }
+ } catch( OutOfMemoryError ome ) {
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, (psm.getUnpackSwapBytes() ? 1 : 0) );
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+ if( dstImage != null ) {
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE ):
+ HalveImage.halveImage_ubyte( cmpts, width, height, data, dstImage, element_size, rowsize, group_size );
+ break;
+ case( GL2.GL_BYTE ):
+ HalveImage.halveImage_byte( cmpts, width, height, data, dstImage, element_size, rowsize, group_size );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT ):
+ HalveImage.halveImage_ushort( cmpts, width, height, data, dstImage.asShortBuffer(), element_size, rowsize, group_size, myswap_bytes );
+ break;
+ case( GL2.GL_SHORT ):
+ HalveImage.halveImage_short( cmpts, width, height, data, dstImage.asShortBuffer(), element_size, rowsize, group_size, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT ):
+ HalveImage.halveImage_uint( cmpts, width, height, data, dstImage.asIntBuffer(), element_size, rowsize, group_size, myswap_bytes );
+ break;
+ case( GL2.GL_INT ):
+ HalveImage.halveImage_int( cmpts, width, height, data, dstImage.asIntBuffer(), element_size, rowsize, group_size, myswap_bytes );
+ break;
+ case( GL2.GL_FLOAT ):
+ HalveImage.halveImage_float( cmpts, width, height, data, dstImage.asFloatBuffer(), element_size, rowsize, group_size, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ assert( format == GL2.GL_RGB );
+ HalveImage.halveImagePackedPixel( 3, new Extract332(), width, height, data, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ assert( format == GL2.GL_RGB );
+ HalveImage.halveImagePackedPixel( 3, new Extract233rev(), width, height, data, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ HalveImage.halveImagePackedPixel( 3, new Extract565(), width, height, data, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ HalveImage.halveImagePackedPixel( 3, new Extract565rev(), width, height, data, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ HalveImage.halveImagePackedPixel( 4, new Extract4444(), width, height, data, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ HalveImage.halveImagePackedPixel( 4, new Extract4444rev(), width, height, data, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ HalveImage.halveImagePackedPixel( 4, new Extract5551(), width, height, data, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ HalveImage.halveImagePackedPixel( 4, new Extract1555rev(), width, height, data, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ HalveImage.halveImagePackedPixel( 4, new Extract8888(), width, height, data, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ HalveImage.halveImagePackedPixel( 4, new Extract8888rev(), width, height, data, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ HalveImage.halveImagePackedPixel( 4, new Extract1010102(), width, height, data, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ HalveImage.halveImagePackedPixel( 4, new Extract2101010rev(), width, height, data, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ default:
+ assert( false );
+ break;
+ }
+ }
+ newwidth = width / 2;
+ newheight = height / 2;
+ // clamp to 1
+ if( newwidth < 1 ) {
+ newwidth = 1;
+ }
+ if( newheight < 1 ) {
+ newheight = 1;
+ }
+
+ myswap_bytes = false;
+ rowsize = newwidth * group_size;
+ memreq = Mipmap.image_size( newwidth, newheight, format, type );
+ // swap srcImage and dstImage
+ tempImage = srcImage;
+ srcImage = dstImage;
+ dstImage = tempImage;
+ try {
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE ):
+ case( GL2.GL_BYTE ):
+ case( GL2.GL_UNSIGNED_SHORT ):
+ case( GL2.GL_SHORT ):
+ case( GL2.GL_UNSIGNED_INT ):
+ case( GL2.GL_INT ):
+ case( GL2.GL_FLOAT ):
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ dstImage = ByteBuffer.allocateDirect( memreq ).order( ByteOrder.nativeOrder() );
+ break;
+ default:
+ return( GLU.GLU_INVALID_ENUM );
+ }
+ } catch( OutOfMemoryError ome ) {
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, (psm.getUnpackSwapBytes() ? 1 : 0) );
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+ // level userLevel+1 is in srcImage; level userLevel already saved
+ level = userLevel + 1;
+ } else { // user's image is not nice powerof2 size square
+ memreq = Mipmap.image_size( newwidth, newheight, format, type );
+ try {
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE ):
+ case( GL2.GL_BYTE ):
+ case( GL2.GL_UNSIGNED_SHORT ):
+ case( GL2.GL_SHORT ):
+ case( GL2.GL_UNSIGNED_INT ):
+ case( GL2.GL_INT ):
+ case( GL2.GL_FLOAT ):
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ dstImage = ByteBuffer.allocateDirect( memreq ).order( ByteOrder.nativeOrder() );
+ break;
+ default:
+ return( GLU.GLU_INVALID_ENUM );
+ }
+ } catch( OutOfMemoryError ome ) {
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, (psm.getUnpackSwapBytes() ? 1 : 0) );
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+ data.reset();
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE ):
+ ScaleInternal.scale_internal_ubyte( cmpts, width, height, data,
+ newwidth, newheight, dstImage, element_size, rowsize, group_size );
+ break;
+ case( GL2.GL_BYTE ):
+ ScaleInternal.scale_internal_byte( cmpts, width, height, data, newwidth,
+ newheight, dstImage, element_size, rowsize, group_size );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT ):
+ ScaleInternal.scale_internal_ushort( cmpts, width, height, data, newwidth,
+ newheight, dstImage.asShortBuffer(), element_size, rowsize, group_size, myswap_bytes );
+ break;
+ case( GL2.GL_SHORT ):
+ ScaleInternal.scale_internal_ushort( cmpts, width, height, data, newwidth,
+ newheight, dstImage.asShortBuffer(), element_size, rowsize, group_size, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT ):
+ ScaleInternal.scale_internal_uint( cmpts, width, height, data, newwidth,
+ newheight, dstImage.asIntBuffer(), element_size, rowsize, group_size, myswap_bytes );
+ break;
+ case( GL2.GL_INT ):
+ ScaleInternal.scale_internal_int( cmpts, width, height, data, newwidth,
+ newheight, dstImage.asIntBuffer(), element_size, rowsize, group_size, myswap_bytes );
+ break;
+ case( GL2.GL_FLOAT ):
+ ScaleInternal.scale_internal_float( cmpts, width, height, data, newwidth,
+ newheight, dstImage.asFloatBuffer(), element_size, rowsize, group_size, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ ScaleInternal.scaleInternalPackedPixel( 3, new Extract332(), width, height, data, newwidth,
+ newheight, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ ScaleInternal.scaleInternalPackedPixel( 3, new Extract233rev(), width, height, data, newwidth,
+ newheight, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ ScaleInternal.scaleInternalPackedPixel( 3, new Extract565(), width, height, data, newwidth,
+ newheight, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ ScaleInternal.scaleInternalPackedPixel( 3, new Extract565rev(), width, height, data, newwidth,
+ newheight, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ ScaleInternal.scaleInternalPackedPixel( 4, new Extract4444(), width, height, data, newwidth,
+ newheight, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ ScaleInternal.scaleInternalPackedPixel( 4, new Extract4444rev(), width, height, data, newwidth,
+ newheight, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ ScaleInternal.scaleInternalPackedPixel( 4, new Extract5551(), width, height, data, newwidth,
+ newheight, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ ScaleInternal.scaleInternalPackedPixel( 4, new Extract1555rev(), width, height, data, newwidth,
+ newheight, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ ScaleInternal.scaleInternalPackedPixel( 4, new Extract8888(), width, height, data, newwidth,
+ newheight, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ ScaleInternal.scaleInternalPackedPixel( 4, new Extract8888rev(), width, height, data, newwidth,
+ newheight, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ ScaleInternal.scaleInternalPackedPixel( 4, new Extract1010102(), width, height, data, newwidth,
+ newheight, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ ScaleInternal.scaleInternalPackedPixel( 4, new Extract2101010rev(), width, height, data, newwidth,
+ newheight, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ default:
+ assert( false );
+ break;
+ }
+ myswap_bytes = false;
+ rowsize = newwidth * group_size;
+ // swap dstImage and srcImage
+ tempImage = srcImage;
+ srcImage = dstImage;
+ dstImage = tempImage;
+
+ if( levels != 0 ) { // use as little memory as possible
+ int nextWidth = newwidth / 2;
+ int nextHeight = newheight / 2;
+ if( nextWidth < 1 ) {
+ nextWidth = 1;
+ }
+ if( nextHeight < 1 ) {
+ nextHeight = 1;
+ }
+
+ memreq = Mipmap.image_size( nextWidth, nextHeight, format, type );
+ try {
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE ):
+ case( GL2.GL_BYTE ):
+ case( GL2.GL_UNSIGNED_SHORT ):
+ case( GL2.GL_SHORT ):
+ case( GL2.GL_UNSIGNED_INT ):
+ case( GL2.GL_INT ):
+ case( GL2.GL_FLOAT ):
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ dstImage = ByteBuffer.allocateDirect( memreq ).order( ByteOrder.nativeOrder() );
+ break;
+ default:
+ return( GLU.GLU_INVALID_ENUM );
+ }
+ } catch( OutOfMemoryError ome ) {
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, (psm.getUnpackSwapBytes() ? 1 : 0) );
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+ }
+ // level userLevel is in srcImage; nothing saved yet
+ level = userLevel;
+ }
+
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, GL2.GL_FALSE );
+ if( baseLevel <= level && level <= maxLevel ) {
+ srcImage.rewind();
+ gl.glTexImage2D( target, level, internalFormat, newwidth, newheight, 0, format, type, srcImage );
+ if (DEBUG) {
+ System.err.println("GL Error(" + level + "): " + gl.glGetError() );
+ if (VERBOSE) {
+ srcImage.limit( Mipmap.image_size( newwidth, newheight, format, type ) );
+ writeTargaFile("glu2DMipmapJ" + level + ".tga",
+ srcImage, newwidth, newheight);
+ srcImage.clear();
+ }
+ }
+ }
+
+ level++; // update current level for the loop
+ for( ; level <= levels; level++ ) {
+ srcImage.rewind();
+ dstImage.rewind();
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE ):
+ HalveImage.halveImage_ubyte( cmpts, newwidth, newheight, srcImage, dstImage, element_size, rowsize, group_size );
+ break;
+ case( GL2.GL_BYTE ):
+ HalveImage.halveImage_byte( cmpts, newwidth, newheight, srcImage, dstImage, element_size, rowsize, group_size );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT ):
+ HalveImage.halveImage_ushort( cmpts, newwidth, newheight, srcImage, dstImage.asShortBuffer(), element_size, rowsize, group_size, myswap_bytes );
+ break;
+ case( GL2.GL_SHORT ):
+ HalveImage.halveImage_short( cmpts, newwidth, newheight, srcImage, dstImage.asShortBuffer(), element_size, rowsize, group_size, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT ):
+ HalveImage.halveImage_uint( cmpts, newwidth, newheight, srcImage, dstImage.asIntBuffer(), element_size, rowsize, group_size, myswap_bytes );
+ break;
+ case( GL2.GL_INT ):
+ HalveImage.halveImage_int( cmpts, newwidth, newheight, srcImage, dstImage.asIntBuffer(), element_size, rowsize, group_size, myswap_bytes );
+ break;
+ case( GL2.GL_FLOAT ):
+ HalveImage.halveImage_float( cmpts, newwidth, newheight, srcImage, dstImage.asFloatBuffer(), element_size, rowsize, group_size, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ assert( format == GL2.GL_RGB );
+ HalveImage.halveImagePackedPixel( 3, new Extract332(), newwidth, newheight, srcImage, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ assert( format == GL2.GL_RGB );
+ HalveImage.halveImagePackedPixel( 3, new Extract233rev(), newwidth, newheight, srcImage, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ HalveImage.halveImagePackedPixel( 3, new Extract565(), newwidth, newheight, srcImage, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ HalveImage.halveImagePackedPixel( 3, new Extract565rev(), newwidth, newheight, srcImage, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ HalveImage.halveImagePackedPixel( 4, new Extract4444(), newwidth, newheight, srcImage, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ HalveImage.halveImagePackedPixel( 4, new Extract4444rev(), newwidth, newheight, srcImage, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ HalveImage.halveImagePackedPixel( 4, new Extract5551(), newwidth, newheight, srcImage, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ HalveImage.halveImagePackedPixel( 4, new Extract1555rev(), newwidth, newheight, srcImage, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ HalveImage.halveImagePackedPixel( 4, new Extract8888(), newwidth, newheight, srcImage, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ HalveImage.halveImagePackedPixel( 4, new Extract8888rev(), newwidth, newheight, srcImage, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ HalveImage.halveImagePackedPixel( 4, new Extract1010102(), newwidth, newheight, srcImage, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ HalveImage.halveImagePackedPixel( 4, new Extract2101010rev(), newwidth, newheight, srcImage, dstImage, element_size, rowsize, myswap_bytes );
+ break;
+ default:
+ assert( false );
+ break;
+ }
+
+ // swap dstImage and srcImage
+ tempImage = srcImage;
+ srcImage = dstImage;
+ dstImage = tempImage;
+
+ if( newwidth > 1 ) {
+ newwidth /= 2;
+ rowsize /= 2;
+ }
+ if( newheight > 1 ) {
+ newheight /= 2;
+ }
+ // compute amount to pad per row if any
+ int rowPad = rowsize % psm.getUnpackAlignment();
+
+ // should row be padded
+ if( rowPad == 0 ) {
+ // call teximage with srcImage untouched since its not padded
+ if( baseLevel <= level && level <= maxLevel ) {
+ srcImage.rewind();
+ gl.glTexImage2D( target, level, internalFormat, newwidth, newheight, 0, format, type, srcImage );
+ if (DEBUG) {
+ System.err.println("GL Error(" + level + "): " + gl.glGetError() );
+ if (VERBOSE) {
+ srcImage.limit( Mipmap.image_size( newwidth, newheight, format, type ) );
+ writeTargaFile("glu2DMipmapJ" + level + ".tga",
+ srcImage, newwidth, newheight);
+ srcImage.clear();
+ }
+ }
+ }
+ } else {
+ // compute length of new row in bytes, including padding
+ int newRowLength = rowsize + psm.getUnpackAlignment() - rowPad;
+ int ii, jj;
+ int dstTrav;
+ int srcTrav;
+
+ // allocate new image for mipmap of size newRowLength x newheight
+ ByteBuffer newMipmapImage = null;
+ try {
+ newMipmapImage = ByteBuffer.allocateDirect( newRowLength * newheight );
+ } catch( OutOfMemoryError ome ) {
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, (psm.getUnpackSwapBytes() ? 1 : 0) );
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+ srcImage.rewind();
+ // copy image from srcImage into newMipmapImage by rows
+ for( ii = 0; ii < newheight; ii++ ) {
+ newMipmapImage.position(newRowLength * ii);
+ for( jj = 0; jj < rowsize; jj++ ) {
+ newMipmapImage.put( srcImage.get() );
+ }
+ }
+
+ // and use this new image for mipmapping instead
+ if( baseLevel <= level && level <= maxLevel ) {
+ newMipmapImage.rewind();
+ gl.glTexImage2D( target, level, internalFormat, newwidth, newheight, 0, format, type, newMipmapImage );
+ if (DEBUG) {
+ System.err.println("GL Error(" + level + " padded): " + gl.glGetError() );
+ if (VERBOSE) {
+ writeTargaFile("glu2DMipmapJ" + level + ".tga",
+ newMipmapImage, newwidth, newheight);
+ }
+ }
+ }
+ }
+ }
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, (psm.getUnpackSwapBytes() ? 1 : 0) );
+
+ return( 0 );
+ }
+
+ public static int fastBuild2DMipmaps( GL gl, PixelStorageModes psm, int target,
+ int components, int width, int height, int format, int type, ByteBuffer data ) {
+ int[] newwidth = new int[1];
+ int[] newheight = new int[1];
+ int level, levels;
+ ByteBuffer newImage;
+ int newImage_width;
+ int newImage_height;
+ ByteBuffer otherImage;
+ ByteBuffer imageTemp;
+ int memreq;
+ int maxsize;
+ int cmpts;
+
+ Mipmap.closestFit( gl, target, width, height, components, format, type, newwidth,
+ newheight );
+
+ levels = Mipmap.computeLog( newwidth[0] );
+ level = Mipmap.computeLog( newheight[0] );
+ if( level > levels ) {
+ levels = level;
+ }
+
+ cmpts = Mipmap.elements_per_group( format, type );
+
+ otherImage = null;
+ // No need to copy the user data if its packed correctly.
+ // Make sure that later routines don't change that data.
+
+ if( psm.getUnpackSkipRows() == 0 && psm.getUnpackSkipPixels() == 0 ) {
+ newImage = data;
+ newImage_width = width;
+ newImage_height = height;
+ } else {
+ int rowsize;
+ int group_per_line;
+ int elements_per_line;
+ int start;
+ int iter;
+ int iter2;
+ int i, j;
+
+ try {
+ newImage = ByteBuffer.allocateDirect( Mipmap.image_size(
+ width, height, format, GL2.GL_UNSIGNED_BYTE ) ).order( ByteOrder.nativeOrder() );
+ } catch( OutOfMemoryError err ) {
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+ newImage_width = width;
+ newImage_height = height;
+
+ // Abbreviated version of fill_image for the restricted case.
+ if( psm.getUnpackRowLength() > 0 ) {
+ group_per_line = psm.getUnpackRowLength();
+ } else {
+ group_per_line = width;
+ }
+ rowsize = group_per_line * cmpts;
+ elements_per_line = width * cmpts;
+ start = psm.getUnpackSkipRows() * rowsize + psm.getUnpackSkipPixels() * cmpts;
+
+ for( i = 0; i < height; i++ ) {
+ iter = start;
+ data.position( iter );
+ for( j = 0; j < elements_per_line; j++ ) {
+ newImage.put( data.get() );
+ }
+ start += rowsize;
+ }
+ }
+
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, 1 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, GL2.GL_FALSE );
+
+ for( level = 0; level <= levels; level++ ) {
+ if( newImage_width == newwidth[0] && newImage_height == newheight[0] ) {
+ // use newImage for this level
+ newImage.rewind();
+ gl.glTexImage2D( target, level, components, newImage_width, newImage_height,
+ 0, format, GL2.GL_UNSIGNED_BYTE, newImage );
+ } else {
+ if( otherImage == null ) {
+ memreq = Mipmap.image_size( newwidth[0], newheight[0], format, GL2.GL_UNSIGNED_BYTE );
+ try {
+ otherImage = ByteBuffer.allocateDirect( memreq ).order( ByteOrder.nativeOrder() );
+ } catch( OutOfMemoryError err ) {
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, ( psm.getUnpackSwapBytes() ? 1 : 0 ) ) ;
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+ }
+ // swap newImage and otherImage
+ imageTemp = otherImage;
+ otherImage = newImage;
+ newImage = imageTemp;
+
+ newImage_width = newwidth[0];
+ newImage_height = newheight[0];
+ newImage.rewind();
+ gl.glTexImage2D( target, level, components, newImage_width, newImage_height,
+ 0, format, GL2.GL_UNSIGNED_BYTE, newImage );
+ }
+ if( newwidth[0] > 1 ) {
+ newwidth[0] /= 2;
+ }
+ if( newheight[0] > 1 ) {
+ newheight[0] /= 2;
+ }
+ }
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, ( psm.getUnpackSwapBytes() ? 1 : 0 ) ) ;
+
+ return( 0 );
+ }
+
+ public static int gluBuild3DMipmapLevelsCore( GL gl, int target, int internalFormat,
+ int width, int height, int depth, int widthPowerOf2, int heightPowerOf2,
+ int depthPowerOf2, int format, int type, int userLevel, int baseLevel,
+ int maxLevel, ByteBuffer data ) {
+ int newWidth;
+ int newHeight;
+ int newDepth;
+ int level, levels;
+ ByteBuffer usersImage;
+ ByteBuffer srcImage, dstImage, tempImage;
+ int newImageWidth;
+ int newImageHeight;
+ int newImageDepth;
+ int memReq;
+ int maxSize;
+ int cmpts;
+
+ boolean myswapBytes;
+ int groupsPerLine, elementSize, groupSize;
+ int rowsPerImage, imageSize;
+ int rowSize, padding;
+ PixelStorageModes psm = new PixelStorageModes();
+
+ assert( Mipmap.checkMipmapArgs( internalFormat, format, type ) == 0 );
+ assert( width >= 1 && height >= 1 && depth >= 1 );
+ assert( type != GL2.GL_BITMAP );
+
+ srcImage = dstImage = null;
+
+ newWidth = widthPowerOf2;
+ newHeight = heightPowerOf2;
+ newDepth = depthPowerOf2;
+ levels = Mipmap.computeLog( newWidth );
+ level = Mipmap.computeLog( newHeight );
+ if( level > levels ) {
+ levels = level;
+ }
+ level = Mipmap.computeLog( newDepth );
+ if( level > levels ) {
+ levels = level;
+ }
+
+ levels += userLevel;
+
+ Mipmap.retrieveStoreModes3D( gl, psm );
+ myswapBytes = psm.getUnpackSwapBytes();
+ cmpts = Mipmap.elements_per_group( format, type );
+ if( psm.getUnpackRowLength() > 0 ) {
+ groupsPerLine = psm.getUnpackRowLength();
+ } else {
+ groupsPerLine = width;
+ }
+
+ elementSize = Mipmap.bytes_per_element( type );
+ groupSize = elementSize * cmpts;
+ if( elementSize == 1 ) {
+ myswapBytes = false;
+ }
+
+ // 3dstuff
+ if( psm.getUnpackImageHeight() > 0 ) {
+ rowsPerImage = psm.getUnpackImageHeight();
+ } else {
+ rowsPerImage = height;
+ }
+
+ rowSize = groupsPerLine * groupSize;
+ padding = ( rowSize % psm.getUnpackAlignment() );
+ if( padding != 0 ) {
+ rowSize += psm.getUnpackAlignment() - padding;
+ }
+
+ imageSize = rowsPerImage * rowSize;
+
+ usersImage = data.duplicate();
+ usersImage.position( psm.getUnpackSkipRows() * rowSize +
+ psm.getUnpackSkipPixels() * groupSize +
+ psm.getUnpackSkipImages() * imageSize );
+ usersImage.mark();
+
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_IMAGES, 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_IMAGE_HEIGHT, 0 );
+
+ level = userLevel;
+
+ if( width == newWidth && height == newHeight && depth == newDepth ) {
+ // use usersImage for level userlevel
+ if( baseLevel <= level && level <= maxLevel ) {
+ gl.getGL2().glTexImage3D( target, level, internalFormat, width, height, depth,
+ 0, format, type, usersImage );
+ }
+ if( levels == 0 ) { /* we're done. clean up and return */
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, psm.getUnpackSwapBytes() ? 1 : 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_IMAGES, psm.getUnpackSkipImages() );
+ gl.glPixelStorei( GL2.GL_UNPACK_IMAGE_HEIGHT, psm.getUnpackImageHeight() );
+ return( 0 );
+ }
+ int nextWidth = newWidth / 2;
+ int nextHeight = newHeight / 2;
+ int nextDepth = newDepth / 2;
+
+ // clamp to one
+ if( nextWidth < 1 ) {
+ nextWidth = 1;
+ }
+ if( nextHeight < 1 ) {
+ nextHeight = 1;
+ }
+ if( nextDepth < 1 ) {
+ nextDepth = 1;
+ }
+ memReq = Mipmap.imageSize3D( nextWidth, nextHeight, nextDepth, format, type );
+ try {
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE ):
+ case( GL2.GL_BYTE ):
+ case( GL2.GL_UNSIGNED_SHORT ):
+ case( GL2.GL_SHORT ):
+ case( GL2.GL_UNSIGNED_INT ):
+ case( GL2.GL_INT ):
+ case( GL2.GL_FLOAT ):
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ dstImage = ByteBuffer.allocateDirect( memReq ).order( ByteOrder.nativeOrder() );
+ break;
+ default:
+ return( GLU.GLU_INVALID_ENUM );
+ }
+ } catch( OutOfMemoryError err ) {
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, psm.getUnpackSwapBytes() ? 1 : 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_IMAGES, psm.getUnpackSkipImages() );
+ gl.glPixelStorei( GL2.GL_UNPACK_IMAGE_HEIGHT, psm.getUnpackImageHeight() );
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+
+ if( dstImage != null ) {
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE ):
+ if( depth > 1 ) {
+ HalveImage.halveImage3D( cmpts, new ExtractUByte(), width, height, depth,
+ usersImage, dstImage, elementSize,
+ groupSize, rowSize, imageSize, myswapBytes );
+ } else {
+ HalveImage.halveImage_ubyte( cmpts, width, height, usersImage,
+ dstImage, elementSize, rowSize, groupSize );
+ }
+ break;
+ case( GL2.GL_BYTE ):
+ if( depth > 1 ) {
+ HalveImage.halveImage3D( cmpts, new ExtractSByte(), width, height, depth,
+ usersImage, dstImage, elementSize, groupSize, rowSize,
+ imageSize, myswapBytes );
+ } else {
+ HalveImage.halveImage_byte( cmpts, width, height, usersImage,
+ dstImage, elementSize, rowSize, groupSize );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT ):
+ if( depth > 1 ) {
+ HalveImage.halveImage3D( cmpts, new ExtractUShort(), width, height, depth,
+ usersImage, dstImage, elementSize, groupSize, rowSize,
+ imageSize, myswapBytes );
+ } else {
+ HalveImage.halveImage_ushort( cmpts, width, height, usersImage,
+ dstImage.asShortBuffer(), elementSize, rowSize, groupSize, myswapBytes );
+ }
+ break;
+ case( GL2.GL_SHORT ):
+ if( depth > 1 ) {
+ HalveImage.halveImage3D( cmpts, new ExtractSShort(), width, height, depth,
+ usersImage, dstImage, elementSize, groupSize, rowSize,
+ imageSize, myswapBytes );
+ } else {
+ HalveImage.halveImage_short( cmpts, width, height, usersImage,
+ dstImage.asShortBuffer(), elementSize, rowSize, groupSize, myswapBytes );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_INT ):
+ if( depth > 1 ) {
+ HalveImage.halveImage3D( cmpts, new ExtractUInt(), width, height, depth,
+ usersImage, dstImage, elementSize, groupSize, rowSize,
+ imageSize, myswapBytes );
+ } else {
+ HalveImage.halveImage_uint( cmpts, width, height, usersImage,
+ dstImage.asIntBuffer(), elementSize, rowSize, groupSize, myswapBytes );
+ }
+ break;
+ case( GL2.GL_INT ):
+ if( depth > 1 ) {
+ HalveImage.halveImage3D( cmpts, new ExtractSInt(), width, height, depth,
+ usersImage, dstImage, elementSize, groupSize, rowSize,
+ imageSize, myswapBytes );
+ } else {
+ HalveImage.halveImage_int( cmpts, width, height, usersImage,
+ dstImage.asIntBuffer(), elementSize, rowSize, groupSize, myswapBytes );
+ }
+ break;
+ case( GL2.GL_FLOAT ):
+ if( depth > 1 ) {
+ HalveImage.halveImage3D( cmpts, new ExtractFloat(), width, height, depth,
+ usersImage, dstImage, elementSize, groupSize, rowSize,
+ imageSize, myswapBytes );
+ } else {
+ HalveImage.halveImage_float( cmpts, width, height, usersImage,
+ dstImage.asFloatBuffer(), elementSize, rowSize, groupSize, myswapBytes );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ assert( format == GL2.GL_RGB );
+ HalveImage.halveImagePackedPixel3D( 3, new Extract332(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ assert( format == GL2.GL_RGB );
+ HalveImage.halveImagePackedPixel3D( 3, new Extract233rev(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ HalveImage.halveImagePackedPixel3D( 3, new Extract565(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ HalveImage.halveImagePackedPixel3D( 3, new Extract565rev(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract4444(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract4444rev(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract5551(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract1555rev(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract8888(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract8888rev(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract1010102(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract2101010rev(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ default:
+ assert( false );
+ break;
+ }
+ }
+ newWidth = width / 2;
+ newHeight = height / 2;
+ newDepth = depth / 2;
+ // clamp to 1
+ if( newWidth < 1 ) {
+ newWidth = 1;
+ }
+ if( newHeight < 1 ) {
+ newHeight = 1;
+ }
+ if( newDepth < 1 ) {
+ newDepth = 1;
+ }
+
+ myswapBytes = false;
+ rowSize = newWidth * groupSize;
+ imageSize = rowSize * newHeight;
+ memReq = Mipmap.imageSize3D( newWidth, newHeight, newDepth, format, type );
+ // swap srcImage and dstImage
+ tempImage = srcImage;
+ srcImage = dstImage;
+ dstImage = tempImage;
+ try {
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE ):
+ case( GL2.GL_BYTE ):
+ case( GL2.GL_UNSIGNED_SHORT ):
+ case( GL2.GL_SHORT ):
+ case( GL2.GL_UNSIGNED_INT ):
+ case( GL2.GL_INT ):
+ case( GL2.GL_FLOAT ):
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ dstImage = ByteBuffer.allocateDirect( memReq ).order( ByteOrder.nativeOrder() );
+ break;
+ default:
+ return( GLU.GLU_INVALID_ENUM );
+ }
+ } catch( OutOfMemoryError err ) {
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, psm.getUnpackSwapBytes() ? 1 : 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_IMAGES, psm.getUnpackSkipImages() );
+ gl.glPixelStorei( GL2.GL_UNPACK_IMAGE_HEIGHT, psm.getUnpackImageHeight() );
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+
+ // level userLevel + 1 is in srcImage; level userLevel already saved
+ level = userLevel + 1;
+ } else {
+ memReq = Mipmap.imageSize3D( newWidth, newHeight, newDepth, format, type );
+ try {
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE ):
+ case( GL2.GL_BYTE ):
+ case( GL2.GL_UNSIGNED_SHORT ):
+ case( GL2.GL_SHORT ):
+ case( GL2.GL_UNSIGNED_INT ):
+ case( GL2.GL_INT ):
+ case( GL2.GL_FLOAT ):
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ dstImage = ByteBuffer.allocateDirect( memReq ).order( ByteOrder.nativeOrder() );
+ break;
+ default:
+ return( GLU.GLU_INVALID_ENUM );
+ }
+ } catch( OutOfMemoryError err ) {
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, psm.getUnpackSwapBytes() ? 1 : 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_IMAGES, psm.getUnpackSkipImages() );
+ gl.glPixelStorei( GL2.GL_UNPACK_IMAGE_HEIGHT, psm.getUnpackImageHeight() );
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+
+ ScaleInternal.gluScaleImage3D( gl, format, width, height, depth, type,
+ usersImage, newWidth, newHeight, newDepth, type, dstImage );
+
+ myswapBytes = false;
+ rowSize = newWidth * groupSize;
+ imageSize = rowSize * newHeight;
+ // swap dstImage and srcImage
+ tempImage = srcImage;
+ srcImage = dstImage;
+ dstImage = tempImage;
+
+ if( levels != 0 ) {
+ int nextWidth = newWidth / 2;
+ int nextHeight = newHeight / 2;
+ int nextDepth = newDepth / 2;
+ if( nextWidth < 1 ) {
+ nextWidth = 1;
+ }
+ if( nextHeight < 1 ) {
+ nextHeight = 1;
+ }
+ if( nextDepth < 1 ) {
+ nextDepth = 1;
+ }
+ memReq = Mipmap.imageSize3D( nextWidth, nextHeight, nextDepth, format, type );
+ try {
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE ):
+ case( GL2.GL_BYTE ):
+ case( GL2.GL_UNSIGNED_SHORT ):
+ case( GL2.GL_SHORT ):
+ case( GL2.GL_UNSIGNED_INT ):
+ case( GL2.GL_INT ):
+ case( GL2.GL_FLOAT ):
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ dstImage = ByteBuffer.allocateDirect( memReq ).order( ByteOrder.nativeOrder() );
+ break;
+ default:
+ return( GLU.GLU_INVALID_ENUM );
+ }
+ } catch( OutOfMemoryError err ) {
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, psm.getUnpackSwapBytes() ? 1 : 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_IMAGES, psm.getUnpackSkipImages() );
+ gl.glPixelStorei( GL2.GL_UNPACK_IMAGE_HEIGHT, psm.getUnpackImageHeight() );
+ return( GLU.GLU_OUT_OF_MEMORY );
+ }
+ }
+ // level userLevel is in srcImage; nothing saved yet
+ level = userLevel;
+ }
+
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, GL2.GL_FALSE );
+ if( baseLevel <= level && level <= maxLevel ) {
+ usersImage.reset();
+ gl.getGL2().glTexImage3D( target, level, internalFormat, width, height, depth,
+ 0, format, type, usersImage );
+ }
+ level++;
+ for( ; level <= levels; level++ ) {
+ switch( type ) {
+ case( GL2.GL_UNSIGNED_BYTE ):
+ if( depth > 1 ) {
+ HalveImage.halveImage3D( cmpts, new ExtractUByte(), width, height, depth,
+ usersImage, dstImage, elementSize, groupSize, rowSize,
+ imageSize, myswapBytes );
+ } else {
+ HalveImage.halveImage_ubyte( cmpts, width, height, usersImage,
+ dstImage, elementSize, rowSize, groupSize );
+ }
+ break;
+ case( GL2.GL_BYTE ):
+ if( depth > 1 ) {
+ HalveImage.halveImage3D( cmpts, new ExtractSByte(), width, height, depth,
+ usersImage, dstImage, elementSize, groupSize, rowSize,
+ imageSize, myswapBytes );
+ } else {
+ HalveImage.halveImage_byte( cmpts, width, height, usersImage,
+ dstImage, elementSize, rowSize, groupSize );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_SHORT ):
+ if( depth > 1 ) {
+ HalveImage.halveImage3D( cmpts, new ExtractUShort(), width, height, depth,
+ usersImage, dstImage, elementSize, groupSize, rowSize,
+ imageSize, myswapBytes );
+ } else {
+ HalveImage.halveImage_ushort( cmpts, width, height, usersImage,
+ dstImage.asShortBuffer(), elementSize, rowSize, groupSize, myswapBytes );
+ }
+ break;
+ case( GL2.GL_SHORT ):
+ if( depth > 1 ) {
+ HalveImage.halveImage3D( cmpts, new ExtractSShort(), width, height, depth,
+ usersImage, dstImage, elementSize, groupSize, rowSize,
+ imageSize, myswapBytes );
+ } else {
+ HalveImage.halveImage_short( cmpts, width, height, usersImage,
+ dstImage.asShortBuffer(), elementSize, rowSize, groupSize, myswapBytes );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_INT ):
+ if( depth > 1 ) {
+ HalveImage.halveImage3D( cmpts, new ExtractUInt(), width, height, depth,
+ usersImage, dstImage, elementSize, groupSize, rowSize,
+ imageSize, myswapBytes );
+ } else {
+ HalveImage.halveImage_uint( cmpts, width, height, usersImage,
+ dstImage.asIntBuffer(), elementSize, rowSize, groupSize, myswapBytes );
+ }
+ break;
+ case( GL2.GL_INT ):
+ if( depth > 1 ) {
+ HalveImage.halveImage3D( cmpts, new ExtractSInt(), width, height, depth,
+ usersImage, dstImage, elementSize, groupSize, rowSize,
+ imageSize, myswapBytes );
+ } else {
+ HalveImage.halveImage_int( cmpts, width, height, usersImage,
+ dstImage.asIntBuffer(), elementSize, rowSize, groupSize, myswapBytes );
+ }
+ break;
+ case( GL2.GL_FLOAT ):
+ if( depth > 1 ) {
+ HalveImage.halveImage3D( cmpts, new ExtractFloat(), width, height, depth,
+ usersImage, dstImage, elementSize, groupSize, rowSize,
+ imageSize, myswapBytes );
+ } else {
+ HalveImage.halveImage_float( cmpts, width, height, usersImage,
+ dstImage.asFloatBuffer(), elementSize, rowSize, groupSize, myswapBytes );
+ }
+ break;
+ case( GL2.GL_UNSIGNED_BYTE_3_3_2 ):
+ HalveImage.halveImagePackedPixel3D( 3, new Extract332(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_BYTE_2_3_3_REV ):
+ HalveImage.halveImagePackedPixel3D( 3, new Extract233rev(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5 ):
+ HalveImage.halveImagePackedPixel3D( 3, new Extract565(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_6_5_REV ):
+ HalveImage.halveImagePackedPixel3D( 3, new Extract565rev(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4 ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract4444(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_4_4_4_4_REV ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract4444rev(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_5_5_5_1 ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract5551(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_SHORT_1_5_5_5_REV ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract1555rev(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8 ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract8888(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_8_8_8_8_REV ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract8888rev(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_10_10_10_2 ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract1010102(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ case( GL2.GL_UNSIGNED_INT_2_10_10_10_REV ):
+ HalveImage.halveImagePackedPixel3D( 4, new Extract2101010rev(), width, height, depth, usersImage,
+ dstImage, elementSize, rowSize, imageSize, myswapBytes );
+ break;
+ default:
+ assert( false );
+ break;
+ }
+
+ tempImage = srcImage;
+ srcImage = dstImage;
+ dstImage = tempImage;
+
+ if( newWidth > 1 ) {
+ newWidth /= 2;
+ rowSize /= 2;
+ }
+ if( newHeight > 1 ) {
+ newHeight /= 2;
+ imageSize = rowSize * newHeight;
+ }
+ if( newDepth > 1 ) {
+ newDepth /= 2;
+ }
+ if( baseLevel <= level && level <= maxLevel ) {
+ usersImage.reset();
+ gl.getGL2().glTexImage3D( target, level, internalFormat, width, height, depth,
+ 0, format, type, usersImage );
+ }
+ }
+ gl.glPixelStorei( GL2.GL_UNPACK_ALIGNMENT, psm.getUnpackAlignment() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_ROWS, psm.getUnpackSkipRows() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_PIXELS, psm.getUnpackSkipPixels() );
+ gl.glPixelStorei( GL2.GL_UNPACK_ROW_LENGTH, psm.getUnpackRowLength() );
+ gl.glPixelStorei( GL2.GL_UNPACK_SWAP_BYTES, psm.getUnpackSwapBytes() ? 1 : 0 );
+ gl.glPixelStorei( GL2.GL_UNPACK_SKIP_IMAGES, psm.getUnpackSkipImages() );
+ gl.glPixelStorei( GL2.GL_UNPACK_IMAGE_HEIGHT, psm.getUnpackImageHeight() );
+ return( 0 );
+ }
+
+ private static final int TARGA_HEADER_SIZE = 18;
+ private static void writeTargaFile(String filename, ByteBuffer data,
+ int width, int height) {
+ try {
+ FileOutputStream fos = new FileOutputStream(new File(filename));
+ ByteBuffer header = ByteBuffer.allocate(TARGA_HEADER_SIZE);
+ header.put(0, (byte) 0).put(1, (byte) 0);
+ header.put(2, (byte) 2); // uncompressed type
+ header.put(12, (byte) (width & 0xFF)); // width
+ header.put(13, (byte) (width >> 8)); // width
+ header.put(14, (byte) (height & 0xFF)); // height
+ header.put(15, (byte) (height >> 8)); // height
+ header.put(16, (byte) 24); // pixel size
+ fos.getChannel().write(header);
+ fos.getChannel().write(data);
+ data.clear();
+ fos.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}