mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 03:08:54 +01:00
internal/graphicsdriver/opengl: Prepare function objects by bind
Passing a Go string to the JS world is expensive. This change reduces this cost by preparing function objects by bind. Closes #1438
This commit is contained in:
parent
5c8d8ab2eb
commit
bd8367588e
@ -89,13 +89,11 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type contextImpl struct {
|
type contextImpl struct {
|
||||||
gl js.Value
|
gl *gl
|
||||||
lastProgramID programID
|
lastProgramID programID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) initGL() {
|
func (c *context) initGL() {
|
||||||
c.gl = js.Value{}
|
|
||||||
|
|
||||||
var gl js.Value
|
var gl js.Value
|
||||||
|
|
||||||
// TODO: Define id?
|
// TODO: Define id?
|
||||||
@ -120,7 +118,7 @@ func (c *context) initGL() {
|
|||||||
gl = go2cpp.Get("gl")
|
gl = go2cpp.Get("gl")
|
||||||
}
|
}
|
||||||
|
|
||||||
c.gl = gl
|
c.gl = newGL(gl)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) reset() error {
|
func (c *context) reset() error {
|
||||||
@ -133,18 +131,18 @@ func (c *context) reset() error {
|
|||||||
|
|
||||||
c.initGL()
|
c.initGL()
|
||||||
|
|
||||||
if c.gl.Call("isContextLost").Bool() {
|
if c.gl.isContextLost.Invoke().Bool() {
|
||||||
return driver.GraphicsNotReady
|
return driver.GraphicsNotReady
|
||||||
}
|
}
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
gl.Call("enable", gles.BLEND)
|
gl.enable.Invoke(gles.BLEND)
|
||||||
gl.Call("enable", gles.SCISSOR_TEST)
|
gl.enable.Invoke(gles.SCISSOR_TEST)
|
||||||
c.blendFunc(driver.CompositeModeSourceOver)
|
c.blendFunc(driver.CompositeModeSourceOver)
|
||||||
f := gl.Call("getParameter", gles.FRAMEBUFFER_BINDING)
|
f := gl.getParameter.Invoke(gles.FRAMEBUFFER_BINDING)
|
||||||
c.screenFramebuffer = framebufferNative(f)
|
c.screenFramebuffer = framebufferNative(f)
|
||||||
|
|
||||||
if !isWebGL2Available {
|
if !isWebGL2Available {
|
||||||
gl.Call("getExtension", "OES_standard_derivatives")
|
gl.getExtension.Invoke("OES_standard_derivatives")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -157,27 +155,27 @@ func (c *context) blendFunc(mode driver.CompositeMode) {
|
|||||||
s, d := mode.Operations()
|
s, d := mode.Operations()
|
||||||
s2, d2 := convertOperation(s), convertOperation(d)
|
s2, d2 := convertOperation(s), convertOperation(d)
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
gl.Call("blendFunc", int(s2), int(d2))
|
gl.blendFunc.Invoke(int(s2), int(d2))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) scissor(x, y, width, height int) {
|
func (c *context) scissor(x, y, width, height int) {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
gl.Call("scissor", x, y, width, height)
|
gl.scissor.Invoke(x, y, width, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) newTexture(width, height int) (textureNative, error) {
|
func (c *context) newTexture(width, height int) (textureNative, error) {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
t := gl.Call("createTexture")
|
t := gl.createTexture.Invoke()
|
||||||
if jsutil.Equal(t, js.Null()) {
|
if jsutil.Equal(t, js.Null()) {
|
||||||
return textureNative(js.Null()), errors.New("opengl: glGenTexture failed")
|
return textureNative(js.Null()), errors.New("opengl: glGenTexture failed")
|
||||||
}
|
}
|
||||||
gl.Call("pixelStorei", gles.UNPACK_ALIGNMENT, 4)
|
gl.pixelStorei.Invoke(gles.UNPACK_ALIGNMENT, 4)
|
||||||
c.bindTexture(textureNative(t))
|
c.bindTexture(textureNative(t))
|
||||||
|
|
||||||
gl.Call("texParameteri", gles.TEXTURE_2D, gles.TEXTURE_MAG_FILTER, gles.NEAREST)
|
gl.texParameteri.Invoke(gles.TEXTURE_2D, gles.TEXTURE_MAG_FILTER, gles.NEAREST)
|
||||||
gl.Call("texParameteri", gles.TEXTURE_2D, gles.TEXTURE_MIN_FILTER, gles.NEAREST)
|
gl.texParameteri.Invoke(gles.TEXTURE_2D, gles.TEXTURE_MIN_FILTER, gles.NEAREST)
|
||||||
gl.Call("texParameteri", gles.TEXTURE_2D, gles.TEXTURE_WRAP_S, gles.CLAMP_TO_EDGE)
|
gl.texParameteri.Invoke(gles.TEXTURE_2D, gles.TEXTURE_WRAP_S, gles.CLAMP_TO_EDGE)
|
||||||
gl.Call("texParameteri", gles.TEXTURE_2D, gles.TEXTURE_WRAP_T, gles.CLAMP_TO_EDGE)
|
gl.texParameteri.Invoke(gles.TEXTURE_2D, gles.TEXTURE_WRAP_T, gles.CLAMP_TO_EDGE)
|
||||||
|
|
||||||
// Firefox warns the usage of textures without specifying pixels (#629)
|
// Firefox warns the usage of textures without specifying pixels (#629)
|
||||||
//
|
//
|
||||||
@ -186,14 +184,14 @@ func (c *context) newTexture(width, height int) (textureNative, error) {
|
|||||||
// In Ebiten, textures are filled with pixels laster by the filter that ignores destination, so it is fine
|
// In Ebiten, textures are filled with pixels laster by the filter that ignores destination, so it is fine
|
||||||
// to leave textures as uninitialized here. Rather, extra memory allocating for initialization should be
|
// to leave textures as uninitialized here. Rather, extra memory allocating for initialization should be
|
||||||
// avoided.
|
// avoided.
|
||||||
gl.Call("texImage2D", gles.TEXTURE_2D, 0, gles.RGBA, width, height, 0, gles.RGBA, gles.UNSIGNED_BYTE, nil)
|
gl.texImage2D.Invoke(gles.TEXTURE_2D, 0, gles.RGBA, width, height, 0, gles.RGBA, gles.UNSIGNED_BYTE, nil)
|
||||||
|
|
||||||
return textureNative(t), nil
|
return textureNative(t), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) bindFramebufferImpl(f framebufferNative) {
|
func (c *context) bindFramebufferImpl(f framebufferNative) {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
gl.Call("bindFramebuffer", gles.FRAMEBUFFER, js.Value(f))
|
gl.bindFramebuffer.Invoke(gles.FRAMEBUFFER, js.Value(f))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) framebufferPixels(f *framebuffer, width, height int) []byte {
|
func (c *context) framebufferPixels(f *framebuffer, width, height int) []byte {
|
||||||
@ -203,7 +201,7 @@ func (c *context) framebufferPixels(f *framebuffer, width, height int) []byte {
|
|||||||
|
|
||||||
l := 4 * width * height
|
l := 4 * width * height
|
||||||
p := jsutil.TemporaryUint8Array(l, nil)
|
p := jsutil.TemporaryUint8Array(l, nil)
|
||||||
gl.Call("readPixels", 0, 0, width, height, gles.RGBA, gles.UNSIGNED_BYTE, p)
|
gl.readPixels.Invoke(0, 0, width, height, gles.RGBA, gles.UNSIGNED_BYTE, p)
|
||||||
|
|
||||||
return jsutil.Uint8ArrayToSlice(p, l)
|
return jsutil.Uint8ArrayToSlice(p, l)
|
||||||
}
|
}
|
||||||
@ -212,31 +210,31 @@ func (c *context) framebufferPixelsToBuffer(f *framebuffer, buffer buffer, width
|
|||||||
gl := c.gl
|
gl := c.gl
|
||||||
|
|
||||||
c.bindFramebuffer(f.native)
|
c.bindFramebuffer(f.native)
|
||||||
gl.Call("bindBuffer", gles.PIXEL_PACK_BUFFER, js.Value(buffer))
|
gl.bindBuffer.Invoke(gles.PIXEL_PACK_BUFFER, js.Value(buffer))
|
||||||
// void gl.readPixels(x, y, width, height, format, type, GLintptr offset);
|
// void gl.readPixels(x, y, width, height, format, type, GLintptr offset);
|
||||||
gl.Call("readPixels", 0, 0, width, height, gles.RGBA, gles.UNSIGNED_BYTE, 0)
|
gl.readPixels.Invoke(0, 0, width, height, gles.RGBA, gles.UNSIGNED_BYTE, 0)
|
||||||
gl.Call("bindBuffer", gles.PIXEL_PACK_BUFFER, nil)
|
gl.bindBuffer.Invoke(gles.PIXEL_PACK_BUFFER, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) activeTexture(idx int) {
|
func (c *context) activeTexture(idx int) {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
gl.Call("activeTexture", gles.TEXTURE0+idx)
|
gl.activeTexture.Invoke(gles.TEXTURE0 + idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) bindTextureImpl(t textureNative) {
|
func (c *context) bindTextureImpl(t textureNative) {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
gl.Call("bindTexture", gles.TEXTURE_2D, js.Value(t))
|
gl.bindTexture.Invoke(gles.TEXTURE_2D, js.Value(t))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) deleteTexture(t textureNative) {
|
func (c *context) deleteTexture(t textureNative) {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
if !gl.Call("isTexture", js.Value(t)).Bool() {
|
if !gl.isTexture.Invoke(js.Value(t)).Bool() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if c.lastTexture.equal(t) {
|
if c.lastTexture.equal(t) {
|
||||||
c.lastTexture = textureNative(js.Null())
|
c.lastTexture = textureNative(js.Null())
|
||||||
}
|
}
|
||||||
gl.Call("deleteTexture", js.Value(t))
|
gl.deleteTexture.Invoke(js.Value(t))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) isTexture(t textureNative) bool {
|
func (c *context) isTexture(t textureNative) bool {
|
||||||
@ -246,11 +244,11 @@ func (c *context) isTexture(t textureNative) bool {
|
|||||||
|
|
||||||
func (c *context) newFramebuffer(t textureNative) (framebufferNative, error) {
|
func (c *context) newFramebuffer(t textureNative) (framebufferNative, error) {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
f := gl.Call("createFramebuffer")
|
f := gl.createFramebuffer.Invoke()
|
||||||
c.bindFramebuffer(framebufferNative(f))
|
c.bindFramebuffer(framebufferNative(f))
|
||||||
|
|
||||||
gl.Call("framebufferTexture2D", gles.FRAMEBUFFER, gles.COLOR_ATTACHMENT0, gles.TEXTURE_2D, js.Value(t), 0)
|
gl.framebufferTexture2D.Invoke(gles.FRAMEBUFFER, gles.COLOR_ATTACHMENT0, gles.TEXTURE_2D, js.Value(t), 0)
|
||||||
if s := gl.Call("checkFramebufferStatus", gles.FRAMEBUFFER); s.Int() != gles.FRAMEBUFFER_COMPLETE {
|
if s := gl.checkFramebufferStatus.Invoke(gles.FRAMEBUFFER); s.Int() != gles.FRAMEBUFFER_COMPLETE {
|
||||||
return framebufferNative(js.Null()), errors.New(fmt.Sprintf("opengl: creating framebuffer failed: %d", s.Int()))
|
return framebufferNative(js.Null()), errors.New(fmt.Sprintf("opengl: creating framebuffer failed: %d", s.Int()))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,12 +257,12 @@ func (c *context) newFramebuffer(t textureNative) (framebufferNative, error) {
|
|||||||
|
|
||||||
func (c *context) setViewportImpl(width, height int) {
|
func (c *context) setViewportImpl(width, height int) {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
gl.Call("viewport", 0, 0, width, height)
|
gl.viewport.Invoke(0, 0, width, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) deleteFramebuffer(f framebufferNative) {
|
func (c *context) deleteFramebuffer(f framebufferNative) {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
if !gl.Call("isFramebuffer", js.Value(f)).Bool() {
|
if !gl.isFramebuffer.Invoke(js.Value(f)).Bool() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// If a framebuffer to be deleted is bound, a newly bound framebuffer
|
// If a framebuffer to be deleted is bound, a newly bound framebuffer
|
||||||
@ -275,7 +273,7 @@ func (c *context) deleteFramebuffer(f framebufferNative) {
|
|||||||
c.lastViewportWidth = 0
|
c.lastViewportWidth = 0
|
||||||
c.lastViewportHeight = 0
|
c.lastViewportHeight = 0
|
||||||
}
|
}
|
||||||
gl.Call("deleteFramebuffer", js.Value(f))
|
gl.deleteFramebuffer.Invoke(js.Value(f))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) newVertexShader(source string) (shader, error) {
|
func (c *context) newVertexShader(source string) (shader, error) {
|
||||||
@ -288,16 +286,16 @@ func (c *context) newFragmentShader(source string) (shader, error) {
|
|||||||
|
|
||||||
func (c *context) newShader(shaderType int, source string) (shader, error) {
|
func (c *context) newShader(shaderType int, source string) (shader, error) {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
s := gl.Call("createShader", int(shaderType))
|
s := gl.createShader.Invoke(int(shaderType))
|
||||||
if jsutil.Equal(s, js.Null()) {
|
if jsutil.Equal(s, js.Null()) {
|
||||||
return shader(js.Null()), fmt.Errorf("opengl: glCreateShader failed: shader type: %d", shaderType)
|
return shader(js.Null()), fmt.Errorf("opengl: glCreateShader failed: shader type: %d", shaderType)
|
||||||
}
|
}
|
||||||
|
|
||||||
gl.Call("shaderSource", js.Value(s), source)
|
gl.shaderSource.Invoke(js.Value(s), source)
|
||||||
gl.Call("compileShader", js.Value(s))
|
gl.compileShader.Invoke(js.Value(s))
|
||||||
|
|
||||||
if !gl.Call("getShaderParameter", js.Value(s), gles.COMPILE_STATUS).Bool() {
|
if !gl.getShaderParameter.Invoke(js.Value(s), gles.COMPILE_STATUS).Bool() {
|
||||||
log := gl.Call("getShaderInfoLog", js.Value(s))
|
log := gl.getShaderInfoLog.Invoke(js.Value(s))
|
||||||
return shader(js.Null()), fmt.Errorf("opengl: shader compile failed: %s", log)
|
return shader(js.Null()), fmt.Errorf("opengl: shader compile failed: %s", log)
|
||||||
}
|
}
|
||||||
return shader(s), nil
|
return shader(s), nil
|
||||||
@ -305,27 +303,27 @@ func (c *context) newShader(shaderType int, source string) (shader, error) {
|
|||||||
|
|
||||||
func (c *context) deleteShader(s shader) {
|
func (c *context) deleteShader(s shader) {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
gl.Call("deleteShader", js.Value(s))
|
gl.deleteShader.Invoke(js.Value(s))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) newProgram(shaders []shader, attributes []string) (program, error) {
|
func (c *context) newProgram(shaders []shader, attributes []string) (program, error) {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
v := gl.Call("createProgram")
|
v := gl.createProgram.Invoke()
|
||||||
if jsutil.Equal(v, js.Null()) {
|
if jsutil.Equal(v, js.Null()) {
|
||||||
return program{}, errors.New("opengl: glCreateProgram failed")
|
return program{}, errors.New("opengl: glCreateProgram failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, shader := range shaders {
|
for _, shader := range shaders {
|
||||||
gl.Call("attachShader", v, js.Value(shader))
|
gl.attachShader.Invoke(v, js.Value(shader))
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, name := range attributes {
|
for i, name := range attributes {
|
||||||
gl.Call("bindAttribLocation", v, i, name)
|
gl.bindAttribLocation.Invoke(v, i, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
gl.Call("linkProgram", v)
|
gl.linkProgram.Invoke(v)
|
||||||
if !gl.Call("getProgramParameter", v, gles.LINK_STATUS).Bool() {
|
if !gl.getProgramParameter.Invoke(v, gles.LINK_STATUS).Bool() {
|
||||||
info := gl.Call("getProgramInfoLog", v).String()
|
info := gl.getProgramInfoLog.Invoke(v).String()
|
||||||
return program{}, fmt.Errorf("opengl: program error: %s", info)
|
return program{}, fmt.Errorf("opengl: program error: %s", info)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,20 +337,20 @@ func (c *context) newProgram(shaders []shader, attributes []string) (program, er
|
|||||||
|
|
||||||
func (c *context) useProgram(p program) {
|
func (c *context) useProgram(p program) {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
gl.Call("useProgram", p.value)
|
gl.useProgram.Invoke(p.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) deleteProgram(p program) {
|
func (c *context) deleteProgram(p program) {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
if !gl.Call("isProgram", p.value).Bool() {
|
if !gl.isProgram.Invoke(p.value).Bool() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
gl.Call("deleteProgram", p.value)
|
gl.deleteProgram.Invoke(p.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) getUniformLocationImpl(p program, location string) uniformLocation {
|
func (c *context) getUniformLocationImpl(p program, location string) uniformLocation {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
return uniformLocation(gl.Call("getUniformLocation", p.value, location))
|
return uniformLocation(gl.getUniformLocation.Invoke(p.value, location))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) uniformInt(p program, location string, v int) bool {
|
func (c *context) uniformInt(p program, location string, v int) bool {
|
||||||
@ -361,7 +359,7 @@ func (c *context) uniformInt(p program, location string, v int) bool {
|
|||||||
if l.equal(invalidUniform) {
|
if l.equal(invalidUniform) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
gl.Call("uniform1i", js.Value(l), v)
|
gl.uniform1i.Invoke(js.Value(l), v)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,7 +369,7 @@ func (c *context) uniformFloat(p program, location string, v float32) bool {
|
|||||||
if l.equal(invalidUniform) {
|
if l.equal(invalidUniform) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
gl.Call("uniform1f", js.Value(l), v)
|
gl.uniform1f.Invoke(js.Value(l), v)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,45 +390,45 @@ func (c *context) uniformFloats(p program, location string, v []float32, typ sha
|
|||||||
switch base {
|
switch base {
|
||||||
case shaderir.Float:
|
case shaderir.Float:
|
||||||
if isWebGL2Available {
|
if isWebGL2Available {
|
||||||
gl.Call("uniform1fv", js.Value(l), arr, 0, len(v))
|
gl.uniform1fv.Invoke(js.Value(l), arr, 0, len(v))
|
||||||
} else {
|
} else {
|
||||||
gl.Call("uniform1fv", js.Value(l), arr.Call("subarray", 0, len(v)))
|
gl.uniform1fv.Invoke(js.Value(l), arr.Call("subarray", 0, len(v)))
|
||||||
}
|
}
|
||||||
case shaderir.Vec2:
|
case shaderir.Vec2:
|
||||||
if isWebGL2Available {
|
if isWebGL2Available {
|
||||||
gl.Call("uniform2fv", js.Value(l), arr, 0, len(v))
|
gl.uniform2fv.Invoke(js.Value(l), arr, 0, len(v))
|
||||||
} else {
|
} else {
|
||||||
gl.Call("uniform2fv", js.Value(l), arr.Call("subarray", 0, len(v)))
|
gl.uniform2fv.Invoke(js.Value(l), arr.Call("subarray", 0, len(v)))
|
||||||
}
|
}
|
||||||
case shaderir.Vec3:
|
case shaderir.Vec3:
|
||||||
if isWebGL2Available {
|
if isWebGL2Available {
|
||||||
gl.Call("uniform3fv", js.Value(l), arr, 0, len(v))
|
gl.uniform3fv.Invoke(js.Value(l), arr, 0, len(v))
|
||||||
} else {
|
} else {
|
||||||
gl.Call("uniform3fv", js.Value(l), arr.Call("subarray", 0, len(v)))
|
gl.uniform3fv.Invoke(js.Value(l), arr.Call("subarray", 0, len(v)))
|
||||||
}
|
}
|
||||||
case shaderir.Vec4:
|
case shaderir.Vec4:
|
||||||
if isWebGL2Available {
|
if isWebGL2Available {
|
||||||
gl.Call("uniform4fv", js.Value(l), arr, 0, len(v))
|
gl.uniform4fv.Invoke(js.Value(l), arr, 0, len(v))
|
||||||
} else {
|
} else {
|
||||||
gl.Call("uniform4fv", js.Value(l), arr.Call("subarray", 0, len(v)))
|
gl.uniform4fv.Invoke(js.Value(l), arr.Call("subarray", 0, len(v)))
|
||||||
}
|
}
|
||||||
case shaderir.Mat2:
|
case shaderir.Mat2:
|
||||||
if isWebGL2Available {
|
if isWebGL2Available {
|
||||||
gl.Call("uniformMatrix2fv", js.Value(l), false, arr, 0, len(v))
|
gl.uniformMatrix2fv.Invoke(js.Value(l), false, arr, 0, len(v))
|
||||||
} else {
|
} else {
|
||||||
gl.Call("uniformMatrix2fv", js.Value(l), false, arr.Call("subarray", 0, len(v)))
|
gl.uniformMatrix2fv.Invoke(js.Value(l), false, arr.Call("subarray", 0, len(v)))
|
||||||
}
|
}
|
||||||
case shaderir.Mat3:
|
case shaderir.Mat3:
|
||||||
if isWebGL2Available {
|
if isWebGL2Available {
|
||||||
gl.Call("uniformMatrix3fv", js.Value(l), false, arr, 0, len(v))
|
gl.uniformMatrix3fv.Invoke(js.Value(l), false, arr, 0, len(v))
|
||||||
} else {
|
} else {
|
||||||
gl.Call("uniformMatrix3fv", js.Value(l), false, arr.Call("subarray", 0, len(v)))
|
gl.uniformMatrix3fv.Invoke(js.Value(l), false, arr.Call("subarray", 0, len(v)))
|
||||||
}
|
}
|
||||||
case shaderir.Mat4:
|
case shaderir.Mat4:
|
||||||
if isWebGL2Available {
|
if isWebGL2Available {
|
||||||
gl.Call("uniformMatrix4fv", js.Value(l), false, arr, 0, len(v))
|
gl.uniformMatrix4fv.Invoke(js.Value(l), false, arr, 0, len(v))
|
||||||
} else {
|
} else {
|
||||||
gl.Call("uniformMatrix4fv", js.Value(l), false, arr.Call("subarray", 0, len(v)))
|
gl.uniformMatrix4fv.Invoke(js.Value(l), false, arr.Call("subarray", 0, len(v)))
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("opengl: unexpected type: %s", typ.String()))
|
panic(fmt.Sprintf("opengl: unexpected type: %s", typ.String()))
|
||||||
@ -441,43 +439,43 @@ func (c *context) uniformFloats(p program, location string, v []float32, typ sha
|
|||||||
|
|
||||||
func (c *context) vertexAttribPointer(index int, size int, stride int, offset int) {
|
func (c *context) vertexAttribPointer(index int, size int, stride int, offset int) {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
gl.Call("vertexAttribPointer", index, size, gles.FLOAT, false, stride, offset)
|
gl.vertexAttribPointer.Invoke(index, size, gles.FLOAT, false, stride, offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) enableVertexAttribArray(index int) {
|
func (c *context) enableVertexAttribArray(index int) {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
gl.Call("enableVertexAttribArray", index)
|
gl.enableVertexAttribArray.Invoke(index)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) disableVertexAttribArray(index int) {
|
func (c *context) disableVertexAttribArray(index int) {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
gl.Call("disableVertexAttribArray", index)
|
gl.disableVertexAttribArray.Invoke(index)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) newArrayBuffer(size int) buffer {
|
func (c *context) newArrayBuffer(size int) buffer {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
b := gl.Call("createBuffer")
|
b := gl.createBuffer.Invoke()
|
||||||
gl.Call("bindBuffer", gles.ARRAY_BUFFER, js.Value(b))
|
gl.bindBuffer.Invoke(gles.ARRAY_BUFFER, js.Value(b))
|
||||||
gl.Call("bufferData", gles.ARRAY_BUFFER, size, gles.DYNAMIC_DRAW)
|
gl.bufferData.Invoke(gles.ARRAY_BUFFER, size, gles.DYNAMIC_DRAW)
|
||||||
return buffer(b)
|
return buffer(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) newElementArrayBuffer(size int) buffer {
|
func (c *context) newElementArrayBuffer(size int) buffer {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
b := gl.Call("createBuffer")
|
b := gl.createBuffer.Invoke()
|
||||||
gl.Call("bindBuffer", gles.ELEMENT_ARRAY_BUFFER, js.Value(b))
|
gl.bindBuffer.Invoke(gles.ELEMENT_ARRAY_BUFFER, js.Value(b))
|
||||||
gl.Call("bufferData", gles.ELEMENT_ARRAY_BUFFER, size, gles.DYNAMIC_DRAW)
|
gl.bufferData.Invoke(gles.ELEMENT_ARRAY_BUFFER, size, gles.DYNAMIC_DRAW)
|
||||||
return buffer(b)
|
return buffer(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) bindArrayBuffer(b buffer) {
|
func (c *context) bindArrayBuffer(b buffer) {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
gl.Call("bindBuffer", gles.ARRAY_BUFFER, js.Value(b))
|
gl.bindBuffer.Invoke(gles.ARRAY_BUFFER, js.Value(b))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) bindElementArrayBuffer(b buffer) {
|
func (c *context) bindElementArrayBuffer(b buffer) {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
gl.Call("bindBuffer", gles.ELEMENT_ARRAY_BUFFER, js.Value(b))
|
gl.bindBuffer.Invoke(gles.ELEMENT_ARRAY_BUFFER, js.Value(b))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) arrayBufferSubData(data []float32) {
|
func (c *context) arrayBufferSubData(data []float32) {
|
||||||
@ -485,9 +483,9 @@ func (c *context) arrayBufferSubData(data []float32) {
|
|||||||
l := len(data) * 4
|
l := len(data) * 4
|
||||||
arr := jsutil.TemporaryUint8Array(l, data)
|
arr := jsutil.TemporaryUint8Array(l, data)
|
||||||
if isWebGL2Available {
|
if isWebGL2Available {
|
||||||
gl.Call("bufferSubData", gles.ARRAY_BUFFER, 0, arr, 0, l)
|
gl.bufferSubData.Invoke(gles.ARRAY_BUFFER, 0, arr, 0, l)
|
||||||
} else {
|
} else {
|
||||||
gl.Call("bufferSubData", gles.ARRAY_BUFFER, 0, arr.Call("subarray", 0, l))
|
gl.bufferSubData.Invoke(gles.ARRAY_BUFFER, 0, arr.Call("subarray", 0, l))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -496,35 +494,35 @@ func (c *context) elementArrayBufferSubData(data []uint16) {
|
|||||||
l := len(data) * 2
|
l := len(data) * 2
|
||||||
arr := jsutil.TemporaryUint8Array(l, data)
|
arr := jsutil.TemporaryUint8Array(l, data)
|
||||||
if isWebGL2Available {
|
if isWebGL2Available {
|
||||||
gl.Call("bufferSubData", gles.ELEMENT_ARRAY_BUFFER, 0, arr, 0, l)
|
gl.bufferSubData.Invoke(gles.ELEMENT_ARRAY_BUFFER, 0, arr, 0, l)
|
||||||
} else {
|
} else {
|
||||||
gl.Call("bufferSubData", gles.ELEMENT_ARRAY_BUFFER, 0, arr.Call("subarray", 0, l))
|
gl.bufferSubData.Invoke(gles.ELEMENT_ARRAY_BUFFER, 0, arr.Call("subarray", 0, l))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) deleteBuffer(b buffer) {
|
func (c *context) deleteBuffer(b buffer) {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
gl.Call("deleteBuffer", js.Value(b))
|
gl.deleteBuffer.Invoke(js.Value(b))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) drawElements(len int, offsetInBytes int) {
|
func (c *context) drawElements(len int, offsetInBytes int) {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
gl.Call("drawElements", gles.TRIANGLES, len, gles.UNSIGNED_SHORT, offsetInBytes)
|
gl.drawElements.Invoke(gles.TRIANGLES, len, gles.UNSIGNED_SHORT, offsetInBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) maxTextureSizeImpl() int {
|
func (c *context) maxTextureSizeImpl() int {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
return gl.Call("getParameter", gles.MAX_TEXTURE_SIZE).Int()
|
return gl.getParameter.Invoke(gles.MAX_TEXTURE_SIZE).Int()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) getShaderPrecisionFormatPrecision() int {
|
func (c *context) getShaderPrecisionFormatPrecision() int {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
return gl.Call("getShaderPrecisionFormat", gles.FRAGMENT_SHADER, gles.HIGH_FLOAT).Get("precision").Int()
|
return gl.getShaderPrecisionFormat.Invoke(gles.FRAGMENT_SHADER, gles.HIGH_FLOAT).Get("precision").Int()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) flush() {
|
func (c *context) flush() {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
gl.Call("flush")
|
gl.flush.Invoke()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) needsRestoring() bool {
|
func (c *context) needsRestoring() bool {
|
||||||
@ -544,22 +542,22 @@ func (c *context) texSubImage2D(t textureNative, width, height int, args []*driv
|
|||||||
// void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
|
// void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
|
||||||
// GLsizei width, GLsizei height,
|
// GLsizei width, GLsizei height,
|
||||||
// GLenum format, GLenum type, ArrayBufferView pixels, srcOffset);
|
// GLenum format, GLenum type, ArrayBufferView pixels, srcOffset);
|
||||||
gl.Call("texSubImage2D", gles.TEXTURE_2D, 0, a.X, a.Y, a.Width, a.Height, gles.RGBA, gles.UNSIGNED_BYTE, arr, 0)
|
gl.texSubImage2D.Invoke(gles.TEXTURE_2D, 0, a.X, a.Y, a.Width, a.Height, gles.RGBA, gles.UNSIGNED_BYTE, arr, 0)
|
||||||
} else {
|
} else {
|
||||||
// void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
|
// void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
|
||||||
// GLsizei width, GLsizei height,
|
// GLsizei width, GLsizei height,
|
||||||
// GLenum format, GLenum type, ArrayBufferView? pixels);
|
// GLenum format, GLenum type, ArrayBufferView? pixels);
|
||||||
gl.Call("texSubImage2D", gles.TEXTURE_2D, 0, a.X, a.Y, a.Width, a.Height, gles.RGBA, gles.UNSIGNED_BYTE, arr)
|
gl.texSubImage2D.Invoke(gles.TEXTURE_2D, 0, a.X, a.Y, a.Width, a.Height, gles.RGBA, gles.UNSIGNED_BYTE, arr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) newPixelBufferObject(width, height int) buffer {
|
func (c *context) newPixelBufferObject(width, height int) buffer {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
b := gl.Call("createBuffer")
|
b := gl.createBuffer.Invoke()
|
||||||
gl.Call("bindBuffer", gles.PIXEL_UNPACK_BUFFER, js.Value(b))
|
gl.bindBuffer.Invoke(gles.PIXEL_UNPACK_BUFFER, js.Value(b))
|
||||||
gl.Call("bufferData", gles.PIXEL_UNPACK_BUFFER, 4*width*height, gles.STREAM_DRAW)
|
gl.bufferData.Invoke(gles.PIXEL_UNPACK_BUFFER, 4*width*height, gles.STREAM_DRAW)
|
||||||
gl.Call("bindBuffer", gles.PIXEL_UNPACK_BUFFER, nil)
|
gl.bindBuffer.Invoke(gles.PIXEL_UNPACK_BUFFER, nil)
|
||||||
return buffer(b)
|
return buffer(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -570,34 +568,34 @@ func (c *context) replacePixelsWithPBO(buffer buffer, t textureNative, width, he
|
|||||||
|
|
||||||
c.bindTexture(t)
|
c.bindTexture(t)
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
gl.Call("bindBuffer", gles.PIXEL_UNPACK_BUFFER, js.Value(buffer))
|
gl.bindBuffer.Invoke(gles.PIXEL_UNPACK_BUFFER, js.Value(buffer))
|
||||||
|
|
||||||
stride := 4 * width
|
stride := 4 * width
|
||||||
for _, a := range args {
|
for _, a := range args {
|
||||||
arr := jsutil.TemporaryUint8Array(len(a.Pixels), a.Pixels)
|
arr := jsutil.TemporaryUint8Array(len(a.Pixels), a.Pixels)
|
||||||
offset := 4 * (a.Y*width + a.X)
|
offset := 4 * (a.Y*width + a.X)
|
||||||
for j := 0; j < a.Height; j++ {
|
for j := 0; j < a.Height; j++ {
|
||||||
gl.Call("bufferSubData", gles.PIXEL_UNPACK_BUFFER, offset+stride*j, arr, 4*a.Width*j, 4*a.Width)
|
gl.bufferSubData.Invoke(gles.PIXEL_UNPACK_BUFFER, offset+stride*j, arr, 4*a.Width*j, 4*a.Width)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
|
// void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
|
||||||
// GLsizei width, GLsizei height,
|
// GLsizei width, GLsizei height,
|
||||||
// GLenum format, GLenum type, GLintptr offset);
|
// GLenum format, GLenum type, GLintptr offset);
|
||||||
gl.Call("texSubImage2D", gles.TEXTURE_2D, 0, 0, 0, width, height, gles.RGBA, gles.UNSIGNED_BYTE, 0)
|
gl.texSubImage2D.Invoke(gles.TEXTURE_2D, 0, 0, 0, width, height, gles.RGBA, gles.UNSIGNED_BYTE, 0)
|
||||||
gl.Call("bindBuffer", gles.PIXEL_UNPACK_BUFFER, nil)
|
gl.bindBuffer.Invoke(gles.PIXEL_UNPACK_BUFFER, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) getBufferSubData(buffer buffer, width, height int) []byte {
|
func (c *context) getBufferSubData(buffer buffer, width, height int) []byte {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
gl.Call("bindBuffer", gles.PIXEL_UNPACK_BUFFER, js.Value(buffer))
|
gl.bindBuffer.Invoke(gles.PIXEL_UNPACK_BUFFER, js.Value(buffer))
|
||||||
l := 4 * width * height
|
l := 4 * width * height
|
||||||
arr := jsutil.TemporaryUint8Array(l, nil)
|
arr := jsutil.TemporaryUint8Array(l, nil)
|
||||||
if isWebGL2Available {
|
if isWebGL2Available {
|
||||||
gl.Call("getBufferSubData", gles.PIXEL_UNPACK_BUFFER, 0, arr, 0, l)
|
gl.getBufferSubData.Invoke(gles.PIXEL_UNPACK_BUFFER, 0, arr, 0, l)
|
||||||
} else {
|
} else {
|
||||||
gl.Call("getBufferSubData", gles.PIXEL_UNPACK_BUFFER, 0, arr.Call("subarray", 0, l))
|
gl.getBufferSubData.Invoke(gles.PIXEL_UNPACK_BUFFER, 0, arr.Call("subarray", 0, l))
|
||||||
}
|
}
|
||||||
gl.Call("bindBuffer", gles.PIXEL_UNPACK_BUFFER, nil)
|
gl.bindBuffer.Invoke(gles.PIXEL_UNPACK_BUFFER, nil)
|
||||||
return jsutil.Uint8ArrayToSlice(arr, l)
|
return jsutil.Uint8ArrayToSlice(arr, l)
|
||||||
}
|
}
|
||||||
|
152
internal/graphicsdriver/opengl/gl_js.go
Normal file
152
internal/graphicsdriver/opengl/gl_js.go
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
// Copyright 2021 The Ebiten Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package opengl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall/js"
|
||||||
|
)
|
||||||
|
|
||||||
|
type gl struct {
|
||||||
|
activeTexture js.Value
|
||||||
|
attachShader js.Value
|
||||||
|
bindAttribLocation js.Value
|
||||||
|
bindBuffer js.Value
|
||||||
|
bindFramebuffer js.Value
|
||||||
|
bindTexture js.Value
|
||||||
|
blendFunc js.Value
|
||||||
|
bufferData js.Value
|
||||||
|
bufferSubData js.Value
|
||||||
|
checkFramebufferStatus js.Value
|
||||||
|
compileShader js.Value
|
||||||
|
createBuffer js.Value
|
||||||
|
createFramebuffer js.Value
|
||||||
|
createProgram js.Value
|
||||||
|
createShader js.Value
|
||||||
|
createTexture js.Value
|
||||||
|
deleteBuffer js.Value
|
||||||
|
deleteFramebuffer js.Value
|
||||||
|
deleteProgram js.Value
|
||||||
|
deleteShader js.Value
|
||||||
|
deleteTexture js.Value
|
||||||
|
disableVertexAttribArray js.Value
|
||||||
|
drawElements js.Value
|
||||||
|
enable js.Value
|
||||||
|
enableVertexAttribArray js.Value
|
||||||
|
framebufferTexture2D js.Value
|
||||||
|
flush js.Value
|
||||||
|
getBufferSubData js.Value
|
||||||
|
getExtension js.Value
|
||||||
|
getParameter js.Value
|
||||||
|
getProgramInfoLog js.Value
|
||||||
|
getProgramParameter js.Value
|
||||||
|
getShaderInfoLog js.Value
|
||||||
|
getShaderParameter js.Value
|
||||||
|
getShaderPrecisionFormat js.Value
|
||||||
|
getUniformLocation js.Value
|
||||||
|
isContextLost js.Value
|
||||||
|
isFramebuffer js.Value
|
||||||
|
isProgram js.Value
|
||||||
|
isTexture js.Value
|
||||||
|
linkProgram js.Value
|
||||||
|
pixelStorei js.Value
|
||||||
|
readPixels js.Value
|
||||||
|
scissor js.Value
|
||||||
|
shaderSource js.Value
|
||||||
|
texImage2D js.Value
|
||||||
|
texSubImage2D js.Value
|
||||||
|
texParameteri js.Value
|
||||||
|
uniform1f js.Value
|
||||||
|
uniform1fv js.Value
|
||||||
|
uniform2fv js.Value
|
||||||
|
uniform3fv js.Value
|
||||||
|
uniform4fv js.Value
|
||||||
|
uniform1i js.Value
|
||||||
|
uniformMatrix2fv js.Value
|
||||||
|
uniformMatrix3fv js.Value
|
||||||
|
uniformMatrix4fv js.Value
|
||||||
|
useProgram js.Value
|
||||||
|
vertexAttribPointer js.Value
|
||||||
|
viewport js.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func newGL(v js.Value) *gl {
|
||||||
|
// Passing a Go string to the JS world is expensive. This causes conversion to UTF-16 (#1438).
|
||||||
|
// In order to reduce the cost when calling functions, create the function objects by bind and use them.
|
||||||
|
g := &gl{
|
||||||
|
activeTexture: v.Get("activeTexture").Call("bind", v),
|
||||||
|
attachShader: v.Get("attachShader").Call("bind", v),
|
||||||
|
bindAttribLocation: v.Get("bindAttribLocation").Call("bind", v),
|
||||||
|
bindBuffer: v.Get("bindBuffer").Call("bind", v),
|
||||||
|
bindFramebuffer: v.Get("bindFramebuffer").Call("bind", v),
|
||||||
|
bindTexture: v.Get("bindTexture").Call("bind", v),
|
||||||
|
blendFunc: v.Get("blendFunc").Call("bind", v),
|
||||||
|
bufferData: v.Get("bufferData").Call("bind", v),
|
||||||
|
bufferSubData: v.Get("bufferSubData").Call("bind", v),
|
||||||
|
checkFramebufferStatus: v.Get("checkFramebufferStatus").Call("bind", v),
|
||||||
|
compileShader: v.Get("compileShader").Call("bind", v),
|
||||||
|
createBuffer: v.Get("createBuffer").Call("bind", v),
|
||||||
|
createFramebuffer: v.Get("createFramebuffer").Call("bind", v),
|
||||||
|
createProgram: v.Get("createProgram").Call("bind", v),
|
||||||
|
createShader: v.Get("createShader").Call("bind", v),
|
||||||
|
createTexture: v.Get("createTexture").Call("bind", v),
|
||||||
|
deleteBuffer: v.Get("deleteBuffer").Call("bind", v),
|
||||||
|
deleteFramebuffer: v.Get("deleteFramebuffer").Call("bind", v),
|
||||||
|
deleteProgram: v.Get("deleteProgram").Call("bind", v),
|
||||||
|
deleteShader: v.Get("deleteShader").Call("bind", v),
|
||||||
|
deleteTexture: v.Get("deleteTexture").Call("bind", v),
|
||||||
|
disableVertexAttribArray: v.Get("disableVertexAttribArray").Call("bind", v),
|
||||||
|
drawElements: v.Get("drawElements").Call("bind", v),
|
||||||
|
enable: v.Get("enable").Call("bind", v),
|
||||||
|
enableVertexAttribArray: v.Get("enableVertexAttribArray").Call("bind", v),
|
||||||
|
framebufferTexture2D: v.Get("framebufferTexture2D").Call("bind", v),
|
||||||
|
flush: v.Get("flush").Call("bind", v),
|
||||||
|
getBufferSubData: v.Get("getBufferSubData").Call("bind", v),
|
||||||
|
getParameter: v.Get("getParameter").Call("bind", v),
|
||||||
|
getProgramInfoLog: v.Get("getProgramInfoLog").Call("bind", v),
|
||||||
|
getProgramParameter: v.Get("getProgramParameter").Call("bind", v),
|
||||||
|
getShaderInfoLog: v.Get("getShaderInfoLog").Call("bind", v),
|
||||||
|
getShaderParameter: v.Get("getShaderParameter").Call("bind", v),
|
||||||
|
getShaderPrecisionFormat: v.Get("getShaderPrecisionFormat").Call("bind", v),
|
||||||
|
getUniformLocation: v.Get("getUniformLocation").Call("bind", v),
|
||||||
|
isContextLost: v.Get("isContextLost").Call("bind", v),
|
||||||
|
isFramebuffer: v.Get("isFramebuffer").Call("bind", v),
|
||||||
|
isProgram: v.Get("isProgram").Call("bind", v),
|
||||||
|
isTexture: v.Get("isTexture").Call("bind", v),
|
||||||
|
linkProgram: v.Get("linkProgram").Call("bind", v),
|
||||||
|
pixelStorei: v.Get("pixelStorei").Call("bind", v),
|
||||||
|
readPixels: v.Get("readPixels").Call("bind", v),
|
||||||
|
scissor: v.Get("scissor").Call("bind", v),
|
||||||
|
shaderSource: v.Get("shaderSource").Call("bind", v),
|
||||||
|
texImage2D: v.Get("texImage2D").Call("bind", v),
|
||||||
|
texSubImage2D: v.Get("texSubImage2D").Call("bind", v),
|
||||||
|
texParameteri: v.Get("texParameteri").Call("bind", v),
|
||||||
|
uniform1f: v.Get("uniform1f").Call("bind", v),
|
||||||
|
uniform1fv: v.Get("uniform1fv").Call("bind", v),
|
||||||
|
uniform2fv: v.Get("uniform2fv").Call("bind", v),
|
||||||
|
uniform3fv: v.Get("uniform3fv").Call("bind", v),
|
||||||
|
uniform4fv: v.Get("uniform4fv").Call("bind", v),
|
||||||
|
uniform1i: v.Get("uniform1i").Call("bind", v),
|
||||||
|
uniformMatrix2fv: v.Get("uniformMatrix2fv").Call("bind", v),
|
||||||
|
uniformMatrix3fv: v.Get("uniformMatrix3fv").Call("bind", v),
|
||||||
|
uniformMatrix4fv: v.Get("uniformMatrix4fv").Call("bind", v),
|
||||||
|
useProgram: v.Get("useProgram").Call("bind", v),
|
||||||
|
vertexAttribPointer: v.Get("vertexAttribPointer").Call("bind", v),
|
||||||
|
viewport: v.Get("viewport").Call("bind", v),
|
||||||
|
}
|
||||||
|
if !isWebGL2Available {
|
||||||
|
g.getExtension = v.Get("getExtension").Call("bind", v)
|
||||||
|
}
|
||||||
|
return g
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user