zorldo

Goofing around with Ebiten
git clone git://bsandro.tech/zorldo
Log | Files | Refs | README

gl.go (35996B)


      1 // Copyright 2014 The Go Authors.  All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 //go:build (darwin || linux || openbsd || windows) && !gldebug
      6 // +build darwin linux openbsd windows
      7 // +build !gldebug
      8 
      9 package gl
     10 
     11 // TODO(crawshaw): should functions on specific types become methods? E.g.
     12 //                 func (t Texture) Bind(target Enum)
     13 //                 this seems natural in Go, but moves us slightly
     14 //                 further away from the underlying OpenGL spec.
     15 
     16 import (
     17 	"math"
     18 	"unsafe"
     19 )
     20 
     21 func (ctx *context) ActiveTexture(texture Enum) {
     22 	ctx.enqueue(call{
     23 		args: fnargs{
     24 			fn: glfnActiveTexture,
     25 			a0: texture.c(),
     26 		},
     27 	})
     28 }
     29 
     30 func (ctx *context) AttachShader(p Program, s Shader) {
     31 	ctx.enqueue(call{
     32 		args: fnargs{
     33 			fn: glfnAttachShader,
     34 			a0: p.c(),
     35 			a1: s.c(),
     36 		},
     37 	})
     38 }
     39 
     40 func (ctx *context) BindAttribLocation(p Program, a Attrib, name string) {
     41 	s, free := ctx.cString(name)
     42 	defer free()
     43 	ctx.enqueue(call{
     44 		args: fnargs{
     45 			fn: glfnBindAttribLocation,
     46 			a0: p.c(),
     47 			a1: a.c(),
     48 			a2: s,
     49 		},
     50 		blocking: true,
     51 	})
     52 }
     53 
     54 func (ctx *context) BindBuffer(target Enum, b Buffer) {
     55 	ctx.enqueue(call{
     56 		args: fnargs{
     57 			fn: glfnBindBuffer,
     58 			a0: target.c(),
     59 			a1: b.c(),
     60 		},
     61 	})
     62 }
     63 
     64 func (ctx *context) BindFramebuffer(target Enum, fb Framebuffer) {
     65 	ctx.enqueue(call{
     66 		args: fnargs{
     67 			fn: glfnBindFramebuffer,
     68 			a0: target.c(),
     69 			a1: fb.c(),
     70 		},
     71 	})
     72 }
     73 
     74 func (ctx *context) BindRenderbuffer(target Enum, rb Renderbuffer) {
     75 	ctx.enqueue(call{
     76 		args: fnargs{
     77 			fn: glfnBindRenderbuffer,
     78 			a0: target.c(),
     79 			a1: rb.c(),
     80 		},
     81 	})
     82 }
     83 
     84 func (ctx *context) BindTexture(target Enum, t Texture) {
     85 	ctx.enqueue(call{
     86 		args: fnargs{
     87 			fn: glfnBindTexture,
     88 			a0: target.c(),
     89 			a1: t.c(),
     90 		},
     91 	})
     92 }
     93 
     94 func (ctx *context) BindVertexArray(va VertexArray) {
     95 	ctx.enqueue(call{
     96 		args: fnargs{
     97 			fn: glfnBindVertexArray,
     98 			a0: va.c(),
     99 		},
    100 	})
    101 }
    102 
    103 func (ctx *context) BlendColor(red, green, blue, alpha float32) {
    104 	ctx.enqueue(call{
    105 		args: fnargs{
    106 			fn: glfnBlendColor,
    107 			a0: uintptr(math.Float32bits(red)),
    108 			a1: uintptr(math.Float32bits(green)),
    109 			a2: uintptr(math.Float32bits(blue)),
    110 			a3: uintptr(math.Float32bits(alpha)),
    111 		},
    112 	})
    113 }
    114 
    115 func (ctx *context) BlendEquation(mode Enum) {
    116 	ctx.enqueue(call{
    117 		args: fnargs{
    118 			fn: glfnBlendEquation,
    119 			a0: mode.c(),
    120 		},
    121 	})
    122 }
    123 
    124 func (ctx *context) BlendEquationSeparate(modeRGB, modeAlpha Enum) {
    125 	ctx.enqueue(call{
    126 		args: fnargs{
    127 			fn: glfnBlendEquationSeparate,
    128 			a0: modeRGB.c(),
    129 			a1: modeAlpha.c(),
    130 		},
    131 	})
    132 }
    133 
    134 func (ctx *context) BlendFunc(sfactor, dfactor Enum) {
    135 	ctx.enqueue(call{
    136 		args: fnargs{
    137 			fn: glfnBlendFunc,
    138 			a0: sfactor.c(),
    139 			a1: dfactor.c(),
    140 		},
    141 	})
    142 }
    143 
    144 func (ctx *context) BlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha Enum) {
    145 	ctx.enqueue(call{
    146 		args: fnargs{
    147 			fn: glfnBlendFuncSeparate,
    148 			a0: sfactorRGB.c(),
    149 			a1: dfactorRGB.c(),
    150 			a2: sfactorAlpha.c(),
    151 			a3: dfactorAlpha.c(),
    152 		},
    153 	})
    154 }
    155 
    156 func (ctx *context) BufferData(target Enum, src []byte, usage Enum) {
    157 	parg := unsafe.Pointer(nil)
    158 	if len(src) > 0 {
    159 		parg = unsafe.Pointer(&src[0])
    160 	}
    161 	ctx.enqueue(call{
    162 		args: fnargs{
    163 			fn: glfnBufferData,
    164 			a0: target.c(),
    165 			a1: uintptr(len(src)),
    166 			a2: usage.c(),
    167 		},
    168 		parg:     parg,
    169 		blocking: true,
    170 	})
    171 }
    172 
    173 func (ctx *context) BufferInit(target Enum, size int, usage Enum) {
    174 	ctx.enqueue(call{
    175 		args: fnargs{
    176 			fn: glfnBufferData,
    177 			a0: target.c(),
    178 			a1: uintptr(size),
    179 			a2: usage.c(),
    180 		},
    181 		parg: unsafe.Pointer(nil),
    182 	})
    183 }
    184 
    185 func (ctx *context) BufferSubData(target Enum, offset int, data []byte) {
    186 	ctx.enqueue(call{
    187 		args: fnargs{
    188 			fn: glfnBufferSubData,
    189 			a0: target.c(),
    190 			a1: uintptr(offset),
    191 			a2: uintptr(len(data)),
    192 		},
    193 		parg:     unsafe.Pointer(&data[0]),
    194 		blocking: true,
    195 	})
    196 }
    197 
    198 func (ctx *context) CheckFramebufferStatus(target Enum) Enum {
    199 	return Enum(ctx.enqueue(call{
    200 		args: fnargs{
    201 			fn: glfnCheckFramebufferStatus,
    202 			a0: target.c(),
    203 		},
    204 		blocking: true,
    205 	}))
    206 }
    207 
    208 func (ctx *context) Clear(mask Enum) {
    209 	ctx.enqueue(call{
    210 		args: fnargs{
    211 			fn: glfnClear,
    212 			a0: uintptr(mask),
    213 		},
    214 	})
    215 }
    216 
    217 func (ctx *context) ClearColor(red, green, blue, alpha float32) {
    218 	ctx.enqueue(call{
    219 		args: fnargs{
    220 			fn: glfnClearColor,
    221 			a0: uintptr(math.Float32bits(red)),
    222 			a1: uintptr(math.Float32bits(green)),
    223 			a2: uintptr(math.Float32bits(blue)),
    224 			a3: uintptr(math.Float32bits(alpha)),
    225 		},
    226 	})
    227 }
    228 
    229 func (ctx *context) ClearDepthf(d float32) {
    230 	ctx.enqueue(call{
    231 		args: fnargs{
    232 			fn: glfnClearDepthf,
    233 			a0: uintptr(math.Float32bits(d)),
    234 		},
    235 	})
    236 }
    237 
    238 func (ctx *context) ClearStencil(s int) {
    239 	ctx.enqueue(call{
    240 		args: fnargs{
    241 			fn: glfnClearStencil,
    242 			a0: uintptr(s),
    243 		},
    244 	})
    245 }
    246 
    247 func (ctx *context) ColorMask(red, green, blue, alpha bool) {
    248 	ctx.enqueue(call{
    249 		args: fnargs{
    250 			fn: glfnColorMask,
    251 			a0: glBoolean(red),
    252 			a1: glBoolean(green),
    253 			a2: glBoolean(blue),
    254 			a3: glBoolean(alpha),
    255 		},
    256 	})
    257 }
    258 
    259 func (ctx *context) CompileShader(s Shader) {
    260 	ctx.enqueue(call{
    261 		args: fnargs{
    262 			fn: glfnCompileShader,
    263 			a0: s.c(),
    264 		},
    265 	})
    266 }
    267 
    268 func (ctx *context) CompressedTexImage2D(target Enum, level int, internalformat Enum, width, height, border int, data []byte) {
    269 	ctx.enqueue(call{
    270 		args: fnargs{
    271 			fn: glfnCompressedTexImage2D,
    272 			a0: target.c(),
    273 			a1: uintptr(level),
    274 			a2: internalformat.c(),
    275 			a3: uintptr(width),
    276 			a4: uintptr(height),
    277 			a5: uintptr(border),
    278 			a6: uintptr(len(data)),
    279 		},
    280 		parg:     unsafe.Pointer(&data[0]),
    281 		blocking: true,
    282 	})
    283 }
    284 
    285 func (ctx *context) CompressedTexSubImage2D(target Enum, level, xoffset, yoffset, width, height int, format Enum, data []byte) {
    286 	ctx.enqueue(call{
    287 		args: fnargs{
    288 			fn: glfnCompressedTexSubImage2D,
    289 			a0: target.c(),
    290 			a1: uintptr(level),
    291 			a2: uintptr(xoffset),
    292 			a3: uintptr(yoffset),
    293 			a4: uintptr(width),
    294 			a5: uintptr(height),
    295 			a6: format.c(),
    296 			a7: uintptr(len(data)),
    297 		},
    298 		parg:     unsafe.Pointer(&data[0]),
    299 		blocking: true,
    300 	})
    301 }
    302 
    303 func (ctx *context) CopyTexImage2D(target Enum, level int, internalformat Enum, x, y, width, height, border int) {
    304 	ctx.enqueue(call{
    305 		args: fnargs{
    306 			fn: glfnCopyTexImage2D,
    307 			a0: target.c(),
    308 			a1: uintptr(level),
    309 			a2: internalformat.c(),
    310 			a3: uintptr(x),
    311 			a4: uintptr(y),
    312 			a5: uintptr(width),
    313 			a6: uintptr(height),
    314 			a7: uintptr(border),
    315 		},
    316 	})
    317 }
    318 
    319 func (ctx *context) CopyTexSubImage2D(target Enum, level, xoffset, yoffset, x, y, width, height int) {
    320 	ctx.enqueue(call{
    321 		args: fnargs{
    322 			fn: glfnCopyTexSubImage2D,
    323 			a0: target.c(),
    324 			a1: uintptr(level),
    325 			a2: uintptr(xoffset),
    326 			a3: uintptr(yoffset),
    327 			a4: uintptr(x),
    328 			a5: uintptr(y),
    329 			a6: uintptr(width),
    330 			a7: uintptr(height),
    331 		},
    332 	})
    333 }
    334 
    335 func (ctx *context) CreateBuffer() Buffer {
    336 	return Buffer{Value: uint32(ctx.enqueue(call{
    337 		args: fnargs{
    338 			fn: glfnGenBuffer,
    339 		},
    340 		blocking: true,
    341 	}))}
    342 }
    343 
    344 func (ctx *context) CreateFramebuffer() Framebuffer {
    345 	return Framebuffer{Value: uint32(ctx.enqueue(call{
    346 		args: fnargs{
    347 			fn: glfnGenFramebuffer,
    348 		},
    349 		blocking: true,
    350 	}))}
    351 }
    352 
    353 func (ctx *context) CreateProgram() Program {
    354 	return Program{
    355 		Init: true,
    356 		Value: uint32(ctx.enqueue(call{
    357 			args: fnargs{
    358 				fn: glfnCreateProgram,
    359 			},
    360 			blocking: true,
    361 		},
    362 		))}
    363 }
    364 
    365 func (ctx *context) CreateRenderbuffer() Renderbuffer {
    366 	return Renderbuffer{Value: uint32(ctx.enqueue(call{
    367 		args: fnargs{
    368 			fn: glfnGenRenderbuffer,
    369 		},
    370 		blocking: true,
    371 	}))}
    372 }
    373 
    374 func (ctx *context) CreateShader(ty Enum) Shader {
    375 	return Shader{Value: uint32(ctx.enqueue(call{
    376 		args: fnargs{
    377 			fn: glfnCreateShader,
    378 			a0: uintptr(ty),
    379 		},
    380 		blocking: true,
    381 	}))}
    382 }
    383 
    384 func (ctx *context) CreateTexture() Texture {
    385 	return Texture{Value: uint32(ctx.enqueue(call{
    386 		args: fnargs{
    387 			fn: glfnGenTexture,
    388 		},
    389 		blocking: true,
    390 	}))}
    391 }
    392 
    393 func (ctx *context) CreateVertexArray() VertexArray {
    394 	return VertexArray{Value: uint32(ctx.enqueue(call{
    395 		args: fnargs{
    396 			fn: glfnGenVertexArray,
    397 		},
    398 		blocking: true,
    399 	}))}
    400 }
    401 
    402 func (ctx *context) CullFace(mode Enum) {
    403 	ctx.enqueue(call{
    404 		args: fnargs{
    405 			fn: glfnCullFace,
    406 			a0: mode.c(),
    407 		},
    408 	})
    409 }
    410 
    411 func (ctx *context) DeleteBuffer(v Buffer) {
    412 	ctx.enqueue(call{
    413 		args: fnargs{
    414 			fn: glfnDeleteBuffer,
    415 			a0: v.c(),
    416 		},
    417 	})
    418 }
    419 
    420 func (ctx *context) DeleteFramebuffer(v Framebuffer) {
    421 	ctx.enqueue(call{
    422 		args: fnargs{
    423 			fn: glfnDeleteFramebuffer,
    424 			a0: v.c(),
    425 		},
    426 	})
    427 }
    428 
    429 func (ctx *context) DeleteProgram(p Program) {
    430 	ctx.enqueue(call{
    431 		args: fnargs{
    432 			fn: glfnDeleteProgram,
    433 			a0: p.c(),
    434 		},
    435 	})
    436 }
    437 
    438 func (ctx *context) DeleteRenderbuffer(v Renderbuffer) {
    439 	ctx.enqueue(call{
    440 		args: fnargs{
    441 			fn: glfnDeleteRenderbuffer,
    442 			a0: v.c(),
    443 		},
    444 	})
    445 }
    446 
    447 func (ctx *context) DeleteShader(s Shader) {
    448 	ctx.enqueue(call{
    449 		args: fnargs{
    450 			fn: glfnDeleteShader,
    451 			a0: s.c(),
    452 		},
    453 	})
    454 }
    455 
    456 func (ctx *context) DeleteTexture(v Texture) {
    457 	ctx.enqueue(call{
    458 		args: fnargs{
    459 			fn: glfnDeleteTexture,
    460 			a0: v.c(),
    461 		},
    462 	})
    463 }
    464 
    465 func (ctx *context) DeleteVertexArray(v VertexArray) {
    466 	ctx.enqueue(call{
    467 		args: fnargs{
    468 			fn: glfnDeleteVertexArray,
    469 			a0: v.c(),
    470 		},
    471 	})
    472 }
    473 
    474 func (ctx *context) DepthFunc(fn Enum) {
    475 	ctx.enqueue(call{
    476 		args: fnargs{
    477 			fn: glfnDepthFunc,
    478 			a0: fn.c(),
    479 		},
    480 	})
    481 }
    482 
    483 func (ctx *context) DepthMask(flag bool) {
    484 	ctx.enqueue(call{
    485 		args: fnargs{
    486 			fn: glfnDepthMask,
    487 			a0: glBoolean(flag),
    488 		},
    489 	})
    490 }
    491 
    492 func (ctx *context) DepthRangef(n, f float32) {
    493 	ctx.enqueue(call{
    494 		args: fnargs{
    495 			fn: glfnDepthRangef,
    496 			a0: uintptr(math.Float32bits(n)),
    497 			a1: uintptr(math.Float32bits(f)),
    498 		},
    499 	})
    500 }
    501 
    502 func (ctx *context) DetachShader(p Program, s Shader) {
    503 	ctx.enqueue(call{
    504 		args: fnargs{
    505 			fn: glfnDetachShader,
    506 			a0: p.c(),
    507 			a1: s.c(),
    508 		},
    509 	})
    510 }
    511 
    512 func (ctx *context) Disable(cap Enum) {
    513 	ctx.enqueue(call{
    514 		args: fnargs{
    515 			fn: glfnDisable,
    516 			a0: cap.c(),
    517 		},
    518 	})
    519 }
    520 
    521 func (ctx *context) DisableVertexAttribArray(a Attrib) {
    522 	ctx.enqueue(call{
    523 		args: fnargs{
    524 			fn: glfnDisableVertexAttribArray,
    525 			a0: a.c(),
    526 		},
    527 	})
    528 }
    529 
    530 func (ctx *context) DrawArrays(mode Enum, first, count int) {
    531 	ctx.enqueue(call{
    532 		args: fnargs{
    533 			fn: glfnDrawArrays,
    534 			a0: mode.c(),
    535 			a1: uintptr(first),
    536 			a2: uintptr(count),
    537 		},
    538 	})
    539 }
    540 
    541 func (ctx *context) DrawElements(mode Enum, count int, ty Enum, offset int) {
    542 	ctx.enqueue(call{
    543 		args: fnargs{
    544 			fn: glfnDrawElements,
    545 			a0: mode.c(),
    546 			a1: uintptr(count),
    547 			a2: ty.c(),
    548 			a3: uintptr(offset),
    549 		},
    550 	})
    551 }
    552 
    553 func (ctx *context) Enable(cap Enum) {
    554 	ctx.enqueue(call{
    555 		args: fnargs{
    556 			fn: glfnEnable,
    557 			a0: cap.c(),
    558 		},
    559 	})
    560 }
    561 
    562 func (ctx *context) EnableVertexAttribArray(a Attrib) {
    563 	ctx.enqueue(call{
    564 		args: fnargs{
    565 			fn: glfnEnableVertexAttribArray,
    566 			a0: a.c(),
    567 		},
    568 	})
    569 }
    570 
    571 func (ctx *context) Finish() {
    572 	ctx.enqueue(call{
    573 		args: fnargs{
    574 			fn: glfnFinish,
    575 		},
    576 		blocking: true,
    577 	})
    578 }
    579 
    580 func (ctx *context) Flush() {
    581 	ctx.enqueue(call{
    582 		args: fnargs{
    583 			fn: glfnFlush,
    584 		},
    585 		blocking: true,
    586 	})
    587 }
    588 
    589 func (ctx *context) FramebufferRenderbuffer(target, attachment, rbTarget Enum, rb Renderbuffer) {
    590 	ctx.enqueue(call{
    591 		args: fnargs{
    592 			fn: glfnFramebufferRenderbuffer,
    593 			a0: target.c(),
    594 			a1: attachment.c(),
    595 			a2: rbTarget.c(),
    596 			a3: rb.c(),
    597 		},
    598 	})
    599 }
    600 
    601 func (ctx *context) FramebufferTexture2D(target, attachment, texTarget Enum, t Texture, level int) {
    602 	ctx.enqueue(call{
    603 		args: fnargs{
    604 			fn: glfnFramebufferTexture2D,
    605 			a0: target.c(),
    606 			a1: attachment.c(),
    607 			a2: texTarget.c(),
    608 			a3: t.c(),
    609 			a4: uintptr(level),
    610 		},
    611 	})
    612 }
    613 
    614 func (ctx *context) FrontFace(mode Enum) {
    615 	ctx.enqueue(call{
    616 		args: fnargs{
    617 			fn: glfnFrontFace,
    618 			a0: mode.c(),
    619 		},
    620 	})
    621 }
    622 
    623 func (ctx *context) GenerateMipmap(target Enum) {
    624 	ctx.enqueue(call{
    625 		args: fnargs{
    626 			fn: glfnGenerateMipmap,
    627 			a0: target.c(),
    628 		},
    629 	})
    630 }
    631 
    632 func (ctx *context) GetActiveAttrib(p Program, index uint32) (name string, size int, ty Enum) {
    633 	bufSize := ctx.GetProgrami(p, ACTIVE_ATTRIBUTE_MAX_LENGTH)
    634 	buf := make([]byte, bufSize)
    635 	var cType int
    636 
    637 	cSize := ctx.enqueue(call{
    638 		args: fnargs{
    639 			fn: glfnGetActiveAttrib,
    640 			a0: p.c(),
    641 			a1: uintptr(index),
    642 			a2: uintptr(bufSize),
    643 			a3: uintptr(unsafe.Pointer(&cType)), // TODO(crawshaw): not safe for a moving collector
    644 		},
    645 		parg:     unsafe.Pointer(&buf[0]),
    646 		blocking: true,
    647 	})
    648 
    649 	return goString(buf), int(cSize), Enum(cType)
    650 }
    651 
    652 func (ctx *context) GetActiveUniform(p Program, index uint32) (name string, size int, ty Enum) {
    653 	bufSize := ctx.GetProgrami(p, ACTIVE_UNIFORM_MAX_LENGTH)
    654 	buf := make([]byte, bufSize+8) // extra space for cType
    655 	var cType int
    656 
    657 	cSize := ctx.enqueue(call{
    658 		args: fnargs{
    659 			fn: glfnGetActiveUniform,
    660 			a0: p.c(),
    661 			a1: uintptr(index),
    662 			a2: uintptr(bufSize),
    663 			a3: uintptr(unsafe.Pointer(&cType)), // TODO(crawshaw): not safe for a moving collector
    664 		},
    665 		parg:     unsafe.Pointer(&buf[0]),
    666 		blocking: true,
    667 	})
    668 
    669 	return goString(buf), int(cSize), Enum(cType)
    670 }
    671 
    672 func (ctx *context) GetAttachedShaders(p Program) []Shader {
    673 	shadersLen := ctx.GetProgrami(p, ATTACHED_SHADERS)
    674 	if shadersLen == 0 {
    675 		return nil
    676 	}
    677 	buf := make([]uint32, shadersLen)
    678 
    679 	n := int(ctx.enqueue(call{
    680 		args: fnargs{
    681 			fn: glfnGetAttachedShaders,
    682 			a0: p.c(),
    683 			a1: uintptr(shadersLen),
    684 		},
    685 		parg:     unsafe.Pointer(&buf[0]),
    686 		blocking: true,
    687 	}))
    688 
    689 	buf = buf[:int(n)]
    690 	shaders := make([]Shader, len(buf))
    691 	for i, s := range buf {
    692 		shaders[i] = Shader{Value: uint32(s)}
    693 	}
    694 	return shaders
    695 }
    696 
    697 func (ctx *context) GetAttribLocation(p Program, name string) Attrib {
    698 	s, free := ctx.cString(name)
    699 	defer free()
    700 	return Attrib{Value: uint(ctx.enqueue(call{
    701 		args: fnargs{
    702 			fn: glfnGetAttribLocation,
    703 			a0: p.c(),
    704 			a1: s,
    705 		},
    706 		blocking: true,
    707 	}))}
    708 }
    709 
    710 func (ctx *context) GetBooleanv(dst []bool, pname Enum) {
    711 	buf := make([]int32, len(dst))
    712 
    713 	ctx.enqueue(call{
    714 		args: fnargs{
    715 			fn: glfnGetBooleanv,
    716 			a0: pname.c(),
    717 		},
    718 		parg:     unsafe.Pointer(&buf[0]),
    719 		blocking: true,
    720 	})
    721 
    722 	for i, v := range buf {
    723 		dst[i] = v != 0
    724 	}
    725 }
    726 
    727 func (ctx *context) GetFloatv(dst []float32, pname Enum) {
    728 	ctx.enqueue(call{
    729 		args: fnargs{
    730 			fn: glfnGetFloatv,
    731 			a0: pname.c(),
    732 		},
    733 		parg:     unsafe.Pointer(&dst[0]),
    734 		blocking: true,
    735 	})
    736 }
    737 
    738 func (ctx *context) GetIntegerv(dst []int32, pname Enum) {
    739 	ctx.enqueue(call{
    740 		args: fnargs{
    741 			fn: glfnGetIntegerv,
    742 			a0: pname.c(),
    743 		},
    744 		parg:     unsafe.Pointer(&dst[0]),
    745 		blocking: true,
    746 	})
    747 }
    748 
    749 func (ctx *context) GetInteger(pname Enum) int {
    750 	var v [1]int32
    751 	ctx.GetIntegerv(v[:], pname)
    752 	return int(v[0])
    753 }
    754 
    755 func (ctx *context) GetBufferParameteri(target, value Enum) int {
    756 	return int(ctx.enqueue(call{
    757 		args: fnargs{
    758 			fn: glfnGetBufferParameteri,
    759 			a0: target.c(),
    760 			a1: value.c(),
    761 		},
    762 		blocking: true,
    763 	}))
    764 }
    765 
    766 func (ctx *context) GetError() Enum {
    767 	return Enum(ctx.enqueue(call{
    768 		args: fnargs{
    769 			fn: glfnGetError,
    770 		},
    771 		blocking: true,
    772 	}))
    773 }
    774 
    775 func (ctx *context) GetFramebufferAttachmentParameteri(target, attachment, pname Enum) int {
    776 	return int(ctx.enqueue(call{
    777 		args: fnargs{
    778 			fn: glfnGetFramebufferAttachmentParameteriv,
    779 			a0: target.c(),
    780 			a1: attachment.c(),
    781 			a2: pname.c(),
    782 		},
    783 		blocking: true,
    784 	}))
    785 }
    786 
    787 func (ctx *context) GetProgrami(p Program, pname Enum) int {
    788 	return int(ctx.enqueue(call{
    789 		args: fnargs{
    790 			fn: glfnGetProgramiv,
    791 			a0: p.c(),
    792 			a1: pname.c(),
    793 		},
    794 		blocking: true,
    795 	}))
    796 }
    797 
    798 func (ctx *context) GetProgramInfoLog(p Program) string {
    799 	infoLen := ctx.GetProgrami(p, INFO_LOG_LENGTH)
    800 	if infoLen == 0 {
    801 		return ""
    802 	}
    803 	buf := make([]byte, infoLen)
    804 
    805 	ctx.enqueue(call{
    806 		args: fnargs{
    807 			fn: glfnGetProgramInfoLog,
    808 			a0: p.c(),
    809 			a1: uintptr(infoLen),
    810 		},
    811 		parg:     unsafe.Pointer(&buf[0]),
    812 		blocking: true,
    813 	})
    814 
    815 	return goString(buf)
    816 }
    817 
    818 func (ctx *context) GetRenderbufferParameteri(target, pname Enum) int {
    819 	return int(ctx.enqueue(call{
    820 		args: fnargs{
    821 			fn: glfnGetRenderbufferParameteriv,
    822 			a0: target.c(),
    823 			a1: pname.c(),
    824 		},
    825 		blocking: true,
    826 	}))
    827 }
    828 
    829 func (ctx *context) GetShaderi(s Shader, pname Enum) int {
    830 	return int(ctx.enqueue(call{
    831 		args: fnargs{
    832 			fn: glfnGetShaderiv,
    833 			a0: s.c(),
    834 			a1: pname.c(),
    835 		},
    836 		blocking: true,
    837 	}))
    838 }
    839 
    840 func (ctx *context) GetShaderInfoLog(s Shader) string {
    841 	infoLen := ctx.GetShaderi(s, INFO_LOG_LENGTH)
    842 	if infoLen == 0 {
    843 		return ""
    844 	}
    845 	buf := make([]byte, infoLen)
    846 
    847 	ctx.enqueue(call{
    848 		args: fnargs{
    849 			fn: glfnGetShaderInfoLog,
    850 			a0: s.c(),
    851 			a1: uintptr(infoLen),
    852 		},
    853 		parg:     unsafe.Pointer(&buf[0]),
    854 		blocking: true,
    855 	})
    856 
    857 	return goString(buf)
    858 }
    859 
    860 func (ctx *context) GetShaderPrecisionFormat(shadertype, precisiontype Enum) (rangeLow, rangeHigh, precision int) {
    861 	var rangeAndPrec [3]int32
    862 
    863 	ctx.enqueue(call{
    864 		args: fnargs{
    865 			fn: glfnGetShaderPrecisionFormat,
    866 			a0: shadertype.c(),
    867 			a1: precisiontype.c(),
    868 		},
    869 		parg:     unsafe.Pointer(&rangeAndPrec[0]),
    870 		blocking: true,
    871 	})
    872 
    873 	return int(rangeAndPrec[0]), int(rangeAndPrec[1]), int(rangeAndPrec[2])
    874 }
    875 
    876 func (ctx *context) GetShaderSource(s Shader) string {
    877 	sourceLen := ctx.GetShaderi(s, SHADER_SOURCE_LENGTH)
    878 	if sourceLen == 0 {
    879 		return ""
    880 	}
    881 	buf := make([]byte, sourceLen)
    882 
    883 	ctx.enqueue(call{
    884 		args: fnargs{
    885 			fn: glfnGetShaderSource,
    886 			a0: s.c(),
    887 			a1: uintptr(sourceLen),
    888 		},
    889 		parg:     unsafe.Pointer(&buf[0]),
    890 		blocking: true,
    891 	})
    892 
    893 	return goString(buf)
    894 }
    895 
    896 func (ctx *context) GetString(pname Enum) string {
    897 	ret := ctx.enqueue(call{
    898 		args: fnargs{
    899 			fn: glfnGetString,
    900 			a0: pname.c(),
    901 		},
    902 		blocking: true,
    903 	})
    904 	retp := unsafe.Pointer(ret)
    905 	buf := (*[1 << 24]byte)(retp)[:]
    906 	return goString(buf)
    907 }
    908 
    909 func (ctx *context) GetTexParameterfv(dst []float32, target, pname Enum) {
    910 	ctx.enqueue(call{
    911 		args: fnargs{
    912 			fn: glfnGetTexParameterfv,
    913 			a0: target.c(),
    914 			a1: pname.c(),
    915 		},
    916 		parg:     unsafe.Pointer(&dst[0]),
    917 		blocking: true,
    918 	})
    919 }
    920 
    921 func (ctx *context) GetTexParameteriv(dst []int32, target, pname Enum) {
    922 	ctx.enqueue(call{
    923 		args: fnargs{
    924 			fn: glfnGetTexParameteriv,
    925 			a0: target.c(),
    926 			a1: pname.c(),
    927 		},
    928 		blocking: true,
    929 	})
    930 }
    931 
    932 func (ctx *context) GetUniformfv(dst []float32, src Uniform, p Program) {
    933 	ctx.enqueue(call{
    934 		args: fnargs{
    935 			fn: glfnGetUniformfv,
    936 			a0: p.c(),
    937 			a1: src.c(),
    938 		},
    939 		parg:     unsafe.Pointer(&dst[0]),
    940 		blocking: true,
    941 	})
    942 }
    943 
    944 func (ctx *context) GetUniformiv(dst []int32, src Uniform, p Program) {
    945 	ctx.enqueue(call{
    946 		args: fnargs{
    947 			fn: glfnGetUniformiv,
    948 			a0: p.c(),
    949 			a1: src.c(),
    950 		},
    951 		parg:     unsafe.Pointer(&dst[0]),
    952 		blocking: true,
    953 	})
    954 }
    955 
    956 func (ctx *context) GetUniformLocation(p Program, name string) Uniform {
    957 	s, free := ctx.cString(name)
    958 	defer free()
    959 	return Uniform{Value: int32(ctx.enqueue(call{
    960 		args: fnargs{
    961 			fn: glfnGetUniformLocation,
    962 			a0: p.c(),
    963 			a1: s,
    964 		},
    965 		blocking: true,
    966 	}))}
    967 }
    968 
    969 func (ctx *context) GetVertexAttribf(src Attrib, pname Enum) float32 {
    970 	var params [1]float32
    971 	ctx.GetVertexAttribfv(params[:], src, pname)
    972 	return params[0]
    973 }
    974 
    975 func (ctx *context) GetVertexAttribfv(dst []float32, src Attrib, pname Enum) {
    976 	ctx.enqueue(call{
    977 		args: fnargs{
    978 			fn: glfnGetVertexAttribfv,
    979 			a0: src.c(),
    980 			a1: pname.c(),
    981 		},
    982 		parg:     unsafe.Pointer(&dst[0]),
    983 		blocking: true,
    984 	})
    985 }
    986 
    987 func (ctx *context) GetVertexAttribi(src Attrib, pname Enum) int32 {
    988 	var params [1]int32
    989 	ctx.GetVertexAttribiv(params[:], src, pname)
    990 	return params[0]
    991 }
    992 
    993 func (ctx *context) GetVertexAttribiv(dst []int32, src Attrib, pname Enum) {
    994 	ctx.enqueue(call{
    995 		args: fnargs{
    996 			fn: glfnGetVertexAttribiv,
    997 			a0: src.c(),
    998 			a1: pname.c(),
    999 		},
   1000 		parg:     unsafe.Pointer(&dst[0]),
   1001 		blocking: true,
   1002 	})
   1003 }
   1004 
   1005 func (ctx *context) Hint(target, mode Enum) {
   1006 	ctx.enqueue(call{
   1007 		args: fnargs{
   1008 			fn: glfnHint,
   1009 			a0: target.c(),
   1010 			a1: mode.c(),
   1011 		},
   1012 	})
   1013 }
   1014 
   1015 func (ctx *context) IsBuffer(b Buffer) bool {
   1016 	return 0 != ctx.enqueue(call{
   1017 		args: fnargs{
   1018 			fn: glfnIsBuffer,
   1019 			a0: b.c(),
   1020 		},
   1021 		blocking: true,
   1022 	})
   1023 }
   1024 
   1025 func (ctx *context) IsEnabled(cap Enum) bool {
   1026 	return 0 != ctx.enqueue(call{
   1027 		args: fnargs{
   1028 			fn: glfnIsEnabled,
   1029 			a0: cap.c(),
   1030 		},
   1031 		blocking: true,
   1032 	})
   1033 }
   1034 
   1035 func (ctx *context) IsFramebuffer(fb Framebuffer) bool {
   1036 	return 0 != ctx.enqueue(call{
   1037 		args: fnargs{
   1038 			fn: glfnIsFramebuffer,
   1039 			a0: fb.c(),
   1040 		},
   1041 		blocking: true,
   1042 	})
   1043 }
   1044 
   1045 func (ctx *context) IsProgram(p Program) bool {
   1046 	return 0 != ctx.enqueue(call{
   1047 		args: fnargs{
   1048 			fn: glfnIsProgram,
   1049 			a0: p.c(),
   1050 		},
   1051 		blocking: true,
   1052 	})
   1053 }
   1054 
   1055 func (ctx *context) IsRenderbuffer(rb Renderbuffer) bool {
   1056 	return 0 != ctx.enqueue(call{
   1057 		args: fnargs{
   1058 			fn: glfnIsRenderbuffer,
   1059 			a0: rb.c(),
   1060 		},
   1061 		blocking: true,
   1062 	})
   1063 }
   1064 
   1065 func (ctx *context) IsShader(s Shader) bool {
   1066 	return 0 != ctx.enqueue(call{
   1067 		args: fnargs{
   1068 			fn: glfnIsShader,
   1069 			a0: s.c(),
   1070 		},
   1071 		blocking: true,
   1072 	})
   1073 }
   1074 
   1075 func (ctx *context) IsTexture(t Texture) bool {
   1076 	return 0 != ctx.enqueue(call{
   1077 		args: fnargs{
   1078 			fn: glfnIsTexture,
   1079 			a0: t.c(),
   1080 		},
   1081 		blocking: true,
   1082 	})
   1083 }
   1084 
   1085 func (ctx *context) LineWidth(width float32) {
   1086 	ctx.enqueue(call{
   1087 		args: fnargs{
   1088 			fn: glfnLineWidth,
   1089 			a0: uintptr(math.Float32bits(width)),
   1090 		},
   1091 	})
   1092 }
   1093 
   1094 func (ctx *context) LinkProgram(p Program) {
   1095 	ctx.enqueue(call{
   1096 		args: fnargs{
   1097 			fn: glfnLinkProgram,
   1098 			a0: p.c(),
   1099 		},
   1100 	})
   1101 }
   1102 
   1103 func (ctx *context) PixelStorei(pname Enum, param int32) {
   1104 	ctx.enqueue(call{
   1105 		args: fnargs{
   1106 			fn: glfnPixelStorei,
   1107 			a0: pname.c(),
   1108 			a1: uintptr(param),
   1109 		},
   1110 	})
   1111 }
   1112 
   1113 func (ctx *context) PolygonOffset(factor, units float32) {
   1114 	ctx.enqueue(call{
   1115 		args: fnargs{
   1116 			fn: glfnPolygonOffset,
   1117 			a0: uintptr(math.Float32bits(factor)),
   1118 			a1: uintptr(math.Float32bits(units)),
   1119 		},
   1120 	})
   1121 }
   1122 
   1123 func (ctx *context) ReadPixels(dst []byte, x, y, width, height int, format, ty Enum) {
   1124 	ctx.enqueue(call{
   1125 		args: fnargs{
   1126 			fn: glfnReadPixels,
   1127 			// TODO(crawshaw): support PIXEL_PACK_BUFFER in GLES3, uses offset.
   1128 			a0: uintptr(x),
   1129 			a1: uintptr(y),
   1130 			a2: uintptr(width),
   1131 			a3: uintptr(height),
   1132 			a4: format.c(),
   1133 			a5: ty.c(),
   1134 		},
   1135 		parg:     unsafe.Pointer(&dst[0]),
   1136 		blocking: true,
   1137 	})
   1138 }
   1139 
   1140 func (ctx *context) ReleaseShaderCompiler() {
   1141 	ctx.enqueue(call{
   1142 		args: fnargs{
   1143 			fn: glfnReleaseShaderCompiler,
   1144 		},
   1145 	})
   1146 }
   1147 
   1148 func (ctx *context) RenderbufferStorage(target, internalFormat Enum, width, height int) {
   1149 	ctx.enqueue(call{
   1150 		args: fnargs{
   1151 			fn: glfnRenderbufferStorage,
   1152 			a0: target.c(),
   1153 			a1: internalFormat.c(),
   1154 			a2: uintptr(width),
   1155 			a3: uintptr(height),
   1156 		},
   1157 	})
   1158 }
   1159 
   1160 func (ctx *context) SampleCoverage(value float32, invert bool) {
   1161 	ctx.enqueue(call{
   1162 		args: fnargs{
   1163 			fn: glfnSampleCoverage,
   1164 			a0: uintptr(math.Float32bits(value)),
   1165 			a1: glBoolean(invert),
   1166 		},
   1167 	})
   1168 }
   1169 
   1170 func (ctx *context) Scissor(x, y, width, height int32) {
   1171 	ctx.enqueue(call{
   1172 		args: fnargs{
   1173 			fn: glfnScissor,
   1174 			a0: uintptr(x),
   1175 			a1: uintptr(y),
   1176 			a2: uintptr(width),
   1177 			a3: uintptr(height),
   1178 		},
   1179 	})
   1180 }
   1181 
   1182 func (ctx *context) ShaderSource(s Shader, src string) {
   1183 	strp, free := ctx.cStringPtr(src)
   1184 	defer free()
   1185 	ctx.enqueue(call{
   1186 		args: fnargs{
   1187 			fn: glfnShaderSource,
   1188 			a0: s.c(),
   1189 			a1: 1,
   1190 			a2: strp,
   1191 		},
   1192 		blocking: true,
   1193 	})
   1194 }
   1195 
   1196 func (ctx *context) StencilFunc(fn Enum, ref int, mask uint32) {
   1197 	ctx.enqueue(call{
   1198 		args: fnargs{
   1199 			fn: glfnStencilFunc,
   1200 			a0: fn.c(),
   1201 			a1: uintptr(ref),
   1202 			a2: uintptr(mask),
   1203 		},
   1204 	})
   1205 }
   1206 
   1207 func (ctx *context) StencilFuncSeparate(face, fn Enum, ref int, mask uint32) {
   1208 	ctx.enqueue(call{
   1209 		args: fnargs{
   1210 			fn: glfnStencilFuncSeparate,
   1211 			a0: face.c(),
   1212 			a1: fn.c(),
   1213 			a2: uintptr(ref),
   1214 			a3: uintptr(mask),
   1215 		},
   1216 	})
   1217 }
   1218 
   1219 func (ctx *context) StencilMask(mask uint32) {
   1220 	ctx.enqueue(call{
   1221 		args: fnargs{
   1222 			fn: glfnStencilMask,
   1223 			a0: uintptr(mask),
   1224 		},
   1225 	})
   1226 }
   1227 
   1228 func (ctx *context) StencilMaskSeparate(face Enum, mask uint32) {
   1229 	ctx.enqueue(call{
   1230 		args: fnargs{
   1231 			fn: glfnStencilMaskSeparate,
   1232 			a0: face.c(),
   1233 			a1: uintptr(mask),
   1234 		},
   1235 	})
   1236 }
   1237 
   1238 func (ctx *context) StencilOp(fail, zfail, zpass Enum) {
   1239 	ctx.enqueue(call{
   1240 		args: fnargs{
   1241 			fn: glfnStencilOp,
   1242 			a0: fail.c(),
   1243 			a1: zfail.c(),
   1244 			a2: zpass.c(),
   1245 		},
   1246 	})
   1247 }
   1248 
   1249 func (ctx *context) StencilOpSeparate(face, sfail, dpfail, dppass Enum) {
   1250 	ctx.enqueue(call{
   1251 		args: fnargs{
   1252 			fn: glfnStencilOpSeparate,
   1253 			a0: face.c(),
   1254 			a1: sfail.c(),
   1255 			a2: dpfail.c(),
   1256 			a3: dppass.c(),
   1257 		},
   1258 	})
   1259 }
   1260 
   1261 func (ctx *context) TexImage2D(target Enum, level int, internalFormat int, width, height int, format Enum, ty Enum, data []byte) {
   1262 	// It is common to pass TexImage2D a nil data, indicating that a
   1263 	// bound GL buffer is being used as the source. In that case, it
   1264 	// is not necessary to block.
   1265 	parg := unsafe.Pointer(nil)
   1266 	if len(data) > 0 {
   1267 		parg = unsafe.Pointer(&data[0])
   1268 	}
   1269 
   1270 	ctx.enqueue(call{
   1271 		args: fnargs{
   1272 			fn: glfnTexImage2D,
   1273 			// TODO(crawshaw): GLES3 offset for PIXEL_UNPACK_BUFFER and PIXEL_PACK_BUFFER.
   1274 			a0: target.c(),
   1275 			a1: uintptr(level),
   1276 			a2: uintptr(internalFormat),
   1277 			a3: uintptr(width),
   1278 			a4: uintptr(height),
   1279 			a5: format.c(),
   1280 			a6: ty.c(),
   1281 		},
   1282 		parg:     parg,
   1283 		blocking: parg != nil,
   1284 	})
   1285 }
   1286 
   1287 func (ctx *context) TexSubImage2D(target Enum, level int, x, y, width, height int, format, ty Enum, data []byte) {
   1288 	// It is common to pass TexSubImage2D a nil data, indicating that a
   1289 	// bound GL buffer is being used as the source. In that case, it
   1290 	// is not necessary to block.
   1291 	parg := unsafe.Pointer(nil)
   1292 	if len(data) > 0 {
   1293 		parg = unsafe.Pointer(&data[0])
   1294 	}
   1295 
   1296 	ctx.enqueue(call{
   1297 		args: fnargs{
   1298 			fn: glfnTexSubImage2D,
   1299 			// TODO(crawshaw): GLES3 offset for PIXEL_UNPACK_BUFFER and PIXEL_PACK_BUFFER.
   1300 			a0: target.c(),
   1301 			a1: uintptr(level),
   1302 			a2: uintptr(x),
   1303 			a3: uintptr(y),
   1304 			a4: uintptr(width),
   1305 			a5: uintptr(height),
   1306 			a6: format.c(),
   1307 			a7: ty.c(),
   1308 		},
   1309 		parg:     parg,
   1310 		blocking: parg != nil,
   1311 	})
   1312 }
   1313 
   1314 func (ctx *context) TexParameterf(target, pname Enum, param float32) {
   1315 	ctx.enqueue(call{
   1316 		args: fnargs{
   1317 			fn: glfnTexParameterf,
   1318 			a0: target.c(),
   1319 			a1: pname.c(),
   1320 			a2: uintptr(math.Float32bits(param)),
   1321 		},
   1322 	})
   1323 }
   1324 
   1325 func (ctx *context) TexParameterfv(target, pname Enum, params []float32) {
   1326 	ctx.enqueue(call{
   1327 		args: fnargs{
   1328 			fn: glfnTexParameterfv,
   1329 			a0: target.c(),
   1330 			a1: pname.c(),
   1331 		},
   1332 		parg:     unsafe.Pointer(&params[0]),
   1333 		blocking: true,
   1334 	})
   1335 }
   1336 
   1337 func (ctx *context) TexParameteri(target, pname Enum, param int) {
   1338 	ctx.enqueue(call{
   1339 		args: fnargs{
   1340 			fn: glfnTexParameteri,
   1341 			a0: target.c(),
   1342 			a1: pname.c(),
   1343 			a2: uintptr(param),
   1344 		},
   1345 	})
   1346 }
   1347 
   1348 func (ctx *context) TexParameteriv(target, pname Enum, params []int32) {
   1349 	ctx.enqueue(call{
   1350 		args: fnargs{
   1351 			fn: glfnTexParameteriv,
   1352 			a0: target.c(),
   1353 			a1: pname.c(),
   1354 		},
   1355 		parg:     unsafe.Pointer(&params[0]),
   1356 		blocking: true,
   1357 	})
   1358 }
   1359 
   1360 func (ctx *context) Uniform1f(dst Uniform, v float32) {
   1361 	ctx.enqueue(call{
   1362 		args: fnargs{
   1363 			fn: glfnUniform1f,
   1364 			a0: dst.c(),
   1365 			a1: uintptr(math.Float32bits(v)),
   1366 		},
   1367 	})
   1368 }
   1369 
   1370 func (ctx *context) Uniform1fv(dst Uniform, src []float32) {
   1371 	ctx.enqueue(call{
   1372 		args: fnargs{
   1373 			fn: glfnUniform1fv,
   1374 			a0: dst.c(),
   1375 			a1: uintptr(len(src)),
   1376 		},
   1377 		parg:     unsafe.Pointer(&src[0]),
   1378 		blocking: true,
   1379 	})
   1380 }
   1381 
   1382 func (ctx *context) Uniform1i(dst Uniform, v int) {
   1383 	ctx.enqueue(call{
   1384 		args: fnargs{
   1385 			fn: glfnUniform1i,
   1386 			a0: dst.c(),
   1387 			a1: uintptr(v),
   1388 		},
   1389 	})
   1390 }
   1391 
   1392 func (ctx *context) Uniform1iv(dst Uniform, src []int32) {
   1393 	ctx.enqueue(call{
   1394 		args: fnargs{
   1395 			fn: glfnUniform1iv,
   1396 			a0: dst.c(),
   1397 			a1: uintptr(len(src)),
   1398 		},
   1399 		parg:     unsafe.Pointer(&src[0]),
   1400 		blocking: true,
   1401 	})
   1402 }
   1403 
   1404 func (ctx *context) Uniform2f(dst Uniform, v0, v1 float32) {
   1405 	ctx.enqueue(call{
   1406 		args: fnargs{
   1407 			fn: glfnUniform2f,
   1408 			a0: dst.c(),
   1409 			a1: uintptr(math.Float32bits(v0)),
   1410 			a2: uintptr(math.Float32bits(v1)),
   1411 		},
   1412 	})
   1413 }
   1414 
   1415 func (ctx *context) Uniform2fv(dst Uniform, src []float32) {
   1416 	ctx.enqueue(call{
   1417 		args: fnargs{
   1418 			fn: glfnUniform2fv,
   1419 			a0: dst.c(),
   1420 			a1: uintptr(len(src) / 2),
   1421 		},
   1422 		parg:     unsafe.Pointer(&src[0]),
   1423 		blocking: true,
   1424 	})
   1425 }
   1426 
   1427 func (ctx *context) Uniform2i(dst Uniform, v0, v1 int) {
   1428 	ctx.enqueue(call{
   1429 		args: fnargs{
   1430 			fn: glfnUniform2i,
   1431 			a0: dst.c(),
   1432 			a1: uintptr(v0),
   1433 			a2: uintptr(v1),
   1434 		},
   1435 	})
   1436 }
   1437 
   1438 func (ctx *context) Uniform2iv(dst Uniform, src []int32) {
   1439 	ctx.enqueue(call{
   1440 		args: fnargs{
   1441 			fn: glfnUniform2iv,
   1442 			a0: dst.c(),
   1443 			a1: uintptr(len(src) / 2),
   1444 		},
   1445 		parg:     unsafe.Pointer(&src[0]),
   1446 		blocking: true,
   1447 	})
   1448 }
   1449 
   1450 func (ctx *context) Uniform3f(dst Uniform, v0, v1, v2 float32) {
   1451 	ctx.enqueue(call{
   1452 		args: fnargs{
   1453 			fn: glfnUniform3f,
   1454 			a0: dst.c(),
   1455 			a1: uintptr(math.Float32bits(v0)),
   1456 			a2: uintptr(math.Float32bits(v1)),
   1457 			a3: uintptr(math.Float32bits(v2)),
   1458 		},
   1459 	})
   1460 }
   1461 
   1462 func (ctx *context) Uniform3fv(dst Uniform, src []float32) {
   1463 	ctx.enqueue(call{
   1464 		args: fnargs{
   1465 			fn: glfnUniform3fv,
   1466 			a0: dst.c(),
   1467 			a1: uintptr(len(src) / 3),
   1468 		},
   1469 		parg:     unsafe.Pointer(&src[0]),
   1470 		blocking: true,
   1471 	})
   1472 }
   1473 
   1474 func (ctx *context) Uniform3i(dst Uniform, v0, v1, v2 int32) {
   1475 	ctx.enqueue(call{
   1476 		args: fnargs{
   1477 			fn: glfnUniform3i,
   1478 			a0: dst.c(),
   1479 			a1: uintptr(v0),
   1480 			a2: uintptr(v1),
   1481 			a3: uintptr(v2),
   1482 		},
   1483 	})
   1484 }
   1485 
   1486 func (ctx *context) Uniform3iv(dst Uniform, src []int32) {
   1487 	ctx.enqueue(call{
   1488 		args: fnargs{
   1489 			fn: glfnUniform3iv,
   1490 			a0: dst.c(),
   1491 			a1: uintptr(len(src) / 3),
   1492 		},
   1493 		parg:     unsafe.Pointer(&src[0]),
   1494 		blocking: true,
   1495 	})
   1496 }
   1497 
   1498 func (ctx *context) Uniform4f(dst Uniform, v0, v1, v2, v3 float32) {
   1499 	ctx.enqueue(call{
   1500 		args: fnargs{
   1501 			fn: glfnUniform4f,
   1502 			a0: dst.c(),
   1503 			a1: uintptr(math.Float32bits(v0)),
   1504 			a2: uintptr(math.Float32bits(v1)),
   1505 			a3: uintptr(math.Float32bits(v2)),
   1506 			a4: uintptr(math.Float32bits(v3)),
   1507 		},
   1508 	})
   1509 }
   1510 
   1511 func (ctx *context) Uniform4fv(dst Uniform, src []float32) {
   1512 	ctx.enqueue(call{
   1513 		args: fnargs{
   1514 			fn: glfnUniform4fv,
   1515 			a0: dst.c(),
   1516 			a1: uintptr(len(src) / 4),
   1517 		},
   1518 		parg:     unsafe.Pointer(&src[0]),
   1519 		blocking: true,
   1520 	})
   1521 }
   1522 
   1523 func (ctx *context) Uniform4i(dst Uniform, v0, v1, v2, v3 int32) {
   1524 	ctx.enqueue(call{
   1525 		args: fnargs{
   1526 			fn: glfnUniform4i,
   1527 			a0: dst.c(),
   1528 			a1: uintptr(v0),
   1529 			a2: uintptr(v1),
   1530 			a3: uintptr(v2),
   1531 			a4: uintptr(v3),
   1532 		},
   1533 	})
   1534 }
   1535 
   1536 func (ctx *context) Uniform4iv(dst Uniform, src []int32) {
   1537 	ctx.enqueue(call{
   1538 		args: fnargs{
   1539 			fn: glfnUniform4iv,
   1540 			a0: dst.c(),
   1541 			a1: uintptr(len(src) / 4),
   1542 		},
   1543 		parg:     unsafe.Pointer(&src[0]),
   1544 		blocking: true,
   1545 	})
   1546 }
   1547 
   1548 func (ctx *context) UniformMatrix2fv(dst Uniform, src []float32) {
   1549 	ctx.enqueue(call{
   1550 		args: fnargs{
   1551 			fn: glfnUniformMatrix2fv,
   1552 			// OpenGL ES 2 does not support transpose.
   1553 			a0: dst.c(),
   1554 			a1: uintptr(len(src) / 4),
   1555 		},
   1556 		parg:     unsafe.Pointer(&src[0]),
   1557 		blocking: true,
   1558 	})
   1559 }
   1560 
   1561 func (ctx *context) UniformMatrix3fv(dst Uniform, src []float32) {
   1562 	ctx.enqueue(call{
   1563 		args: fnargs{
   1564 			fn: glfnUniformMatrix3fv,
   1565 			a0: dst.c(),
   1566 			a1: uintptr(len(src) / 9),
   1567 		},
   1568 		parg:     unsafe.Pointer(&src[0]),
   1569 		blocking: true,
   1570 	})
   1571 }
   1572 
   1573 func (ctx *context) UniformMatrix4fv(dst Uniform, src []float32) {
   1574 	ctx.enqueue(call{
   1575 		args: fnargs{
   1576 			fn: glfnUniformMatrix4fv,
   1577 			a0: dst.c(),
   1578 			a1: uintptr(len(src) / 16),
   1579 		},
   1580 		parg:     unsafe.Pointer(&src[0]),
   1581 		blocking: true,
   1582 	})
   1583 }
   1584 
   1585 func (ctx *context) UseProgram(p Program) {
   1586 	ctx.enqueue(call{
   1587 		args: fnargs{
   1588 			fn: glfnUseProgram,
   1589 			a0: p.c(),
   1590 		},
   1591 	})
   1592 }
   1593 
   1594 func (ctx *context) ValidateProgram(p Program) {
   1595 	ctx.enqueue(call{
   1596 		args: fnargs{
   1597 			fn: glfnValidateProgram,
   1598 			a0: p.c(),
   1599 		},
   1600 	})
   1601 }
   1602 
   1603 func (ctx *context) VertexAttrib1f(dst Attrib, x float32) {
   1604 	ctx.enqueue(call{
   1605 		args: fnargs{
   1606 			fn: glfnVertexAttrib1f,
   1607 			a0: dst.c(),
   1608 			a1: uintptr(math.Float32bits(x)),
   1609 		},
   1610 	})
   1611 }
   1612 
   1613 func (ctx *context) VertexAttrib1fv(dst Attrib, src []float32) {
   1614 	ctx.enqueue(call{
   1615 		args: fnargs{
   1616 			fn: glfnVertexAttrib1fv,
   1617 			a0: dst.c(),
   1618 		},
   1619 		parg:     unsafe.Pointer(&src[0]),
   1620 		blocking: true,
   1621 	})
   1622 }
   1623 
   1624 func (ctx *context) VertexAttrib2f(dst Attrib, x, y float32) {
   1625 	ctx.enqueue(call{
   1626 		args: fnargs{
   1627 			fn: glfnVertexAttrib2f,
   1628 			a0: dst.c(),
   1629 			a1: uintptr(math.Float32bits(x)),
   1630 			a2: uintptr(math.Float32bits(y)),
   1631 		},
   1632 	})
   1633 }
   1634 
   1635 func (ctx *context) VertexAttrib2fv(dst Attrib, src []float32) {
   1636 	ctx.enqueue(call{
   1637 		args: fnargs{
   1638 			fn: glfnVertexAttrib2fv,
   1639 			a0: dst.c(),
   1640 		},
   1641 		parg:     unsafe.Pointer(&src[0]),
   1642 		blocking: true,
   1643 	})
   1644 }
   1645 
   1646 func (ctx *context) VertexAttrib3f(dst Attrib, x, y, z float32) {
   1647 	ctx.enqueue(call{
   1648 		args: fnargs{
   1649 			fn: glfnVertexAttrib3f,
   1650 			a0: dst.c(),
   1651 			a1: uintptr(math.Float32bits(x)),
   1652 			a2: uintptr(math.Float32bits(y)),
   1653 			a3: uintptr(math.Float32bits(z)),
   1654 		},
   1655 	})
   1656 }
   1657 
   1658 func (ctx *context) VertexAttrib3fv(dst Attrib, src []float32) {
   1659 	ctx.enqueue(call{
   1660 		args: fnargs{
   1661 			fn: glfnVertexAttrib3fv,
   1662 			a0: dst.c(),
   1663 		},
   1664 		parg:     unsafe.Pointer(&src[0]),
   1665 		blocking: true,
   1666 	})
   1667 }
   1668 
   1669 func (ctx *context) VertexAttrib4f(dst Attrib, x, y, z, w float32) {
   1670 	ctx.enqueue(call{
   1671 		args: fnargs{
   1672 			fn: glfnVertexAttrib4f,
   1673 			a0: dst.c(),
   1674 			a1: uintptr(math.Float32bits(x)),
   1675 			a2: uintptr(math.Float32bits(y)),
   1676 			a3: uintptr(math.Float32bits(z)),
   1677 			a4: uintptr(math.Float32bits(w)),
   1678 		},
   1679 	})
   1680 }
   1681 
   1682 func (ctx *context) VertexAttrib4fv(dst Attrib, src []float32) {
   1683 	ctx.enqueue(call{
   1684 		args: fnargs{
   1685 			fn: glfnVertexAttrib4fv,
   1686 			a0: dst.c(),
   1687 		},
   1688 		parg:     unsafe.Pointer(&src[0]),
   1689 		blocking: true,
   1690 	})
   1691 }
   1692 
   1693 func (ctx *context) VertexAttribPointer(dst Attrib, size int, ty Enum, normalized bool, stride, offset int) {
   1694 	ctx.enqueue(call{
   1695 		args: fnargs{
   1696 			fn: glfnVertexAttribPointer,
   1697 			a0: dst.c(),
   1698 			a1: uintptr(size),
   1699 			a2: ty.c(),
   1700 			a3: glBoolean(normalized),
   1701 			a4: uintptr(stride),
   1702 			a5: uintptr(offset),
   1703 		},
   1704 	})
   1705 }
   1706 
   1707 func (ctx *context) Viewport(x, y, width, height int) {
   1708 	ctx.enqueue(call{
   1709 		args: fnargs{
   1710 			fn: glfnViewport,
   1711 			a0: uintptr(x),
   1712 			a1: uintptr(y),
   1713 			a2: uintptr(width),
   1714 			a3: uintptr(height),
   1715 		},
   1716 	})
   1717 }
   1718 
   1719 func (ctx context3) UniformMatrix2x3fv(dst Uniform, src []float32) {
   1720 	ctx.enqueue(call{
   1721 		args: fnargs{
   1722 			fn: glfnUniformMatrix2x3fv,
   1723 			a0: dst.c(),
   1724 			a1: uintptr(len(src) / 6),
   1725 		},
   1726 		parg:     unsafe.Pointer(&src[0]),
   1727 		blocking: true,
   1728 	})
   1729 }
   1730 
   1731 func (ctx context3) UniformMatrix3x2fv(dst Uniform, src []float32) {
   1732 	ctx.enqueue(call{
   1733 		args: fnargs{
   1734 			fn: glfnUniformMatrix3x2fv,
   1735 			a0: dst.c(),
   1736 			a1: uintptr(len(src) / 6),
   1737 		},
   1738 		parg:     unsafe.Pointer(&src[0]),
   1739 		blocking: true,
   1740 	})
   1741 }
   1742 
   1743 func (ctx context3) UniformMatrix2x4fv(dst Uniform, src []float32) {
   1744 	ctx.enqueue(call{
   1745 		args: fnargs{
   1746 			fn: glfnUniformMatrix2x4fv,
   1747 			a0: dst.c(),
   1748 			a1: uintptr(len(src) / 8),
   1749 		},
   1750 		parg:     unsafe.Pointer(&src[0]),
   1751 		blocking: true,
   1752 	})
   1753 }
   1754 
   1755 func (ctx context3) UniformMatrix4x2fv(dst Uniform, src []float32) {
   1756 	ctx.enqueue(call{
   1757 		args: fnargs{
   1758 			fn: glfnUniformMatrix4x2fv,
   1759 			a0: dst.c(),
   1760 			a1: uintptr(len(src) / 8),
   1761 		},
   1762 		parg:     unsafe.Pointer(&src[0]),
   1763 		blocking: true,
   1764 	})
   1765 }
   1766 
   1767 func (ctx context3) UniformMatrix3x4fv(dst Uniform, src []float32) {
   1768 	ctx.enqueue(call{
   1769 		args: fnargs{
   1770 			fn: glfnUniformMatrix3x4fv,
   1771 			a0: dst.c(),
   1772 			a1: uintptr(len(src) / 12),
   1773 		},
   1774 		parg:     unsafe.Pointer(&src[0]),
   1775 		blocking: true,
   1776 	})
   1777 }
   1778 
   1779 func (ctx context3) UniformMatrix4x3fv(dst Uniform, src []float32) {
   1780 	ctx.enqueue(call{
   1781 		args: fnargs{
   1782 			fn: glfnUniformMatrix4x3fv,
   1783 			a0: dst.c(),
   1784 			a1: uintptr(len(src) / 12),
   1785 		},
   1786 		parg:     unsafe.Pointer(&src[0]),
   1787 		blocking: true,
   1788 	})
   1789 }
   1790 
   1791 func (ctx context3) BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1 int, mask uint, filter Enum) {
   1792 	ctx.enqueue(call{
   1793 		args: fnargs{
   1794 			fn: glfnBlitFramebuffer,
   1795 			a0: uintptr(srcX0),
   1796 			a1: uintptr(srcY0),
   1797 			a2: uintptr(srcX1),
   1798 			a3: uintptr(srcY1),
   1799 			a4: uintptr(dstX0),
   1800 			a5: uintptr(dstY0),
   1801 			a6: uintptr(dstX1),
   1802 			a7: uintptr(dstY1),
   1803 			a8: uintptr(mask),
   1804 			a9: filter.c(),
   1805 		},
   1806 	})
   1807 }
   1808 
   1809 func (ctx context3) Uniform1ui(dst Uniform, v uint32) {
   1810 	ctx.enqueue(call{
   1811 		args: fnargs{
   1812 			fn: glfnUniform1ui,
   1813 			a0: dst.c(),
   1814 			a1: uintptr(v),
   1815 		},
   1816 	})
   1817 }
   1818 
   1819 func (ctx context3) Uniform2ui(dst Uniform, v0, v1 uint32) {
   1820 	ctx.enqueue(call{
   1821 		args: fnargs{
   1822 			fn: glfnUniform2ui,
   1823 			a0: dst.c(),
   1824 			a1: uintptr(v0),
   1825 			a2: uintptr(v1),
   1826 		},
   1827 	})
   1828 }
   1829 
   1830 func (ctx context3) Uniform3ui(dst Uniform, v0, v1, v2 uint) {
   1831 	ctx.enqueue(call{
   1832 		args: fnargs{
   1833 			fn: glfnUniform3ui,
   1834 			a0: dst.c(),
   1835 			a1: uintptr(v0),
   1836 			a2: uintptr(v1),
   1837 			a3: uintptr(v2),
   1838 		},
   1839 	})
   1840 }
   1841 
   1842 func (ctx context3) Uniform4ui(dst Uniform, v0, v1, v2, v3 uint32) {
   1843 	ctx.enqueue(call{
   1844 		args: fnargs{
   1845 			fn: glfnUniform4ui,
   1846 			a0: dst.c(),
   1847 			a1: uintptr(v0),
   1848 			a2: uintptr(v1),
   1849 			a3: uintptr(v2),
   1850 			a4: uintptr(v3),
   1851 		},
   1852 	})
   1853 }