LWJGLTextureUpdater for jme 1.0

I learned from Momoko_Fan about a class called "LWJGLTextureUpdater" that efficiently sends updated image data to the graphics card after a texture has already been bound.  Unfortunately, I soon learned that this class is not in jme 1.0, and I am still using jme 1.0 for my project, so I created a port of it for jme 1.0.  Jme 1.0 has far fewer image formats than 2.0, particularly support for 8-bit alpha maps, so there are many formats from 2.0 commented out here.  Here it is…


import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import org.lwjgl.opengl.EXTTextureCompressionS3TC;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.OpenGLException;
import org.lwjgl.opengl.Util;

import com.jme.image.Texture;
import com.jme.util.geom.BufferUtils;

import static com.jme.image.Image.*;

/**
   * @author Anubis
  */
public class LWJGLTextureUpdater {
    private static IntBuffer idBuff = BufferUtils.createIntBuffer(16);
    private static boolean glTexSubImage2DSupported = true;

    /**
     * Efficiently sends the updated image data to the graphics card.
     *
     * @param texture the <code>Texture</code>
     * @param data the image data   
     * @param w the image width
     * @param h the image height
     * @param format the image format in <code>com.jme.image.Image</code>
     */
    public static void updateTexture(Texture texture, ByteBuffer data, int w, int h, int format) {
        int dataFormat = getGLDataFormat(format);
        int pixelFormat = getGLPixelFormat(format);
       
        idBuff.clear();
        GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D, idBuff);
        int oldTex = idBuff.get();

        GL11.glBindTexture( GL11.GL_TEXTURE_2D, texture.getTextureId() );
        GL11.glPixelStorei( GL11.GL_UNPACK_ALIGNMENT, 1 );

        if (glTexSubImage2DSupported) {
            GL11.glTexSubImage2D( GL11.GL_TEXTURE_2D, 0,
                    0, 0, w, h, pixelFormat,
                    GL11.GL_UNSIGNED_BYTE, data );

            try {
                Util.checkGLError();
            } catch ( OpenGLException e ) {
                glTexSubImage2DSupported = false;
                updateTexture(texture, data, w, h, format);
            }
        } else {
            GL11.glTexImage2D( GL11.GL_TEXTURE_2D, 0,
                    dataFormat, w,
                    h, 0, pixelFormat,
                    GL11.GL_UNSIGNED_BYTE, data );
        }

        GL11.glBindTexture(GL11.GL_TEXTURE_2D, oldTex);
    }

