// OpenGL 3.3 Core — runtime-loaded function pointers // No #library needed — caller provides a loader (e.g. SDL_GL_GetProcAddress) // Constants GL_FALSE :s32: 0; GL_TRUE :s32: 1; GL_DEPTH_TEST :u32: 0x0B71; GL_CULL_FACE :u32: 0x0B44; GL_BLEND :u32: 0x0BE2; GL_TRIANGLES :u32: 4; GL_LINES :u32: 1; GL_FLOAT :u32: 0x1406; GL_UNSIGNED_INT :u32: 0x1405; GL_VERTEX_SHADER :u32: 0x8B31; GL_FRAGMENT_SHADER :u32: 0x8B30; GL_COMPILE_STATUS :u32: 0x8B81; GL_LINK_STATUS :u32: 0x8B82; GL_ARRAY_BUFFER :u32: 0x8892; GL_ELEMENT_ARRAY_BUFFER :u32: 0x8893; GL_STATIC_DRAW :u32: 0x88E4; GL_COLOR_BUFFER_BIT :u32: 0x4000; GL_DEPTH_BUFFER_BIT :u32: 0x0100; GL_FRONT_AND_BACK :u32: 0x0408; GL_LINE :u32: 0x1B01; GL_FILL :u32: 0x1B02; // Function pointer variables (mutable, loaded at runtime) glClearColor : (f32, f32, f32, f32) -> void = ---; glClear : (u32) -> void = ---; glEnable : (u32) -> void = ---; glDisable : (u32) -> void = ---; glViewport : (s32, s32, s32, s32) -> void = ---; glFlush : () -> void = ---; glDrawArrays : (u32, s32, s32) -> void = ---; glPolygonMode : (u32, u32) -> void = ---; glLineWidth : (f32) -> void = ---; glCreateShader : (u32) -> u32 = ---; glShaderSource : (u32, s32, *[:0]u8, *s32) -> void = ---; glCompileShader : (u32) -> void = ---; glGetShaderiv : (u32, u32, *s32) -> void = ---; glGetShaderInfoLog : (u32, s32, *s32, [*]u8) -> void = ---; glCreateProgram : () -> u32 = ---; glAttachShader : (u32, u32) -> void = ---; glLinkProgram : (u32) -> void = ---; glGetProgramiv : (u32, u32, *s32) -> void = ---; glGetProgramInfoLog : (u32, s32, *s32, [*]u8) -> void = ---; glUseProgram : (u32) -> void = ---; glDeleteShader : (u32) -> void = ---; glGenVertexArrays : (s32, *u32) -> void = ---; glGenBuffers : (s32, *u32) -> void = ---; glBindVertexArray : (u32) -> void = ---; glBindBuffer : (u32, u32) -> void = ---; glBufferData : (u32, isize, *void, u32) -> void = ---; glVertexAttribPointer : (u32, s32, u32, u8, s32, *void) -> void = ---; glEnableVertexAttribArray : (u32) -> void = ---; glGetUniformLocation : (u32, [*]u8) -> s32 = ---; glUniformMatrix4fv : (s32, s32, u8, [*]f32) -> void = ---; glUniform3f : (s32, f32, f32, f32) -> void = ---; glDepthFunc : (u32) -> void = ---; glUniform1f : (s32, f32) -> void = ---; GL_LESS :u32: 0x0201; GL_LEQUAL :u32: 0x0203; GL_SCISSOR_TEST :u32: 0x0C11; GL_DYNAMIC_DRAW :u32: 0x88E8; GL_TEXTURE_2D :u32: 0x0DE1; GL_TEXTURE_MIN_FILTER :u32: 0x2801; GL_TEXTURE_MAG_FILTER :u32: 0x2800; GL_NEAREST :u32: 0x2600; GL_RGBA :u32: 0x1908; GL_UNSIGNED_BYTE :u32: 0x1401; GL_SRC_ALPHA :u32: 0x0302; GL_ONE_MINUS_SRC_ALPHA :u32: 0x0303; GL_TEXTURE0 :u32: 0x84C0; GL_LINEAR :u32: 0x2601; GL_RED :u32: 0x1903; GL_R8 :u32: 0x8229; GL_UNPACK_ALIGNMENT :u32: 0x0CF5; glScissor : (s32, s32, s32, s32) -> void = ---; glBufferSubData : (u32, isize, isize, *void) -> void = ---; glGenTextures : (s32, *u32) -> void = ---; glBindTexture : (u32, u32) -> void = ---; glTexImage2D : (u32, s32, s32, s32, s32, s32, u32, u32, *void) -> void = ---; glTexParameteri : (u32, u32, s32) -> void = ---; glBlendFunc : (u32, u32) -> void = ---; glReadPixels : (s32, s32, s32, s32, u32, u32, *void) -> void = ---; glActiveTexture : (u32) -> void = ---; glUniform1i : (s32, s32) -> void = ---; glPixelStorei : (u32, s32) -> void = ---; glTexSubImage2D : (u32, s32, s32, s32, s32, s32, u32, u32, *void) -> void = ---; glDeleteTextures : (s32, *u32) -> void = ---; glGenFramebuffers : (s32, *u32) -> void = ---; glGenRenderbuffers : (s32, *u32) -> void = ---; glBindFramebuffer : (u32, u32) -> void = ---; glBindRenderbuffer : (u32, u32) -> void = ---; glFramebufferRenderbuffer : (u32, u32, u32, u32) -> void = ---; glGetRenderbufferParameteriv : (u32, u32, *s32) -> void = ---; glCheckFramebufferStatus : (u32) -> u32 = ---; GL_TEXTURE_WRAP_S :u32: 0x2802; GL_TEXTURE_WRAP_T :u32: 0x2803; GL_CLAMP_TO_EDGE :u32: 0x812F; // Loader: call once after creating GL context // Pass in a proc loader (e.g. SDL_GL_GetProcAddress) load_gl :: (get_proc: ([*]u8) -> *void) { glClearColor = xx get_proc("glClearColor"); glClear = xx get_proc("glClear"); glEnable = xx get_proc("glEnable"); glDisable = xx get_proc("glDisable"); glViewport = xx get_proc("glViewport"); glFlush = xx get_proc("glFlush"); glDrawArrays = xx get_proc("glDrawArrays"); glPolygonMode = xx get_proc("glPolygonMode"); glLineWidth = xx get_proc("glLineWidth"); glCreateShader = xx get_proc("glCreateShader"); glShaderSource = xx get_proc("glShaderSource"); glCompileShader = xx get_proc("glCompileShader"); glGetShaderiv = xx get_proc("glGetShaderiv"); glGetShaderInfoLog = xx get_proc("glGetShaderInfoLog"); glCreateProgram = xx get_proc("glCreateProgram"); glAttachShader = xx get_proc("glAttachShader"); glLinkProgram = xx get_proc("glLinkProgram"); glGetProgramiv = xx get_proc("glGetProgramiv"); glGetProgramInfoLog = xx get_proc("glGetProgramInfoLog"); glUseProgram = xx get_proc("glUseProgram"); glDeleteShader = xx get_proc("glDeleteShader"); glGenVertexArrays = xx get_proc("glGenVertexArrays"); glGenBuffers = xx get_proc("glGenBuffers"); glBindVertexArray = xx get_proc("glBindVertexArray"); glBindBuffer = xx get_proc("glBindBuffer"); glBufferData = xx get_proc("glBufferData"); glVertexAttribPointer = xx get_proc("glVertexAttribPointer"); glEnableVertexAttribArray = xx get_proc("glEnableVertexAttribArray"); glGetUniformLocation = xx get_proc("glGetUniformLocation"); glUniformMatrix4fv = xx get_proc("glUniformMatrix4fv"); glUniform3f = xx get_proc("glUniform3f"); glDepthFunc = xx get_proc("glDepthFunc"); glUniform1f = xx get_proc("glUniform1f"); glScissor = xx get_proc("glScissor"); glBufferSubData = xx get_proc("glBufferSubData"); glGenTextures = xx get_proc("glGenTextures"); glBindTexture = xx get_proc("glBindTexture"); glTexImage2D = xx get_proc("glTexImage2D"); glTexParameteri = xx get_proc("glTexParameteri"); glBlendFunc = xx get_proc("glBlendFunc"); glReadPixels = xx get_proc("glReadPixels"); glActiveTexture = xx get_proc("glActiveTexture"); glUniform1i = xx get_proc("glUniform1i"); glPixelStorei = xx get_proc("glPixelStorei"); glTexSubImage2D = xx get_proc("glTexSubImage2D"); glDeleteTextures = xx get_proc("glDeleteTextures"); glGenFramebuffers = xx get_proc("glGenFramebuffers"); glGenRenderbuffers = xx get_proc("glGenRenderbuffers"); glBindFramebuffer = xx get_proc("glBindFramebuffer"); glBindRenderbuffer = xx get_proc("glBindRenderbuffer"); glFramebufferRenderbuffer = xx get_proc("glFramebufferRenderbuffer"); glGetRenderbufferParameteriv = xx get_proc("glGetRenderbufferParameteriv"); glCheckFramebufferStatus = xx get_proc("glCheckFramebufferStatus"); } // --- Shader utilities --- create_program :: (vert_src: [:0]u8, frag_src: [:0]u8) -> u32 { vs := compile_shader(GL_VERTEX_SHADER, vert_src); fs := compile_shader(GL_FRAGMENT_SHADER, frag_src); prog := glCreateProgram(); glAttachShader(prog, vs); glAttachShader(prog, fs); glLinkProgram(prog); status : s32 = 0; glGetProgramiv(prog, GL_LINK_STATUS, @status); if status == GL_FALSE { log_buf: [512]u8 = ---; glGetProgramInfoLog(prog, 512, null, log_buf); } glDeleteShader(vs); glDeleteShader(fs); return prog; } compile_shader :: (shader_type : u32, source: [:0]u8) -> u32 { shader := glCreateShader(shader_type); glShaderSource(shader, 1, source, null); glCompileShader(shader); status : s32 = 0; glGetShaderiv(shader, GL_COMPILE_STATUS, @status); if status == GL_FALSE { log_buf : [512]u8 = ---; glGetShaderInfoLog(shader, 512, null, log_buf); } return shader; }