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 701da81518..aff21a20ce 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 @@ -595,6 +595,21 @@ public void glVertexAttribDivisorARB(int index, int divisor) { GLES30.glVertexAttribDivisor(index, divisor); } + @Override + public int glGetUniformBlockIndex(int program, String uniformBlockName) { + return GLES30.glGetUniformBlockIndex(program, uniformBlockName); + } + + @Override + public void glBindBufferBase(int target, int index, int buffer) { + GLES30.glBindBufferBase(target, index, buffer); + } + + @Override + public void glUniformBlockBinding(int program, int uniformBlockIndex, int uniformBlockBinding) { + GLES30.glUniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding); + } + @Override public void glBindFramebufferEXT(int param1, int param2) { GLES20.glBindFramebuffer(param1, param2); @@ -759,4 +774,3 @@ public void glGenVertexArrays(IntBuffer arrays) { } } - 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 3cc4f175fa..10c5c7ff88 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 @@ -260,6 +260,39 @@ public void glTexImage2DMultisample(int target, int samples, int internalFormat, */ public void glVertexAttribDivisorARB(int index, int divisor); + /** + * Retrieves the index of a named uniform block. + * + * @param program the name of a program containing the uniform block + * @param uniformBlockName the name of the uniform block whose index to retrieve + * @return the block index + */ + public default int glGetUniformBlockIndex(int program, String uniformBlockName) { + throw new UnsupportedOperationException("Uniform buffer objects are not supported"); + } + + /** + * Binds a buffer object to an indexed buffer target. + * + * @param target the target of the bind operation + * @param index the index of the binding point within the array specified by {@code target} + * @param buffer a buffer object to bind to the specified binding point + */ + public default void glBindBufferBase(int target, int index, int buffer) { + throw new UnsupportedOperationException("Uniform buffer objects are not supported"); + } + + /** + * Assigns a uniform block to a binding point. + * + * @param program the name of a program object + * @param uniformBlockIndex the index of the active uniform block within {@code program} + * @param uniformBlockBinding the binding point to assign + */ + public default void glUniformBlockBinding(int program, int uniformBlockIndex, int uniformBlockBinding) { + throw new UnsupportedOperationException("Uniform buffer objects are not supported"); + } + public default void glPushDebugGroup(int source, int id, String message) { } 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 f4ae6fe0e1..643cc6a700 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 @@ -217,7 +217,24 @@ public static int extractVersion(String version) { } private boolean hasExtension(String extensionName) { - return extensions.contains(extensionName); + if (extensions.contains(extensionName)) { + return true; + } + + if (extensionName.startsWith("GL_")) { + return extensions.contains(extensionName.substring(3)); + } else { + return extensions.contains("GL_" + extensionName); + } + } + + private boolean hasAnyExtension(String... extensionNames) { + for (String extensionName : extensionNames) { + if (hasExtension(extensionName)) { + return true; + } + } + return false; } private void loadCapabilitiesES() { @@ -266,10 +283,10 @@ private void loadCapabilitiesGL2() { } if (oglVer >= 320) { caps.add(Caps.OpenGL32); + caps.add(Caps.GeometryShader); } if (oglVer >= 330) { caps.add(Caps.OpenGL33); - caps.add(Caps.GeometryShader); } if (oglVer >= 400) { caps.add(Caps.OpenGL40); @@ -369,17 +386,24 @@ private void loadCapabilitiesCommon() { limits.put(Limits.TextureSize, getInteger(GL.GL_MAX_TEXTURE_SIZE)); limits.put(Limits.CubemapSize, getInteger(GL.GL_MAX_CUBE_MAP_TEXTURE_SIZE)); - if (hasExtension("GL_ARB_draw_instanced") && - hasExtension("GL_ARB_instanced_arrays")) { + if ((hasExtension("GL_ARB_draw_instanced") && + hasExtension("GL_ARB_instanced_arrays")) + || caps.contains(Caps.OpenGL33) + || caps.contains(Caps.OpenGLES30) + || caps.contains(Caps.WebGL)) { // TODO: If there were a way to call the EXT extension for GLES2, should check also (hasExtension("GL_EXT_draw_instanced") && hasExtension("GL_EXT_instanced_arrays")) caps.add(Caps.MeshInstancing); } - if (hasExtension("GL_OES_element_index_uint") || gl2 != null) { + if (hasExtension("GL_OES_element_index_uint") || gl2 != null + || caps.contains(Caps.OpenGLES30) || caps.contains(Caps.WebGL)) { caps.add(Caps.IntegerIndexBuffer); } - if (hasExtension("GL_ARB_texture_buffer_object")) { + if (hasAnyExtension("GL_OES_texture_buffer", "GL_EXT_texture_buffer") + || caps.contains(Caps.OpenGL31) + || caps.contains(Caps.OpenGLES32) + ) { caps.add(Caps.TextureBuffer); } @@ -395,7 +419,8 @@ private void loadCapabilitiesCommon() { hasExtension("GL_ARB_half_float_pixel"); if (!hasFloatTexture) { - hasFloatTexture = caps.contains(Caps.OpenGL30) || caps.contains(Caps.OpenGLES30); + hasFloatTexture = caps.contains(Caps.OpenGL30) || caps.contains(Caps.OpenGLES30) + || caps.contains(Caps.WebGL); } } @@ -404,81 +429,108 @@ private void loadCapabilitiesCommon() { } // integer texture format extensions - if(hasExtension("GL_EXT_texture_integer") || caps.contains(Caps.OpenGL30)) + if(hasExtension("GL_EXT_texture_integer") || caps.contains(Caps.OpenGL30) + || caps.contains(Caps.OpenGLES30) || caps.contains(Caps.WebGL)) caps.add(Caps.IntegerTexture); - if (hasExtension("GL_OES_depth_texture") || gl2 != null) { + if (hasExtension("GL_OES_depth_texture") || hasExtension("WEBGL_depth_texture") || gl2 != null + || caps.contains(Caps.OpenGLES30) || caps.contains(Caps.WebGL)) { caps.add(Caps.DepthTexture); } - if (hasExtension("GL_OES_depth24")) { + if (caps.contains(Caps.OpenGL20) || caps.contains(Caps.OpenGLES30) || caps.contains(Caps.WebGL) + || hasExtension("GL_OES_depth24")) { caps.add(Caps.Depth24); } - if (hasExtension("GL_OES_rgb8_rgba8") || + if (caps.contains(Caps.OpenGL20) || caps.contains(Caps.OpenGLES30) || caps.contains(Caps.WebGL) || + hasExtension("GL_OES_rgb8_rgba8") || hasExtension("GL_ARM_rgba8") || hasExtension("GL_EXT_texture_format_BGRA8888")) { caps.add(Caps.Rgba8); } - if (caps.contains(Caps.OpenGL30) || caps.contains(Caps.OpenGLES30) || hasExtension("GL_OES_packed_depth_stencil")) { + if (caps.contains(Caps.OpenGL30) || caps.contains(Caps.OpenGLES30) || caps.contains(Caps.WebGL) + || hasExtension("GL_OES_packed_depth_stencil")) { caps.add(Caps.PackedDepthStencilBuffer); } if (hasExtension("GL_ARB_color_buffer_float") && hasExtension("GL_ARB_half_float_pixel") - ||caps.contains(Caps.OpenGL30) || caps.contains(Caps.OpenGLES30)) { + ||caps.contains(Caps.OpenGL30) || caps.contains(Caps.OpenGLES30) + || caps.contains(Caps.WebGL)) { // XXX: Require both 16- and 32-bit float support for FloatColorBuffer. caps.add(Caps.FloatColorBuffer); caps.add(Caps.FloatColorBufferRGBA); - if (!caps.contains(Caps.OpenGLES30)) { + if (!caps.contains(Caps.OpenGLES30) && !caps.contains(Caps.WebGL)) { caps.add(Caps.FloatColorBufferRGB); } } - if (caps.contains(Caps.OpenGLES30) || hasExtension("GL_ARB_depth_buffer_float")) { + if (caps.contains(Caps.OpenGL30) || caps.contains(Caps.OpenGLES30) || caps.contains(Caps.WebGL) + || hasExtension("GL_ARB_depth_buffer_float")) { caps.add(Caps.FloatDepthBuffer); } + if ((hasExtension("GL_EXT_packed_float") && hasFloatTexture) || + caps.contains(Caps.OpenGL30) || caps.contains(Caps.OpenGLES30) + || caps.contains(Caps.WebGL)) { + // Either GL3/GLES3 is available or both packed_float & half_float_pixel. + caps.add(Caps.PackedFloatTexture); + } + if ((hasExtension("GL_EXT_packed_float") && hasFloatTexture) || caps.contains(Caps.OpenGL30)) { - // Either OpenGL3 is available or both packed_float & half_float_pixel. caps.add(Caps.PackedFloatColorBuffer); - caps.add(Caps.PackedFloatTexture); } - if (hasExtension("GL_EXT_texture_shared_exponent") || caps.contains(Caps.OpenGL30)) { + if (hasExtension("GL_EXT_texture_shared_exponent") || caps.contains(Caps.OpenGL30) + || caps.contains(Caps.OpenGLES30) || caps.contains(Caps.WebGL)) { caps.add(Caps.SharedExponentTexture); } - if (hasExtension("GL_EXT_texture_compression_s3tc")) { + if (hasAnyExtension("GL_EXT_texture_compression_s3tc", + "WEBGL_compressed_texture_s3tc", + "WEBKIT_WEBGL_compressed_texture_s3tc", + "MOZ_WEBGL_compressed_texture_s3tc")) { caps.add(Caps.TextureCompressionS3TC); } - if (hasExtension("GL_ARB_texture_compression_bptc")) { + if (hasAnyExtension("GL_ARB_texture_compression_bptc", + "EXT_texture_compression_bptc") + || caps.contains(Caps.OpenGL42)) { caps.add(Caps.TextureCompressionBPTC); } - if (hasExtension("GL_EXT_texture_compression_rgtc")) { + if (hasExtension("GL_EXT_texture_compression_rgtc") || caps.contains(Caps.OpenGL30)) { caps.add(Caps.TextureCompressionRGTC); } - if (hasExtension("GL_ARB_ES3_compatibility")) { + if (hasExtension("GL_ARB_ES3_compatibility") + || caps.contains(Caps.OpenGL43) + || caps.contains(Caps.OpenGLES30) + || caps.contains(Caps.WebGL) + || hasExtension("WEBGL_compressed_texture_etc")) { caps.add(Caps.TextureCompressionETC2); caps.add(Caps.TextureCompressionETC1); - } else if (hasExtension("GL_OES_compressed_ETC1_RGB8_texture")) { + } else if (hasAnyExtension("GL_OES_compressed_ETC1_RGB8_texture", + "WEBGL_compressed_texture_etc1")) { caps.add(Caps.TextureCompressionETC1); } // == end texture format extensions == - if (hasExtension("GL_ARB_vertex_array_object") || caps.contains(Caps.OpenGL30) || caps.contains(Caps.OpenGLES30) ) { + if (hasExtension("GL_ARB_vertex_array_object") + || caps.contains(Caps.OpenGL30) + || caps.contains(Caps.OpenGLES30) + || caps.contains(Caps.WebGL)) { caps.add(Caps.VertexBufferArray); } if (hasExtension("GL_ARB_texture_non_power_of_two") || hasExtension("GL_OES_texture_npot") || - caps.contains(Caps.OpenGL30) || caps.contains(Caps.OpenGLES30)) { + caps.contains(Caps.OpenGL20) || caps.contains(Caps.OpenGLES30) + || caps.contains(Caps.WebGL)) { caps.add(Caps.NonPowerOfTwoTextures); } else { logger.log(Level.WARNING, "Your graphics card does not " @@ -491,7 +543,8 @@ private void loadCapabilitiesCommon() { caps.add(Caps.PartialNonPowerOfTwoTextures); } - if (hasExtension("GL_EXT_texture_array") || caps.contains(Caps.OpenGL30) || caps.contains(Caps.OpenGLES30)) { + if (hasExtension("GL_EXT_texture_array") || caps.contains(Caps.OpenGL30) + || caps.contains(Caps.OpenGLES30) || caps.contains(Caps.WebGL)) { caps.add(Caps.TextureArray); } @@ -508,18 +561,19 @@ private void loadCapabilitiesCommon() { 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.contains(Caps.OpenGL30) || caps.contains(Caps.OpenGLES30)) { + if (hasExtension("GL_EXT_framebuffer_blit") || caps.contains(Caps.OpenGL30) + || caps.contains(Caps.OpenGLES30) || caps.contains(Caps.WebGL)) { caps.add(Caps.FrameBufferBlit); } - if (hasExtension("GL_EXT_framebuffer_multisample") || caps.contains(Caps.OpenGLES30)) { + if (hasExtension("GL_EXT_framebuffer_multisample") || caps.contains(Caps.OpenGL30) + || caps.contains(Caps.OpenGLES30) || caps.contains(Caps.WebGL)) { caps.add(Caps.FrameBufferMultisample); limits.put(Limits.FrameBufferSamples, getInteger(GLExt.GL_MAX_SAMPLES_EXT)); } - if (hasExtension("GL_ARB_texture_multisample") || caps.contains(Caps.OpenGLES31) - || (JmeSystem.getPlatform().getOs() == Platform.Os.MacOS - && caps.contains(Caps.OpenGL32))) { // GLES31 does not fully support it + if (hasExtension("GL_ARB_texture_multisample") || caps.contains(Caps.OpenGL32) + || caps.contains(Caps.OpenGLES31)) { // GLES31 does not fully support it caps.add(Caps.TextureMultisample); limits.put(Limits.ColorTextureSamples, getInteger(GLExt.GL_MAX_COLOR_TEXTURE_SAMPLES)); limits.put(Limits.DepthTextureSamples, getInteger(GLExt.GL_MAX_DEPTH_TEXTURE_SAMPLES)); @@ -529,7 +583,12 @@ private void loadCapabilitiesCommon() { } } - if (hasExtension("GL_ARB_draw_buffers") || caps.contains(Caps.OpenGL30) || caps.contains(Caps.OpenGLES30)) { + if (hasExtension("GL_ARB_draw_buffers") + || hasExtension("WEBGL_draw_buffers") + || caps.contains(Caps.OpenGL20) + || caps.contains(Caps.OpenGL30) + || caps.contains(Caps.OpenGLES30) + || caps.contains(Caps.WebGL)) { limits.put(Limits.FrameBufferMrtAttachments, getInteger(GLExt.GL_MAX_DRAW_BUFFERS_ARB)); if (limits.get(Limits.FrameBufferMrtAttachments) > 1) { caps.add(Caps.FrameBufferMRT); @@ -539,7 +598,7 @@ private void loadCapabilitiesCommon() { } } - if (hasExtension("GL_ARB_multisample") /*|| caps.contains(Caps.OpenGLES20)*/) { + if (hasExtension("GL_ARB_multisample") || caps.contains(Caps.OpenGL20) /*|| caps.contains(Caps.OpenGLES20)*/) { boolean available = getInteger(GLExt.GL_SAMPLE_BUFFERS_ARB) != 0; int samples = getInteger(GLExt.GL_SAMPLES_ARB); logger.log(Level.FINER, "Samples: {0}", samples); @@ -553,8 +612,10 @@ private void loadCapabilitiesCommon() { } // Supports sRGB pipeline. - if ( (hasExtension("GL_ARB_framebuffer_sRGB") && hasExtension("GL_EXT_texture_sRGB")) - || caps.contains(Caps.OpenGL30) || caps.contains(Caps.OpenGLES30)) { + if ((hasExtension("GL_ARB_framebuffer_sRGB") && hasExtension("GL_EXT_texture_sRGB")) + || hasExtension("GL_EXT_sRGB") + || caps.contains(Caps.OpenGL30) || caps.contains(Caps.OpenGLES30) + || caps.contains(Caps.WebGL)) { caps.add(Caps.Srgb); } @@ -563,13 +624,14 @@ private void loadCapabilitiesCommon() { caps.add(Caps.SeamlessCubemap); } - if ((caps.contains(Caps.OpenGLES30) || caps.contains(Caps.OpenGL32)) && !hasExtension("GL_ARB_compatibility")) { + if ((caps.contains(Caps.OpenGLES30) || caps.contains(Caps.WebGL) + || caps.contains(Caps.OpenGL32)) && !hasExtension("GL_ARB_compatibility")) { if (JmeSystem.getPlatform().getOs() != Platform.Os.iOS) { // some features are not supported on iOS caps.add(Caps.CoreProfile); } } - if (hasExtension("GL_ARB_get_program_binary")) { + if (hasExtension("GL_ARB_get_program_binary") || caps.contains(Caps.OpenGL41)) { int binaryFormats = getInteger(GLExt.GL_NUM_PROGRAM_BINARY_FORMATS); if (binaryFormats > 0) { caps.add(Caps.BinaryShader); @@ -584,7 +646,7 @@ private void loadCapabilitiesCommon() { caps.add(Caps.TesselationShader); } - if (hasExtension("GL_ARB_shader_storage_buffer_object")) { + if (hasExtension("GL_ARB_shader_storage_buffer_object") || caps.contains(Caps.OpenGL43) || caps.contains(Caps.OpenGLES31)) { caps.add(Caps.ShaderStorageBufferObject); limits.put(Limits.ShaderStorageBufferObjectMaxBlockSize, getInteger(GL4.GL_MAX_SHADER_STORAGE_BLOCK_SIZE)); @@ -608,7 +670,9 @@ private void loadCapabilitiesCommon() { getInteger(GL4.GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS)); } - if (hasExtension("GL_ARB_uniform_buffer_object")) { + if (hasExtension("GL_ARB_uniform_buffer_object") || caps.contains(Caps.OpenGL31) + || caps.contains(Caps.WebGL) + || (caps.contains(Caps.OpenGLES30) && JmeSystem.getPlatform().getOs() != Platform.Os.iOS)) { caps.add(Caps.UniformBufferObject); limits.put(Limits.UniformBufferObjectMaxBlockSize, getInteger(GL3.GL_MAX_UNIFORM_BLOCK_SIZE)); @@ -622,11 +686,11 @@ private void loadCapabilitiesCommon() { getInteger(GL3.GL_MAX_VERTEX_UNIFORM_BLOCKS)); } - if (caps.contains(Caps.OpenGL20)) { + if (caps.contains(Caps.OpenGL20) || caps.contains(Caps.OpenGLES30) || caps.contains(Caps.WebGL)) { caps.add(Caps.UnpackRowLength); } - if (caps.contains(Caps.OpenGL43) || hasExtension("GL_KHR_debug") || caps.contains(Caps.WebGL)) { + if (caps.contains(Caps.OpenGL43) || hasExtension("GL_KHR_debug") ) { caps.add(Caps.GLDebug); } @@ -690,6 +754,29 @@ private boolean getBoolean(int en) { return nameBuf.get(0) != (byte)0; } + private int getUniformBlockIndex(int program, String uniformBlockName) { + if (gl3 != null) { + return gl3.glGetUniformBlockIndex(program, uniformBlockName); + } + return glext.glGetUniformBlockIndex(program, uniformBlockName); + } + + private void bindUniformBufferBase(int bindingPoint, int buffer) { + if (gl3 != null) { + gl3.glBindBufferBase(GL3.GL_UNIFORM_BUFFER, bindingPoint, buffer); + } else { + glext.glBindBufferBase(GL3.GL_UNIFORM_BUFFER, bindingPoint, buffer); + } + } + + private void bindUniformBlock(int program, int uniformBlockIndex, int uniformBlockBinding) { + if (gl3 != null) { + gl3.glUniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding); + } else { + glext.glUniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding); + } + } + @SuppressWarnings("fallthrough") @Override public void initialize() { @@ -1481,11 +1568,11 @@ protected void updateShaderBufferBlock(final Shader shader, final ShaderBufferBl if (bufferBlock.isUpdateNeeded()) { int blockIndex = bufferBlock.getLocation(); if (blockIndex < 0) { - blockIndex = gl3.glGetUniformBlockIndex(shaderId, bufferBlock.getName()); + blockIndex = getUniformBlockIndex(shaderId, bufferBlock.getName()); bufferBlock.setLocation(blockIndex); } if (bufferBlock.getLocation() != NativeObject.INVALID_ID) { - gl3.glUniformBlockBinding(shaderId, bufferBlock.getLocation(), bindingPoint); + bindUniformBlock(shaderId, bufferBlock.getLocation(), bindingPoint); } } break; @@ -2777,7 +2864,7 @@ public void setUniformBufferObject(int bindingPoint, BufferObject bufferObject) } if (context.boundBO[bindingPoint] == null || context.boundBO[bindingPoint].get() != bufferObject) { - gl3.glBindBufferBase(GL3.GL_UNIFORM_BUFFER, bindingPoint, bufferObject.getId()); + bindUniformBufferBase(bindingPoint, bufferObject.getId()); bufferObject.setBinding(bindingPoint); context.boundBO[bindingPoint] = bufferObject.getWeakRef(); } diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/TextureUtil.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/TextureUtil.java index 7064f7ce2e..5eafcf865a 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/opengl/TextureUtil.java +++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/TextureUtil.java @@ -394,10 +394,10 @@ public void uploadSubTexture(int target, Image src, int index, int targetX, int } } else { if (needsStride) - gl2.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, srcWidth); + gl.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, srcWidth); gl.glTexSubImage2D(target, 0, targetX, targetY, areaWidth, areaHeight, oglFormat.format, oglFormat.dataType, data); if (needsStride) - gl2.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, 0); + gl.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, 0); } data.position(cpos); 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 62360e67d6..56ef07ffab 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 @@ -9,6 +9,7 @@ import org.lwjgl.opengl.ARBInstancedArrays; import org.lwjgl.opengl.ARBSync; import org.lwjgl.opengl.ARBTextureMultisample; +import org.lwjgl.opengl.ARBUniformBufferObject; import org.lwjgl.opengl.GL15; import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GLSync; @@ -71,6 +72,21 @@ public void glVertexAttribDivisorARB(int index, int divisor) { ARBInstancedArrays.glVertexAttribDivisorARB(index, divisor); } + @Override + public int glGetUniformBlockIndex(int program, String uniformBlockName) { + return ARBUniformBufferObject.glGetUniformBlockIndex(program, uniformBlockName); + } + + @Override + public void glBindBufferBase(int target, int index, int buffer) { + ARBUniformBufferObject.glBindBufferBase(target, index, buffer); + } + + @Override + public void glUniformBlockBinding(int program, int uniformBlockIndex, int uniformBlockBinding) { + ARBUniformBufferObject.glUniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding); + } + @Override public Object glFenceSync(int condition, int flags) { return ARBSync.glFenceSync(condition, flags); diff --git a/jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGLExt.java b/jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGLExt.java index f9899fe8b3..74736f0666 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGLExt.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGLExt.java @@ -88,6 +88,21 @@ public void glVertexAttribDivisorARB(final int index, final int divisor) { ARBInstancedArrays.glVertexAttribDivisorARB(index, divisor); } + @Override + public int glGetUniformBlockIndex(final int program, final String uniformBlockName) { + return ARBUniformBufferObject.glGetUniformBlockIndex(program, uniformBlockName); + } + + @Override + public void glBindBufferBase(final int target, final int index, final int buffer) { + ARBUniformBufferObject.glBindBufferBase(target, index, buffer); + } + + @Override + public void glUniformBlockBinding(final int program, final int uniformBlockIndex, final int uniformBlockBinding) { + ARBUniformBufferObject.glUniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding); + } + @Override public Object glFenceSync(final int condition, final int flags) { return ARBSync.glFenceSync(condition, flags);