Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 87 additions & 15 deletions jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGLExt.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,14 @@
import java.nio.IntBuffer;

/**
* The LWJGL implementation og {@link GLExt}.
* The LWJGL implementation of {@link GLExt}.
*
* <p>Each method prefers the equivalent core OpenGL function (available since
* the GL version that promoted the feature to core) and falls back to the
* corresponding ARB extension only when the core entry point is unavailable.
* This avoids JVM crashes on macOS Core Profile drivers that strip legacy ARB
* extension pointers even when the underlying functionality is exposed through
* the core profile.
*/
public class LwjglGLExt extends LwjglRender implements GLExt {

Expand All @@ -56,7 +63,12 @@ public void glBufferSubData(final int target, final long offset, final IntBuffer

@Override
public void glDrawArraysInstancedARB(final int mode, final int first, final int count, final int primCount) {
ARBDrawInstanced.glDrawArraysInstancedARB(mode, first, count, primCount);
// glDrawArraysInstanced is core since OpenGL 3.1
if (GL.getCapabilities().OpenGL31) {
GL31.glDrawArraysInstanced(mode, first, count, primCount);
} else {
ARBDrawInstanced.glDrawArraysInstancedARB(mode, first, count, primCount);
}
}

@Override
Expand All @@ -68,64 +80,124 @@ public void glDrawBuffers(final IntBuffer bufs) {
@Override
public void glDrawElementsInstancedARB(final int mode, final int indicesCount, final int type,
final long indicesBufferOffset, final int primCount) {
ARBDrawInstanced.glDrawElementsInstancedARB(mode, indicesCount, type, indicesBufferOffset, primCount);
// glDrawElementsInstanced is core since OpenGL 3.1
if (GL.getCapabilities().OpenGL31) {
GL31.glDrawElementsInstanced(mode, indicesCount, type, indicesBufferOffset, primCount);
} else {
ARBDrawInstanced.glDrawElementsInstancedARB(mode, indicesCount, type, indicesBufferOffset, primCount);
}
}

@Override
public void glGetMultisample(final int pname, final int index, final FloatBuffer val) {
checkLimit(val);
ARBTextureMultisample.glGetMultisamplefv(pname, index, val);
// glGetMultisamplefv is core since OpenGL 3.2
if (GL.getCapabilities().OpenGL32) {
GL32.glGetMultisamplefv(pname, index, val);
} else {
ARBTextureMultisample.glGetMultisamplefv(pname, index, val);
}
}

@Override
public void glTexImage2DMultisample(final int target, final int samples, final int internalFormat, final int width,
final int height, final boolean fixedSampleLocations) {
ARBTextureMultisample.glTexImage2DMultisample(target, samples, internalFormat, width, height, fixedSampleLocations);
// glTexImage2DMultisample is core since OpenGL 3.2
if (GL.getCapabilities().OpenGL32) {
GL32.glTexImage2DMultisample(target, samples, internalFormat, width, height, fixedSampleLocations);
} else {
ARBTextureMultisample.glTexImage2DMultisample(target, samples, internalFormat, width, height, fixedSampleLocations);
}
}

@Override
public void glVertexAttribDivisorARB(final int index, final int divisor) {
ARBInstancedArrays.glVertexAttribDivisorARB(index, divisor);
// glVertexAttribDivisor is core since OpenGL 3.3
if (GL.getCapabilities().OpenGL33) {
GL33.glVertexAttribDivisor(index, divisor);
} else {
ARBInstancedArrays.glVertexAttribDivisorARB(index, divisor);
}
}

@Override
public int glGetUniformBlockIndex(final int program, final String uniformBlockName) {
return ARBUniformBufferObject.glGetUniformBlockIndex(program, uniformBlockName);
// glGetUniformBlockIndex is core since OpenGL 3.1
if (GL.getCapabilities().OpenGL31) {
return GL31.glGetUniformBlockIndex(program, uniformBlockName);
} else {
return ARBUniformBufferObject.glGetUniformBlockIndex(program, uniformBlockName);
}
}

@Override
public void glBindBufferBase(final int target, final int index, final int buffer) {
ARBUniformBufferObject.glBindBufferBase(target, index, buffer);
// glBindBufferBase is core since OpenGL 3.0
if (GL.getCapabilities().OpenGL30) {
GL30.glBindBufferBase(target, index, buffer);
} else {
ARBUniformBufferObject.glBindBufferBase(target, index, buffer);
}
}

@Override
public void glUniformBlockBinding(final int program, final int uniformBlockIndex, final int uniformBlockBinding) {
ARBUniformBufferObject.glUniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding);
// glUniformBlockBinding is core since OpenGL 3.1
if (GL.getCapabilities().OpenGL31) {
GL31.glUniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding);
} else {
ARBUniformBufferObject.glUniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding);
}
}

@Override
public int glGetProgramResourceIndex(final int program, final int programInterface, final String name) {
return ARBProgramInterfaceQuery.glGetProgramResourceIndex(program, programInterface, name);
// glGetProgramResourceIndex is core since OpenGL 4.3
if (GL.getCapabilities().OpenGL43) {
return GL43.glGetProgramResourceIndex(program, programInterface, name);
} else {
return ARBProgramInterfaceQuery.glGetProgramResourceIndex(program, programInterface, name);
}
}

@Override
public void glShaderStorageBlockBinding(final int program, final int storageBlockIndex, final int storageBlockBinding) {
ARBShaderStorageBufferObject.glShaderStorageBlockBinding(program, storageBlockIndex, storageBlockBinding);
// glShaderStorageBlockBinding is core since OpenGL 4.3
if (GL.getCapabilities().OpenGL43) {
GL43.glShaderStorageBlockBinding(program, storageBlockIndex, storageBlockBinding);
} else {
ARBShaderStorageBufferObject.glShaderStorageBlockBinding(program, storageBlockIndex, storageBlockBinding);
}
}

@Override
public Object glFenceSync(final int condition, final int flags) {
return ARBSync.glFenceSync(condition, flags);
// glFenceSync is core since OpenGL 3.2
if (GL.getCapabilities().OpenGL32) {
return GL32.glFenceSync(condition, flags);
} else {
return ARBSync.glFenceSync(condition, flags);
}
}

@Override
public int glClientWaitSync(final Object sync, final int flags, final long timeout) {
return ARBSync.glClientWaitSync((Long) sync, flags, timeout);
// glClientWaitSync is core since OpenGL 3.2
if (GL.getCapabilities().OpenGL32) {
return GL32.glClientWaitSync((Long) sync, flags, timeout);
} else {
return ARBSync.glClientWaitSync((Long) sync, flags, timeout);
}
}

@Override
public void glDeleteSync(final Object sync) {
ARBSync.glDeleteSync((Long) sync);
// glDeleteSync is core since OpenGL 3.2
if (GL.getCapabilities().OpenGL32) {
GL32.glDeleteSync((Long) sync);
} else {
ARBSync.glDeleteSync((Long) sync);
}
}

@Override
Expand Down
Loading