/**
* Copyright (c) 2003-2009, Xith3D Project Group all rights reserved.
*
* Portions based on the Java3D interface, Copyright by Sun Microsystems.
* Many thanks to the developers of Java3D and Sun Microsystems for their
* innovation and design.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the 'Xith3D Project Group' nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) A
* RISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE
*/
package org.xith3d.scenegraph;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import org.jagatoo.image.BufferedImageFactory;
import org.jagatoo.opengl.enums.TextureImageFormat;
import org.jagatoo.opengl.enums.TextureImageInternalFormat;
import org.jagatoo.util.image.ImageUtility;
import org.jagatoo.util.nio.BufferUtils;
import org.openmali.types.twodee.Rect2i;
import org.openmali.vecmath2.Colorf;
import org.openmali.vecmath2.TexCoord2f;
import org.openmali.vecmath2.Tuple2f;
/**
* {@link TextureImage2D} defines 2D {@link TextureImage}
* as part of a {@link Texture2D}.
*
* Application may define internal format hint for OpenGL that determines how image data should be stored in texture memory.
* If both format and hint designate uncompressed formats, image will be transferred and stored in uncompressed form.
* If both format and hint designate compressed formats, image will be transferred and stored compressed form.
* If format designates uncompressed format and hint designates compressed format, image will be transferred in uncompressed form,
* compressed by OpenGL driver and stored in texture memory in compressed form.
*
* @author David Yazel
* @author Marvin Froehlich (aka Qudus)
*/
public class TextureImage2D extends TextureImage
{
private ByteBuffer dataBuffer = null;
private byte[] data = null;
private byte[] pixelRow1 = null;
private byte[] pixelRow2 = null;
private int pixelSize = 0;
private final ArrayList< Rect2i > updateList = new ArrayList< Rect2i >();
private final TexCoord2f texCoordUR = new TexCoord2f();
private final Rect2i userClipRect = new Rect2i( 0, 0, 128, 128 );
private final Rect2i clipRect = new Rect2i( 0, 0, 128, 128 );
private boolean readOnly = true;
private BufferedImage bufferedImage = null;
private final boolean yUp;
protected final boolean getYUp()
{
return ( yUp );
}
/**
* @return the texture-coordinate for the upper-right corner
* according to the size and original-size.
*/
public final TexCoord2f getTextureCoordinateUR( TexCoord2f tcUR )
{
tcUR.set( texCoordUR );
return ( tcUR );
}
/**
* @return the texture-coordinate for the upper-right corner
* according to the size and original-size.
*/
public final < T extends Tuple2f > T getTextureCoordinateUR( T tcUR )
{
tcUR.set( texCoordUR.getS(), texCoordUR.getT() );
return ( tcUR );
}
public final int getPixelSize()
{
return ( pixelSize );
}
public final int getDataSize()
{
if ( ( data == null ) && ( dataBuffer == null ) )
return ( getWidth() * getHeight() * pixelSize );
if ( data == null )
return ( dataBuffer.capacity() );
return ( data.length );
}
public final ByteBuffer getDataBuffer()
{
return ( dataBuffer );
}
public final void getData( ByteBuffer bb )
{
bb.position( 0 );
bb.limit( bb.capacity() );
if ( !hasData() )
{
bb.flip();
return;
}
if ( getFormat().isCompressed() )
{
bb.put( data, 0, data.length );
}
else
{
switch ( this.pixelSize )
{
case 4:
for ( int i = 0; i < data.length; i += 4 )
{
bb.put( data[ i + 3 ] );
bb.put( data[ i + 2 ] );
bb.put( data[ i + 1 ] );
bb.put( data[ i + 0 ] );
}
break;
case 3:
for ( int i = 0; i < data.length; i += 3 )
{
bb.put( data[ i + 2 ] );
bb.put( data[ i + 1 ] );
bb.put( data[ i + 0 ] );
}
break;
case 2:
for ( int i = 0; i < data.length; i += 2 )
{
bb.put( data[ i + 1 ] );
bb.put( data[ i + 0 ] );
}
break;
case 1:
for ( int i = 0; i < data.length; i += 1 )
{
bb.put( data[ i + 0 ] );
}
break;
}
}
bb.flip();
}
public final int getData( byte[] data )
{
final byte[] trg = data;
if ( !hasData() )
{
return ( 0 );
}
if ( getFormat().isCompressed() )
{
if ( this.dataBuffer == null )
{
System.arraycopy( this.data, 0, trg, 0, this.data.length );
return ( this.data.length );
}
this.dataBuffer.position( 0 );
this.dataBuffer.get( trg, 0, this.dataBuffer.limit() );
this.dataBuffer.position( 0 );
return ( this.dataBuffer.limit() );
}
int b = 0;
if ( dataBuffer == null )
{
final byte[] src = this.data;
final int n = src.length;
switch ( this.pixelSize )
{
case 4:
for ( int i = 0; i < n; i += 4 )
{
trg[ b++ ] = src[ i + 3 ];
trg[ b++ ] = src[ i + 2 ];
trg[ b++ ] = src[ i + 1 ];
trg[ b++ ] = src[ i + 0 ];
}
break;
case 3:
for ( int i = 0; i < n; i += 3 )
{
trg[ b++ ] = src[ i + 2 ];
trg[ b++ ] = src[ i + 1 ];
trg[ b++ ] = src[ i + 0 ];
}
break;
case 2:
for ( int i = 0; i < n; i += 2 )
{
trg[ b++ ] = src[ i + 1 ];
trg[ b++ ] = src[ i + 0 ];
}
break;
case 1:
for ( int i = 0; i < n; i += 1 )
{
trg[ b++ ] = src[ i + 0 ];
}
break;
}
return ( n );
}
final int n = dataBuffer.limit();
switch ( this.pixelSize )
{
case 4:
for ( int i = 0; i < n; i += 4 )
{
trg[ b++ ] = dataBuffer.get( i + 3 );
trg[ b++ ] = dataBuffer.get( i + 2 );
trg[ b++ ] = dataBuffer.get( i + 1 );
trg[ b++ ] = dataBuffer.get( i + 0 );
}
break;
case 3:
for ( int i = 0; i < n; i += 3 )
{
trg[ b++ ] = dataBuffer.get( i + 2 );
trg[ b++ ] = dataBuffer.get( i + 1 );
trg[ b++ ] = dataBuffer.get( i + 0 );
}
break;
case 2:
for ( int i = 0; i < n; i += 2 )
{
trg[ b++ ] = dataBuffer.get( i + 1 );
trg[ b++ ] = dataBuffer.get( i + 0 );
}
break;
case 1:
for ( int i = 0; i < n; i += 1 )
{
trg[ b++ ] = dataBuffer.get( i + 0 );
}
break;
}
dataBuffer.position( 0 );
return ( n );
}
public void freeLocalData()
{
this.dataBuffer = null;
this.data = null;
this.bufferedImage = null;
}
/**
* Marks a portion of the image component as dirty.
* The region will be pushed to the graphics card on the next frame.
*
* {@link Texture2D#setHasUpdateList(boolean)} must be called afterwards.
*
* @param x
* @param y
* @param width
* @param height
*/
public void update( int x, int y, int width, int height )
{
if ( ( x < 0 ) || ( y < 0 ) || ( x >= this.getWidth() ) || ( y >= this.getHeight() ) || ( width > this.getWidth() ) || ( height > this.getHeight() ) || ( ( x + width ) > this.getWidth() ) || ( ( y + height ) > this.getHeight() ) )
{
throw new IllegalArgumentException( "Rectangle outside of image" );
}
Rect2i rect = Rect2i.fromPool();
if ( yUp )
{
rect.set( x, this.getHeight() - height - y, width, height );
}
else
{
rect.set( x, y, width, height );
}
if ( updateList.size() > 0 )
{
int mostSimilar = -1;
int mostSimMatchFact = 0;
for ( int i = 0; i < updateList.size(); i++ )
{
Rect2i r = updateList.get( i );
if ( rect.isCoveredBy( r ) )
{
Rect2i.toPool( rect );
return;
}
else if ( !rect.intersects( r ) )
{
int matchFact = rect.getMatchFactor( r );
if ( matchFact < mostSimMatchFact )
{
mostSimMatchFact = matchFact;
mostSimilar = i;
}
}
}
if ( mostSimilar >= 0 )
{
updateList.get( mostSimilar ).combine( rect );
Rect2i.toPool( rect );
return;
}
}
updateList.add( rect );
}
/**
* Marks a portion of the image component as dirty.
* The region will be pushed to the graphics card on the next frame.
*
* {@link Texture2D#setHasUpdateList(boolean)} must be called afterwards.
*
* @param r
*/
public final void update( Rect2i r )
{
update( r.getLeft(), r.getTop(), r.getWidth(), r.getHeight() );
}
public final ArrayList< Rect2i > getUpdateList()
{
return ( updateList );
}
public final void clearUpdateList()
{
for ( int i = updateList.size() - 1; i >= 0; i-- )
{
Rect2i.toPool( updateList.get( i ) );
}
updateList.clear();
}
void fixUpdateListAfterSizeChange()
{
for ( int i = 0; i < updateList.size(); i++ )
{
Rect2i r = updateList.get( i );
r.setLocation( Math.min( r.getLeft(), this.getWidth() ), Math.min( r.getTop(), this.getHeight() ) );
r.setSize( Math.min( r.getLeft() + r.getWidth(), this.getWidth() ) - r.getLeft(), Math.min( r.getTop() + r.getHeight(), this.getHeight() ) - r.getTop() );
}
}
void setReadOnly( boolean readOnly )
{
this.readOnly = readOnly;
}
public BufferedImage getBufferedImage()
{
if ( getFormat().isCompressed() )
return ( null );
if ( bufferedImage == null )
{
if ( this.data == null )
{
if ( readOnly )
{
// DirectBufferedImages cannot currently be scaled. Hence we need this to create scalable images.
byte[] dbbData = new byte[ dataBuffer.limit() ];
getData( dbbData );
bufferedImage = BufferedImageFactory.createSharedBufferedImage( getWidth(), getHeight(), pixelSize, hasAlpha(), null, dbbData );
}
else
{
int[] pixelOffsets = getFormat().hasAlpha() ? new int[] { 0, 1, 2, 3 } : new int[] { 0, 1, 2 };
bufferedImage = BufferedImageFactory.createDirectBufferedImage( getWidth(), getHeight(), getFormat().hasAlpha(), pixelOffsets, dataBuffer );
}
}
else
{
bufferedImage = BufferedImageFactory.createSharedBufferedImage( getWidth(), getHeight(), pixelSize, hasAlpha(), null, data );
}
}
return ( bufferedImage );
}
protected Graphics2D createGraphics2D()
{
BufferedImage bi = getBufferedImage();
return ( bi.createGraphics() );
}
private void clampClipRect( int texWidth, int texHeight )
{
clipRect.set( userClipRect );
clipRect.clamp( 0, 0, texWidth, texHeight );
}
public void setClipRect( int x, int y, int width, int height )
{
userClipRect.set( x, y, width, height );
clampClipRect( getWidth(), getHeight() );
}
public final void setClipRect( Rect2i clipRect )
{
setClipRect( clipRect.getLeft(), clipRect.getTop(), clipRect.getWidth(), clipRect.getHeight() );
}
public final <Rect2i_ extends Rect2i> Rect2i_ getClipRect( Rect2i_ rect )
{
rect.set( userClipRect );
return ( rect );
}
final Rect2i getEffectiveClipRect()
{
return ( clipRect );
}
/**
* Sets the data for the image.
*
* @param data
* @param dataLength
* @param useBuffer
*/
protected final void setImageData( byte[] data, int dataLength, boolean useBuffer )
{
clampClipRect( getWidth(), getHeight() );
if ( ( data == null ) && ( dataLength <= 0 ) )
{
this.dataBuffer = null;
this.data = null;
this.bufferedImage = null;
this.setHasData( false );
return;
}
if ( useBuffer )
{
if ( ( this.dataBuffer == null ) || ( this.dataBuffer.capacity() < dataLength ) )
{
this.dataBuffer = BufferUtils.createByteBuffer( dataLength );
}
this.data = null;
}
else
{
if ( ( this.data == null ) || ( this.data.length < dataLength ) )
{
this.data = new byte[ dataLength ];
}
this.dataBuffer = null;
}
this.bufferedImage = null;
if ( getFormat().isCompressed() )
{
if ( ( data != null ) && ( dataLength > 0 ) )
{
//final int imgSize = calculateNeededImageSize();
final int imgSize = dataLength;
this.pixelSize = imgSize / ( getWidth() * getHeight() );
if ( useBuffer )
{
dataBuffer.position( 0 );
dataBuffer.put( data, 0, dataLength );
dataBuffer.flip();
}
else
{
System.arraycopy( data, 0, this.data, 0, dataLength );
}
}
}
else
{
if ( data == null )
{
this.setHasData( true );
return;
}
if ( useBuffer )
{
dataBuffer.position( 0 );
dataBuffer.put( data, 0, dataLength );
dataBuffer.flip();
}
else
{
switch ( this.pixelSize )
{
case 4:
for ( int i = 0; i < dataLength; i += 4 )
{
this.data[ i + 0 ] = data[ i + 3 ];
this.data[ i + 1 ] = data[ i + 2 ];
this.data[ i + 2 ] = data[ i + 1 ];
this.data[ i + 3 ] = data[ i + 0 ];
}
break;
case 3:
for ( int i = 0; i < dataLength; i += 3 )
{
this.data[ i + 0 ] = data[ i + 2 ];
this.data[ i + 1 ] = data[ i + 1 ];
this.data[ i + 2 ] = data[ i + 0 ];
}
break;
case 2:
for ( int i = 0; i < dataLength; i += 2 )
{
this.data[ i + 0 ] = data[ i + 1 ];
this.data[ i + 1 ] = data[ i + 0 ];
}
break;
case 1:
for ( int i = 0; i < dataLength; i += 1 )
{
this.data[ i + 0 ] = data[ i + 0 ];
}
break;
}
}
}
setHasData( true );
}
/**
* Sets the data for the image.
*
* @param data
* @param dataLength
*/
public final void setImageData( byte[] data, int dataLength )
{
setImageData( data, dataLength, true );
}
/**
* Sets the data for the image.
*
* @param data
* @param useBuffer
*/
protected final void setImageData( byte[] data, boolean useBuffer )
{
setImageData( data, ( data != null ) ? data.length : 0, useBuffer );
}
/**
* Sets the data for the image.
*
* @param data
*/
public final void setImageData( byte[] data )
{
setImageData( data, true );
}
private final boolean needsDataResize( int width, int height, boolean allowBiggerTexture )
{
if ( ( width > this.getWidth() ) || ( height > this.getHeight() ) )
return ( true );
if ( allowBiggerTexture )
return ( false );
int lWidth = this.getWidth() >> 1;
int lHeight = this.getHeight() >> 1;
return ( ( width <= lWidth ) || ( height <= lHeight ) );
}
protected boolean initImageData( int width, int height, int orgWidth, int orgHeight, boolean allowBiggerTexture, boolean usebuffer )
{
int oldDataLength = getOriginalWidth() * getOriginalHeight() * pixelSize;
int newDataLength = orgWidth * orgHeight * pixelSize;
if ( newDataLength == oldDataLength )
{
if ( usebuffer && ( this.dataBuffer != null ) )
return ( false );
if ( !usebuffer && ( this.data != null ) )
return ( false );
}
boolean sizeChanged = ( ( width != this.getWidth() ) || ( height != this.getHeight() ) ) && needsDataResize( width, height, allowBiggerTexture );
if ( sizeChanged )
this.setSize( width, height );
if ( ( orgWidth != this.getOriginalWidth() ) || ( orgHeight != this.getOriginalHeight() ) )
this.setOriginalSize( orgWidth, orgHeight );
texCoordUR.set( (float)orgWidth / (float)getWidth(), (float)orgHeight / (float)getHeight() );
if ( sizeChanged )
setImageData( null, width * height * pixelSize, usebuffer );
return ( sizeChanged );
}
public final boolean initImageData( int orgWidth, int orgHeight, boolean allowBiggerTexture, boolean usebuffer )
{
int width = ImageUtility.roundUpPower2( orgWidth );
int height = ImageUtility.roundUpPower2( orgHeight );
return ( initImageData( width, height, orgWidth, orgHeight, allowBiggerTexture, usebuffer ) );
}
public final boolean initImageData( int orgWidth, int orgHeight, boolean allowBiggerTexture )
{
return ( initImageData( orgWidth, orgHeight, allowBiggerTexture, ( dataBuffer != null ) ) );
}
public final boolean initImageData( boolean allowBiggerTexture, boolean usebuffer )
{
return ( initImageData( getWidth(), getHeight(), getOriginalWidth(), getOriginalHeight(), allowBiggerTexture, usebuffer ) );
}
protected void setImageData( BufferedImage image, boolean useBuffer )
{
int orgWidth = image.getWidth();
int orgHeight = image.getWidth();
int width = ImageUtility.roundUpPower2( orgWidth );
int height = ImageUtility.roundUpPower2( orgHeight );
this.setSize( width, height );
this.setOriginalSize( orgWidth, orgHeight );
texCoordUR.set( (float)orgWidth / (float)width, (float)orgHeight / (float)height );
if ( useBuffer )
this.data = null;
else
this.dataBuffer = null;
this.pixelSize = getFormat().getPixelSize();
if ( useBuffer )
{
this.dataBuffer = BufferUtils.createByteBuffer( width * height * pixelSize );
Raster raster = image.getRaster();
ColorModel cm = image.getColorModel();
Object o = null;
int i = 0;
for ( int x = 0; x < width; x++ )
{
for ( int y = 0; y < height; y++ )
{
o = raster.getDataElements( x, y, o );
switch ( pixelSize )
{
case 4:
{
final byte r = (byte)cm.getRed( o );
final byte g = (byte)cm.getGreen( o );
final byte b = (byte)cm.getBlue( o );
final byte a = (byte)cm.getAlpha( o );
dataBuffer.put( i++, r );
dataBuffer.put( i++, g );
dataBuffer.put( i++, b );
dataBuffer.put( i++, a );
break;
}
case 3:
{
final byte r = (byte)cm.getRed( o );
final byte g = (byte)cm.getGreen( o );
final byte b = (byte)cm.getBlue( o );
dataBuffer.put( i++, r );
dataBuffer.put( i++, g );
dataBuffer.put( i++, b );
break;
}
case 2:
{
final byte r = (byte)cm.getRed( o );
final byte g = (byte)cm.getGreen( o );
dataBuffer.put( i++, r );
dataBuffer.put( i++, g );
break;
}
case 1:
{
final byte r = (byte)cm.getRed( o );
dataBuffer.put( i++, r );
break;
}
}
}
}
//dataBuffer.flip();
dataBuffer.position( 0 );
dataBuffer.limit( dataBuffer.capacity() );
}
else
{
this.data = new byte[ width * height * pixelSize ];
int i = getDataOffset( 0, 0 );
for ( int x = 0; x < width; x++ )
{
for ( int y = 0; y < height; y++ )
{
int argb = image.getRGB( x, y );
if ( pixelSize == 4 )
{
data[ i++ ] = (byte)( ( argb & 0xFF000000 ) >> 24 );
data[ i++ ] = (byte)( ( argb & 0x00FF0000 ) >> 16 );
data[ i++ ] = (byte)( ( argb & 0x0000FF00 ) >> 8 );
data[ i++ ] = (byte)( argb & 0x000000FF );
}
else if ( pixelSize == 3 )
{
data[ i++ ] = (byte)( ( argb & 0x00FF0000 ) >> 16 );
data[ i++ ] = (byte)( ( argb & 0x0000FF00 ) >> 8 );
data[ i++ ] = (byte)( argb & 0x000000FF );
}
}
}
}
setHasData( true );
}
public void setImageData( BufferedImage image )
{
setImageData( image, true );
}
private final int getDataOffset( int x, int y )
{
if ( yUp )
return ( ( y * getWidth() * pixelSize ) + ( x * pixelSize ) );
return ( ( ( getHeight() - y - 1 ) * getWidth() * pixelSize ) + ( x * pixelSize ) );
}
protected final void setPixel( int offset, byte[] data )
{
if ( this.data == null )
{
this.dataBuffer.position( offset );
this.dataBuffer.put( data, 0, pixelSize );
this.dataBuffer.position( 0 );
}
else
{
switch ( this.pixelSize )
{
case 4:
this.data[ offset + 0 ] = data[ 3 ];
this.data[ offset + 1 ] = data[ 2 ];
this.data[ offset + 2 ] = data[ 1 ];
this.data[ offset + 3 ] = data[ 0 ];
break;
case 3:
this.data[ offset + 0 ] = data[ 2 ];
this.data[ offset + 1 ] = data[ 1 ];
this.data[ offset + 2 ] = data[ 0 ];
break;
case 2:
this.data[ offset + 0 ] = data[ 1 ];
this.data[ offset + 1 ] = data[ 0 ];
break;
case 1:
this.data[ offset + 0 ] = data[ 0 ];
break;
}
}
}
public final void setPixel( int x, int y, byte[] data )
{
//if ( ( x < 0 ) || ( x >= getOriginalWidth() ) || ( y < 0 ) || ( y >= getOriginalHeight() ) )
if ( ( x < 0 ) || ( x >= getWidth() ) || ( y < 0 ) || ( y >= getHeight() ) )
return;
setPixel( getDataOffset( x, y ), data );
}
private final byte[] getPixel( int offset, byte[] data )
{
if ( this.data == null )
{
this.dataBuffer.position( offset );
this.dataBuffer.get( data, 0, pixelSize );
this.dataBuffer.position( 0 );
}
else
{
switch ( this.pixelSize )
{
case 4:
data[ 0 ] = this.data[ offset + 3 ];
data[ 1 ] = this.data[ offset + 2 ];
data[ 2 ] = this.data[ offset + 1 ];
data[ 3 ] = this.data[ offset + 0 ];
break;
case 3:
data[ 0 ] = this.data[ offset + 2 ];
data[ 1 ] = this.data[ offset + 1 ];
data[ 2 ] = this.data[ offset + 0 ];
break;
case 2:
data[ 0 ] = this.data[ offset + 1 ];
data[ 1 ] = this.data[ offset + 0 ];
break;
case 1:
data[ 0 ] = this.data[ offset + 0 ];
break;
}
}
return ( data );
}
public final byte[] getPixel( int x, int y, byte[] data )
{
return ( getPixel( getDataOffset( x, y ), data ) );
}
public final void setPixelLine( int trgByteOffset, byte[] data, int srcByteOffset, int length )
{
final int n = length * pixelSize;
if ( this.data == null )
{
this.dataBuffer.position( trgByteOffset );
this.dataBuffer.put( data, srcByteOffset, n );
this.dataBuffer.position( 0 );
}
else
{
switch ( this.pixelSize )
{
case 4:
for ( int i = 0; i < n; i += 4 )
{
this.data[ trgByteOffset + i + 0 ] = data[ srcByteOffset + i + 3 ];
this.data[ trgByteOffset + i + 1 ] = data[ srcByteOffset + i + 2 ];
this.data[ trgByteOffset + i + 2 ] = data[ srcByteOffset + i + 1 ];
this.data[ trgByteOffset + i + 3 ] = data[ srcByteOffset + i + 0 ];
}
break;
case 3:
for ( int i = 0; i < n; i += 3 )
{
this.data[ trgByteOffset + i + 0 ] = data[ srcByteOffset + i + 2 ];
this.data[ trgByteOffset + i + 1 ] = data[ srcByteOffset + i + 1 ];
this.data[ trgByteOffset + i + 2 ] = data[ srcByteOffset + i + 0 ];
}
break;
case 2:
for ( int i = 0; i < n; i += 2 )
{
this.data[ trgByteOffset + i + 0 ] = data[ srcByteOffset + i + 1 ];
this.data[ trgByteOffset + i + 1 ] = data[ srcByteOffset + i + 0 ];
}
break;
case 1:
for ( int i = 0; i < n; i += 1 )
{
this.data[ trgByteOffset + i + 0 ] = data[ srcByteOffset + i + 0 ];
}
break;
}
}
}
public final void setPixelLine( int x, int y, byte[] data, int srcOffset, int length )
{
setPixelLine( getDataOffset( x, y ), data, srcOffset, length );
}
public final byte[] getPixelLine( int offset, int length, byte[] data )
{
if ( this.data == null )
{
this.dataBuffer.position( offset );
this.dataBuffer.get( data, 0, length * pixelSize );
this.dataBuffer.position( 0 );
}
else
{
final int n = length * pixelSize;
switch ( this.pixelSize )
{
case 4:
for ( int i = 0; i < n; i += 4 )
{
data[ i + 0 ] = this.data[ offset + i + 3 ];
data[ i + 1 ] = this.data[ offset + i + 2 ];
data[ i + 2 ] = this.data[ offset + i + 1 ];
data[ i + 3 ] = this.data[ offset + i + 0 ];
}
break;
case 3:
for ( int i = 0; i < n; i += 3 )
{
data[ i + 0 ] = this.data[ offset + i + 2 ];
data[ i + 1 ] = this.data[ offset + i + 1 ];
data[ i + 2 ] = this.data[ offset + i + 0 ];
}
break;
case 2:
for ( int i = 0; i < n; i += 2 )
{
data[ i + 0 ] = this.data[ offset + i + 1 ];
data[ i + 1 ] = this.data[ offset + i + 0 ];
}
break;
case 1:
for ( int i = 0; i < n; i += 1 )
{
data[ i + 0 ] = this.data[ offset + i + 0 ];
}
break;
}
}
return ( data );
}
public final byte[] getPixelLine( int x, int y, int length, byte[] data )
{
return ( getPixelLine( getDataOffset( x, y ), length, data ) );
}
private static final byte[] combinePixels( final byte[] src,
final int srcByteOffset,
final int srcPixelSize,
final TextureImage2D trgIC, final int trgPixelSize,
final byte[] trg, final int trgByteOffset,
final int numPixels,
final boolean overwrite
)
{
if ( srcPixelSize == 3 )
{
if ( trgPixelSize == 3 )
{
return ( src );
}
// target has size 4
//trgIC.getPixelLine( trgOffset, numPixels, trg );
int j = srcByteOffset;
int k = 0;
for ( int i = 0; i < numPixels; i++ )
{
trg[ k + 0 ] = src[ j + 0 ];
trg[ k + 1 ] = src[ j + 1 ];
trg[ k + 2 ] = src[ j + 2 ];
trg[ k + 3 ] = (byte)255;
j += srcPixelSize;
k += trgPixelSize;
}
}
else if ( srcPixelSize == 4 )
{
if ( trgPixelSize == 3 )
{
if ( !overwrite )
trgIC.getPixelLine( trgByteOffset, numPixels, trg );
int j = srcByteOffset;
int k = 0;
for ( int i = 0; i < numPixels; i++ )
{
final int srcR = src[ j + 0 ] & 0x000000FF;
final int srcG = src[ j + 1 ] & 0x000000FF;
final int srcB = src[ j + 2 ] & 0x000000FF;
final int srcA = src[ j + 3 ] & 0x000000FF;
if ( overwrite )
{
trg[ k + 0 ] = (byte)( srcR * srcA / 255 );
trg[ k + 1 ] = (byte)( srcG * srcA / 255 );
trg[ k + 2 ] = (byte)( srcB * srcA / 255 );
}
else
{
final int trgR = trg[ k + 0 ] & 0x000000FF;
final int trgG = trg[ k + 1 ] & 0x000000FF;
final int trgB = trg[ k + 2 ] & 0x000000FF;
trg[ k + 0 ] = (byte)( ( srcR * srcA / 255 ) + ( trgR * ( 255 - srcA ) / 255 ) );
trg[ k + 1 ] = (byte)( ( srcG * srcA / 255 ) + ( trgG * ( 255 - srcA ) / 255 ) );
trg[ k + 2 ] = (byte)( ( srcB * srcA / 255 ) + ( trgB * ( 255 - srcA ) / 255 ) );
}
j += srcPixelSize;
k += trgPixelSize;
}
}
else if ( trgPixelSize == 4 )
{
if ( overwrite )
return ( src );
trgIC.getPixelLine( trgByteOffset, numPixels, trg );
int j = srcByteOffset;
int k = 0;
for ( int i = 0; i < numPixels; i++ )
{
final int srcR = src[ j + 0 ] & 0x000000FF;
final int srcG = src[ j + 1 ] & 0x000000FF;
final int srcB = src[ j + 2 ] & 0x000000FF;
final int srcA = src[ j + 3 ] & 0x000000FF;
final int trgR = trg[ k + 0 ] & 0x000000FF;
final int trgG = trg[ k + 1 ] & 0x000000FF;
final int trgB = trg[ k + 2 ] & 0x000000FF;
final int trgA = trg[ k + 3 ] & 0x000000FF;
trg[ k + 0 ] = (byte)( ( srcR * srcA / 255 ) + ( trgR * ( 255 - srcA ) / 255 ) );
trg[ k + 1 ] = (byte)( ( srcG * srcA / 255 ) + ( trgG * ( 255 - srcA ) / 255 ) );
trg[ k + 2 ] = (byte)( ( srcB * srcA / 255 ) + ( trgB * ( 255 - srcA ) / 255 ) );
trg[ k + 3 ] = (byte)( ( srcA * srcA / 255 ) + ( trgA * ( 255 - srcA ) / 255 ) );
j += srcPixelSize;
k += trgPixelSize;
}
}
}
return ( trg );
}
private final byte[] getPixelLineBuffer1( int size )
{
if ( ( pixelRow1 == null ) || ( pixelRow1.length < size ) )
pixelRow1 = new byte[ Math.max( size, this.getWidth() * this.getPixelSize() ) ];
return ( pixelRow1 );
}
private final byte[] getPixelLineBuffer2( int size )
{
if ( ( pixelRow2 == null ) || ( pixelRow2.length < size ) )
pixelRow2 = new byte[ Math.max( size, this.getWidth() * this.getPixelSize() ) ];
return ( pixelRow2 );
}
/**
* Copies the image data from the given {@link TextureImage2D}
* and writes them to this image at the given position.
*
* @param srcTI source image
* @param srcX the rectangle's left to copy from the source {@link TextureImage2D}.
* @param srcY the rectangle's top to copy from the source {@link TextureImage2D}.
* @param srcWidth the rectangle's width to copy from the source {@link TextureImage2D}.
* @param srcHeight the rectangle's height to copy from the source {@link TextureImage2D}.
* @param trgX target x-coordinate
* @param trgY target y-coordinate
* @param trgWidth the targetWidth (tiled or clipped if necessary)
* @param trgHeight the targetHeight (tiled or clipped if necessary)
* @param overwrite
*/
private void copyImageDataFrom( TextureImage2D srcTI, int srcX, int srcY, int srcWidth, int srcHeight, int trgX, int trgY, int trgWidth, int trgHeight, boolean overwrite )
{
if ( trgX + trgWidth < clipRect.getLeft() )
return;
if ( trgY + trgHeight < clipRect.getTop() )
return;
if ( trgX >= clipRect.getLeft() + clipRect.getWidth() )
return;
if ( trgY >= clipRect.getTop() + clipRect.getHeight() )
return;
if ( trgX < clipRect.getLeft() )
{
int oldTrgX = trgX;
trgX = clipRect.getLeft() - ( ( clipRect.getLeft() - trgX ) % srcWidth );
trgWidth -= trgX - oldTrgX;
}
if ( trgY < clipRect.getTop() )
{
int oldTrgY = trgY;
trgY = clipRect.getTop() - ( ( clipRect.getTop() - trgY ) % srcHeight );
trgHeight -= trgY - oldTrgY;
}
if ( trgX + trgWidth > clipRect.getLeft() + clipRect.getWidth() )
{
trgWidth = (int)Math.ceil( (double)( clipRect.getLeft() + clipRect.getWidth() - trgX ) / (double)srcWidth ) * srcWidth;
}
/*
if ( trgY + trgHeight > clipRect.getTop() + clipRect.getHeight() )
{
trgHeight = (int)Math.ceil( (double)( clipRect.getTop() + clipRect.getHeight() - trgY ) / (double)srcHeight ) * srcHeight;
}
*/
final int srcPixelSize = srcTI.getPixelSize();
final int trgPixelSize = this.getPixelSize();
byte[] srcBuffer = getPixelLineBuffer1( srcWidth * srcPixelSize );
byte[] trgBuffer = getPixelLineBuffer2( srcWidth * trgPixelSize );
final int y_ = getHeight() - getOriginalHeight();
final int x0 = Math.max( clipRect.getLeft(), trgX );
final int x1 = Math.min( clipRect.getLeft() + clipRect.getWidth(), trgX + trgWidth );
final int y0 = Math.max( clipRect.getTop(), trgY );
final int y1 = Math.min( clipRect.getTop() + clipRect.getHeight(), trgY + trgHeight );
for ( int j = y0; j < y1; j++ )
{
int srcJ = srcY + ( ( j - trgY ) % srcHeight );
srcTI.getPixelLine( srcX, srcJ, srcWidth, srcBuffer );
int trgX_ = trgX;
int trgWidth_ = trgWidth;
int trgLength_ = srcWidth;
while ( trgX_ < trgX + trgWidth )
{
if ( trgWidth_ < srcWidth )
trgLength_ = trgWidth_;
if ( trgX_ + trgLength_ >= x1 )
trgLength_ = x1 - trgX_;
int trgX__ = Math.max( x0, trgX_ );
int trgByteOffset = this.getDataOffset( trgX__, y_ + j );
int srcPixelOffset = ( trgX__ - trgX_ );
byte[] pixels = combinePixels( srcBuffer, srcPixelOffset * srcPixelSize, srcPixelSize, this, trgPixelSize, trgBuffer, trgByteOffset, trgLength_ - srcPixelOffset, overwrite );
if ( ( srcPixelSize == trgPixelSize ) && overwrite )
this.setPixelLine( trgByteOffset, pixels, srcPixelOffset * srcPixelSize, trgLength_ - srcPixelOffset );
else
this.setPixelLine( trgByteOffset, pixels, 0, trgLength_ - srcPixelOffset );
trgX_ += srcWidth;
trgWidth_ -= srcWidth;
}
}
}
/**
* Draws the given {@link TextureImage2D} onto this one and honors the alpha channels (if any).
*
* @param srcTI source image
* @param srcX the rectangle's left to copy from the source {@link TextureImage2D}.
* @param srcY the rectangle's top to copy from the source {@link TextureImage2D}.
* @param srcWidth the rectangle's width to copy from the source {@link TextureImage2D}.
* @param srcHeight the rectangle's height to copy from the source {@link TextureImage2D}.
* @param trgX target x-coordinate
* @param trgY target y-coordinate
* @param trgWidth the targetWidth (tiled or clipped if necessary)
* @param trgHeight the targetHeight (tiled or clipped if necessary)
*/
public final void drawImage( TextureImage2D srcTI, int srcX, int srcY, int srcWidth, int srcHeight, int trgX, int trgY, int trgWidth, int trgHeight )
{
copyImageDataFrom( srcTI, srcX, srcY, srcWidth, srcHeight, trgX, trgY, trgWidth, trgHeight, false );
}
/**
* Draws the given {@link TextureImage2D} onto this one and honors the alpha channels (if any).
*
* @param srcTI source image
* @param srcX the rectangle's left to copy from the source {@link TextureImage2D}.
* @param srcY the rectangle's top to copy from the source {@link TextureImage2D}.
* @param srcWidth the rectangle's width to copy from the source {@link TextureImage2D}.
* @param srcHeight the rectangle's height to copy from the source {@link TextureImage2D}.
* @param trgX target x-coordinate
* @param trgY target y-coordinate
*/
public final void drawImage( TextureImage2D srcTI, int srcX, int srcY, int srcWidth, int srcHeight, int trgX, int trgY )
{
drawImage( srcTI, srcX, srcY, srcWidth, srcHeight, trgX, trgY, srcWidth, srcHeight );
}
/**
* Draws the given {@link TextureImage2D} onto this one and honors the alpha channels (if any).
*
* @param ti source image
* @param srcRect the rectangle to copy from the source {@link TextureImage2D}.
* @param trgX target x-coordinate
* @param trgY target y-coordinate
*/
public final void drawImage( TextureImage2D ti, Rect2i srcRect, int trgX, int trgY )
{
drawImage( ti, srcRect.getLeft(), srcRect.getTop(), srcRect.getWidth(), srcRect.getHeight(), trgX, trgY );
}
/**
* Draws the given {@link TextureImage2D} onto this one and honors the alpha channels (if any).
*
* @param ti source image
* @param trgX target x-coordinate
* @param trgY target y-coordinate
*/
public final void drawImage( TextureImage2D ti, int trgX, int trgY )
{
drawImage( ti, 0, 0, ti.getOriginalWidth(), ti.getOriginalHeight(), trgX, trgY );
}
public void fillRectangle( Colorf color, int offsetX, int offsetY, int width, int height )
{
if ( !color.hasAlpha() )
{
clear( color, offsetX, offsetY, width, height );
return;
}
int srcPixelSize = 4;
byte[] pixel = getPixelLineBuffer1( srcPixelSize );
pixel[ 0 ] = color.getRedByte();
pixel[ 1 ] = color.getGreenByte();
pixel[ 2 ] = color.getBlueByte();
pixel[ 3 ] = (byte)( (byte)255 - color.getAlphaByte() );
int trgPixelSize = this.getPixelSize();
byte[] trgBuffer = getPixelLineBuffer2( trgPixelSize );
final int x0 = Math.max( clipRect.getLeft(), offsetX );
final int x1 = Math.min( clipRect.getLeft() + clipRect.getWidth(), offsetX + width );
final int y0 = Math.max( clipRect.getTop(), offsetY );
final int y1 = Math.min( clipRect.getTop() + clipRect.getHeight(), offsetY + height );
final int y_ = getHeight() - getOriginalHeight();
for ( int j = y0; j < y1; j++ )
{
for ( int i = x0; i < x1; i++ )
{
int trgOffset = this.getDataOffset( i, y_ + j );
byte[] newPixel = combinePixels( pixel, 0, pixelSize, this, pixelSize, trgBuffer, trgOffset, 1, false );
this.setPixel( trgOffset, newPixel );
}
}
}
public final void fillFullRectangle( Colorf color )
{
fillRectangle( color, 0, 0, getOriginalWidth(), getOriginalHeight() );
}
public void drawPixelLine( byte[] pixels, int pixelSize, int startX, int startY, int length )
{
if ( pixelSize < 4 )
{
clearPixelLine( pixels, pixelSize, startX, startY, length );
return;
}
if ( ( clipRect.getLeft() > startX + length - 1 ) || ( clipRect.getLeft() + clipRect.getWidth() - 1 < startX ) )
return;
if ( ( clipRect.getTop() > startY ) || ( clipRect.getTop() + clipRect.getHeight() - 1 < startY ) )
return;
int trgPixelSize = this.getPixelSize();
byte[] trgBuffer = getPixelLineBuffer2( trgPixelSize );
final int x0 = Math.max( clipRect.getLeft(), startX );
final int x1 = Math.min( clipRect.getLeft() + clipRect.getWidth() - 1, startX + length - 1 );
length = x1 - x0 + 1;
final int y_ = getHeight() - getOriginalHeight();
int srcByteOffset = ( x0 - startX ) * pixelSize;
int trgByteOffset = this.getDataOffset( x0, y_ + startY );
byte[] newPixels = combinePixels( pixels, srcByteOffset, pixelSize, this, trgPixelSize, trgBuffer, trgByteOffset, length, false );
this.setPixelLine( trgByteOffset, newPixels, srcByteOffset, length );
}
/**
* Draws the given {@link TextureImage2D} onto this one and simply overwrites anything.
*
* @param srcTI source image
* @param srcX the rectangle's left to copy from the source {@link TextureImage2D}.
* @param srcY the rectangle's top to copy from the source {@link TextureImage2D}.
* @param srcWidth the rectangle's width to copy from the source {@link TextureImage2D}.
* @param srcHeight the rectangle's height to copy from the source {@link TextureImage2D}.
* @param trgX target x-coordinate
* @param trgY target y-coordinate
* @param trgWidth the targetWidth (tiled or clipped if necessary)
* @param trgHeight the targetHeight (tiled or clipped if necessary)
*/
public final void clear( TextureImage2D srcTI, int srcX, int srcY, int srcWidth, int srcHeight, int trgX, int trgY, int trgWidth, int trgHeight )
{
copyImageDataFrom( srcTI, srcX, srcY, srcWidth, srcHeight, trgX, trgY, trgWidth, trgHeight, true );
}
/**
* Draws the given {@link TextureImage2D} onto this one and simply overwrites anything.
*
* @param srcTI source image
* @param trgX target x-coordinate
* @param trgY target y-coordinate
* @param trgWidth the targetWidth (tiled or clipped if necessary)
* @param trgHeight the targetHeight (tiled or clipped if necessary)
*/
public final void clear( TextureImage2D srcTI, int trgX, int trgY, int trgWidth, int trgHeight )
{
copyImageDataFrom( srcTI, 0, 0, srcTI.getOriginalWidth(), srcTI.getOriginalHeight(), trgX, trgY, trgWidth, trgHeight, true );
}
/**
* Draws the given {@link TextureImage2D} onto this one and simply overwrites anything.
*
* @param srcTI source image
* @param srcX the rectangle's left to copy from the source {@link TextureImage2D}.
* @param srcY the rectangle's top to copy from the source {@link TextureImage2D}.
* @param srcWidth the rectangle's width to copy from the source {@link TextureImage2D}.
* @param srcHeight the rectangle's height to copy from the source {@link TextureImage2D}.
* @param trgX target x-coordinate
* @param trgY target y-coordinate
*/
public final void clear( TextureImage2D srcTI, int srcX, int srcY, int srcWidth, int srcHeight, int trgX, int trgY )
{
clear( srcTI, srcX, srcY, srcWidth, srcHeight, trgX, trgY, srcWidth, srcHeight );
}
/**
* Draws the given {@link TextureImage2D} onto this one and simply overwrites anything.
*
* @param srcTI source image
* @param srcRect the rectangle to copy from the source {@link TextureImage2D}.
* @param trgX target x-coordinate
* @param trgY target y-coordinate
*/
public final void clear( TextureImage2D srcTI, Rect2i srcRect, int trgX, int trgY )
{
clear( srcTI, srcRect.getLeft(), srcRect.getTop(), srcRect.getWidth(), srcRect.getHeight(), trgX, trgY );
}
/**
* Draws the given {@link TextureImage2D} onto this one and simply overwrites anything.
*
* @param srcTI source image
* @param trgX target x-coordinate
* @param trgY target y-coordinate
*/
public final void clear( TextureImage2D srcTI, int trgX, int trgY )
{
clear( srcTI, 0, 0, srcTI.getOriginalWidth(), srcTI.getOriginalHeight(), trgX, trgY );
}
/**
* Draws the given {@link TextureImage2D} onto this one and simply overwrites anything.
*
* @param ti source image
*/
public final void clear( TextureImage2D srcTI )
{
clear( srcTI, 0, 0, srcTI.getOriginalWidth(), srcTI.getOriginalHeight(), 0, 0 );
}
public void clear( Colorf color, int offsetX, int offsetY, int width, int height )
{
//byte[] pixel = getPixelLineBuffer1( width * this.getPixelSize() );
byte[] pixel = getPixelLineBuffer1( this.getPixelSize() );
switch ( this.getPixelSize() )
{
case 4:
pixel[ 0 ] = color.getRedByte();
pixel[ 1 ] = color.getGreenByte();
pixel[ 2 ] = color.getBlueByte();
pixel[ 3 ] = (byte)( (byte)255 - color.getAlphaByte() );
break;
case 3:
pixel[ 0 ] = color.getRedByte();
pixel[ 1 ] = color.getGreenByte();
pixel[ 2 ] = color.getBlueByte();
break;
case 2:
pixel[ 0 ] = color.getRedByte();
pixel[ 1 ] = (byte)( (byte)255 - color.getAlphaByte() );
break;
case 1:
pixel[ 0 ] = (byte)( (byte)255 - color.getAlphaByte() );
break;
}
final int x0 = Math.max( clipRect.getLeft(), offsetX );
final int x1 = Math.min( clipRect.getLeft() + clipRect.getWidth(), offsetX + width );
final int y0 = Math.max( clipRect.getTop(), offsetY );
final int y1 = Math.min( clipRect.getTop() + clipRect.getHeight(), offsetY + height );
final int y_ = getHeight() - getOriginalHeight();
for ( int j = y0; j < y1; j++ )
{
for ( int i = x0; i < x1; i++ )
{
this.setPixel( i, y_ + j, pixel );
}
}
}
public final void clear( Colorf color )
{
clear( color, 0, 0, getOriginalWidth(), getOriginalHeight() );
}
public void clearPixelLine( byte[] pixels, int pixelSize, int startX, int startY, int length )
{
if ( ( clipRect.getLeft() > startX + length - 1 ) || ( clipRect.getLeft() + clipRect.getWidth() - 1 < startX ) )
return;
if ( ( clipRect.getTop() > startY ) || ( clipRect.getTop() + clipRect.getHeight() - 1 < startY ) )
return;
final int x0 = Math.max( clipRect.getLeft(), startX );
final int x1 = Math.min( clipRect.getLeft() + clipRect.getWidth() - 1, startX + length - 1 );
length = x1 - x0 + 1;
final int y_ = getHeight() - getOriginalHeight();
int srcByteOffset = ( x0 - startX ) * pixelSize;
int trgByteOffset = this.getDataOffset( x0, y_ + startY );
this.setPixelLine( trgByteOffset, pixels, srcByteOffset, length );
}
/**
* {@inheritDoc}
*/
@Override
protected void duplicateNodeComponent( NodeComponent original, boolean forceDuplicate )
{
//super.duplicateNodeComponent( original, forceDuplicate );
throw new UnsupportedOperationException( "Not implemented yet" );
}
/**
* {@inheritDoc}
*/
@Override
public TextureImage2D cloneNodeComponent( boolean forceDuplicate )
{
throw new UnsupportedOperationException( "Not implemented yet" );
}
public TextureImage2D( TextureImageFormat format, int width, int height, int orgWidth, int orgHeight, boolean yUp, TextureImageInternalFormat internalFormat )
{
super( format, width, height, orgWidth, orgHeight, internalFormat );
setClipRect( 0, 0, width, height );
this.pixelSize = format.getPixelSize();
this.yUp = yUp;
setHasData( false );
texCoordUR.set( (float)orgWidth / (float)width, (float)orgHeight / (float)height );
}
public TextureImage2D( TextureImageFormat format, int width, int height, int orgWidth, int orgHeight, boolean yUp )
{
this( format, width, height, orgWidth, orgHeight, yUp, TextureImageInternalFormat.getFallbackInternalFormat( format ) );
}
protected TextureImage2D( TextureImageFormat format, int width, int height, int orgWidth, int orgHeight, byte[] data, int dataLength, boolean useBuffer, TextureImageInternalFormat internalFormat )
{
this( format, width, height, orgWidth, orgHeight, false, internalFormat );
if ( format.isCompressed() )
{
//final int imgSize = calculateNeededImageSize();
final int imgSize = dataLength;
//this.dataBuffer = BufferUtils.createByteBuffer( imgSize );
//dataBuffer.put( data, 0, dataLength );
//dataBuffer.flip();
//this.data = new byte[ imgSize ];
this.pixelSize = imgSize / ( width * height );
setHasData( true );
}
else
{
if ( dataLength <= 0 )
{
this.data = null;
this.dataBuffer = null;
setHasData( false );
}
}
setImageData( data, dataLength, useBuffer );
}
public TextureImage2D( TextureImageFormat format, int width, int height, int orgWidth, int orgHeight, byte[] data, int dataLength, TextureImageInternalFormat internalFormat )
{
this( format, width, height, orgWidth, orgHeight, data, dataLength, true, internalFormat );
}
public TextureImage2D( TextureImageFormat format, int width, int height, int orgWidth, int orgHeight, byte[] data, TextureImageInternalFormat internalFormat )
{
this( format, width, height, orgWidth, orgHeight, data, ( data != null ) ? data.length : 0, true, internalFormat );
}
/**
* Constructs a new {@link TextureImage2D} object.
*/
public TextureImage2D( TextureImageFormat format, int width, int height, int orgWidth, int orgHeight, byte[] data, int dataLength )
{
this( format, width, height, orgWidth, orgHeight, data, dataLength, true, TextureImageInternalFormat.getFallbackInternalFormat( format ) );
}
/**
* Constructs a new {@link TextureImage2D} object.
*/
public TextureImage2D( TextureImageFormat format, int width, int height, int orgWidth, int orgHeight, byte[] data )
{
this( format, width, height, orgWidth, orgHeight, data, ( data != null ) ? data.length : 0 );
}
public TextureImage2D( TextureImageFormat format, int width, int height, boolean yUp, TextureImageInternalFormat internalFormat )
{
this( format, width, height, width, height, yUp, internalFormat );
}
public TextureImage2D( TextureImageFormat format, int width, int height, boolean yUp )
{
this( format, width, height, width, height, yUp );
}
protected TextureImage2D( TextureImageFormat format, int width, int height, byte[] data, int dataLength, boolean useBuffer, TextureImageInternalFormat internalFormat )
{
this( format, width, height, width, height, data, dataLength, useBuffer, internalFormat );
}
public TextureImage2D( TextureImageFormat format, int width, int height, byte[] data, int dataLength, TextureImageInternalFormat internalFormat )
{
this( format, width, height, width, height, data, dataLength, internalFormat );
}
public TextureImage2D( TextureImageFormat format, int width, int height, byte[] data, TextureImageInternalFormat internalFormat )
{
this( format, width, height, width, height, data, internalFormat );
}
/**
* Constructs a new {@link TextureImage2D} object.
*/
public TextureImage2D( TextureImageFormat format, int width, int height, byte[] data, int dataLength )
{
this( format, width, height, width, height, data, dataLength );
}
/**
* Constructs a new {@link TextureImage2D} object.
*/
public TextureImage2D( TextureImageFormat format, int width, int height, byte[] data )
{
this( format, width, height, width, height, data );
}
public TextureImage2D( TextureImageFormat format, int orgWidth, int orgHeight, BufferedImage image, boolean yUp )
{
this( format, image.getWidth(), image.getHeight(), orgWidth, orgHeight, yUp );
setImageData( image, true );
}
public TextureImage2D( TextureImageFormat format, BufferedImage image, boolean yUp )
{
this( format, image.getWidth(), image.getHeight(), image, yUp );
}
public TextureImage2D( TextureImageFormat format, BufferedImage image )
{
this( format, image.getWidth(), image.getHeight(), image, false );
}
}