Преглед изворни кода

Avoid use of LWJGL specific ContextCapabilities class.
Instead parse GL_EXTENSIONS and use that to determine supported features.

shadowislord пре 11 година
родитељ
комит
84046018ba

+ 16 - 1
jme3-core/src/main/java/com/jme3/renderer/Caps.java

@@ -236,7 +236,22 @@ public enum Caps {
     /**
      * Supports sRGB framebuffers and sRGB texture format
      */
-    Srgb;
+    Srgb,
+    
+    /**
+     * Supports blitting framebuffers.
+     */
+    FrameBufferBlit,
+    
+    /**
+     * Supports {@link Format#DXT1} and sister formats.
+     */
+    TextureCompressionS3TC,
+    
+    /**
+     * Supports anisotropic texture filtering.
+     */
+    TextureFilterAnisotropic;
 
     /**
      * Returns true if given the renderer capabilities, the texture

+ 2 - 2
jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL1Renderer.java

@@ -802,7 +802,7 @@ public class LwjglGL1Renderer implements GL1Renderer {
         TextureUtil.uploadTexture(img, target, i, 0, tdc);
         }
         } else {*/
-        TextureUtil.uploadTexture(ctxCaps, img, target, 0, 0, false);
+        TextureUtil.uploadTexture(caps, img, target, 0, 0, false);
         //}
 
         img.clearUpdateNeeded();
@@ -853,7 +853,7 @@ public class LwjglGL1Renderer implements GL1Renderer {
 
     public void modifyTexture(Texture tex, Image pixels, int x, int y) {
       setTexture(0, tex);
-      TextureUtil.uploadSubTexture(ctxCaps, pixels, convertTextureType(tex.getType()), 0, x, y, false);
+      TextureUtil.uploadSubTexture(caps, pixels, convertTextureType(tex.getType()), 0, x, y, false);
     }
 
     private void clearTextureUnits() {

+ 90 - 72
jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglRenderer.java

@@ -57,7 +57,9 @@ import com.jme3.util.BufferUtils;
 import com.jme3.util.ListMap;
 import com.jme3.util.NativeObjectManager;
 import java.nio.*;
+import java.util.ArrayList;
 import java.util.EnumSet;
+import java.util.HashSet;
 import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -69,7 +71,6 @@ import static org.lwjgl.opengl.ARBInstancedArrays.*;
 import static org.lwjgl.opengl.ARBMultisample.*;
 import static org.lwjgl.opengl.ARBTextureMultisample.*;
 import static org.lwjgl.opengl.ARBVertexArrayObject.*;
-import org.lwjgl.opengl.ContextCapabilities;
 import static org.lwjgl.opengl.EXTFramebufferBlit.*;
 import static org.lwjgl.opengl.EXTFramebufferMultisample.*;
 import static org.lwjgl.opengl.EXTFramebufferObject.*;
@@ -83,7 +84,7 @@ import static org.lwjgl.opengl.GL13.*;
 import static org.lwjgl.opengl.GL14.*;
 import static org.lwjgl.opengl.GL15.*;
 import static org.lwjgl.opengl.GL20.*;
-import org.lwjgl.opengl.GLContext;
+import org.lwjgl.opengl.GL30;
 //import static org.lwjgl.opengl.GL21.*;
 //import static org.lwjgl.opengl.GL30.*;
 
@@ -121,7 +122,7 @@ public class LwjglRenderer implements Renderer {
     private int vpX, vpY, vpW, vpH;
     private int clipX, clipY, clipW, clipH;
     private boolean linearizeSrgbImages;
-    private ContextCapabilities ctxCaps;
+    private HashSet<String> extensions;
 
     public LwjglRenderer() {
     }
@@ -148,6 +149,14 @@ public class LwjglRenderer implements Renderer {
         return caps;
     }
 
+    private static HashSet<String> loadExtensions(String extensions) {
+        HashSet<String> extensionSet = new HashSet<String>(64);
+        for (String extension : extensions.split(" ")) {
+            extensionSet.add(extension);
+        }
+        return extensionSet;
+    }
+    
     private static int extractVersion(String prefixStr, String versionStr) {
         if (versionStr != null) {
             int spaceIdx = versionStr.indexOf(" ", prefixStr.length());
@@ -185,9 +194,12 @@ public class LwjglRenderer implements Renderer {
         }
     }
     
-    @SuppressWarnings("fallthrough")
-    public void initialize() {
-        int oglVer  = extractVersion("", glGetString(GL_VERSION));
+    private boolean hasExtension(String extensionName) {
+        return extensions.contains(extensionName);
+    }
+    
+    private void loadCapabilities() {
+        int oglVer = extractVersion("", glGetString(GL_VERSION));
         
         if (oglVer >= 200) {
             caps.add(Caps.OpenGL20);
@@ -205,17 +217,6 @@ public class LwjglRenderer implements Renderer {
             }
         }
         
-        // Fix issue in TestRenderToMemory when GL_FRONT is the main
-        // buffer being used.
-        context.initialDrawBuf = glGetInteger(GL_DRAW_BUFFER);
-        context.initialReadBuf = glGetInteger(GL_READ_BUFFER);
-
-        // XXX: This has to be GL_BACK for canvas on Mac
-        // Since initialDrawBuf is GL_FRONT for pbuffer, gotta
-        // change this value later on ...
-//        initialDrawBuf = GL_BACK;
-//        initialReadBuf = GL_BACK;
-
         int glslVer = extractVersion("", glGetString(GL_SHADING_LANGUAGE_VERSION));
         
         switch (glslVer) {
@@ -245,9 +246,25 @@ public class LwjglRenderer implements Renderer {
         // Workaround, always assume we support GLSL100.
         // Some cards just don't report this correctly.
         caps.add(Caps.GLSL100);
-
-        ctxCaps = GLContext.getCapabilities();
         
+        extensions = loadExtensions(glGetString(GL_EXTENSIONS));
+    }
+    
+    @SuppressWarnings("fallthrough")
+    public void initialize() {
+        loadCapabilities();
+        
+        // Fix issue in TestRenderToMemory when GL_FRONT is the main
+        // buffer being used.
+        context.initialDrawBuf = glGetInteger(GL_DRAW_BUFFER);
+        context.initialReadBuf = glGetInteger(GL_READ_BUFFER);
+
+        // XXX: This has to be GL_BACK for canvas on Mac
+        // Since initialDrawBuf is GL_FRONT for pbuffer, gotta
+        // change this value later on ...
+//        initialDrawBuf = GL_BACK;
+//        initialReadBuf = GL_BACK;
+
         glGetInteger(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, intBuf16);
         vertexTextureUnits = intBuf16.get(0);
         logger.log(Level.FINER, "VTF Units: {0}", vertexTextureUnits);
@@ -291,44 +308,41 @@ public class LwjglRenderer implements Renderer {
         maxCubeTexSize = intBuf16.get(0);
         logger.log(Level.FINER, "Maximum CubeMap Resolution: {0}", maxCubeTexSize);
 
-        if (ctxCaps.GL_ARB_color_buffer_float) {
+        // ctxCaps = GLContext.getCapabilities();
+        
+        if (hasExtension("GL_ARB_color_buffer_float") &&
+            hasExtension("GL_ARB_half_float_pixel")) {
             // XXX: Require both 16 and 32 bit float support for FloatColorBuffer.
-            if (ctxCaps.GL_ARB_half_float_pixel) {
-                caps.add(Caps.FloatColorBuffer);
-            }
+            caps.add(Caps.FloatColorBuffer);
         }
 
-        if (ctxCaps.GL_ARB_depth_buffer_float) {
+        if (hasExtension("GL_ARB_depth_buffer_float")) {
             caps.add(Caps.FloatDepthBuffer);
         }
 
-        if (ctxCaps.OpenGL30) {
+        if (caps.contains(Caps.OpenGL30)) {
             caps.add(Caps.PackedDepthStencilBuffer);
         }
 
-        if (ctxCaps.GL_ARB_draw_instanced && ctxCaps.GL_ARB_instanced_arrays) {
+        if (hasExtension("GL_ARB_draw_instanced") && 
+            hasExtension("GL_ARB_instanced_arrays")) {
             caps.add(Caps.MeshInstancing);
         }
 
-        if (ctxCaps.GL_ARB_fragment_program) {
-            caps.add(Caps.ARBprogram);
-        }
-
-        if (ctxCaps.GL_ARB_texture_buffer_object) {
+        if (hasExtension("GL_ARB_texture_buffer_object")) {
             caps.add(Caps.TextureBuffer);
         }
 
-        if (ctxCaps.GL_ARB_texture_float) {
-            if (ctxCaps.GL_ARB_half_float_pixel) {
-                caps.add(Caps.FloatTexture);
-            }
+        if (hasExtension("GL_ARB_texture_float") &&
+            hasExtension("GL_ARB_half_float_pixel")) {
+            caps.add(Caps.FloatTexture);
         }
 
-        if (ctxCaps.GL_ARB_vertex_array_object) {
+        if (hasExtension("GL_ARB_vertex_array_object") || caps.contains(Caps.OpenGL30)) {
             caps.add(Caps.VertexBufferArray);
         }
 
-        if (ctxCaps.GL_ARB_texture_non_power_of_two) {
+        if (hasExtension("GL_ARB_texture_non_power_of_two") || caps.contains(Caps.OpenGL30)) {
             caps.add(Caps.NonPowerOfTwoTextures);
         } else {
             logger.log(Level.WARNING, "Your graphics card does not "
@@ -336,30 +350,34 @@ public class LwjglRenderer implements Renderer {
                     + "Some features might not work.");
         }
 
-        boolean latc = ctxCaps.GL_EXT_texture_compression_latc;
-        if (latc) {
+        if (hasExtension("GL_EXT_texture_compression_latc")) {
             caps.add(Caps.TextureCompressionLATC);
         }
 
-        if (ctxCaps.GL_EXT_packed_float || ctxCaps.OpenGL30) {
+        if (hasExtension("GL_EXT_packed_float") || caps.contains(Caps.OpenGL30)) {
             // This format is part of the OGL3 specification
             caps.add(Caps.PackedFloatColorBuffer);
-            if (ctxCaps.GL_ARB_half_float_pixel) {
+            
+            if (hasExtension("GL_ARB_half_float_pixel")) {
                 // because textures are usually uploaded as RGB16F
                 // need half-float pixel
                 caps.add(Caps.PackedFloatTexture);
             }
         }
 
-        if (ctxCaps.GL_EXT_texture_array || ctxCaps.OpenGL30) {
+        if (hasExtension("GL_EXT_texture_array") || caps.contains(Caps.OpenGL30)) {
             caps.add(Caps.TextureArray);
         }
 
-        if (ctxCaps.GL_EXT_texture_shared_exponent || ctxCaps.OpenGL30) {
+        if (hasExtension("GL_EXT_texture_shared_exponent") || caps.contains(Caps.OpenGL30)) {
             caps.add(Caps.SharedExponentTexture);
         }
+        
+        if (hasExtension("GL_EXT_texture_filter_anisotropic")) {
+            caps.add(Caps.TextureFilterAnisotropic);
+        }
 
-        if (ctxCaps.GL_EXT_framebuffer_object) {
+        if (hasExtension("GL_EXT_framebuffer_object")) {
             caps.add(Caps.FrameBuffer);
 
             glGetInteger(GL_MAX_RENDERBUFFER_SIZE_EXT, intBuf16);
@@ -370,7 +388,7 @@ public class LwjglRenderer implements Renderer {
             maxFBOAttachs = intBuf16.get(0);
             logger.log(Level.FINER, "FBO Max renderbuffers: {0}", maxFBOAttachs);
 
-            if (ctxCaps.GL_EXT_framebuffer_multisample) {
+            if (hasExtension("GL_EXT_framebuffer_multisample")) {
                 caps.add(Caps.FrameBufferMultisample);
 
                 glGetInteger(GL_MAX_SAMPLES_EXT, intBuf16);
@@ -378,7 +396,7 @@ public class LwjglRenderer implements Renderer {
                 logger.log(Level.FINER, "FBO Max Samples: {0}", maxFBOSamples);
             }
 
-            if (ctxCaps.GL_ARB_texture_multisample) {
+            if (hasExtension("GL_ARB_texture_multisample")) {
                 caps.add(Caps.TextureMultisample);
 
                 glGetInteger(GL_MAX_COLOR_TEXTURE_SAMPLES, intBuf16);
@@ -398,7 +416,7 @@ public class LwjglRenderer implements Renderer {
             }
         }
 
-        if (ctxCaps.GL_ARB_multisample) {
+        if (hasExtension("GL_ARB_multisample")) {
             glGetInteger(GL_SAMPLE_BUFFERS_ARB, intBuf16);
             boolean available = intBuf16.get(0) != 0;
             glGetInteger(GL_SAMPLES_ARB, intBuf16);
@@ -412,7 +430,8 @@ public class LwjglRenderer implements Renderer {
         }
         
         // Supports sRGB pipeline.
-        if ( (ctxCaps.GL_ARB_framebuffer_sRGB && ctxCaps.GL_EXT_texture_sRGB ) || ctxCaps.OpenGL30 ) {
+        if ( (hasExtension("GL_ARB_framebuffer_sRGB") && hasExtension("GL_EXT_texture_sRGB")) 
+           || caps.contains(Caps.OpenGL30) ) {
             caps.add(Caps.Srgb);
         }
 
@@ -487,7 +506,7 @@ public class LwjglRenderer implements Renderer {
     }
 
     public void setAlphaToCoverage(boolean value) {
-        if (ctxCaps.GL_ARB_multisample) {
+        if (caps.contains(Caps.Multisample)) {
             if (value) {
                 glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
             } else {
@@ -1089,12 +1108,12 @@ public class LwjglRenderer implements Renderer {
             glAttachShader(id, source.getId());
         }
 
-        if (ctxCaps.GL_EXT_gpu_shader4) {
+        if (caps.contains(Caps.OpenGL30)) {
             // Check if GLSL version is 1.5 for shader
-            glBindFragDataLocationEXT(id, 0, "outFragColor");
+            GL30.glBindFragDataLocation(id, 0, "outFragColor");
             // For MRT
             for (int i = 0; i < maxMRTFBOAttachs; i++) {
-                glBindFragDataLocationEXT(id, i, "outFragData[" + i + "]");
+                GL30.glBindFragDataLocation(id, i, "outFragData[" + i + "]");
             }
         }
 
@@ -1199,7 +1218,7 @@ public class LwjglRenderer implements Renderer {
     }
 
     public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst, boolean copyDepth) {
-        if (ctxCaps.GL_EXT_framebuffer_blit) {
+        if (caps.contains(Caps.FrameBufferBlit)) {
             int srcX0 = 0;
             int srcY0 = 0;
             int srcX1;
@@ -1300,11 +1319,11 @@ public class LwjglRenderer implements Renderer {
 
         int attachment = convertAttachmentSlot(rb.getSlot());
 
-        int type = glGetFramebufferAttachmentParameterEXT(GL_DRAW_FRAMEBUFFER_EXT,
+        int type = glGetFramebufferAttachmentParameteriEXT(GL_DRAW_FRAMEBUFFER_EXT,
                 attachment,
                 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT);
 
-        int rbName = glGetFramebufferAttachmentParameterEXT(GL_DRAW_FRAMEBUFFER_EXT,
+        int rbName = glGetFramebufferAttachmentParameteriEXT(GL_DRAW_FRAMEBUFFER_EXT,
                 attachment,
                 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT);
 
@@ -1405,9 +1424,9 @@ public class LwjglRenderer implements Renderer {
                     + ":" + fb.getHeight() + " is not supported.");
         }
 
-        TextureUtil.GLImageFormat glFmt = TextureUtil.getImageFormatWithError(ctxCaps, rb.getFormat(), fb.isSrgb());
+        TextureUtil.GLImageFormat glFmt = TextureUtil.getImageFormatWithError(caps, rb.getFormat(), fb.isSrgb());
 
-        if (fb.getSamples() > 1 && ctxCaps.GL_EXT_framebuffer_multisample) {
+        if (fb.getSamples() > 1 && caps.contains(Caps.FrameBufferMultisample)) {
             int samples = fb.getSamples();
             if (maxFBOSamples < samples) {
                 samples = maxFBOSamples;
@@ -1509,7 +1528,7 @@ public class LwjglRenderer implements Renderer {
         if (fb.getSamples() <= 1) {
             throw new IllegalArgumentException("Framebuffer must be multisampled");
         }
-        if (!ctxCaps.GL_ARB_texture_multisample) {
+        if (!caps.contains(Caps.TextureMultisample)) {
             throw new RendererException("Multisampled textures are not supported");
         }
 
@@ -1531,7 +1550,7 @@ public class LwjglRenderer implements Renderer {
     }
 
     public void setFrameBuffer(FrameBuffer fb) {
-        if (!ctxCaps.GL_EXT_framebuffer_object) {
+        if (!caps.contains(Caps.FrameBuffer)) {
             throw new RendererException("Framebuffer objects are not supported" +
                                         " by the video hardware");
         }
@@ -1713,7 +1732,7 @@ public class LwjglRenderer implements Renderer {
     |* Textures                                                          *|
     \*********************************************************************/
     private int convertTextureType(Texture.Type type, int samples, int face) {
-        if (samples > 1 && !ctxCaps.GL_ARB_texture_multisample) {
+        if (samples > 1 && !caps.contains(Caps.TextureMultisample)) {
             throw new RendererException("Multisample textures are not supported" + 
                                         " by the video hardware.");
         }
@@ -1826,7 +1845,7 @@ public class LwjglRenderer implements Renderer {
         glTexParameteri(target, GL_TEXTURE_MAG_FILTER, magFilter);
 
         if (tex.getAnisotropicFilter() > 1) {
-            if (ctxCaps.GL_EXT_texture_filter_anisotropic) {
+            if (caps.contains(Caps.TextureFilterAnisotropic)) {
                 glTexParameterf(target,
                         GL_TEXTURE_MAX_ANISOTROPY_EXT,
                         tex.getAnisotropicFilter());
@@ -1908,7 +1927,7 @@ public class LwjglRenderer implements Renderer {
             // Image does not have mipmaps, but they are required.
             // Generate from base level.
 
-            if (!ctxCaps.OpenGL30) {
+            if (!caps.contains(Caps.OpenGL30)) {
                 glTexParameteri(target, GL_GENERATE_MIPMAP, GL_TRUE);
                 img.setMipmapsGenerated(true);
             } else {
@@ -1935,7 +1954,7 @@ public class LwjglRenderer implements Renderer {
         }
 
         // Yes, some OpenGL2 cards (GeForce 5) still dont support NPOT.
-        if (!ctxCaps.GL_ARB_texture_non_power_of_two && img.isNPOT()) {
+        if (!caps.contains(Caps.NonPowerOfTwoTextures) && img.isNPOT()) {
             if (img.getData(0) == null) {
                 throw new RendererException("non-power-of-2 framebuffer textures are not supported by the video hardware");
             } else {
@@ -1944,7 +1963,7 @@ public class LwjglRenderer implements Renderer {
         }
 
         // Check if graphics card doesn't support multisample textures
-        if (!ctxCaps.GL_ARB_texture_multisample) {
+        if (!caps.contains(Caps.TextureMultisample)) {
             if (img.getMultiSamples() > 1) {
                 throw new RendererException("Multisample textures not supported by graphics hardware");
             }
@@ -1972,7 +1991,7 @@ public class LwjglRenderer implements Renderer {
                 return;
             }
             for (int i = 0; i < 6; i++) {
-                TextureUtil.uploadTexture(ctxCaps, img, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, i, 0, linearizeSrgbImages);
+                TextureUtil.uploadTexture(caps, img, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, i, 0, linearizeSrgbImages);
             }
         } else if (target == GL_TEXTURE_2D_ARRAY_EXT) {
             if (!caps.contains(Caps.TextureArray)) {
@@ -1982,22 +2001,22 @@ public class LwjglRenderer implements Renderer {
             List<ByteBuffer> data = img.getData();
             
             // -1 index specifies prepare data for 2D Array
-            TextureUtil.uploadTexture(ctxCaps, img, target, -1, 0, linearizeSrgbImages);
+            TextureUtil.uploadTexture(caps, img, target, -1, 0, linearizeSrgbImages);
             
             for (int i = 0; i < data.size(); i++) {
                 // upload each slice of 2D array in turn
                 // this time with the appropriate index
-                TextureUtil.uploadTexture(ctxCaps, img, target, i, 0, linearizeSrgbImages);
+                TextureUtil.uploadTexture(caps, img, target, i, 0, linearizeSrgbImages);
             }
         } else {
-            TextureUtil.uploadTexture(ctxCaps, img, target, 0, 0, linearizeSrgbImages);
+            TextureUtil.uploadTexture(caps, img, target, 0, 0, linearizeSrgbImages);
         }
 
         if (img.getMultiSamples() != imageSamples) {
             img.setMultiSamples(imageSamples);
         }
 
-        if (ctxCaps.OpenGL30) {
+        if (caps.contains(Caps.OpenGL30)) {
             if (!img.hasMipmaps() && img.isGeneratedMipmapsRequired() && img.getData() != null) {
                 // XXX: Required for ATI
                 glEnable(target);
@@ -2048,7 +2067,7 @@ public class LwjglRenderer implements Renderer {
 
     public void modifyTexture(Texture tex, Image pixels, int x, int y) {
       setTexture(0, tex);
-      TextureUtil.uploadSubTexture(ctxCaps, pixels, convertTextureType(tex.getType(), pixels.getMultiSamples(), -1), 0, x, y, linearizeSrgbImages);
+      TextureUtil.uploadSubTexture(caps, pixels, convertTextureType(tex.getType(), pixels.getMultiSamples(), -1), 0, x, y, linearizeSrgbImages);
     }
 
     public void clearTextureUnits() {
@@ -2267,8 +2286,7 @@ public class LwjglRenderer implements Renderer {
             }
             
             if (vb.isInstanced()) {
-                if (!ctxCaps.GL_ARB_instanced_arrays
-                 || !ctxCaps.GL_ARB_draw_instanced) {
+                if (!caps.contains(Caps.MeshInstancing)) {
                     throw new RendererException("Instancing is required, "
                             + "but not supported by the "
                             + "graphics hardware");

+ 14 - 13
jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/TextureUtil.java

@@ -32,11 +32,13 @@
 
 package com.jme3.renderer.lwjgl;
 
+import com.jme3.renderer.Caps;
 import com.jme3.renderer.RendererException;
 import com.jme3.texture.Image;
 import com.jme3.texture.Image.Format;
 import com.jme3.texture.image.ColorSpace;
 import java.nio.ByteBuffer;
+import java.util.EnumSet;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import static org.lwjgl.opengl.ARBDepthBufferFloat.*;
@@ -55,7 +57,6 @@ import static org.lwjgl.opengl.GL11.*;
 import static org.lwjgl.opengl.GL12.*;
 import static org.lwjgl.opengl.GL13.*;
 import static org.lwjgl.opengl.GL14.*;
-import static org.lwjgl.opengl.GL20.*;
 
 class TextureUtil {
 
@@ -140,7 +141,7 @@ class TextureUtil {
     
         // LTC/LATC/3Dc formats
         setFormat(Format.LTC,  GL_COMPRESSED_LUMINANCE_LATC1_EXT,       GL_LUMINANCE,       GL_UNSIGNED_BYTE, true);
-        setFormat(Format.LATC, GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, true);   
+        setFormat(Format.LATC, GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, true);
     }
     
     //sRGB formats        
@@ -157,18 +158,18 @@ class TextureUtil {
     private static final GLImageFormat sRGB_DXT3 = new GLImageFormat(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_BYTE, true);
     private static final GLImageFormat sRGB_DXT5 = new GLImageFormat(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_BYTE, true);
 
-    public static GLImageFormat getImageFormat(ContextCapabilities caps, Format fmt, boolean isSrgb){
+    public static GLImageFormat getImageFormat(EnumSet<Caps> caps, Format fmt, boolean isSrgb){
         switch (fmt){
             case DXT1:
             case DXT1A:
             case DXT3:
             case DXT5:
-                if (!caps.GL_EXT_texture_compression_s3tc) {
+                if (!caps.contains(Caps.TextureCompressionS3TC)) {
                     return null;
                 }
                 break;
             case Depth24Stencil8:
-                if (!caps.OpenGL30 && !caps.GL_EXT_packed_depth_stencil){
+                if (!caps.contains(Caps.PackedDepthStencilBuffer)){
                     return null;
                 }
                 break;
@@ -179,30 +180,30 @@ class TextureUtil {
             case RGB32F:
             case RGBA16F:
             case RGBA32F:
-                if (!caps.OpenGL30 && !caps.GL_ARB_texture_float){
+                if (!caps.contains(Caps.FloatTexture)){
                     return null;
                 }
                 break;
             case Depth32F:
-                if (!caps.OpenGL30 && !caps.GL_NV_depth_buffer_float){
+                if (!caps.contains(Caps.FloatDepthBuffer)){
                     return null;
                 }
                 break;
             case LATC:
             case LTC:
-                if (!caps.GL_EXT_texture_compression_latc){
+                if (!caps.contains(Caps.TextureCompressionLATC)){
                     return null;
                 }
                 break;
             case RGB9E5:
             case RGB16F_to_RGB9E5:
-                if (!caps.OpenGL30 && !caps.GL_EXT_texture_shared_exponent){
+                if (!caps.contains(Caps.SharedExponentTexture)){
                     return null;
                 }
                 break;
             case RGB111110F:
             case RGB16F_to_RGB111110F:
-                if (!caps.OpenGL30 && !caps.GL_EXT_packed_float){
+                if (!caps.contains(Caps.PackedFloatTexture)){
                     return null;
                 }
                 break;
@@ -214,7 +215,7 @@ class TextureUtil {
         }
     }
     
-    public static GLImageFormat getImageFormatWithError(ContextCapabilities caps, Format fmt, boolean isSrgb) {
+    public static GLImageFormat getImageFormatWithError(EnumSet<Caps> caps, Format fmt, boolean isSrgb) {
         GLImageFormat glFmt = getImageFormat(caps, fmt, isSrgb);
         if (glFmt == null) {
             throw new RendererException("Image format '" + fmt + "' is unsupported by the video hardware.");
@@ -254,7 +255,7 @@ class TextureUtil {
         }
     }
     
-    public static void uploadTexture(ContextCapabilities caps,
+    public static void uploadTexture(EnumSet<Caps> caps,
                                      Image image,
                                      int target,
                                      int index,
@@ -412,7 +413,7 @@ class TextureUtil {
      * @param y the y position where to put the image in the texture
      */
     public static void uploadSubTexture(
-        ContextCapabilities caps,
+        EnumSet<Caps> caps,
         Image image,
         int target,
         int index,