using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace Quik.OpenGL { public delegate IntPtr GetProcAddressProc(string procName); public unsafe static partial class GL { private delegate void GenObjectsProc(int count, int *ids); private delegate void BindObjectProc(int id); private delegate void BindSlottedProc(GLEnum target, int id); private delegate void GLEnum1Proc(GLEnum x); private delegate void GLEnum2Proc(GLEnum x, GLEnum y); private delegate void GLI4Proc(int x, int y, int z, int w); private delegate void GLF4Proc(float x, float y, float z, float w); private delegate void DrawElementsProc(GLEnum primitive, int size, GLEnum type, void *offset); private delegate void DrawArraysProc(GLEnum primitive, int first, int offset); private delegate void GetIntegervProc(GLEnum pname, int *data); private delegate void GetFloatvProc(GLEnum pname, float *data); private delegate byte* GetStringProc(GLEnum pname); private const short AggressiveInlining = (short)MethodImplOptions.AggressiveInlining; private static GetProcAddressProc _getProcAddress; private static GLEnum1Proc _enable; private static GLEnum1Proc _disable; private static GLEnum2Proc _blendFunc; private static GLEnum1Proc _depthFunc; private static GLEnum1Proc _clear; private static GLI4Proc _viewport; private static GLF4Proc _clearColor; private static DrawElementsProc _drawElements; private static DrawArraysProc _drawArrays; private static GetIntegervProc _getIntegerv; private static GetFloatvProc _getFloatv; private static GetStringProc _getString; private static T GetProcAddress(string procName) where T : Delegate { IntPtr funcptr = _getProcAddress(procName); return Marshal.GetDelegateForFunctionPointer(funcptr); } public static void LoadBindings(GetProcAddressProc getProcAddress) { _getProcAddress = getProcAddress; _enable = GetProcAddress("glEnable"); _disable = GetProcAddress("glDisable"); _blendFunc = GetProcAddress("glBlendFunc"); _depthFunc = GetProcAddress("glDepthFunc"); _clear = GetProcAddress("glClear"); _viewport = GetProcAddress("glViewport"); _clearColor = GetProcAddress("glClearColor"); _drawElements = GetProcAddress("glDrawElements"); _drawArrays = GetProcAddress("glDrawArrays"); _getIntegerv = GetProcAddress("glGetIntegerv"); _getFloatv = GetProcAddress("glGetFloatv"); _getString = GetProcAddress("glGetString"); LoadBuffer(); LoadProgram(); LoadShader(); LoadTexture(); LoadUniform(); LoadVertexArrays(); } [MethodImpl(AggressiveInlining)] public static void Enable(GLEnum cap) => _enable(cap); [MethodImpl(AggressiveInlining)] public static void Disable(GLEnum cap) => _disable(cap); [MethodImpl(AggressiveInlining)] public static void BlendFunc(GLEnum src, GLEnum dst) => _blendFunc(src, dst); [MethodImpl(AggressiveInlining)] public static void DepthFunc(GLEnum func) => _depthFunc(func); [MethodImpl(AggressiveInlining)] public static void Clear(GLEnum buffer_bits) => _clear(buffer_bits); [MethodImpl(AggressiveInlining)] public static void Viewport(int x, int y, int w, int h) => _viewport(x, y, w, h); [MethodImpl(AggressiveInlining)] public static void ClearColor(float r, float g, float b, float a) => _clearColor(r, g, b, a); [MethodImpl(AggressiveInlining)] public static void DrawElements(GLEnum primitive, int count, GLEnum type, int offset) => _drawElements(primitive, count, type, (void*)offset); [MethodImpl(AggressiveInlining)] public static void DrawArrays(GLEnum primitive, int offset, int count) => _drawArrays(primitive, offset, count); [MethodImpl(AggressiveInlining)] public static void Get(GLEnum pname, out int value) { value = default; fixed(int* ptr = &value) { _getIntegerv(pname, ptr); } } [MethodImpl(AggressiveInlining)] public static void Get(GLEnum pname, out float value) { value = default; fixed (float* ptr = &value) { _getFloatv(pname, ptr); } } [MethodImpl(AggressiveInlining)] public static string GetString(GLEnum pname) { int length; byte* str = _getString(pname); for (length = 0; str[length] == 0 || length < 256; length++); return System.Text.Encoding.UTF8.GetString(str, length); } } }