diff --git a/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java b/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java
index 9472bff0b..991ad25c0 100644
--- a/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java
+++ b/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java
@@ -54,6 +54,7 @@ import com.jme3.input.dummy.DummyMouseInput;
import com.jme3.renderer.android.AndroidGL;
import com.jme3.renderer.opengl.GL;
import com.jme3.renderer.opengl.GLExt;
+import com.jme3.renderer.opengl.GLFbo;
import com.jme3.renderer.opengl.GLRenderer;
import com.jme3.system.*;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -196,7 +197,7 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
Object gl = new AndroidGL();
// gl = GLTracer.createGlesTracer((GL)gl, (GLExt)gl);
// gl = new GLDebugES((GL)gl, (GLExt)gl);
- renderer = new GLRenderer((GL)gl, (GLExt)gl);
+ renderer = new GLRenderer((GL)gl, (GLExt)gl, (GLFbo)gl);
renderer.initialize();
JmeSystem.setSoftTextDialogInput(this);
diff --git a/jme3-core/src/main/java/com/jme3/renderer/Caps.java b/jme3-core/src/main/java/com/jme3/renderer/Caps.java
index f0d42c8f2..9387b687e 100644
--- a/jme3-core/src/main/java/com/jme3/renderer/Caps.java
+++ b/jme3-core/src/main/java/com/jme3/renderer/Caps.java
@@ -337,7 +337,19 @@ public enum Caps {
*
* Improves the quality of environment mapping.
*/
- SeamlessCubemap;
+ SeamlessCubemap,
+
+ /**
+ * Running with OpenGL 3.2+ core profile.
+ *
+ * Compatibility features will not be available.
+ */
+ CoreProfile,
+
+ /**
+ * GPU can provide and accept binary shaders.
+ */
+ BinaryShader;
/**
* Returns true if given the renderer capabilities, the texture
diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GL.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GL.java
index 9c73838e2..21ca7a7fa 100644
--- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GL.java
+++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GL.java
@@ -32,7 +32,6 @@
package com.jme3.renderer.opengl;
import java.nio.ByteBuffer;
-import java.nio.DoubleBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GL3.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GL3.java
index 50eb065ab..190ed4547 100644
--- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GL3.java
+++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GL3.java
@@ -35,14 +35,18 @@ import java.nio.IntBuffer;
/**
* GL functions only available on vanilla desktop OpenGL 3.0.
- *
+ *
* @author Kirill Vainer
*/
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_GEOMETRY_SHADER = 0x8DD9;
+ public static final int GL_NUM_EXTENSIONS = 0x821D;
+
public void glBindFragDataLocation(int param1, int param2, String param3); /// GL3+
public void glBindVertexArray(int param1); /// GL3+
+ public void glDeleteVertexArrays(IntBuffer arrays); /// GL3+
public void glGenVertexArrays(IntBuffer param1); /// GL3+
+ public String glGetString(int param1, int param2); /// GL3+
}
diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLDebugDesktop.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLDebugDesktop.java
index e13402bd5..5fbaaaa52 100644
--- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLDebugDesktop.java
+++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLDebugDesktop.java
@@ -3,13 +3,13 @@ package com.jme3.renderer.opengl;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
-public class GLDebugDesktop extends GLDebugES implements GL2, GL3 {
+public class GLDebugDesktop extends GLDebugES implements GL2, GL3, GL4 {
private final GL2 gl2;
private final GL3 gl3;
- public GLDebugDesktop(GL gl, GLFbo glfbo) {
- super(gl, glfbo);
+ public GLDebugDesktop(GL gl, GLExt glext, GLFbo glfbo) {
+ super(gl, glext, glfbo);
this.gl2 = gl instanceof GL2 ? (GL2) gl : null;
this.gl3 = gl instanceof GL3 ? (GL3) gl : null;
}
@@ -73,5 +73,18 @@ public class GLDebugDesktop extends GLDebugES implements GL2, GL3 {
gl3.glGenVertexArrays(param1);
checkError();
}
+
+ @Override
+ public String glGetString(int param1, int param2) {
+ String result = gl3.glGetString(param1, param2);
+ checkError();
+ return result;
+ }
+
+ @Override
+ public void glDeleteVertexArrays(IntBuffer arrays) {
+ gl3.glDeleteVertexArrays(arrays);
+ checkError();
+ }
}
diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLDebugES.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLDebugES.java
index 259c56406..3e8850589 100644
--- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLDebugES.java
+++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLDebugES.java
@@ -10,12 +10,10 @@ public class GLDebugES extends GLDebug implements GL, GLFbo, GLExt {
private final GLFbo glfbo;
private final GLExt glext;
- public GLDebugES(GL gl, GLFbo glfbo) {
+ public GLDebugES(GL gl, GLExt glext, GLFbo glfbo) {
this.gl = gl;
-// this.gl2 = gl instanceof GL2 ? (GL2) gl : null;
-// this.gl3 = gl instanceof GL3 ? (GL3) gl : null;
+ this.glext = glext;
this.glfbo = glfbo;
- this.glext = glfbo instanceof GLExt ? (GLExt) glfbo : null;
}
public void glActiveTexture(int texture) {
@@ -478,7 +476,7 @@ public class GLDebugES extends GLDebug implements GL, GLFbo, GLExt {
}
public void glBlitFramebufferEXT(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, int mask, int filter) {
- glext.glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+ glfbo.glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
checkError();
}
@@ -525,7 +523,7 @@ public class GLDebugES extends GLDebug implements GL, GLFbo, GLExt {
}
public void glRenderbufferStorageMultisampleEXT(int target, int samples, int internalformat, int width, int height) {
- glext.glRenderbufferStorageMultisampleEXT(target, samples, internalformat, width, height);
+ glfbo.glRenderbufferStorageMultisampleEXT(target, samples, internalformat, width, height);
checkError();
}
diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLExt.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLExt.java
index b0e0b5f78..27f0eb8bd 100644
--- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLExt.java
+++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLExt.java
@@ -41,7 +41,7 @@ import java.nio.IntBuffer;
*
* @author Kirill Vainer
*/
-public interface GLExt extends GLFbo {
+public interface GLExt {
public static final int GL_ALREADY_SIGNALED = 0x911A;
public static final int GL_COMPRESSED_RGB8_ETC2 = 0x9274;
@@ -100,7 +100,6 @@ public interface GLExt extends GLFbo {
public static final int GL_UNSIGNED_INT_5_9_9_9_REV_EXT = 0x8C3E;
public static final int GL_WAIT_FAILED = 0x911D;
- public void glBlitFramebufferEXT(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, int mask, int filter);
public void glBufferData(int target, IntBuffer data, int usage);
public void glBufferSubData(int target, long offset, IntBuffer data);
public int glClientWaitSync(Object sync, int flags, long timeout);
@@ -110,7 +109,6 @@ public interface GLExt extends GLFbo {
public void glDrawElementsInstancedARB(int mode, int indices_count, int type, long indices_buffer_offset, int primcount);
public Object glFenceSync(int condition, int flags);
public void glGetMultisample(int pname, int index, FloatBuffer val);
- public void glRenderbufferStorageMultisampleEXT(int target, int samples, int internalformat, int width, int height);
public void glTexImage2DMultisample(int target, int samples, int internalformat, int width, int height, boolean fixedsamplelocations);
public void glVertexAttribDivisorARB(int index, int divisor);
}
diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLFbo.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLFbo.java
index 252619db8..737019ce2 100644
--- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLFbo.java
+++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLFbo.java
@@ -83,6 +83,7 @@ public interface GLFbo {
public void glBindFramebufferEXT(int param1, int param2);
public void glBindRenderbufferEXT(int param1, int param2);
+ public void glBlitFramebufferEXT(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, int mask, int filter);
public int glCheckFramebufferStatusEXT(int param1);
public void glDeleteFramebuffersEXT(IntBuffer param1);
public void glDeleteRenderbuffersEXT(IntBuffer param1);
@@ -92,5 +93,5 @@ public interface GLFbo {
public void glGenRenderbuffersEXT(IntBuffer param1);
public void glGenerateMipmapEXT(int param1);
public void glRenderbufferStorageEXT(int param1, int param2, int param3, int param4);
-
+ public void glRenderbufferStorageMultisampleEXT(int target, int samples, int internalformat, int width, int height);
}
diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLImageFormats.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLImageFormats.java
index 423ae909e..a7ef9f52d 100644
--- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLImageFormats.java
+++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLImageFormats.java
@@ -89,9 +89,11 @@ public final class GLImageFormats {
GLImageFormat[][] formatToGL = new GLImageFormat[2][Image.Format.values().length];
if (caps.contains(Caps.OpenGL20)) {
- format(formatToGL, Format.Alpha8, GL2.GL_ALPHA8, GL.GL_ALPHA, GL.GL_UNSIGNED_BYTE);
- format(formatToGL, Format.Luminance8, GL2.GL_LUMINANCE8, GL.GL_LUMINANCE, GL.GL_UNSIGNED_BYTE);
- format(formatToGL, Format.Luminance8Alpha8, GL2.GL_LUMINANCE8_ALPHA8, GL.GL_LUMINANCE_ALPHA, GL.GL_UNSIGNED_BYTE);
+ if (!caps.contains(Caps.CoreProfile)) {
+ format(formatToGL, Format.Alpha8, GL2.GL_ALPHA8, GL.GL_ALPHA, GL.GL_UNSIGNED_BYTE);
+ format(formatToGL, Format.Luminance8, GL2.GL_LUMINANCE8, GL.GL_LUMINANCE, GL.GL_UNSIGNED_BYTE);
+ format(formatToGL, Format.Luminance8Alpha8, GL2.GL_LUMINANCE8_ALPHA8, GL.GL_LUMINANCE_ALPHA, GL.GL_UNSIGNED_BYTE);
+ }
format(formatToGL, Format.RGB8, GL2.GL_RGB8, GL.GL_RGB, GL.GL_UNSIGNED_BYTE);
format(formatToGL, Format.RGBA8, GLExt.GL_RGBA8, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE);
format(formatToGL, Format.RGB565, GL2.GL_RGB8, GL.GL_RGB, GL.GL_UNSIGNED_SHORT_5_6_5);
@@ -108,8 +110,10 @@ public final class GLImageFormats {
formatSrgb(formatToGL, Format.RGB565, GLExt.GL_SRGB8_EXT, GL.GL_RGB, GL.GL_UNSIGNED_SHORT_5_6_5);
formatSrgb(formatToGL, Format.RGB5A1, GLExt.GL_SRGB8_ALPHA8_EXT, GL.GL_RGBA, GL.GL_UNSIGNED_SHORT_5_5_5_1);
formatSrgb(formatToGL, Format.RGBA8, GLExt.GL_SRGB8_ALPHA8_EXT, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE);
- formatSrgb(formatToGL, Format.Luminance8, GLExt.GL_SLUMINANCE8_EXT, GL.GL_LUMINANCE, GL.GL_UNSIGNED_BYTE);
- formatSrgb(formatToGL, Format.Luminance8Alpha8, GLExt.GL_SLUMINANCE8_ALPHA8_EXT, GL.GL_LUMINANCE_ALPHA, GL.GL_UNSIGNED_BYTE);
+ if (!caps.contains(Caps.CoreProfile)) {
+ formatSrgb(formatToGL, Format.Luminance8, GLExt.GL_SLUMINANCE8_EXT, GL.GL_LUMINANCE, GL.GL_UNSIGNED_BYTE);
+ formatSrgb(formatToGL, Format.Luminance8Alpha8, GLExt.GL_SLUMINANCE8_ALPHA8_EXT, GL.GL_LUMINANCE_ALPHA, GL.GL_UNSIGNED_BYTE);
+ }
formatSrgb(formatToGL, Format.BGR8, GLExt.GL_SRGB8_EXT, GL2.GL_BGR, GL.GL_UNSIGNED_BYTE);
formatSrgb(formatToGL, Format.ABGR8, GLExt.GL_SRGB8_ALPHA8_EXT, GL.GL_RGBA, GL2.GL_UNSIGNED_INT_8_8_8_8);
formatSrgb(formatToGL, Format.ARGB8, GLExt.GL_SRGB8_ALPHA8_EXT, GL2.GL_BGRA, GL2.GL_UNSIGNED_INT_8_8_8_8);
@@ -124,16 +128,20 @@ public final class GLImageFormats {
}
} else if (caps.contains(Caps.Rgba8)) {
// A more limited form of 32-bit RGBA. Only GL_RGBA8 is available.
- format(formatToGL, Format.Alpha8, GLExt.GL_RGBA8, GL.GL_ALPHA, GL.GL_UNSIGNED_BYTE);
- format(formatToGL, Format.Luminance8, GLExt.GL_RGBA8, GL.GL_LUMINANCE, GL.GL_UNSIGNED_BYTE);
- format(formatToGL, Format.Luminance8Alpha8, GLExt.GL_RGBA8, GL.GL_LUMINANCE_ALPHA, GL.GL_UNSIGNED_BYTE);
+ if (!caps.contains(Caps.CoreProfile)) {
+ format(formatToGL, Format.Alpha8, GLExt.GL_RGBA8, GL.GL_ALPHA, GL.GL_UNSIGNED_BYTE);
+ format(formatToGL, Format.Luminance8, GLExt.GL_RGBA8, GL.GL_LUMINANCE, GL.GL_UNSIGNED_BYTE);
+ format(formatToGL, Format.Luminance8Alpha8, GLExt.GL_RGBA8, GL.GL_LUMINANCE_ALPHA, GL.GL_UNSIGNED_BYTE);
+ }
format(formatToGL, Format.RGB8, GLExt.GL_RGBA8, GL.GL_RGB, GL.GL_UNSIGNED_BYTE);
format(formatToGL, Format.RGBA8, GLExt.GL_RGBA8, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE);
} else {
// Actually, the internal format isn't used for OpenGL ES 2! This is the same as the above..
- format(formatToGL, Format.Alpha8, GL.GL_RGBA4, GL.GL_ALPHA, GL.GL_UNSIGNED_BYTE);
- format(formatToGL, Format.Luminance8, GL.GL_RGB565, GL.GL_LUMINANCE, GL.GL_UNSIGNED_BYTE);
- format(formatToGL, Format.Luminance8Alpha8, GL.GL_RGBA4, GL.GL_LUMINANCE_ALPHA, GL.GL_UNSIGNED_BYTE);
+ if (!caps.contains(Caps.CoreProfile)) {
+ format(formatToGL, Format.Alpha8, GL.GL_RGBA4, GL.GL_ALPHA, GL.GL_UNSIGNED_BYTE);
+ format(formatToGL, Format.Luminance8, GL.GL_RGB565, GL.GL_LUMINANCE, GL.GL_UNSIGNED_BYTE);
+ format(formatToGL, Format.Luminance8Alpha8, GL.GL_RGBA4, GL.GL_LUMINANCE_ALPHA, GL.GL_UNSIGNED_BYTE);
+ }
format(formatToGL, Format.RGB8, GL.GL_RGB565, GL.GL_RGB, GL.GL_UNSIGNED_BYTE);
format(formatToGL, Format.RGBA8, GL.GL_RGBA4, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE);
}
@@ -145,9 +153,11 @@ public final class GLImageFormats {
format(formatToGL, Format.RGB5A1, GL.GL_RGB5_A1, GL.GL_RGBA, GL.GL_UNSIGNED_SHORT_5_5_5_1);
if (caps.contains(Caps.FloatTexture)) {
- format(formatToGL, Format.Luminance16F, GLExt.GL_LUMINANCE16F_ARB, GL.GL_LUMINANCE, GLExt.GL_HALF_FLOAT_ARB);
- format(formatToGL, Format.Luminance32F, GLExt.GL_LUMINANCE32F_ARB, GL.GL_LUMINANCE, GL.GL_FLOAT);
- format(formatToGL, Format.Luminance16FAlpha16F, GLExt.GL_LUMINANCE_ALPHA16F_ARB, GL.GL_LUMINANCE_ALPHA, GLExt.GL_HALF_FLOAT_ARB);
+ if (!caps.contains(Caps.CoreProfile)) {
+ format(formatToGL, Format.Luminance16F, GLExt.GL_LUMINANCE16F_ARB, GL.GL_LUMINANCE, GLExt.GL_HALF_FLOAT_ARB);
+ format(formatToGL, Format.Luminance32F, GLExt.GL_LUMINANCE32F_ARB, GL.GL_LUMINANCE, GL.GL_FLOAT);
+ format(formatToGL, Format.Luminance16FAlpha16F, GLExt.GL_LUMINANCE_ALPHA16F_ARB, GL.GL_LUMINANCE_ALPHA, GLExt.GL_HALF_FLOAT_ARB);
+ }
format(formatToGL, Format.RGB16F, GLExt.GL_RGB16F_ARB, GL.GL_RGB, GLExt.GL_HALF_FLOAT_ARB);
format(formatToGL, Format.RGB32F, GLExt.GL_RGB32F_ARB, GL.GL_RGB, GL.GL_FLOAT);
format(formatToGL, Format.RGBA16F, GLExt.GL_RGBA16F_ARB, GL.GL_RGBA, GLExt.GL_HALF_FLOAT_ARB);
diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java
index 32d8e6b24..7b928202f 100644
--- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java
+++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java
@@ -112,13 +112,13 @@ public class GLRenderer implements Renderer {
private final GLFbo glfbo;
private final TextureUtil texUtil;
- public GLRenderer(GL gl, GLFbo glfbo) {
+ public GLRenderer(GL gl, GLExt glext, GLFbo glfbo) {
this.gl = gl;
this.gl2 = gl instanceof GL2 ? (GL2)gl : null;
this.gl3 = gl instanceof GL3 ? (GL3)gl : null;
this.gl4 = gl instanceof GL4 ? (GL4)gl : null;
this.glfbo = glfbo;
- this.glext = glfbo instanceof GLExt ? (GLExt)glfbo : null;
+ this.glext = glext;
this.texUtil = new TextureUtil(gl, gl2, glext, context);
}
@@ -137,10 +137,19 @@ public class GLRenderer implements Renderer {
return limits;
}
- private static HashSet loadExtensions(String extensions) {
+ private HashSet loadExtensions() {
HashSet extensionSet = new HashSet(64);
- for (String extension : extensions.split(" ")) {
- extensionSet.add(extension);
+ if (gl3 != null) {
+ // If OpenGL3+ is available, use the non-deprecated way
+ // of getting supported extensions.
+ gl3.glGetInteger(GL3.GL_NUM_EXTENSIONS, intBuf16);
+ int extensionCount = intBuf16.get(0);
+ for (int i = 0; i < extensionCount; i++) {
+ String extension = gl3.glGetString(GL.GL_EXTENSIONS, i);
+ extensionSet.add(extension);
+ }
+ } else {
+ extensionSet.addAll(Arrays.asList(gl.glGetString(GL.GL_EXTENSIONS).split(" ")));
}
return extensionSet;
}
@@ -185,10 +194,12 @@ public class GLRenderer implements Renderer {
caps.add(Caps.OpenGL31);
if (oglVer >= 320) {
caps.add(Caps.OpenGL32);
- }if(oglVer>=330){
+ }
+ if (oglVer >= 330) {
caps.add(Caps.OpenGL33);
caps.add(Caps.GeometryShader);
- }if(oglVer>=400){
+ }
+ if (oglVer >= 400) {
caps.add(Caps.OpenGL40);
caps.add(Caps.TesselationShader);
}
@@ -243,7 +254,7 @@ public class GLRenderer implements Renderer {
}
private void loadCapabilitiesCommon() {
- extensions = loadExtensions(gl.glGetString(GL.GL_EXTENSIONS));
+ extensions = loadExtensions();
limits.put(Limits.VertexTextureUnits, getInteger(GL.GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS));
if (limits.get(Limits.VertexTextureUnits) > 0) {
@@ -251,7 +262,7 @@ public class GLRenderer implements Renderer {
}
limits.put(Limits.FragmentTextureUnits, getInteger(GL.GL_MAX_TEXTURE_IMAGE_UNITS));
-
+
// gl.glGetInteger(GL.GL_MAX_VERTEX_UNIFORM_COMPONENTS, intBuf16);
// vertexUniforms = intBuf16.get(0);
// logger.log(Level.FINER, "Vertex Uniforms: {0}", vertexUniforms);
@@ -279,7 +290,7 @@ public class GLRenderer implements Renderer {
// == texture format extensions ==
- boolean hasFloatTexture = false;
+ boolean hasFloatTexture;
hasFloatTexture = hasExtension("GL_OES_texture_half_float") &&
hasExtension("GL_OES_texture_float");
@@ -375,11 +386,11 @@ public class GLRenderer implements Renderer {
caps.add(Caps.TextureFilterAnisotropic);
}
- if (hasExtension("GL_EXT_framebuffer_object")) {
+ if (hasExtension("GL_EXT_framebuffer_object") || gl3 != null) {
caps.add(Caps.FrameBuffer);
- limits.put(Limits.RenderBufferSize, getInteger(GLExt.GL_MAX_RENDERBUFFER_SIZE_EXT));
- limits.put(Limits.FrameBufferAttachments, getInteger(GLExt.GL_MAX_COLOR_ATTACHMENTS_EXT));
+ limits.put(Limits.RenderBufferSize, getInteger(GLFbo.GL_MAX_RENDERBUFFER_SIZE_EXT));
+ limits.put(Limits.FrameBufferAttachments, getInteger(GLFbo.GL_MAX_COLOR_ATTACHMENTS_EXT));
if (hasExtension("GL_EXT_framebuffer_blit")) {
caps.add(Caps.FrameBufferBlit);
@@ -434,21 +445,30 @@ public class GLRenderer implements Renderer {
caps.add(Caps.SeamlessCubemap);
}
-// if (hasExtension("GL_ARB_get_program_binary")) {
-// int binaryFormats = getInteger(GLExt.GL_NUM_PROGRAM_BINARY_FORMATS);
-// }
+ if (caps.contains(Caps.OpenGL32) && !hasExtension("GL_ARB_compatibility")) {
+ caps.add(Caps.CoreProfile);
+ }
+
+ if (hasExtension("GL_ARB_get_program_binary")) {
+ int binaryFormats = getInteger(GLExt.GL_NUM_PROGRAM_BINARY_FORMATS);
+ if (binaryFormats > 0) {
+ caps.add(Caps.BinaryShader);
+ }
+ }
// Print context information
logger.log(Level.INFO, "OpenGL Renderer Information\n" +
" * Vendor: {0}\n" +
" * Renderer: {1}\n" +
" * OpenGL Version: {2}\n" +
- " * GLSL Version: {3}",
+ " * GLSL Version: {3}\n" +
+ " * Profile: {4}",
new Object[]{
gl.glGetString(GL.GL_VENDOR),
gl.glGetString(GL.GL_RENDERER),
gl.glGetString(GL.GL_VERSION),
- gl.glGetString(GL.GL_SHADING_LANGUAGE_VERSION)
+ gl.glGetString(GL.GL_SHADING_LANGUAGE_VERSION),
+ caps.contains(Caps.CoreProfile) ? "Core" : "Compatibility"
});
// Print capabilities (if fine logging is enabled)
@@ -491,6 +511,20 @@ public class GLRenderer implements Renderer {
// Initialize default state..
gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1);
+
+ if (caps.contains(Caps.CoreProfile)) {
+ // Core Profile requires VAO to be bound.
+ gl3.glGenVertexArrays(intBuf16);
+ int vaoId = intBuf16.get(0);
+ gl3.glBindVertexArray(vaoId);
+ }
+ if (gl2 != null) {
+ gl2.glEnable(GL2.GL_VERTEX_PROGRAM_POINT_SIZE);
+ if (!caps.contains(Caps.CoreProfile)) {
+ gl2.glEnable(GL2.GL_POINT_SPRITE);
+ context.pointSprite = true;
+ }
+ }
}
public void invalidateState() {
@@ -610,31 +644,6 @@ public class GLRenderer implements Renderer {
context.colorWriteEnabled = false;
}
- if (gl2 != null) {
- if (state.isPointSprite() && !context.pointSprite) {
- // Only enable/disable sprite
- if (context.boundTextures[0] != null) {
- if (context.boundTextureUnit != 0) {
- gl.glActiveTexture(GL.GL_TEXTURE0);
- context.boundTextureUnit = 0;
- }
- gl2.glEnable(GL2.GL_POINT_SPRITE);
- gl2.glEnable(GL2.GL_VERTEX_PROGRAM_POINT_SIZE);
- }
- context.pointSprite = true;
- } else if (!state.isPointSprite() && context.pointSprite) {
- if (context.boundTextures[0] != null) {
- if (context.boundTextureUnit != 0) {
- gl.glActiveTexture(GL.GL_TEXTURE0);
- context.boundTextureUnit = 0;
- }
- gl2.glDisable(GL2.GL_POINT_SPRITE);
- gl2.glDisable(GL2.GL_VERTEX_PROGRAM_POINT_SIZE);
- context.pointSprite = false;
- }
- }
- }
-
if (state.isPolyOffset()) {
if (!context.polyOffsetEnabled) {
gl.glEnable(GL.GL_POLYGON_OFFSET_FILL);
@@ -1288,24 +1297,24 @@ public class GLRenderer implements Renderer {
}
if (src == null) {
- glfbo.glBindFramebufferEXT(GLExt.GL_READ_FRAMEBUFFER_EXT, 0);
+ glfbo.glBindFramebufferEXT(GLFbo.GL_READ_FRAMEBUFFER_EXT, 0);
srcX0 = vpX;
srcY0 = vpY;
srcX1 = vpX + vpW;
srcY1 = vpY + vpH;
} else {
- glfbo.glBindFramebufferEXT(GLExt.GL_READ_FRAMEBUFFER_EXT, src.getId());
+ glfbo.glBindFramebufferEXT(GLFbo.GL_READ_FRAMEBUFFER_EXT, src.getId());
srcX1 = src.getWidth();
srcY1 = src.getHeight();
}
if (dst == null) {
- glfbo.glBindFramebufferEXT(GLExt.GL_DRAW_FRAMEBUFFER_EXT, 0);
+ glfbo.glBindFramebufferEXT(GLFbo.GL_DRAW_FRAMEBUFFER_EXT, 0);
dstX0 = vpX;
dstY0 = vpY;
dstX1 = vpX + vpW;
dstY1 = vpY + vpH;
} else {
- glfbo.glBindFramebufferEXT(GLExt.GL_DRAW_FRAMEBUFFER_EXT, dst.getId());
+ glfbo.glBindFramebufferEXT(GLFbo.GL_DRAW_FRAMEBUFFER_EXT, dst.getId());
dstX1 = dst.getWidth();
dstY1 = dst.getHeight();
}
@@ -1313,12 +1322,12 @@ public class GLRenderer implements Renderer {
if (copyDepth) {
mask |= GL.GL_DEPTH_BUFFER_BIT;
}
- glext.glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1,
+ glfbo.glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1,
dstX0, dstY0, dstX1, dstY1, mask,
GL.GL_NEAREST);
- glfbo.glBindFramebufferEXT(GLExt.GL_FRAMEBUFFER_EXT, prevFBO);
+ glfbo.glBindFramebufferEXT(GLFbo.GL_FRAMEBUFFER_EXT, prevFBO);
} else {
throw new RendererException("Framebuffer blitting not supported by the video hardware");
}
@@ -1364,7 +1373,7 @@ public class GLRenderer implements Renderer {
}
if (context.boundRB != id) {
- glfbo.glBindRenderbufferEXT(GLExt.GL_RENDERBUFFER_EXT, id);
+ glfbo.glBindRenderbufferEXT(GLFbo.GL_RENDERBUFFER_EXT, id);
context.boundRB = id;
}
@@ -1382,13 +1391,13 @@ public class GLRenderer implements Renderer {
if (maxSamples < samples) {
samples = maxSamples;
}
- glext.glRenderbufferStorageMultisampleEXT(GLExt.GL_RENDERBUFFER_EXT,
+ glfbo.glRenderbufferStorageMultisampleEXT(GLFbo.GL_RENDERBUFFER_EXT,
samples,
glFmt.internalFormat,
fb.getWidth(),
fb.getHeight());
} else {
- glfbo.glRenderbufferStorageEXT(GLExt.GL_RENDERBUFFER_EXT,
+ glfbo.glRenderbufferStorageEXT(GLFbo.GL_RENDERBUFFER_EXT,
glFmt.internalFormat,
fb.getWidth(),
fb.getHeight());
@@ -1398,7 +1407,7 @@ public class GLRenderer implements Renderer {
private int convertAttachmentSlot(int attachmentSlot) {
// can also add support for stencil here
if (attachmentSlot == FrameBuffer.SLOT_DEPTH) {
- return GLExt.GL_DEPTH_ATTACHMENT_EXT;
+ return GLFbo.GL_DEPTH_ATTACHMENT_EXT;
} else if (attachmentSlot == FrameBuffer.SLOT_DEPTH_STENCIL) {
// NOTE: Using depth stencil format requires GL3, this is already
// checked via render caps.
@@ -1407,7 +1416,7 @@ public class GLRenderer implements Renderer {
throw new UnsupportedOperationException("Invalid FBO attachment slot: " + attachmentSlot);
}
- return GLExt.GL_COLOR_ATTACHMENT0_EXT + attachmentSlot;
+ return GLFbo.GL_COLOR_ATTACHMENT0_EXT + attachmentSlot;
}
public void updateRenderTexture(FrameBuffer fb, RenderBuffer rb) {
@@ -1425,7 +1434,7 @@ public class GLRenderer implements Renderer {
setupTextureParams(tex);
}
- glfbo.glFramebufferTexture2DEXT(GLExt.GL_FRAMEBUFFER_EXT,
+ glfbo.glFramebufferTexture2DEXT(GLFbo.GL_FRAMEBUFFER_EXT,
convertAttachmentSlot(rb.getSlot()),
convertTextureType(tex.getType(), image.getMultiSamples(), rb.getFace()),
image.getId(),
@@ -1443,9 +1452,9 @@ public class GLRenderer implements Renderer {
updateRenderTexture(fb, rb);
}
if (needAttach) {
- glfbo.glFramebufferRenderbufferEXT(GLExt.GL_FRAMEBUFFER_EXT,
+ glfbo.glFramebufferRenderbufferEXT(GLFbo.GL_FRAMEBUFFER_EXT,
convertAttachmentSlot(rb.getSlot()),
- GLExt.GL_RENDERBUFFER_EXT,
+ GLFbo.GL_RENDERBUFFER_EXT,
rb.getId());
}
}
@@ -1463,7 +1472,7 @@ public class GLRenderer implements Renderer {
}
if (context.boundFBO != id) {
- glfbo.glBindFramebufferEXT(GLExt.GL_FRAMEBUFFER_EXT, id);
+ glfbo.glBindFramebufferEXT(GLFbo.GL_FRAMEBUFFER_EXT, id);
// binding an FBO automatically sets draw buf to GL_COLOR_ATTACHMENT0
context.boundDrawBuf = 0;
context.boundFBO = id;
@@ -1543,7 +1552,7 @@ public class GLRenderer implements Renderer {
if (fb == null) {
// unbind any fbos
if (context.boundFBO != 0) {
- glfbo.glBindFramebufferEXT(GLExt.GL_FRAMEBUFFER_EXT, 0);
+ glfbo.glBindFramebufferEXT(GLFbo.GL_FRAMEBUFFER_EXT, 0);
statistics.onFrameBufferUse(null, true);
context.boundFBO = 0;
@@ -1575,7 +1584,7 @@ public class GLRenderer implements Renderer {
setViewPort(0, 0, fb.getWidth(), fb.getHeight());
if (context.boundFBO != fb.getId()) {
- glfbo.glBindFramebufferEXT(GLExt.GL_FRAMEBUFFER_EXT, fb.getId());
+ glfbo.glBindFramebufferEXT(GLFbo.GL_FRAMEBUFFER_EXT, fb.getId());
statistics.onFrameBufferUse(fb, true);
context.boundFBO = fb.getId();
@@ -1615,7 +1624,7 @@ public class GLRenderer implements Renderer {
if (context.boundDrawBuf != 100 + fb.getNumColorBuffers()) {
intBuf16.clear();
for (int i = 0; i < fb.getNumColorBuffers(); i++) {
- intBuf16.put(GLExt.GL_COLOR_ATTACHMENT0_EXT + i);
+ intBuf16.put(GLFbo.GL_COLOR_ATTACHMENT0_EXT + i);
}
intBuf16.flip();
@@ -1627,7 +1636,7 @@ public class GLRenderer implements Renderer {
// select this draw buffer
if (gl2 != null) {
if (context.boundDrawBuf != rb.getSlot()) {
- gl2.glDrawBuffer(GLExt.GL_COLOR_ATTACHMENT0_EXT + rb.getSlot());
+ gl2.glDrawBuffer(GLFbo.GL_COLOR_ATTACHMENT0_EXT + rb.getSlot());
context.boundDrawBuf = rb.getSlot();
}
}
@@ -1656,7 +1665,7 @@ public class GLRenderer implements Renderer {
setFrameBuffer(fb);
if (gl2 != null) {
if (context.boundReadBuf != rb.getSlot()) {
- gl2.glReadBuffer(GLExt.GL_COLOR_ATTACHMENT0_EXT + rb.getSlot());
+ gl2.glReadBuffer(GLFbo.GL_COLOR_ATTACHMENT0_EXT + rb.getSlot());
context.boundReadBuf = rb.getSlot();
}
}
@@ -1680,7 +1689,7 @@ public class GLRenderer implements Renderer {
public void deleteFrameBuffer(FrameBuffer fb) {
if (fb.getId() != -1) {
if (context.boundFBO == fb.getId()) {
- glfbo.glBindFramebufferEXT(GLExt.GL_FRAMEBUFFER_EXT, 0);
+ glfbo.glBindFramebufferEXT(GLFbo.GL_FRAMEBUFFER_EXT, 0);
context.boundFBO = 0;
}
@@ -2618,32 +2627,13 @@ public class GLRenderer implements Renderer {
return;
}
- if (context.pointSprite && mesh.getMode() != Mode.Points) {
- // XXX: Hack, disable point sprite mode if mesh not in point mode
- if (context.boundTextures[0] != null) {
- if (context.boundTextureUnit != 0) {
- gl.glActiveTexture(GL.GL_TEXTURE0);
- context.boundTextureUnit = 0;
- }
- if (gl2 != null) {
- gl2.glDisable(GL2.GL_POINT_SPRITE);
- gl2.glDisable(GL2.GL_VERTEX_PROGRAM_POINT_SIZE);
- }
- context.pointSprite = false;
- }
- }
- if (gl2 != null) {
- if (context.pointSize != mesh.getPointSize()) {
- gl2.glPointSize(mesh.getPointSize());
- context.pointSize = mesh.getPointSize();
- }
- }
if (context.lineWidth != mesh.getLineWidth()) {
gl.glLineWidth(mesh.getLineWidth());
context.lineWidth = mesh.getLineWidth();
}
- if(gl4!=null && mesh.getMode().equals(Mode.Patch)){
+
+ if (gl4 != null && mesh.getMode().equals(Mode.Patch)) {
gl4.glPatchParameter(mesh.getPatchVertexCount());
}
statistics.onMeshDrawn(mesh, lod, count);
diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLTracer.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLTracer.java
index b69d524b4..1b0d70749 100644
--- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLTracer.java
+++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLTracer.java
@@ -64,6 +64,7 @@ public final class GLTracer implements InvocationHandler {
noEnumArgs("glScissor", 0, 1, 2, 3);
noEnumArgs("glClear", 0);
noEnumArgs("glGetInteger", 1);
+ noEnumArgs("glGetString", 1);
noEnumArgs("glBindTexture", 1);
noEnumArgs("glPixelStorei", 1);
@@ -95,8 +96,6 @@ public final class GLTracer implements InvocationHandler {
noEnumArgs("glFramebufferTexture2DEXT", 3, 4);
noEnumArgs("glBlitFramebufferEXT", 0, 1, 2, 3, 4, 5, 6, 7, 8);
-
-
noEnumArgs("glCreateProgram", -1);
noEnumArgs("glCreateShader", -1);
noEnumArgs("glShaderSource", 0);
@@ -155,7 +154,7 @@ public final class GLTracer implements InvocationHandler {
* @return A tracer that implements the given interface
*/
public static Object createGlesTracer(Object glInterface, Class> glInterfaceClass) {
- IntMap constMap = generateConstantMap(GL.class, GLExt.class);
+ IntMap constMap = generateConstantMap(GL.class, GLFbo.class, GLExt.class);
return Proxy.newProxyInstance(glInterface.getClass().getClassLoader(),
new Class>[] { glInterfaceClass },
new GLTracer(glInterface, constMap));
@@ -169,7 +168,7 @@ public final class GLTracer implements InvocationHandler {
* @return A tracer that implements the given interface
*/
public static Object createDesktopGlTracer(Object glInterface, Class> ... glInterfaceClasses) {
- IntMap constMap = generateConstantMap(GL2.class, GLExt.class);
+ IntMap constMap = generateConstantMap(GL2.class, GL3.class, GL4.class, GLFbo.class, GLExt.class);
return Proxy.newProxyInstance(glInterface.getClass().getClassLoader(),
glInterfaceClasses,
new GLTracer(glInterface, constMap));
diff --git a/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java b/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java
index 7feaeae5b..2d046550e 100644
--- a/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java
+++ b/jme3-ios/src/main/java/com/jme3/system/ios/IGLESContext.java
@@ -40,6 +40,7 @@ import com.jme3.renderer.ios.IosGL;
import com.jme3.renderer.opengl.GL;
import com.jme3.renderer.opengl.GLDebugES;
import com.jme3.renderer.opengl.GLExt;
+import com.jme3.renderer.opengl.GLFbo;
import com.jme3.renderer.opengl.GLRenderer;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
@@ -158,11 +159,11 @@ public class IGLESContext implements JmeContext {
GLExt glext = (GLExt) gl;
// if (settings.getBoolean("GraphicsDebug")) {
- gl = new GLDebugES(gl, glext);
+ gl = new GLDebugES(gl, glext, (GLFbo) glext);
glext = (GLExt) gl;
// }
- renderer = new GLRenderer(gl, glext);
+ renderer = new GLRenderer(gl, glext, (GLFbo) glext);
renderer.initialize();
input = new IosInputHandler();
diff --git a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java
index 82b8ee72b..0b55a3a40 100644
--- a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java
+++ b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java
@@ -13,7 +13,7 @@ import java.nio.ShortBuffer;
import com.jme3.renderer.opengl.GL4;
import org.lwjgl.opengl.*;
-public class LwjglGL implements GL, GL2, GL3,GL4 {
+public class LwjglGL implements GL, GL2, GL3, GL4 {
private static void checkLimit(Buffer buffer) {
if (buffer == null) {
@@ -237,6 +237,10 @@ public class LwjglGL implements GL, GL2, GL3,GL4 {
public String glGetString(int param1) {
return GL11.glGetString(param1);
}
+
+ public String glGetString(int param1, int param2) {
+ return GL30.glGetStringi(param1, param2);
+ }
public boolean glIsEnabled(int param1) {
return GL11.glIsEnabled(param1);
@@ -444,4 +448,10 @@ public class LwjglGL implements GL, GL2, GL3,GL4 {
public void glPatchParameter(int count) {
GL40.glPatchParameteri(GL40.GL_PATCH_VERTICES,count);
}
+
+ @Override
+ public void glDeleteVertexArrays(IntBuffer arrays) {
+ checkLimit(arrays);
+ ARBVertexArrayObject.glDeleteVertexArrays(arrays);
+ }
}
diff --git a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGLExt.java b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGLExt.java
index 89139282a..2c6a63fd7 100644
--- a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGLExt.java
+++ b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGLExt.java
@@ -7,12 +7,8 @@ import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import org.lwjgl.opengl.ARBDrawInstanced;
import org.lwjgl.opengl.ARBInstancedArrays;
-import org.lwjgl.opengl.ARBPixelBufferObject;
import org.lwjgl.opengl.ARBSync;
import org.lwjgl.opengl.ARBTextureMultisample;
-import org.lwjgl.opengl.EXTFramebufferBlit;
-import org.lwjgl.opengl.EXTFramebufferMultisample;
-import org.lwjgl.opengl.EXTFramebufferObject;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GLSync;
@@ -30,99 +26,51 @@ public class LwjglGLExt implements GLExt {
throw new RendererException("Attempting to upload empty buffer (remaining = 0), that's an error");
}
}
-
- public void glBlitFramebufferEXT(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, int mask, int filter) {
- EXTFramebufferBlit.glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
- }
+ @Override
public void glBufferData(int target, IntBuffer data, int usage) {
checkLimit(data);
GL15.glBufferData(target, data, usage);
}
+ @Override
public void glBufferSubData(int target, long offset, IntBuffer data) {
checkLimit(data);
GL15.glBufferSubData(target, offset, data);
}
+ @Override
public void glDrawArraysInstancedARB(int mode, int first, int count, int primcount) {
ARBDrawInstanced.glDrawArraysInstancedARB(mode, first, count, primcount);
}
+ @Override
public void glDrawBuffers(IntBuffer bufs) {
checkLimit(bufs);
GL20.glDrawBuffers(bufs);
}
+ @Override
public void glDrawElementsInstancedARB(int mode, int indices_count, int type, long indices_buffer_offset, int primcount) {
ARBDrawInstanced.glDrawElementsInstancedARB(mode, indices_count, type, indices_buffer_offset, primcount);
}
+ @Override
public void glGetMultisample(int pname, int index, FloatBuffer val) {
checkLimit(val);
ARBTextureMultisample.glGetMultisample(pname, index, val);
}
- public void glRenderbufferStorageMultisampleEXT(int target, int samples, int internalformat, int width, int height) {
- EXTFramebufferMultisample.glRenderbufferStorageMultisampleEXT(target, samples, internalformat, width, height);
- }
-
+ @Override
public void glTexImage2DMultisample(int target, int samples, int internalformat, int width, int height, boolean fixedsamplelocations) {
ARBTextureMultisample.glTexImage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations);
}
+ @Override
public void glVertexAttribDivisorARB(int index, int divisor) {
ARBInstancedArrays.glVertexAttribDivisorARB(index, divisor);
}
- public void glBindFramebufferEXT(int param1, int param2) {
- EXTFramebufferObject.glBindFramebufferEXT(param1, param2);
- }
-
- public void glBindRenderbufferEXT(int param1, int param2) {
- EXTFramebufferObject.glBindRenderbufferEXT(param1, param2);
- }
-
- public int glCheckFramebufferStatusEXT(int param1) {
- return EXTFramebufferObject.glCheckFramebufferStatusEXT(param1);
- }
-
- public void glDeleteFramebuffersEXT(IntBuffer param1) {
- checkLimit(param1);
- EXTFramebufferObject.glDeleteFramebuffersEXT(param1);
- }
-
- public void glDeleteRenderbuffersEXT(IntBuffer param1) {
- checkLimit(param1);
- EXTFramebufferObject.glDeleteRenderbuffersEXT(param1);
- }
-
- public void glFramebufferRenderbufferEXT(int param1, int param2, int param3, int param4) {
- EXTFramebufferObject.glFramebufferRenderbufferEXT(param1, param2, param3, param4);
- }
-
- public void glFramebufferTexture2DEXT(int param1, int param2, int param3, int param4, int param5) {
- EXTFramebufferObject.glFramebufferTexture2DEXT(param1, param2, param3, param4, param5);
- }
-
- public void glGenFramebuffersEXT(IntBuffer param1) {
- checkLimit(param1);
- EXTFramebufferObject.glGenFramebuffersEXT(param1);
- }
-
- public void glGenRenderbuffersEXT(IntBuffer param1) {
- checkLimit(param1);
- EXTFramebufferObject.glGenRenderbuffersEXT(param1);
- }
-
- public void glGenerateMipmapEXT(int param1) {
- EXTFramebufferObject.glGenerateMipmapEXT(param1);
- }
-
- public void glRenderbufferStorageEXT(int param1, int param2, int param3, int param4) {
- EXTFramebufferObject.glRenderbufferStorageEXT(param1, param2, param3, param4);
- }
-
@Override
public Object glFenceSync(int condition, int flags) {
return ARBSync.glFenceSync(condition, flags);
diff --git a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGLFboEXT.java b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGLFboEXT.java
new file mode 100644
index 000000000..159000a6c
--- /dev/null
+++ b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGLFboEXT.java
@@ -0,0 +1,98 @@
+package com.jme3.renderer.lwjgl;
+
+import com.jme3.renderer.RendererException;
+import com.jme3.renderer.opengl.GLFbo;
+import java.nio.Buffer;
+import java.nio.IntBuffer;
+import org.lwjgl.opengl.EXTFramebufferBlit;
+import org.lwjgl.opengl.EXTFramebufferMultisample;
+import org.lwjgl.opengl.EXTFramebufferObject;
+
+/**
+ * Implements GLFbo via GL_EXT_framebuffer_object.
+ *
+ * @author Kirill Vainer
+ */
+public class LwjglGLFboEXT implements GLFbo {
+
+ private static void checkLimit(Buffer buffer) {
+ if (buffer == null) {
+ return;
+ }
+ if (buffer.limit() == 0) {
+ throw new RendererException("Attempting to upload empty buffer (limit = 0), that's an error");
+ }
+ if (buffer.remaining() == 0) {
+ throw new RendererException("Attempting to upload empty buffer (remaining = 0), that's an error");
+ }
+ }
+
+ @Override
+ public void glBlitFramebufferEXT(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, int mask, int filter) {
+ EXTFramebufferBlit.glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+ }
+
+ @Override
+ public void glRenderbufferStorageMultisampleEXT(int target, int samples, int internalformat, int width, int height) {
+ EXTFramebufferMultisample.glRenderbufferStorageMultisampleEXT(target, samples, internalformat, width, height);
+ }
+
+ @Override
+ public void glBindFramebufferEXT(int param1, int param2) {
+ EXTFramebufferObject.glBindFramebufferEXT(param1, param2);
+ }
+
+ @Override
+ public void glBindRenderbufferEXT(int param1, int param2) {
+ EXTFramebufferObject.glBindRenderbufferEXT(param1, param2);
+ }
+
+ @Override
+ public int glCheckFramebufferStatusEXT(int param1) {
+ return EXTFramebufferObject.glCheckFramebufferStatusEXT(param1);
+ }
+
+ @Override
+ public void glDeleteFramebuffersEXT(IntBuffer param1) {
+ checkLimit(param1);
+ EXTFramebufferObject.glDeleteFramebuffersEXT(param1);
+ }
+
+ @Override
+ public void glDeleteRenderbuffersEXT(IntBuffer param1) {
+ checkLimit(param1);
+ EXTFramebufferObject.glDeleteRenderbuffersEXT(param1);
+ }
+
+ @Override
+ public void glFramebufferRenderbufferEXT(int param1, int param2, int param3, int param4) {
+ EXTFramebufferObject.glFramebufferRenderbufferEXT(param1, param2, param3, param4);
+ }
+
+ @Override
+ public void glFramebufferTexture2DEXT(int param1, int param2, int param3, int param4, int param5) {
+ EXTFramebufferObject.glFramebufferTexture2DEXT(param1, param2, param3, param4, param5);
+ }
+
+ @Override
+ public void glGenFramebuffersEXT(IntBuffer param1) {
+ checkLimit(param1);
+ EXTFramebufferObject.glGenFramebuffersEXT(param1);
+ }
+
+ @Override
+ public void glGenRenderbuffersEXT(IntBuffer param1) {
+ checkLimit(param1);
+ EXTFramebufferObject.glGenRenderbuffersEXT(param1);
+ }
+
+ @Override
+ public void glGenerateMipmapEXT(int param1) {
+ EXTFramebufferObject.glGenerateMipmapEXT(param1);
+ }
+
+ @Override
+ public void glRenderbufferStorageEXT(int param1, int param2, int param3, int param4) {
+ EXTFramebufferObject.glRenderbufferStorageEXT(param1, param2, param3, param4);
+ }
+}
diff --git a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGLFboGL3.java b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGLFboGL3.java
new file mode 100644
index 000000000..acc540273
--- /dev/null
+++ b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGLFboGL3.java
@@ -0,0 +1,96 @@
+package com.jme3.renderer.lwjgl;
+
+import com.jme3.renderer.RendererException;
+import com.jme3.renderer.opengl.GLFbo;
+import java.nio.Buffer;
+import java.nio.IntBuffer;
+import org.lwjgl.opengl.GL30;
+
+/**
+ * Implements GLFbo via OpenGL3+.
+ *
+ * @author Kirill Vainer
+ */
+public class LwjglGLFboGL3 implements GLFbo {
+
+ private static void checkLimit(Buffer buffer) {
+ if (buffer == null) {
+ return;
+ }
+ if (buffer.limit() == 0) {
+ throw new RendererException("Attempting to upload empty buffer (limit = 0), that's an error");
+ }
+ if (buffer.remaining() == 0) {
+ throw new RendererException("Attempting to upload empty buffer (remaining = 0), that's an error");
+ }
+ }
+
+ @Override
+ public void glBlitFramebufferEXT(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, int mask, int filter) {
+ GL30.glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+ }
+
+ @Override
+ public void glRenderbufferStorageMultisampleEXT(int target, int samples, int internalformat, int width, int height) {
+ GL30.glRenderbufferStorageMultisample(target, samples, internalformat, width, height);
+ }
+
+ @Override
+ public void glBindFramebufferEXT(int param1, int param2) {
+ GL30.glBindFramebuffer(param1, param2);
+ }
+
+ @Override
+ public void glBindRenderbufferEXT(int param1, int param2) {
+ GL30.glBindRenderbuffer(param1, param2);
+ }
+
+ @Override
+ public int glCheckFramebufferStatusEXT(int param1) {
+ return GL30.glCheckFramebufferStatus(param1);
+ }
+
+ @Override
+ public void glDeleteFramebuffersEXT(IntBuffer param1) {
+ checkLimit(param1);
+ GL30.glDeleteFramebuffers(param1);
+ }
+
+ @Override
+ public void glDeleteRenderbuffersEXT(IntBuffer param1) {
+ checkLimit(param1);
+ GL30.glDeleteRenderbuffers(param1);
+ }
+
+ @Override
+ public void glFramebufferRenderbufferEXT(int param1, int param2, int param3, int param4) {
+ GL30.glFramebufferRenderbuffer(param1, param2, param3, param4);
+ }
+
+ @Override
+ public void glFramebufferTexture2DEXT(int param1, int param2, int param3, int param4, int param5) {
+ GL30.glFramebufferTexture2D(param1, param2, param3, param4, param5);
+ }
+
+ @Override
+ public void glGenFramebuffersEXT(IntBuffer param1) {
+ checkLimit(param1);
+ GL30.glGenFramebuffers(param1);
+ }
+
+ @Override
+ public void glGenRenderbuffersEXT(IntBuffer param1) {
+ checkLimit(param1);
+ GL30.glGenRenderbuffers(param1);
+ }
+
+ @Override
+ public void glGenerateMipmapEXT(int param1) {
+ GL30.glGenerateMipmap(param1);
+ }
+
+ @Override
+ public void glRenderbufferStorageEXT(int param1, int param2, int param3, int param4) {
+ GL30.glRenderbufferStorage(param1, param2, param3, param4);
+ }
+}
diff --git a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglContext.java b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglContext.java
index 1286323ef..57ef81c0a 100644
--- a/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglContext.java
+++ b/jme3-lwjgl/src/main/java/com/jme3/system/lwjgl/LwjglContext.java
@@ -39,13 +39,18 @@ import com.jme3.renderer.Renderer;
import com.jme3.renderer.RendererException;
import com.jme3.renderer.lwjgl.LwjglGL;
import com.jme3.renderer.lwjgl.LwjglGLExt;
+import com.jme3.renderer.lwjgl.LwjglGLFboEXT;
+import com.jme3.renderer.lwjgl.LwjglGLFboGL3;
import com.jme3.renderer.opengl.GL;
import com.jme3.renderer.opengl.GL2;
import com.jme3.renderer.opengl.GL3;
+import com.jme3.renderer.opengl.GL4;
import com.jme3.renderer.opengl.GLDebugDesktop;
import com.jme3.renderer.opengl.GLExt;
import com.jme3.renderer.opengl.GLFbo;
import com.jme3.renderer.opengl.GLRenderer;
+import com.jme3.renderer.opengl.GLTiming;
+import com.jme3.renderer.opengl.GLTimingState;
import com.jme3.renderer.opengl.GLTracer;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeContext;
@@ -203,21 +208,30 @@ public abstract class LwjglContext implements JmeContext {
}
if (settings.getRenderer().equals(AppSettings.LWJGL_OPENGL2)
- || settings.getRenderer().equals(AppSettings.LWJGL_OPENGL3)) {
+ || settings.getRenderer().equals(AppSettings.LWJGL_OPENGL3)) {
GL gl = new LwjglGL();
- GLFbo glfbo = new LwjglGLExt();
+ GLExt glext = new LwjglGLExt();
+ GLFbo glfbo;
+
+ if (GLContext.getCapabilities().OpenGL30) {
+ glfbo = new LwjglGLFboGL3();
+ } else {
+ glfbo = new LwjglGLFboEXT();
+ }
if (settings.getBoolean("GraphicsDebug")) {
- gl = new GLDebugDesktop(gl, glfbo);
+ gl = new GLDebugDesktop(gl, glext, glfbo);
+ glext = (GLExt) gl;
glfbo = (GLFbo) gl;
}
if (settings.getBoolean("GraphicsTrace")) {
- gl = (GL) GLTracer.createDesktopGlTracer(gl, GL.class, GL2.class, GL3.class);
- glfbo = (GLFbo) GLTracer.createDesktopGlTracer(glfbo, GLExt.class);
+ gl = (GL) GLTracer.createDesktopGlTracer(gl, GL.class, GL2.class, GL3.class, GL4.class);
+ glext = (GLExt) GLTracer.createDesktopGlTracer(glext, GLExt.class);
+ glfbo = (GLFbo) GLTracer.createDesktopGlTracer(glfbo, GLFbo.class);
}
- renderer = new GLRenderer(gl, glfbo);
+ renderer = new GLRenderer(gl, glext, glfbo);
renderer.initialize();
} else {
throw new UnsupportedOperationException("Unsupported renderer: " + settings.getRenderer());