* Added new image format: Depth24Stencil8, for framebuffers and textures that need stencil data
* Renderer now uses getArray() to access mesh's buffers * GL image format data now stored in a special data structure for easier management (instead of huge switch/case statement) * Android texture loading: If the format is not supported by GLES spec, the texture upload will fail git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9298 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
		
							parent
							
								
									cf9d5b5ebc
								
							
						
					
					
						commit
						f68475319a
					
				| @ -6,50 +6,11 @@ import android.opengl.GLUtils; | |||||||
| import com.jme3.asset.AndroidImageInfo; | import com.jme3.asset.AndroidImageInfo; | ||||||
| import com.jme3.math.FastMath; | import com.jme3.math.FastMath; | ||||||
| import com.jme3.texture.Image; | import com.jme3.texture.Image; | ||||||
| import com.jme3.texture.Image.Format; |  | ||||||
| import java.nio.ByteBuffer; | import java.nio.ByteBuffer; | ||||||
| import javax.microedition.khronos.opengles.GL10; | import javax.microedition.khronos.opengles.GL10; | ||||||
| 
 | 
 | ||||||
| public class TextureUtil { | public class TextureUtil { | ||||||
| 
 | 
 | ||||||
|     public static int convertTextureFormat(Format fmt){ |  | ||||||
|         switch (fmt){ |  | ||||||
|             case Alpha16: |  | ||||||
|             case Alpha8: |  | ||||||
|                 return GL10.GL_ALPHA; |  | ||||||
|             case Luminance8Alpha8: |  | ||||||
|             case Luminance16Alpha16: |  | ||||||
|                 return GL10.GL_LUMINANCE_ALPHA; |  | ||||||
|             case Luminance8: |  | ||||||
|             case Luminance16: |  | ||||||
|                 return GL10.GL_LUMINANCE; |  | ||||||
|             case RGB10: |  | ||||||
|             case RGB16: |  | ||||||
|             case BGR8: |  | ||||||
|             case RGB8: |  | ||||||
|             case RGB565: |  | ||||||
|                 return GL10.GL_RGB; |  | ||||||
|             case RGB5A1: |  | ||||||
|             case RGBA16: |  | ||||||
|             case RGBA8: |  | ||||||
|                 return GL10.GL_RGBA; |  | ||||||
|                  |  | ||||||
|             case Depth: |  | ||||||
|                 return GLES20.GL_DEPTH_COMPONENT; |  | ||||||
|             case Depth16: |  | ||||||
|                 return GLES20.GL_DEPTH_COMPONENT16; |  | ||||||
|             case Depth24: |  | ||||||
|             case Depth32: |  | ||||||
|             case Depth32F: |  | ||||||
|                 throw new UnsupportedOperationException("Unsupported depth format: " + fmt);    |  | ||||||
|                  |  | ||||||
|             case DXT1A: |  | ||||||
|                 throw new UnsupportedOperationException("Unsupported format: " + fmt); |  | ||||||
|             default: |  | ||||||
|                 throw new UnsupportedOperationException("Unrecognized format: " + fmt); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private static void buildMipmap(Bitmap bitmap) { |     private static void buildMipmap(Bitmap bitmap) { | ||||||
|         int level = 0; |         int level = 0; | ||||||
|         int height = bitmap.getHeight(); |         int height = bitmap.getHeight(); | ||||||
| @ -77,21 +38,17 @@ public class TextureUtil { | |||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * <code>uploadTextureBitmap</code> uploads a native android bitmap |      * <code>uploadTextureBitmap</code> uploads a native android bitmap | ||||||
|      * @param target |  | ||||||
|      * @param bitmap |  | ||||||
|      * @param generateMips |  | ||||||
|      * @param powerOf2 |  | ||||||
|      */ |      */ | ||||||
|     public static void uploadTextureBitmap(final int target, Bitmap bitmap, boolean generateMips, boolean powerOf2) |     public static void uploadTextureBitmap(final int target, Bitmap bitmap, boolean generateMips, boolean powerOf2) { | ||||||
|     { |         if (!powerOf2) { | ||||||
|         if (!powerOf2) |             // Power of 2 images are not supported by this GPU.  | ||||||
|         { |  | ||||||
|             int width = bitmap.getWidth(); |             int width = bitmap.getWidth(); | ||||||
|             int height = bitmap.getHeight(); |             int height = bitmap.getHeight(); | ||||||
|             if (!FastMath.isPowerOfTwo(width) || !FastMath.isPowerOfTwo(height)) |              | ||||||
|             { |             // If the image is not power of 2, rescale it | ||||||
|                 // scale to power of two |             if (!FastMath.isPowerOfTwo(width) || !FastMath.isPowerOfTwo(height)) { | ||||||
|                 width = FastMath.nearestPowerOfTwo(width); |                 // scale to power of two, then recycle the old image. | ||||||
|  |                 width  = FastMath.nearestPowerOfTwo(width); | ||||||
|                 height = FastMath.nearestPowerOfTwo(height); |                 height = FastMath.nearestPowerOfTwo(height); | ||||||
|                 Bitmap bitmap2 = Bitmap.createScaledBitmap(bitmap, width, height, true); |                 Bitmap bitmap2 = Bitmap.createScaledBitmap(bitmap, width, height, true); | ||||||
|                 bitmap.recycle(); |                 bitmap.recycle(); | ||||||
| @ -99,19 +56,15 @@ public class TextureUtil { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (generateMips) |         if (generateMips) { | ||||||
|         { |  | ||||||
|             buildMipmap(bitmap); |             buildMipmap(bitmap); | ||||||
|         } |         } else { | ||||||
|         else |  | ||||||
|         { |  | ||||||
|             GLUtils.texImage2D(target, 0, bitmap, 0); |             GLUtils.texImage2D(target, 0, bitmap, 0); | ||||||
|             //bitmap.recycle(); |             //bitmap.recycle(); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static void uploadTexture( |     public static void uploadTexture(Image img, | ||||||
|                                      Image img, |  | ||||||
|                                      int target, |                                      int target, | ||||||
|                                      int index, |                                      int index, | ||||||
|                                      int border, |                                      int border, | ||||||
| @ -128,7 +81,6 @@ public class TextureUtil { | |||||||
| 
 | 
 | ||||||
|         // Otherwise upload image directly.  |         // Otherwise upload image directly.  | ||||||
|         // Prefer to only use power of 2 textures here to avoid errors. |         // Prefer to only use power of 2 textures here to avoid errors. | ||||||
|          |  | ||||||
|         Image.Format fmt = img.getFormat(); |         Image.Format fmt = img.getFormat(); | ||||||
|         ByteBuffer data; |         ByteBuffer data; | ||||||
|         if (index >= 0 || img.getData() != null && img.getData().size() > 0){ |         if (index >= 0 || img.getData() != null && img.getData().size() > 0){ | ||||||
| @ -142,12 +94,20 @@ public class TextureUtil { | |||||||
|         int depth = img.getDepth(); |         int depth = img.getDepth(); | ||||||
| 
 | 
 | ||||||
|         boolean compress = false; |         boolean compress = false; | ||||||
|         int internalFormat = -1; |  | ||||||
|         int format = -1; |         int format = -1; | ||||||
|         int dataType = -1; |         int dataType = -1; | ||||||
| 
 | 
 | ||||||
|         switch (fmt){ |         switch (fmt){ | ||||||
|  |             case RGBA16: | ||||||
|  |             case RGB16: | ||||||
|  |             case RGB10: | ||||||
|  |             case Luminance16: | ||||||
|  |             case Luminance16Alpha16: | ||||||
|             case Alpha16: |             case Alpha16: | ||||||
|  |             case Depth32: | ||||||
|  |             case Depth32F: | ||||||
|  |                 throw new UnsupportedOperationException("The image format '"  | ||||||
|  |                         + fmt + "' is not supported by OpenGL ES 2.0 specification."); | ||||||
|             case Alpha8: |             case Alpha8: | ||||||
|                 format = GLES20.GL_ALPHA; |                 format = GLES20.GL_ALPHA; | ||||||
|                 dataType = GLES20.GL_UNSIGNED_BYTE;                 |                 dataType = GLES20.GL_UNSIGNED_BYTE;                 | ||||||
| @ -160,34 +120,16 @@ public class TextureUtil { | |||||||
|                 format = GLES20.GL_LUMINANCE_ALPHA; |                 format = GLES20.GL_LUMINANCE_ALPHA; | ||||||
|                 dataType = GLES20.GL_UNSIGNED_BYTE; |                 dataType = GLES20.GL_UNSIGNED_BYTE; | ||||||
|                 break; |                 break; | ||||||
|             case Luminance16Alpha16: |  | ||||||
|                 format = GLES20.GL_LUMINANCE_ALPHA; |  | ||||||
|                 dataType = GLES20.GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case Luminance16: |  | ||||||
|                 format = GLES20.GL_LUMINANCE; |  | ||||||
|                 dataType = GLES20.GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case RGB565: |             case RGB565: | ||||||
|                 format = GLES20.GL_RGB; |                 format = GLES20.GL_RGB; | ||||||
|                 internalFormat = GLES20.GL_RGB565; |  | ||||||
|                 dataType = GLES20.GL_UNSIGNED_SHORT_5_6_5; |                 dataType = GLES20.GL_UNSIGNED_SHORT_5_6_5; | ||||||
|                 break; |                 break; | ||||||
|             case ARGB4444: |             case ARGB4444: | ||||||
|                 format = GLES20.GL_RGBA; |                 format = GLES20.GL_RGBA4; | ||||||
|                 dataType = GLES20.GL_UNSIGNED_SHORT_4_4_4_4; |                 dataType = GLES20.GL_UNSIGNED_SHORT_4_4_4_4; | ||||||
|                 break; |                 break; | ||||||
|             case RGB10: |  | ||||||
|                 format = GLES20.GL_RGB; |  | ||||||
|                 dataType = GLES20.GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case RGB16: |  | ||||||
|                 format = GLES20.GL_RGB; |  | ||||||
|                 dataType = GLES20.GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case RGB5A1: |             case RGB5A1: | ||||||
|                 format = GLES20.GL_RGBA; |                 format = GLES20.GL_RGBA; | ||||||
|                 internalFormat = GLES20.GL_RGB5_A1; |  | ||||||
|                 dataType = GLES20.GL_UNSIGNED_SHORT_5_5_5_1; |                 dataType = GLES20.GL_UNSIGNED_SHORT_5_5_5_1; | ||||||
|                 break; |                 break; | ||||||
|             case RGB8: |             case RGB8: | ||||||
| @ -198,42 +140,23 @@ public class TextureUtil { | |||||||
|                 format = GLES20.GL_RGB; |                 format = GLES20.GL_RGB; | ||||||
|                 dataType = GLES20.GL_UNSIGNED_BYTE; |                 dataType = GLES20.GL_UNSIGNED_BYTE; | ||||||
|                 break; |                 break; | ||||||
|             case RGBA16: |  | ||||||
|                 format = GLES20.GL_RGBA; |  | ||||||
|                 internalFormat = GLES20.GL_RGBA4; |  | ||||||
|                 dataType = GLES20.GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case RGBA8: |             case RGBA8: | ||||||
|                 format = GLES20.GL_RGBA;                 |                 format = GLES20.GL_RGBA;                 | ||||||
|                 dataType = GLES20.GL_UNSIGNED_BYTE; |                 dataType = GLES20.GL_UNSIGNED_BYTE; | ||||||
|                 break; |                 break; | ||||||
|             case DXT1A: |  | ||||||
|                 format = GLES20.GL_COMPRESSED_TEXTURE_FORMATS; |  | ||||||
|                 dataType = GLES20.GL_UNSIGNED_BYTE; |  | ||||||
|             case Depth: |             case Depth: | ||||||
|                 format = GLES20.GL_DEPTH_COMPONENT; |  | ||||||
|                 dataType = GLES20.GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case Depth16: |             case Depth16: | ||||||
|  |             case Depth24: | ||||||
|                 format = GLES20.GL_DEPTH_COMPONENT; |                 format = GLES20.GL_DEPTH_COMPONENT; | ||||||
|                 internalFormat = GLES20.GL_DEPTH_COMPONENT16; |  | ||||||
|                 dataType = GLES20.GL_UNSIGNED_BYTE; |                 dataType = GLES20.GL_UNSIGNED_BYTE; | ||||||
|                 break; |                 break; | ||||||
|             case Depth24: |  | ||||||
|             case Depth32: |  | ||||||
|             case Depth32F: |  | ||||||
|                 throw new UnsupportedOperationException("Unsupported depth format: " + fmt);                 |  | ||||||
|             default: |             default: | ||||||
|                 throw new UnsupportedOperationException("Unrecognized format: " + fmt); |                 throw new UnsupportedOperationException("Unrecognized format: " + fmt); | ||||||
|         } |         } | ||||||
|          |  | ||||||
|         if (internalFormat == -1) |  | ||||||
|         { |  | ||||||
|             internalFormat = format; |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         if (data != null) |         if (data != null) { | ||||||
|             GLES20.glPixelStorei(GLES20.GL_UNPACK_ALIGNMENT, 1); |             GLES20.glPixelStorei(GLES20.GL_UNPACK_ALIGNMENT, 1); | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         int[] mipSizes = img.getMipMapSizes(); |         int[] mipSizes = img.getMipMapSizes(); | ||||||
|         int pos = 0; |         int pos = 0; | ||||||
| @ -246,9 +169,10 @@ public class TextureUtil { | |||||||
| 
 | 
 | ||||||
|         // XXX: might want to change that when support |         // XXX: might want to change that when support | ||||||
|         // of more than paletted compressions is added.. |         // of more than paletted compressions is added.. | ||||||
|  |         /// NOTE: Doesn't support mipmaps | ||||||
|         if (compress){ |         if (compress){ | ||||||
|             data.clear(); |             data.clear(); | ||||||
|             GLES20.glCompressedTexImage2D(GLES20.GL_TEXTURE_2D, |             GLES20.glCompressedTexImage2D(target, | ||||||
|                                       1 - mipSizes.length, |                                       1 - mipSizes.length, | ||||||
|                                       format, |                                       format, | ||||||
|                                       width, |                                       width, | ||||||
| @ -262,7 +186,7 @@ public class TextureUtil { | |||||||
|         for (int i = 0; i < mipSizes.length; i++){ |         for (int i = 0; i < mipSizes.length; i++){ | ||||||
|             int mipWidth =  Math.max(1, width  >> i); |             int mipWidth =  Math.max(1, width  >> i); | ||||||
|             int mipHeight = Math.max(1, height >> i); |             int mipHeight = Math.max(1, height >> i); | ||||||
|             int mipDepth =  Math.max(1, depth  >> i); | //            int mipDepth =  Math.max(1, depth  >> i); | ||||||
| 
 | 
 | ||||||
|             if (data != null){ |             if (data != null){ | ||||||
|                 data.position(pos); |                 data.position(pos); | ||||||
| @ -270,7 +194,7 @@ public class TextureUtil { | |||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if (compress && data != null){ |             if (compress && data != null){ | ||||||
|                 GLES20.glCompressedTexImage2D(GLES20.GL_TEXTURE_2D, |                 GLES20.glCompressedTexImage2D(target, | ||||||
|                                           i, |                                           i, | ||||||
|                                           format, |                                           format, | ||||||
|                                           mipWidth, |                                           mipWidth, | ||||||
| @ -279,9 +203,9 @@ public class TextureUtil { | |||||||
|                                           data.remaining(), |                                           data.remaining(), | ||||||
|                                           data); |                                           data); | ||||||
|             }else{ |             }else{ | ||||||
|                 GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, |                 GLES20.glTexImage2D(target, | ||||||
|                                 i, |                                 i, | ||||||
|                                 internalFormat, |                                 format, | ||||||
|                                 mipWidth, |                                 mipWidth, | ||||||
|                                 mipHeight, |                                 mipHeight, | ||||||
|                                 0, |                                 0, | ||||||
|  | |||||||
| @ -738,7 +738,6 @@ public class LwjglGL1Renderer implements GL1Renderer { | |||||||
| 
 | 
 | ||||||
|                     // Resize texture to Power-of-2 size |                     // Resize texture to Power-of-2 size | ||||||
|                     MipMapGenerator.resizeToPowerOf2(img); |                     MipMapGenerator.resizeToPowerOf2(img); | ||||||
| 
 |  | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| @ -777,7 +776,7 @@ public class LwjglGL1Renderer implements GL1Renderer { | |||||||
|         TextureUtil.uploadTexture(img, target, i, 0, tdc); |         TextureUtil.uploadTexture(img, target, i, 0, tdc); | ||||||
|         } |         } | ||||||
|         } else {*/ |         } else {*/ | ||||||
|         TextureUtil.uploadTexture(img, target, 0, 0, false); |         TextureUtil.uploadTexture(img, target, 0, 0); | ||||||
|         //} |         //} | ||||||
| 
 | 
 | ||||||
|         img.clearUpdateNeeded(); |         img.clearUpdateNeeded(); | ||||||
| @ -1052,15 +1051,12 @@ public class LwjglGL1Renderer implements GL1Renderer { | |||||||
|             updateBufferData(interleavedData); |             updateBufferData(interleavedData); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         IntMap<VertexBuffer> buffers = mesh.getBuffers(); |  | ||||||
|         if (mesh.getNumLodLevels() > 0) { |         if (mesh.getNumLodLevels() > 0) { | ||||||
|             indices = mesh.getLodLevel(lod); |             indices = mesh.getLodLevel(lod); | ||||||
|         } else { |         } else { | ||||||
|             indices = buffers.get(Type.Index.ordinal()); |             indices = mesh.getBuffer(Type.Index); | ||||||
|         } |         } | ||||||
|         for (Entry<VertexBuffer> entry : buffers) { |         for (VertexBuffer vb : mesh.getBufferList().getArray()) { | ||||||
|             VertexBuffer vb = entry.getValue(); |  | ||||||
| 
 |  | ||||||
|             if (vb.getBufferType() == Type.InterleavedData |             if (vb.getBufferType() == Type.InterleavedData | ||||||
|                     || vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers |                     || vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers | ||||||
|                     || vb.getBufferType() == Type.Index) { |                     || vb.getBufferType() == Type.Index) { | ||||||
| @ -1108,9 +1104,8 @@ public class LwjglGL1Renderer implements GL1Renderer { | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (mesh.getNumLodLevels() == 0) { |         if (mesh.getNumLodLevels() == 0) { | ||||||
|             IntMap<VertexBuffer> bufs = mesh.getBuffers(); |             for (VertexBuffer vb : mesh.getBufferList().getArray()) { | ||||||
|             for (Entry<VertexBuffer> entry : bufs) { |                 if (vb.getUsage() != VertexBuffer.Usage.Static) { | ||||||
|                 if (entry.getValue().getUsage() != VertexBuffer.Usage.Static) { |  | ||||||
|                     dynamic = true; |                     dynamic = true; | ||||||
|                     break; |                     break; | ||||||
|                 } |                 } | ||||||
|  | |||||||
| @ -53,12 +53,8 @@ import com.jme3.texture.FrameBuffer.RenderBuffer; | |||||||
| import com.jme3.texture.Image; | import com.jme3.texture.Image; | ||||||
| import com.jme3.texture.Texture; | import com.jme3.texture.Texture; | ||||||
| import com.jme3.texture.Texture.WrapAxis; | import com.jme3.texture.Texture.WrapAxis; | ||||||
| import com.jme3.util.BufferUtils; |  | ||||||
| import com.jme3.util.IntMap; |  | ||||||
| import com.jme3.util.IntMap.Entry; | import com.jme3.util.IntMap.Entry; | ||||||
| import com.jme3.util.ListMap; | import com.jme3.util.*; | ||||||
| import com.jme3.util.NativeObjectManager; |  | ||||||
| import com.jme3.util.SafeArrayList; |  | ||||||
| import java.nio.*; | import java.nio.*; | ||||||
| import java.util.EnumSet; | import java.util.EnumSet; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| @ -109,7 +105,6 @@ public class LwjglRenderer implements Renderer { | |||||||
|     private int maxTriCount; |     private int maxTriCount; | ||||||
|     private int maxColorTexSamples; |     private int maxColorTexSamples; | ||||||
|     private int maxDepthTexSamples; |     private int maxDepthTexSamples; | ||||||
|     private boolean tdc; |  | ||||||
|     private FrameBuffer lastFb = null; |     private FrameBuffer lastFb = null; | ||||||
|     private FrameBuffer mainFbOverride = null; |     private FrameBuffer mainFbOverride = null; | ||||||
|     private final Statistics statistics = new Statistics(); |     private final Statistics statistics = new Statistics(); | ||||||
| @ -272,6 +267,10 @@ public class LwjglRenderer implements Renderer { | |||||||
|         if (ctxCaps.GL_ARB_depth_buffer_float) { |         if (ctxCaps.GL_ARB_depth_buffer_float) { | ||||||
|             caps.add(Caps.FloatDepthBuffer); |             caps.add(Caps.FloatDepthBuffer); | ||||||
|         } |         } | ||||||
|  |          | ||||||
|  |         if (ctxCaps.OpenGL30){ | ||||||
|  |             caps.add(Caps.PackedDepthStencilBuffer); | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         if (ctxCaps.GL_ARB_draw_instanced) { |         if (ctxCaps.GL_ARB_draw_instanced) { | ||||||
|             caps.add(Caps.MeshInstancing); |             caps.add(Caps.MeshInstancing); | ||||||
| @ -304,12 +303,8 @@ public class LwjglRenderer implements Renderer { | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         boolean latc = ctxCaps.GL_EXT_texture_compression_latc; |         boolean latc = ctxCaps.GL_EXT_texture_compression_latc; | ||||||
|         boolean atdc = ctxCaps.GL_ATI_texture_compression_3dc; |         if (latc) { | ||||||
|         if (latc || atdc) { |  | ||||||
|             caps.add(Caps.TextureCompressionLATC); |             caps.add(Caps.TextureCompressionLATC); | ||||||
|             if (atdc && !latc) { |  | ||||||
|                 tdc = true; |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (ctxCaps.GL_EXT_packed_float) { |         if (ctxCaps.GL_EXT_packed_float) { | ||||||
| @ -454,10 +449,12 @@ public class LwjglRenderer implements Renderer { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public void setAlphaToCoverage(boolean value) { |     public void setAlphaToCoverage(boolean value) { | ||||||
|         if (value) { |         if (caps.contains(Caps.Multisample)){ | ||||||
|             glEnable(ARBMultisample.GL_SAMPLE_ALPHA_TO_COVERAGE_ARB); |             if (value) { | ||||||
|         } else { |                 glEnable(ARBMultisample.GL_SAMPLE_ALPHA_TO_COVERAGE_ARB); | ||||||
|             glDisable(ARBMultisample.GL_SAMPLE_ALPHA_TO_COVERAGE_ARB); |             } else { | ||||||
|  |                 glDisable(ARBMultisample.GL_SAMPLE_ALPHA_TO_COVERAGE_ARB); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -1270,7 +1267,7 @@ public class LwjglRenderer implements Renderer { | |||||||
|         switch (type) { |         switch (type) { | ||||||
|             case GL_NONE: |             case GL_NONE: | ||||||
|                 System.out.println("Type: None"); |                 System.out.println("Type: None"); | ||||||
|                 return; // note: return from method as other queries will be invalid |                 break; | ||||||
|             case GL_TEXTURE: |             case GL_TEXTURE: | ||||||
|                 System.out.println("Type: Texture"); |                 System.out.println("Type: Texture"); | ||||||
|                 break; |                 break; | ||||||
| @ -1364,8 +1361,8 @@ public class LwjglRenderer implements Renderer { | |||||||
|                     + ":" + fb.getHeight() + " is not supported."); |                     + ":" + fb.getHeight() + " is not supported."); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         TextureUtil.checkFormatSupported(rb.getFormat()); |         TextureUtil.GLImageFormat glFmt = TextureUtil.getImageFormatWithError(rb.getFormat()); | ||||||
| 
 |          | ||||||
|         if (fb.getSamples() > 1 && GLContext.getCapabilities().GL_EXT_framebuffer_multisample) { |         if (fb.getSamples() > 1 && GLContext.getCapabilities().GL_EXT_framebuffer_multisample) { | ||||||
|             int samples = fb.getSamples(); |             int samples = fb.getSamples(); | ||||||
|             if (maxFBOSamples < samples) { |             if (maxFBOSamples < samples) { | ||||||
| @ -1373,12 +1370,12 @@ public class LwjglRenderer implements Renderer { | |||||||
|             } |             } | ||||||
|             glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, |             glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, | ||||||
|                     samples, |                     samples, | ||||||
|                     TextureUtil.convertTextureFormat(rb.getFormat()), |                     glFmt.internalFormat, | ||||||
|                     fb.getWidth(), |                     fb.getWidth(), | ||||||
|                     fb.getHeight()); |                     fb.getHeight()); | ||||||
|         } else { |         } else { | ||||||
|             glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, |             glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, | ||||||
|                     TextureUtil.convertTextureFormat(rb.getFormat()), |                     glFmt.internalFormat, | ||||||
|                     fb.getWidth(), |                     fb.getWidth(), | ||||||
|                     fb.getHeight()); |                     fb.getHeight()); | ||||||
|         } |         } | ||||||
| @ -1854,19 +1851,19 @@ public class LwjglRenderer implements Renderer { | |||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|             for (int i = 0; i < 6; i++) { |             for (int i = 0; i < 6; i++) { | ||||||
|                 TextureUtil.uploadTexture(img, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, i, 0, tdc); |                 TextureUtil.uploadTexture(img, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, i, 0); | ||||||
|             } |             } | ||||||
|         } else if (target == EXTTextureArray.GL_TEXTURE_2D_ARRAY_EXT) { |         } else if (target == EXTTextureArray.GL_TEXTURE_2D_ARRAY_EXT) { | ||||||
|             List<ByteBuffer> data = img.getData(); |             List<ByteBuffer> data = img.getData(); | ||||||
|             // -1 index specifies prepare data for 2D Array |             // -1 index specifies prepare data for 2D Array | ||||||
|             TextureUtil.uploadTexture(img, target, -1, 0, tdc); |             TextureUtil.uploadTexture(img, target, -1, 0); | ||||||
|             for (int i = 0; i < data.size(); i++) { |             for (int i = 0; i < data.size(); i++) { | ||||||
|                 // upload each slice of 2D array in turn |                 // upload each slice of 2D array in turn | ||||||
|                 // this time with the appropriate index |                 // this time with the appropriate index | ||||||
|                 TextureUtil.uploadTexture(img, target, i, 0, tdc); |                 TextureUtil.uploadTexture(img, target, i, 0); | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             TextureUtil.uploadTexture(img, target, 0, 0, tdc); |             TextureUtil.uploadTexture(img, target, 0, 0); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (img.getMultiSamples() != imageSamples) { |         if (img.getMultiSamples() != imageSamples) { | ||||||
| @ -1978,8 +1975,8 @@ public class LwjglRenderer implements Renderer { | |||||||
|                 return GL_INT; |                 return GL_INT; | ||||||
|             case UnsignedInt: |             case UnsignedInt: | ||||||
|                 return GL_UNSIGNED_INT; |                 return GL_UNSIGNED_INT; | ||||||
|             case Half: | //            case Half: | ||||||
|                 return NVHalfFloat.GL_HALF_FLOAT_NV; | //                return NVHalfFloat.GL_HALF_FLOAT_NV; | ||||||
| //                return ARBHalfFloatVertex.GL_HALF_FLOAT; | //                return ARBHalfFloatVertex.GL_HALF_FLOAT; | ||||||
|             case Float: |             case Float: | ||||||
|                 return GL_FLOAT; |                 return GL_FLOAT; | ||||||
| @ -2343,10 +2340,7 @@ public class LwjglRenderer implements Renderer { | |||||||
|             updateBufferData(interleavedData); |             updateBufferData(interleavedData); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         IntMap<VertexBuffer> buffers = mesh.getBuffers(); |         for (VertexBuffer vb : mesh.getBufferList().getArray()) { | ||||||
|         for (Entry<VertexBuffer> entry : buffers) { |  | ||||||
|             VertexBuffer vb = entry.getValue(); |  | ||||||
| 
 |  | ||||||
|             if (vb.getBufferType() == Type.InterleavedData |             if (vb.getBufferType() == Type.InterleavedData | ||||||
|                     || vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers |                     || vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers | ||||||
|                     || vb.getBufferType() == Type.Index) { |                     || vb.getBufferType() == Type.Index) { | ||||||
| @ -2376,7 +2370,7 @@ public class LwjglRenderer implements Renderer { | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| //        IntMap<VertexBuffer> buffers = mesh.getBuffers(); | //        IntMap<VertexBuffer> buffers = mesh.getBuffers(); | ||||||
|         VertexBuffer indices = null; |         VertexBuffer indices; | ||||||
|         if (mesh.getNumLodLevels() > 0) { |         if (mesh.getNumLodLevels() > 0) { | ||||||
|             indices = mesh.getLodLevel(lod); |             indices = mesh.getLodLevel(lod); | ||||||
|         } else { |         } else { | ||||||
|  | |||||||
| @ -36,369 +36,192 @@ import com.jme3.renderer.RendererException; | |||||||
| import com.jme3.texture.Image; | import com.jme3.texture.Image; | ||||||
| import com.jme3.texture.Image.Format; | import com.jme3.texture.Image.Format; | ||||||
| import java.nio.ByteBuffer; | import java.nio.ByteBuffer; | ||||||
| import static org.lwjgl.opengl.ATITextureCompression3DC.GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI; |  | ||||||
| import static org.lwjgl.opengl.EXTTextureCompressionLATC.GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT; |  | ||||||
| import static org.lwjgl.opengl.EXTTextureCompressionLATC.GL_COMPRESSED_LUMINANCE_LATC1_EXT; |  | ||||||
| import static org.lwjgl.opengl.EXTTextureCompressionS3TC.*; |  | ||||||
| import static org.lwjgl.opengl.GL11.*; |  | ||||||
| import static org.lwjgl.opengl.GL12.*; |  | ||||||
| import static org.lwjgl.opengl.GL13.glCompressedTexImage2D; |  | ||||||
| import static org.lwjgl.opengl.GL13.glCompressedTexImage3D; |  | ||||||
| import static org.lwjgl.opengl.GL14.*; |  | ||||||
| import org.lwjgl.opengl.*; | import org.lwjgl.opengl.*; | ||||||
| 
 | 
 | ||||||
| public class TextureUtil { | class TextureUtil { | ||||||
| 
 | 
 | ||||||
|     private static boolean isFormatSupported(Format fmt, ContextCapabilities caps){ |     static class GLImageFormat { | ||||||
|  |          | ||||||
|  |         int internalFormat; | ||||||
|  |         int format; | ||||||
|  |         int dataType; | ||||||
|  |         boolean compressed; | ||||||
|  | 
 | ||||||
|  |         public GLImageFormat(int internalFormat, int format, int dataType, boolean compressed) { | ||||||
|  |             this.internalFormat = internalFormat; | ||||||
|  |             this.format = format; | ||||||
|  |             this.dataType = dataType; | ||||||
|  |             this.compressed = compressed; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     private static final GLImageFormat[] formatToGL = new GLImageFormat[Format.values().length]; | ||||||
|  |      | ||||||
|  |     private static void setFormat(Format format, int glInternalFormat, int glFormat, int glDataType, boolean glCompressed){ | ||||||
|  |         formatToGL[format.ordinal()] = new GLImageFormat(glInternalFormat, glFormat, glDataType, glCompressed); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     static { | ||||||
|  |         // Alpha formats | ||||||
|  |         setFormat(Format.Alpha8,  GL11.GL_ALPHA8,  GL11.GL_ALPHA, GL11.GL_UNSIGNED_BYTE, false); | ||||||
|  |         setFormat(Format.Alpha16, GL11.GL_ALPHA16, GL11.GL_ALPHA, GL11.GL_UNSIGNED_BYTE, false); | ||||||
|  |          | ||||||
|  |         // Luminance formats | ||||||
|  |         setFormat(Format.Luminance8,   GL11.GL_LUMINANCE8,  GL11.GL_LUMINANCE, GL11.GL_UNSIGNED_BYTE, false); | ||||||
|  |         setFormat(Format.Luminance16,  GL11.GL_LUMINANCE16, GL11.GL_LUMINANCE, GL11.GL_UNSIGNED_BYTE, false); | ||||||
|  |         setFormat(Format.Luminance16F, ARBTextureFloat.GL_LUMINANCE16F_ARB, GL11.GL_LUMINANCE, GL11.GL_UNSIGNED_BYTE, false); | ||||||
|  |         setFormat(Format.Luminance32F, ARBTextureFloat.GL_LUMINANCE32F_ARB, GL11.GL_LUMINANCE, GL11.GL_UNSIGNED_BYTE, false); | ||||||
|  |          | ||||||
|  |         // Luminance alpha formats | ||||||
|  |         setFormat(Format.Luminance8Alpha8, GL11.GL_LUMINANCE8_ALPHA8,  GL11.GL_LUMINANCE_ALPHA, GL11.GL_UNSIGNED_BYTE, false); | ||||||
|  |         setFormat(Format.Luminance16Alpha16, GL11.GL_LUMINANCE16_ALPHA16, GL11.GL_LUMINANCE_ALPHA, GL11.GL_UNSIGNED_BYTE, false); | ||||||
|  |         setFormat(Format.Luminance16FAlpha16F, ARBTextureFloat.GL_LUMINANCE_ALPHA16F_ARB, GL11.GL_LUMINANCE_ALPHA, GL11.GL_UNSIGNED_BYTE, false); | ||||||
|  |          | ||||||
|  |         // Depth formats | ||||||
|  |         setFormat(Format.Depth,    GL11.GL_DEPTH_COMPONENT,    GL11.GL_DEPTH_COMPONENT, GL11.GL_UNSIGNED_BYTE, false); | ||||||
|  |         setFormat(Format.Depth16,  GL14.GL_DEPTH_COMPONENT16,  GL11.GL_DEPTH_COMPONENT, GL11.GL_UNSIGNED_BYTE, false); | ||||||
|  |         setFormat(Format.Depth24,  GL14.GL_DEPTH_COMPONENT24,  GL11.GL_DEPTH_COMPONENT, GL11.GL_UNSIGNED_BYTE, false); | ||||||
|  |         setFormat(Format.Depth32,  GL14.GL_DEPTH_COMPONENT32,  GL11.GL_DEPTH_COMPONENT, GL11.GL_UNSIGNED_BYTE, false); | ||||||
|  |         setFormat(Format.Depth32F, GL30.GL_DEPTH_COMPONENT32F, GL11.GL_DEPTH_COMPONENT, GL11.GL_FLOAT,         false); | ||||||
|  |          | ||||||
|  |         // Depth stencil formats | ||||||
|  |         setFormat(Format.Depth24Stencil8, GL30.GL_DEPTH24_STENCIL8, GL11.GL_DEPTH_COMPONENT, GL30.GL_UNSIGNED_INT_24_8, false); | ||||||
|  |          | ||||||
|  |         // RGB formats | ||||||
|  |         setFormat(Format.BGR8,       GL11.GL_RGB8,  EXTBgra.GL_BGR_EXT, GL11.GL_UNSIGNED_BYTE, false); | ||||||
|  |         setFormat(Format.RGB8,       GL11.GL_RGB8,  GL11.GL_RGB,        GL11.GL_UNSIGNED_BYTE, false); | ||||||
|  |         setFormat(Format.RGB10,      GL11.GL_RGB10, GL11.GL_RGB,        GL12.GL_UNSIGNED_INT_10_10_10_2, false);  | ||||||
|  |         setFormat(Format.RGB16,      GL11.GL_RGB16, GL11.GL_RGB,        GL11.GL_UNSIGNED_BYTE, false); // might be incorrect | ||||||
|  |         setFormat(Format.RGB16F,     ARBTextureFloat.GL_RGB16F_ARB, GL11.GL_RGB, ARBHalfFloatPixel.GL_HALF_FLOAT_ARB, false); | ||||||
|  |         setFormat(Format.RGB32F,     ARBTextureFloat.GL_RGB32F_ARB, GL11.GL_RGB, GL11.GL_FLOAT, false); | ||||||
|  |          | ||||||
|  |         // Special RGB formats | ||||||
|  |         setFormat(Format.RGB111110F, EXTPackedFloat.GL_R11F_G11F_B10F_EXT,    GL11.GL_RGB, EXTPackedFloat.GL_UNSIGNED_INT_10F_11F_11F_REV_EXT, false); | ||||||
|  |         setFormat(Format.RGB9E5,     EXTTextureSharedExponent.GL_RGB9_E5_EXT, GL11.GL_RGB, EXTTextureSharedExponent.GL_UNSIGNED_INT_5_9_9_9_REV_EXT, false); | ||||||
|  |         setFormat(Format.RGB16F_to_RGB111110F, EXTPackedFloat.GL_R11F_G11F_B10F_EXT,    GL11.GL_RGB, ARBHalfFloatPixel.GL_HALF_FLOAT_ARB, false); | ||||||
|  |         setFormat(Format.RGB16F_to_RGB111110F, EXTTextureSharedExponent.GL_RGB9_E5_EXT, GL11.GL_RGB, ARBHalfFloatPixel.GL_HALF_FLOAT_ARB, false); | ||||||
|  |          | ||||||
|  |         // RGBA formats | ||||||
|  |         setFormat(Format.ABGR8,   GL11.GL_RGBA8,       EXTAbgr.GL_ABGR_EXT, GL11.GL_UNSIGNED_BYTE, false); | ||||||
|  |         setFormat(Format.RGB5A1,  GL11.GL_RGB5_A1,     GL11.GL_RGBA,        GL12.GL_UNSIGNED_SHORT_5_5_5_1, false); | ||||||
|  |         setFormat(Format.RGBA8,   GL11.GL_RGBA8,       GL11.GL_RGBA,        GL11.GL_UNSIGNED_BYTE, false); | ||||||
|  |         setFormat(Format.RGBA16,  GL11.GL_RGBA16,      GL11.GL_RGBA,        GL11.GL_UNSIGNED_BYTE, false); // might be incorrect | ||||||
|  |         setFormat(Format.RGBA16F, ARBTextureFloat.GL_RGBA16F_ARB, GL11.GL_RGBA, ARBHalfFloatPixel.GL_HALF_FLOAT_ARB, false); | ||||||
|  |         setFormat(Format.RGBA32F, ARBTextureFloat.GL_RGBA32F_ARB, GL11.GL_RGBA, GL11.GL_FLOAT, false); | ||||||
|  |          | ||||||
|  |         // DXT formats | ||||||
|  |         setFormat(Format.DXT1,  EXTTextureCompressionS3TC.GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL11.GL_RGB,   GL11.GL_UNSIGNED_BYTE, true); | ||||||
|  |         setFormat(Format.DXT1A, EXTTextureCompressionS3TC.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, true); | ||||||
|  |         setFormat(Format.DXT3,  EXTTextureCompressionS3TC.GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, true); | ||||||
|  |         setFormat(Format.DXT5,  EXTTextureCompressionS3TC.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, true); | ||||||
|  |      | ||||||
|  |         // LTC/LATC/3Dc formats | ||||||
|  |         setFormat(Format.LTC,  EXTTextureCompressionLATC.GL_COMPRESSED_LUMINANCE_LATC1_EXT,       GL11.GL_LUMINANCE,       GL11.GL_UNSIGNED_BYTE, true); | ||||||
|  |         setFormat(Format.LATC, EXTTextureCompressionLATC.GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT, GL11.GL_LUMINANCE_ALPHA, GL11.GL_UNSIGNED_BYTE, true); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     public static GLImageFormat getImageFormat(ContextCapabilities caps, Format fmt){ | ||||||
|         switch (fmt){ |         switch (fmt){ | ||||||
|             case ARGB4444: |             case ABGR8: | ||||||
|                 return false; |                 if (!caps.GL_EXT_abgr){ | ||||||
|  |                     return null; | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|             case BGR8: |             case BGR8: | ||||||
|                 return caps.OpenGL12 || caps.GL_EXT_bgra; |                 if (!caps.OpenGL12 && !caps.GL_EXT_bgra){ | ||||||
|  |                     return null; | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|             case DXT1: |             case DXT1: | ||||||
|             case DXT1A: |             case DXT1A: | ||||||
|             case DXT3: |             case DXT3: | ||||||
|             case DXT5: |             case DXT5: | ||||||
|                 return caps.GL_EXT_texture_compression_s3tc; |                 if (!caps.GL_EXT_texture_compression_s3tc) { | ||||||
|  |                     return null; | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|             case Depth: |             case Depth: | ||||||
|             case Depth16: |             case Depth16: | ||||||
|             case Depth24: |             case Depth24: | ||||||
|             case Depth32: |             case Depth32: | ||||||
|                 return caps.OpenGL14 || caps.GL_ARB_depth_texture; |                 if (!caps.OpenGL14 && !caps.GL_ARB_depth_texture){ | ||||||
|             case Depth32F: |                     return null; | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|             case Luminance16F: |             case Luminance16F: | ||||||
|             case Luminance16FAlpha16F: |             case Luminance16FAlpha16F: | ||||||
|             case Luminance32F: |             case Luminance32F: | ||||||
|  |                 if (!caps.GL_ARB_texture_float){ | ||||||
|  |                     return null; | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|  |             case RGB16F: | ||||||
|  |             case RGB32F: | ||||||
|             case RGBA16F: |             case RGBA16F: | ||||||
|             case RGBA32F: |             case RGBA32F: | ||||||
|                 return caps.OpenGL30 || caps.GL_ARB_texture_float; |                 if (!caps.OpenGL30 && !caps.GL_ARB_texture_float){ | ||||||
|  |                     return null; | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|  |             case Depth32F: | ||||||
|  |                 if (!caps.OpenGL30 && !caps.GL_NV_depth_buffer_float){ | ||||||
|  |                     return null; | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|             case LATC: |             case LATC: | ||||||
|             case LTC: |             case LTC: | ||||||
|                 return caps.GL_EXT_texture_compression_latc; |                 if (!caps.GL_EXT_texture_compression_latc){ | ||||||
|  |                     return null; | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|             case RGB9E5: |             case RGB9E5: | ||||||
|             case RGB16F_to_RGB9E5: |             case RGB16F_to_RGB9E5: | ||||||
|                 return caps.OpenGL30 || caps.GL_EXT_texture_shared_exponent; |                 if (!caps.OpenGL30 && !caps.GL_EXT_texture_shared_exponent){ | ||||||
|  |                     return null; | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|             case RGB111110F: |             case RGB111110F: | ||||||
|             case RGB16F_to_RGB111110F: |             case RGB16F_to_RGB111110F: | ||||||
|                 return caps.OpenGL30 || caps.GL_EXT_packed_float; |                 if (!caps.OpenGL30 && !caps.GL_EXT_packed_float){ | ||||||
|             default: |                     return null; | ||||||
|                 return true; |                 } | ||||||
|  |                 break; | ||||||
|         } |         } | ||||||
|  |         return formatToGL[fmt.ordinal()]; | ||||||
|     } |     } | ||||||
| 
 |      | ||||||
|     public static void checkFormatSupported(Format fmt) { |     public static GLImageFormat getImageFormatWithError(Format fmt) { | ||||||
|         if (!isFormatSupported(fmt, GLContext.getCapabilities())) { |         GLImageFormat glFmt = getImageFormat(GLContext.getCapabilities(), fmt); | ||||||
|  |         if (glFmt == null) { | ||||||
|             throw new RendererException("Image format '" + fmt + "' is unsupported by the video hardware."); |             throw new RendererException("Image format '" + fmt + "' is unsupported by the video hardware."); | ||||||
|         } |         } | ||||||
|  |         return glFmt; | ||||||
|     } |     } | ||||||
| 
 |      | ||||||
|     public static int convertTextureFormat(Format fmt){ |     public static void uploadTexture(Image image, | ||||||
|         switch (fmt){ |  | ||||||
|             case Alpha16: |  | ||||||
|                 return GL_ALPHA16; |  | ||||||
|             case Alpha8: |  | ||||||
|                 return GL_ALPHA8; |  | ||||||
|             case DXT1: |  | ||||||
|                 return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; |  | ||||||
|             case DXT1A: |  | ||||||
|                 return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; |  | ||||||
|             case DXT3: |  | ||||||
|                 return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; |  | ||||||
|             case DXT5: |  | ||||||
|                 return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; |  | ||||||
|             case LATC: |  | ||||||
|                 return GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT; |  | ||||||
|             case Depth: |  | ||||||
|                 return GL_DEPTH_COMPONENT; |  | ||||||
|             case Depth16: |  | ||||||
|                 return GL_DEPTH_COMPONENT16; |  | ||||||
|             case Depth24: |  | ||||||
|                 return GL_DEPTH_COMPONENT24; |  | ||||||
|             case Depth32: |  | ||||||
|                 return GL_DEPTH_COMPONENT32; |  | ||||||
|             case Depth32F: |  | ||||||
|                 return ARBDepthBufferFloat.GL_DEPTH_COMPONENT32F; |  | ||||||
|             case Luminance8Alpha8: |  | ||||||
|                 return GL_LUMINANCE8_ALPHA8; |  | ||||||
|             case Luminance16Alpha16: |  | ||||||
|                 return GL_LUMINANCE16_ALPHA16; |  | ||||||
|             case Luminance16FAlpha16F: |  | ||||||
|                 return ARBTextureFloat.GL_LUMINANCE_ALPHA16F_ARB; |  | ||||||
|             case Intensity8: |  | ||||||
|                 return GL_INTENSITY8; |  | ||||||
|             case Intensity16: |  | ||||||
|                 return GL_INTENSITY16; |  | ||||||
|             case Luminance8: |  | ||||||
|                 return GL_LUMINANCE8; |  | ||||||
|             case Luminance16: |  | ||||||
|                 return GL_LUMINANCE16; |  | ||||||
|             case Luminance16F: |  | ||||||
|                 return ARBTextureFloat.GL_LUMINANCE16F_ARB; |  | ||||||
|              case Luminance32F: |  | ||||||
|                 return ARBTextureFloat.GL_LUMINANCE32F_ARB; |  | ||||||
|             case RGB10: |  | ||||||
|                 return GL_RGB10; |  | ||||||
|             case RGB16: |  | ||||||
|                 return GL_RGB16; |  | ||||||
|             case RGB111110F: |  | ||||||
|                 return EXTPackedFloat.GL_R11F_G11F_B10F_EXT; |  | ||||||
|             case RGB9E5: |  | ||||||
|                 return EXTTextureSharedExponent.GL_RGB9_E5_EXT; |  | ||||||
|             case RGB16F: |  | ||||||
|                 return ARBTextureFloat.GL_RGB16F_ARB; |  | ||||||
|             case RGBA16F: |  | ||||||
|                 return ARBTextureFloat.GL_RGBA16F_ARB; |  | ||||||
|             case RGB32F: |  | ||||||
|                 return ARBTextureFloat.GL_RGB32F_ARB; |  | ||||||
|             case RGB5A1: |  | ||||||
|                 return GL_RGB5_A1; |  | ||||||
|             case BGR8: |  | ||||||
|                 return GL_RGB8; |  | ||||||
|             case RGB8: |  | ||||||
|                 return GL_RGB8; |  | ||||||
|             case RGBA16: |  | ||||||
|                 return GL_RGBA16; |  | ||||||
|             case RGBA8: |  | ||||||
|                 return GL_RGBA8; |  | ||||||
|             default: |  | ||||||
|                 throw new UnsupportedOperationException("Unrecognized format: "+fmt); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public static void uploadTexture(Image img, |  | ||||||
|                                      int target, |                                      int target, | ||||||
|                                      int index, |                                      int index, | ||||||
|                                      int border, |                                      int border){ | ||||||
|                                      boolean tdc){ |          | ||||||
|         Image.Format fmt = img.getFormat(); |         Image.Format fmt = image.getFormat(); | ||||||
| 
 |         GLImageFormat glFmt = getImageFormatWithError(fmt); | ||||||
|         checkFormatSupported(fmt); |  | ||||||
| 
 | 
 | ||||||
|         ByteBuffer data; |         ByteBuffer data; | ||||||
|         if (index >= 0 && img.getData() != null && img.getData().size() > 0){ |         if (index >= 0 && image.getData() != null && image.getData().size() > 0){ | ||||||
|             data = img.getData(index); |             data = image.getData(index); | ||||||
|         }else{ |         }else{ | ||||||
|             data = null; |             data = null; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         int width = img.getWidth(); |         int width = image.getWidth(); | ||||||
|         int height = img.getHeight(); |         int height = image.getHeight(); | ||||||
|         int depth = img.getDepth(); |         int depth = image.getDepth(); | ||||||
| 
 | 
 | ||||||
|         boolean compress = false; |         if (data != null) { | ||||||
|         int internalFormat = -1; |             GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1); | ||||||
|         int format = -1; |  | ||||||
|         int dataType = -1; |  | ||||||
| 
 |  | ||||||
|         switch (fmt){ |  | ||||||
|             case Alpha16: |  | ||||||
|                 internalFormat = GL_ALPHA16; |  | ||||||
|                 format = GL_ALPHA; |  | ||||||
|                 dataType = GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case Alpha8: |  | ||||||
|                 internalFormat = GL_ALPHA8; |  | ||||||
|                 format = GL_ALPHA; |  | ||||||
|                 dataType = GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case DXT1: |  | ||||||
|                 compress = true; |  | ||||||
|                 internalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; |  | ||||||
|                 format = GL_RGB; |  | ||||||
|                 dataType = GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case DXT1A: |  | ||||||
|                 compress = true; |  | ||||||
|                 internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; |  | ||||||
|                 format = GL_RGBA; |  | ||||||
|                 dataType = GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case DXT3: |  | ||||||
|                 compress = true; |  | ||||||
|                 internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; |  | ||||||
|                 format = GL_RGBA; |  | ||||||
|                 dataType = GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case DXT5: |  | ||||||
|                 compress = true; |  | ||||||
|                 internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; |  | ||||||
|                 format = GL_RGBA; |  | ||||||
|                 dataType = GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case LATC: |  | ||||||
|                 compress = true; |  | ||||||
|                 if (tdc){ |  | ||||||
|                     internalFormat = GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI; |  | ||||||
|                 }else{ |  | ||||||
|                     internalFormat = GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT; |  | ||||||
|                 } |  | ||||||
|                 format = GL_LUMINANCE_ALPHA; |  | ||||||
|                 dataType = GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case LTC: |  | ||||||
|                 compress = true; |  | ||||||
|                 internalFormat = GL_COMPRESSED_LUMINANCE_LATC1_EXT; |  | ||||||
|                 format = GL_LUMINANCE_ALPHA; |  | ||||||
|                 dataType = GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case Depth: |  | ||||||
|                 internalFormat = GL_DEPTH_COMPONENT; |  | ||||||
|                 format = GL_DEPTH_COMPONENT; |  | ||||||
|                 dataType = GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case Depth16: |  | ||||||
|                 internalFormat = GL_DEPTH_COMPONENT16; |  | ||||||
|                 format = GL_DEPTH_COMPONENT; |  | ||||||
|                 dataType = GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case Depth24: |  | ||||||
|                 internalFormat = GL_DEPTH_COMPONENT24; |  | ||||||
|                 format = GL_DEPTH_COMPONENT; |  | ||||||
|                 dataType = GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case Depth32: |  | ||||||
|                 internalFormat = GL_DEPTH_COMPONENT32; |  | ||||||
|                 format = GL_DEPTH_COMPONENT; |  | ||||||
|                 dataType = GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case Depth32F: |  | ||||||
|                 internalFormat = NVDepthBufferFloat.GL_DEPTH_COMPONENT32F_NV; |  | ||||||
|                 format = GL_DEPTH_COMPONENT; |  | ||||||
|                 dataType = GL_FLOAT; |  | ||||||
|                 break; |  | ||||||
|             case Luminance16FAlpha16F: |  | ||||||
|                 internalFormat = ARBTextureFloat.GL_LUMINANCE_ALPHA16F_ARB; |  | ||||||
|                 format = GL_LUMINANCE_ALPHA; |  | ||||||
|                 dataType = GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case Intensity8: |  | ||||||
|                 internalFormat = GL_INTENSITY8; |  | ||||||
|                 format = GL_INTENSITY; |  | ||||||
|                 dataType = GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case Intensity16: |  | ||||||
|                 internalFormat = GL_INTENSITY16; |  | ||||||
|                 format = GL_INTENSITY; |  | ||||||
|                 dataType = GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case Luminance8: |  | ||||||
|                 internalFormat = GL_LUMINANCE8; |  | ||||||
|                 format = GL_LUMINANCE; |  | ||||||
|                 dataType = GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case Luminance8Alpha8: |  | ||||||
|                 internalFormat = GL_LUMINANCE8_ALPHA8; |  | ||||||
|                 format = GL_LUMINANCE_ALPHA; |  | ||||||
|                 dataType = GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case Luminance16Alpha16: |  | ||||||
|                 internalFormat = GL_LUMINANCE16_ALPHA16; |  | ||||||
|                 format = GL_LUMINANCE_ALPHA; |  | ||||||
|                 dataType = GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case Luminance16: |  | ||||||
|                 internalFormat = GL_LUMINANCE16; |  | ||||||
|                 format = GL_LUMINANCE; |  | ||||||
|                 dataType = GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case Luminance16F: |  | ||||||
|                 internalFormat = ARBTextureFloat.GL_LUMINANCE16F_ARB; |  | ||||||
|                 format = GL_LUMINANCE; |  | ||||||
|                 dataType = ARBHalfFloatPixel.GL_HALF_FLOAT_ARB; |  | ||||||
|                 break; |  | ||||||
|             case Luminance32F: |  | ||||||
|                 internalFormat = ARBTextureFloat.GL_LUMINANCE32F_ARB; |  | ||||||
|                 format = GL_LUMINANCE; |  | ||||||
|                 dataType = GL_FLOAT; |  | ||||||
|                 break; |  | ||||||
|             case RGB10: |  | ||||||
|                 internalFormat = GL_RGB10; |  | ||||||
|                 format = GL_RGB; |  | ||||||
|                 dataType = GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case RGB16: |  | ||||||
|                 internalFormat = GL_RGB16; |  | ||||||
|                 format = GL_RGB; |  | ||||||
|                 dataType = GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case RGB111110F: |  | ||||||
|                 internalFormat = EXTPackedFloat.GL_R11F_G11F_B10F_EXT; |  | ||||||
|                 format = GL_RGB; |  | ||||||
|                 dataType = EXTPackedFloat.GL_UNSIGNED_INT_10F_11F_11F_REV_EXT; |  | ||||||
|                 break; |  | ||||||
|             case RGB16F_to_RGB111110F: |  | ||||||
|                 internalFormat = EXTPackedFloat.GL_R11F_G11F_B10F_EXT; |  | ||||||
|                 format = GL_RGB; |  | ||||||
|                 dataType = ARBHalfFloatPixel.GL_HALF_FLOAT_ARB; |  | ||||||
|                 break; |  | ||||||
|             case RGB16F_to_RGB9E5: |  | ||||||
|                 internalFormat = EXTTextureSharedExponent.GL_RGB9_E5_EXT; |  | ||||||
|                 format = GL_RGB; |  | ||||||
|                 dataType = ARBHalfFloatPixel.GL_HALF_FLOAT_ARB; |  | ||||||
|                 break; |  | ||||||
|             case RGB9E5: |  | ||||||
|                 internalFormat = EXTTextureSharedExponent.GL_RGB9_E5_EXT; |  | ||||||
|                 format = GL_RGB; |  | ||||||
|                 dataType = EXTTextureSharedExponent.GL_UNSIGNED_INT_5_9_9_9_REV_EXT; |  | ||||||
|                 break; |  | ||||||
|             case RGB16F: |  | ||||||
|                 internalFormat = ARBTextureFloat.GL_RGB16F_ARB; |  | ||||||
|                 format = GL_RGB; |  | ||||||
|                 dataType = ARBHalfFloatPixel.GL_HALF_FLOAT_ARB; |  | ||||||
|                 break; |  | ||||||
|             case RGBA16F: |  | ||||||
|                 internalFormat = ARBTextureFloat.GL_RGBA16F_ARB; |  | ||||||
|                 format = GL_RGBA; |  | ||||||
|                 dataType = ARBHalfFloatPixel.GL_HALF_FLOAT_ARB; |  | ||||||
|                 break; |  | ||||||
|             case RGB32F: |  | ||||||
|                 internalFormat = ARBTextureFloat.GL_RGB32F_ARB; |  | ||||||
|                 format = GL_RGB; |  | ||||||
|                 dataType = GL_FLOAT; |  | ||||||
|                 break; |  | ||||||
|             case RGBA32F: |  | ||||||
|                 internalFormat = ARBTextureFloat.GL_RGBA32F_ARB; |  | ||||||
|                 format = GL_RGBA; |  | ||||||
|                 dataType = GL_FLOAT; |  | ||||||
|                 break; |  | ||||||
|             case RGB5A1: |  | ||||||
|                 internalFormat = GL_RGB5_A1; |  | ||||||
|                 format = GL_RGBA; |  | ||||||
|                 dataType = GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case RGB8: |  | ||||||
|                 internalFormat = GL_RGB8; |  | ||||||
|                 format = GL_RGB; |  | ||||||
|                 dataType = GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case BGR8: |  | ||||||
|                 internalFormat = GL_RGB8; |  | ||||||
|                 format = GL_BGR; |  | ||||||
|                 dataType = GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case RGBA16: |  | ||||||
|                 internalFormat = GL_RGBA16; |  | ||||||
|                 format = GL_RGBA; |  | ||||||
|                 dataType = GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case RGBA8: |  | ||||||
|                 internalFormat = GL_RGBA8; |  | ||||||
|                 format = GL_RGBA; |  | ||||||
|                 dataType = GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             case ABGR8: |  | ||||||
|                 internalFormat = GL_RGBA8; |  | ||||||
|                 format = EXTAbgr.GL_ABGR_EXT; |  | ||||||
|                 dataType = GL_UNSIGNED_BYTE; |  | ||||||
|                 break; |  | ||||||
|             default: |  | ||||||
|                 throw new UnsupportedOperationException("Unrecognized format: "+fmt); |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (data != null) |         int[] mipSizes = image.getMipMapSizes(); | ||||||
|             glPixelStorei(GL_UNPACK_ALIGNMENT, 1); |  | ||||||
| 
 |  | ||||||
|         int[] mipSizes = img.getMipMapSizes(); |  | ||||||
|         int pos = 0; |         int pos = 0; | ||||||
|         // TODO: Remove unneccessary allocation |         // TODO: Remove unneccessary allocation | ||||||
|         if (mipSizes == null){ |         if (mipSizes == null){ | ||||||
| @ -409,7 +232,7 @@ public class TextureUtil { | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         boolean subtex = false; |         boolean subtex = false; | ||||||
|         int samples = img.getMultiSamples(); |         int samples = image.getMultiSamples(); | ||||||
| 
 | 
 | ||||||
|         for (int i = 0; i < mipSizes.length; i++){ |         for (int i = 0; i < mipSizes.length; i++){ | ||||||
|             int mipWidth =  Math.max(1, width  >> i); |             int mipWidth =  Math.max(1, width  >> i); | ||||||
| @ -421,95 +244,96 @@ public class TextureUtil { | |||||||
|                 data.limit(pos + mipSizes[i]); |                 data.limit(pos + mipSizes[i]); | ||||||
|             } |             } | ||||||
|              |              | ||||||
|             if (compress && data != null){ |             if (glFmt.compressed && data != null){ | ||||||
|                 if (target == GL_TEXTURE_3D){ |                 if (target == GL12.GL_TEXTURE_3D){ | ||||||
|                     glCompressedTexImage3D(target, |                     GL13.glCompressedTexImage3D(target, | ||||||
|                                            i, |                                                 i, | ||||||
|                                            internalFormat, |                                                 glFmt.internalFormat, | ||||||
|                                            mipWidth, |                                                 mipWidth, | ||||||
|                                            mipHeight, |                                                 mipHeight, | ||||||
|                                            mipDepth, |                                                 mipDepth, | ||||||
|                                            border, |                                                 border, | ||||||
|                                            data); |                                                 data); | ||||||
|                 }else{ |                 }else{ | ||||||
|                     //all other targets use 2D: array, cubemap, 2d |                     //all other targets use 2D: array, cubemap, 2d | ||||||
|                     glCompressedTexImage2D(target, |                     GL13.glCompressedTexImage2D(target, | ||||||
|                                            i, |                                                 i, | ||||||
|                                            internalFormat, |                                                 glFmt.internalFormat, | ||||||
|                                            mipWidth, |                                                 mipWidth, | ||||||
|                                            mipHeight, |                                                 mipHeight, | ||||||
|                                            border, |                                                 border, | ||||||
|                                            data); |                                                 data); | ||||||
|                 } |                 } | ||||||
|             }else{ |             }else{ | ||||||
|                 if (target == GL_TEXTURE_3D){ |                 if (target == GL12.GL_TEXTURE_3D){ | ||||||
|                     glTexImage3D(target, |                     GL12.glTexImage3D(target, | ||||||
|                                  i, |                                       i, | ||||||
|                                  internalFormat, |                                       glFmt.internalFormat, | ||||||
|                                  mipWidth, |                                       mipWidth, | ||||||
|                                  mipHeight, |                                       mipHeight, | ||||||
|                                  mipDepth, |                                       mipDepth, | ||||||
|                                  border, |                                       border, | ||||||
|                                  format, |                                       glFmt.format, | ||||||
|                                  dataType, |                                       glFmt.dataType, | ||||||
|                                  data); |                                       data); | ||||||
|                 }else if (target == EXTTextureArray.GL_TEXTURE_2D_ARRAY_EXT){ |                 }else if (target == EXTTextureArray.GL_TEXTURE_2D_ARRAY_EXT){ | ||||||
|                     // prepare data for 2D array |                     // prepare data for 2D array | ||||||
|                     // or upload slice |                     // or upload slice | ||||||
|                     if (index == -1){ |                     if (index == -1){ | ||||||
|                         glTexImage3D(target, |                         GL12.glTexImage3D(target, | ||||||
|                                      0, |                                           0, | ||||||
|                                      internalFormat, |                                           glFmt.internalFormat, | ||||||
|                                      mipWidth, |                                           mipWidth, | ||||||
|                                      mipHeight, |                                           mipHeight, | ||||||
|                                      img.getData().size(), //# of slices |                                           image.getData().size(), //# of slices | ||||||
|                                      border, |                                           border, | ||||||
|                                      format, |                                           glFmt.format, | ||||||
|                                      dataType, |                                           glFmt.dataType, | ||||||
|                                      data); |                                           data); | ||||||
|                     }else{ |                     }else{ | ||||||
|                         glTexSubImage3D(target, |                         GL12.glTexSubImage3D(target, | ||||||
|                                         i, // level |                                              i, // level | ||||||
|                                         0, // xoffset |                                              0, // xoffset | ||||||
|                                         0, // yoffset |                                              0, // yoffset | ||||||
|                                         index, // zoffset |                                              index, // zoffset | ||||||
|                                         width, // width |                                              width, // width | ||||||
|                                         height, // height |                                              height, // height | ||||||
|                                         1, // depth |                                              1, // depth | ||||||
|                                         format, |                                              glFmt.format, | ||||||
|                                         dataType, |                                              glFmt.dataType, | ||||||
|                                         data); |                                              data); | ||||||
|                     } |                     } | ||||||
|                 }else{ |                 }else{ | ||||||
|                     if (subtex){ |                     if (subtex){ | ||||||
|                         if (samples > 1) |                         if (samples > 1){ | ||||||
|                             throw new IllegalStateException("Cannot update multisample textures"); |                             throw new IllegalStateException("Cannot update multisample textures"); | ||||||
|  |                         } | ||||||
| 
 | 
 | ||||||
|                         glTexSubImage2D(target, |                         GL11.glTexSubImage2D(target, | ||||||
|                                         i, |                                              i, | ||||||
|                                         0, 0, |                                              0, 0, | ||||||
|                                         mipWidth, mipHeight, |                                              mipWidth, mipHeight, | ||||||
|                                         format, |                                              glFmt.format, | ||||||
|                                         dataType, |                                              glFmt.dataType, | ||||||
|                                         data); |                                              data); | ||||||
|                     }else{ |                     }else{ | ||||||
|                         if (samples > 1){ |                         if (samples > 1){ | ||||||
|                             ARBTextureMultisample.glTexImage2DMultisample(target, |                             ARBTextureMultisample.glTexImage2DMultisample(target, | ||||||
|                                                                           samples, |                                                                           samples, | ||||||
|                                                                           internalFormat, |                                                                           glFmt.internalFormat, | ||||||
|                                                                           mipWidth, |                                                                           mipWidth, | ||||||
|                                                                           mipHeight, |                                                                           mipHeight, | ||||||
|                                                                           true); |                                                                           true); | ||||||
|                         }else{ |                         }else{ | ||||||
|                             glTexImage2D(target, |                             GL11.glTexImage2D(target, | ||||||
|                                          i, |                                               i, | ||||||
|                                          internalFormat, |                                               glFmt.internalFormat, | ||||||
|                                          mipWidth, |                                               mipWidth, | ||||||
|                                          mipHeight, |                                               mipHeight, | ||||||
|                                          border, |                                               border, | ||||||
|                                          format, |                                               glFmt.format, | ||||||
|                                          dataType, |                                               glFmt.dataType, | ||||||
|                                          data); |                                               data); | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user