github.com/thommil/tge-gl@v0.0.0-20190313100017-83d8f10f8fae/gl_browser.go (about)

     1  // Copyright (c) 2019 Thomas MILLET. All rights reserved.
     2  
     3  // +build js
     4  
     5  package gl
     6  
     7  import (
     8  	binary "encoding/binary"
     9  	fmt "fmt"
    10  	math "math"
    11  	js "syscall/js"
    12  	unsafe "unsafe"
    13  
    14  	tge "github.com/thommil/tge"
    15  )
    16  
    17  type plugin struct {
    18  	glContext *js.Value
    19  }
    20  
    21  func (p *plugin) Init(runtime tge.Runtime) error {
    22  	renderer := runtime.GetRenderer()
    23  	switch renderer.(type) {
    24  	case *js.Value:
    25  		p.glContext = renderer.(*js.Value)
    26  	default:
    27  		return fmt.Errorf("Runtime renderer must be a *syscall/js.Value")
    28  	}
    29  
    30  	programMap[NONE] = js.Null()
    31  	shaderMap[NONE] = js.Null()
    32  	bufferMap[NONE] = js.Null()
    33  	framebufferMap[NONE] = js.Null()
    34  	renderbufferMap[NONE] = js.Null()
    35  	textureMap[NONE] = js.Null()
    36  	vertexArrayMap[NONE] = js.Null()
    37  
    38  	return nil
    39  }
    40  
    41  func (p *plugin) Dispose() {
    42  	FlushCache()
    43  }
    44  
    45  // GetGLSLVersion gives the glsl version ti put in #version ${VERSION}
    46  func GetGLSLVersion() string {
    47  	return "300 es"
    48  }
    49  
    50  // FlushCache free memory cache, should be called between scenes
    51  func FlushCache() {
    52  	for k := range float32TypedArrayCacheMap {
    53  		delete(float32TypedArrayCacheMap, k)
    54  	}
    55  	for k := range int32TypedArrayCacheMap {
    56  		delete(int32TypedArrayCacheMap, k)
    57  	}
    58  
    59  	for k := range programMap {
    60  		delete(programMap, k)
    61  	}
    62  	programMapIndex = Program(1)
    63  
    64  	for k := range shaderMap {
    65  		delete(shaderMap, k)
    66  	}
    67  	shaderMapIndex = Shader(1)
    68  
    69  	for k := range bufferMap {
    70  		delete(bufferMap, k)
    71  	}
    72  	bufferMapIndex = Buffer(1)
    73  
    74  	for k := range framebufferMap {
    75  		delete(framebufferMap, k)
    76  	}
    77  	framebufferMapIndex = Framebuffer(1)
    78  
    79  	for k := range renderbufferMap {
    80  		delete(renderbufferMap, k)
    81  	}
    82  	renderbufferMapIndex = Renderbuffer(1)
    83  
    84  	for k := range textureMap {
    85  		delete(textureMap, k)
    86  	}
    87  	textureMapIndex = Texture(1)
    88  
    89  	for k := range uniformMap {
    90  		delete(uniformMap, k)
    91  	}
    92  	uniformMapIndex = Uniform(0)
    93  
    94  	for k := range vertexArrayMap {
    95  		delete(vertexArrayMap, k)
    96  	}
    97  	vertexArrayMapIndex = VertexArray(1)
    98  
    99  	int32ArrayBuffer = make([]int32, 0)
   100  	int32ArrayBufferExtendFactor = 1
   101  
   102  	float32ArrayBuffer = make([]float32, 0)
   103  	float32ArrayBufferExtendFactor = 1
   104  
   105  	byteArrayBuffer = make([]byte, 0)
   106  	byteArrayBufferExtendFactor = 1
   107  }
   108  
   109  var programMap = make(map[Program]js.Value)
   110  var programMapIndex = Program(1)
   111  
   112  var shaderMap = make(map[Shader]js.Value)
   113  var shaderMapIndex = Shader(1)
   114  
   115  var bufferMap = make(map[Buffer]js.Value)
   116  var bufferMapIndex = Buffer(1)
   117  
   118  var framebufferMap = make(map[Framebuffer]js.Value)
   119  var framebufferMapIndex = Framebuffer(1)
   120  
   121  var renderbufferMap = make(map[Renderbuffer]js.Value)
   122  var renderbufferMapIndex = Renderbuffer(1)
   123  
   124  var textureMap = make(map[Texture]js.Value)
   125  var textureMapIndex = Texture(1)
   126  
   127  var uniformMap = make(map[Uniform]js.Value)
   128  var uniformMapIndex = Uniform(0)
   129  
   130  var vertexArrayMap = make(map[VertexArray]js.Value)
   131  var vertexArrayMapIndex = VertexArray(1)
   132  
   133  func ActiveTexture(texture Enum) {
   134  	_pluginInstance.glContext.Call("activeTexture", int(texture))
   135  }
   136  
   137  func AttachShader(p Program, s Shader) {
   138  	_pluginInstance.glContext.Call("attachShader", programMap[p], shaderMap[s])
   139  }
   140  
   141  func BindAttribLocation(p Program, a Attrib, name string) {
   142  	_pluginInstance.glContext.Call("bindAttribLocation", programMap[p], int32(a), name)
   143  }
   144  
   145  func BindBuffer(target Enum, b Buffer) {
   146  	_pluginInstance.glContext.Call("bindBuffer", int(target), bufferMap[b])
   147  }
   148  
   149  func BindFramebuffer(target Enum, fb Framebuffer) {
   150  	_pluginInstance.glContext.Call("bindFramebuffer", int(target), framebufferMap[fb])
   151  }
   152  
   153  func BindRenderbuffer(target Enum, rb Renderbuffer) {
   154  	_pluginInstance.glContext.Call("bindRenderbuffer", int(target), renderbufferMap[rb])
   155  }
   156  
   157  func BindTexture(target Enum, t Texture) {
   158  	_pluginInstance.glContext.Call("bindTexture", int(target), textureMap[t])
   159  }
   160  
   161  func BindVertexArray(vao VertexArray) {
   162  	_pluginInstance.glContext.Call("bindVertexArray", vertexArrayMap[vao])
   163  }
   164  
   165  func BlendColor(red, green, blue, alpha float32) {
   166  	_pluginInstance.glContext.Call("blendColor", red, green, blue, alpha)
   167  }
   168  
   169  func BlendEquation(mode Enum) {
   170  	_pluginInstance.glContext.Call("blendEquation", int(mode))
   171  }
   172  
   173  func BlendEquationSeparate(modeRGB, modeAlpha Enum) {
   174  	_pluginInstance.glContext.Call("blendEquationSeparate", modeRGB, modeAlpha)
   175  }
   176  
   177  func BlendFunc(sfactor, dfactor Enum) {
   178  	_pluginInstance.glContext.Call("blendFunc", int(sfactor), int(dfactor))
   179  }
   180  
   181  func BlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha Enum) {
   182  	_pluginInstance.glContext.Call("blendFuncSeparate", int(sfactorRGB), int(dfactorRGB), int(sfactorAlpha), int(dfactorAlpha))
   183  }
   184  
   185  func BufferInit(target Enum, size int, usage Enum) {
   186  	js.TypedArrayOf(getByteArrayBuffer(size))
   187  	_pluginInstance.glContext.Call("bufferData", int(target), size, int(usage))
   188  }
   189  
   190  func BufferData(target Enum, src []byte, usage Enum) {
   191  	srcTA := js.TypedArrayOf(src)
   192  	_pluginInstance.glContext.Call("bufferData", int(target), srcTA, int(usage))
   193  	srcTA.Release()
   194  }
   195  
   196  func BufferSubData(target Enum, offset int, data []byte) {
   197  	_pluginInstance.glContext.Call("bufferSubData", int(target), offset, data)
   198  }
   199  
   200  func CheckFramebufferStatus(target Enum) Enum {
   201  	return Enum(_pluginInstance.glContext.Call("checkFramebufferStatus", int(target)).Int())
   202  }
   203  
   204  func Clear(mask Enum) {
   205  	_pluginInstance.glContext.Call("clear", int(mask))
   206  }
   207  
   208  func ClearColor(red, green, blue, alpha float32) {
   209  	_pluginInstance.glContext.Call("clearColor", red, green, blue, alpha)
   210  }
   211  
   212  func ClearDepthf(d float32) {
   213  	_pluginInstance.glContext.Call("clearDepth", d)
   214  }
   215  
   216  func ClearStencil(s int) {
   217  	_pluginInstance.glContext.Call("clearStencil", s)
   218  }
   219  
   220  func ColorMask(red, green, blue, alpha bool) {
   221  	_pluginInstance.glContext.Call("colorMask", red, green, blue, alpha)
   222  }
   223  
   224  func CompileShader(s Shader) {
   225  	_pluginInstance.glContext.Call("compileShader", shaderMap[s])
   226  }
   227  
   228  func CompressedTexImage2D(target Enum, level int, internalformat Enum, width, height, border int, data []byte) {
   229  	_pluginInstance.glContext.Call("compressedTexImage2D", int(target), level, internalformat, width, height, border, data)
   230  }
   231  
   232  func CompressedTexSubImage2D(target Enum, level, xoffset, yoffset, width, height int, format Enum, data []byte) {
   233  	_pluginInstance.glContext.Call("compressedTexSubImage2D", int(target), level, xoffset, yoffset, width, height, format, data)
   234  }
   235  
   236  func CopyTexImage2D(target Enum, level int, internalformat Enum, x, y, width, height, border int) {
   237  	_pluginInstance.glContext.Call("copyTexImage2D", int(target), level, internalformat, x, y, width, height, border)
   238  }
   239  
   240  func CopyTexSubImage2D(target Enum, level, xoffset, yoffset, x, y, width, height int) {
   241  	_pluginInstance.glContext.Call("copyTexSubImage2D", int(target), level, xoffset, yoffset, x, y, width, height)
   242  }
   243  
   244  func CreateBuffer() Buffer {
   245  	bufferMap[bufferMapIndex] = _pluginInstance.glContext.Call("createBuffer")
   246  	buffer := Buffer(bufferMapIndex)
   247  	bufferMapIndex++
   248  	return buffer
   249  }
   250  
   251  func CreateFramebuffer() Framebuffer {
   252  	framebufferMap[framebufferMapIndex] = _pluginInstance.glContext.Call("createFramebuffer")
   253  	framebuffer := Framebuffer(framebufferMapIndex)
   254  	framebufferMapIndex++
   255  	return framebuffer
   256  }
   257  
   258  func CreateProgram() Program {
   259  	programMap[programMapIndex] = _pluginInstance.glContext.Call("createProgram")
   260  	program := Program(programMapIndex)
   261  	programMapIndex++
   262  	return program
   263  }
   264  
   265  func CreateRenderbuffer() Renderbuffer {
   266  	renderbufferMap[renderbufferMapIndex] = _pluginInstance.glContext.Call("createRenderbuffer")
   267  	renderbuffer := Renderbuffer(renderbufferMapIndex)
   268  	renderbufferMapIndex++
   269  	return renderbuffer
   270  }
   271  
   272  func CreateShader(ty Enum) Shader {
   273  	shaderMap[shaderMapIndex] = _pluginInstance.glContext.Call("createShader", int(ty))
   274  	shader := Shader(shaderMapIndex)
   275  	shaderMapIndex++
   276  	return shader
   277  }
   278  
   279  func CreateTexture() Texture {
   280  	textureMap[textureMapIndex] = _pluginInstance.glContext.Call("createTexture")
   281  	texture := Texture(textureMapIndex)
   282  	textureMapIndex++
   283  	return texture
   284  }
   285  
   286  func CreateVertexArray() VertexArray {
   287  	vertexArrayMap[vertexArrayMapIndex] = _pluginInstance.glContext.Call("createVertexArray")
   288  	vao := VertexArray(vertexArrayMapIndex)
   289  	vertexArrayMapIndex++
   290  	return vao
   291  }
   292  
   293  func CullFace(mode Enum) {
   294  	_pluginInstance.glContext.Call("cullFace", int(mode))
   295  }
   296  
   297  func DeleteBuffer(v Buffer) {
   298  	_pluginInstance.glContext.Call("deleteBuffer", bufferMap[v])
   299  	delete(bufferMap, v)
   300  }
   301  
   302  func DeleteFramebuffer(v Framebuffer) {
   303  	_pluginInstance.glContext.Call("deleteFramebuffer", framebufferMap[v])
   304  	delete(framebufferMap, v)
   305  }
   306  
   307  func DeleteProgram(p Program) {
   308  	_pluginInstance.glContext.Call("deleteProgram", programMap[p])
   309  	delete(programMap, p)
   310  }
   311  
   312  func DeleteRenderbuffer(v Renderbuffer) {
   313  	_pluginInstance.glContext.Call("deleteRenderbuffer", renderbufferMap[v])
   314  	delete(renderbufferMap, v)
   315  }
   316  
   317  func DeleteShader(s Shader) {
   318  	_pluginInstance.glContext.Call("deleteShader", shaderMap[s])
   319  	delete(shaderMap, s)
   320  }
   321  
   322  func DeleteTexture(v Texture) {
   323  	_pluginInstance.glContext.Call("deleteTexture", textureMap[v])
   324  	delete(textureMap, v)
   325  }
   326  
   327  func DeleteVertexArray(v VertexArray) {
   328  	_pluginInstance.glContext.Call("DeleteVertexArray", vertexArrayMap[v])
   329  	delete(vertexArrayMap, v)
   330  }
   331  
   332  func DepthFunc(fn Enum) {
   333  	_pluginInstance.glContext.Call("depthFunc", uint32(fn))
   334  }
   335  
   336  func DepthMask(flag bool) {
   337  	_pluginInstance.glContext.Call("depthMask", flag)
   338  }
   339  
   340  func DepthRangef(n, f float32) {
   341  	_pluginInstance.glContext.Call("depthRange", n, f)
   342  }
   343  
   344  func DetachShader(p Program, s Shader) {
   345  	_pluginInstance.glContext.Call("detachShader", programMap[p], shaderMap[s])
   346  }
   347  
   348  func Disable(cap Enum) {
   349  	_pluginInstance.glContext.Call("disable", int(cap))
   350  }
   351  
   352  func DisableVertexAttribArray(a Attrib) {
   353  	_pluginInstance.glContext.Call("disableVertexAttribArray", int32(a))
   354  }
   355  
   356  func DrawArrays(mode Enum, first, count int) {
   357  	_pluginInstance.glContext.Call("drawArrays", int(mode), first, count)
   358  }
   359  
   360  func DrawElements(mode Enum, count int, ty Enum, offset int) {
   361  	_pluginInstance.glContext.Call("drawElements", int(mode), count, int(ty), offset)
   362  }
   363  
   364  func Enable(cap Enum) {
   365  	_pluginInstance.glContext.Call("enable", uint32(cap))
   366  }
   367  
   368  func EnableVertexAttribArray(a Attrib) {
   369  	_pluginInstance.glContext.Call("enableVertexAttribArray", int32(a))
   370  }
   371  
   372  func Finish() {
   373  	_pluginInstance.glContext.Call("finish")
   374  }
   375  
   376  func Flush() {
   377  	_pluginInstance.glContext.Call("flush")
   378  }
   379  
   380  func FramebufferRenderbuffer(target, attachment, rbTarget Enum, rb Renderbuffer) {
   381  	_pluginInstance.glContext.Call("framebufferRenderbuffer", target, attachment, int(rbTarget), renderbufferMap[rb])
   382  }
   383  
   384  func FramebufferTexture2D(target, attachment, texTarget Enum, t Texture, level int) {
   385  	_pluginInstance.glContext.Call("framebufferTexture2D", target, attachment, int(texTarget), textureMap[t], level)
   386  }
   387  
   388  func FrontFace(mode Enum) {
   389  	_pluginInstance.glContext.Call("frontFace", int(mode))
   390  }
   391  
   392  func GenerateMipmap(target Enum) {
   393  	_pluginInstance.glContext.Call("generateMipmap", int(target))
   394  }
   395  
   396  func GetActiveAttrib(p Program, index uint32) (name string, size int, ty Enum) {
   397  	ai := _pluginInstance.glContext.Call("getActiveAttrib", programMap[p], index)
   398  	return ai.Get("name").String(), ai.Get("size").Int(), Enum(ai.Get("type").Int())
   399  }
   400  
   401  func GetActiveUniform(p Program, index uint32) (name string, size int, ty Enum) {
   402  	ai := _pluginInstance.glContext.Call("getActiveUniform", programMap[p], index)
   403  	return ai.Get("name").String(), ai.Get("size").Int(), Enum(ai.Get("type").Int())
   404  }
   405  
   406  func GetAttachedShaders(p Program) []Shader {
   407  	fmt.Printf("WARNING: GetAttachedShaders not implemented\n")
   408  	return []Shader{}
   409  }
   410  
   411  func GetAttribLocation(p Program, name string) Attrib {
   412  	return Attrib(int32(_pluginInstance.glContext.Call("getAttribLocation", programMap[p], name).Int()))
   413  }
   414  
   415  func GetBooleanv(dst []bool, pname Enum) {
   416  	result := _pluginInstance.glContext.Call("getParameter", int(pname))
   417  	length := result.Length()
   418  	for i := 0; i < length; i++ {
   419  		dst[i] = result.Index(i).Bool()
   420  	}
   421  }
   422  
   423  func GetFloatv(dst []float32, pname Enum) {
   424  	result := _pluginInstance.glContext.Call("getParameter", int(pname))
   425  	length := result.Length()
   426  	for i := 0; i < length; i++ {
   427  		dst[i] = float32(result.Index(i).Float())
   428  	}
   429  }
   430  
   431  func GetIntegerv(pname Enum, data []int32) {
   432  	result := _pluginInstance.glContext.Call("getParameter", int(pname))
   433  	length := result.Length()
   434  	for i := 0; i < length; i++ {
   435  		data[i] = int32(result.Index(i).Int())
   436  	}
   437  }
   438  
   439  func GetInteger(pname Enum) int {
   440  	return _pluginInstance.glContext.Call("getParameter", int(pname)).Int()
   441  }
   442  
   443  func GetBufferParameteri(target, pname Enum) int {
   444  	return _pluginInstance.glContext.Call("getBufferParameter", int(target), int(pname)).Int()
   445  }
   446  
   447  func GetError() Enum {
   448  	return Enum(_pluginInstance.glContext.Call("getError").Int())
   449  }
   450  
   451  func GetBoundFramebuffer() Framebuffer {
   452  	fmt.Printf("WARNING: GetAttachedShaders not implemented\n")
   453  	return NONE
   454  }
   455  
   456  func GetFramebufferAttachmentParameteri(target, attachment, pname Enum) int {
   457  	return _pluginInstance.glContext.Call("getFramebufferAttachmentParameter", int(target), int(attachment), int(pname)).Int()
   458  }
   459  
   460  func GetProgrami(p Program, pname Enum) int {
   461  	switch pname {
   462  	case DELETE_STATUS, LINK_STATUS, VALIDATE_STATUS:
   463  		if _pluginInstance.glContext.Call("getProgramParameter", programMap[p], int(pname)).Bool() {
   464  			return TRUE
   465  		}
   466  		return FALSE
   467  	default:
   468  		return _pluginInstance.glContext.Call("getProgramParameter", programMap[p], int(pname)).Int()
   469  	}
   470  }
   471  
   472  func GetProgramInfoLog(p Program) string {
   473  	return _pluginInstance.glContext.Call("getProgramInfoLog", programMap[p]).String()
   474  }
   475  
   476  func GetRenderbufferParameteri(target, pname Enum) int {
   477  	return _pluginInstance.glContext.Call("getRenderbufferParameter", int(target), int(pname)).Int()
   478  }
   479  
   480  func GetShaderi(s Shader, pname Enum) int {
   481  	switch pname {
   482  	case DELETE_STATUS, COMPILE_STATUS:
   483  		if _pluginInstance.glContext.Call("getShaderParameter", shaderMap[s], int(pname)).Bool() {
   484  			return TRUE
   485  		}
   486  		return FALSE
   487  	default:
   488  		return _pluginInstance.glContext.Call("getShaderParameter", shaderMap[s], int(pname)).Int()
   489  	}
   490  }
   491  
   492  func GetShaderInfoLog(s Shader) string {
   493  	return _pluginInstance.glContext.Call("getShaderInfoLog", shaderMap[s]).String()
   494  }
   495  
   496  func GetShaderPrecisionFormat(shadertype, precisiontype Enum) (rangeMin, rangeMax, precision int) {
   497  	format := _pluginInstance.glContext.Call("getShaderPrecisionFormat", uint32(shadertype), uint32(precisiontype))
   498  	rangeMin = format.Get("rangeMin").Int()
   499  	rangeMax = format.Get("rangeMax").Int()
   500  	precision = format.Get("precision").Int()
   501  	return
   502  }
   503  
   504  func GetShaderSource(s Shader) string {
   505  	return _pluginInstance.glContext.Call("getShaderSource", shaderMap[s]).String()
   506  }
   507  
   508  func GetString(pname Enum) string {
   509  	return _pluginInstance.glContext.Call("getParameter", int(pname)).String()
   510  }
   511  
   512  func GetTexParameterfv(dst []float32, target, pname Enum) {
   513  	dst[0] = float32(_pluginInstance.glContext.Call("getTexParameter", int(pname)).Float())
   514  }
   515  
   516  func GetTexParameteriv(dst []int32, target, pname Enum) {
   517  	dst[0] = int32(_pluginInstance.glContext.Call("getTexParameter", int(pname)).Int())
   518  }
   519  
   520  func GetUniformfv(dst []float32, src Uniform, p Program) {
   521  	result := _pluginInstance.glContext.Call("getUniform")
   522  	length := result.Length()
   523  	for i := 0; i < length; i++ {
   524  		dst[i] = float32(result.Index(i).Float())
   525  	}
   526  }
   527  
   528  func GetUniformiv(dst []int32, src Uniform, p Program) {
   529  	result := _pluginInstance.glContext.Call("getUniform")
   530  	length := result.Length()
   531  	for i := 0; i < length; i++ {
   532  		dst[i] = int32(result.Index(i).Int())
   533  	}
   534  }
   535  
   536  func GetUniformLocation(p Program, name string) Uniform {
   537  	uniform := _pluginInstance.glContext.Call("getUniformLocation", programMap[p], name)
   538  	uniformIndex := *(*Uniform)(unsafe.Pointer(&uniform))
   539  	uniformMap[uniformIndex] = uniform
   540  	return Uniform(uniformIndex)
   541  
   542  }
   543  
   544  func GetVertexAttribf(src Attrib, pname Enum) float32 {
   545  	return float32(_pluginInstance.glContext.Call("getVertexAttrib", int32(src), int(pname)).Float())
   546  }
   547  
   548  func GetVertexAttribfv(dst []float32, src Attrib, pname Enum) {
   549  	result := _pluginInstance.glContext.Call("getVertexAttrib")
   550  	length := result.Length()
   551  	for i := 0; i < length; i++ {
   552  		dst[i] = float32(result.Index(i).Float())
   553  	}
   554  }
   555  
   556  func GetVertexAttribi(src Attrib, pname Enum) int32 {
   557  	return int32(_pluginInstance.glContext.Call("getVertexAttrib", int32(src), int(pname)).Int())
   558  }
   559  
   560  func GetVertexAttribiv(dst []int32, src Attrib, pname Enum) {
   561  	result := _pluginInstance.glContext.Call("getVertexAttrib")
   562  	length := result.Length()
   563  	for i := 0; i < length; i++ {
   564  		dst[i] = int32(result.Index(i).Int())
   565  	}
   566  }
   567  
   568  func Hint(target, mode Enum) {
   569  	_pluginInstance.glContext.Call("hint", int(target), int(mode))
   570  }
   571  
   572  func IsBuffer(b Buffer) bool {
   573  	if buffer, found := bufferMap[b]; found {
   574  		return _pluginInstance.glContext.Call("isBuffer", buffer).Bool()
   575  	}
   576  	return false
   577  }
   578  
   579  func IsEnabled(cap Enum) bool {
   580  	return _pluginInstance.glContext.Call("isEnabled", int(cap)).Bool()
   581  }
   582  
   583  func IsFramebuffer(fb Framebuffer) bool {
   584  	if framebuffer, found := framebufferMap[fb]; found {
   585  		return _pluginInstance.glContext.Call("isFramebuffer", framebuffer).Bool()
   586  	}
   587  	return false
   588  }
   589  
   590  func IsProgram(p Program) bool {
   591  	if program, found := programMap[p]; found {
   592  		return _pluginInstance.glContext.Call("isProgram", program).Bool()
   593  	}
   594  	return false
   595  }
   596  
   597  func IsRenderbuffer(rb Renderbuffer) bool {
   598  	if renderbuffer, found := renderbufferMap[rb]; found {
   599  		return _pluginInstance.glContext.Call("isRenderbuffer", renderbuffer).Bool()
   600  	}
   601  	return false
   602  }
   603  
   604  func IsShader(s Shader) bool {
   605  	if shader, found := shaderMap[s]; found {
   606  		return _pluginInstance.glContext.Call("isShader", shader).Bool()
   607  	}
   608  	return false
   609  }
   610  
   611  func IsTexture(t Texture) bool {
   612  	if texture, found := textureMap[t]; found {
   613  		return _pluginInstance.glContext.Call("isTexture", texture).Bool()
   614  	}
   615  	return false
   616  }
   617  
   618  func LineWidth(width float32) {
   619  	_pluginInstance.glContext.Call("lineWidth", width)
   620  }
   621  
   622  func LinkProgram(p Program) {
   623  	_pluginInstance.glContext.Call("linkProgram", programMap[p])
   624  }
   625  
   626  func PixelStorei(pname Enum, param int32) {
   627  	_pluginInstance.glContext.Call("pixelStorei", int(pname), param)
   628  }
   629  
   630  func PolygonOffset(factor, units float32) {
   631  	_pluginInstance.glContext.Call("polygonOffset", factor, units)
   632  }
   633  
   634  func PolygonMode(face, mode Enum) {
   635  	fmt.Printf("WARNING: PolygonMode not implemented\n")
   636  }
   637  
   638  func ReadPixels(dst []byte, x, y, width, height int, format, ty Enum) {
   639  	if ty == Enum(UNSIGNED_BYTE) {
   640  		_pluginInstance.glContext.Call("readPixels", x, y, width, height, format, int(ty), dst)
   641  	} else {
   642  		tmpDst := make([]float32, len(dst)/4)
   643  		_pluginInstance.glContext.Call("readPixels", x, y, width, height, format, int(ty), tmpDst)
   644  		for i, f := range tmpDst {
   645  			binary.LittleEndian.PutUint32(dst[i*4:], math.Float32bits(f))
   646  		}
   647  	}
   648  }
   649  
   650  func ReleaseShaderCompiler() {
   651  	fmt.Printf("WARNING: ReleaseShaderCompiler not implemented\n")
   652  }
   653  
   654  func RenderbufferStorage(target, internalFormat Enum, width, height int) {
   655  	_pluginInstance.glContext.Call("renderbufferStorage", target, uint32(internalFormat), width, height)
   656  }
   657  
   658  func SampleCoverage(value float32, invert bool) {
   659  	_pluginInstance.glContext.Call("sampleCoverage", value, invert)
   660  }
   661  
   662  func Scissor(x, y, width, height int32) {
   663  	_pluginInstance.glContext.Call("scissor", x, y, width, height)
   664  }
   665  
   666  func ShaderSource(s Shader, src string) {
   667  	_pluginInstance.glContext.Call("shaderSource", shaderMap[s], src)
   668  }
   669  
   670  func StencilFunc(fn Enum, ref int, mask uint32) {
   671  	_pluginInstance.glContext.Call("stencilFunc", uint32(fn), ref, mask)
   672  }
   673  
   674  func StencilFuncSeparate(face, fn Enum, ref int, mask uint32) {
   675  	_pluginInstance.glContext.Call("stencilFuncSeparate", uint32(face), uint32(fn), ref, mask)
   676  }
   677  
   678  func StencilMask(mask uint32) {
   679  	_pluginInstance.glContext.Call("stencilMask", mask)
   680  }
   681  
   682  func StencilMaskSeparate(face Enum, mask uint32) {
   683  	_pluginInstance.glContext.Call("stencilMaskSeparate", uint32(face), mask)
   684  }
   685  
   686  func StencilOp(fail, zfail, zpass Enum) {
   687  	_pluginInstance.glContext.Call("stencilOp", uint32(fail), uint32(zfail), uint32(zpass))
   688  }
   689  
   690  func StencilOpSeparate(face, sfail, dpfail, dppass Enum) {
   691  	_pluginInstance.glContext.Call("stencilOpSeparate", uint32(face), uint32(sfail), uint32(dpfail), uint32(dppass))
   692  }
   693  
   694  func TexImage2D(target Enum, level int, width, height int, format Enum, ty Enum, data []byte) {
   695  	var p interface{}
   696  	if data != nil {
   697  		dataTA := js.TypedArrayOf(data)
   698  		defer dataTA.Release()
   699  		p = dataTA
   700  	}
   701  	_pluginInstance.glContext.Call("texImage2D", int(target), level, int(format), width, height, 0, int(format), int(ty), p)
   702  }
   703  
   704  func TexSubImage2D(target Enum, level int, x, y, width, height int, format, ty Enum, data []byte) {
   705  	_pluginInstance.glContext.Call("texSubImage2D", int(target), level, x, y, width, height, format, int(ty), data)
   706  }
   707  
   708  func TexParameterf(target, pname Enum, param float32) {
   709  	_pluginInstance.glContext.Call("texParameterf", int(target), int(pname), param)
   710  }
   711  
   712  func TexParameterfv(target, pname Enum, params []float32) {
   713  	for _, param := range params {
   714  		_pluginInstance.glContext.Call("texParameterf", int(target), int(pname), param)
   715  	}
   716  }
   717  
   718  func TexParameteri(target, pname Enum, param int) {
   719  	_pluginInstance.glContext.Call("texParameteri", int(target), int(pname), param)
   720  }
   721  
   722  func TexParameteriv(target, pname Enum, params []int32) {
   723  	for _, param := range params {
   724  		_pluginInstance.glContext.Call("texParameteri", int(target), int(pname), param)
   725  	}
   726  }
   727  
   728  //go:linkname memmove runtime.memmove
   729  func memmove(to, from unsafe.Pointer, n uintptr)
   730  
   731  // int32 array singleton, allocate 1KB at startup
   732  var int32ArrayBuffer = make([]int32, 0)
   733  var int32ArrayBufferExtendFactor = 1
   734  
   735  const int32Offset = unsafe.Sizeof(int32(0))
   736  
   737  func getInt32ArrayBuffer(size int) []int32 {
   738  	if size > len(int32ArrayBuffer) {
   739  		for (1024 * int32ArrayBufferExtendFactor) < size {
   740  			int32ArrayBufferExtendFactor++
   741  		}
   742  		int32ArrayBuffer = make([]int32, (1024 * int32ArrayBufferExtendFactor))
   743  	}
   744  	return int32ArrayBuffer[:size]
   745  }
   746  
   747  var int32TypedArrayCacheMap = make(map[uintptr]*js.TypedArray)
   748  
   749  // No affectation if done due to magic coincidence between this cache and syscall.js one \o/
   750  func getInt32TypedArrayFromCache(src []int32) *js.TypedArray {
   751  	key := uintptr(unsafe.Pointer(&src[0])) + uintptr(len(src))
   752  	if b, found := int32TypedArrayCacheMap[key]; found {
   753  		return b
   754  	} else {
   755  		b := js.TypedArrayOf(src)
   756  		int32TypedArrayCacheMap[key] = &b
   757  		return &b
   758  	}
   759  }
   760  
   761  func getInt32TypedArrayFromCacheP(size int, src *int32) *js.TypedArray {
   762  	b := getInt32ArrayBuffer(size)
   763  	memmove(unsafe.Pointer(&b[0]), unsafe.Pointer(src), uintptr(size)*int32Offset)
   764  	return getInt32TypedArrayFromCache(b)
   765  }
   766  
   767  func getInt32TypedArrayFromCacheUP(size int, src unsafe.Pointer) *js.TypedArray {
   768  	b := getInt32ArrayBuffer(size)
   769  	memmove(unsafe.Pointer(&b[0]), src, uintptr(size)*int32Offset)
   770  	return getInt32TypedArrayFromCache(b)
   771  }
   772  
   773  // float32 array singleton, allocate 1KB at startup
   774  var float32ArrayBuffer = make([]float32, 0)
   775  var float32ArrayBufferExtendFactor = 1
   776  
   777  const float32Offset = unsafe.Sizeof(float32(0))
   778  
   779  func getFloat32ArrayBuffer(size int) []float32 {
   780  	if size > len(float32ArrayBuffer) {
   781  		for (1024 * float32ArrayBufferExtendFactor) < size {
   782  			float32ArrayBufferExtendFactor++
   783  		}
   784  		float32ArrayBuffer = make([]float32, (1024 * float32ArrayBufferExtendFactor))
   785  	}
   786  	return float32ArrayBuffer[:size]
   787  }
   788  
   789  var float32TypedArrayCacheMap = make(map[uintptr]*js.TypedArray)
   790  
   791  // Hack using backed array of js.TypeArray and internal cache of syscall/js
   792  func getFloat32TypedArrayFromCache(src []float32) *js.TypedArray {
   793  	key := uintptr(unsafe.Pointer(&src[0])) + uintptr(len(src))
   794  	if b, found := float32TypedArrayCacheMap[key]; found {
   795  		return b
   796  	} else {
   797  		b := js.TypedArrayOf(src)
   798  		float32TypedArrayCacheMap[key] = &b
   799  		return &b
   800  	}
   801  }
   802  
   803  func getFloat32TypedArrayFromCacheP(size int, src *float32) *js.TypedArray {
   804  	b := getFloat32ArrayBuffer(size)
   805  	memmove(unsafe.Pointer(&b[0]), unsafe.Pointer(src), uintptr(size)*float32Offset)
   806  	return getFloat32TypedArrayFromCache(b)
   807  }
   808  
   809  func getFloat32TypedArrayFromCacheUP(size int, src unsafe.Pointer) *js.TypedArray {
   810  	b := getFloat32ArrayBuffer(size)
   811  	memmove(unsafe.Pointer(&b[0]), src, uintptr(size)*float32Offset)
   812  	return getFloat32TypedArrayFromCache(b)
   813  }
   814  
   815  func Uniform1f(dst Uniform, v float32) {
   816  	_pluginInstance.glContext.Call("uniform1f", uniformMap[dst], v)
   817  }
   818  
   819  func Uniform1fv(dst Uniform, src []float32) {
   820  	_pluginInstance.glContext.Call("uniform1fv", uniformMap[dst], *getFloat32TypedArrayFromCache(src))
   821  }
   822  
   823  func Uniform1fvP(dst Uniform, count int32, value *float32) {
   824  	_pluginInstance.glContext.Call("uniform1fv", uniformMap[dst], *getFloat32TypedArrayFromCacheP(int(count), value))
   825  }
   826  
   827  func Uniform1fvUP(dst Uniform, count int32, value unsafe.Pointer) {
   828  	_pluginInstance.glContext.Call("uniform1fv", uniformMap[dst], *getFloat32TypedArrayFromCacheUP(int(count), value))
   829  }
   830  
   831  func Uniform1i(dst Uniform, v int) {
   832  	_pluginInstance.glContext.Call("uniform1i", uniformMap[dst], v)
   833  }
   834  
   835  func Uniform1iv(dst Uniform, src []int32) {
   836  	_pluginInstance.glContext.Call("uniform1iv", uniformMap[dst], *getInt32TypedArrayFromCache(src))
   837  }
   838  
   839  func Uniform1ivP(dst Uniform, count int32, value *int32) {
   840  	_pluginInstance.glContext.Call("uniform1iv", uniformMap[dst], *getInt32TypedArrayFromCacheP(int(count), value))
   841  }
   842  
   843  func Uniform1ivUP(dst Uniform, count int32, value unsafe.Pointer) {
   844  	_pluginInstance.glContext.Call("uniform1iv", uniformMap[dst], *getInt32TypedArrayFromCacheUP(int(count), value))
   845  }
   846  
   847  func Uniform2f(dst Uniform, v0, v1 float32) {
   848  	_pluginInstance.glContext.Call("uniform2f", uniformMap[dst], v0, v1)
   849  }
   850  
   851  func Uniform2fv(dst Uniform, src []float32) {
   852  	_pluginInstance.glContext.Call("uniform2fv", uniformMap[dst], *getFloat32TypedArrayFromCache(src))
   853  }
   854  
   855  func Uniform2fvP(dst Uniform, count int32, value *float32) {
   856  	_pluginInstance.glContext.Call("uniform2fv", uniformMap[dst], *getFloat32TypedArrayFromCacheP(int(count*2), value))
   857  }
   858  
   859  func Uniform2fvUP(dst Uniform, count int32, value unsafe.Pointer) {
   860  	_pluginInstance.glContext.Call("uniform2fv", uniformMap[dst], *getFloat32TypedArrayFromCacheUP(int(count*2), value))
   861  }
   862  
   863  func Uniform2i(dst Uniform, v0, v1 int) {
   864  	_pluginInstance.glContext.Call("uniform2i", uniformMap[dst], v0, v1)
   865  }
   866  
   867  func Uniform2iv(dst Uniform, src []int32) {
   868  	_pluginInstance.glContext.Call("uniform2iv", uniformMap[dst], *getInt32TypedArrayFromCache(src))
   869  }
   870  
   871  func Uniform2ivP(dst Uniform, count int32, value *int32) {
   872  	_pluginInstance.glContext.Call("uniform2iv", uniformMap[dst], *getInt32TypedArrayFromCacheP(int(count*2), value))
   873  }
   874  
   875  func Uniform2ivUP(dst Uniform, count int32, value unsafe.Pointer) {
   876  	_pluginInstance.glContext.Call("uniform2iv", uniformMap[dst], *getInt32TypedArrayFromCacheUP(int(count*2), value))
   877  }
   878  
   879  func Uniform3f(dst Uniform, v0, v1, v2 float32) {
   880  	_pluginInstance.glContext.Call("uniform3f", uniformMap[dst], v0, v1, v2)
   881  }
   882  
   883  func Uniform3fv(dst Uniform, src []float32) {
   884  	_pluginInstance.glContext.Call("uniform3fv", uniformMap[dst], *getFloat32TypedArrayFromCache(src))
   885  }
   886  
   887  func Uniform3fvP(dst Uniform, count int32, value *float32) {
   888  	_pluginInstance.glContext.Call("uniform3fv", uniformMap[dst], *getFloat32TypedArrayFromCacheP(int(count*3), value))
   889  }
   890  
   891  func Uniform3fvUP(dst Uniform, count int32, value unsafe.Pointer) {
   892  	_pluginInstance.glContext.Call("uniform3fv", uniformMap[dst], *getFloat32TypedArrayFromCacheUP(int(count*3), value))
   893  }
   894  
   895  func Uniform3i(dst Uniform, v0, v1, v2 int32) {
   896  	_pluginInstance.glContext.Call("uniform3i", uniformMap[dst], v0, v1, v2)
   897  }
   898  
   899  func Uniform3iv(dst Uniform, src []int32) {
   900  	_pluginInstance.glContext.Call("uniform3iv", uniformMap[dst], *getInt32TypedArrayFromCache(src))
   901  }
   902  
   903  func Uniform3ivP(dst Uniform, count int32, value *int32) {
   904  	_pluginInstance.glContext.Call("uniform3iv", uniformMap[dst], *getInt32TypedArrayFromCacheP(int(count*3), value))
   905  }
   906  
   907  func Uniform3ivUP(dst Uniform, count int32, value unsafe.Pointer) {
   908  	_pluginInstance.glContext.Call("uniform3iv", uniformMap[dst], *getInt32TypedArrayFromCacheUP(int(count*3), value))
   909  }
   910  
   911  func Uniform4f(dst Uniform, v0, v1, v2, v3 float32) {
   912  	_pluginInstance.glContext.Call("uniform4f", uniformMap[dst], v0, v1, v2, v3)
   913  }
   914  
   915  func Uniform4fv(dst Uniform, src []float32) {
   916  	_pluginInstance.glContext.Call("uniform4fv", uniformMap[dst], *getFloat32TypedArrayFromCache(src))
   917  }
   918  
   919  func Uniform4fvP(dst Uniform, count int32, value *float32) {
   920  	_pluginInstance.glContext.Call("uniform4fv", uniformMap[dst], *getFloat32TypedArrayFromCacheP(int(count*4), value))
   921  }
   922  
   923  func Uniform4fvUP(dst Uniform, count int32, value unsafe.Pointer) {
   924  	_pluginInstance.glContext.Call("uniform4fv", uniformMap[dst], *getFloat32TypedArrayFromCacheUP(int(count*4), value))
   925  }
   926  
   927  func Uniform4i(dst Uniform, v0, v1, v2, v3 int32) {
   928  	_pluginInstance.glContext.Call("uniform4i", uniformMap[dst], v0, v1, v2, v3)
   929  }
   930  
   931  func Uniform4iv(dst Uniform, src []int32) {
   932  	_pluginInstance.glContext.Call("uniform4iv", uniformMap[dst], *getInt32TypedArrayFromCache(src))
   933  }
   934  
   935  func Uniform4ivP(dst Uniform, count int32, value *int32) {
   936  	_pluginInstance.glContext.Call("uniform4iv", uniformMap[dst], *getInt32TypedArrayFromCacheP(int(count*4), value))
   937  }
   938  
   939  func Uniform4ivUP(dst Uniform, count int32, value unsafe.Pointer) {
   940  	_pluginInstance.glContext.Call("uniform4iv", uniformMap[dst], *getInt32TypedArrayFromCacheUP(int(count*4), value))
   941  }
   942  
   943  func UniformMatrix2fv(dst Uniform, transpose bool, src []float32) {
   944  	_pluginInstance.glContext.Call("uniformMatrix2fv", uniformMap[dst], transpose, *getFloat32TypedArrayFromCache(src))
   945  }
   946  
   947  func UniformMatrix2fvP(dst Uniform, count int32, transpose bool, value *float32) {
   948  	_pluginInstance.glContext.Call("uniformMatrix2fv", uniformMap[dst], transpose, *getFloat32TypedArrayFromCacheP(int(count*4), value))
   949  }
   950  
   951  func UniformMatrix2fvUP(dst Uniform, count int32, transpose bool, value unsafe.Pointer) {
   952  	_pluginInstance.glContext.Call("uniformMatrix2fv", uniformMap[dst], transpose, *getFloat32TypedArrayFromCacheUP(int(count*4), value))
   953  }
   954  
   955  func UniformMatrix3fv(dst Uniform, transpose bool, src []float32) {
   956  	_pluginInstance.glContext.Call("uniformMatrix3fv", uniformMap[dst], transpose, *getFloat32TypedArrayFromCache(src))
   957  }
   958  
   959  func UniformMatrix3fvP(dst Uniform, count int32, transpose bool, value *float32) {
   960  	_pluginInstance.glContext.Call("uniformMatrix3fv", uniformMap[dst], transpose, *getFloat32TypedArrayFromCacheP(int(count*9), value))
   961  }
   962  
   963  func UniformMatrix3fvUP(dst Uniform, count int32, transpose bool, value unsafe.Pointer) {
   964  	_pluginInstance.glContext.Call("uniformMatrix3fv", uniformMap[dst], transpose, *getFloat32TypedArrayFromCacheUP(int(count*9), value))
   965  }
   966  
   967  func UniformMatrix4fv(dst Uniform, transpose bool, src []float32) {
   968  	_pluginInstance.glContext.Call("uniformMatrix4fv", uniformMap[dst], transpose, *getFloat32TypedArrayFromCache(src))
   969  }
   970  
   971  func UniformMatrix4fvP(dst Uniform, count int32, transpose bool, value *float32) {
   972  	_pluginInstance.glContext.Call("uniformMatrix4fv", uniformMap[dst], transpose, *getFloat32TypedArrayFromCacheP(int(count*16), value))
   973  }
   974  
   975  func UniformMatrix4fvUP(dst Uniform, count int32, transpose bool, value unsafe.Pointer) {
   976  	_pluginInstance.glContext.Call("uniformMatrix4fv", uniformMap[dst], transpose, *getFloat32TypedArrayFromCacheUP(int(count*16), value))
   977  }
   978  
   979  func UseProgram(p Program) {
   980  	_pluginInstance.glContext.Call("useProgram", programMap[p])
   981  }
   982  
   983  func ValidateProgram(p Program) {
   984  	_pluginInstance.glContext.Call("validateProgram", programMap[p])
   985  }
   986  
   987  func VertexAttrib1f(dst Attrib, x float32) {
   988  	_pluginInstance.glContext.Call("vertexAttrib1f", int32(dst), x)
   989  }
   990  
   991  func VertexAttrib1fv(dst Attrib, src []float32) {
   992  	_pluginInstance.glContext.Call("vertexAttrib1fv", int32(dst), src)
   993  }
   994  
   995  func VertexAttrib2f(dst Attrib, x, y float32) {
   996  	_pluginInstance.glContext.Call("vertexAttrib2f", int32(dst), x, y)
   997  }
   998  
   999  func VertexAttrib2fv(dst Attrib, src []float32) {
  1000  	_pluginInstance.glContext.Call("vertexAttrib2fv", int32(dst), src)
  1001  }
  1002  
  1003  func VertexAttrib3f(dst Attrib, x, y, z float32) {
  1004  	_pluginInstance.glContext.Call("vertexAttrib3f", int32(dst), x, y, z)
  1005  }
  1006  
  1007  func VertexAttrib3fv(dst Attrib, src []float32) {
  1008  	_pluginInstance.glContext.Call("vertexAttrib3fv", int32(dst), src)
  1009  }
  1010  
  1011  func VertexAttrib4f(dst Attrib, x, y, z, w float32) {
  1012  	_pluginInstance.glContext.Call("vertexAttrib4f", int32(dst), x, y, z, w)
  1013  }
  1014  
  1015  func VertexAttrib4fv(dst Attrib, src []float32) {
  1016  	_pluginInstance.glContext.Call("vertexAttrib4fv", int32(dst), src)
  1017  }
  1018  
  1019  func VertexAttribPointer(dst Attrib, size int, ty Enum, normalized bool, stride, offset int) {
  1020  	_pluginInstance.glContext.Call("vertexAttribPointer", int32(dst), size, int(ty), normalized, stride, offset)
  1021  }
  1022  
  1023  func Viewport(x, y, width, height int) {
  1024  	_pluginInstance.glContext.Call("viewport", x, y, width, height)
  1025  }