From 9651d6d822001e7006a347ec3c148fd949c334e5 Mon Sep 17 00:00:00 2001 From: shadowislord Date: Sun, 15 Feb 2015 16:42:42 -0500 Subject: [PATCH] GL interface: add support for PBO, FB readback, and fences (ARB sync) --- .../com/jme3/renderer/android/AndroidGL.java | 29 +++++++++++++++ .../java/com/jme3/renderer/RenderContext.java | 6 +++ .../java/com/jme3/renderer/opengl/GL.java | 4 ++ .../com/jme3/renderer/opengl/GLDebugES.java | 37 +++++++++++++++++++ .../java/com/jme3/renderer/opengl/GLExt.java | 11 ++++++ .../java/com/jme3/renderer/lwjgl/LwjglGL.java | 13 +++++++ .../com/jme3/renderer/lwjgl/LwjglGLExt.java | 18 +++++++++ 7 files changed, 118 insertions(+) diff --git a/jme3-android/src/main/java/com/jme3/renderer/android/AndroidGL.java b/jme3-android/src/main/java/com/jme3/renderer/android/AndroidGL.java index 567cd47ca..2a7b54023 100644 --- a/jme3-android/src/main/java/com/jme3/renderer/android/AndroidGL.java +++ b/jme3-android/src/main/java/com/jme3/renderer/android/AndroidGL.java @@ -112,6 +112,10 @@ public class AndroidGL implements GL, GLExt { GLES20.glBufferData(target, getLimitBytes(data), data, usage); } + public void glBufferData(int target, long data_size, int usage) { + GLES20.glBufferData(target, (int) data_size, null, usage); + } + public void glBufferSubData(int target, long offset, FloatBuffer data) { GLES20.glBufferSubData(target, (int) offset, getLimitBytes(data), data); } @@ -123,6 +127,10 @@ public class AndroidGL implements GL, GLExt { public void glBufferSubData(int target, long offset, ByteBuffer data) { GLES20.glBufferSubData(target, (int) offset, getLimitBytes(data), data); } + + public void glGetBufferSubData(int target, long offset, ByteBuffer data) { + throw new UnsupportedOperationException("OpenGL ES 2 does not support glGetBufferSubData"); + } public void glClear(int mask) { GLES20.glClear(mask); @@ -490,4 +498,25 @@ public class AndroidGL implements GL, GLExt { public void glRenderbufferStorageEXT(int param1, int param2, int param3, int param4) { GLES20.glRenderbufferStorage(param1, param2, param3, param4); } + + @Override + public void glReadPixels(int x, int y, int width, int height, int format, int type, long offset) { + // TODO: no offset??? + GLES20.glReadPixels(x, y, width, height, format, type, null); + } + + @Override + public int glClientWaitSync(Object sync, int flags, long timeout) { + throw new UnsupportedOperationException("OpenGL ES 2 does not support sync fences"); + } + + @Override + public void glDeleteSync(Object sync) { + throw new UnsupportedOperationException("OpenGL ES 2 does not support sync fences"); + } + + @Override + public Object glFenceSync(int condition, int flags) { + throw new UnsupportedOperationException("OpenGL ES 2 does not support sync fences"); + } } diff --git a/jme3-core/src/main/java/com/jme3/renderer/RenderContext.java b/jme3-core/src/main/java/com/jme3/renderer/RenderContext.java index 18b1d5a56..50d2374b0 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/RenderContext.java +++ b/jme3-core/src/main/java/com/jme3/renderer/RenderContext.java @@ -202,6 +202,11 @@ public class RenderContext { * @see Renderer#renderMesh(com.jme3.scene.Mesh, int, int) */ public int boundArrayVBO; + + /** + * Currently bound pixel pack pixel buffer. + */ + public int boundPixelPackPBO; public int numTexturesSet = 0; @@ -295,6 +300,7 @@ public class RenderContext { boundElementArrayVBO = 0; boundVertexArray = 0; boundArrayVBO = 0; + boundPixelPackPBO = 0; numTexturesSet = 0; for (int i = 0; i < boundTextures.length; i++) boundTextures[i] = null; 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 9cbf2f65d..9c73838e2 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 @@ -132,6 +132,7 @@ public interface GL { public static final int GL_STENCIL_BUFFER_BIT = 0x400; public static final int GL_STENCIL_TEST = 0xB90; public static final int GL_STREAM_DRAW = 0x88E0; + public static final int GL_STREAM_READ = 0x88E1; public static final int GL_TEXTURE = 0x1702; public static final int GL_TEXTURE0 = 0x84C0; public static final int GL_TEXTURE1 = 0x84C1; @@ -182,6 +183,7 @@ public interface GL { public void glBindBuffer(int target, int buffer); public void glBindTexture(int target, int texture); public void glBlendFunc(int sfactor, int dfactor); + public void glBufferData(int target, long data_size, int usage); public void glBufferData(int target, FloatBuffer data, int usage); public void glBufferData(int target, ShortBuffer data, int usage); public void glBufferData(int target, ByteBuffer data, int usage); @@ -216,6 +218,7 @@ public interface GL { public void glGenTextures(IntBuffer textures); public int glGetAttribLocation(int program, String name); public void glGetBoolean(int pname, ByteBuffer params); + public void glGetBufferSubData(int target, long offset, ByteBuffer data); public int glGetError(); public void glGetInteger(int pname, IntBuffer params); public void glGetProgram(int program, int pname, IntBuffer params); @@ -230,6 +233,7 @@ public interface GL { public void glPixelStorei(int pname, int param); public void glPolygonOffset(float factor, float units); public void glReadPixels(int x, int y, int width, int height, int format, int type, ByteBuffer data); + public void glReadPixels(int x, int y, int width, int height, int format, int type, long offset); public void glScissor(int x, int y, int width, int height); public void glShaderSource(int shader, String[] string, IntBuffer length); public void glStencilFuncSeparate(int face, int func, int ref, int mask); 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 3d5f0dc81..259c56406 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 @@ -285,6 +285,11 @@ public class GLDebugES extends GLDebug implements GL, GLFbo, GLExt { gl.glReadPixels(x, y, width, height, format, type, data); checkError(); } + + public void glReadPixels(int x, int y, int width, int height, int format, int type, long offset) { + gl.glReadPixels(x, y, width, height, format, type, offset); + checkError(); + } public void glScissor(int x, int y, int width, int height) { gl.glScissor(x, y, width, height); @@ -477,6 +482,18 @@ public class GLDebugES extends GLDebug implements GL, GLFbo, GLExt { checkError(); } + @Override + public void glBufferData(int target, long data_size, int usage) { + gl.glBufferData(target, data_size, usage); + checkError(); + } + + @Override + public void glGetBufferSubData(int target, long offset, ByteBuffer data) { + gl.glGetBufferSubData(target, offset, data); + checkError(); + } + public void glBufferData(int target, IntBuffer data, int usage) { glext.glBufferData(target, data, usage); checkError(); @@ -521,4 +538,24 @@ public class GLDebugES extends GLDebug implements GL, GLFbo, GLExt { glext.glVertexAttribDivisorARB(index, divisor); checkError(); } + + @Override + public int glClientWaitSync(Object sync, int flags, long timeout) { + int result = glext.glClientWaitSync(sync, flags, timeout); + checkError(); + return result; + } + + @Override + public void glDeleteSync(Object sync) { + glext.glDeleteSync(sync); + checkError(); + } + + @Override + public Object glFenceSync(int condition, int flags) { + Object sync = glext.glFenceSync(condition, flags); + checkError(); + return sync; + } } 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 f2bb272ae..b0e0b5f78 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 @@ -43,6 +43,7 @@ import java.nio.IntBuffer; */ public interface GLExt extends GLFbo { + public static final int GL_ALREADY_SIGNALED = 0x911A; public static final int GL_COMPRESSED_RGB8_ETC2 = 0x9274; public static final int GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = 0x83F1; public static final int GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = 0x83F2; @@ -52,6 +53,7 @@ public interface GLExt extends GLFbo { public static final int GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT = 0x8C4E; public static final int GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT = 0x8C4F; public static final int GL_COMPRESSED_SRGB_S3TC_DXT1_EXT = 0x8C4C; + public static final int GL_CONDITION_SATISFIED = 0x911C; public static final int GL_DEPTH_COMPONENT32F = 0x8CAC; public static final int GL_DEPTH24_STENCIL8_EXT = 0x88F0; public static final int GL_DEPTH_STENCIL_EXT = 0x84F9; @@ -68,6 +70,8 @@ public interface GLExt extends GLFbo { public static final int GL_MAX_SAMPLES_EXT = 0x8D57; public static final int GL_MULTISAMPLE_ARB = 0x809D; public static final int GL_NUM_PROGRAM_BINARY_FORMATS = 0x87FE; + public static final int GL_PIXEL_PACK_BUFFER_ARB = 0x88EB; + public static final int GL_PIXEL_UNPACK_BUFFER_ARB = 0x88EC; public static final int GL_R11F_G11F_B10F_EXT = 0x8C3A; public static final int GL_RGBA8 = 0x8058; public static final int GL_RGB16F_ARB = 0x881B; @@ -83,21 +87,28 @@ public interface GLExt extends GLFbo { public static final int GL_SLUMINANCE8_EXT = 0x8C47; public static final int GL_SRGB8_ALPHA8_EXT = 0x8C43; public static final int GL_SRGB8_EXT = 0x8C41; + public static final int GL_SYNC_FLUSH_COMMANDS_BIT = 0x1; + public static final int GL_SYNC_GPU_COMMANDS_COMPLETE = 0x9117; public static final int GL_TEXTURE_2D_ARRAY_EXT = 0x8C1A; public static final int GL_TEXTURE_2D_MULTISAMPLE = 0x9100; public static final int GL_TEXTURE_2D_MULTISAMPLE_ARRAY = 0x9102; public static final int GL_TEXTURE_CUBE_MAP_SEAMLESS = 0x884F; public static final int GL_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FE; + public static final int GL_TIMEOUT_EXPIRED = 0x911B; public static final int GL_UNSIGNED_INT_10F_11F_11F_REV_EXT = 0x8C3B; public static final int GL_UNSIGNED_INT_24_8_EXT = 0x84FA; 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); + public void glDeleteSync(Object sync); public void glDrawArraysInstancedARB(int mode, int first, int count, int primcount); public void glDrawBuffers(IntBuffer bufs); 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); 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 13dbdcbcc..b213fdded 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 @@ -54,6 +54,10 @@ public class LwjglGL implements GL, GL2, GL3 { GL11.glBlendFunc(param1, param2); } + public void glBufferData(int param1, long param2, int param3) { + GL15.glBufferData(param1, param2, param3); + } + public void glBufferData(int param1, FloatBuffer param2, int param3) { checkLimit(param2); GL15.glBufferData(param1, param2, param3); @@ -208,6 +212,11 @@ public class LwjglGL implements GL, GL2, GL3 { checkLimit(param2); GL11.glGetBoolean(param1, param2); } + + public void glGetBufferSubData(int target, long offset, ByteBuffer data) { + checkLimit(data); + GL15.glGetBufferSubData(target, offset, data); + } public int glGetError() { return GL11.glGetError(); @@ -268,6 +277,10 @@ public class LwjglGL implements GL, GL2, GL3 { checkLimit(param7); GL11.glReadPixels(param1, param2, param3, param4, param5, param6, param7); } + + public void glReadPixels(int param1, int param2, int param3, int param4, int param5, int param6, long param7) { + GL11.glReadPixels(param1, param2, param3, param4, param5, param6, param7); + } public void glScissor(int param1, int param2, int param3, int param4) { GL11.glScissor(param1, param2, param3, param4); 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 25104d5fc..89139282a 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,15 @@ 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; public class LwjglGLExt implements GLExt { @@ -119,4 +122,19 @@ public class LwjglGLExt implements GLExt { 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); + } + + @Override + public int glClientWaitSync(Object sync, int flags, long timeout) { + return ARBSync.glClientWaitSync((GLSync) sync, flags, timeout); + } + + @Override + public void glDeleteSync(Object sync) { + ARBSync.glDeleteSync((GLSync) sync); + } }