using System.Runtime.CompilerServices; using System.Text; using static Quik.OpenGL.GLEnum; namespace Quik.OpenGL { public unsafe static partial class GL { private delegate int CreateProgramProc(); private delegate void UseProgramProc(int program); private delegate void AttachShaderProc(int program, int shader); private delegate void DetachShaderProc(int program, int shader); private delegate void LinkProgramProc(int program); private delegate void GetProgramProc(int program, GLEnum pname, int *value); private delegate void GetProgramInfoLogProc(int program, int maxLength, int * length, byte *infoLog); private delegate void DeleteProgramProc(int program); private delegate int GetShaderLocationProc(int program, byte *name); private static CreateProgramProc _createProgram; private static UseProgramProc _useProgram; private static AttachShaderProc _attachShader; private static DetachShaderProc _detachShader; private static LinkProgramProc _linkProgram; private static GetProgramProc _getProgram; private static GetProgramInfoLogProc _getProgramInfoLog; private static DeleteProgramProc _deleteProgram; private static GetShaderLocationProc _getUniformLocation; private static GetShaderLocationProc _getAttribLocation; private static void LoadProgram() { _createProgram = GetProcAddress("glCreateProgram"); _useProgram = GetProcAddress("glUseProgram"); _attachShader = GetProcAddress("glAttachShader"); _detachShader = GetProcAddress("glDetachShader"); _linkProgram = GetProcAddress("glLinkProgram"); _getProgram = GetProcAddress("glGetProgramiv"); _getProgramInfoLog = GetProcAddress("glGetProgramInfoLog"); _deleteProgram = GetProcAddress("glDeleteProgram"); _getUniformLocation = GetProcAddress("glGetUniformLocation"); _getAttribLocation = GetProcAddress("glGetAttribLocation"); } [MethodImpl(AggressiveInlining)] public static int CreateProgram() => _createProgram(); [MethodImpl(AggressiveInlining)] public static void UseProgram(int program) => _useProgram(program); [MethodImpl(AggressiveInlining)] public static void AttachShader(int program, int shader) => _attachShader(program, shader); [MethodImpl(AggressiveInlining)] public static void DetachShader(int program, int shader) => _detachShader(program, shader); [MethodImpl(AggressiveInlining)] public static void LinkProgram(int program) => _linkProgram(program); [MethodImpl(AggressiveInlining)] public static void GetProgram(int program, GLEnum pname, out int value) { value = default; fixed (int* ptr = &value) _getProgram(program, pname, ptr); } [MethodImpl(AggressiveInlining)] public static string GetProgramInfoLog(int program) { GetProgram(program, GL_INFO_LOG_LENGTH, out int length); byte[] infoLog = new byte[length]; fixed (byte *ptr = infoLog) _getProgramInfoLog(program, length, &length, ptr); return Encoding.UTF8.GetString(infoLog); } [MethodImpl(AggressiveInlining)] public static void DeleteProgram(int program) => _deleteProgram(program); [MethodImpl(AggressiveInlining)] public static int GetUniformLocation(int program, string name) { fixed(byte* ptr = Encoding.UTF8.GetBytes(name)) return _getUniformLocation(program, ptr); } [MethodImpl(AggressiveInlining)] public static int GetAttribLocation(int program, string name) { fixed(byte* ptr = Encoding.UTF8.GetBytes(name)) return _getAttribLocation(program, ptr); } } }