浏览代码

GLRenderer: support luminance / alpha textures in core profile

Kirill Vainer 10 年之前
父节点
当前提交
e2d8fe8293

+ 2 - 0
jme3-core/src/main/java/com/jme3/renderer/opengl/GL.java

@@ -74,6 +74,7 @@ public interface GL {
 	public static final int GL_FRONT_AND_BACK = 0x408;
 	public static final int GL_GEQUAL = 0x206;
 	public static final int GL_GREATER = 0x204;
+        public static final int GL_GREEN = 0x1904;
 	public static final int GL_INCR = 0x1E02;
 	public static final int GL_INCR_WRAP = 0x8507;
 	public static final int GL_INFO_LOG_LENGTH = 0x8B84;
@@ -114,6 +115,7 @@ public interface GL {
         public static final int GL_OUT_OF_MEMORY = 0x505;
 	public static final int GL_POINTS = 0x0;
 	public static final int GL_POLYGON_OFFSET_FILL = 0x8037;
+        public static final int GL_RED = 0x1903;
         public static final int GL_RENDERER = 0x1F01;
 	public static final int GL_REPEAT = 0x2901;
 	public static final int GL_REPLACE = 0x1E01;

+ 12 - 1
jme3-core/src/main/java/com/jme3/renderer/opengl/GL3.java

@@ -34,7 +34,7 @@ package com.jme3.renderer.opengl;
 import java.nio.IntBuffer;
 
 /**
- * GL functions only available on vanilla desktop OpenGL 3.0.
+ * GL functions only available on vanilla desktop OpenGL 3.0+.
  *
  * @author Kirill Vainer
  */
@@ -43,6 +43,17 @@ public interface GL3 extends GL2 {
     public static final int GL_DEPTH_STENCIL_ATTACHMENT = 0x821A;
     public static final int GL_GEOMETRY_SHADER = 0x8DD9;
     public static final int GL_NUM_EXTENSIONS = 0x821D;
+    public static final int GL_R8 = 0x8229;
+    public static final int GL_R16F = 0x822D;
+    public static final int GL_R32F = 0x822E;
+    public static final int GL_RG16F = 0x822F;
+    public static final int GL_RG32F = 0x8230;
+    public static final int GL_RG = 0x8227;
+    public static final int GL_RG8 = 0x822B;
+    public static final int GL_TEXTURE_SWIZZLE_A = 0x8E45;
+    public static final int GL_TEXTURE_SWIZZLE_B = 0x8E44;
+    public static final int GL_TEXTURE_SWIZZLE_G = 0x8E43;
+    public static final int GL_TEXTURE_SWIZZLE_R = 0x8E42;
     
     public void glBindFragDataLocation(int param1, int param2, String param3); /// GL3+
     public void glBindVertexArray(int param1); /// GL3+

+ 1 - 1
jme3-core/src/main/java/com/jme3/renderer/opengl/GL4.java

@@ -34,7 +34,7 @@ package com.jme3.renderer.opengl;
 import java.nio.IntBuffer;
 
 /**
- * GL functions only available on vanilla desktop OpenGL 3.0.
+ * GL functions only available on vanilla desktop OpenGL 4.0.
  * 
  * @author Kirill Vainer
  */

+ 21 - 0
jme3-core/src/main/java/com/jme3/renderer/opengl/GLImageFormat.java

@@ -42,6 +42,7 @@ public final class GLImageFormat {
     public final int format;
     public final int dataType;
     public final boolean compressed;
+    public final boolean swizzleRequired;
 
     /**
      * Constructor for formats.
@@ -55,6 +56,7 @@ public final class GLImageFormat {
         this.format = format;
         this.dataType = dataType;
         this.compressed = false;
+        this.swizzleRequired = false;
     }
     
     /**
@@ -63,11 +65,30 @@ public final class GLImageFormat {
      * @param internalFormat OpenGL internal format
      * @param format OpenGL format
      * @param dataType OpenGL datatype
+     * @param compressed Format is compressed
      */
     public GLImageFormat(int internalFormat, int format, int dataType, boolean compressed) {
         this.internalFormat = internalFormat;
         this.format = format;
         this.dataType = dataType;
         this.compressed = compressed;
+        this.swizzleRequired = false;
+    }
+    
+    /**
+     * Constructor for formats.
+     * 
+     * @param internalFormat OpenGL internal format
+     * @param format OpenGL format
+     * @param dataType OpenGL datatype
+     * @param compressed Format is compressed
+     * @param swizzleRequired Need to use texture swizzle to upload texture
+     */
+    public GLImageFormat(int internalFormat, int format, int dataType, boolean compressed, boolean swizzleRequired) {
+        this.internalFormat = internalFormat;
+        this.format = format;
+        this.dataType = dataType;
+        this.compressed = compressed;
+        this.swizzleRequired = swizzleRequired;
     }
 }

+ 28 - 0
jme3-core/src/main/java/com/jme3/renderer/opengl/GLImageFormats.java

@@ -52,6 +52,13 @@ public final class GLImageFormats {
         formatToGL[0][format.ordinal()] = new GLImageFormat(glInternalFormat, glFormat, glDataType);
     }
     
+    private static void formatSwiz(GLImageFormat[][] formatToGL, Image.Format format, 
+                                   int glInternalFormat, 
+                                   int glFormat, 
+                                   int glDataType){
+        formatToGL[0][format.ordinal()] = new GLImageFormat(glInternalFormat, glFormat, glDataType, false, true);
+    }
+    
     private static void formatSrgb(GLImageFormat[][] formatToGL, Image.Format format, 
                                    int glInternalFormat, 
                                    int glFormat, 
@@ -60,6 +67,14 @@ public final class GLImageFormats {
         formatToGL[1][format.ordinal()] = new GLImageFormat(glInternalFormat, glFormat, glDataType);
     }
     
+    private static void formatSrgbSwiz(GLImageFormat[][] formatToGL, Image.Format format, 
+                                       int glInternalFormat, 
+                                       int glFormat, 
+                                       int glDataType)
+    {
+        formatToGL[1][format.ordinal()] = new GLImageFormat(glInternalFormat, glFormat, glDataType, false, true);
+    }
+    
     private static void formatComp(GLImageFormat[][] formatToGL, Image.Format format, 
                                    int glCompressedFormat,
                                    int glFormat, 
@@ -88,6 +103,19 @@ public final class GLImageFormats {
     public static GLImageFormat[][] getFormatsForCaps(EnumSet<Caps> caps) {
         GLImageFormat[][] formatToGL = new GLImageFormat[2][Image.Format.values().length];
         
+        // Core Profile Formats (supported by both OpenGL Core 3.3 and OpenGL ES 3.0+)
+        if (caps.contains(Caps.CoreProfile)) {
+            formatSwiz(formatToGL,     Format.Alpha8,               GL3.GL_R8,                 GL.GL_RED,       GL.GL_UNSIGNED_BYTE);
+            formatSwiz(formatToGL,     Format.Luminance8,           GL3.GL_R8,                 GL.GL_RED,       GL.GL_UNSIGNED_BYTE);
+            formatSwiz(formatToGL,     Format.Luminance8Alpha8,     GL3.GL_RG8,                GL3.GL_RG,       GL.GL_UNSIGNED_BYTE);
+            formatSwiz(formatToGL,     Format.Luminance16F,         GL3.GL_R16F,               GL.GL_RED,       GLExt.GL_HALF_FLOAT_ARB);
+            formatSwiz(formatToGL,     Format.Luminance32F,         GL3.GL_R32F,               GL.GL_RED,       GL.GL_FLOAT);
+            formatSwiz(formatToGL,     Format.Luminance16FAlpha16F, GL3.GL_RG16F,              GL3.GL_RG,       GLExt.GL_HALF_FLOAT_ARB);
+            
+            formatSrgbSwiz(formatToGL, Format.Luminance8,           GLExt.GL_SRGB8_EXT,        GL.GL_RED,       GL.GL_UNSIGNED_BYTE);
+            formatSrgbSwiz(formatToGL, Format.Luminance8Alpha8,     GLExt.GL_SRGB8_ALPHA8_EXT, GL3.GL_RG,       GL.GL_UNSIGNED_BYTE);
+        }
+        
         if (caps.contains(Caps.OpenGL20)) {
             if (!caps.contains(Caps.CoreProfile)) {
                 format(formatToGL, Format.Alpha8,           GL2.GL_ALPHA8,            GL.GL_ALPHA,           GL.GL_UNSIGNED_BYTE);

+ 1 - 1
jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java

@@ -106,7 +106,7 @@ public class GLRenderer implements Renderer {
         this.gl4 = gl instanceof GL4 ? (GL4)gl : null;
         this.glfbo = glfbo;
         this.glext = glext;
-        this.texUtil = new TextureUtil(gl, gl2, glext, context);
+        this.texUtil = new TextureUtil(gl, gl2, glext);
     }
 
     @Override

+ 34 - 4
jme3-core/src/main/java/com/jme3/renderer/opengl/TextureUtil.java

@@ -54,14 +54,12 @@ final class TextureUtil {
     private final GL gl;
     private final GL2 gl2;
     private final GLExt glext;
-    private final RenderContext context;
     private GLImageFormat[][] formats;
-
-    public TextureUtil(GL gl, GL2 gl2, GLExt glext, RenderContext context) {
+    
+    public TextureUtil(GL gl, GL2 gl2, GLExt glext) {
         this.gl = gl;
         this.gl2 = gl2;
         this.glext = glext;
-        this.context = context;
     }
     
     public void initialize(EnumSet<Caps> caps) {
@@ -103,6 +101,33 @@ final class TextureUtil {
         return glFmt;
     }
     
+    private void setupTextureSwizzle(int target, Format format) {
+        // Needed for OpenGL 3.3 to support luminance / alpha formats
+        switch (format) {
+            case Alpha8:
+                gl.glTexParameteri(target, GL3.GL_TEXTURE_SWIZZLE_R, GL.GL_ZERO);
+                gl.glTexParameteri(target, GL3.GL_TEXTURE_SWIZZLE_G, GL.GL_ZERO);
+                gl.glTexParameteri(target, GL3.GL_TEXTURE_SWIZZLE_B, GL.GL_ZERO);
+                gl.glTexParameteri(target, GL3.GL_TEXTURE_SWIZZLE_A, GL.GL_RED);
+                break;
+            case Luminance8:
+            case Luminance16F:
+            case Luminance32F:
+                gl.glTexParameteri(target, GL3.GL_TEXTURE_SWIZZLE_R, GL.GL_RED);
+                gl.glTexParameteri(target, GL3.GL_TEXTURE_SWIZZLE_G, GL.GL_RED);
+                gl.glTexParameteri(target, GL3.GL_TEXTURE_SWIZZLE_B, GL.GL_RED);
+                gl.glTexParameteri(target, GL3.GL_TEXTURE_SWIZZLE_A, GL.GL_ONE);
+                break;
+            case Luminance8Alpha8:
+            case Luminance16FAlpha16F:
+                gl.glTexParameteri(target, GL3.GL_TEXTURE_SWIZZLE_R, GL.GL_RED);
+                gl.glTexParameteri(target, GL3.GL_TEXTURE_SWIZZLE_G, GL.GL_RED);
+                gl.glTexParameteri(target, GL3.GL_TEXTURE_SWIZZLE_B, GL.GL_RED);
+                gl.glTexParameteri(target, GL3.GL_TEXTURE_SWIZZLE_A, GL.GL_GREEN);
+                break;
+        }
+    }
+    
     private void uploadTextureLevel(GLImageFormat format, int target, int level, int slice, int sliceCount, int width, int height, int depth, int samples, ByteBuffer data) {
         if (format.compressed && data != null) {
             if (target == GL2.GL_TEXTURE_3D) {
@@ -242,6 +267,11 @@ final class TextureUtil {
         }
 
         int samples = image.getMultiSamples();
+        
+        // For OGL3 core: setup texture swizzle.
+        if (oglFormat.swizzleRequired) {
+            setupTextureSwizzle(target, jmeFormat);
+        }
 
         for (int i = 0; i < mipSizes.length; i++) {
             int mipWidth = Math.max(1, width >> i);