package openmods.renderer.shaders; import org.lwjgl.opengl.ARBShaderObjects; import org.lwjgl.opengl.ARBVertexShader; import org.lwjgl.opengl.ContextCapabilities; import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GLContext; public class ShaderHelper { /** * Class for shader functions, calling ARB methods if GL20 is not supported * A lot of this is already implemented in OpenGlHelper, but it misses some * methods and is confusing in general. */ static { initialize(); } public static IShaderMethods methods; static void initialize() { ContextCapabilities caps = GLContext.getCapabilities(); if (GL20ShaderMethods.isSupported(caps)) methods = new GL20ShaderMethods(); else if (ARBShaderMethods.isSupported(caps)) methods = new ARBShaderMethods(); } public static boolean isSupported() { return methods != null; } public static IShaderMethods methods() { return methods; } public static interface IShaderMethods { public int glCreateProgram(); public int glCreateShader(int type); public void glAttachShader(int program, int shader); public void glDetachShader(int program, int shader); public void glLinkProgram(int program); public void glValidateProgram(int program); public void glDeleteProgram(int program); public void glDeleteShader(int shader); public int glGetProgrami(int shader, int parameter); public int glGetShaderi(int program, int parameter); public String getProgramLogInfo(int program); public String getShaderLogInfo(int shader); public void glUseProgram(int program); public void glShaderSource(int shader, String shaderSource); public void glCompileShader(int shader); public int glGetUniformLocation(int program, String uniform); public void glUniform1i(int loc, int val); public void glUniform1f(int loc, float val); public void glUniform3f(int loc, float x, float y, float z); public int glGetAttribLocation(int program, String attrib); public void glEnableVertexAttribArray(int index); public void glDisableVertexAttribArray(int index); public void glVertexAttribPointer(int index, int size, int type, boolean normalized, int stride, long offset); } private static class GL20ShaderMethods implements IShaderMethods { public static boolean isSupported(ContextCapabilities caps) { return caps.OpenGL20; } @Override public int glCreateProgram() { return GL20.glCreateProgram(); } @Override public int glCreateShader(int type) { return GL20.glCreateShader(type); } @Override public void glAttachShader(int program, int shader) { GL20.glAttachShader(program, shader); } @Override public void glDetachShader(int program, int shader) { GL20.glDetachShader(program, shader); } @Override public void glLinkProgram(int program) { GL20.glLinkProgram(program); } @Override public void glValidateProgram(int program) { GL20.glValidateProgram(program); } @Override public void glDeleteProgram(int program) { GL20.glDeleteProgram(program); } @Override public void glDeleteShader(int shader) { GL20.glDeleteShader(shader); } @Override public int glGetProgrami(int program, int parameter) { return GL20.glGetProgrami(program, parameter); } @Override public int glGetShaderi(int shader, int parameter) { return GL20.glGetShaderi(shader, parameter); } @Override public String getProgramLogInfo(int program) { return GL20.glGetProgramInfoLog(program, glGetProgrami(program, GL20.GL_INFO_LOG_LENGTH)); } @Override public String getShaderLogInfo(int shader) { return GL20.glGetShaderInfoLog(shader, glGetShaderi(shader, GL20.GL_INFO_LOG_LENGTH)); } @Override public void glUseProgram(int program) { GL20.glUseProgram(program); } @Override public void glShaderSource(int shader, String shaderSource) { GL20.glShaderSource(shader, shaderSource); } @Override public void glCompileShader(int shader) { GL20.glCompileShader(shader); } @Override public int glGetUniformLocation(int program, String uniform) { return GL20.glGetUniformLocation(program, uniform); } @Override public void glUniform1i(int loc, int val) { GL20.glUniform1i(loc, val); } @Override public void glUniform1f(int loc, float val) { GL20.glUniform1f(loc, val); } @Override public void glUniform3f(int loc, float x, float y, float z) { GL20.glUniform3f(loc, x, y, z); } @Override public int glGetAttribLocation(int program, String attrib) { return GL20.glGetAttribLocation(program, attrib); } @Override public void glEnableVertexAttribArray(int index) { GL20.glEnableVertexAttribArray(index); } @Override public void glDisableVertexAttribArray(int index) { GL20.glDisableVertexAttribArray(index); } @Override public void glVertexAttribPointer(int index, int size, int type, boolean normalized, int stride, long offset) { GL20.glVertexAttribPointer(index, size, type, normalized, stride, offset); } } private static class ARBShaderMethods implements IShaderMethods { public static boolean isSupported(ContextCapabilities caps) { return caps.GL_ARB_shader_objects && caps.GL_ARB_vertex_shader && caps.GL_ARB_fragment_shader; } @Override public int glCreateProgram() { return ARBShaderObjects.glCreateProgramObjectARB(); } @Override public int glCreateShader(int type) { return ARBShaderObjects.glCreateShaderObjectARB(type); } @Override public void glAttachShader(int program, int shader) { ARBShaderObjects.glAttachObjectARB(program, shader); } @Override public void glDetachShader(int program, int shader) { ARBShaderObjects.glDetachObjectARB(program, shader); } @Override public void glLinkProgram(int program) { ARBShaderObjects.glLinkProgramARB(program); } @Override public void glValidateProgram(int program) { ARBShaderObjects.glValidateProgramARB(program); } @Override public void glDeleteProgram(int program) { ARBShaderObjects.glDeleteObjectARB(program); } @Override public void glDeleteShader(int shader) { ARBShaderObjects.glDeleteObjectARB(shader); } @Override public int glGetProgrami(int program, int parameter) { return ARBShaderObjects.glGetObjectParameteriARB(program, parameter); } @Override public int glGetShaderi(int shader, int parameter) { return ARBShaderObjects.glGetObjectParameteriARB(shader, parameter); } @Override public String getProgramLogInfo(int program) { return ARBShaderObjects.glGetInfoLogARB(program, glGetProgrami(program, GL20.GL_INFO_LOG_LENGTH)); } @Override public String getShaderLogInfo(int shader) { return ARBShaderObjects.glGetInfoLogARB(shader, glGetShaderi(shader, GL20.GL_INFO_LOG_LENGTH)); } @Override public void glUseProgram(int program) { ARBShaderObjects.glUseProgramObjectARB(program); } @Override public void glShaderSource(int shader, String shaderSource) { ARBShaderObjects.glShaderSourceARB(shader, shaderSource); } @Override public void glCompileShader(int shader) { ARBShaderObjects.glCompileShaderARB(shader); } @Override public int glGetUniformLocation(int program, String uniform) { return ARBShaderObjects.glGetUniformLocationARB(program, uniform); } @Override public void glUniform1i(int loc, int val) { ARBShaderObjects.glUniform1iARB(loc, val); } @Override public void glUniform1f(int loc, float val) { ARBShaderObjects.glUniform1fARB(loc, val); } @Override public void glUniform3f(int loc, float x, float y, float z) { ARBShaderObjects.glUniform3fARB(loc, x, y, z); } @Override public int glGetAttribLocation(int program, String attrib) { return ARBVertexShader.glGetAttribLocationARB(program, attrib); } @Override public void glEnableVertexAttribArray(int index) { ARBVertexShader.glEnableVertexAttribArrayARB(index); } @Override public void glDisableVertexAttribArray(int index) { ARBVertexShader.glDisableVertexAttribArrayARB(index); } @Override public void glVertexAttribPointer(int index, int size, int type, boolean normalized, int stride, long offset) { ARBVertexShader.glVertexAttribPointerARB(index, size, type, normalized, stride, offset); } } }