Avoid use of LWJGL specific ContextCapabilities class.

Instead parse GL_EXTENSIONS and use that to determine supported features.
experimental
shadowislord 11 years ago
parent 18b9ef5540
commit 84046018ba
  1. 17
      jme3-core/src/main/java/com/jme3/renderer/Caps.java
  2. 4
      jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL1Renderer.java
  3. 162
      jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglRenderer.java
  4. 27
      jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/TextureUtil.java

@ -236,7 +236,22 @@ public enum Caps {
/** /**
* Supports sRGB framebuffers and sRGB texture format * 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 * Returns true if given the renderer capabilities, the texture

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

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

@ -32,11 +32,13 @@
package com.jme3.renderer.lwjgl; package com.jme3.renderer.lwjgl;
import com.jme3.renderer.Caps;
import com.jme3.renderer.RendererException; 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 com.jme3.texture.image.ColorSpace; import com.jme3.texture.image.ColorSpace;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.EnumSet;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import static org.lwjgl.opengl.ARBDepthBufferFloat.*; 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.GL12.*;
import static org.lwjgl.opengl.GL13.*; import static org.lwjgl.opengl.GL13.*;
import static org.lwjgl.opengl.GL14.*; import static org.lwjgl.opengl.GL14.*;
import static org.lwjgl.opengl.GL20.*;
class TextureUtil { class TextureUtil {
@ -140,7 +141,7 @@ class TextureUtil {
// LTC/LATC/3Dc formats // LTC/LATC/3Dc formats
setFormat(Format.LTC, GL_COMPRESSED_LUMINANCE_LATC1_EXT, GL_LUMINANCE, GL_UNSIGNED_BYTE, true); 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 //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_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); 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){ switch (fmt){
case DXT1: case DXT1:
case DXT1A: case DXT1A:
case DXT3: case DXT3:
case DXT5: case DXT5:
if (!caps.GL_EXT_texture_compression_s3tc) { if (!caps.contains(Caps.TextureCompressionS3TC)) {
return null; return null;
} }
break; break;
case Depth24Stencil8: case Depth24Stencil8:
if (!caps.OpenGL30 && !caps.GL_EXT_packed_depth_stencil){ if (!caps.contains(Caps.PackedDepthStencilBuffer)){
return null; return null;
} }
break; break;
@ -179,30 +180,30 @@ class TextureUtil {
case RGB32F: case RGB32F:
case RGBA16F: case RGBA16F:
case RGBA32F: case RGBA32F:
if (!caps.OpenGL30 && !caps.GL_ARB_texture_float){ if (!caps.contains(Caps.FloatTexture)){
return null; return null;
} }
break; break;
case Depth32F: case Depth32F:
if (!caps.OpenGL30 && !caps.GL_NV_depth_buffer_float){ if (!caps.contains(Caps.FloatDepthBuffer)){
return null; return null;
} }
break; break;
case LATC: case LATC:
case LTC: case LTC:
if (!caps.GL_EXT_texture_compression_latc){ if (!caps.contains(Caps.TextureCompressionLATC)){
return null; return null;
} }
break; break;
case RGB9E5: case RGB9E5:
case RGB16F_to_RGB9E5: case RGB16F_to_RGB9E5:
if (!caps.OpenGL30 && !caps.GL_EXT_texture_shared_exponent){ if (!caps.contains(Caps.SharedExponentTexture)){
return null; return null;
} }
break; break;
case RGB111110F: case RGB111110F:
case RGB16F_to_RGB111110F: case RGB16F_to_RGB111110F:
if (!caps.OpenGL30 && !caps.GL_EXT_packed_float){ if (!caps.contains(Caps.PackedFloatTexture)){
return null; return null;
} }
break; 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); GLImageFormat glFmt = getImageFormat(caps, fmt, isSrgb);
if (glFmt == null) { 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.");
@ -254,7 +255,7 @@ class TextureUtil {
} }
} }
public static void uploadTexture(ContextCapabilities caps, public static void uploadTexture(EnumSet<Caps> caps,
Image image, Image image,
int target, int target,
int index, int index,
@ -412,7 +413,7 @@ class TextureUtil {
* @param y the y position where to put the image in the texture * @param y the y position where to put the image in the texture
*/ */
public static void uploadSubTexture( public static void uploadSubTexture(
ContextCapabilities caps, EnumSet<Caps> caps,
Image image, Image image,
int target, int target,
int index, int index,

Loading…
Cancel
Save