twitchapon-anim

Basic Twitchapon Receiver/Visuals
git clone git://bsandro.tech/twitchapon-anim
Log | Files | Refs | README | LICENSE

gl.go (35933B)


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