github.com/danbrough/mobile@v0.0.3-beta03/gl/gl.go (about)

     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  }