github.com/cybriq/giocore@v0.0.7-0.20210703034601-cfb9cb5f3900/internal/gl/gl_unix.go (about) 1 // SPDX-License-Identifier: Unlicense OR MIT 2 3 // +build darwin linux freebsd openbsd 4 5 package gl 6 7 import ( 8 "fmt" 9 "runtime" 10 "strings" 11 "unsafe" 12 ) 13 14 /* 15 #cgo CFLAGS: -Werror 16 #cgo linux freebsd LDFLAGS: -ldl 17 18 #include <stdint.h> 19 #include <stdlib.h> 20 #include <sys/types.h> 21 #define __USE_GNU 22 #include <dlfcn.h> 23 24 typedef unsigned int GLenum; 25 typedef unsigned int GLuint; 26 typedef char GLchar; 27 typedef float GLfloat; 28 typedef ssize_t GLsizeiptr; 29 typedef intptr_t GLintptr; 30 typedef unsigned int GLbitfield; 31 typedef int GLint; 32 typedef unsigned char GLboolean; 33 typedef int GLsizei; 34 typedef uint8_t GLubyte; 35 36 typedef struct { 37 void (*glActiveTexture)(GLenum texture); 38 void (*glAttachShader)(GLuint program, GLuint shader); 39 void (*glBindAttribLocation)(GLuint program, GLuint index, const GLchar *name); 40 void (*glBindBuffer)(GLenum target, GLuint buffer); 41 void (*glBindFramebuffer)(GLenum target, GLuint framebuffer); 42 void (*glBindRenderbuffer)(GLenum target, GLuint renderbuffer); 43 void (*glBindTexture)(GLenum target, GLuint texture); 44 void (*glBlendEquation)(GLenum mode); 45 void (*glBlendFuncSeparate)(GLenum srcRGB, GLenum dstRGB, GLenum srcA, GLenum dstA); 46 void (*glBufferData)(GLenum target, GLsizeiptr size, const void *data, GLenum usage); 47 void (*glBufferSubData)(GLenum target, GLintptr offset, GLsizeiptr size, const void *data); 48 GLenum (*glCheckFramebufferStatus)(GLenum target); 49 void (*glClear)(GLbitfield mask); 50 void (*glClearColor)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); 51 void (*glClearDepthf)(GLfloat d); 52 void (*glCompileShader)(GLuint shader); 53 GLuint (*glCreateProgram)(void); 54 GLuint (*glCreateShader)(GLenum type); 55 void (*glDeleteBuffers)(GLsizei n, const GLuint *buffers); 56 void (*glDeleteFramebuffers)(GLsizei n, const GLuint *framebuffers); 57 void (*glDeleteProgram)(GLuint program); 58 void (*glDeleteRenderbuffers)(GLsizei n, const GLuint *renderbuffers); 59 void (*glDeleteShader)(GLuint shader); 60 void (*glDeleteTextures)(GLsizei n, const GLuint *textures); 61 void (*glDepthFunc)(GLenum func); 62 void (*glDepthMask)(GLboolean flag); 63 void (*glDisable)(GLenum cap); 64 void (*glDisableVertexAttribArray)(GLuint index); 65 void (*glDrawArrays)(GLenum mode, GLint first, GLsizei count); 66 void (*glDrawElements)(GLenum mode, GLsizei count, GLenum type, const void *indices); 67 void (*glEnable)(GLenum cap); 68 void (*glEnableVertexAttribArray)(GLuint index); 69 void (*glFinish)(void); 70 void (*glFlush)(void); 71 void (*glFramebufferRenderbuffer)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); 72 void (*glFramebufferTexture2D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); 73 void (*glGenBuffers)(GLsizei n, GLuint *buffers); 74 void (*glGenFramebuffers)(GLsizei n, GLuint *framebuffers); 75 void (*glGenRenderbuffers)(GLsizei n, GLuint *renderbuffers); 76 void (*glGenTextures)(GLsizei n, GLuint *textures); 77 GLenum (*glGetError)(void); 78 void (*glGetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment, GLenum pname, GLint *params); 79 void (*glGetFloatv)(GLenum pname, GLfloat *data); 80 void (*glGetIntegerv)(GLenum pname, GLint *data); 81 void (*glGetIntegeri_v)(GLenum pname, GLuint idx, GLint *data); 82 void (*glGetProgramiv)(GLuint program, GLenum pname, GLint *params); 83 void (*glGetProgramInfoLog)(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); 84 void (*glGetRenderbufferParameteriv)(GLenum target, GLenum pname, GLint *params); 85 void (*glGetShaderiv)(GLuint shader, GLenum pname, GLint *params); 86 void (*glGetShaderInfoLog)(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); 87 const GLubyte *(*glGetString)(GLenum name); 88 GLint (*glGetUniformLocation)(GLuint program, const GLchar *name); 89 void (*glGetVertexAttribiv)(GLuint index, GLenum pname, GLint *params); 90 void (*glGetVertexAttribPointerv)(GLuint index, GLenum pname, void **params); 91 GLboolean (*glIsEnabled)(GLenum cap); 92 void (*glLinkProgram)(GLuint program); 93 void (*glPixelStorei)(GLenum pname, GLint param); 94 void (*glReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); 95 void (*glRenderbufferStorage)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); 96 void (*glScissor)(GLint x, GLint y, GLsizei width, GLsizei height); 97 void (*glShaderSource)(GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); 98 void (*glTexImage2D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); 99 void (*glTexParameteri)(GLenum target, GLenum pname, GLint param); 100 void (*glTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); 101 void (*glUniform1f)(GLint location, GLfloat v0); 102 void (*glUniform1i)(GLint location, GLint v0); 103 void (*glUniform2f)(GLint location, GLfloat v0, GLfloat v1); 104 void (*glUniform3f)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2); 105 void (*glUniform4f)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); 106 void (*glUseProgram)(GLuint program); 107 void (*glVertexAttribPointer)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); 108 void (*glViewport)(GLint x, GLint y, GLsizei width, GLsizei height); 109 110 void (*glBindVertexArray)(GLuint array); 111 void (*glBindBufferBase)(GLenum target, GLuint index, GLuint buffer); 112 GLuint (*glGetUniformBlockIndex)(GLuint program, const GLchar *uniformBlockName); 113 void (*glUniformBlockBinding)(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); 114 void (*glInvalidateFramebuffer)(GLenum target, GLsizei numAttachments, const GLenum *attachments); 115 void (*glBeginQuery)(GLenum target, GLuint id); 116 void (*glDeleteQueries)(GLsizei n, const GLuint *ids); 117 void (*glDeleteVertexArrays)(GLsizei n, const GLuint *ids); 118 void (*glEndQuery)(GLenum target); 119 void (*glGenQueries)(GLsizei n, GLuint *ids); 120 void (*glGenVertexArrays)(GLsizei n, GLuint *ids); 121 void (*glGetProgramBinary)(GLuint program, GLsizei bufsize, GLsizei *length, GLenum *binaryFormat, void *binary); 122 void (*glGetQueryObjectuiv)(GLuint id, GLenum pname, GLuint *params); 123 const GLubyte* (*glGetStringi)(GLenum name, GLuint index); 124 void (*glDispatchCompute)(GLuint x, GLuint y, GLuint z); 125 void (*glMemoryBarrier)(GLbitfield barriers); 126 void* (*glMapBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); 127 GLboolean (*glUnmapBuffer)(GLenum target); 128 void (*glBindImageTexture)(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); 129 void (*glTexStorage2D)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); 130 void (*glBlitFramebuffer)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); 131 } glFunctions; 132 133 static void glActiveTexture(glFunctions *f, GLenum texture) { 134 f->glActiveTexture(texture); 135 } 136 137 static void glAttachShader(glFunctions *f, GLuint program, GLuint shader) { 138 f->glAttachShader(program, shader); 139 } 140 141 static void glBindAttribLocation(glFunctions *f, GLuint program, GLuint index, const GLchar *name) { 142 f->glBindAttribLocation(program, index, name); 143 } 144 145 static void glBindBuffer(glFunctions *f, GLenum target, GLuint buffer) { 146 f->glBindBuffer(target, buffer); 147 } 148 149 static void glBindFramebuffer(glFunctions *f, GLenum target, GLuint framebuffer) { 150 f->glBindFramebuffer(target, framebuffer); 151 } 152 153 static void glBindRenderbuffer(glFunctions *f, GLenum target, GLuint renderbuffer) { 154 f->glBindRenderbuffer(target, renderbuffer); 155 } 156 157 static void glBindTexture(glFunctions *f, GLenum target, GLuint texture) { 158 f->glBindTexture(target, texture); 159 } 160 161 static void glBindVertexArray(glFunctions *f, GLuint array) { 162 f->glBindVertexArray(array); 163 } 164 165 static void glBlendEquation(glFunctions *f, GLenum mode) { 166 f->glBlendEquation(mode); 167 } 168 169 static void glBlendFuncSeparate(glFunctions *f, GLenum srcRGB, GLenum dstRGB, GLenum srcA, GLenum dstA) { 170 f->glBlendFuncSeparate(srcRGB, dstRGB, srcA, dstA); 171 } 172 173 static void glBufferData(glFunctions *f, GLenum target, GLsizeiptr size, const void *data, GLenum usage) { 174 f->glBufferData(target, size, data, usage); 175 } 176 177 static void glBufferSubData(glFunctions *f, GLenum target, GLintptr offset, GLsizeiptr size, const void *data) { 178 f->glBufferSubData(target, offset, size, data); 179 } 180 181 static GLenum glCheckFramebufferStatus(glFunctions *f, GLenum target) { 182 return f->glCheckFramebufferStatus(target); 183 } 184 185 static void glClear(glFunctions *f, GLbitfield mask) { 186 f->glClear(mask); 187 } 188 189 static void glClearColor(glFunctions *f, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { 190 f->glClearColor(red, green, blue, alpha); 191 } 192 193 static void glClearDepthf(glFunctions *f, GLfloat d) { 194 f->glClearDepthf(d); 195 } 196 197 static void glCompileShader(glFunctions *f, GLuint shader) { 198 f->glCompileShader(shader); 199 } 200 201 static GLuint glCreateProgram(glFunctions *f) { 202 return f->glCreateProgram(); 203 } 204 205 static GLuint glCreateShader(glFunctions *f, GLenum type) { 206 return f->glCreateShader(type); 207 } 208 209 static void glDeleteBuffers(glFunctions *f, GLsizei n, const GLuint *buffers) { 210 f->glDeleteBuffers(n, buffers); 211 } 212 213 static void glDeleteFramebuffers(glFunctions *f, GLsizei n, const GLuint *framebuffers) { 214 f->glDeleteFramebuffers(n, framebuffers); 215 } 216 217 static void glDeleteProgram(glFunctions *f, GLuint program) { 218 f->glDeleteProgram(program); 219 } 220 221 static void glDeleteRenderbuffers(glFunctions *f, GLsizei n, const GLuint *renderbuffers) { 222 f->glDeleteRenderbuffers(n, renderbuffers); 223 } 224 225 static void glDeleteShader(glFunctions *f, GLuint shader) { 226 f->glDeleteShader(shader); 227 } 228 229 static void glDeleteTextures(glFunctions *f, GLsizei n, const GLuint *textures) { 230 f->glDeleteTextures(n, textures); 231 } 232 233 static void glDepthFunc(glFunctions *f, GLenum func) { 234 f->glDepthFunc(func); 235 } 236 237 static void glDepthMask(glFunctions *f, GLboolean flag) { 238 f->glDepthMask(flag); 239 } 240 241 static void glDisable(glFunctions *f, GLenum cap) { 242 f->glDisable(cap); 243 } 244 245 static void glDisableVertexAttribArray(glFunctions *f, GLuint index) { 246 f->glDisableVertexAttribArray(index); 247 } 248 249 static void glDrawArrays(glFunctions *f, GLenum mode, GLint first, GLsizei count) { 250 f->glDrawArrays(mode, first, count); 251 } 252 253 // offset is defined as an uintptr_t to omit Cgo pointer checks. 254 static void glDrawElements(glFunctions *f, GLenum mode, GLsizei count, GLenum type, const uintptr_t offset) { 255 f->glDrawElements(mode, count, type, (const void *)offset); 256 } 257 258 static void glEnable(glFunctions *f, GLenum cap) { 259 f->glEnable(cap); 260 } 261 262 static void glEnableVertexAttribArray(glFunctions *f, GLuint index) { 263 f->glEnableVertexAttribArray(index); 264 } 265 266 static void glFinish(glFunctions *f) { 267 f->glFinish(); 268 } 269 270 static void glFlush(glFunctions *f) { 271 f->glFlush(); 272 } 273 274 static void glFramebufferRenderbuffer(glFunctions *f, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) { 275 f->glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer); 276 } 277 278 static void glFramebufferTexture2D(glFunctions *f, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) { 279 f->glFramebufferTexture2D(target, attachment, textarget, texture, level); 280 } 281 282 static void glGenBuffers(glFunctions *f, GLsizei n, GLuint *buffers) { 283 f->glGenBuffers(n, buffers); 284 } 285 286 static void glGenFramebuffers(glFunctions *f, GLsizei n, GLuint *framebuffers) { 287 f->glGenFramebuffers(n, framebuffers); 288 } 289 290 static void glGenRenderbuffers(glFunctions *f, GLsizei n, GLuint *renderbuffers) { 291 f->glGenRenderbuffers(n, renderbuffers); 292 } 293 294 static void glGenTextures(glFunctions *f, GLsizei n, GLuint *textures) { 295 f->glGenTextures(n, textures); 296 } 297 298 static GLenum glGetError(glFunctions *f) { 299 return f->glGetError(); 300 } 301 302 static void glGetFramebufferAttachmentParameteriv(glFunctions *f, GLenum target, GLenum attachment, GLenum pname, GLint *params) { 303 f->glGetFramebufferAttachmentParameteriv(target, attachment, pname, params); 304 } 305 306 static void glGetIntegerv(glFunctions *f, GLenum pname, GLint *data) { 307 f->glGetIntegerv(pname, data); 308 } 309 310 static void glGetFloatv(glFunctions *f, GLenum pname, GLfloat *data) { 311 f->glGetFloatv(pname, data); 312 } 313 314 static void glGetIntegeri_v(glFunctions *f, GLenum pname, GLuint idx, GLint *data) { 315 f->glGetIntegeri_v(pname, idx, data); 316 } 317 318 static void glGetProgramiv(glFunctions *f, GLuint program, GLenum pname, GLint *params) { 319 f->glGetProgramiv(program, pname, params); 320 } 321 322 static void glGetProgramInfoLog(glFunctions *f, GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog) { 323 f->glGetProgramInfoLog(program, bufSize, length, infoLog); 324 } 325 326 static void glGetRenderbufferParameteriv(glFunctions *f, GLenum target, GLenum pname, GLint *params) { 327 f->glGetRenderbufferParameteriv(target, pname, params); 328 } 329 330 static void glGetShaderiv(glFunctions *f, GLuint shader, GLenum pname, GLint *params) { 331 f->glGetShaderiv(shader, pname, params); 332 } 333 334 static void glGetShaderInfoLog(glFunctions *f, GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog) { 335 f->glGetShaderInfoLog(shader, bufSize, length, infoLog); 336 } 337 338 static const GLubyte *glGetString(glFunctions *f, GLenum name) { 339 return f->glGetString(name); 340 } 341 342 static GLint glGetUniformLocation(glFunctions *f, GLuint program, const GLchar *name) { 343 return f->glGetUniformLocation(program, name); 344 } 345 346 static void glGetVertexAttribiv(glFunctions *f, GLuint index, GLenum pname, GLint *data) { 347 f->glGetVertexAttribiv(index, pname, data); 348 } 349 350 // Return uintptr_t to avoid Cgo pointer check. 351 static uintptr_t glGetVertexAttribPointerv(glFunctions *f, GLuint index, GLenum pname) { 352 void *ptrs; 353 f->glGetVertexAttribPointerv(index, pname, &ptrs); 354 return (uintptr_t)ptrs; 355 } 356 357 static GLboolean glIsEnabled(glFunctions *f, GLenum cap) { 358 return f->glIsEnabled(cap); 359 } 360 361 static void glLinkProgram(glFunctions *f, GLuint program) { 362 f->glLinkProgram(program); 363 } 364 365 static void glPixelStorei(glFunctions *f, GLenum pname, GLint param) { 366 f->glPixelStorei(pname, param); 367 } 368 369 static void glReadPixels(glFunctions *f, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels) { 370 f->glReadPixels(x, y, width, height, format, type, pixels); 371 } 372 373 static void glRenderbufferStorage(glFunctions *f, GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { 374 f->glRenderbufferStorage(target, internalformat, width, height); 375 } 376 377 static void glScissor(glFunctions *f, GLint x, GLint y, GLsizei width, GLsizei height) { 378 f->glScissor(x, y, width, height); 379 } 380 381 static void glShaderSource(glFunctions *f, GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length) { 382 f->glShaderSource(shader, count, string, length); 383 } 384 385 static void glTexImage2D(glFunctions *f, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels) { 386 f->glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); 387 } 388 389 static void glTexParameteri(glFunctions *f, GLenum target, GLenum pname, GLint param) { 390 f->glTexParameteri(target, pname, param); 391 } 392 393 static void glTexSubImage2D(glFunctions *f, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) { 394 f->glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); 395 } 396 397 static void glUniform1f(glFunctions *f, GLint location, GLfloat v0) { 398 f->glUniform1f(location, v0); 399 } 400 401 static void glUniform1i(glFunctions *f, GLint location, GLint v0) { 402 f->glUniform1i(location, v0); 403 } 404 405 static void glUniform2f(glFunctions *f, GLint location, GLfloat v0, GLfloat v1) { 406 f->glUniform2f(location, v0, v1); 407 } 408 409 static void glUniform3f(glFunctions *f, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) { 410 f->glUniform3f(location, v0, v1, v2); 411 } 412 413 static void glUniform4f(glFunctions *f, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) { 414 f->glUniform4f(location, v0, v1, v2, v3); 415 } 416 417 static void glUseProgram(glFunctions *f, GLuint program) { 418 f->glUseProgram(program); 419 } 420 421 // offset is defined as an uintptr_t to omit Cgo pointer checks. 422 static void glVertexAttribPointer(glFunctions *f, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, uintptr_t offset) { 423 f->glVertexAttribPointer(index, size, type, normalized, stride, (const void *)offset); 424 } 425 426 static void glViewport(glFunctions *f, GLint x, GLint y, GLsizei width, GLsizei height) { 427 f->glViewport(x, y, width, height); 428 } 429 430 static void glBindBufferBase(glFunctions *f, GLenum target, GLuint index, GLuint buffer) { 431 f->glBindBufferBase(target, index, buffer); 432 } 433 434 static void glUniformBlockBinding(glFunctions *f, GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) { 435 f->glUniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding); 436 } 437 438 static GLuint glGetUniformBlockIndex(glFunctions *f, GLuint program, const GLchar *uniformBlockName) { 439 return f->glGetUniformBlockIndex(program, uniformBlockName); 440 } 441 442 static void glInvalidateFramebuffer(glFunctions *f, GLenum target, GLenum attachment) { 443 // Framebuffer invalidation is just a hint and can safely be ignored. 444 if (f->glInvalidateFramebuffer != NULL) { 445 f->glInvalidateFramebuffer(target, 1, &attachment); 446 } 447 } 448 449 static void glBeginQuery(glFunctions *f, GLenum target, GLenum attachment) { 450 f->glBeginQuery(target, attachment); 451 } 452 453 static void glDeleteQueries(glFunctions *f, GLsizei n, const GLuint *ids) { 454 f->glDeleteQueries(n, ids); 455 } 456 457 static void glDeleteVertexArrays(glFunctions *f, GLsizei n, const GLuint *ids) { 458 f->glDeleteVertexArrays(n, ids); 459 } 460 461 static void glEndQuery(glFunctions *f, GLenum target) { 462 f->glEndQuery(target); 463 } 464 465 static const GLubyte* glGetStringi(glFunctions *f, GLenum name, GLuint index) { 466 return f->glGetStringi(name, index); 467 } 468 469 static void glGenQueries(glFunctions *f, GLsizei n, GLuint *ids) { 470 f->glGenQueries(n, ids); 471 } 472 473 static void glGenVertexArrays(glFunctions *f, GLsizei n, GLuint *ids) { 474 f->glGenVertexArrays(n, ids); 475 } 476 477 static void glGetProgramBinary(glFunctions *f, GLuint program, GLsizei bufsize, GLsizei *length, GLenum *binaryFormat, void *binary) { 478 f->glGetProgramBinary(program, bufsize, length, binaryFormat, binary); 479 } 480 481 static void glGetQueryObjectuiv(glFunctions *f, GLuint id, GLenum pname, GLuint *params) { 482 f->glGetQueryObjectuiv(id, pname, params); 483 } 484 485 static void glMemoryBarrier(glFunctions *f, GLbitfield barriers) { 486 f->glMemoryBarrier(barriers); 487 } 488 489 static void glDispatchCompute(glFunctions *f, GLuint x, GLuint y, GLuint z) { 490 f->glDispatchCompute(x, y, z); 491 } 492 493 static void *glMapBufferRange(glFunctions *f, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) { 494 return f->glMapBufferRange(target, offset, length, access); 495 } 496 497 static GLboolean glUnmapBuffer(glFunctions *f, GLenum target) { 498 return f->glUnmapBuffer(target); 499 } 500 501 static void glBindImageTexture(glFunctions *f, GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format) { 502 f->glBindImageTexture(unit, texture, level, layered, layer, access, format); 503 } 504 505 static void glTexStorage2D(glFunctions *f, GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height) { 506 f->glTexStorage2D(target, levels, internalFormat, width, height); 507 } 508 509 static void glBlitFramebuffer(glFunctions *f, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { 510 f->glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); 511 } 512 */ 513 import "C" 514 515 type Context interface{} 516 517 type Functions struct { 518 // Query caches. 519 uints [100]C.GLuint 520 ints [100]C.GLint 521 floats [100]C.GLfloat 522 523 f C.glFunctions 524 } 525 526 func NewFunctions(ctx Context, forceES bool) (*Functions, error) { 527 if ctx != nil { 528 panic("non-nil context") 529 } 530 f := new(Functions) 531 err := f.load(forceES) 532 if err != nil { 533 return nil, err 534 } 535 return f, nil 536 } 537 538 func dlsym(handle unsafe.Pointer, s string) unsafe.Pointer { 539 cs := C.CString(s) 540 defer C.free(unsafe.Pointer(cs)) 541 return C.dlsym(handle, cs) 542 } 543 544 func dlopen(lib string) unsafe.Pointer { 545 clib := C.CString(lib) 546 defer C.free(unsafe.Pointer(clib)) 547 return C.dlopen(clib, C.RTLD_NOW) 548 } 549 550 func (f *Functions) load(forceES bool) error { 551 var ( 552 loadErr error 553 libNames []string 554 handles []unsafe.Pointer 555 ) 556 switch { 557 case runtime.GOOS == "darwin" && !forceES: 558 libNames = []string{"/System/Library/Frameworks/OpenGL.framework/OpenGL"} 559 case runtime.GOOS == "darwin" && forceES: 560 libNames = []string{"libGLESv2.dylib"} 561 case runtime.GOOS == "ios": 562 libNames = []string{"/System/Library/Frameworks/OpenGLES.framework/OpenGLES"} 563 default: 564 libNames = []string{"libGLESv2.so", "libGLESv3.so"} 565 } 566 for _, lib := range libNames { 567 if h := dlopen(lib); h != nil { 568 handles = append(handles, h) 569 } 570 } 571 if len(handles) == 0 { 572 return fmt.Errorf("gl: no OpenGL implementation could be loaded (tried %q)", libNames) 573 } 574 load := func(s string) *[0]byte { 575 for _, h := range handles { 576 if f := dlsym(h, s); f != nil { 577 return (*[0]byte)(f) 578 } 579 } 580 return nil 581 } 582 must := func(s string) *[0]byte { 583 ptr := load(s) 584 if ptr == nil { 585 loadErr = fmt.Errorf("gl: failed to load symbol %q", s) 586 } 587 return ptr 588 } 589 // GL ES 2.0 functions. 590 f.f.glActiveTexture = must("glActiveTexture") 591 f.f.glAttachShader = must("glAttachShader") 592 f.f.glBindAttribLocation = must("glBindAttribLocation") 593 f.f.glBindBuffer = must("glBindBuffer") 594 f.f.glBindFramebuffer = must("glBindFramebuffer") 595 f.f.glBindRenderbuffer = must("glBindRenderbuffer") 596 f.f.glBindTexture = must("glBindTexture") 597 f.f.glBlendEquation = must("glBlendEquation") 598 f.f.glBlendFuncSeparate = must("glBlendFuncSeparate") 599 f.f.glBufferData = must("glBufferData") 600 f.f.glBufferSubData = must("glBufferSubData") 601 f.f.glCheckFramebufferStatus = must("glCheckFramebufferStatus") 602 f.f.glClear = must("glClear") 603 f.f.glClearColor = must("glClearColor") 604 f.f.glClearDepthf = must("glClearDepthf") 605 f.f.glCompileShader = must("glCompileShader") 606 f.f.glCreateProgram = must("glCreateProgram") 607 f.f.glCreateShader = must("glCreateShader") 608 f.f.glDeleteBuffers = must("glDeleteBuffers") 609 f.f.glDeleteFramebuffers = must("glDeleteFramebuffers") 610 f.f.glDeleteProgram = must("glDeleteProgram") 611 f.f.glDeleteRenderbuffers = must("glDeleteRenderbuffers") 612 f.f.glDeleteShader = must("glDeleteShader") 613 f.f.glDeleteTextures = must("glDeleteTextures") 614 f.f.glDepthFunc = must("glDepthFunc") 615 f.f.glDepthMask = must("glDepthMask") 616 f.f.glDisable = must("glDisable") 617 f.f.glDisableVertexAttribArray = must("glDisableVertexAttribArray") 618 f.f.glDrawArrays = must("glDrawArrays") 619 f.f.glDrawElements = must("glDrawElements") 620 f.f.glEnable = must("glEnable") 621 f.f.glEnableVertexAttribArray = must("glEnableVertexAttribArray") 622 f.f.glFinish = must("glFinish") 623 f.f.glFlush = must("glFlush") 624 f.f.glFramebufferRenderbuffer = must("glFramebufferRenderbuffer") 625 f.f.glFramebufferTexture2D = must("glFramebufferTexture2D") 626 f.f.glGenBuffers = must("glGenBuffers") 627 f.f.glGenFramebuffers = must("glGenFramebuffers") 628 f.f.glGenRenderbuffers = must("glGenRenderbuffers") 629 f.f.glGenTextures = must("glGenTextures") 630 f.f.glGetError = must("glGetError") 631 f.f.glGetFramebufferAttachmentParameteriv = must("glGetFramebufferAttachmentParameteriv") 632 f.f.glGetIntegerv = must("glGetIntegerv") 633 f.f.glGetFloatv = must("glGetFloatv") 634 f.f.glGetProgramiv = must("glGetProgramiv") 635 f.f.glGetProgramInfoLog = must("glGetProgramInfoLog") 636 f.f.glGetRenderbufferParameteriv = must("glGetRenderbufferParameteriv") 637 f.f.glGetShaderiv = must("glGetShaderiv") 638 f.f.glGetShaderInfoLog = must("glGetShaderInfoLog") 639 f.f.glGetString = must("glGetString") 640 f.f.glGetUniformLocation = must("glGetUniformLocation") 641 f.f.glGetVertexAttribiv = must("glGetVertexAttribiv") 642 f.f.glGetVertexAttribPointerv = must("glGetVertexAttribPointerv") 643 f.f.glIsEnabled = must("glIsEnabled") 644 f.f.glLinkProgram = must("glLinkProgram") 645 f.f.glPixelStorei = must("glPixelStorei") 646 f.f.glReadPixels = must("glReadPixels") 647 f.f.glRenderbufferStorage = must("glRenderbufferStorage") 648 f.f.glScissor = must("glScissor") 649 f.f.glShaderSource = must("glShaderSource") 650 f.f.glTexImage2D = must("glTexImage2D") 651 f.f.glTexParameteri = must("glTexParameteri") 652 f.f.glTexSubImage2D = must("glTexSubImage2D") 653 f.f.glUniform1f = must("glUniform1f") 654 f.f.glUniform1i = must("glUniform1i") 655 f.f.glUniform2f = must("glUniform2f") 656 f.f.glUniform3f = must("glUniform3f") 657 f.f.glUniform4f = must("glUniform4f") 658 f.f.glUseProgram = must("glUseProgram") 659 f.f.glVertexAttribPointer = must("glVertexAttribPointer") 660 f.f.glViewport = must("glViewport") 661 662 // Extensions and GL ES 3 functions. 663 f.f.glBindBufferBase = load("glBindBufferBase") 664 f.f.glBindVertexArray = load("glBindVertexArray") 665 f.f.glGetIntegeri_v = load("glGetIntegeri_v") 666 f.f.glGetUniformBlockIndex = load("glGetUniformBlockIndex") 667 f.f.glUniformBlockBinding = load("glUniformBlockBinding") 668 f.f.glInvalidateFramebuffer = load("glInvalidateFramebuffer") 669 f.f.glGetStringi = load("glGetStringi") 670 // Fall back to EXT_invalidate_framebuffer if available. 671 if f.f.glInvalidateFramebuffer == nil { 672 f.f.glInvalidateFramebuffer = load("glDiscardFramebufferEXT") 673 } 674 675 f.f.glBeginQuery = load("glBeginQuery") 676 if f.f.glBeginQuery == nil { 677 f.f.glBeginQuery = load("glBeginQueryEXT") 678 } 679 f.f.glDeleteQueries = load("glDeleteQueries") 680 if f.f.glDeleteQueries == nil { 681 f.f.glDeleteQueries = load("glDeleteQueriesEXT") 682 } 683 f.f.glEndQuery = load("glEndQuery") 684 if f.f.glEndQuery == nil { 685 f.f.glEndQuery = load("glEndQueryEXT") 686 } 687 f.f.glGenQueries = load("glGenQueries") 688 if f.f.glGenQueries == nil { 689 f.f.glGenQueries = load("glGenQueriesEXT") 690 } 691 f.f.glGetQueryObjectuiv = load("glGetQueryObjectuiv") 692 if f.f.glGetQueryObjectuiv == nil { 693 f.f.glGetQueryObjectuiv = load("glGetQueryObjectuivEXT") 694 } 695 696 f.f.glDeleteVertexArrays = load("glDeleteVertexArrays") 697 f.f.glGenVertexArrays = load("glGenVertexArrays") 698 f.f.glMemoryBarrier = load("glMemoryBarrier") 699 f.f.glDispatchCompute = load("glDispatchCompute") 700 f.f.glMapBufferRange = load("glMapBufferRange") 701 f.f.glUnmapBuffer = load("glUnmapBuffer") 702 f.f.glBindImageTexture = load("glBindImageTexture") 703 f.f.glTexStorage2D = load("glTexStorage2D") 704 f.f.glBlitFramebuffer = load("glBlitFramebuffer") 705 f.f.glGetProgramBinary = load("glGetProgramBinary") 706 707 return loadErr 708 } 709 710 func (f *Functions) ActiveTexture(texture Enum) { 711 C.glActiveTexture(&f.f, C.GLenum(texture)) 712 } 713 714 func (f *Functions) AttachShader(p Program, s Shader) { 715 C.glAttachShader(&f.f, C.GLuint(p.V), C.GLuint(s.V)) 716 } 717 718 func (f *Functions) BeginQuery(target Enum, query Query) { 719 C.glBeginQuery(&f.f, C.GLenum(target), C.GLenum(query.V)) 720 } 721 722 func (f *Functions) BindAttribLocation(p Program, a Attrib, name string) { 723 cname := C.CString(name) 724 defer C.free(unsafe.Pointer(cname)) 725 C.glBindAttribLocation(&f.f, C.GLuint(p.V), C.GLuint(a), cname) 726 } 727 728 func (f *Functions) BindBufferBase(target Enum, index int, b Buffer) { 729 C.glBindBufferBase(&f.f, C.GLenum(target), C.GLuint(index), C.GLuint(b.V)) 730 } 731 732 func (f *Functions) BindBuffer(target Enum, b Buffer) { 733 C.glBindBuffer(&f.f, C.GLenum(target), C.GLuint(b.V)) 734 } 735 736 func (f *Functions) BindFramebuffer(target Enum, fb Framebuffer) { 737 C.glBindFramebuffer(&f.f, C.GLenum(target), C.GLuint(fb.V)) 738 } 739 740 func (f *Functions) BindRenderbuffer(target Enum, fb Renderbuffer) { 741 C.glBindRenderbuffer(&f.f, C.GLenum(target), C.GLuint(fb.V)) 742 } 743 744 func (f *Functions) BindImageTexture(unit int, t Texture, level int, layered bool, layer int, access, format Enum) { 745 l := C.GLboolean(FALSE) 746 if layered { 747 l = TRUE 748 } 749 C.glBindImageTexture(&f.f, C.GLuint(unit), C.GLuint(t.V), C.GLint(level), l, C.GLint(layer), C.GLenum(access), C.GLenum(format)) 750 } 751 752 func (f *Functions) BindTexture(target Enum, t Texture) { 753 C.glBindTexture(&f.f, C.GLenum(target), C.GLuint(t.V)) 754 } 755 756 func (f *Functions) BindVertexArray(a VertexArray) { 757 C.glBindVertexArray(&f.f, C.GLuint(a.V)) 758 } 759 760 func (f *Functions) BlendEquation(mode Enum) { 761 C.glBlendEquation(&f.f, C.GLenum(mode)) 762 } 763 764 func (f *Functions) BlendFuncSeparate(srcRGB, dstRGB, srcA, dstA Enum) { 765 C.glBlendFuncSeparate(&f.f, C.GLenum(srcRGB), C.GLenum(dstRGB), C.GLenum(srcA), C.GLenum(dstA)) 766 } 767 768 func (f *Functions) BlitFramebuffer(sx0, sy0, sx1, sy1, dx0, dy0, dx1, dy1 int, mask Enum, filter Enum) { 769 C.glBlitFramebuffer(&f.f, 770 C.GLint(sx0), C.GLint(sy0), C.GLint(sx1), C.GLint(sy1), 771 C.GLint(dx0), C.GLint(dy0), C.GLint(dx1), C.GLint(dy1), 772 C.GLenum(mask), C.GLenum(filter), 773 ) 774 } 775 776 func (f *Functions) BufferData(target Enum, size int, usage Enum) { 777 C.glBufferData(&f.f, C.GLenum(target), C.GLsizeiptr(size), nil, C.GLenum(usage)) 778 } 779 780 func (f *Functions) BufferSubData(target Enum, offset int, src []byte) { 781 var p unsafe.Pointer 782 if len(src) > 0 { 783 p = unsafe.Pointer(&src[0]) 784 } 785 C.glBufferSubData(&f.f, C.GLenum(target), C.GLintptr(offset), C.GLsizeiptr(len(src)), p) 786 } 787 788 func (f *Functions) CheckFramebufferStatus(target Enum) Enum { 789 return Enum(C.glCheckFramebufferStatus(&f.f, C.GLenum(target))) 790 } 791 792 func (f *Functions) Clear(mask Enum) { 793 C.glClear(&f.f, C.GLbitfield(mask)) 794 } 795 796 func (f *Functions) ClearColor(red float32, green float32, blue float32, alpha float32) { 797 C.glClearColor(&f.f, C.GLfloat(red), C.GLfloat(green), C.GLfloat(blue), C.GLfloat(alpha)) 798 } 799 800 func (f *Functions) ClearDepthf(d float32) { 801 C.glClearDepthf(&f.f, C.GLfloat(d)) 802 } 803 804 func (f *Functions) CompileShader(s Shader) { 805 C.glCompileShader(&f.f, C.GLuint(s.V)) 806 } 807 808 func (f *Functions) CreateBuffer() Buffer { 809 C.glGenBuffers(&f.f, 1, &f.uints[0]) 810 return Buffer{uint(f.uints[0])} 811 } 812 813 func (f *Functions) CreateFramebuffer() Framebuffer { 814 C.glGenFramebuffers(&f.f, 1, &f.uints[0]) 815 return Framebuffer{uint(f.uints[0])} 816 } 817 818 func (f *Functions) CreateProgram() Program { 819 return Program{uint(C.glCreateProgram(&f.f))} 820 } 821 822 func (f *Functions) CreateQuery() Query { 823 C.glGenQueries(&f.f, 1, &f.uints[0]) 824 return Query{uint(f.uints[0])} 825 } 826 827 func (f *Functions) CreateRenderbuffer() Renderbuffer { 828 C.glGenRenderbuffers(&f.f, 1, &f.uints[0]) 829 return Renderbuffer{uint(f.uints[0])} 830 } 831 832 func (f *Functions) CreateShader(ty Enum) Shader { 833 return Shader{uint(C.glCreateShader(&f.f, C.GLenum(ty)))} 834 } 835 836 func (f *Functions) CreateTexture() Texture { 837 C.glGenTextures(&f.f, 1, &f.uints[0]) 838 return Texture{uint(f.uints[0])} 839 } 840 841 func (f *Functions) CreateVertexArray() VertexArray { 842 C.glGenVertexArrays(&f.f, 1, &f.uints[0]) 843 return VertexArray{uint(f.uints[0])} 844 } 845 846 func (f *Functions) DeleteBuffer(v Buffer) { 847 f.uints[0] = C.GLuint(v.V) 848 C.glDeleteBuffers(&f.f, 1, &f.uints[0]) 849 } 850 851 func (f *Functions) DeleteFramebuffer(v Framebuffer) { 852 f.uints[0] = C.GLuint(v.V) 853 C.glDeleteFramebuffers(&f.f, 1, &f.uints[0]) 854 } 855 856 func (f *Functions) DeleteProgram(p Program) { 857 C.glDeleteProgram(&f.f, C.GLuint(p.V)) 858 } 859 860 func (f *Functions) DeleteQuery(query Query) { 861 f.uints[0] = C.GLuint(query.V) 862 C.glDeleteQueries(&f.f, 1, &f.uints[0]) 863 } 864 865 func (f *Functions) DeleteVertexArray(array VertexArray) { 866 f.uints[0] = C.GLuint(array.V) 867 C.glDeleteVertexArrays(&f.f, 1, &f.uints[0]) 868 } 869 870 func (f *Functions) DeleteRenderbuffer(v Renderbuffer) { 871 f.uints[0] = C.GLuint(v.V) 872 C.glDeleteRenderbuffers(&f.f, 1, &f.uints[0]) 873 } 874 875 func (f *Functions) DeleteShader(s Shader) { 876 C.glDeleteShader(&f.f, C.GLuint(s.V)) 877 } 878 879 func (f *Functions) DeleteTexture(v Texture) { 880 f.uints[0] = C.GLuint(v.V) 881 C.glDeleteTextures(&f.f, 1, &f.uints[0]) 882 } 883 884 func (f *Functions) DepthFunc(v Enum) { 885 C.glDepthFunc(&f.f, C.GLenum(v)) 886 } 887 888 func (f *Functions) DepthMask(mask bool) { 889 m := C.GLboolean(FALSE) 890 if mask { 891 m = C.GLboolean(TRUE) 892 } 893 C.glDepthMask(&f.f, m) 894 } 895 896 func (f *Functions) DisableVertexAttribArray(a Attrib) { 897 C.glDisableVertexAttribArray(&f.f, C.GLuint(a)) 898 } 899 900 func (f *Functions) Disable(cap Enum) { 901 C.glDisable(&f.f, C.GLenum(cap)) 902 } 903 904 func (f *Functions) DrawArrays(mode Enum, first int, count int) { 905 C.glDrawArrays(&f.f, C.GLenum(mode), C.GLint(first), C.GLsizei(count)) 906 } 907 908 func (f *Functions) DrawElements(mode Enum, count int, ty Enum, offset int) { 909 C.glDrawElements(&f.f, C.GLenum(mode), C.GLsizei(count), C.GLenum(ty), C.uintptr_t(offset)) 910 } 911 912 func (f *Functions) DispatchCompute(x, y, z int) { 913 C.glDispatchCompute(&f.f, C.GLuint(x), C.GLuint(y), C.GLuint(z)) 914 } 915 916 func (f *Functions) Enable(cap Enum) { 917 C.glEnable(&f.f, C.GLenum(cap)) 918 } 919 920 func (f *Functions) EndQuery(target Enum) { 921 C.glEndQuery(&f.f, C.GLenum(target)) 922 } 923 924 func (f *Functions) EnableVertexAttribArray(a Attrib) { 925 C.glEnableVertexAttribArray(&f.f, C.GLuint(a)) 926 } 927 928 func (f *Functions) Finish() { 929 C.glFinish(&f.f) 930 } 931 932 func (f *Functions) Flush() { 933 C.glFlush(&f.f) 934 } 935 936 func (f *Functions) FramebufferRenderbuffer(target, attachment, renderbuffertarget Enum, renderbuffer Renderbuffer) { 937 C.glFramebufferRenderbuffer(&f.f, C.GLenum(target), C.GLenum(attachment), C.GLenum(renderbuffertarget), C.GLuint(renderbuffer.V)) 938 } 939 940 func (f *Functions) FramebufferTexture2D(target, attachment, texTarget Enum, t Texture, level int) { 941 C.glFramebufferTexture2D(&f.f, C.GLenum(target), C.GLenum(attachment), C.GLenum(texTarget), C.GLuint(t.V), C.GLint(level)) 942 } 943 944 func (c *Functions) GetBinding(pname Enum) Object { 945 return Object{uint(c.GetInteger(pname))} 946 } 947 948 func (c *Functions) GetBindingi(pname Enum, idx int) Object { 949 return Object{uint(c.GetIntegeri(pname, idx))} 950 } 951 952 func (f *Functions) GetError() Enum { 953 return Enum(C.glGetError(&f.f)) 954 } 955 956 func (f *Functions) GetRenderbufferParameteri(target, pname Enum) int { 957 C.glGetRenderbufferParameteriv(&f.f, C.GLenum(target), C.GLenum(pname), &f.ints[0]) 958 return int(f.ints[0]) 959 } 960 961 func (f *Functions) GetFramebufferAttachmentParameteri(target, attachment, pname Enum) int { 962 C.glGetFramebufferAttachmentParameteriv(&f.f, C.GLenum(target), C.GLenum(attachment), C.GLenum(pname), &f.ints[0]) 963 return int(f.ints[0]) 964 } 965 966 func (f *Functions) GetFloat4(pname Enum) [4]float32 { 967 C.glGetFloatv(&f.f, C.GLenum(pname), &f.floats[0]) 968 var r [4]float32 969 for i := range r { 970 r[i] = float32(f.floats[i]) 971 } 972 return r 973 } 974 975 func (f *Functions) GetFloat(pname Enum) float32 { 976 C.glGetFloatv(&f.f, C.GLenum(pname), &f.floats[0]) 977 return float32(f.floats[0]) 978 } 979 980 func (f *Functions) GetInteger4(pname Enum) [4]int { 981 C.glGetIntegerv(&f.f, C.GLenum(pname), &f.ints[0]) 982 var r [4]int 983 for i := range r { 984 r[i] = int(f.ints[i]) 985 } 986 return r 987 } 988 989 func (f *Functions) GetInteger(pname Enum) int { 990 C.glGetIntegerv(&f.f, C.GLenum(pname), &f.ints[0]) 991 return int(f.ints[0]) 992 } 993 994 func (f *Functions) GetIntegeri(pname Enum, idx int) int { 995 C.glGetIntegeri_v(&f.f, C.GLenum(pname), C.GLuint(idx), &f.ints[0]) 996 return int(f.ints[0]) 997 } 998 999 func (f *Functions) GetProgrami(p Program, pname Enum) int { 1000 C.glGetProgramiv(&f.f, C.GLuint(p.V), C.GLenum(pname), &f.ints[0]) 1001 return int(f.ints[0]) 1002 } 1003 1004 func (f *Functions) GetProgramBinary(p Program) []byte { 1005 sz := f.GetProgrami(p, PROGRAM_BINARY_LENGTH) 1006 if sz == 0 { 1007 return nil 1008 } 1009 buf := make([]byte, sz) 1010 var format C.GLenum 1011 C.glGetProgramBinary(&f.f, C.GLuint(p.V), C.GLsizei(sz), nil, &format, unsafe.Pointer(&buf[0])) 1012 return buf 1013 } 1014 1015 func (f *Functions) GetProgramInfoLog(p Program) string { 1016 n := f.GetProgrami(p, INFO_LOG_LENGTH) 1017 buf := make([]byte, n) 1018 C.glGetProgramInfoLog(&f.f, C.GLuint(p.V), C.GLsizei(len(buf)), nil, (*C.GLchar)(unsafe.Pointer(&buf[0]))) 1019 return string(buf) 1020 } 1021 1022 func (f *Functions) GetQueryObjectuiv(query Query, pname Enum) uint { 1023 C.glGetQueryObjectuiv(&f.f, C.GLuint(query.V), C.GLenum(pname), &f.uints[0]) 1024 return uint(f.uints[0]) 1025 } 1026 1027 func (f *Functions) GetShaderi(s Shader, pname Enum) int { 1028 C.glGetShaderiv(&f.f, C.GLuint(s.V), C.GLenum(pname), &f.ints[0]) 1029 return int(f.ints[0]) 1030 } 1031 1032 func (f *Functions) GetShaderInfoLog(s Shader) string { 1033 n := f.GetShaderi(s, INFO_LOG_LENGTH) 1034 buf := make([]byte, n) 1035 C.glGetShaderInfoLog(&f.f, C.GLuint(s.V), C.GLsizei(len(buf)), nil, (*C.GLchar)(unsafe.Pointer(&buf[0]))) 1036 return string(buf) 1037 } 1038 1039 func (f *Functions) getStringi(pname Enum, index int) string { 1040 str := C.glGetStringi(&f.f, C.GLenum(pname), C.GLuint(index)) 1041 if str == nil { 1042 return "" 1043 } 1044 return C.GoString((*C.char)(unsafe.Pointer(str))) 1045 } 1046 1047 func (f *Functions) GetString(pname Enum) string { 1048 switch { 1049 case runtime.GOOS == "darwin" && pname == EXTENSIONS: 1050 // macOS OpenGL 3 core profile doesn't support glGetString(GL_EXTENSIONS). 1051 // Use glGetStringi(GL_EXTENSIONS, <index>). 1052 var exts []string 1053 nexts := f.GetInteger(NUM_EXTENSIONS) 1054 for i := 0; i < nexts; i++ { 1055 ext := f.getStringi(EXTENSIONS, i) 1056 exts = append(exts, ext) 1057 } 1058 return strings.Join(exts, " ") 1059 default: 1060 str := C.glGetString(&f.f, C.GLenum(pname)) 1061 return C.GoString((*C.char)(unsafe.Pointer(str))) 1062 } 1063 } 1064 1065 func (f *Functions) GetUniformBlockIndex(p Program, name string) uint { 1066 cname := C.CString(name) 1067 defer C.free(unsafe.Pointer(cname)) 1068 return uint(C.glGetUniformBlockIndex(&f.f, C.GLuint(p.V), cname)) 1069 } 1070 1071 func (f *Functions) GetUniformLocation(p Program, name string) Uniform { 1072 cname := C.CString(name) 1073 defer C.free(unsafe.Pointer(cname)) 1074 return Uniform{int(C.glGetUniformLocation(&f.f, C.GLuint(p.V), cname))} 1075 } 1076 1077 func (f *Functions) GetVertexAttrib(index int, pname Enum) int { 1078 C.glGetVertexAttribiv(&f.f, C.GLuint(index), C.GLenum(pname), &f.ints[0]) 1079 return int(f.ints[0]) 1080 } 1081 1082 func (f *Functions) GetVertexAttribBinding(index int, pname Enum) Object { 1083 return Object{uint(f.GetVertexAttrib(index, pname))} 1084 } 1085 1086 func (f *Functions) GetVertexAttribPointer(index int, pname Enum) uintptr { 1087 ptr := C.glGetVertexAttribPointerv(&f.f, C.GLuint(index), C.GLenum(pname)) 1088 return uintptr(ptr) 1089 } 1090 1091 func (f *Functions) InvalidateFramebuffer(target, attachment Enum) { 1092 C.glInvalidateFramebuffer(&f.f, C.GLenum(target), C.GLenum(attachment)) 1093 } 1094 1095 func (f *Functions) IsEnabled(cap Enum) bool { 1096 return C.glIsEnabled(&f.f, C.GLenum(cap)) == TRUE 1097 } 1098 1099 func (f *Functions) LinkProgram(p Program) { 1100 C.glLinkProgram(&f.f, C.GLuint(p.V)) 1101 } 1102 1103 func (f *Functions) PixelStorei(pname Enum, param int32) { 1104 C.glPixelStorei(&f.f, C.GLenum(pname), C.GLint(param)) 1105 } 1106 1107 func (f *Functions) MemoryBarrier(barriers Enum) { 1108 C.glMemoryBarrier(&f.f, C.GLbitfield(barriers)) 1109 } 1110 1111 func (f *Functions) MapBufferRange(target Enum, offset, length int, access Enum) []byte { 1112 p := C.glMapBufferRange(&f.f, C.GLenum(target), C.GLintptr(offset), C.GLsizeiptr(length), C.GLbitfield(access)) 1113 if p == nil { 1114 return nil 1115 } 1116 return (*[1 << 30]byte)(p)[:length:length] 1117 } 1118 1119 func (f *Functions) Scissor(x, y, width, height int32) { 1120 C.glScissor(&f.f, C.GLint(x), C.GLint(y), C.GLsizei(width), C.GLsizei(height)) 1121 } 1122 1123 func (f *Functions) ReadPixels(x, y, width, height int, format, ty Enum, data []byte) { 1124 var p unsafe.Pointer 1125 if len(data) > 0 { 1126 p = unsafe.Pointer(&data[0]) 1127 } 1128 C.glReadPixels(&f.f, C.GLint(x), C.GLint(y), C.GLsizei(width), C.GLsizei(height), C.GLenum(format), C.GLenum(ty), p) 1129 } 1130 1131 func (f *Functions) RenderbufferStorage(target, internalformat Enum, width, height int) { 1132 C.glRenderbufferStorage(&f.f, C.GLenum(target), C.GLenum(internalformat), C.GLsizei(width), C.GLsizei(height)) 1133 } 1134 1135 func (f *Functions) ShaderSource(s Shader, src string) { 1136 csrc := C.CString(src) 1137 defer C.free(unsafe.Pointer(csrc)) 1138 strlen := C.GLint(len(src)) 1139 C.glShaderSource(&f.f, C.GLuint(s.V), 1, &csrc, &strlen) 1140 } 1141 1142 func (f *Functions) TexImage2D(target Enum, level int, internalFormat Enum, width int, height int, format Enum, ty Enum) { 1143 C.glTexImage2D(&f.f, C.GLenum(target), C.GLint(level), C.GLint(internalFormat), C.GLsizei(width), C.GLsizei(height), 0, C.GLenum(format), C.GLenum(ty), nil) 1144 } 1145 1146 func (f *Functions) TexStorage2D(target Enum, levels int, internalFormat Enum, width, height int) { 1147 C.glTexStorage2D(&f.f, C.GLenum(target), C.GLsizei(levels), C.GLenum(internalFormat), C.GLsizei(width), C.GLsizei(height)) 1148 } 1149 1150 func (f *Functions) TexSubImage2D(target Enum, level int, x int, y int, width int, height int, format Enum, ty Enum, data []byte) { 1151 var p unsafe.Pointer 1152 if len(data) > 0 { 1153 p = unsafe.Pointer(&data[0]) 1154 } 1155 C.glTexSubImage2D(&f.f, C.GLenum(target), C.GLint(level), C.GLint(x), C.GLint(y), C.GLsizei(width), C.GLsizei(height), C.GLenum(format), C.GLenum(ty), p) 1156 } 1157 1158 func (f *Functions) TexParameteri(target, pname Enum, param int) { 1159 C.glTexParameteri(&f.f, C.GLenum(target), C.GLenum(pname), C.GLint(param)) 1160 } 1161 1162 func (f *Functions) UniformBlockBinding(p Program, uniformBlockIndex uint, uniformBlockBinding uint) { 1163 C.glUniformBlockBinding(&f.f, C.GLuint(p.V), C.GLuint(uniformBlockIndex), C.GLuint(uniformBlockBinding)) 1164 } 1165 1166 func (f *Functions) Uniform1f(dst Uniform, v float32) { 1167 C.glUniform1f(&f.f, C.GLint(dst.V), C.GLfloat(v)) 1168 } 1169 1170 func (f *Functions) Uniform1i(dst Uniform, v int) { 1171 C.glUniform1i(&f.f, C.GLint(dst.V), C.GLint(v)) 1172 } 1173 1174 func (f *Functions) Uniform2f(dst Uniform, v0 float32, v1 float32) { 1175 C.glUniform2f(&f.f, C.GLint(dst.V), C.GLfloat(v0), C.GLfloat(v1)) 1176 } 1177 1178 func (f *Functions) Uniform3f(dst Uniform, v0 float32, v1 float32, v2 float32) { 1179 C.glUniform3f(&f.f, C.GLint(dst.V), C.GLfloat(v0), C.GLfloat(v1), C.GLfloat(v2)) 1180 } 1181 1182 func (f *Functions) Uniform4f(dst Uniform, v0 float32, v1 float32, v2 float32, v3 float32) { 1183 C.glUniform4f(&f.f, C.GLint(dst.V), C.GLfloat(v0), C.GLfloat(v1), C.GLfloat(v2), C.GLfloat(v3)) 1184 } 1185 1186 func (f *Functions) UseProgram(p Program) { 1187 C.glUseProgram(&f.f, C.GLuint(p.V)) 1188 } 1189 1190 func (f *Functions) UnmapBuffer(target Enum) bool { 1191 r := C.glUnmapBuffer(&f.f, C.GLenum(target)) 1192 return r == TRUE 1193 } 1194 1195 func (f *Functions) VertexAttribPointer(dst Attrib, size int, ty Enum, normalized bool, stride int, offset int) { 1196 var n C.GLboolean = FALSE 1197 if normalized { 1198 n = TRUE 1199 } 1200 C.glVertexAttribPointer(&f.f, C.GLuint(dst), C.GLint(size), C.GLenum(ty), n, C.GLsizei(stride), C.uintptr_t(offset)) 1201 } 1202 1203 func (f *Functions) Viewport(x int, y int, width int, height int) { 1204 C.glViewport(&f.f, C.GLint(x), C.GLint(y), C.GLsizei(width), C.GLsizei(height)) 1205 }