// converted from jme 2.0 com.jme.scene.state.lwjgl.records.TextureStateRecord
private static int getGLDataFormat(int format) {
    switch (format) {
        // first some frequently used formats
        case RGBA8888:
            return GL11.GL_RGBA8;
        case RGB888:
            return GL11.GL_RGB8;
       // case Alpha8:
      //      return GL11.GL_ALPHA8;
        case RGB888_DXT1:
        case DXT1_NATIVE:
            return EXTTextureCompressionS3TC.GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
        //case RGBA_TO_DXT1:
        case RGBA8888_DXT1A:
        case DXT1A_NATIVE:
            return EXTTextureCompressionS3TC.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
        case RGBA8888_DXT3:
        case DXT3_NATIVE:
            return EXTTextureCompressionS3TC.GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
        case RGBA8888_DXT5:
        case DXT5_NATIVE:
            return EXTTextureCompressionS3TC.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;

        // The rest...
        /*
        case Alpha4:
            return GL11.GL_ALPHA4;
        case Alpha12:
            return GL11.GL_ALPHA12;
        case Alpha16:
            return GL11.GL_ALPHA16;
        case Luminance4:
            return GL11.GL_LUMINANCE4;
        case Luminance8:
            return GL11.GL_LUMINANCE8;
        case Luminance12:
            return GL11.GL_LUMINANCE12;
        case Luminance16:
            return GL11.GL_LUMINANCE16;
        case Intensity4:
            return GL11.GL_INTENSITY4;
        case Intensity8:
            return GL11.GL_INTENSITY8;
        case Intensity12:
            return GL11.GL_INTENSITY12;
        case Intensity16:
            return GL11.GL_INTENSITY16;
        case Luminance4Alpha4:
            return GL11.GL_LUMINANCE4_ALPHA4;
        case Luminance6Alpha2:
            return GL11.GL_LUMINANCE6_ALPHA2;
        case Luminance8Alpha8:
            return GL11.GL_LUMINANCE8_ALPHA8;
        case Luminance12Alpha4:
            return GL11.GL_LUMINANCE12_ALPHA4;
        case Luminance12Alpha12:
            return GL11.GL_LUMINANCE12_ALPHA12;
        case Luminance16Alpha16:
            return GL11.GL_LUMINANCE16_ALPHA16;
        case R3G3B2:
            return GL11.GL_R3_G3_B2;
        case RGB4:
            return GL11.GL_RGB4;
        case RGB5:
            return GL11.GL_RGB5;
        case RGB10:
            return GL11.GL_RGB10;
        case RGB12:
            return GL11.GL_RGB12;
        case RGB16:
            return GL11.GL_RGB16;
        case RGBA2:
            return GL11.GL_RGBA2;
        case RGBA4:
            return GL11.GL_RGBA4;
        case RGB5A1:
            return GL11.GL_RGB5_A1;
        case RGB10A2:
            return GL11.GL_RGB10_A2;
        case RGBA12:
            return GL11.GL_RGBA12;
        case RGBA16:
            return GL11.GL_RGBA16;
        case Depth16:
            return ARBDepthTexture.GL_DEPTH_COMPONENT16_ARB;
        case Depth24:
            return ARBDepthTexture.GL_DEPTH_COMPONENT24_ARB;
        case Depth32:
            return ARBDepthTexture.GL_DEPTH_COMPONENT32_ARB;
        case RGB16F:
            return ARBTextureFloat.GL_RGB16F_ARB;
        case RGB32F:
            return ARBTextureFloat.GL_RGB32F_ARB;
        case RGBA16F:
            return ARBTextureFloat.GL_RGBA16F_ARB;
        case RGBA32F:
            return ARBTextureFloat.GL_RGBA32F_ARB;
        case Alpha16F:
            return ARBTextureFloat.GL_ALPHA16F_ARB;
        case Alpha32F:
            return ARBTextureFloat.GL_ALPHA32F_ARB;
        case Luminance16F:
            return ARBTextureFloat.GL_LUMINANCE16F_ARB;
        case Luminance32F:
            return ARBTextureFloat.GL_LUMINANCE32F_ARB;
        case LuminanceAlpha16F:
            return ARBTextureFloat.GL_LUMINANCE_ALPHA16F_ARB;
        case LuminanceAlpha32F:
            return ARBTextureFloat.GL_LUMINANCE_ALPHA32F_ARB;
        case Intensity16F:
            return ARBTextureFloat.GL_INTENSITY16F_ARB;
        case Intensity32F:
            return ARBTextureFloat.GL_INTENSITY32F_ARB;
        */
    }
    throw new IllegalArgumentException("Incorrect format set: "+format);
}
// converted from jme 2.0 com.jme.scene.state.lwjgl.records.TextureStateRecord
private static int getGLPixelFormat(int format) {
    switch (format) {
       
        case RA88:
        case RGBA4444:
        case RGBA8888:
        case RGBA5551:
        /*
        case RGB10A2:
        case RGBA12:
        case RGBA16:
        case RGBA_TO_DXT1:
        case NativeDXT1A:
        case RGBA_TO_DXT3:
        case NativeDXT3:
        case RGBA_TO_DXT5:
        case NativeDXT5:
        case RGBA16F:
        case RGBA32F:
        */
            return GL11.GL_RGBA;
        case RGB888:
        /*
        case RGB4:
        case RGB5:
        case RGB8:
        case RGB10:
        case RGB12:
        case RGB16:
        case RGB_TO_DXT1:
        case NativeDXT1:
        case RGB16F:
        case RGB32F:
        */
            return GL11.GL_RGB;
        /*
        case Alpha4:
        case Alpha8:
        case Alpha12:
        case Alpha16:
        case Alpha16F:
        case Alpha32F:
            return GL11.GL_ALPHA;
        case Luminance4:
        case Luminance8:
        case Luminance12:
        case Luminance16:
        case Luminance16F:
        case Luminance32F:
            return GL11.GL_LUMINANCE;
        case Intensity4:
        case Intensity8:
        case Intensity12:
        case Intensity16:
        case Intensity16F:
        case Intensity32F:
            return GL11.GL_INTENSITY;
        case Luminance4Alpha4:
        case Luminance6Alpha2:
        case Luminance8Alpha8:
        case Luminance12Alpha4:
        case Luminance12Alpha12:
        case Luminance16Alpha16:
        case LuminanceAlpha16F:
        case LuminanceAlpha32F:
            return GL11.GL_LUMINANCE_ALPHA;
        case Depth16:
        case Depth24:
        case Depth32:
            return GL11.GL_DEPTH_COMPONENT;
        */
    }
    throw new IllegalArgumentException("Incorrect format set: "+format);
}
}