diff --git a/internal/graphicsdriver/opengl/context_gl.go b/internal/graphicsdriver/opengl/context_gl.go deleted file mode 100644 index 1bfa8f636..000000000 --- a/internal/graphicsdriver/opengl/context_gl.go +++ /dev/null @@ -1,502 +0,0 @@ -// Copyright 2014 Hajime Hoshi -// -// 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. - -//go:build !android && !ios && !js && !opengles - -package opengl - -import ( - "errors" - "fmt" - - "github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver" - "github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl/gl" - "github.com/hajimehoshi/ebiten/v2/internal/shaderir" -) - -type ( - textureNative uint32 - renderbufferNative uint32 - framebufferNative uint32 - shader uint32 - program uint32 - buffer uint32 -) - -func (t textureNative) equal(rhs textureNative) bool { - return t == rhs -} - -func (r renderbufferNative) equal(rhs renderbufferNative) bool { - return r == rhs -} - -func (f framebufferNative) equal(rhs framebufferNative) bool { - return f == rhs -} - -func (s shader) equal(rhs shader) bool { - return s == rhs -} - -func (b buffer) equal(rhs buffer) bool { - return b == rhs -} - -func (u uniformLocation) equal(rhs uniformLocation) bool { - return u == rhs -} - -func (p program) equal(rhs program) bool { - return p == rhs -} - -var InvalidTexture textureNative - -type ( - uniformLocation int32 - attribLocation int32 -) - -type programID uint32 - -const ( - invalidTexture = 0 - invalidFramebuffer = (1 << 32) - 1 - invalidUniform = -1 -) - -func getProgramID(p program) programID { - return programID(p) -} - -type contextImpl struct { - init bool -} - -func (c *context) reset() error { - if !c.init { - // Initialize OpenGL after WGL is initialized especially for Windows (#2452). - if err := gl.Init(); err != nil { - return err - } - c.init = true - } - - c.locationCache = newLocationCache() - c.lastTexture = invalidTexture - c.lastFramebuffer = invalidFramebuffer - c.lastViewportWidth = 0 - c.lastViewportHeight = 0 - c.lastBlend = graphicsdriver.Blend{} - gl.Enable(gl.BLEND) - gl.Enable(gl.SCISSOR_TEST) - - // Set the source over blending. - c.blend(graphicsdriver.BlendSourceOver) - - f := int32(0) - gl.GetIntegerv(gl.FRAMEBUFFER_BINDING, &f) - c.screenFramebuffer = framebufferNative(f) - return nil -} - -func (c *context) blend(blend graphicsdriver.Blend) { - if c.lastBlend == blend { - return - } - c.lastBlend = blend - gl.BlendFuncSeparate( - uint32(convertBlendFactor(blend.BlendFactorSourceRGB)), - uint32(convertBlendFactor(blend.BlendFactorDestinationRGB)), - uint32(convertBlendFactor(blend.BlendFactorSourceAlpha)), - uint32(convertBlendFactor(blend.BlendFactorDestinationAlpha)), - ) - gl.BlendEquationSeparate( - uint32(convertBlendOperation(blend.BlendOperationRGB)), - uint32(convertBlendOperation(blend.BlendOperationAlpha)), - ) -} - -func (c *context) scissor(x, y, width, height int) { - gl.Scissor(int32(x), int32(y), int32(width), int32(height)) -} - -func (c *context) newTexture(width, height int) (textureNative, error) { - var t uint32 - gl.GenTextures(1, &t) - // TODO: Use gl.IsTexture - if t <= 0 { - return 0, errors.New("opengl: creating texture failed") - } - texture := textureNative(t) - c.bindTexture(texture) - - gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST) - gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST) - gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE) - gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE) - - gl.PixelStorei(gl.UNPACK_ALIGNMENT, 4) - // If data is nil, this just allocates memory and the content is undefined. - // https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glTexImage2D.xhtml - gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int32(width), int32(height), 0, gl.RGBA, gl.UNSIGNED_BYTE, nil) - return texture, nil -} - -func (c *context) bindFramebufferImpl(f framebufferNative) { - gl.BindFramebufferEXT(gl.FRAMEBUFFER, uint32(f)) -} - -func (c *context) framebufferPixels(buf []byte, f *framebuffer, x, y, width, height int) { - gl.Flush() - c.bindFramebuffer(f.native) - gl.ReadPixels(int32(x), int32(y), int32(width), int32(height), gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(buf)) -} - -func (c *context) framebufferPixelsToBuffer(f *framebuffer, buffer buffer, width, height int) { - gl.Flush() - c.bindFramebuffer(f.native) - gl.BindBuffer(gl.PIXEL_PACK_BUFFER, uint32(buffer)) - gl.ReadPixels(0, 0, int32(width), int32(height), gl.RGBA, gl.UNSIGNED_BYTE, nil) - gl.BindBuffer(gl.PIXEL_PACK_BUFFER, 0) -} - -func (c *context) activeTexture(idx int) { - gl.ActiveTexture(gl.TEXTURE0 + uint32(idx)) -} - -func (c *context) bindTextureImpl(t textureNative) { - gl.BindTexture(gl.TEXTURE_2D, uint32(t)) -} - -func (c *context) deleteTexture(t textureNative) { - tt := uint32(t) - if !gl.IsTexture(tt) { - return - } - if c.lastTexture == t { - c.lastTexture = invalidTexture - } - gl.DeleteTextures(1, &tt) -} - -func (c *context) isTexture(t textureNative) bool { - panic("opengl: isTexture is not implemented") -} - -func (c *context) newRenderbuffer(width, height int) (renderbufferNative, error) { - var r uint32 - gl.GenRenderbuffersEXT(1, &r) - if r <= 0 { - return 0, errors.New("opengl: creating renderbuffer failed") - } - - renderbuffer := renderbufferNative(r) - c.bindRenderbuffer(renderbuffer) - - // GL_STENCIL_INDEX8 might not be available with OpenGL 2.1. - // https://www.khronos.org/opengl/wiki/Image_Format - gl.RenderbufferStorageEXT(gl.RENDERBUFFER, gl.DEPTH24_STENCIL8, int32(width), int32(height)) - - return renderbuffer, nil -} - -func (c *context) bindRenderbufferImpl(r renderbufferNative) { - gl.BindRenderbufferEXT(gl.RENDERBUFFER, uint32(r)) -} - -func (c *context) deleteRenderbuffer(r renderbufferNative) { - rr := uint32(r) - if !gl.IsRenderbufferEXT(rr) { - return - } - if c.lastRenderbuffer.equal(r) { - c.lastRenderbuffer = 0 - } - gl.DeleteRenderbuffersEXT(1, &rr) -} - -func (c *context) newFramebuffer(texture textureNative) (framebufferNative, error) { - var f uint32 - gl.GenFramebuffersEXT(1, &f) - if f <= 0 { - return 0, errors.New("opengl: creating framebuffer failed") - } - c.bindFramebuffer(framebufferNative(f)) - gl.FramebufferTexture2DEXT(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, uint32(texture), 0) - s := gl.CheckFramebufferStatusEXT(gl.FRAMEBUFFER) - if s != gl.FRAMEBUFFER_COMPLETE { - if s != 0 { - return 0, fmt.Errorf("opengl: creating framebuffer failed: %v", s) - } - if e := gl.GetError(); e != gl.NO_ERROR { - return 0, fmt.Errorf("opengl: creating framebuffer failed: (glGetError) %d", e) - } - return 0, fmt.Errorf("opengl: creating framebuffer failed: unknown error") - } - return framebufferNative(f), nil -} - -func (c *context) bindStencilBuffer(f framebufferNative, r renderbufferNative) error { - c.bindFramebuffer(f) - - gl.FramebufferRenderbufferEXT(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, uint32(r)) - if s := gl.CheckFramebufferStatusEXT(gl.FRAMEBUFFER); s != gl.FRAMEBUFFER_COMPLETE { - return errors.New(fmt.Sprintf("opengl: glFramebufferRenderbuffer failed: %d", s)) - } - return nil -} - -func (c *context) setViewportImpl(width, height int) { - gl.Viewport(0, 0, int32(width), int32(height)) -} - -func (c *context) deleteFramebuffer(f framebufferNative) { - ff := uint32(f) - if !gl.IsFramebufferEXT(ff) { - return - } - if c.lastFramebuffer == f { - c.lastFramebuffer = invalidFramebuffer - c.lastViewportWidth = 0 - c.lastViewportHeight = 0 - } - gl.DeleteFramebuffersEXT(1, &ff) -} - -func (c *context) newVertexShader(source string) (shader, error) { - return c.newShader(gl.VERTEX_SHADER, source) -} - -func (c *context) newFragmentShader(source string) (shader, error) { - return c.newShader(gl.FRAGMENT_SHADER, source) -} - -func (c *context) newShader(shaderType uint32, source string) (shader, error) { - s := gl.CreateShader(shaderType) - if s == 0 { - return 0, fmt.Errorf("opengl: glCreateShader failed: shader type: %d", shaderType) - } - cSources, free := gl.CStr(source) - gl.ShaderSource(uint32(s), 1, &cSources, nil) - free() - gl.CompileShader(s) - - var v int32 - gl.GetShaderiv(s, gl.COMPILE_STATUS, &v) - if v == gl.FALSE { - var l int32 - var log []byte - gl.GetShaderiv(uint32(s), gl.INFO_LOG_LENGTH, &l) - if l != 0 { - log = make([]byte, l) - gl.GetShaderInfoLog(s, l, nil, (*uint8)(gl.Ptr(log))) - } - return 0, fmt.Errorf("opengl: shader compile failed: %s", log) - } - return shader(s), nil -} - -func (c *context) deleteShader(s shader) { - gl.DeleteShader(uint32(s)) -} - -func (c *context) newProgram(shaders []shader, attributes []string) (program, error) { - p := gl.CreateProgram() - if p == 0 { - return 0, errors.New("opengl: glCreateProgram failed") - } - - for _, shader := range shaders { - gl.AttachShader(p, uint32(shader)) - } - - for i, name := range attributes { - l, free := gl.CStr(name) - gl.BindAttribLocation(p, uint32(i), l) - free() - } - - gl.LinkProgram(p) - var v int32 - gl.GetProgramiv(p, gl.LINK_STATUS, &v) - if v == gl.FALSE { - var l int32 - var log []byte - gl.GetProgramiv(p, gl.INFO_LOG_LENGTH, &l) - if l != 0 { - log = make([]byte, l) - gl.GetProgramInfoLog(p, l, nil, (*uint8)(gl.Ptr(log))) - } - return 0, fmt.Errorf("opengl: program error: %s", log) - } - return program(p), nil -} - -func (c *context) useProgram(p program) { - gl.UseProgram(uint32(p)) -} - -func (c *context) deleteProgram(p program) { - c.locationCache.deleteProgram(p) - - if !gl.IsProgram(uint32(p)) { - return - } - gl.DeleteProgram(uint32(p)) -} - -func (c *context) getUniformLocationImpl(p program, location string) uniformLocation { - l, free := gl.CStr(location) - uniform := uniformLocation(gl.GetUniformLocation(uint32(p), l)) - free() - return uniform -} - -func (c *context) uniformInt(p program, location string, v int) bool { - l := int32(c.locationCache.GetUniformLocation(c, p, location)) - if l == invalidUniform { - return false - } - gl.Uniform1i(l, int32(v)) - return true -} - -func (c *context) uniforms(p program, location string, v []uint32, typ shaderir.Type) bool { - l := int32(c.locationCache.GetUniformLocation(c, p, location)) - if l == invalidUniform { - return false - } - - base := typ.Main - len := int32(1) - if base == shaderir.Array { - base = typ.Sub[0].Main - len = int32(typ.Length) - } - - switch base { - case shaderir.Float: - gl.Uniform1fv(l, len, (*float32)(gl.Ptr(v))) - case shaderir.Int: - gl.Uniform1iv(l, len, (*int32)(gl.Ptr(v))) - case shaderir.Vec2: - gl.Uniform2fv(l, len, (*float32)(gl.Ptr(v))) - case shaderir.Vec3: - gl.Uniform3fv(l, len, (*float32)(gl.Ptr(v))) - case shaderir.Vec4: - gl.Uniform4fv(l, len, (*float32)(gl.Ptr(v))) - case shaderir.Mat2: - gl.UniformMatrix2fv(l, len, false, (*float32)(gl.Ptr(v))) - case shaderir.Mat3: - gl.UniformMatrix3fv(l, len, false, (*float32)(gl.Ptr(v))) - case shaderir.Mat4: - gl.UniformMatrix4fv(l, len, false, (*float32)(gl.Ptr(v))) - default: - panic(fmt.Sprintf("opengl: unexpected type: %s", typ.String())) - } - return true -} - -func (c *context) vertexAttribPointer(index int, size int, stride int, offset int) { - gl.VertexAttribPointer(uint32(index), int32(size), gl.FLOAT, false, int32(stride), uintptr(offset)) -} - -func (c *context) enableVertexAttribArray(index int) { - gl.EnableVertexAttribArray(uint32(index)) -} - -func (c *context) disableVertexAttribArray(index int) { - gl.DisableVertexAttribArray(uint32(index)) -} - -func (c *context) newArrayBuffer(size int) buffer { - var b uint32 - gl.GenBuffers(1, &b) - gl.BindBuffer(gl.ARRAY_BUFFER, b) - gl.BufferData(gl.ARRAY_BUFFER, size, nil, gl.DYNAMIC_DRAW) - return buffer(b) -} - -func (c *context) newElementArrayBuffer(size int) buffer { - var b uint32 - gl.GenBuffers(1, &b) - gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, b) - gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, size, nil, gl.DYNAMIC_DRAW) - return buffer(b) -} - -func (c *context) bindArrayBuffer(b buffer) { - gl.BindBuffer(gl.ARRAY_BUFFER, uint32(b)) -} - -func (c *context) bindElementArrayBuffer(b buffer) { - gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, uint32(b)) -} - -func (c *context) arrayBufferSubData(data []float32) { - gl.BufferSubData(gl.ARRAY_BUFFER, 0, len(data)*4, gl.Ptr(data)) -} - -func (c *context) elementArrayBufferSubData(data []uint16) { - gl.BufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, len(data)*2, gl.Ptr(data)) -} - -func (c *context) deleteBuffer(b buffer) { - bb := uint32(b) - gl.DeleteBuffers(1, &bb) -} - -func (c *context) drawElements(len int, offsetInBytes int) { - gl.DrawElements(gl.TRIANGLES, int32(len), gl.UNSIGNED_SHORT, uintptr(offsetInBytes)) -} - -func (c *context) maxTextureSizeImpl() int { - s := int32(0) - gl.GetIntegerv(gl.MAX_TEXTURE_SIZE, &s) - return int(s) -} - -func (c *context) flush() { - gl.Flush() -} - -func (c *context) texSubImage2D(t textureNative, args []*graphicsdriver.WritePixelsArgs) { - c.bindTexture(t) - for _, a := range args { - gl.TexSubImage2D(gl.TEXTURE_2D, 0, int32(a.X), int32(a.Y), int32(a.Width), int32(a.Height), gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(a.Pixels)) - } -} - -func (c *context) enableStencilTest() { - gl.Enable(gl.STENCIL_TEST) -} - -func (c *context) disableStencilTest() { - gl.Disable(gl.STENCIL_TEST) -} - -func (c *context) beginStencilWithEvenOddRule() { - gl.Clear(gl.STENCIL_BUFFER_BIT) - gl.StencilFunc(gl.ALWAYS, 0x00, 0xff) - gl.StencilOp(gl.KEEP, gl.KEEP, gl.INVERT) - gl.ColorMask(false, false, false, false) -} - -func (c *context) endStencilWithEvenOddRule() { - gl.StencilFunc(gl.NOTEQUAL, 0x00, 0xff) - gl.StencilOp(gl.KEEP, gl.KEEP, gl.KEEP) - gl.ColorMask(true, true, true, true) -} diff --git a/internal/graphicsdriver/opengl/context_gles.go b/internal/graphicsdriver/opengl/context_notjs.go similarity index 98% rename from internal/graphicsdriver/opengl/context_gles.go rename to internal/graphicsdriver/opengl/context_notjs.go index a52350eef..514483345 100644 --- a/internal/graphicsdriver/opengl/context_gles.go +++ b/internal/graphicsdriver/opengl/context_notjs.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:build (android || ios || opengles) && !js +//go:build !js package opengl @@ -83,10 +83,19 @@ func getProgramID(p program) programID { } type contextImpl struct { - ctx gl.Context + ctx gl.Context + init bool } func (c *context) reset() error { + if !c.init { + // Initialize OpenGL after WGL is initialized especially for Windows (#2452). + if err := c.ctx.Init(); err != nil { + return err + } + c.init = true + } + c.locationCache = newLocationCache() c.lastTexture = invalidTexture c.lastFramebuffer = invalidFramebuffer diff --git a/internal/graphicsdriver/opengl/gl/conversions.go b/internal/graphicsdriver/opengl/gl/conversions.go deleted file mode 100644 index b9593fcae..000000000 --- a/internal/graphicsdriver/opengl/gl/conversions.go +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: MIT - -//go:build !android && !ios && !js && !opengles - -package gl - -import ( - "fmt" - "unsafe" -) - -// Ptr takes a slice or pointer (to a singular scalar value or the first -// element of an array or slice) and returns its GL-compatible address. -// -// For example: -// -// var data []byte -// ... -// gl.TexImage2D(gl.TEXTURE_2D, ..., gl.UNSIGNED_BYTE, gl.Ptr(&data[0])) -func Ptr(data any) unsafe.Pointer { - if data == nil { - return unsafe.Pointer(nil) - } - var addr unsafe.Pointer - switch v := data.(type) { - case *uint8: - addr = unsafe.Pointer(v) - case *uint16: - addr = unsafe.Pointer(v) - case *float32: - addr = unsafe.Pointer(v) - case []uint8: - addr = unsafe.Pointer(&v[0]) - case []uint16: - addr = unsafe.Pointer(&v[0]) - case []uint32: - addr = unsafe.Pointer(&v[0]) - case []float32: - addr = unsafe.Pointer(&v[0]) - default: - panic(fmt.Errorf("unsupported type %T; must be a slice or pointer to a singular scalar value or the first element of an array or slice", v)) - } - return addr -} diff --git a/internal/graphicsdriver/opengl/gl/conversions_cgo.go b/internal/graphicsdriver/opengl/gl/conversions_cgo.go index eaa8f33d0..3e7214403 100644 --- a/internal/graphicsdriver/opengl/gl/conversions_cgo.go +++ b/internal/graphicsdriver/opengl/gl/conversions_cgo.go @@ -1,4 +1,5 @@ // SPDX-License-Identifier: MIT +// SPDX-FileCopyrightText: 2014 Eric Woroshow //go:build !android && !darwin && !js && !windows && !opengles @@ -11,18 +12,12 @@ import ( // #include import "C" -// GoStr takes a null-terminated string returned by OpenGL and constructs a -// corresponding Go string. -func GoStr(cstr *byte) string { - return C.GoString((*C.char)(unsafe.Pointer(cstr))) -} - -// CStr takes a Go string (with or without null-termination) +// cStr takes a Go string (with or without null-termination) // and returns the C counterpart. // // The returned free function must be called once you are done using the string // in order to free the memory. -func CStr(str string) (cstr *byte, free func()) { +func cStr(str string) (cstr *byte, free func()) { cs := C.CString(str) return (*byte)(unsafe.Pointer(cs)), func() { C.free(unsafe.Pointer(cs)) diff --git a/internal/graphicsdriver/opengl/gl/conversions_nocgo.go b/internal/graphicsdriver/opengl/gl/conversions_nocgo.go index 22ab636f7..9550ab480 100644 --- a/internal/graphicsdriver/opengl/gl/conversions_nocgo.go +++ b/internal/graphicsdriver/opengl/gl/conversions_nocgo.go @@ -1,4 +1,5 @@ // SPDX-License-Identifier: MIT +// SPDX-FileCopyrightText: 2014 Eric Woroshow //go:build darwin || windows @@ -6,30 +7,14 @@ package gl import ( "runtime" - "unsafe" ) -// GoStr takes a null-terminated string returned by OpenGL and constructs a -// corresponding Go string. -func GoStr(cstr *byte) string { - if cstr == nil { - return "" - } - x := unsafe.Slice(cstr, 1e9) - for i, c := range x { - if c == 0 { - return string(x[:i]) - } - } - return "" -} - -// CStr takes a Go string (with or without null-termination) +// cStr takes a Go string (with or without null-termination) // and returns the C counterpart. // // The returned free function must be called once you are done using the string // in order to free the memory. -func CStr(str string) (cstr *byte, free func()) { +func cStr(str string) (cstr *byte, free func()) { bs := []byte(str) if len(bs) == 0 || bs[len(bs)-1] != 0 { bs = append(bs, 0) diff --git a/internal/graphicsdriver/opengl/gl/default.go b/internal/graphicsdriver/opengl/gl/default_gles.go similarity index 99% rename from internal/graphicsdriver/opengl/gl/default.go rename to internal/graphicsdriver/opengl/gl/default_gles.go index a3d22ad01..cf70e3b46 100644 --- a/internal/graphicsdriver/opengl/gl/default.go +++ b/internal/graphicsdriver/opengl/gl/default_gles.go @@ -51,6 +51,10 @@ func NewDefaultContext() Context { return defaultContext{} } +func (defaultContext) Init() error { + return nil +} + func (defaultContext) ActiveTexture(texture uint32) { C.glActiveTexture(C.GLenum(texture)) } diff --git a/internal/graphicsdriver/opengl/gl/package_notpurego.go b/internal/graphicsdriver/opengl/gl/default_notpurego.go similarity index 54% rename from internal/graphicsdriver/opengl/gl/package_notpurego.go rename to internal/graphicsdriver/opengl/gl/default_notpurego.go index 2a7bc2f7b..7efbf3949 100644 --- a/internal/graphicsdriver/opengl/gl/package_notpurego.go +++ b/internal/graphicsdriver/opengl/gl/default_notpurego.go @@ -1,4 +1,5 @@ // SPDX-License-Identifier: MIT +// SPDX-FileCopyrightText: 2014 Eric Woroshow //go:build !android && !darwin && !js && !windows && !opengles @@ -319,10 +320,11 @@ import "C" import ( "errors" + "runtime" "unsafe" ) -var ( +type defaultContext struct { gpActiveTexture C.GPACTIVETEXTURE gpAttachShader C.GPATTACHSHADER gpBindAttribLocation C.GPBINDATTRIBLOCATION @@ -392,7 +394,11 @@ var ( gpUseProgram C.GPUSEPROGRAM gpVertexAttribPointer C.GPVERTEXATTRIBPOINTER gpViewport C.GPVIEWPORT -) +} + +func NewDefaultContext() Context { + return &defaultContext{} +} func boolToInt(b bool) int { if b { @@ -401,534 +407,576 @@ func boolToInt(b bool) int { return 0 } -func ActiveTexture(texture uint32) { - C.glowActiveTexture(gpActiveTexture, (C.GLenum)(texture)) +func (c *defaultContext) ActiveTexture(texture uint32) { + C.glowActiveTexture(c.gpActiveTexture, (C.GLenum)(texture)) } -func AttachShader(program uint32, shader uint32) { - C.glowAttachShader(gpAttachShader, (C.GLuint)(program), (C.GLuint)(shader)) +func (c *defaultContext) AttachShader(program uint32, shader uint32) { + C.glowAttachShader(c.gpAttachShader, (C.GLuint)(program), (C.GLuint)(shader)) } -func BindAttribLocation(program uint32, index uint32, name *uint8) { - C.glowBindAttribLocation(gpBindAttribLocation, (C.GLuint)(program), (C.GLuint)(index), (*C.GLchar)(unsafe.Pointer(name))) +func (c *defaultContext) BindAttribLocation(program uint32, index uint32, name string) { + cname, free := cStr(name) + defer free() + C.glowBindAttribLocation(c.gpBindAttribLocation, (C.GLuint)(program), (C.GLuint)(index), (*C.GLchar)(unsafe.Pointer(cname))) } -func BindBuffer(target uint32, buffer uint32) { - C.glowBindBuffer(gpBindBuffer, (C.GLenum)(target), (C.GLuint)(buffer)) +func (c *defaultContext) BindBuffer(target uint32, buffer uint32) { + C.glowBindBuffer(c.gpBindBuffer, (C.GLenum)(target), (C.GLuint)(buffer)) } -func BindFramebufferEXT(target uint32, framebuffer uint32) { - C.glowBindFramebufferEXT(gpBindFramebufferEXT, (C.GLenum)(target), (C.GLuint)(framebuffer)) +func (c *defaultContext) BindFramebuffer(target uint32, framebuffer uint32) { + C.glowBindFramebufferEXT(c.gpBindFramebufferEXT, (C.GLenum)(target), (C.GLuint)(framebuffer)) } -func BindRenderbufferEXT(target uint32, renderbuffer uint32) { - C.glowBindRenderbufferEXT(gpBindRenderbufferEXT, (C.GLenum)(target), (C.GLuint)(renderbuffer)) +func (c *defaultContext) BindRenderbuffer(target uint32, renderbuffer uint32) { + C.glowBindRenderbufferEXT(c.gpBindRenderbufferEXT, (C.GLenum)(target), (C.GLuint)(renderbuffer)) } -func BindTexture(target uint32, texture uint32) { - C.glowBindTexture(gpBindTexture, (C.GLenum)(target), (C.GLuint)(texture)) +func (c *defaultContext) BindTexture(target uint32, texture uint32) { + C.glowBindTexture(c.gpBindTexture, (C.GLenum)(target), (C.GLuint)(texture)) } -func BlendEquationSeparate(modeRGB uint32, modeAlpha uint32) { - C.glowBlendEquationSeparate(gpBlendEquationSeparate, (C.GLenum)(modeRGB), (C.GLenum)(modeAlpha)) +func (c *defaultContext) BlendEquationSeparate(modeRGB uint32, modeAlpha uint32) { + C.glowBlendEquationSeparate(c.gpBlendEquationSeparate, (C.GLenum)(modeRGB), (C.GLenum)(modeAlpha)) } -func BlendFuncSeparate(srcRGB uint32, dstRGB uint32, srcAlpha uint32, dstAlpha uint32) { - C.glowBlendFuncSeparate(gpBlendFuncSeparate, (C.GLenum)(srcRGB), (C.GLenum)(dstRGB), (C.GLenum)(srcAlpha), (C.GLenum)(dstAlpha)) +func (c *defaultContext) BlendFuncSeparate(srcRGB uint32, dstRGB uint32, srcAlpha uint32, dstAlpha uint32) { + C.glowBlendFuncSeparate(c.gpBlendFuncSeparate, (C.GLenum)(srcRGB), (C.GLenum)(dstRGB), (C.GLenum)(srcAlpha), (C.GLenum)(dstAlpha)) } -func BufferData(target uint32, size int, data unsafe.Pointer, usage uint32) { - C.glowBufferData(gpBufferData, (C.GLenum)(target), (C.GLsizeiptr)(size), data, (C.GLenum)(usage)) +func (c *defaultContext) BufferData(target uint32, size int, data []byte, usage uint32) { + var ptr *byte + if len(data) > 0 { + ptr = &data[0] + } + C.glowBufferData(c.gpBufferData, (C.GLenum)(target), (C.GLsizeiptr)(size), unsafe.Pointer(ptr), (C.GLenum)(usage)) + runtime.KeepAlive(data) } -func BufferSubData(target uint32, offset int, size int, data unsafe.Pointer) { - C.glowBufferSubData(gpBufferSubData, (C.GLenum)(target), (C.GLintptr)(offset), (C.GLsizeiptr)(size), data) +func (c *defaultContext) BufferSubData(target uint32, offset int, data []byte) { + C.glowBufferSubData(c.gpBufferSubData, (C.GLenum)(target), (C.GLintptr)(offset), (C.GLsizeiptr)(len(data)), unsafe.Pointer(&data[0])) + runtime.KeepAlive(data) } -func CheckFramebufferStatusEXT(target uint32) uint32 { - ret := C.glowCheckFramebufferStatusEXT(gpCheckFramebufferStatusEXT, (C.GLenum)(target)) - return (uint32)(ret) +func (c *defaultContext) CheckFramebufferStatus(target uint32) uint32 { + ret := C.glowCheckFramebufferStatusEXT(c.gpCheckFramebufferStatusEXT, (C.GLenum)(target)) + return uint32(ret) } -func Clear(mask uint32) { - C.glowClear(gpClear, (C.GLbitfield)(mask)) +func (c *defaultContext) Clear(mask uint32) { + C.glowClear(c.gpClear, (C.GLbitfield)(mask)) } -func ColorMask(red bool, green bool, blue bool, alpha bool) { - C.glowColorMask(gpColorMask, (C.GLboolean)(boolToInt(red)), (C.GLboolean)(boolToInt(green)), (C.GLboolean)(boolToInt(blue)), (C.GLboolean)(boolToInt(alpha))) +func (c *defaultContext) ColorMask(red bool, green bool, blue bool, alpha bool) { + C.glowColorMask(c.gpColorMask, (C.GLboolean)(boolToInt(red)), (C.GLboolean)(boolToInt(green)), (C.GLboolean)(boolToInt(blue)), (C.GLboolean)(boolToInt(alpha))) } -func CompileShader(shader uint32) { - C.glowCompileShader(gpCompileShader, (C.GLuint)(shader)) +func (c *defaultContext) CompileShader(shader uint32) { + C.glowCompileShader(c.gpCompileShader, (C.GLuint)(shader)) } -func CreateProgram() uint32 { - ret := C.glowCreateProgram(gpCreateProgram) - return (uint32)(ret) +func (c *defaultContext) CreateProgram() uint32 { + ret := C.glowCreateProgram(c.gpCreateProgram) + return uint32(ret) } -func CreateShader(xtype uint32) uint32 { - ret := C.glowCreateShader(gpCreateShader, (C.GLenum)(xtype)) - return (uint32)(ret) +func (c *defaultContext) CreateShader(xtype uint32) uint32 { + ret := C.glowCreateShader(c.gpCreateShader, (C.GLenum)(xtype)) + return uint32(ret) } -func DeleteBuffers(n int32, buffers *uint32) { - C.glowDeleteBuffers(gpDeleteBuffers, (C.GLsizei)(n), (*C.GLuint)(unsafe.Pointer(buffers))) +func (c *defaultContext) DeleteBuffers(buffers []uint32) { + C.glowDeleteBuffers(c.gpDeleteBuffers, (C.GLsizei)(len(buffers)), (*C.GLuint)(unsafe.Pointer(&buffers[0]))) + runtime.KeepAlive(buffers) } -func DeleteFramebuffersEXT(n int32, framebuffers *uint32) { - C.glowDeleteFramebuffersEXT(gpDeleteFramebuffersEXT, (C.GLsizei)(n), (*C.GLuint)(unsafe.Pointer(framebuffers))) +func (c *defaultContext) DeleteFramebuffers(framebuffers []uint32) { + C.glowDeleteFramebuffersEXT(c.gpDeleteFramebuffersEXT, (C.GLsizei)(len(framebuffers)), (*C.GLuint)(unsafe.Pointer(&framebuffers[0]))) + runtime.KeepAlive(framebuffers) } -func DeleteProgram(program uint32) { - C.glowDeleteProgram(gpDeleteProgram, (C.GLuint)(program)) +func (c *defaultContext) DeleteProgram(program uint32) { + C.glowDeleteProgram(c.gpDeleteProgram, (C.GLuint)(program)) } -func DeleteRenderbuffersEXT(n int32, renderbuffers *uint32) { - C.glowDeleteRenderbuffersEXT(gpDeleteRenderbuffersEXT, (C.GLsizei)(n), (*C.GLuint)(unsafe.Pointer(renderbuffers))) +func (c *defaultContext) DeleteRenderbuffers(renderbuffers []uint32) { + C.glowDeleteRenderbuffersEXT(c.gpDeleteRenderbuffersEXT, (C.GLsizei)(len(renderbuffers)), (*C.GLuint)(unsafe.Pointer(&renderbuffers[0]))) + runtime.KeepAlive(renderbuffers) } -func DeleteShader(shader uint32) { - C.glowDeleteShader(gpDeleteShader, (C.GLuint)(shader)) +func (c *defaultContext) DeleteShader(shader uint32) { + C.glowDeleteShader(c.gpDeleteShader, (C.GLuint)(shader)) } -func DeleteTextures(n int32, textures *uint32) { - C.glowDeleteTextures(gpDeleteTextures, (C.GLsizei)(n), (*C.GLuint)(unsafe.Pointer(textures))) +func (c *defaultContext) DeleteTextures(textures []uint32) { + C.glowDeleteTextures(c.gpDeleteTextures, (C.GLsizei)(len(textures)), (*C.GLuint)(unsafe.Pointer(&textures[0]))) + runtime.KeepAlive(textures) } -func Disable(cap uint32) { - C.glowDisable(gpDisable, (C.GLenum)(cap)) +func (c *defaultContext) Disable(cap uint32) { + C.glowDisable(c.gpDisable, (C.GLenum)(cap)) } -func DisableVertexAttribArray(index uint32) { - C.glowDisableVertexAttribArray(gpDisableVertexAttribArray, (C.GLuint)(index)) +func (c *defaultContext) DisableVertexAttribArray(index uint32) { + C.glowDisableVertexAttribArray(c.gpDisableVertexAttribArray, (C.GLuint)(index)) } -func DrawElements(mode uint32, count int32, xtype uint32, indices uintptr) { - C.glowDrawElements(gpDrawElements, (C.GLenum)(mode), (C.GLsizei)(count), (C.GLenum)(xtype), C.uintptr_t(indices)) +func (c *defaultContext) DrawElements(mode uint32, count int32, xtype uint32, offset int) { + C.glowDrawElements(c.gpDrawElements, (C.GLenum)(mode), (C.GLsizei)(count), (C.GLenum)(xtype), C.uintptr_t(offset)) } -func Enable(cap uint32) { - C.glowEnable(gpEnable, (C.GLenum)(cap)) +func (c *defaultContext) Enable(cap uint32) { + C.glowEnable(c.gpEnable, (C.GLenum)(cap)) } -func EnableVertexAttribArray(index uint32) { - C.glowEnableVertexAttribArray(gpEnableVertexAttribArray, (C.GLuint)(index)) +func (c *defaultContext) EnableVertexAttribArray(index uint32) { + C.glowEnableVertexAttribArray(c.gpEnableVertexAttribArray, (C.GLuint)(index)) } -func Flush() { - C.glowFlush(gpFlush) +func (c *defaultContext) Flush() { + C.glowFlush(c.gpFlush) } -func FramebufferRenderbufferEXT(target uint32, attachment uint32, renderbuffertarget uint32, renderbuffer uint32) { - C.glowFramebufferRenderbufferEXT(gpFramebufferRenderbufferEXT, (C.GLenum)(target), (C.GLenum)(attachment), (C.GLenum)(renderbuffertarget), (C.GLuint)(renderbuffer)) +func (c *defaultContext) FramebufferRenderbuffer(target uint32, attachment uint32, renderbuffertarget uint32, renderbuffer uint32) { + C.glowFramebufferRenderbufferEXT(c.gpFramebufferRenderbufferEXT, (C.GLenum)(target), (C.GLenum)(attachment), (C.GLenum)(renderbuffertarget), (C.GLuint)(renderbuffer)) } -func FramebufferTexture2DEXT(target uint32, attachment uint32, textarget uint32, texture uint32, level int32) { - C.glowFramebufferTexture2DEXT(gpFramebufferTexture2DEXT, (C.GLenum)(target), (C.GLenum)(attachment), (C.GLenum)(textarget), (C.GLuint)(texture), (C.GLint)(level)) +func (c *defaultContext) FramebufferTexture2D(target uint32, attachment uint32, textarget uint32, texture uint32, level int32) { + C.glowFramebufferTexture2DEXT(c.gpFramebufferTexture2DEXT, (C.GLenum)(target), (C.GLenum)(attachment), (C.GLenum)(textarget), (C.GLuint)(texture), (C.GLint)(level)) } -func GenBuffers(n int32, buffers *uint32) { - C.glowGenBuffers(gpGenBuffers, (C.GLsizei)(n), (*C.GLuint)(unsafe.Pointer(buffers))) +func (c *defaultContext) GenBuffers(n int32) []uint32 { + buffers := make([]uint32, n) + C.glowGenBuffers(c.gpGenBuffers, (C.GLsizei)(n), (*C.GLuint)(unsafe.Pointer(&buffers[0]))) + return buffers } -func GenFramebuffersEXT(n int32, framebuffers *uint32) { - C.glowGenFramebuffersEXT(gpGenFramebuffersEXT, (C.GLsizei)(n), (*C.GLuint)(unsafe.Pointer(framebuffers))) +func (c *defaultContext) GenFramebuffers(n int32) []uint32 { + framebuffers := make([]uint32, n) + C.glowGenFramebuffersEXT(c.gpGenFramebuffersEXT, (C.GLsizei)(n), (*C.GLuint)(unsafe.Pointer(&framebuffers[0]))) + return framebuffers } -func GenRenderbuffersEXT(n int32, renderbuffers *uint32) { - C.glowGenRenderbuffersEXT(gpGenRenderbuffersEXT, (C.GLsizei)(n), (*C.GLuint)(unsafe.Pointer(renderbuffers))) +func (c *defaultContext) GenRenderbuffers(n int32) []uint32 { + renderbuffers := make([]uint32, n) + C.glowGenRenderbuffersEXT(c.gpGenRenderbuffersEXT, (C.GLsizei)(n), (*C.GLuint)(unsafe.Pointer(&renderbuffers[0]))) + return renderbuffers } -func GenTextures(n int32, textures *uint32) { - C.glowGenTextures(gpGenTextures, (C.GLsizei)(n), (*C.GLuint)(unsafe.Pointer(textures))) +func (c *defaultContext) GenTextures(n int32) []uint32 { + textures := make([]uint32, n) + C.glowGenTextures(c.gpGenTextures, (C.GLsizei)(n), (*C.GLuint)(unsafe.Pointer(&textures[0]))) + return textures } -func GetError() uint32 { - ret := C.glowGetError(gpGetError) - return (uint32)(ret) +func (c *defaultContext) GetError() uint32 { + ret := C.glowGetError(c.gpGetError) + return uint32(ret) } -func GetIntegerv(pname uint32, data *int32) { - C.glowGetIntegerv(gpGetIntegerv, (C.GLenum)(pname), (*C.GLint)(unsafe.Pointer(data))) +func (c *defaultContext) GetIntegerv(dst []int32, pname uint32) { + C.glowGetIntegerv(c.gpGetIntegerv, (C.GLenum)(pname), (*C.GLint)(unsafe.Pointer(&dst[0]))) } -func GetProgramInfoLog(program uint32, bufSize int32, length *int32, infoLog *uint8) { - C.glowGetProgramInfoLog(gpGetProgramInfoLog, (C.GLuint)(program), (C.GLsizei)(bufSize), (*C.GLsizei)(unsafe.Pointer(length)), (*C.GLchar)(unsafe.Pointer(infoLog))) +func (c *defaultContext) GetProgramInfoLog(program uint32) string { + var bufSize [1]int32 + c.GetProgramiv(bufSize[:], program, INFO_LOG_LENGTH) + infoLog := make([]byte, bufSize[0]) + C.glowGetProgramInfoLog(c.gpGetProgramInfoLog, (C.GLuint)(program), (C.GLsizei)(bufSize[0]), nil, (*C.GLchar)(unsafe.Pointer(&infoLog[0]))) + return string(infoLog) } -func GetProgramiv(program uint32, pname uint32, params *int32) { - C.glowGetProgramiv(gpGetProgramiv, (C.GLuint)(program), (C.GLenum)(pname), (*C.GLint)(unsafe.Pointer(params))) +func (c *defaultContext) GetProgramiv(dst []int32, program uint32, pname uint32) { + C.glowGetProgramiv(c.gpGetProgramiv, (C.GLuint)(program), (C.GLenum)(pname), (*C.GLint)(unsafe.Pointer(&dst[0]))) } -func GetShaderInfoLog(shader uint32, bufSize int32, length *int32, infoLog *uint8) { - C.glowGetShaderInfoLog(gpGetShaderInfoLog, (C.GLuint)(shader), (C.GLsizei)(bufSize), (*C.GLsizei)(unsafe.Pointer(length)), (*C.GLchar)(unsafe.Pointer(infoLog))) +func (c *defaultContext) GetShaderInfoLog(shader uint32) string { + var bufSize [1]int32 + c.GetShaderiv(bufSize[:], shader, INFO_LOG_LENGTH) + infoLog := make([]byte, bufSize[0]) + C.glowGetShaderInfoLog(c.gpGetShaderInfoLog, (C.GLuint)(shader), (C.GLsizei)(bufSize[0]), nil, (*C.GLchar)(unsafe.Pointer(&infoLog[0]))) + return string(infoLog) } -func GetShaderiv(shader uint32, pname uint32, params *int32) { - C.glowGetShaderiv(gpGetShaderiv, (C.GLuint)(shader), (C.GLenum)(pname), (*C.GLint)(unsafe.Pointer(params))) +func (c *defaultContext) GetShaderiv(dst []int32, shader uint32, pname uint32) { + C.glowGetShaderiv(c.gpGetShaderiv, (C.GLuint)(shader), (C.GLenum)(pname), (*C.GLint)(unsafe.Pointer(&dst[0]))) } -func GetUniformLocation(program uint32, name *uint8) int32 { - ret := C.glowGetUniformLocation(gpGetUniformLocation, (C.GLuint)(program), (*C.GLchar)(unsafe.Pointer(name))) - return (int32)(ret) +func (c *defaultContext) GetUniformLocation(program uint32, name string) int32 { + cname, free := cStr(name) + defer free() + ret := C.glowGetUniformLocation(c.gpGetUniformLocation, (C.GLuint)(program), (*C.GLchar)(unsafe.Pointer(cname))) + return int32(ret) } -func IsFramebufferEXT(framebuffer uint32) bool { - ret := C.glowIsFramebufferEXT(gpIsFramebufferEXT, (C.GLuint)(framebuffer)) +func (c *defaultContext) IsFramebuffer(framebuffer uint32) bool { + ret := C.glowIsFramebufferEXT(c.gpIsFramebufferEXT, (C.GLuint)(framebuffer)) return ret == TRUE } -func IsProgram(program uint32) bool { - ret := C.glowIsProgram(gpIsProgram, (C.GLuint)(program)) +func (c *defaultContext) IsProgram(program uint32) bool { + ret := C.glowIsProgram(c.gpIsProgram, (C.GLuint)(program)) return ret == TRUE } -func IsRenderbufferEXT(renderbuffer uint32) bool { - ret := C.glowIsRenderbufferEXT(gpIsRenderbufferEXT, (C.GLuint)(renderbuffer)) +func (c *defaultContext) IsRenderbuffer(renderbuffer uint32) bool { + ret := C.glowIsRenderbufferEXT(c.gpIsRenderbufferEXT, (C.GLuint)(renderbuffer)) return ret == TRUE } -func IsTexture(texture uint32) bool { - ret := C.glowIsTexture(gpIsTexture, (C.GLuint)(texture)) +func (c *defaultContext) IsTexture(texture uint32) bool { + ret := C.glowIsTexture(c.gpIsTexture, (C.GLuint)(texture)) return ret == TRUE } -func LinkProgram(program uint32) { - C.glowLinkProgram(gpLinkProgram, (C.GLuint)(program)) +func (c *defaultContext) LinkProgram(program uint32) { + C.glowLinkProgram(c.gpLinkProgram, (C.GLuint)(program)) } -func PixelStorei(pname uint32, param int32) { - C.glowPixelStorei(gpPixelStorei, (C.GLenum)(pname), (C.GLint)(param)) +func (c *defaultContext) PixelStorei(pname uint32, param int32) { + C.glowPixelStorei(c.gpPixelStorei, (C.GLenum)(pname), (C.GLint)(param)) } -func ReadPixels(x int32, y int32, width int32, height int32, format uint32, xtype uint32, pixels unsafe.Pointer) { - C.glowReadPixels(gpReadPixels, (C.GLint)(x), (C.GLint)(y), (C.GLsizei)(width), (C.GLsizei)(height), (C.GLenum)(format), (C.GLenum)(xtype), pixels) +func (c *defaultContext) ReadPixels(dst []byte, x int32, y int32, width int32, height int32, format uint32, xtype uint32) { + C.glowReadPixels(c.gpReadPixels, (C.GLint)(x), (C.GLint)(y), (C.GLsizei)(width), (C.GLsizei)(height), (C.GLenum)(format), (C.GLenum)(xtype), unsafe.Pointer(&dst[0])) } -func RenderbufferStorageEXT(target uint32, internalformat uint32, width int32, height int32) { - C.glowRenderbufferStorageEXT(gpRenderbufferStorageEXT, (C.GLenum)(target), (C.GLenum)(internalformat), (C.GLsizei)(width), (C.GLsizei)(height)) +func (c *defaultContext) RenderbufferStorage(target uint32, internalformat uint32, width int32, height int32) { + C.glowRenderbufferStorageEXT(c.gpRenderbufferStorageEXT, (C.GLenum)(target), (C.GLenum)(internalformat), (C.GLsizei)(width), (C.GLsizei)(height)) } -func Scissor(x int32, y int32, width int32, height int32) { - C.glowScissor(gpScissor, (C.GLint)(x), (C.GLint)(y), (C.GLsizei)(width), (C.GLsizei)(height)) +func (c *defaultContext) Scissor(x int32, y int32, width int32, height int32) { + C.glowScissor(c.gpScissor, (C.GLint)(x), (C.GLint)(y), (C.GLsizei)(width), (C.GLsizei)(height)) } -func ShaderSource(shader uint32, count int32, xstring **uint8, length *int32) { - C.glowShaderSource(gpShaderSource, (C.GLuint)(shader), (C.GLsizei)(count), (**C.GLchar)(unsafe.Pointer(xstring)), (*C.GLint)(unsafe.Pointer(length))) +func (c *defaultContext) ShaderSource(shader uint32, xstring string) { + cstring, free := cStr(xstring) + defer free() + C.glowShaderSource(c.gpShaderSource, (C.GLuint)(shader), 1, (**C.GLchar)(unsafe.Pointer(&cstring)), nil) } -func StencilFunc(xfunc uint32, ref int32, mask uint32) { - C.glowStencilFunc(gpStencilFunc, (C.GLenum)(xfunc), (C.GLint)(ref), (C.GLuint)(mask)) +func (c *defaultContext) StencilFunc(xfunc uint32, ref int32, mask uint32) { + C.glowStencilFunc(c.gpStencilFunc, (C.GLenum)(xfunc), (C.GLint)(ref), (C.GLuint)(mask)) } -func StencilOp(fail uint32, zfail uint32, zpass uint32) { - C.glowStencilOp(gpStencilOp, (C.GLenum)(fail), (C.GLenum)(zfail), (C.GLenum)(zpass)) +func (c *defaultContext) StencilOp(fail uint32, zfail uint32, zpass uint32) { + C.glowStencilOp(c.gpStencilOp, (C.GLenum)(fail), (C.GLenum)(zfail), (C.GLenum)(zpass)) } -func TexImage2D(target uint32, level int32, internalformat int32, width int32, height int32, border int32, format uint32, xtype uint32, pixels unsafe.Pointer) { - C.glowTexImage2D(gpTexImage2D, (C.GLenum)(target), (C.GLint)(level), (C.GLint)(internalformat), (C.GLsizei)(width), (C.GLsizei)(height), (C.GLint)(border), (C.GLenum)(format), (C.GLenum)(xtype), pixels) +func (c *defaultContext) TexImage2D(target uint32, level int32, internalformat int32, width int32, height int32, format uint32, xtype uint32, pixels []byte) { + var ptr *byte + if len(pixels) > 0 { + ptr = &pixels[0] + } + C.glowTexImage2D(c.gpTexImage2D, (C.GLenum)(target), (C.GLint)(level), (C.GLint)(internalformat), (C.GLsizei)(width), (C.GLsizei)(height), 0, (C.GLenum)(format), (C.GLenum)(xtype), unsafe.Pointer(ptr)) + runtime.KeepAlive(pixels) } -func TexParameteri(target uint32, pname uint32, param int32) { - C.glowTexParameteri(gpTexParameteri, (C.GLenum)(target), (C.GLenum)(pname), (C.GLint)(param)) +func (c *defaultContext) TexParameteri(target uint32, pname uint32, param int32) { + C.glowTexParameteri(c.gpTexParameteri, (C.GLenum)(target), (C.GLenum)(pname), (C.GLint)(param)) } -func TexSubImage2D(target uint32, level int32, xoffset int32, yoffset int32, width int32, height int32, format uint32, xtype uint32, pixels unsafe.Pointer) { - C.glowTexSubImage2D(gpTexSubImage2D, (C.GLenum)(target), (C.GLint)(level), (C.GLint)(xoffset), (C.GLint)(yoffset), (C.GLsizei)(width), (C.GLsizei)(height), (C.GLenum)(format), (C.GLenum)(xtype), pixels) +func (c *defaultContext) TexSubImage2D(target uint32, level int32, xoffset int32, yoffset int32, width int32, height int32, format uint32, xtype uint32, pixels []byte) { + C.glowTexSubImage2D(c.gpTexSubImage2D, (C.GLenum)(target), (C.GLint)(level), (C.GLint)(xoffset), (C.GLint)(yoffset), (C.GLsizei)(width), (C.GLsizei)(height), (C.GLenum)(format), (C.GLenum)(xtype), unsafe.Pointer(&pixels[0])) + runtime.KeepAlive(pixels) } -func Uniform1fv(location int32, count int32, value *float32) { - C.glowUniform1fv(gpUniform1fv, (C.GLint)(location), (C.GLsizei)(count), (*C.GLfloat)(unsafe.Pointer(value))) +func (c *defaultContext) Uniform1fv(location int32, value []float32) { + C.glowUniform1fv(c.gpUniform1fv, (C.GLint)(location), (C.GLsizei)(len(value)), (*C.GLfloat)(unsafe.Pointer(&value[0]))) + runtime.KeepAlive(value) } -func Uniform1i(location int32, v0 int32) { - C.glowUniform1i(gpUniform1i, (C.GLint)(location), (C.GLint)(v0)) +func (c *defaultContext) Uniform1i(location int32, v0 int32) { + C.glowUniform1i(c.gpUniform1i, (C.GLint)(location), (C.GLint)(v0)) } -func Uniform1iv(location int32, count int32, value *int32) { - C.glowUniform1iv(gpUniform1iv, (C.GLint)(location), (C.GLsizei)(count), (*C.GLint)(unsafe.Pointer(value))) +func (c *defaultContext) Uniform1iv(location int32, value []int32) { + C.glowUniform1iv(c.gpUniform1iv, (C.GLint)(location), (C.GLsizei)(len(value)), (*C.GLint)(unsafe.Pointer(&value[0]))) + runtime.KeepAlive(value) } -func Uniform2fv(location int32, count int32, value *float32) { - C.glowUniform2fv(gpUniform2fv, (C.GLint)(location), (C.GLsizei)(count), (*C.GLfloat)(unsafe.Pointer(value))) +func (c *defaultContext) Uniform2fv(location int32, value []float32) { + C.glowUniform2fv(c.gpUniform2fv, (C.GLint)(location), (C.GLsizei)(len(value)/2), (*C.GLfloat)(unsafe.Pointer(&value[0]))) + runtime.KeepAlive(value) } -func Uniform3fv(location int32, count int32, value *float32) { - C.glowUniform3fv(gpUniform3fv, (C.GLint)(location), (C.GLsizei)(count), (*C.GLfloat)(unsafe.Pointer(value))) +func (c *defaultContext) Uniform3fv(location int32, value []float32) { + C.glowUniform3fv(c.gpUniform3fv, (C.GLint)(location), (C.GLsizei)(len(value)/3), (*C.GLfloat)(unsafe.Pointer(&value[0]))) + runtime.KeepAlive(value) } -func Uniform4fv(location int32, count int32, value *float32) { - C.glowUniform4fv(gpUniform4fv, (C.GLint)(location), (C.GLsizei)(count), (*C.GLfloat)(unsafe.Pointer(value))) +func (c *defaultContext) Uniform4fv(location int32, value []float32) { + C.glowUniform4fv(c.gpUniform4fv, (C.GLint)(location), (C.GLsizei)(len(value)/4), (*C.GLfloat)(unsafe.Pointer(&value[0]))) + runtime.KeepAlive(value) } -func UniformMatrix2fv(location int32, count int32, transpose bool, value *float32) { - C.glowUniformMatrix2fv(gpUniformMatrix2fv, (C.GLint)(location), (C.GLsizei)(count), (C.GLboolean)(boolToInt(transpose)), (*C.GLfloat)(unsafe.Pointer(value))) +func (c *defaultContext) UniformMatrix2fv(location int32, transpose bool, value []float32) { + C.glowUniformMatrix2fv(c.gpUniformMatrix2fv, (C.GLint)(location), (C.GLsizei)(len(value)/4), (C.GLboolean)(boolToInt(transpose)), (*C.GLfloat)(unsafe.Pointer(&value[0]))) + runtime.KeepAlive(value) } -func UniformMatrix3fv(location int32, count int32, transpose bool, value *float32) { - C.glowUniformMatrix3fv(gpUniformMatrix3fv, (C.GLint)(location), (C.GLsizei)(count), (C.GLboolean)(boolToInt(transpose)), (*C.GLfloat)(unsafe.Pointer(value))) +func (c *defaultContext) UniformMatrix3fv(location int32, transpose bool, value []float32) { + C.glowUniformMatrix3fv(c.gpUniformMatrix3fv, (C.GLint)(location), (C.GLsizei)(len(value)/9), (C.GLboolean)(boolToInt(transpose)), (*C.GLfloat)(unsafe.Pointer(&value[0]))) + runtime.KeepAlive(value) } -func UniformMatrix4fv(location int32, count int32, transpose bool, value *float32) { - C.glowUniformMatrix4fv(gpUniformMatrix4fv, (C.GLint)(location), (C.GLsizei)(count), (C.GLboolean)(boolToInt(transpose)), (*C.GLfloat)(unsafe.Pointer(value))) +func (c *defaultContext) UniformMatrix4fv(location int32, transpose bool, value []float32) { + C.glowUniformMatrix4fv(c.gpUniformMatrix4fv, (C.GLint)(location), (C.GLsizei)(len(value)/16), (C.GLboolean)(boolToInt(transpose)), (*C.GLfloat)(unsafe.Pointer(&value[0]))) + runtime.KeepAlive(value) } -func UseProgram(program uint32) { - C.glowUseProgram(gpUseProgram, (C.GLuint)(program)) +func (c *defaultContext) UseProgram(program uint32) { + C.glowUseProgram(c.gpUseProgram, (C.GLuint)(program)) } -func VertexAttribPointer(index uint32, size int32, xtype uint32, normalized bool, stride int32, pointer uintptr) { - C.glowVertexAttribPointer(gpVertexAttribPointer, (C.GLuint)(index), (C.GLint)(size), (C.GLenum)(xtype), (C.GLboolean)(boolToInt(normalized)), (C.GLsizei)(stride), C.uintptr_t(pointer)) +func (c *defaultContext) VertexAttribPointer(index uint32, size int32, xtype uint32, normalized bool, stride int32, offset int) { + C.glowVertexAttribPointer(c.gpVertexAttribPointer, (C.GLuint)(index), (C.GLint)(size), (C.GLenum)(xtype), (C.GLboolean)(boolToInt(normalized)), (C.GLsizei)(stride), C.uintptr_t(offset)) } -func Viewport(x int32, y int32, width int32, height int32) { - C.glowViewport(gpViewport, (C.GLint)(x), (C.GLint)(y), (C.GLsizei)(width), (C.GLsizei)(height)) +func (c *defaultContext) Viewport(x int32, y int32, width int32, height int32) { + C.glowViewport(c.gpViewport, (C.GLint)(x), (C.GLint)(y), (C.GLsizei)(width), (C.GLsizei)(height)) } -// InitWithProcAddrFunc intializes the package using the specified OpenGL -// function pointer loading function. -// -// For more cases Init should be used. -func InitWithProcAddrFunc(getProcAddr func(name string) unsafe.Pointer) error { - gpActiveTexture = (C.GPACTIVETEXTURE)(getProcAddr("glActiveTexture")) - if gpActiveTexture == nil { +func (c *defaultContext) Init() error { + c.gpActiveTexture = (C.GPACTIVETEXTURE)(getProcAddress("glActiveTexture")) + if c.gpActiveTexture == nil { return errors.New("gl: glActiveTexture is missing") } - gpAttachShader = (C.GPATTACHSHADER)(getProcAddr("glAttachShader")) - if gpAttachShader == nil { + c.gpAttachShader = (C.GPATTACHSHADER)(getProcAddress("glAttachShader")) + if c.gpAttachShader == nil { return errors.New("gl: glAttachShader is missing") } - gpBindAttribLocation = (C.GPBINDATTRIBLOCATION)(getProcAddr("glBindAttribLocation")) - if gpBindAttribLocation == nil { + c.gpBindAttribLocation = (C.GPBINDATTRIBLOCATION)(getProcAddress("glBindAttribLocation")) + if c.gpBindAttribLocation == nil { return errors.New("gl: glBindAttribLocation is missing") } - gpBindBuffer = (C.GPBINDBUFFER)(getProcAddr("glBindBuffer")) - if gpBindBuffer == nil { + c.gpBindBuffer = (C.GPBINDBUFFER)(getProcAddress("glBindBuffer")) + if c.gpBindBuffer == nil { return errors.New("gl: glBindBuffer is missing") } - gpBindFramebufferEXT = (C.GPBINDFRAMEBUFFEREXT)(getProcAddr("glBindFramebufferEXT")) - gpBindRenderbufferEXT = (C.GPBINDRENDERBUFFEREXT)(getProcAddr("glBindRenderbufferEXT")) - gpBindTexture = (C.GPBINDTEXTURE)(getProcAddr("glBindTexture")) - if gpBindTexture == nil { + c.gpBindFramebufferEXT = (C.GPBINDFRAMEBUFFEREXT)(getProcAddress("glBindFramebufferEXT")) + c.gpBindRenderbufferEXT = (C.GPBINDRENDERBUFFEREXT)(getProcAddress("glBindRenderbufferEXT")) + c.gpBindTexture = (C.GPBINDTEXTURE)(getProcAddress("glBindTexture")) + if c.gpBindTexture == nil { return errors.New("gl: glBindTexture is missing") } - gpBlendEquationSeparate = (C.GPBLENDEQUATIONSEPARATE)(getProcAddr("glBlendEquationSeparate")) - if gpBlendEquationSeparate == nil { + c.gpBlendEquationSeparate = (C.GPBLENDEQUATIONSEPARATE)(getProcAddress("glBlendEquationSeparate")) + if c.gpBlendEquationSeparate == nil { return errors.New("gl: glBlendEquationSeparate is missing") } - gpBlendFuncSeparate = (C.GPBLENDFUNCSEPARATE)(getProcAddr("glBlendFuncSeparate")) - if gpBlendFuncSeparate == nil { + c.gpBlendFuncSeparate = (C.GPBLENDFUNCSEPARATE)(getProcAddress("glBlendFuncSeparate")) + if c.gpBlendFuncSeparate == nil { return errors.New("gl: glBlendFuncSeparate is missing") } - gpBufferData = (C.GPBUFFERDATA)(getProcAddr("glBufferData")) - if gpBufferData == nil { + c.gpBufferData = (C.GPBUFFERDATA)(getProcAddress("glBufferData")) + if c.gpBufferData == nil { return errors.New("gl: glBufferData is missing") } - gpBufferSubData = (C.GPBUFFERSUBDATA)(getProcAddr("glBufferSubData")) - if gpBufferSubData == nil { + c.gpBufferSubData = (C.GPBUFFERSUBDATA)(getProcAddress("glBufferSubData")) + if c.gpBufferSubData == nil { return errors.New("gl: glBufferSubData is missing") } - gpCheckFramebufferStatusEXT = (C.GPCHECKFRAMEBUFFERSTATUSEXT)(getProcAddr("glCheckFramebufferStatusEXT")) - gpClear = (C.GPCLEAR)(getProcAddr("glClear")) - if gpClear == nil { + c.gpCheckFramebufferStatusEXT = (C.GPCHECKFRAMEBUFFERSTATUSEXT)(getProcAddress("glCheckFramebufferStatusEXT")) + c.gpClear = (C.GPCLEAR)(getProcAddress("glClear")) + if c.gpClear == nil { return errors.New("gl: glClear is missing") } - gpColorMask = (C.GPCOLORMASK)(getProcAddr("glColorMask")) - if gpColorMask == nil { + c.gpColorMask = (C.GPCOLORMASK)(getProcAddress("glColorMask")) + if c.gpColorMask == nil { return errors.New("gl: glColorMask is missing") } - gpCompileShader = (C.GPCOMPILESHADER)(getProcAddr("glCompileShader")) - if gpCompileShader == nil { + c.gpCompileShader = (C.GPCOMPILESHADER)(getProcAddress("glCompileShader")) + if c.gpCompileShader == nil { return errors.New("gl: glCompileShader is missing") } - gpCreateProgram = (C.GPCREATEPROGRAM)(getProcAddr("glCreateProgram")) - if gpCreateProgram == nil { + c.gpCreateProgram = (C.GPCREATEPROGRAM)(getProcAddress("glCreateProgram")) + if c.gpCreateProgram == nil { return errors.New("gl: glCreateProgram is missing") } - gpCreateShader = (C.GPCREATESHADER)(getProcAddr("glCreateShader")) - if gpCreateShader == nil { + c.gpCreateShader = (C.GPCREATESHADER)(getProcAddress("glCreateShader")) + if c.gpCreateShader == nil { return errors.New("gl: glCreateShader is missing") } - gpDeleteBuffers = (C.GPDELETEBUFFERS)(getProcAddr("glDeleteBuffers")) - if gpDeleteBuffers == nil { + c.gpDeleteBuffers = (C.GPDELETEBUFFERS)(getProcAddress("glDeleteBuffers")) + if c.gpDeleteBuffers == nil { return errors.New("gl: glDeleteBuffers is missing") } - gpDeleteFramebuffersEXT = (C.GPDELETEFRAMEBUFFERSEXT)(getProcAddr("glDeleteFramebuffersEXT")) - gpDeleteProgram = (C.GPDELETEPROGRAM)(getProcAddr("glDeleteProgram")) - if gpDeleteProgram == nil { + c.gpDeleteFramebuffersEXT = (C.GPDELETEFRAMEBUFFERSEXT)(getProcAddress("glDeleteFramebuffersEXT")) + c.gpDeleteProgram = (C.GPDELETEPROGRAM)(getProcAddress("glDeleteProgram")) + if c.gpDeleteProgram == nil { return errors.New("gl: glDeleteProgram is missing") } - gpDeleteRenderbuffersEXT = (C.GPDELETERENDERBUFFERSEXT)(getProcAddr("glDeleteRenderbuffersEXT")) - gpDeleteShader = (C.GPDELETESHADER)(getProcAddr("glDeleteShader")) - if gpDeleteShader == nil { + c.gpDeleteRenderbuffersEXT = (C.GPDELETERENDERBUFFERSEXT)(getProcAddress("glDeleteRenderbuffersEXT")) + c.gpDeleteShader = (C.GPDELETESHADER)(getProcAddress("glDeleteShader")) + if c.gpDeleteShader == nil { return errors.New("gl: glDeleteShader is missing") } - gpDeleteTextures = (C.GPDELETETEXTURES)(getProcAddr("glDeleteTextures")) - if gpDeleteTextures == nil { + c.gpDeleteTextures = (C.GPDELETETEXTURES)(getProcAddress("glDeleteTextures")) + if c.gpDeleteTextures == nil { return errors.New("gl: glDeleteTextures is missing") } - gpDisable = (C.GPDISABLE)(getProcAddr("glDisable")) - if gpDisable == nil { + c.gpDisable = (C.GPDISABLE)(getProcAddress("glDisable")) + if c.gpDisable == nil { return errors.New("gl: glDisable is missing") } - gpDisableVertexAttribArray = (C.GPDISABLEVERTEXATTRIBARRAY)(getProcAddr("glDisableVertexAttribArray")) - if gpDisableVertexAttribArray == nil { + c.gpDisableVertexAttribArray = (C.GPDISABLEVERTEXATTRIBARRAY)(getProcAddress("glDisableVertexAttribArray")) + if c.gpDisableVertexAttribArray == nil { return errors.New("gl: glDisableVertexAttribArray is missing") } - gpDrawElements = (C.GPDRAWELEMENTS)(getProcAddr("glDrawElements")) - if gpDrawElements == nil { + c.gpDrawElements = (C.GPDRAWELEMENTS)(getProcAddress("glDrawElements")) + if c.gpDrawElements == nil { return errors.New("gl: glDrawElements is missing") } - gpEnable = (C.GPENABLE)(getProcAddr("glEnable")) - if gpEnable == nil { + c.gpEnable = (C.GPENABLE)(getProcAddress("glEnable")) + if c.gpEnable == nil { return errors.New("gl: glEnable is missing") } - gpEnableVertexAttribArray = (C.GPENABLEVERTEXATTRIBARRAY)(getProcAddr("glEnableVertexAttribArray")) - if gpEnableVertexAttribArray == nil { + c.gpEnableVertexAttribArray = (C.GPENABLEVERTEXATTRIBARRAY)(getProcAddress("glEnableVertexAttribArray")) + if c.gpEnableVertexAttribArray == nil { return errors.New("gl: glEnableVertexAttribArray is missing") } - gpFlush = (C.GPFLUSH)(getProcAddr("glFlush")) - if gpFlush == nil { + c.gpFlush = (C.GPFLUSH)(getProcAddress("glFlush")) + if c.gpFlush == nil { return errors.New("gl: glFlush is missing") } - gpFramebufferRenderbufferEXT = (C.GPFRAMEBUFFERRENDERBUFFEREXT)(getProcAddr("glFramebufferRenderbufferEXT")) - gpFramebufferTexture2DEXT = (C.GPFRAMEBUFFERTEXTURE2DEXT)(getProcAddr("glFramebufferTexture2DEXT")) - gpGenBuffers = (C.GPGENBUFFERS)(getProcAddr("glGenBuffers")) - if gpGenBuffers == nil { + c.gpFramebufferRenderbufferEXT = (C.GPFRAMEBUFFERRENDERBUFFEREXT)(getProcAddress("glFramebufferRenderbufferEXT")) + c.gpFramebufferTexture2DEXT = (C.GPFRAMEBUFFERTEXTURE2DEXT)(getProcAddress("glFramebufferTexture2DEXT")) + c.gpGenBuffers = (C.GPGENBUFFERS)(getProcAddress("glGenBuffers")) + if c.gpGenBuffers == nil { return errors.New("gl: glGenBuffers is missing") } - gpGenFramebuffersEXT = (C.GPGENFRAMEBUFFERSEXT)(getProcAddr("glGenFramebuffersEXT")) - gpGenRenderbuffersEXT = (C.GPGENRENDERBUFFERSEXT)(getProcAddr("glGenRenderbuffersEXT")) - gpGenTextures = (C.GPGENTEXTURES)(getProcAddr("glGenTextures")) - if gpGenTextures == nil { + c.gpGenFramebuffersEXT = (C.GPGENFRAMEBUFFERSEXT)(getProcAddress("glGenFramebuffersEXT")) + c.gpGenRenderbuffersEXT = (C.GPGENRENDERBUFFERSEXT)(getProcAddress("glGenRenderbuffersEXT")) + c.gpGenTextures = (C.GPGENTEXTURES)(getProcAddress("glGenTextures")) + if c.gpGenTextures == nil { return errors.New("gl: glGenTextures is missing") } - gpGetError = (C.GPGETERROR)(getProcAddr("glGetError")) - if gpGetError == nil { + c.gpGetError = (C.GPGETERROR)(getProcAddress("glGetError")) + if c.gpGetError == nil { return errors.New("gl: glGetError is missing") } - gpGetIntegerv = (C.GPGETINTEGERV)(getProcAddr("glGetIntegerv")) - if gpGetIntegerv == nil { + c.gpGetIntegerv = (C.GPGETINTEGERV)(getProcAddress("glGetIntegerv")) + if c.gpGetIntegerv == nil { return errors.New("gl: glGetIntegerv is missing") } - gpGetProgramInfoLog = (C.GPGETPROGRAMINFOLOG)(getProcAddr("glGetProgramInfoLog")) - if gpGetProgramInfoLog == nil { + c.gpGetProgramInfoLog = (C.GPGETPROGRAMINFOLOG)(getProcAddress("glGetProgramInfoLog")) + if c.gpGetProgramInfoLog == nil { return errors.New("gl: glGetProgramInfoLog is missing") } - gpGetProgramiv = (C.GPGETPROGRAMIV)(getProcAddr("glGetProgramiv")) - if gpGetProgramiv == nil { + c.gpGetProgramiv = (C.GPGETPROGRAMIV)(getProcAddress("glGetProgramiv")) + if c.gpGetProgramiv == nil { return errors.New("gl: glGetProgramiv is missing") } - gpGetShaderInfoLog = (C.GPGETSHADERINFOLOG)(getProcAddr("glGetShaderInfoLog")) - if gpGetShaderInfoLog == nil { + c.gpGetShaderInfoLog = (C.GPGETSHADERINFOLOG)(getProcAddress("glGetShaderInfoLog")) + if c.gpGetShaderInfoLog == nil { return errors.New("gl: glGetShaderInfoLog is missing") } - gpGetShaderiv = (C.GPGETSHADERIV)(getProcAddr("glGetShaderiv")) - if gpGetShaderiv == nil { + c.gpGetShaderiv = (C.GPGETSHADERIV)(getProcAddress("glGetShaderiv")) + if c.gpGetShaderiv == nil { return errors.New("gl: glGetShaderiv is missing") } - gpGetUniformLocation = (C.GPGETUNIFORMLOCATION)(getProcAddr("glGetUniformLocation")) - if gpGetUniformLocation == nil { + c.gpGetUniformLocation = (C.GPGETUNIFORMLOCATION)(getProcAddress("glGetUniformLocation")) + if c.gpGetUniformLocation == nil { return errors.New("gl: glGetUniformLocation is missing") } - gpIsFramebufferEXT = (C.GPISFRAMEBUFFEREXT)(getProcAddr("glIsFramebufferEXT")) - gpIsProgram = (C.GPISPROGRAM)(getProcAddr("glIsProgram")) - if gpIsProgram == nil { + c.gpIsFramebufferEXT = (C.GPISFRAMEBUFFEREXT)(getProcAddress("glIsFramebufferEXT")) + c.gpIsProgram = (C.GPISPROGRAM)(getProcAddress("glIsProgram")) + if c.gpIsProgram == nil { return errors.New("gl: glIsProgram is missing") } - gpIsRenderbufferEXT = (C.GPISRENDERBUFFEREXT)(getProcAddr("glIsRenderbufferEXT")) - gpIsTexture = (C.GPISTEXTURE)(getProcAddr("glIsTexture")) - if gpIsTexture == nil { + c.gpIsRenderbufferEXT = (C.GPISRENDERBUFFEREXT)(getProcAddress("glIsRenderbufferEXT")) + c.gpIsTexture = (C.GPISTEXTURE)(getProcAddress("glIsTexture")) + if c.gpIsTexture == nil { return errors.New("gl: glIsTexture is missing") } - gpLinkProgram = (C.GPLINKPROGRAM)(getProcAddr("glLinkProgram")) - if gpLinkProgram == nil { + c.gpLinkProgram = (C.GPLINKPROGRAM)(getProcAddress("glLinkProgram")) + if c.gpLinkProgram == nil { return errors.New("gl: glLinkProgram is missing") } - gpPixelStorei = (C.GPPIXELSTOREI)(getProcAddr("glPixelStorei")) - if gpPixelStorei == nil { + c.gpPixelStorei = (C.GPPIXELSTOREI)(getProcAddress("glPixelStorei")) + if c.gpPixelStorei == nil { return errors.New("gl: glPixelStorei is missing") } - gpReadPixels = (C.GPREADPIXELS)(getProcAddr("glReadPixels")) - if gpReadPixels == nil { + c.gpReadPixels = (C.GPREADPIXELS)(getProcAddress("glReadPixels")) + if c.gpReadPixels == nil { return errors.New("gl: glReadPixels is missing") } - gpRenderbufferStorageEXT = (C.GPRENDERBUFFERSTORAGEEXT)(getProcAddr("glRenderbufferStorageEXT")) - gpScissor = (C.GPSCISSOR)(getProcAddr("glScissor")) - if gpScissor == nil { + c.gpRenderbufferStorageEXT = (C.GPRENDERBUFFERSTORAGEEXT)(getProcAddress("glRenderbufferStorageEXT")) + c.gpScissor = (C.GPSCISSOR)(getProcAddress("glScissor")) + if c.gpScissor == nil { return errors.New("gl: glScissor is missing") } - gpShaderSource = (C.GPSHADERSOURCE)(getProcAddr("glShaderSource")) - if gpShaderSource == nil { + c.gpShaderSource = (C.GPSHADERSOURCE)(getProcAddress("glShaderSource")) + if c.gpShaderSource == nil { return errors.New("gl: glShaderSource is missing") } - gpStencilFunc = (C.GPSTENCILFUNC)(getProcAddr("glStencilFunc")) - if gpStencilFunc == nil { + c.gpStencilFunc = (C.GPSTENCILFUNC)(getProcAddress("glStencilFunc")) + if c.gpStencilFunc == nil { return errors.New("gl: glStencilFunc is missing") } - gpStencilOp = (C.GPSTENCILOP)(getProcAddr("glStencilOp")) - if gpStencilOp == nil { + c.gpStencilOp = (C.GPSTENCILOP)(getProcAddress("glStencilOp")) + if c.gpStencilOp == nil { return errors.New("gl: glStencilOp is missing") } - gpTexImage2D = (C.GPTEXIMAGE2D)(getProcAddr("glTexImage2D")) - if gpTexImage2D == nil { + c.gpTexImage2D = (C.GPTEXIMAGE2D)(getProcAddress("glTexImage2D")) + if c.gpTexImage2D == nil { return errors.New("gl: glTexImage2D is missing") } - gpTexParameteri = (C.GPTEXPARAMETERI)(getProcAddr("glTexParameteri")) - if gpTexParameteri == nil { + c.gpTexParameteri = (C.GPTEXPARAMETERI)(getProcAddress("glTexParameteri")) + if c.gpTexParameteri == nil { return errors.New("gl: glTexParameteri is missing") } - gpTexSubImage2D = (C.GPTEXSUBIMAGE2D)(getProcAddr("glTexSubImage2D")) - if gpTexSubImage2D == nil { + c.gpTexSubImage2D = (C.GPTEXSUBIMAGE2D)(getProcAddress("glTexSubImage2D")) + if c.gpTexSubImage2D == nil { return errors.New("gl: glTexSubImage2D is missing") } - gpUniform1fv = (C.GPUNIFORM1FV)(getProcAddr("glUniform1fv")) - if gpUniform1fv == nil { + c.gpUniform1fv = (C.GPUNIFORM1FV)(getProcAddress("glUniform1fv")) + if c.gpUniform1fv == nil { return errors.New("gl: glUniform1fv is missing") } - gpUniform1i = (C.GPUNIFORM1I)(getProcAddr("glUniform1i")) - if gpUniform1i == nil { + c.gpUniform1i = (C.GPUNIFORM1I)(getProcAddress("glUniform1i")) + if c.gpUniform1i == nil { return errors.New("gl: glUniform1i is missing") } - gpUniform1iv = (C.GPUNIFORM1IV)(getProcAddr("glUniform1iv")) - if gpUniform1iv == nil { + c.gpUniform1iv = (C.GPUNIFORM1IV)(getProcAddress("glUniform1iv")) + if c.gpUniform1iv == nil { return errors.New("gl: glUniform1iv is missing") } - gpUniform2fv = (C.GPUNIFORM2FV)(getProcAddr("glUniform2fv")) - if gpUniform2fv == nil { + c.gpUniform2fv = (C.GPUNIFORM2FV)(getProcAddress("glUniform2fv")) + if c.gpUniform2fv == nil { return errors.New("gl: glUniform2fv is missing") } - gpUniform3fv = (C.GPUNIFORM3FV)(getProcAddr("glUniform3fv")) - if gpUniform3fv == nil { + c.gpUniform3fv = (C.GPUNIFORM3FV)(getProcAddress("glUniform3fv")) + if c.gpUniform3fv == nil { return errors.New("gl: glUniform3fv is missing") } - gpUniform4fv = (C.GPUNIFORM4FV)(getProcAddr("glUniform4fv")) - if gpUniform4fv == nil { + c.gpUniform4fv = (C.GPUNIFORM4FV)(getProcAddress("glUniform4fv")) + if c.gpUniform4fv == nil { return errors.New("gl: glUniform4fv is missing") } - gpUniformMatrix2fv = (C.GPUNIFORMMATRIX2FV)(getProcAddr("glUniformMatrix2fv")) - if gpUniformMatrix2fv == nil { + c.gpUniformMatrix2fv = (C.GPUNIFORMMATRIX2FV)(getProcAddress("glUniformMatrix2fv")) + if c.gpUniformMatrix2fv == nil { return errors.New("gl: glUniformMatrix2fv is missing") } - gpUniformMatrix3fv = (C.GPUNIFORMMATRIX3FV)(getProcAddr("glUniformMatrix3fv")) - if gpUniformMatrix3fv == nil { + c.gpUniformMatrix3fv = (C.GPUNIFORMMATRIX3FV)(getProcAddress("glUniformMatrix3fv")) + if c.gpUniformMatrix3fv == nil { return errors.New("gl: glUniformMatrix3fv is missing") } - gpUniformMatrix4fv = (C.GPUNIFORMMATRIX4FV)(getProcAddr("glUniformMatrix4fv")) - if gpUniformMatrix4fv == nil { + c.gpUniformMatrix4fv = (C.GPUNIFORMMATRIX4FV)(getProcAddress("glUniformMatrix4fv")) + if c.gpUniformMatrix4fv == nil { return errors.New("gl: glUniformMatrix4fv is missing") } - gpUseProgram = (C.GPUSEPROGRAM)(getProcAddr("glUseProgram")) - if gpUseProgram == nil { + c.gpUseProgram = (C.GPUSEPROGRAM)(getProcAddress("glUseProgram")) + if c.gpUseProgram == nil { return errors.New("gl: glUseProgram is missing") } - gpVertexAttribPointer = (C.GPVERTEXATTRIBPOINTER)(getProcAddr("glVertexAttribPointer")) - if gpVertexAttribPointer == nil { + c.gpVertexAttribPointer = (C.GPVERTEXATTRIBPOINTER)(getProcAddress("glVertexAttribPointer")) + if c.gpVertexAttribPointer == nil { return errors.New("gl: glVertexAttribPointer is missing") } - gpViewport = (C.GPVIEWPORT)(getProcAddr("glViewport")) - if gpViewport == nil { + c.gpViewport = (C.GPVIEWPORT)(getProcAddress("glViewport")) + if c.gpViewport == nil { return errors.New("gl: glViewport is missing") } return nil diff --git a/internal/graphicsdriver/opengl/gl/default_purego.go b/internal/graphicsdriver/opengl/gl/default_purego.go new file mode 100644 index 000000000..d579c38d1 --- /dev/null +++ b/internal/graphicsdriver/opengl/gl/default_purego.go @@ -0,0 +1,681 @@ +// Copyright 2022 The Ebitengine 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. + +//go:build (darwin || windows) && !ios && !opengles + +package gl + +import ( + "errors" + "runtime" + "unsafe" + + "github.com/ebitengine/purego" +) + +type defaultContext struct { + gpActiveTexture uintptr + gpAttachShader uintptr + gpBindAttribLocation uintptr + gpBindBuffer uintptr + gpBindFramebufferEXT uintptr + gpBindRenderbufferEXT uintptr + gpBindTexture uintptr + gpBlendEquationSeparate uintptr + gpBlendFuncSeparate uintptr + gpBufferData uintptr + gpBufferSubData uintptr + gpCheckFramebufferStatusEXT uintptr + gpClear uintptr + gpColorMask uintptr + gpCompileShader uintptr + gpCreateProgram uintptr + gpCreateShader uintptr + gpDeleteBuffers uintptr + gpDeleteFramebuffersEXT uintptr + gpDeleteProgram uintptr + gpDeleteRenderbuffersEXT uintptr + gpDeleteShader uintptr + gpDeleteTextures uintptr + gpDisable uintptr + gpDisableVertexAttribArray uintptr + gpDrawElements uintptr + gpEnable uintptr + gpEnableVertexAttribArray uintptr + gpFlush uintptr + gpFramebufferRenderbufferEXT uintptr + gpFramebufferTexture2DEXT uintptr + gpGenBuffers uintptr + gpGenFramebuffersEXT uintptr + gpGenRenderbuffersEXT uintptr + gpGenTextures uintptr + gpGetError uintptr + gpGetIntegerv uintptr + gpGetProgramInfoLog uintptr + gpGetProgramiv uintptr + gpGetShaderInfoLog uintptr + gpGetShaderiv uintptr + gpGetUniformLocation uintptr + gpIsFramebufferEXT uintptr + gpIsProgram uintptr + gpIsRenderbufferEXT uintptr + gpIsTexture uintptr + gpLinkProgram uintptr + gpPixelStorei uintptr + gpReadPixels uintptr + gpRenderbufferStorageEXT uintptr + gpScissor uintptr + gpShaderSource uintptr + gpStencilFunc uintptr + gpStencilOp uintptr + gpTexImage2D uintptr + gpTexParameteri uintptr + gpTexSubImage2D uintptr + gpUniform1fv uintptr + gpUniform1i uintptr + gpUniform1iv uintptr + gpUniform2fv uintptr + gpUniform3fv uintptr + gpUniform4fv uintptr + gpUniformMatrix2fv uintptr + gpUniformMatrix3fv uintptr + gpUniformMatrix4fv uintptr + gpUseProgram uintptr + gpVertexAttribPointer uintptr + gpViewport uintptr +} + +func NewDefaultContext() Context { + return &defaultContext{} +} + +func boolToInt(b bool) int { + if b { + return 1 + } + return 0 +} + +func (c *defaultContext) ActiveTexture(texture uint32) { + purego.SyscallN(c.gpActiveTexture, uintptr(texture)) +} + +func (c *defaultContext) AttachShader(program uint32, shader uint32) { + purego.SyscallN(c.gpAttachShader, uintptr(program), uintptr(shader)) +} + +func (c *defaultContext) BindAttribLocation(program uint32, index uint32, name string) { + cname, free := cStr(name) + defer free() + purego.SyscallN(c.gpBindAttribLocation, uintptr(program), uintptr(index), uintptr(unsafe.Pointer(cname))) +} + +func (c *defaultContext) BindBuffer(target uint32, buffer uint32) { + purego.SyscallN(c.gpBindBuffer, uintptr(target), uintptr(buffer)) +} + +func (c *defaultContext) BindFramebuffer(target uint32, framebuffer uint32) { + purego.SyscallN(c.gpBindFramebufferEXT, uintptr(target), uintptr(framebuffer)) +} + +func (c *defaultContext) BindRenderbuffer(target uint32, renderbuffer uint32) { + purego.SyscallN(c.gpBindRenderbufferEXT, uintptr(target), uintptr(renderbuffer)) +} + +func (c *defaultContext) BindTexture(target uint32, texture uint32) { + purego.SyscallN(c.gpBindTexture, uintptr(target), uintptr(texture)) +} + +func (c *defaultContext) BlendEquationSeparate(modeRGB uint32, modeAlpha uint32) { + purego.SyscallN(c.gpBlendEquationSeparate, uintptr(modeRGB), uintptr(modeAlpha)) +} + +func (c *defaultContext) BlendFuncSeparate(srcRGB uint32, dstRGB uint32, srcAlpha uint32, dstAlpha uint32) { + purego.SyscallN(c.gpBlendFuncSeparate, uintptr(srcRGB), uintptr(dstRGB), uintptr(srcAlpha), uintptr(dstAlpha)) +} + +func (c *defaultContext) BufferData(target uint32, size int, data []byte, usage uint32) { + var ptr *byte + if len(data) > 0 { + ptr = &data[0] + } + purego.SyscallN(c.gpBufferData, uintptr(target), uintptr(size), uintptr(unsafe.Pointer(ptr)), uintptr(usage)) + runtime.KeepAlive(data) +} + +func (c *defaultContext) BufferSubData(target uint32, offset int, data []byte) { + purego.SyscallN(c.gpBufferSubData, uintptr(target), uintptr(offset), uintptr(len(data)), uintptr(unsafe.Pointer(&data[0]))) + runtime.KeepAlive(data) +} + +func (c *defaultContext) CheckFramebufferStatus(target uint32) uint32 { + ret, _, _ := purego.SyscallN(c.gpCheckFramebufferStatusEXT, uintptr(target)) + return uint32(ret) +} + +func (c *defaultContext) Clear(mask uint32) { + purego.SyscallN(c.gpClear, uintptr(mask)) +} + +func (c *defaultContext) ColorMask(red bool, green bool, blue bool, alpha bool) { + purego.SyscallN(c.gpColorMask, uintptr(boolToInt(red)), uintptr(boolToInt(green)), uintptr(boolToInt(blue)), uintptr(boolToInt(alpha))) +} + +func (c *defaultContext) CompileShader(shader uint32) { + purego.SyscallN(c.gpCompileShader, uintptr(shader)) +} + +func (c *defaultContext) CreateProgram() uint32 { + ret, _, _ := purego.SyscallN(c.gpCreateProgram) + return uint32(ret) +} + +func (c *defaultContext) CreateShader(xtype uint32) uint32 { + ret, _, _ := purego.SyscallN(c.gpCreateShader, uintptr(xtype)) + return uint32(ret) +} + +func (c *defaultContext) DeleteBuffers(buffers []uint32) { + purego.SyscallN(c.gpDeleteBuffers, uintptr(len(buffers)), uintptr(unsafe.Pointer(&buffers[0]))) + runtime.KeepAlive(buffers) +} + +func (c *defaultContext) DeleteFramebuffers(framebuffers []uint32) { + purego.SyscallN(c.gpDeleteFramebuffersEXT, uintptr(len(framebuffers)), uintptr(unsafe.Pointer(&framebuffers[0]))) + runtime.KeepAlive(framebuffers) +} + +func (c *defaultContext) DeleteProgram(program uint32) { + purego.SyscallN(c.gpDeleteProgram, uintptr(program)) +} + +func (c *defaultContext) DeleteRenderbuffers(renderbuffers []uint32) { + purego.SyscallN(c.gpDeleteRenderbuffersEXT, uintptr(len(renderbuffers)), uintptr(unsafe.Pointer(&renderbuffers[0]))) +} + +func (c *defaultContext) DeleteShader(shader uint32) { + purego.SyscallN(c.gpDeleteShader, uintptr(shader)) +} + +func (c *defaultContext) DeleteTextures(textures []uint32) { + purego.SyscallN(c.gpDeleteTextures, uintptr(len(textures)), uintptr(unsafe.Pointer(&textures[0]))) +} + +func (c *defaultContext) Disable(cap uint32) { + purego.SyscallN(c.gpDisable, uintptr(cap)) +} + +func (c *defaultContext) DisableVertexAttribArray(index uint32) { + purego.SyscallN(c.gpDisableVertexAttribArray, uintptr(index)) +} + +func (c *defaultContext) DrawElements(mode uint32, count int32, xtype uint32, offset int) { + purego.SyscallN(c.gpDrawElements, uintptr(mode), uintptr(count), uintptr(xtype), uintptr(offset)) +} + +func (c *defaultContext) Enable(cap uint32) { + purego.SyscallN(c.gpEnable, uintptr(cap)) +} + +func (c *defaultContext) EnableVertexAttribArray(index uint32) { + purego.SyscallN(c.gpEnableVertexAttribArray, uintptr(index)) +} + +func (c *defaultContext) Flush() { + purego.SyscallN(c.gpFlush) +} + +func (c *defaultContext) FramebufferRenderbuffer(target uint32, attachment uint32, renderbuffertarget uint32, renderbuffer uint32) { + purego.SyscallN(c.gpFramebufferRenderbufferEXT, uintptr(target), uintptr(attachment), uintptr(renderbuffertarget), uintptr(renderbuffer)) +} + +func (c *defaultContext) FramebufferTexture2D(target uint32, attachment uint32, textarget uint32, texture uint32, level int32) { + purego.SyscallN(c.gpFramebufferTexture2DEXT, uintptr(target), uintptr(attachment), uintptr(textarget), uintptr(texture), uintptr(level)) +} + +func (c *defaultContext) GenBuffers(n int32) []uint32 { + buffers := make([]uint32, n) + purego.SyscallN(c.gpGenBuffers, uintptr(n), uintptr(unsafe.Pointer(&buffers[0]))) + return buffers +} + +func (c *defaultContext) GenFramebuffers(n int32) []uint32 { + framebuffers := make([]uint32, n) + purego.SyscallN(c.gpGenFramebuffersEXT, uintptr(n), uintptr(unsafe.Pointer(&framebuffers[0]))) + return framebuffers +} + +func (c *defaultContext) GenRenderbuffers(n int32) []uint32 { + renderbuffers := make([]uint32, n) + purego.SyscallN(c.gpGenRenderbuffersEXT, uintptr(n), uintptr(unsafe.Pointer(&renderbuffers[0]))) + return renderbuffers +} + +func (c *defaultContext) GenTextures(n int32) []uint32 { + textures := make([]uint32, n) + purego.SyscallN(c.gpGenTextures, uintptr(n), uintptr(unsafe.Pointer(&textures[0]))) + return textures +} + +func (c *defaultContext) GetError() uint32 { + ret, _, _ := purego.SyscallN(c.gpGetError) + return uint32(ret) +} + +func (c *defaultContext) GetIntegerv(dst []int32, pname uint32) { + purego.SyscallN(c.gpGetIntegerv, uintptr(pname), uintptr(unsafe.Pointer(&dst[0]))) +} + +func (c *defaultContext) GetProgramInfoLog(program uint32) string { + var bufSize [1]int32 + c.GetProgramiv(bufSize[:], program, INFO_LOG_LENGTH) + infoLog := make([]byte, bufSize[0]) + purego.SyscallN(c.gpGetProgramInfoLog, uintptr(program), uintptr(bufSize[0]), 0, uintptr(unsafe.Pointer(&infoLog[0]))) + return string(infoLog) +} + +func (c *defaultContext) GetProgramiv(dst []int32, program uint32, pname uint32) { + purego.SyscallN(c.gpGetProgramiv, uintptr(program), uintptr(pname), uintptr(unsafe.Pointer(&dst[0]))) +} + +func (c *defaultContext) GetShaderInfoLog(shader uint32) string { + var bufSize [1]int32 + c.GetShaderiv(bufSize[:], shader, INFO_LOG_LENGTH) + infoLog := make([]byte, bufSize[0]) + purego.SyscallN(c.gpGetShaderInfoLog, uintptr(shader), uintptr(bufSize[0]), 0, uintptr(unsafe.Pointer(&infoLog[0]))) + return string(infoLog) +} + +func (c *defaultContext) GetShaderiv(dst []int32, shader uint32, pname uint32) { + purego.SyscallN(c.gpGetShaderiv, uintptr(shader), uintptr(pname), uintptr(unsafe.Pointer(&dst[0]))) +} + +func (c *defaultContext) GetUniformLocation(program uint32, name string) int32 { + cname, free := cStr(name) + defer free() + ret, _, _ := purego.SyscallN(c.gpGetUniformLocation, uintptr(program), uintptr(unsafe.Pointer(cname))) + return int32(ret) +} + +func (c *defaultContext) IsFramebuffer(framebuffer uint32) bool { + ret, _, _ := purego.SyscallN(c.gpIsFramebufferEXT, uintptr(framebuffer)) + return byte(ret) != 0 +} + +func (c *defaultContext) IsProgram(program uint32) bool { + ret, _, _ := purego.SyscallN(c.gpIsProgram, uintptr(program)) + return byte(ret) != 0 +} + +func (c *defaultContext) IsRenderbuffer(renderbuffer uint32) bool { + ret, _, _ := purego.SyscallN(c.gpIsRenderbufferEXT, uintptr(renderbuffer)) + return byte(ret) != 0 +} + +func (c *defaultContext) IsTexture(texture uint32) bool { + ret, _, _ := purego.SyscallN(c.gpIsTexture, uintptr(texture)) + return byte(ret) != 0 +} + +func (c *defaultContext) LinkProgram(program uint32) { + purego.SyscallN(c.gpLinkProgram, uintptr(program)) +} + +func (c *defaultContext) PixelStorei(pname uint32, param int32) { + purego.SyscallN(c.gpPixelStorei, uintptr(pname), uintptr(param)) +} + +func (c *defaultContext) ReadPixels(dst []byte, x int32, y int32, width int32, height int32, format uint32, xtype uint32) { + purego.SyscallN(c.gpReadPixels, uintptr(x), uintptr(y), uintptr(width), uintptr(height), uintptr(format), uintptr(xtype), uintptr(unsafe.Pointer(&dst[0]))) +} + +func (c *defaultContext) RenderbufferStorage(target uint32, internalformat uint32, width int32, height int32) { + purego.SyscallN(c.gpRenderbufferStorageEXT, uintptr(target), uintptr(internalformat), uintptr(width), uintptr(height)) +} + +func (c *defaultContext) Scissor(x int32, y int32, width int32, height int32) { + purego.SyscallN(c.gpScissor, uintptr(x), uintptr(y), uintptr(width), uintptr(height)) +} + +func (c *defaultContext) ShaderSource(shader uint32, xstring string) { + cstring, free := cStr(xstring) + defer free() + purego.SyscallN(c.gpShaderSource, uintptr(shader), 1, uintptr(unsafe.Pointer(&cstring)), 0) +} + +func (c *defaultContext) StencilFunc(xfunc uint32, ref int32, mask uint32) { + purego.SyscallN(c.gpStencilFunc, uintptr(xfunc), uintptr(ref), uintptr(mask)) +} + +func (c *defaultContext) StencilOp(fail uint32, zfail uint32, zpass uint32) { + purego.SyscallN(c.gpStencilOp, uintptr(fail), uintptr(zfail), uintptr(zpass)) +} + +func (c *defaultContext) TexImage2D(target uint32, level int32, internalformat int32, width int32, height int32, format uint32, xtype uint32, pixels []byte) { + var ptr *byte + if len(pixels) > 0 { + ptr = &pixels[0] + } + purego.SyscallN(c.gpTexImage2D, uintptr(target), uintptr(level), uintptr(internalformat), uintptr(width), uintptr(height), 0, uintptr(format), uintptr(xtype), uintptr(unsafe.Pointer(ptr))) + runtime.KeepAlive(pixels) +} + +func (c *defaultContext) TexParameteri(target uint32, pname uint32, param int32) { + purego.SyscallN(c.gpTexParameteri, uintptr(target), uintptr(pname), uintptr(param)) +} + +func (c *defaultContext) TexSubImage2D(target uint32, level int32, xoffset int32, yoffset int32, width int32, height int32, format uint32, xtype uint32, pixels []byte) { + purego.SyscallN(c.gpTexSubImage2D, uintptr(target), uintptr(level), uintptr(xoffset), uintptr(yoffset), uintptr(width), uintptr(height), uintptr(format), uintptr(xtype), uintptr(unsafe.Pointer(&pixels[0]))) + runtime.KeepAlive(pixels) +} + +func (c *defaultContext) Uniform1fv(location int32, value []float32) { + purego.SyscallN(c.gpUniform1fv, uintptr(location), uintptr(len(value)), uintptr(unsafe.Pointer(&value[0]))) + runtime.KeepAlive(value) +} + +func (c *defaultContext) Uniform1i(location int32, v0 int32) { + purego.SyscallN(c.gpUniform1i, uintptr(location), uintptr(v0)) +} + +func (c *defaultContext) Uniform1iv(location int32, value []int32) { + purego.SyscallN(c.gpUniform1iv, uintptr(location), uintptr(len(value)), uintptr(unsafe.Pointer(&value[0]))) + runtime.KeepAlive(value) +} + +func (c *defaultContext) Uniform2fv(location int32, value []float32) { + purego.SyscallN(c.gpUniform2fv, uintptr(location), uintptr(len(value)/2), uintptr(unsafe.Pointer(&value[0]))) + runtime.KeepAlive(value) +} + +func (c *defaultContext) Uniform3fv(location int32, value []float32) { + purego.SyscallN(c.gpUniform3fv, uintptr(location), uintptr(len(value)/3), uintptr(unsafe.Pointer(&value[0]))) + runtime.KeepAlive(value) +} + +func (c *defaultContext) Uniform4fv(location int32, value []float32) { + purego.SyscallN(c.gpUniform4fv, uintptr(location), uintptr(len(value)/4), uintptr(unsafe.Pointer(&value[0]))) + runtime.KeepAlive(value) +} + +func (c *defaultContext) UniformMatrix2fv(location int32, transpose bool, value []float32) { + purego.SyscallN(c.gpUniformMatrix2fv, uintptr(location), uintptr(len(value)/4), uintptr(boolToInt(transpose)), uintptr(unsafe.Pointer(&value[0]))) + runtime.KeepAlive(value) +} + +func (c *defaultContext) UniformMatrix3fv(location int32, transpose bool, value []float32) { + purego.SyscallN(c.gpUniformMatrix3fv, uintptr(location), uintptr(len(value)/9), uintptr(boolToInt(transpose)), uintptr(unsafe.Pointer(&value[0]))) + runtime.KeepAlive(value) +} + +func (c *defaultContext) UniformMatrix4fv(location int32, transpose bool, value []float32) { + purego.SyscallN(c.gpUniformMatrix4fv, uintptr(location), uintptr(len(value)/16), uintptr(boolToInt(transpose)), uintptr(unsafe.Pointer(&value[0]))) + runtime.KeepAlive(value) +} + +func (c *defaultContext) UseProgram(program uint32) { + purego.SyscallN(c.gpUseProgram, uintptr(program)) +} + +func (c *defaultContext) VertexAttribPointer(index uint32, size int32, xtype uint32, normalized bool, stride int32, offset int) { + purego.SyscallN(c.gpVertexAttribPointer, uintptr(index), uintptr(size), uintptr(xtype), uintptr(boolToInt(normalized)), uintptr(stride), uintptr(offset)) +} + +func (c *defaultContext) Viewport(x int32, y int32, width int32, height int32) { + purego.SyscallN(c.gpViewport, uintptr(x), uintptr(y), uintptr(width), uintptr(height)) +} + +func (c *defaultContext) Init() error { + c.gpActiveTexture = getProcAddress("glActiveTexture") + if c.gpActiveTexture == 0 { + return errors.New("gl: glActiveTexture is missing") + } + c.gpAttachShader = getProcAddress("glAttachShader") + if c.gpAttachShader == 0 { + return errors.New("gl: glAttachShader is missing") + } + c.gpBindAttribLocation = getProcAddress("glBindAttribLocation") + if c.gpBindAttribLocation == 0 { + return errors.New("gl: glBindAttribLocation is missing") + } + c.gpBindBuffer = getProcAddress("glBindBuffer") + if c.gpBindBuffer == 0 { + return errors.New("gl: glBindBuffer is missing") + } + c.gpBindFramebufferEXT = getProcAddress("glBindFramebufferEXT") + c.gpBindRenderbufferEXT = getProcAddress("glBindRenderbufferEXT") + c.gpBindTexture = getProcAddress("glBindTexture") + if c.gpBindTexture == 0 { + return errors.New("gl: glBindTexture is missing") + } + c.gpBlendEquationSeparate = getProcAddress("glBlendEquationSeparate") + if c.gpBlendEquationSeparate == 0 { + return errors.New("gl: glBlendEquationSeparate is missing") + } + c.gpBlendFuncSeparate = getProcAddress("glBlendFuncSeparate") + if c.gpBlendFuncSeparate == 0 { + return errors.New("gl: glBlendFuncSeparate is missing") + } + c.gpBufferData = getProcAddress("glBufferData") + if c.gpBufferData == 0 { + return errors.New("gl: glBufferData is missing") + } + c.gpBufferSubData = getProcAddress("glBufferSubData") + if c.gpBufferSubData == 0 { + return errors.New("gl: glBufferSubData is missing") + } + c.gpCheckFramebufferStatusEXT = getProcAddress("glCheckFramebufferStatusEXT") + c.gpClear = getProcAddress("glClear") + if c.gpClear == 0 { + return errors.New("gl: glClear is missing") + } + c.gpColorMask = getProcAddress("glColorMask") + if c.gpColorMask == 0 { + return errors.New("gl: glColorMask is missing") + } + c.gpCompileShader = getProcAddress("glCompileShader") + if c.gpCompileShader == 0 { + return errors.New("gl: glCompileShader is missing") + } + c.gpCreateProgram = getProcAddress("glCreateProgram") + if c.gpCreateProgram == 0 { + return errors.New("gl: glCreateProgram is missing") + } + c.gpCreateShader = getProcAddress("glCreateShader") + if c.gpCreateShader == 0 { + return errors.New("gl: glCreateShader is missing") + } + c.gpDeleteBuffers = getProcAddress("glDeleteBuffers") + if c.gpDeleteBuffers == 0 { + return errors.New("gl: glDeleteBuffers is missing") + } + c.gpDeleteFramebuffersEXT = getProcAddress("glDeleteFramebuffersEXT") + c.gpDeleteProgram = getProcAddress("glDeleteProgram") + if c.gpDeleteProgram == 0 { + return errors.New("gl: glDeleteProgram is missing") + } + c.gpDeleteRenderbuffersEXT = getProcAddress("glDeleteRenderbuffersEXT") + c.gpDeleteShader = getProcAddress("glDeleteShader") + if c.gpDeleteShader == 0 { + return errors.New("gl: glDeleteShader is missing") + } + c.gpDeleteTextures = getProcAddress("glDeleteTextures") + if c.gpDeleteTextures == 0 { + return errors.New("gl: glDeleteTextures is missing") + } + c.gpDisable = getProcAddress("glDisable") + if c.gpDisable == 0 { + return errors.New("gl: glDisable is missing") + } + c.gpDisableVertexAttribArray = getProcAddress("glDisableVertexAttribArray") + if c.gpDisableVertexAttribArray == 0 { + return errors.New("gl: glDisableVertexAttribArray is missing") + } + c.gpDrawElements = getProcAddress("glDrawElements") + if c.gpDrawElements == 0 { + return errors.New("gl: glDrawElements is missing") + } + c.gpEnable = getProcAddress("glEnable") + if c.gpEnable == 0 { + return errors.New("gl: glEnable is missing") + } + c.gpEnableVertexAttribArray = getProcAddress("glEnableVertexAttribArray") + if c.gpEnableVertexAttribArray == 0 { + return errors.New("gl: glEnableVertexAttribArray is missing") + } + c.gpFlush = getProcAddress("glFlush") + if c.gpFlush == 0 { + return errors.New("gl: glFlush is missing") + } + c.gpFramebufferRenderbufferEXT = getProcAddress("glFramebufferRenderbufferEXT") + c.gpFramebufferTexture2DEXT = getProcAddress("glFramebufferTexture2DEXT") + c.gpGenBuffers = getProcAddress("glGenBuffers") + if c.gpGenBuffers == 0 { + return errors.New("gl: glGenBuffers is missing") + } + c.gpGenFramebuffersEXT = getProcAddress("glGenFramebuffersEXT") + c.gpGenRenderbuffersEXT = getProcAddress("glGenRenderbuffersEXT") + c.gpGenTextures = getProcAddress("glGenTextures") + if c.gpGenTextures == 0 { + return errors.New("gl: glGenTextures is missing") + } + c.gpGetError = getProcAddress("glGetError") + if c.gpGetError == 0 { + return errors.New("gl: glGetError is missing") + } + c.gpGetIntegerv = getProcAddress("glGetIntegerv") + if c.gpGetIntegerv == 0 { + return errors.New("gl: glGetIntegerv is missing") + } + c.gpGetProgramInfoLog = getProcAddress("glGetProgramInfoLog") + if c.gpGetProgramInfoLog == 0 { + return errors.New("gl: glGetProgramInfoLog is missing") + } + c.gpGetProgramiv = getProcAddress("glGetProgramiv") + if c.gpGetProgramiv == 0 { + return errors.New("gl: glGetProgramiv is missing") + } + c.gpGetShaderInfoLog = getProcAddress("glGetShaderInfoLog") + if c.gpGetShaderInfoLog == 0 { + return errors.New("gl: glGetShaderInfoLog is missing") + } + c.gpGetShaderiv = getProcAddress("glGetShaderiv") + if c.gpGetShaderiv == 0 { + return errors.New("gl: glGetShaderiv is missing") + } + c.gpGetUniformLocation = getProcAddress("glGetUniformLocation") + if c.gpGetUniformLocation == 0 { + return errors.New("gl: glGetUniformLocation is missing") + } + c.gpIsFramebufferEXT = getProcAddress("glIsFramebufferEXT") + c.gpIsProgram = getProcAddress("glIsProgram") + if c.gpIsProgram == 0 { + return errors.New("gl: glIsProgram is missing") + } + c.gpIsRenderbufferEXT = getProcAddress("glIsRenderbufferEXT") + c.gpIsTexture = getProcAddress("glIsTexture") + if c.gpIsTexture == 0 { + return errors.New("gl: glIsTexture is missing") + } + c.gpLinkProgram = getProcAddress("glLinkProgram") + if c.gpLinkProgram == 0 { + return errors.New("gl: glLinkProgram is missing") + } + c.gpPixelStorei = getProcAddress("glPixelStorei") + if c.gpPixelStorei == 0 { + return errors.New("gl: glPixelStorei is missing") + } + c.gpReadPixels = getProcAddress("glReadPixels") + if c.gpReadPixels == 0 { + return errors.New("gl: glReadPixels is missing") + } + c.gpRenderbufferStorageEXT = getProcAddress("glRenderbufferStorageEXT") + c.gpScissor = getProcAddress("glScissor") + if c.gpScissor == 0 { + return errors.New("gl: glScissor is missing") + } + c.gpShaderSource = getProcAddress("glShaderSource") + if c.gpShaderSource == 0 { + return errors.New("gl: glShaderSource is missing") + } + c.gpStencilFunc = getProcAddress("glStencilFunc") + if c.gpStencilFunc == 0 { + return errors.New("gl: glStencilFunc is missing") + } + c.gpStencilOp = getProcAddress("glStencilOp") + if c.gpStencilOp == 0 { + return errors.New("gl: glStencilOp is missing") + } + c.gpTexImage2D = getProcAddress("glTexImage2D") + if c.gpTexImage2D == 0 { + return errors.New("gl: glTexImage2D is missing") + } + c.gpTexParameteri = getProcAddress("glTexParameteri") + if c.gpTexParameteri == 0 { + return errors.New("gl: glTexParameteri is missing") + } + c.gpTexSubImage2D = getProcAddress("glTexSubImage2D") + if c.gpTexSubImage2D == 0 { + return errors.New("gl: glTexSubImage2D is missing") + } + c.gpUniform1fv = getProcAddress("glUniform1fv") + if c.gpUniform1fv == 0 { + return errors.New("gl: glUniform1fv is missing") + } + c.gpUniform1i = getProcAddress("glUniform1i") + if c.gpUniform1i == 0 { + return errors.New("gl: glUniform1i is missing") + } + c.gpUniform1iv = getProcAddress("glUniform1iv") + if c.gpUniform1iv == 0 { + return errors.New("gl: glUniform1iv is missing") + } + c.gpUniform2fv = getProcAddress("glUniform2fv") + if c.gpUniform2fv == 0 { + return errors.New("gl: glUniform2fv is missing") + } + c.gpUniform3fv = getProcAddress("glUniform3fv") + if c.gpUniform3fv == 0 { + return errors.New("gl: glUniform3fv is missing") + } + c.gpUniform4fv = getProcAddress("glUniform4fv") + if c.gpUniform4fv == 0 { + return errors.New("gl: glUniform4fv is missing") + } + c.gpUniformMatrix2fv = getProcAddress("glUniformMatrix2fv") + if c.gpUniformMatrix2fv == 0 { + return errors.New("gl: glUniformMatrix2fv is missing") + } + c.gpUniformMatrix3fv = getProcAddress("glUniformMatrix3fv") + if c.gpUniformMatrix3fv == 0 { + return errors.New("gl: glUniformMatrix3fv is missing") + } + c.gpUniformMatrix4fv = getProcAddress("glUniformMatrix4fv") + if c.gpUniformMatrix4fv == 0 { + return errors.New("gl: glUniformMatrix4fv is missing") + } + c.gpUseProgram = getProcAddress("glUseProgram") + if c.gpUseProgram == 0 { + return errors.New("gl: glUseProgram is missing") + } + c.gpVertexAttribPointer = getProcAddress("glVertexAttribPointer") + if c.gpVertexAttribPointer == 0 { + return errors.New("gl: glVertexAttribPointer is missing") + } + c.gpViewport = getProcAddress("glViewport") + if c.gpViewport == 0 { + return errors.New("gl: glViewport is missing") + } + return nil +} diff --git a/internal/graphicsdriver/opengl/gl/gomobile.go b/internal/graphicsdriver/opengl/gl/gomobile.go index a2f05ee50..ce9db5d4a 100644 --- a/internal/graphicsdriver/opengl/gl/gomobile.go +++ b/internal/graphicsdriver/opengl/gl/gomobile.go @@ -35,6 +35,10 @@ func NewGomobileContext(ctx gl.Context) Context { return &gomobileContext{ctx} } +func (g *gomobileContext) Init() error { + return nil +} + func (g *gomobileContext) ActiveTexture(texture uint32) { g.ctx.ActiveTexture(gl.Enum(texture)) } diff --git a/internal/graphicsdriver/opengl/gl/interface.go b/internal/graphicsdriver/opengl/gl/interface.go index 7bf02acf0..82ca63a7a 100644 --- a/internal/graphicsdriver/opengl/gl/interface.go +++ b/internal/graphicsdriver/opengl/gl/interface.go @@ -14,7 +14,13 @@ package gl +// Context is a context for OpenGL (ES) functions. +// +// Context is basically the same as gomobile's gl.Context. +// See https://pkg.go.dev/golang.org/x/mobile/gl#Context type Context interface { + Init() error + ActiveTexture(texture uint32) AttachShader(program uint32, shader uint32) BindAttribLocation(program uint32, index uint32, name string) diff --git a/internal/graphicsdriver/opengl/gl/package.go b/internal/graphicsdriver/opengl/gl/package.go deleted file mode 100644 index f7988f297..000000000 --- a/internal/graphicsdriver/opengl/gl/package.go +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: MIT - -// Copyright (c) 2010 Khronos Group. -// This material may be distributed subject to the terms and conditions -// set forth in the Open Publication License, v 1.0, 8 June 1999. -// http://opencontent.org/openpub/. -// -// Copyright (c) 1991-2006 Silicon Graphics, Inc. -// This document is licensed under the SGI Free Software B License. -// For details, see http://oss.sgi.com/projects/FreeB. - -//go:build !android && !ios && !js && !opengles - -// Package gl implements Go bindings to OpenGL. -package gl - -// Init initializes the OpenGL bindings by loading the function pointers (for -// each OpenGL function) from the active OpenGL context. -// -// It must be called under the presence of an active OpenGL context, e.g., -// always after calling window.MakeContextCurrent() and always before calling -// any OpenGL functions exported by this package. -// -// On Windows, Init loads pointers that are context-specific (and hence you -// must re-init if switching between OpenGL contexts, although not calling Init -// again after switching between OpenGL contexts may work if the contexts belong -// to the same graphics driver/device). -// -// On macOS and the other POSIX systems, the behavior is different, but code -// written compatible with the Windows behavior is compatible with macOS and the -// other POSIX systems. That is, always Init under an active OpenGL context, and -// always re-init after switching graphics contexts. -// -// For information about caveats of Init, you should read the "Platform Specific -// Function Retrieval" section of https://www.opengl.org/wiki/Load_OpenGL_Functions. -func Init() error { - return InitWithProcAddrFunc(getProcAddress) -} diff --git a/internal/graphicsdriver/opengl/gl/package_purego.go b/internal/graphicsdriver/opengl/gl/package_purego.go deleted file mode 100644 index 93205005c..000000000 --- a/internal/graphicsdriver/opengl/gl/package_purego.go +++ /dev/null @@ -1,624 +0,0 @@ -// SPDX-License-Identifier: MIT - -//go:build darwin || windows - -package gl - -import ( - "errors" - "unsafe" - - "github.com/ebitengine/purego" -) - -var ( - gpActiveTexture uintptr - gpAttachShader uintptr - gpBindAttribLocation uintptr - gpBindBuffer uintptr - gpBindFramebufferEXT uintptr - gpBindRenderbufferEXT uintptr - gpBindTexture uintptr - gpBlendEquationSeparate uintptr - gpBlendFuncSeparate uintptr - gpBufferData uintptr - gpBufferSubData uintptr - gpCheckFramebufferStatusEXT uintptr - gpClear uintptr - gpColorMask uintptr - gpCompileShader uintptr - gpCreateProgram uintptr - gpCreateShader uintptr - gpDeleteBuffers uintptr - gpDeleteFramebuffersEXT uintptr - gpDeleteProgram uintptr - gpDeleteRenderbuffersEXT uintptr - gpDeleteShader uintptr - gpDeleteTextures uintptr - gpDisable uintptr - gpDisableVertexAttribArray uintptr - gpDrawElements uintptr - gpEnable uintptr - gpEnableVertexAttribArray uintptr - gpFlush uintptr - gpFramebufferRenderbufferEXT uintptr - gpFramebufferTexture2DEXT uintptr - gpGenBuffers uintptr - gpGenFramebuffersEXT uintptr - gpGenRenderbuffersEXT uintptr - gpGenTextures uintptr - gpGetError uintptr - gpGetIntegerv uintptr - gpGetProgramInfoLog uintptr - gpGetProgramiv uintptr - gpGetShaderInfoLog uintptr - gpGetShaderiv uintptr - gpGetUniformLocation uintptr - gpIsFramebufferEXT uintptr - gpIsProgram uintptr - gpIsRenderbufferEXT uintptr - gpIsTexture uintptr - gpLinkProgram uintptr - gpPixelStorei uintptr - gpReadPixels uintptr - gpRenderbufferStorageEXT uintptr - gpScissor uintptr - gpShaderSource uintptr - gpStencilFunc uintptr - gpStencilOp uintptr - gpTexImage2D uintptr - gpTexParameteri uintptr - gpTexSubImage2D uintptr - gpUniform1fv uintptr - gpUniform1i uintptr - gpUniform1iv uintptr - gpUniform2fv uintptr - gpUniform3fv uintptr - gpUniform4fv uintptr - gpUniformMatrix2fv uintptr - gpUniformMatrix3fv uintptr - gpUniformMatrix4fv uintptr - gpUseProgram uintptr - gpVertexAttribPointer uintptr - gpViewport uintptr -) - -func boolToInt(b bool) int { - if b { - return 1 - } - return 0 -} - -func ActiveTexture(texture uint32) { - purego.SyscallN(gpActiveTexture, uintptr(texture)) -} - -func AttachShader(program uint32, shader uint32) { - purego.SyscallN(gpAttachShader, uintptr(program), uintptr(shader)) -} - -func BindAttribLocation(program uint32, index uint32, name *uint8) { - purego.SyscallN(gpBindAttribLocation, uintptr(program), uintptr(index), uintptr(unsafe.Pointer(name))) -} - -func BindBuffer(target uint32, buffer uint32) { - purego.SyscallN(gpBindBuffer, uintptr(target), uintptr(buffer)) -} - -func BindFramebufferEXT(target uint32, framebuffer uint32) { - purego.SyscallN(gpBindFramebufferEXT, uintptr(target), uintptr(framebuffer)) -} - -func BindRenderbufferEXT(target uint32, renderbuffer uint32) { - purego.SyscallN(gpBindRenderbufferEXT, uintptr(target), uintptr(renderbuffer)) -} - -func BindTexture(target uint32, texture uint32) { - purego.SyscallN(gpBindTexture, uintptr(target), uintptr(texture)) -} - -func BlendEquationSeparate(modeRGB uint32, modeAlpha uint32) { - purego.SyscallN(gpBlendEquationSeparate, uintptr(modeRGB), uintptr(modeAlpha)) -} - -func BlendFuncSeparate(srcRGB uint32, dstRGB uint32, srcAlpha uint32, dstAlpha uint32) { - purego.SyscallN(gpBlendFuncSeparate, uintptr(srcRGB), uintptr(dstRGB), uintptr(srcAlpha), uintptr(dstAlpha)) -} - -func BufferData(target uint32, size int, data unsafe.Pointer, usage uint32) { - purego.SyscallN(gpBufferData, uintptr(target), uintptr(size), uintptr(data), uintptr(usage)) -} - -func BufferSubData(target uint32, offset int, size int, data unsafe.Pointer) { - purego.SyscallN(gpBufferSubData, uintptr(target), uintptr(offset), uintptr(size), uintptr(data)) -} - -func CheckFramebufferStatusEXT(target uint32) uint32 { - ret, _, _ := purego.SyscallN(gpCheckFramebufferStatusEXT, uintptr(target)) - return uint32(ret) -} - -func Clear(mask uint32) { - purego.SyscallN(gpClear, uintptr(mask)) -} - -func ColorMask(red bool, green bool, blue bool, alpha bool) { - purego.SyscallN(gpColorMask, uintptr(boolToInt(red)), uintptr(boolToInt(green)), uintptr(boolToInt(blue)), uintptr(boolToInt(alpha))) -} - -func CompileShader(shader uint32) { - purego.SyscallN(gpCompileShader, uintptr(shader)) -} - -func CreateProgram() uint32 { - ret, _, _ := purego.SyscallN(gpCreateProgram) - return uint32(ret) -} - -func CreateShader(xtype uint32) uint32 { - ret, _, _ := purego.SyscallN(gpCreateShader, uintptr(xtype)) - return uint32(ret) -} - -func DeleteBuffers(n int32, buffers *uint32) { - purego.SyscallN(gpDeleteBuffers, uintptr(n), uintptr(unsafe.Pointer(buffers))) -} - -func DeleteFramebuffersEXT(n int32, framebuffers *uint32) { - purego.SyscallN(gpDeleteFramebuffersEXT, uintptr(n), uintptr(unsafe.Pointer(framebuffers))) -} - -func DeleteProgram(program uint32) { - purego.SyscallN(gpDeleteProgram, uintptr(program)) -} - -func DeleteRenderbuffersEXT(n int32, renderbuffers *uint32) { - purego.SyscallN(gpDeleteRenderbuffersEXT, uintptr(n), uintptr(unsafe.Pointer(renderbuffers))) -} - -func DeleteShader(shader uint32) { - purego.SyscallN(gpDeleteShader, uintptr(shader)) -} - -func DeleteTextures(n int32, textures *uint32) { - purego.SyscallN(gpDeleteTextures, uintptr(n), uintptr(unsafe.Pointer(textures))) -} - -func Disable(cap uint32) { - purego.SyscallN(gpDisable, uintptr(cap)) -} - -func DisableVertexAttribArray(index uint32) { - purego.SyscallN(gpDisableVertexAttribArray, uintptr(index)) -} - -func DrawElements(mode uint32, count int32, xtype uint32, indices uintptr) { - purego.SyscallN(gpDrawElements, uintptr(mode), uintptr(count), uintptr(xtype), uintptr(indices)) -} - -func Enable(cap uint32) { - purego.SyscallN(gpEnable, uintptr(cap)) -} - -func EnableVertexAttribArray(index uint32) { - purego.SyscallN(gpEnableVertexAttribArray, uintptr(index)) -} - -func Flush() { - purego.SyscallN(gpFlush) -} - -func FramebufferRenderbufferEXT(target uint32, attachment uint32, renderbuffertarget uint32, renderbuffer uint32) { - purego.SyscallN(gpFramebufferRenderbufferEXT, uintptr(target), uintptr(attachment), uintptr(renderbuffertarget), uintptr(renderbuffer)) -} - -func FramebufferTexture2DEXT(target uint32, attachment uint32, textarget uint32, texture uint32, level int32) { - purego.SyscallN(gpFramebufferTexture2DEXT, uintptr(target), uintptr(attachment), uintptr(textarget), uintptr(texture), uintptr(level)) -} - -func GenBuffers(n int32, buffers *uint32) { - purego.SyscallN(gpGenBuffers, uintptr(n), uintptr(unsafe.Pointer(buffers))) -} - -func GenFramebuffersEXT(n int32, framebuffers *uint32) { - purego.SyscallN(gpGenFramebuffersEXT, uintptr(n), uintptr(unsafe.Pointer(framebuffers))) -} - -func GenRenderbuffersEXT(n int32, renderbuffers *uint32) { - purego.SyscallN(gpGenRenderbuffersEXT, uintptr(n), uintptr(unsafe.Pointer(renderbuffers))) -} - -func GenTextures(n int32, textures *uint32) { - purego.SyscallN(gpGenTextures, uintptr(n), uintptr(unsafe.Pointer(textures))) -} - -func GetError() uint32 { - ret, _, _ := purego.SyscallN(gpGetError) - return uint32(ret) -} - -func GetIntegerv(pname uint32, data *int32) { - purego.SyscallN(gpGetIntegerv, uintptr(pname), uintptr(unsafe.Pointer(data))) -} - -func GetProgramInfoLog(program uint32, bufSize int32, length *int32, infoLog *uint8) { - purego.SyscallN(gpGetProgramInfoLog, uintptr(program), uintptr(bufSize), uintptr(unsafe.Pointer(length)), uintptr(unsafe.Pointer(infoLog))) -} - -func GetProgramiv(program uint32, pname uint32, params *int32) { - purego.SyscallN(gpGetProgramiv, uintptr(program), uintptr(pname), uintptr(unsafe.Pointer(params))) -} - -func GetShaderInfoLog(shader uint32, bufSize int32, length *int32, infoLog *uint8) { - purego.SyscallN(gpGetShaderInfoLog, uintptr(shader), uintptr(bufSize), uintptr(unsafe.Pointer(length)), uintptr(unsafe.Pointer(infoLog))) -} - -func GetShaderiv(shader uint32, pname uint32, params *int32) { - purego.SyscallN(gpGetShaderiv, uintptr(shader), uintptr(pname), uintptr(unsafe.Pointer(params))) -} - -func GetUniformLocation(program uint32, name *uint8) int32 { - ret, _, _ := purego.SyscallN(gpGetUniformLocation, uintptr(program), uintptr(unsafe.Pointer(name))) - return int32(ret) -} - -func IsFramebufferEXT(framebuffer uint32) bool { - ret, _, _ := purego.SyscallN(gpIsFramebufferEXT, uintptr(framebuffer)) - return byte(ret) != 0 -} - -func IsProgram(program uint32) bool { - ret, _, _ := purego.SyscallN(gpIsProgram, uintptr(program)) - return byte(ret) != 0 -} - -func IsRenderbufferEXT(renderbuffer uint32) bool { - ret, _, _ := purego.SyscallN(gpIsRenderbufferEXT, uintptr(renderbuffer)) - return byte(ret) != 0 -} - -func IsTexture(texture uint32) bool { - ret, _, _ := purego.SyscallN(gpIsTexture, uintptr(texture)) - return byte(ret) != 0 -} - -func LinkProgram(program uint32) { - purego.SyscallN(gpLinkProgram, uintptr(program)) -} - -func PixelStorei(pname uint32, param int32) { - purego.SyscallN(gpPixelStorei, uintptr(pname), uintptr(param)) -} - -func ReadPixels(x int32, y int32, width int32, height int32, format uint32, xtype uint32, pixels unsafe.Pointer) { - purego.SyscallN(gpReadPixels, uintptr(x), uintptr(y), uintptr(width), uintptr(height), uintptr(format), uintptr(xtype), uintptr(pixels)) -} - -func RenderbufferStorageEXT(target uint32, internalformat uint32, width int32, height int32) { - purego.SyscallN(gpRenderbufferStorageEXT, uintptr(target), uintptr(internalformat), uintptr(width), uintptr(height)) -} - -func Scissor(x int32, y int32, width int32, height int32) { - purego.SyscallN(gpScissor, uintptr(x), uintptr(y), uintptr(width), uintptr(height)) -} - -func ShaderSource(shader uint32, count int32, xstring **uint8, length *int32) { - purego.SyscallN(gpShaderSource, uintptr(shader), uintptr(count), uintptr(unsafe.Pointer(xstring)), uintptr(unsafe.Pointer(length))) -} - -func StencilFunc(xfunc uint32, ref int32, mask uint32) { - purego.SyscallN(gpStencilFunc, uintptr(xfunc), uintptr(ref), uintptr(mask)) -} - -func StencilOp(fail uint32, zfail uint32, zpass uint32) { - purego.SyscallN(gpStencilOp, uintptr(fail), uintptr(zfail), uintptr(zpass)) -} - -func TexImage2D(target uint32, level int32, internalformat int32, width int32, height int32, border int32, format uint32, xtype uint32, pixels unsafe.Pointer) { - purego.SyscallN(gpTexImage2D, uintptr(target), uintptr(level), uintptr(internalformat), uintptr(width), uintptr(height), uintptr(border), uintptr(format), uintptr(xtype), uintptr(pixels)) -} - -func TexParameteri(target uint32, pname uint32, param int32) { - purego.SyscallN(gpTexParameteri, uintptr(target), uintptr(pname), uintptr(param)) -} - -func TexSubImage2D(target uint32, level int32, xoffset int32, yoffset int32, width int32, height int32, format uint32, xtype uint32, pixels unsafe.Pointer) { - purego.SyscallN(gpTexSubImage2D, uintptr(target), uintptr(level), uintptr(xoffset), uintptr(yoffset), uintptr(width), uintptr(height), uintptr(format), uintptr(xtype), uintptr(pixels)) -} - -func Uniform1fv(location int32, count int32, value *float32) { - purego.SyscallN(gpUniform1fv, uintptr(location), uintptr(count), uintptr(unsafe.Pointer(value))) -} - -func Uniform1i(location int32, v0 int32) { - purego.SyscallN(gpUniform1i, uintptr(location), uintptr(v0)) -} - -func Uniform1iv(location int32, count int32, value *int32) { - purego.SyscallN(gpUniform1iv, uintptr(location), uintptr(count), uintptr(unsafe.Pointer(value))) -} - -func Uniform2fv(location int32, count int32, value *float32) { - purego.SyscallN(gpUniform2fv, uintptr(location), uintptr(count), uintptr(unsafe.Pointer(value))) -} - -func Uniform3fv(location int32, count int32, value *float32) { - purego.SyscallN(gpUniform3fv, uintptr(location), uintptr(count), uintptr(unsafe.Pointer(value))) -} - -func Uniform4fv(location int32, count int32, value *float32) { - purego.SyscallN(gpUniform4fv, uintptr(location), uintptr(count), uintptr(unsafe.Pointer(value))) -} - -func UniformMatrix2fv(location int32, count int32, transpose bool, value *float32) { - purego.SyscallN(gpUniformMatrix2fv, uintptr(location), uintptr(count), uintptr(boolToInt(transpose)), uintptr(unsafe.Pointer(value))) -} - -func UniformMatrix3fv(location int32, count int32, transpose bool, value *float32) { - purego.SyscallN(gpUniformMatrix3fv, uintptr(location), uintptr(count), uintptr(boolToInt(transpose)), uintptr(unsafe.Pointer(value))) -} - -func UniformMatrix4fv(location int32, count int32, transpose bool, value *float32) { - purego.SyscallN(gpUniformMatrix4fv, uintptr(location), uintptr(count), uintptr(boolToInt(transpose)), uintptr(unsafe.Pointer(value))) -} - -func UseProgram(program uint32) { - purego.SyscallN(gpUseProgram, uintptr(program)) -} - -func VertexAttribPointer(index uint32, size int32, xtype uint32, normalized bool, stride int32, pointer uintptr) { - purego.SyscallN(gpVertexAttribPointer, uintptr(index), uintptr(size), uintptr(xtype), uintptr(boolToInt(normalized)), uintptr(stride), uintptr(pointer)) -} - -func Viewport(x int32, y int32, width int32, height int32) { - purego.SyscallN(gpViewport, uintptr(x), uintptr(y), uintptr(width), uintptr(height)) -} - -// InitWithProcAddrFunc intializes the package using the specified OpenGL -// function pointer loading function. -// -// For more cases Init should be used. -func InitWithProcAddrFunc(getProcAddr func(name string) uintptr) error { - gpActiveTexture = getProcAddr("glActiveTexture") - if gpActiveTexture == 0 { - return errors.New("gl: glActiveTexture is missing") - } - gpAttachShader = getProcAddr("glAttachShader") - if gpAttachShader == 0 { - return errors.New("gl: glAttachShader is missing") - } - gpBindAttribLocation = getProcAddr("glBindAttribLocation") - if gpBindAttribLocation == 0 { - return errors.New("gl: glBindAttribLocation is missing") - } - gpBindBuffer = getProcAddr("glBindBuffer") - if gpBindBuffer == 0 { - return errors.New("gl: glBindBuffer is missing") - } - gpBindFramebufferEXT = getProcAddr("glBindFramebufferEXT") - gpBindRenderbufferEXT = getProcAddr("glBindRenderbufferEXT") - gpBindTexture = getProcAddr("glBindTexture") - if gpBindTexture == 0 { - return errors.New("gl: glBindTexture is missing") - } - gpBlendEquationSeparate = getProcAddr("glBlendEquationSeparate") - if gpBlendEquationSeparate == 0 { - return errors.New("gl: glBlendEquationSeparate is missing") - } - gpBlendFuncSeparate = getProcAddr("glBlendFuncSeparate") - if gpBlendFuncSeparate == 0 { - return errors.New("gl: glBlendFuncSeparate is missing") - } - gpBufferData = getProcAddr("glBufferData") - if gpBufferData == 0 { - return errors.New("gl: glBufferData is missing") - } - gpBufferSubData = getProcAddr("glBufferSubData") - if gpBufferSubData == 0 { - return errors.New("gl: glBufferSubData is missing") - } - gpCheckFramebufferStatusEXT = getProcAddr("glCheckFramebufferStatusEXT") - gpClear = getProcAddr("glClear") - if gpClear == 0 { - return errors.New("gl: glClear is missing") - } - gpColorMask = getProcAddr("glColorMask") - if gpColorMask == 0 { - return errors.New("gl: glColorMask is missing") - } - gpCompileShader = getProcAddr("glCompileShader") - if gpCompileShader == 0 { - return errors.New("gl: glCompileShader is missing") - } - gpCreateProgram = getProcAddr("glCreateProgram") - if gpCreateProgram == 0 { - return errors.New("gl: glCreateProgram is missing") - } - gpCreateShader = getProcAddr("glCreateShader") - if gpCreateShader == 0 { - return errors.New("gl: glCreateShader is missing") - } - gpDeleteBuffers = getProcAddr("glDeleteBuffers") - if gpDeleteBuffers == 0 { - return errors.New("gl: glDeleteBuffers is missing") - } - gpDeleteFramebuffersEXT = getProcAddr("glDeleteFramebuffersEXT") - gpDeleteProgram = getProcAddr("glDeleteProgram") - if gpDeleteProgram == 0 { - return errors.New("gl: glDeleteProgram is missing") - } - gpDeleteRenderbuffersEXT = getProcAddr("glDeleteRenderbuffersEXT") - gpDeleteShader = getProcAddr("glDeleteShader") - if gpDeleteShader == 0 { - return errors.New("gl: glDeleteShader is missing") - } - gpDeleteTextures = getProcAddr("glDeleteTextures") - if gpDeleteTextures == 0 { - return errors.New("gl: glDeleteTextures is missing") - } - gpDisable = getProcAddr("glDisable") - if gpDisable == 0 { - return errors.New("gl: glDisable is missing") - } - gpDisableVertexAttribArray = getProcAddr("glDisableVertexAttribArray") - if gpDisableVertexAttribArray == 0 { - return errors.New("gl: glDisableVertexAttribArray is missing") - } - gpDrawElements = getProcAddr("glDrawElements") - if gpDrawElements == 0 { - return errors.New("gl: glDrawElements is missing") - } - gpEnable = getProcAddr("glEnable") - if gpEnable == 0 { - return errors.New("gl: glEnable is missing") - } - gpEnableVertexAttribArray = getProcAddr("glEnableVertexAttribArray") - if gpEnableVertexAttribArray == 0 { - return errors.New("gl: glEnableVertexAttribArray is missing") - } - gpFlush = getProcAddr("glFlush") - if gpFlush == 0 { - return errors.New("gl: glFlush is missing") - } - gpFramebufferRenderbufferEXT = getProcAddr("glFramebufferRenderbufferEXT") - gpFramebufferTexture2DEXT = getProcAddr("glFramebufferTexture2DEXT") - gpGenBuffers = getProcAddr("glGenBuffers") - if gpGenBuffers == 0 { - return errors.New("gl: glGenBuffers is missing") - } - gpGenFramebuffersEXT = getProcAddr("glGenFramebuffersEXT") - gpGenRenderbuffersEXT = getProcAddr("glGenRenderbuffersEXT") - gpGenTextures = getProcAddr("glGenTextures") - if gpGenTextures == 0 { - return errors.New("gl: glGenTextures is missing") - } - gpGetError = getProcAddr("glGetError") - if gpGetError == 0 { - return errors.New("gl: glGetError is missing") - } - gpGetIntegerv = getProcAddr("glGetIntegerv") - if gpGetIntegerv == 0 { - return errors.New("gl: glGetIntegerv is missing") - } - gpGetProgramInfoLog = getProcAddr("glGetProgramInfoLog") - if gpGetProgramInfoLog == 0 { - return errors.New("gl: glGetProgramInfoLog is missing") - } - gpGetProgramiv = getProcAddr("glGetProgramiv") - if gpGetProgramiv == 0 { - return errors.New("gl: glGetProgramiv is missing") - } - gpGetShaderInfoLog = getProcAddr("glGetShaderInfoLog") - if gpGetShaderInfoLog == 0 { - return errors.New("gl: glGetShaderInfoLog is missing") - } - gpGetShaderiv = getProcAddr("glGetShaderiv") - if gpGetShaderiv == 0 { - return errors.New("gl: glGetShaderiv is missing") - } - gpGetUniformLocation = getProcAddr("glGetUniformLocation") - if gpGetUniformLocation == 0 { - return errors.New("gl: glGetUniformLocation is missing") - } - gpIsFramebufferEXT = getProcAddr("glIsFramebufferEXT") - gpIsProgram = getProcAddr("glIsProgram") - if gpIsProgram == 0 { - return errors.New("gl: glIsProgram is missing") - } - gpIsRenderbufferEXT = getProcAddr("glIsRenderbufferEXT") - gpIsTexture = getProcAddr("glIsTexture") - if gpIsTexture == 0 { - return errors.New("gl: glIsTexture is missing") - } - gpLinkProgram = getProcAddr("glLinkProgram") - if gpLinkProgram == 0 { - return errors.New("gl: glLinkProgram is missing") - } - gpPixelStorei = getProcAddr("glPixelStorei") - if gpPixelStorei == 0 { - return errors.New("gl: glPixelStorei is missing") - } - gpReadPixels = getProcAddr("glReadPixels") - if gpReadPixels == 0 { - return errors.New("gl: glReadPixels is missing") - } - gpRenderbufferStorageEXT = getProcAddr("glRenderbufferStorageEXT") - gpScissor = getProcAddr("glScissor") - if gpScissor == 0 { - return errors.New("gl: glScissor is missing") - } - gpShaderSource = getProcAddr("glShaderSource") - if gpShaderSource == 0 { - return errors.New("gl: glShaderSource is missing") - } - gpStencilFunc = getProcAddr("glStencilFunc") - if gpStencilFunc == 0 { - return errors.New("gl: glStencilFunc is missing") - } - gpStencilOp = getProcAddr("glStencilOp") - if gpStencilOp == 0 { - return errors.New("gl: glStencilOp is missing") - } - gpTexImage2D = getProcAddr("glTexImage2D") - if gpTexImage2D == 0 { - return errors.New("gl: glTexImage2D is missing") - } - gpTexParameteri = getProcAddr("glTexParameteri") - if gpTexParameteri == 0 { - return errors.New("gl: glTexParameteri is missing") - } - gpTexSubImage2D = getProcAddr("glTexSubImage2D") - if gpTexSubImage2D == 0 { - return errors.New("gl: glTexSubImage2D is missing") - } - gpUniform1fv = getProcAddr("glUniform1fv") - if gpUniform1fv == 0 { - return errors.New("gl: glUniform1fv is missing") - } - gpUniform1i = getProcAddr("glUniform1i") - if gpUniform1i == 0 { - return errors.New("gl: glUniform1i is missing") - } - gpUniform1iv = getProcAddr("glUniform1iv") - if gpUniform1iv == 0 { - return errors.New("gl: glUniform1iv is missing") - } - gpUniform2fv = getProcAddr("glUniform2fv") - if gpUniform2fv == 0 { - return errors.New("gl: glUniform2fv is missing") - } - gpUniform3fv = getProcAddr("glUniform3fv") - if gpUniform3fv == 0 { - return errors.New("gl: glUniform3fv is missing") - } - gpUniform4fv = getProcAddr("glUniform4fv") - if gpUniform4fv == 0 { - return errors.New("gl: glUniform4fv is missing") - } - gpUniformMatrix2fv = getProcAddr("glUniformMatrix2fv") - if gpUniformMatrix2fv == 0 { - return errors.New("gl: glUniformMatrix2fv is missing") - } - gpUniformMatrix3fv = getProcAddr("glUniformMatrix3fv") - if gpUniformMatrix3fv == 0 { - return errors.New("gl: glUniformMatrix3fv is missing") - } - gpUniformMatrix4fv = getProcAddr("glUniformMatrix4fv") - if gpUniformMatrix4fv == 0 { - return errors.New("gl: glUniformMatrix4fv is missing") - } - gpUseProgram = getProcAddr("glUseProgram") - if gpUseProgram == 0 { - return errors.New("gl: glUseProgram is missing") - } - gpVertexAttribPointer = getProcAddr("glVertexAttribPointer") - if gpVertexAttribPointer == 0 { - return errors.New("gl: glVertexAttribPointer is missing") - } - gpViewport = getProcAddr("glViewport") - if gpViewport == 0 { - return errors.New("gl: glViewport is missing") - } - return nil -} diff --git a/internal/graphicsdriver/opengl/gl/procaddr_darwin.go b/internal/graphicsdriver/opengl/gl/procaddr_darwin.go index a54387d20..38a537b33 100644 --- a/internal/graphicsdriver/opengl/gl/procaddr_darwin.go +++ b/internal/graphicsdriver/opengl/gl/procaddr_darwin.go @@ -1,4 +1,5 @@ // SPDX-License-Identifier: MIT +// SPDX-FileCopyrightText: 2014 Eric Woroshow package gl diff --git a/internal/graphicsdriver/opengl/gl/procaddr_others.go b/internal/graphicsdriver/opengl/gl/procaddr_others.go index 3f1ade31d..1a2e9b2a9 100644 --- a/internal/graphicsdriver/opengl/gl/procaddr_others.go +++ b/internal/graphicsdriver/opengl/gl/procaddr_others.go @@ -1,4 +1,5 @@ // SPDX-License-Identifier: MIT +// SPDX-FileCopyrightText: 2014 Eric Woroshow //go:build !android && !darwin && !js && !windows && !opengles diff --git a/internal/graphicsdriver/opengl/gl/procaddr_windows.go b/internal/graphicsdriver/opengl/gl/procaddr_windows.go index b72d67693..0fcaddc2d 100644 --- a/internal/graphicsdriver/opengl/gl/procaddr_windows.go +++ b/internal/graphicsdriver/opengl/gl/procaddr_windows.go @@ -1,4 +1,5 @@ // SPDX-License-Identifier: MIT +// SPDX-FileCopyrightText: 2014 Eric Woroshow package gl @@ -25,7 +26,7 @@ func getProcAddress(namea string) uintptr { return r } if err != nil && err != windows.ERROR_SUCCESS && err != windows.ERROR_PROC_NOT_FOUND { - panic(fmt.Sprintf("gl: wglGetProcAddress failed: %s", err.Error())) + panic(fmt.Sprintf("gl: wglGetProcAddress failed for %s: %s", namea, err.Error())) } p := opengl32.NewProc(namea) diff --git a/internal/graphicsdriver/opengl/graphics_gl.go b/internal/graphicsdriver/opengl/graphics_default.go similarity index 88% rename from internal/graphicsdriver/opengl/graphics_gl.go rename to internal/graphicsdriver/opengl/graphics_default.go index 31a1e5df9..8965a97bb 100644 --- a/internal/graphicsdriver/opengl/graphics_gl.go +++ b/internal/graphicsdriver/opengl/graphics_default.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:build !android && !ios && !js && !opengles +//go:build !android && !ios && !js package opengl @@ -20,6 +20,7 @@ import ( "fmt" "github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver" + "github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl/gl" "github.com/hajimehoshi/ebiten/v2/internal/microsoftgdk" ) @@ -29,6 +30,8 @@ func NewGraphics() (graphicsdriver.Graphics, error) { if microsoftgdk.IsXbox() { return nil, fmt.Errorf("opengl: OpenGL is not supported on Xbox") } + g := &Graphics{} + g.context.ctx = gl.NewDefaultContext() return g, nil } diff --git a/internal/graphicsdriver/opengl/graphics_gles.go b/internal/graphicsdriver/opengl/graphics_gles.go deleted file mode 100644 index 6975c6dc8..000000000 --- a/internal/graphicsdriver/opengl/graphics_gles.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2022 The Ebitengine 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. - -//go:build !android && !ios && !js && opengles - -package opengl - -import ( - "github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver" - "github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl/gl" -) - -// NewGraphics creates an implementation of graphicsdriver.Graphics for OpenGL. -// The returned graphics value is nil iff the error is not nil. -func NewGraphics() (graphicsdriver.Graphics, error) { - g := &Graphics{} - g.context.ctx = gl.NewDefaultContext() - return g, nil -} diff --git a/internal/graphicsdriver/opengl/graphics_mobile.go b/internal/graphicsdriver/opengl/graphics_mobile.go index cf3ab252c..d23e6560f 100644 --- a/internal/graphicsdriver/opengl/graphics_mobile.go +++ b/internal/graphicsdriver/opengl/graphics_mobile.go @@ -26,11 +26,15 @@ import ( // NewGraphics creates an implementation of graphicsdriver.Graphics for OpenGL. // The returned graphics value is nil iff the error is not nil. func NewGraphics(context mgl.Context) (graphicsdriver.Graphics, error) { - g := &Graphics{} + var ctx gl.Context if context != nil { - g.context.ctx = gl.NewGomobileContext(context.(mgl.Context)) + ctx = gl.NewGomobileContext(context.(mgl.Context)) } else { - g.context.ctx = gl.NewDefaultContext() + ctx = gl.NewDefaultContext() } + + g := &Graphics{} + g.context.ctx = ctx + return g, nil }