1 /* 2 * License Applicability. Except to the extent portions of this file are 3 * made subject to an alternative license as permitted in the SGI Free 4 * Software License B, Version 2.0 (the "License"), the contents of this 5 * file are subject only to the provisions of the License. You may not use 6 * this file except in compliance with the License. You may obtain a copy 7 * of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 8 * Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: 9 * 10 * http://oss.sgi.com/projects/FreeB 11 * 12 * Note that, as provided in the License, the Software is distributed on an 13 * "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS 14 * DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND 15 * CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A 16 * PARTICULAR PURPOSE, AND NON-INFRINGEMENT. 17 * 18 * NOTE: The Original Code (as defined below) has been licensed to Sun 19 * Microsystems, Inc. ("Sun") under the SGI Free Software License B 20 * (Version 1.1), shown above ("SGI License"). Pursuant to Section 21 * 3.2(3) of the SGI License, Sun is distributing the Covered Code to 22 * you under an alternative license ("Alternative License"). This 23 * Alternative License includes all of the provisions of the SGI License 24 * except that Section 2.2 and 11 are omitted. Any differences between 25 * the Alternative License and the SGI License are offered solely by Sun 26 * and not by SGI. 27 * 28 * Original Code. The Original Code is: OpenGL Sample Implementation, 29 * Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, 30 * Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. 31 * Copyright in any portions created by third parties is as indicated 32 * elsewhere herein. All Rights Reserved. 33 * 34 * Additional Notice Provisions: The application programming interfaces 35 * established by SGI in conjunction with the Original Code are The 36 * OpenGL(R) Graphics System: A Specification (Version 1.2.1), released 37 * April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version 38 * 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X 39 * Window System(R) (Version 1.3), released October 19, 1998. This software 40 * was created using the OpenGL(R) version 1.2.1 Sample Implementation 41 * published by SGI, but has not been independently verified as being 42 * compliant with the OpenGL(R) version 1.2.1 Specification. 43 */ 44 45 package jogamp.opengl.glu.mipmap; 46 47 import com.jogamp.opengl.GL; 48 import com.jogamp.opengl.GL2; 49 import com.jogamp.opengl.GL2ES2; 50 import com.jogamp.opengl.GL2ES3; 51 import com.jogamp.opengl.GL2GL3; 52 import com.jogamp.opengl.GLContext; 53 import com.jogamp.opengl.glu.GLU; 54 import com.jogamp.opengl.GLException; 55 56 import java.nio.*; 57 58 import com.jogamp.common.nio.Buffers; 59 60 /** 61 * 62 * @author Administrator 63 */ 64 public class Mipmap { 65 66 /** Creates a new instance of Mipmap */ Mipmap()67 public Mipmap() { 68 } 69 computeLog( int value )70 public static int computeLog( int value ) { 71 int i = 0; 72 // Error 73 if( value == 0 ) { 74 return( -1 ); 75 } 76 for( ;; ) { 77 if( (value & 1) >= 1 ) { 78 if( value != 1 ) { 79 return( -1 ); 80 } 81 return( i ); 82 } 83 value = value >> 1; 84 i++; 85 } 86 } 87 88 /* Compute the nearest power of 2 number. This algorithm is a little strange 89 * but it works quite well. 90 */ nearestPower( int value )91 public static int nearestPower( int value ) { 92 int i = 1; 93 // Error! 94 if( value == 0 ) { 95 return( -1 ); 96 } 97 for( ;; ) { 98 if( value == 1 ) { 99 return( i ); 100 } else if( value == 3 ) { 101 return( i * 4 ); 102 } 103 value = value >> 1; 104 i *= 2; 105 } 106 } 107 GLU_SWAP_2_BYTES( short s )108 public static short GLU_SWAP_2_BYTES( short s ) { 109 byte b = 0; 110 b = (byte)( s >>> 8 ); 111 s = (short)( s << 8 ); 112 s = (short)( s | (0x00FF & b) ); 113 return( s ); 114 } 115 GLU_SWAP_4_BYTES( final int i )116 public static int GLU_SWAP_4_BYTES( final int i ) { 117 int t = i << 24; 118 t |= 0x00FF0000 & ( i << 8 ); 119 t |= 0x0000FF00 & ( i >>> 8 ); 120 t |= 0x000000FF & ( i >>> 24 ); 121 return( t ); 122 } 123 GLU_SWAP_4_BYTES( final float f )124 public static float GLU_SWAP_4_BYTES( final float f ) { 125 final int i = Float.floatToRawIntBits( f ); 126 final float temp = Float.intBitsToFloat( i ); 127 return( temp ); 128 } 129 checkMipmapArgs( final int internalFormat, final int format, final int type )130 public static int checkMipmapArgs( final int internalFormat, final int format, final int type ) { 131 if( !legalFormat( format ) || !legalType( type ) ) { 132 return( GLU.GLU_INVALID_ENUM ); 133 } 134 if( format == GL2ES2.GL_STENCIL_INDEX ) { 135 return( GLU.GLU_INVALID_ENUM ); 136 } 137 if( !isLegalFormatForPackedPixelType( format, type ) ) { 138 return( GLU.GLU_INVALID_OPERATION ); 139 } 140 return( 0 ); 141 } 142 legalFormat( final int format )143 public static boolean legalFormat( final int format ) { 144 switch( format ) { 145 case( GL2.GL_COLOR_INDEX ): 146 case( GL2ES2.GL_STENCIL_INDEX ): 147 case( GL2ES2.GL_DEPTH_COMPONENT ): 148 case( GL2ES2.GL_RED ): 149 case( GL2ES3.GL_GREEN ): 150 case( GL2ES3.GL_BLUE ): 151 case( GL.GL_ALPHA ): 152 case( GL.GL_RGB ): 153 case( GL.GL_RGBA ): 154 case( GL.GL_LUMINANCE ): 155 case( GL.GL_LUMINANCE_ALPHA ): 156 case( GL2GL3.GL_BGR ): 157 case( GL.GL_BGRA ): 158 return( true ); 159 default: 160 return( false ); 161 } 162 } 163 legalType( final int type )164 public static boolean legalType( final int type ) { 165 switch( type ) { 166 case( GL2.GL_BITMAP ): 167 case( GL.GL_BYTE ): 168 case( GL.GL_UNSIGNED_BYTE ): 169 case( GL.GL_SHORT ): 170 case( GL.GL_UNSIGNED_SHORT ): 171 case( GL2ES2.GL_INT ): 172 case( GL.GL_UNSIGNED_INT ): 173 case( GL.GL_FLOAT ): 174 case( GL2GL3.GL_UNSIGNED_BYTE_3_3_2 ): 175 case( GL2GL3.GL_UNSIGNED_BYTE_2_3_3_REV ): 176 case( GL.GL_UNSIGNED_SHORT_5_6_5 ): 177 case( GL2GL3.GL_UNSIGNED_SHORT_5_6_5_REV ): 178 case( GL.GL_UNSIGNED_SHORT_4_4_4_4 ): 179 case( GL2GL3.GL_UNSIGNED_SHORT_4_4_4_4_REV ): 180 case( GL.GL_UNSIGNED_SHORT_5_5_5_1 ): 181 case( GL2GL3.GL_UNSIGNED_SHORT_1_5_5_5_REV ): 182 case( GL2GL3.GL_UNSIGNED_INT_8_8_8_8 ): 183 case( GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV ): 184 case( GL2ES2.GL_UNSIGNED_INT_10_10_10_2 ): 185 case( GL2ES2.GL_UNSIGNED_INT_2_10_10_10_REV ): 186 return( true ); 187 default: 188 return( false ); 189 } 190 } 191 isTypePackedPixel( final int type )192 public static boolean isTypePackedPixel( final int type ) { 193 assert( legalType( type ) ); 194 195 if( type == GL2GL3.GL_UNSIGNED_BYTE_3_3_2 || 196 type == GL2GL3.GL_UNSIGNED_BYTE_2_3_3_REV || 197 type == GL.GL_UNSIGNED_SHORT_5_6_5 || 198 type == GL2GL3.GL_UNSIGNED_SHORT_5_6_5_REV || 199 type == GL.GL_UNSIGNED_SHORT_4_4_4_4 || 200 type == GL2GL3.GL_UNSIGNED_SHORT_4_4_4_4_REV || 201 type == GL.GL_UNSIGNED_SHORT_5_5_5_1 || 202 type == GL2GL3.GL_UNSIGNED_SHORT_1_5_5_5_REV || 203 type == GL2GL3.GL_UNSIGNED_INT_8_8_8_8 || 204 type == GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV || 205 type == GL2ES2.GL_UNSIGNED_INT_10_10_10_2 || 206 type == GL2ES2.GL_UNSIGNED_INT_2_10_10_10_REV ) { 207 return( true ); 208 } 209 return( false ); 210 } 211 isLegalFormatForPackedPixelType( final int format, final int type )212 public static boolean isLegalFormatForPackedPixelType( final int format, final int type ) { 213 // if not a packed pixel type then return true 214 if( isTypePackedPixel( type ) ) { 215 return( true ); 216 } 217 218 // 3_3_2/2_3_3_REV & 5_6_5/5_6_5_REV are only compatible with RGB 219 if( (type == GL2GL3.GL_UNSIGNED_BYTE_3_3_2 || type == GL2GL3.GL_UNSIGNED_BYTE_2_3_3_REV || 220 type == GL.GL_UNSIGNED_SHORT_5_6_5 || type == GL2GL3.GL_UNSIGNED_SHORT_5_6_5_REV ) 221 & format != GL.GL_RGB ) { 222 return( false ); 223 } 224 225 // 4_4_4_4/4_4_4_4_REV & 5_5_5_1/1_5_5_5_REV & 8_8_8_8/8_8_8_8_REV & 226 // 10_10_10_2/2_10_10_10_REV are only campatible with RGBA, BGRA & ARGB_EXT 227 if( ( type == GL.GL_UNSIGNED_SHORT_4_4_4_4 || 228 type == GL2GL3.GL_UNSIGNED_SHORT_4_4_4_4_REV || 229 type == GL.GL_UNSIGNED_SHORT_5_5_5_1 || 230 type == GL2GL3.GL_UNSIGNED_SHORT_1_5_5_5_REV || 231 type == GL2GL3.GL_UNSIGNED_INT_8_8_8_8 || 232 type == GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV || 233 type == GL2ES2.GL_UNSIGNED_INT_10_10_10_2 || 234 type == GL2ES2.GL_UNSIGNED_INT_2_10_10_10_REV ) && 235 (format != GL.GL_RGBA && format != GL.GL_BGRA) ) { 236 return( false ); 237 } 238 return( true ); 239 } 240 isLegalLevels( final int userLevel, final int baseLevel, final int maxLevel, final int totalLevels )241 public static boolean isLegalLevels( final int userLevel, final int baseLevel, final int maxLevel, 242 final int totalLevels ) { 243 if( (baseLevel < 0) || (baseLevel < userLevel) || (maxLevel < baseLevel) || 244 (totalLevels < maxLevel) ) { 245 return( false ); 246 } 247 return( true ); 248 } 249 250 /* Given user requested textures size, determine if it fits. If it doesn't then 251 * halve both sides and make the determination again until it does fit ( for 252 * IR only ). 253 * Note that proxy textures are not implemented in RE* even though they 254 * advertise the texture extension. 255 * Note that proxy textures are implemented but not according to spec in IMPACT* 256 */ closestFit( final GL gl, final int target, final int width, final int height, final int internalFormat, final int format, final int type, final int[] newWidth, final int[] newHeight )257 public static void closestFit( final GL gl, final int target, final int width, final int height, final int internalFormat, 258 final int format, final int type, final int[] newWidth, final int[] newHeight ) { 259 // Use proxy textures if OpenGL GL2/GL3 version >= 1.1 260 if( gl.isGL2GL3() && gl.getContext().getGLVersionNumber().compareTo(GLContext.Version1_1) >= 0 ) { 261 int widthPowerOf2 = nearestPower( width ); 262 int heightPowerOf2 = nearestPower( height ); 263 final int[] proxyWidth = new int[1]; 264 boolean noProxyTextures = false; 265 266 // Some drivers (in particular, ATI's) seem to set a GL error 267 // when proxy textures are used even though this is in violation 268 // of the spec. Guard against this and interactions with the 269 // DebugGL by watching for GLException. 270 try { 271 do { 272 // compute level 1 width & height, clamping each at 1 273 final int widthAtLevelOne = ( ( width > 1 ) ? (widthPowerOf2 >> 1) : widthPowerOf2 ); 274 final int heightAtLevelOne = ( ( height > 1 ) ? (heightPowerOf2 >> 1) : heightPowerOf2 ); 275 int proxyTarget; 276 277 assert( widthAtLevelOne > 0 ); 278 assert( heightAtLevelOne > 0 ); 279 280 // does width x height at level 1 & all their mipmaps fit? 281 if( target == GL.GL_TEXTURE_2D || target == GL2GL3.GL_PROXY_TEXTURE_2D ) { 282 proxyTarget = GL2GL3.GL_PROXY_TEXTURE_2D; 283 gl.glTexImage2D( proxyTarget, 1, internalFormat, widthAtLevelOne, 284 heightAtLevelOne, 0, format, type, null ); 285 } else if( (target == GL.GL_TEXTURE_CUBE_MAP_POSITIVE_X) || 286 (target == GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_X) || 287 (target == GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Y) || 288 (target == GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y) || 289 (target == GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Z) || 290 (target == GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) ) { 291 proxyTarget = GL2GL3.GL_PROXY_TEXTURE_CUBE_MAP; 292 gl.glTexImage2D( proxyTarget, 1, internalFormat, widthAtLevelOne, 293 heightAtLevelOne, 0, format, type, null ); 294 } else { 295 assert( target == GL2GL3.GL_TEXTURE_1D || target == GL2GL3.GL_PROXY_TEXTURE_1D ); 296 proxyTarget = GL2GL3.GL_PROXY_TEXTURE_1D; 297 gl.getGL2GL3().glTexImage1D( proxyTarget, 1, internalFormat, widthAtLevelOne, 298 0, format, type, null ); 299 } 300 if(gl.isGL2GL3()) { 301 gl.getGL2GL3().glGetTexLevelParameteriv( proxyTarget, 1, GL2GL3.GL_TEXTURE_WIDTH, proxyWidth, 0 ); 302 } else { 303 proxyWidth[0] = 0; 304 } 305 // does it fit? 306 if( proxyWidth[0] == 0 ) { // nope, so try again with theses sizes 307 if( widthPowerOf2 == 1 && heightPowerOf2 == 1 ) { 308 /* A 1x1 texture couldn't fit for some reason so break out. This 309 * should never happen. But things happen. The disadvantage with 310 * this if-statement is that we will never be aware of when this 311 * happens since it will silently branch out. 312 */ 313 noProxyTextures = true; 314 break; 315 } 316 widthPowerOf2 = widthAtLevelOne; 317 heightPowerOf2 = heightAtLevelOne; 318 } 319 // else it does fit 320 } while( proxyWidth[0] == 0 ); 321 } catch (final GLException e) { 322 noProxyTextures = true; 323 } 324 // loop must terminate 325 // return the width & height at level 0 that fits 326 if( !noProxyTextures ) { 327 newWidth[0] = widthPowerOf2; 328 newHeight[0] = heightPowerOf2; 329 return; 330 } 331 } 332 final int[] maxsize = new int[1]; 333 gl.glGetIntegerv( GL.GL_MAX_TEXTURE_SIZE, maxsize , 0); 334 // clamp user's texture sizes to maximum sizes, if necessary 335 newWidth[0] = nearestPower( width ); 336 if( newWidth[0] > maxsize[0] ) { 337 newWidth[0] = maxsize[0]; 338 } 339 newHeight[0] = nearestPower( height ); 340 if( newHeight[0] > maxsize[0] ) { 341 newHeight[0] = maxsize[0]; 342 } 343 } 344 closestFit3D( final GL gl, final int target, final int width, final int height, final int depth, final int internalFormat, final int format, final int type, final int[] newWidth, final int[] newHeight, final int[] newDepth )345 public static void closestFit3D( final GL gl, final int target, final int width, final int height, final int depth, 346 final int internalFormat, final int format, final int type, final int[] newWidth, final int[] newHeight, 347 final int[] newDepth ) { 348 int widthPowerOf2 = nearestPower( width ); 349 int heightPowerOf2 = nearestPower( height ); 350 int depthPowerOf2 = nearestPower( depth ); 351 final int[] proxyWidth = new int[1]; 352 353 do { 354 // compute level 1 width & height & depth, clamping each at 1 355 final int widthAtLevelOne = (widthPowerOf2 > 1) ? widthPowerOf2 >> 1 : widthPowerOf2; 356 final int heightAtLevelOne = (heightPowerOf2 > 1) ? heightPowerOf2 >> 1 : heightPowerOf2; 357 final int depthAtLevelOne = (depthPowerOf2 > 1) ? depthPowerOf2 >> 1 : depthPowerOf2; 358 int proxyTarget = 0; 359 assert( widthAtLevelOne > 0 ); 360 assert( heightAtLevelOne > 0 ); 361 assert( depthAtLevelOne > 0 ); 362 363 // does width x height x depth at level 1 & all their mipmaps fit? 364 if( target == GL2ES2.GL_TEXTURE_3D || target == GL2GL3.GL_PROXY_TEXTURE_3D ) { 365 proxyTarget = GL2GL3.GL_PROXY_TEXTURE_3D; 366 gl.getGL2GL3().glTexImage3D( proxyTarget, 1, internalFormat, widthAtLevelOne, 367 heightAtLevelOne, depthAtLevelOne, 0, format, type, null ); 368 } 369 if(gl.isGL2GL3()) { 370 gl.getGL2GL3().glGetTexLevelParameteriv( proxyTarget, 1, GL2GL3.GL_TEXTURE_WIDTH, proxyWidth, 0 ); 371 } else { 372 proxyWidth[0] = 0; 373 } 374 // does it fit 375 if( proxyWidth[0] == 0 ) { 376 if( widthPowerOf2 == 1 && heightPowerOf2 == 1 && depthPowerOf2 == 1 ) { 377 newWidth[0] = newHeight[0] = newDepth[0] = 1; 378 return; 379 } 380 widthPowerOf2 = widthAtLevelOne; 381 heightPowerOf2 = heightAtLevelOne; 382 depthPowerOf2 = depthAtLevelOne; 383 } 384 } while( proxyWidth[0] == 0 ); 385 // loop must terminate 386 387 // return the width & height at level 0 that fits 388 newWidth[0] = widthPowerOf2; 389 newHeight[0] = heightPowerOf2; 390 newDepth[0] = depthPowerOf2; 391 } 392 elements_per_group( final int format, final int type )393 public static int elements_per_group( final int format, final int type ) { 394 // Return the number of elements per grtoup of a specified gromat 395 396 // If the type is packedpixels then answer is 1 397 if( type == GL2GL3.GL_UNSIGNED_BYTE_3_3_2 || 398 type == GL2GL3.GL_UNSIGNED_BYTE_2_3_3_REV || 399 type == GL.GL_UNSIGNED_SHORT_5_6_5 || 400 type == GL2GL3.GL_UNSIGNED_SHORT_5_6_5_REV || 401 type == GL.GL_UNSIGNED_SHORT_4_4_4_4 || 402 type == GL2GL3.GL_UNSIGNED_SHORT_4_4_4_4_REV || 403 type == GL.GL_UNSIGNED_SHORT_5_5_5_1 || 404 type == GL2GL3.GL_UNSIGNED_SHORT_1_5_5_5_REV || 405 type == GL2GL3.GL_UNSIGNED_INT_8_8_8_8 || 406 type == GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV || 407 type == GL2ES2.GL_UNSIGNED_INT_10_10_10_2 || 408 type == GL2ES2.GL_UNSIGNED_INT_2_10_10_10_REV ) { 409 return( 1 ); 410 } 411 412 // Types are not packed pixels so get elements per group 413 switch( format ) { 414 case( GL.GL_RGB ): 415 case( GL2GL3.GL_BGR ): 416 return( 3 ); 417 case( GL.GL_LUMINANCE_ALPHA ): 418 return( 2 ); 419 case( GL.GL_RGBA ): 420 case( GL.GL_BGRA ): 421 return( 4 ); 422 default: 423 return( 1 ); 424 } 425 } 426 bytes_per_element( final int type )427 public static int bytes_per_element( final int type ) { 428 // return the number of bytes per element, based on the element type 429 430 switch( type ) { 431 case( GL2.GL_BITMAP ): 432 case( GL.GL_BYTE ): 433 case( GL.GL_UNSIGNED_BYTE ): 434 case( GL2GL3.GL_UNSIGNED_BYTE_3_3_2 ): 435 case( GL2GL3.GL_UNSIGNED_BYTE_2_3_3_REV ): 436 return( 1 ); 437 case( GL.GL_SHORT ): 438 case( GL.GL_UNSIGNED_SHORT ): 439 case( GL.GL_UNSIGNED_SHORT_5_6_5 ): 440 case( GL2GL3.GL_UNSIGNED_SHORT_5_6_5_REV ): 441 case( GL.GL_UNSIGNED_SHORT_4_4_4_4 ): 442 case( GL2GL3.GL_UNSIGNED_SHORT_4_4_4_4_REV ): 443 case( GL.GL_UNSIGNED_SHORT_5_5_5_1 ): 444 case( GL2GL3.GL_UNSIGNED_SHORT_1_5_5_5_REV ): 445 return( 2 ); 446 case( GL2ES2.GL_INT ): 447 case( GL.GL_UNSIGNED_INT ): 448 case( GL2GL3.GL_UNSIGNED_INT_8_8_8_8 ): 449 case( GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV ): 450 case( GL2ES2.GL_UNSIGNED_INT_10_10_10_2 ): 451 case( GL2ES2.GL_UNSIGNED_INT_2_10_10_10_REV ): 452 case( GL.GL_FLOAT ): 453 return( 4 ); 454 default: 455 return( 4 ); 456 } 457 } 458 is_index( final int format )459 public static boolean is_index( final int format ) { 460 return( format == GL2.GL_COLOR_INDEX || format == GL2ES2.GL_STENCIL_INDEX ); 461 } 462 463 /* Compute memory required for internal packed array of data of given type and format. */ 464 image_size( final int width, final int height, final int format, final int type )465 public static int image_size( final int width, final int height, final int format, final int type ) { 466 int bytes_per_row; 467 int components; 468 469 assert( width > 0 ); 470 assert( height > 0 ); 471 components = elements_per_group( format, type ); 472 if( type == GL2.GL_BITMAP ) { 473 bytes_per_row = (width + 7) / 8; 474 } else { 475 bytes_per_row = bytes_per_element( type ) * width; 476 } 477 return( bytes_per_row * height * components ); 478 } 479 imageSize3D( final int width, final int height, final int depth, final int format, final int type )480 public static int imageSize3D( final int width, final int height, final int depth, final int format, final int type ) { 481 final int components = elements_per_group( format, type ); 482 final int bytes_per_row = bytes_per_element( type ) * width; 483 484 assert( width > 0 && height > 0 && depth > 0 ); 485 assert( type != GL2.GL_BITMAP ); 486 487 return( bytes_per_row * height * depth * components ); 488 } 489 retrieveStoreModes( final GL gl, final PixelStorageModes psm )490 public static void retrieveStoreModes( final GL gl, final PixelStorageModes psm ) { 491 final int[] a = new int[1]; 492 gl.glGetIntegerv( GL.GL_UNPACK_ALIGNMENT, a, 0); 493 psm.setUnpackAlignment( a[0] ); 494 gl.glGetIntegerv( GL2ES2.GL_UNPACK_ROW_LENGTH, a, 0); 495 psm.setUnpackRowLength( a[0] ); 496 gl.glGetIntegerv( GL2ES2.GL_UNPACK_SKIP_ROWS, a, 0); 497 psm.setUnpackSkipRows( a[0] ); 498 gl.glGetIntegerv( GL2ES2.GL_UNPACK_SKIP_PIXELS, a, 0); 499 psm.setUnpackSkipPixels( a[0] ); 500 gl.glGetIntegerv( GL2GL3.GL_UNPACK_LSB_FIRST, a, 0); 501 psm.setUnpackLsbFirst( ( a[0] == 1 ) ); 502 gl.glGetIntegerv( GL2GL3.GL_UNPACK_SWAP_BYTES, a, 0); 503 psm.setUnpackSwapBytes( ( a[0] == 1 ) ); 504 505 gl.glGetIntegerv( GL.GL_PACK_ALIGNMENT, a, 0); 506 psm.setPackAlignment( a[0] ); 507 gl.glGetIntegerv( GL2ES3.GL_PACK_ROW_LENGTH, a, 0); 508 psm.setPackRowLength( a[0] ); 509 gl.glGetIntegerv( GL2ES3.GL_PACK_SKIP_ROWS, a, 0); 510 psm.setPackSkipRows( a[0] ); 511 gl.glGetIntegerv( GL2ES3.GL_PACK_SKIP_PIXELS, a, 0); 512 psm.setPackSkipPixels( a[0] ); 513 gl.glGetIntegerv( GL2GL3.GL_PACK_LSB_FIRST, a, 0); 514 psm.setPackLsbFirst( ( a[0] == 1 ) ); 515 gl.glGetIntegerv( GL2GL3.GL_PACK_SWAP_BYTES, a, 0); 516 psm.setPackSwapBytes( ( a[0] == 1 ) ); 517 } 518 retrieveStoreModes3D( final GL gl, final PixelStorageModes psm )519 public static void retrieveStoreModes3D( final GL gl, final PixelStorageModes psm ) { 520 final int[] a = new int[1]; 521 gl.glGetIntegerv( GL.GL_UNPACK_ALIGNMENT, a, 0); 522 psm.setUnpackAlignment( a[0] ); 523 gl.glGetIntegerv( GL2ES2.GL_UNPACK_ROW_LENGTH, a, 0); 524 psm.setUnpackRowLength( a[0] ); 525 gl.glGetIntegerv( GL2ES2.GL_UNPACK_SKIP_ROWS, a, 0); 526 psm.setUnpackSkipRows( a[0] ); 527 gl.glGetIntegerv( GL2ES2.GL_UNPACK_SKIP_PIXELS, a, 0); 528 psm.setUnpackSkipPixels( a[0] ); 529 gl.glGetIntegerv( GL2GL3.GL_UNPACK_LSB_FIRST, a, 0); 530 psm.setUnpackLsbFirst( ( a[0] == 1 ) ); 531 gl.glGetIntegerv( GL2GL3.GL_UNPACK_SWAP_BYTES, a, 0); 532 psm.setUnpackSwapBytes( ( a[0] == 1 ) ); 533 gl.glGetIntegerv( GL2ES3.GL_UNPACK_SKIP_IMAGES, a, 0); 534 psm.setUnpackSkipImages( a[0] ); 535 gl.glGetIntegerv( GL2ES3.GL_UNPACK_IMAGE_HEIGHT, a, 0); 536 psm.setUnpackImageHeight( a[0] ); 537 538 gl.glGetIntegerv( GL.GL_PACK_ALIGNMENT, a, 0); 539 psm.setPackAlignment( a[0] ); 540 gl.glGetIntegerv( GL2ES3.GL_PACK_ROW_LENGTH, a, 0); 541 psm.setPackRowLength( a[0] ); 542 gl.glGetIntegerv( GL2ES3.GL_PACK_SKIP_ROWS, a, 0); 543 psm.setPackSkipRows( a[0] ); 544 gl.glGetIntegerv( GL2ES3.GL_PACK_SKIP_PIXELS, a, 0 ); 545 psm.setPackSkipPixels( a[0] ); 546 gl.glGetIntegerv( GL2GL3.GL_PACK_LSB_FIRST, a, 0 ); 547 psm.setPackLsbFirst( ( a[0] == 1 ) ); 548 gl.glGetIntegerv( GL2GL3.GL_PACK_SWAP_BYTES, a, 0 ); 549 psm.setPackSwapBytes( ( a[0] == 1 ) ); 550 gl.glGetIntegerv( GL2GL3.GL_PACK_SKIP_IMAGES, a, 0 ); 551 psm.setPackSkipImages( a[0] ); 552 gl.glGetIntegerv( GL2GL3.GL_PACK_IMAGE_HEIGHT, a, 0 ); 553 psm.setPackImageHeight( a[0] ); 554 } 555 gluScaleImage( final GL gl, final int format, final int widthin, final int heightin, final int typein, final ByteBuffer datain, final int widthout, final int heightout, final int typeout, final ByteBuffer dataout )556 public static int gluScaleImage( final GL gl, final int format, final int widthin, final int heightin, 557 final int typein, final ByteBuffer datain, final int widthout, final int heightout, 558 final int typeout, final ByteBuffer dataout ) { 559 final int datainPos = datain.position(); 560 final int dataoutPos = dataout.position(); 561 try { 562 563 int components; 564 ByteBuffer beforeimage; 565 ByteBuffer afterimage; 566 final PixelStorageModes psm = new PixelStorageModes(); 567 568 if( (widthin == 0) || (heightin == 0) || (widthout == 0) || (heightout == 0) ) { 569 return( 0 ); 570 } 571 if( (widthin < 0) || (heightin < 0) || (widthout < 0) || (heightout < 0) ) { 572 return( GLU.GLU_INVALID_VALUE ); 573 } 574 if( !legalFormat( format ) || !legalType( typein ) || !legalType( typeout ) ) { 575 return( GLU.GLU_INVALID_ENUM ); 576 } 577 if( !isLegalFormatForPackedPixelType( format, typein ) ) { 578 return( GLU.GLU_INVALID_OPERATION ); 579 } 580 if( !isLegalFormatForPackedPixelType( format, typeout ) ) { 581 return( GLU.GLU_INVALID_OPERATION ); 582 } 583 beforeimage = Buffers.newDirectByteBuffer( image_size( widthin, heightin, format, GL.GL_UNSIGNED_SHORT ) ); 584 afterimage = Buffers.newDirectByteBuffer( image_size( widthout, heightout, format, GL.GL_UNSIGNED_SHORT ) ); 585 if( beforeimage == null || afterimage == null ) { 586 return( GLU.GLU_OUT_OF_MEMORY ); 587 } 588 589 retrieveStoreModes( gl, psm ); 590 Image.fill_image( psm, widthin, heightin, format, typein, is_index( format ), datain, beforeimage.asShortBuffer() ); 591 components = elements_per_group( format, 0 ); 592 ScaleInternal.scale_internal( components, widthin, heightin, beforeimage.asShortBuffer(), widthout, heightout, afterimage.asShortBuffer() ); 593 Image.empty_image( psm, widthout, heightout, format, typeout, is_index( format ), afterimage.asShortBuffer(), dataout ); 594 595 return( 0 ); 596 } finally { 597 datain.position(datainPos); 598 dataout.position(dataoutPos); 599 } 600 } 601 gluBuild1DMipmapLevels( final GL gl, final int target, final int internalFormat, final int width, final int format, final int type, final int userLevel, final int baseLevel, final int maxLevel, final ByteBuffer data )602 public static int gluBuild1DMipmapLevels( final GL gl, final int target, final int internalFormat, 603 final int width, final int format, final int type, final int userLevel, final int baseLevel, 604 final int maxLevel, final ByteBuffer data ) { 605 final int dataPos = data.position(); 606 try { 607 608 int levels; 609 610 final int rc = checkMipmapArgs( internalFormat, format, type ); 611 if( rc != 0 ) { 612 return( rc ); 613 } 614 615 if( width < 1 ) { 616 return( GLU.GLU_INVALID_VALUE ); 617 } 618 619 levels = computeLog( width ); 620 621 levels += userLevel; 622 if( !isLegalLevels( userLevel, baseLevel, maxLevel, levels ) ) { 623 return( GLU.GLU_INVALID_VALUE ); 624 } 625 626 return( BuildMipmap.gluBuild1DMipmapLevelsCore( gl, target, internalFormat, width, 627 width, format, type, userLevel, baseLevel, maxLevel, data ) ); 628 } finally { 629 data.position(dataPos); 630 } 631 } 632 gluBuild1DMipmaps( final GL gl, final int target, final int internalFormat, final int width, final int format, final int type, final ByteBuffer data )633 public static int gluBuild1DMipmaps( final GL gl, final int target, final int internalFormat, final int width, 634 final int format, final int type, final ByteBuffer data ) { 635 final int dataPos = data.position(); 636 637 try { 638 final int[] widthPowerOf2 = new int[1]; 639 int levels; 640 final int[] dummy = new int[1]; 641 642 final int rc = checkMipmapArgs( internalFormat, format, type ); 643 if( rc != 0 ) { 644 return( rc ); 645 } 646 647 if( width < 1 ) { 648 return( GLU.GLU_INVALID_VALUE ); 649 } 650 651 closestFit( gl, target, width, 1, internalFormat, format, type, widthPowerOf2, dummy ); 652 levels = computeLog( widthPowerOf2[0] ); 653 654 return( BuildMipmap.gluBuild1DMipmapLevelsCore( gl, target, internalFormat, 655 width, widthPowerOf2[0], format, type, 0, 0, levels, data ) ); 656 } finally { 657 data.position(dataPos); 658 } 659 } 660 661 gluBuild2DMipmapLevels( final GL gl, final int target, final int internalFormat, final int width, final int height, final int format, final int type, final int userLevel, final int baseLevel, final int maxLevel, final Object data )662 public static int gluBuild2DMipmapLevels( final GL gl, final int target, final int internalFormat, 663 final int width, final int height, final int format, final int type, final int userLevel, 664 final int baseLevel, final int maxLevel, final Object data ) { 665 int level, levels; 666 667 final int rc = checkMipmapArgs( internalFormat, format, type ); 668 if( rc != 0 ) { 669 return( rc ); 670 } 671 672 if( width < 1 || height < 1 ) { 673 return( GLU.GLU_INVALID_VALUE ); 674 } 675 676 levels = computeLog( width ); 677 level = computeLog( height ); 678 if( level > levels ) { 679 levels = level; 680 } 681 682 levels += userLevel; 683 if( !isLegalLevels( userLevel, baseLevel, maxLevel, levels ) ) { 684 return( GLU.GLU_INVALID_VALUE ); 685 } 686 687 //PointerWrapper pointer = PointerWrapperFactory.getPointerWrapper( data ); 688 final ByteBuffer buffer; 689 if( data instanceof ByteBuffer ) { 690 buffer = (ByteBuffer)data; 691 } else if( data instanceof byte[] ) { 692 final byte[] array = (byte[])data; 693 buffer = ByteBuffer.allocateDirect(array.length); 694 buffer.put(array); 695 buffer.flip(); 696 } else if( data instanceof short[] ) { 697 final short[] array = (short[])data; 698 buffer = ByteBuffer.allocateDirect( array.length * 2 ); 699 final ShortBuffer sb = buffer.asShortBuffer(); 700 sb.put( array ); 701 } else if( data instanceof int[] ) { 702 final int[] array = (int[])data; 703 buffer = ByteBuffer.allocateDirect( array.length * 4 ); 704 final IntBuffer ib = buffer.asIntBuffer(); 705 ib.put( array ); 706 } else if( data instanceof float[] ) { 707 final float[] array = (float[])data; 708 buffer = ByteBuffer.allocateDirect( array.length * 4 ); 709 final FloatBuffer fb = buffer.asFloatBuffer(); 710 fb.put( array ); 711 } else { 712 throw new IllegalArgumentException("Unhandled data type: "+data.getClass().getName()); 713 } 714 715 final int dataPos = buffer.position(); 716 try { 717 return( BuildMipmap.gluBuild2DMipmapLevelsCore( gl, target, internalFormat, 718 width, height, width, height, format, type, userLevel, baseLevel, 719 maxLevel, buffer ) ); 720 } finally { 721 buffer.position(dataPos); 722 } 723 } 724 725 gluBuild2DMipmaps( final GL gl, final int target, final int internalFormat, final int width, final int height, final int format, final int type, final Object data )726 public static int gluBuild2DMipmaps( final GL gl, final int target, final int internalFormat, 727 final int width, final int height, final int format, final int type, final Object data ) { 728 final int[] widthPowerOf2 = new int[1]; 729 final int[] heightPowerOf2 = new int[1]; 730 int level, levels; 731 732 final int rc = checkMipmapArgs( internalFormat, format, type ); 733 if( rc != 0 ) { 734 return( rc ); 735 } 736 737 if( width < 1 || height < 1 ) { 738 return( GLU.GLU_INVALID_VALUE ); 739 } 740 741 closestFit( gl, target, width, height, internalFormat, format, type, 742 widthPowerOf2, heightPowerOf2 ); 743 744 levels = computeLog( widthPowerOf2[0] ); 745 level = computeLog( heightPowerOf2[0] ); 746 if( level > levels ) { 747 levels = level; 748 } 749 750 //PointerWrapper pointer = PointerWrapperFactory.getPointerWrapper( data ); 751 final ByteBuffer buffer; 752 if( data instanceof ByteBuffer ) { 753 buffer = (ByteBuffer)data; 754 } else if( data instanceof byte[] ) { 755 final byte[] array = (byte[])data; 756 buffer = ByteBuffer.allocateDirect(array.length); 757 buffer.put(array); 758 buffer.flip(); 759 } else if( data instanceof short[] ) { 760 final short[] array = (short[])data; 761 buffer = ByteBuffer.allocateDirect( array.length * 2 ); 762 final ShortBuffer sb = buffer.asShortBuffer(); 763 sb.put( array ); 764 } else if( data instanceof int[] ) { 765 final int[] array = (int[])data; 766 buffer = ByteBuffer.allocateDirect( array.length * 4 ); 767 final IntBuffer ib = buffer.asIntBuffer(); 768 ib.put( array ); 769 } else if( data instanceof float[] ) { 770 final float[] array = (float[])data; 771 buffer = ByteBuffer.allocateDirect( array.length * 4 ); 772 final FloatBuffer fb = buffer.asFloatBuffer(); 773 fb.put( array ); 774 } else { 775 throw new IllegalArgumentException("Unhandled data type: "+data.getClass().getName()); 776 } 777 778 final int dataPos = buffer.position(); 779 try { 780 return( BuildMipmap.gluBuild2DMipmapLevelsCore( gl, target, internalFormat, 781 width, height, widthPowerOf2[0], heightPowerOf2[0], format, type, 0, 782 0, levels, buffer ) ); 783 } finally { 784 buffer.position(dataPos); 785 } 786 } 787 788 gluBuild3DMipmaps( final GL gl, final int target, final int internalFormat, final int width, final int height, final int depth, final int format, final int type, final ByteBuffer data )789 public static int gluBuild3DMipmaps( final GL gl, final int target, final int internalFormat, 790 final int width, final int height, final int depth, final int format, final int type, final ByteBuffer data ) { 791 final int dataPos = data.position(); 792 try { 793 794 final int[] widthPowerOf2 = new int[1]; 795 final int[] heightPowerOf2 = new int[1]; 796 final int[] depthPowerOf2 = new int[1]; 797 int level, levels; 798 799 final int rc = checkMipmapArgs( internalFormat, format, type ); 800 if( rc != 0 ) { 801 return( rc ); 802 } 803 804 if( width < 1 || height < 1 || depth < 1 ) { 805 return( GLU.GLU_INVALID_VALUE ); 806 } 807 808 if( type == GL2.GL_BITMAP ) { 809 return( GLU.GLU_INVALID_ENUM ); 810 } 811 812 closestFit3D( gl, target, width, height, depth, internalFormat, format, 813 type, widthPowerOf2, heightPowerOf2, depthPowerOf2 ); 814 815 levels = computeLog( widthPowerOf2[0] ); 816 level = computeLog( heightPowerOf2[0] ); 817 if( level > levels ) { 818 levels = level; 819 } 820 level = computeLog( depthPowerOf2[0] ); 821 if( level > levels ) { 822 levels = level; 823 } 824 825 return( BuildMipmap.gluBuild3DMipmapLevelsCore( gl, target, internalFormat, width, 826 height, depth, widthPowerOf2[0], heightPowerOf2[0], depthPowerOf2[0], 827 format, type, 0, 0, levels, data ) ); 828 } finally { 829 data.position(dataPos); 830 } 831 } 832 gluBuild3DMipmapLevels( final GL gl, final int target, final int internalFormat, final int width, final int height, final int depth, final int format, final int type, final int userLevel, final int baseLevel, final int maxLevel, final ByteBuffer data )833 public static int gluBuild3DMipmapLevels( final GL gl, final int target, final int internalFormat, 834 final int width, final int height, final int depth, final int format, final int type, final int userLevel, 835 final int baseLevel, final int maxLevel, final ByteBuffer data ) { 836 final int dataPos = data.position(); 837 try { 838 int level, levels; 839 840 final int rc = checkMipmapArgs( internalFormat, format, type ); 841 if( rc != 0 ) { 842 return( rc ); 843 } 844 845 if( width < 1 || height < 1 || depth < 1 ) { 846 return( GLU.GLU_INVALID_VALUE ); 847 } 848 849 if( type == GL2.GL_BITMAP ) { 850 return( GLU.GLU_INVALID_ENUM ); 851 } 852 853 levels = computeLog( width ); 854 level = computeLog( height ); 855 if( level > levels ) { 856 levels = level; 857 } 858 level = computeLog( depth ); 859 if( level > levels ) { 860 levels = level; 861 } 862 863 levels += userLevel; 864 if( !isLegalLevels( userLevel, baseLevel, maxLevel, levels ) ) { 865 return( GLU.GLU_INVALID_VALUE ); 866 } 867 868 return( BuildMipmap.gluBuild3DMipmapLevelsCore( gl, target, internalFormat, width, 869 height, depth, width, height, depth, format, type, userLevel, 870 baseLevel, maxLevel, data ) ); 871 } finally { 872 data.position(dataPos); 873 } 874 } 875 } 876