vendor dependencies, make some changes to how input is done
This commit is contained in:
Generated
Vendored
+498
@@ -0,0 +1,498 @@
|
||||
// Copyright 2016 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 !playstation5
|
||||
|
||||
package opengl
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"image"
|
||||
"sync"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl/gl"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/shaderir"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/shaderir/glsl"
|
||||
)
|
||||
|
||||
type blendFactor int
|
||||
|
||||
type blendOperation int
|
||||
|
||||
func convertBlendFactor(f graphicsdriver.BlendFactor) blendFactor {
|
||||
switch f {
|
||||
case graphicsdriver.BlendFactorZero:
|
||||
return gl.ZERO
|
||||
case graphicsdriver.BlendFactorOne:
|
||||
return gl.ONE
|
||||
case graphicsdriver.BlendFactorSourceColor:
|
||||
return gl.SRC_COLOR
|
||||
case graphicsdriver.BlendFactorOneMinusSourceColor:
|
||||
return gl.ONE_MINUS_SRC_COLOR
|
||||
case graphicsdriver.BlendFactorSourceAlpha:
|
||||
return gl.SRC_ALPHA
|
||||
case graphicsdriver.BlendFactorOneMinusSourceAlpha:
|
||||
return gl.ONE_MINUS_SRC_ALPHA
|
||||
case graphicsdriver.BlendFactorDestinationColor:
|
||||
return gl.DST_COLOR
|
||||
case graphicsdriver.BlendFactorOneMinusDestinationColor:
|
||||
return gl.ONE_MINUS_DST_COLOR
|
||||
case graphicsdriver.BlendFactorDestinationAlpha:
|
||||
return gl.DST_ALPHA
|
||||
case graphicsdriver.BlendFactorOneMinusDestinationAlpha:
|
||||
return gl.ONE_MINUS_DST_ALPHA
|
||||
case graphicsdriver.BlendFactorSourceAlphaSaturated:
|
||||
return gl.SRC_ALPHA_SATURATE
|
||||
default:
|
||||
panic(fmt.Sprintf("opengl: invalid blend factor %d", f))
|
||||
}
|
||||
}
|
||||
|
||||
func convertBlendOperation(o graphicsdriver.BlendOperation) blendOperation {
|
||||
switch o {
|
||||
case graphicsdriver.BlendOperationAdd:
|
||||
return gl.FUNC_ADD
|
||||
case graphicsdriver.BlendOperationSubtract:
|
||||
return gl.FUNC_SUBTRACT
|
||||
case graphicsdriver.BlendOperationReverseSubtract:
|
||||
return gl.FUNC_REVERSE_SUBTRACT
|
||||
case graphicsdriver.BlendOperationMin:
|
||||
return gl.MIN
|
||||
case graphicsdriver.BlendOperationMax:
|
||||
return gl.MAX
|
||||
default:
|
||||
panic(fmt.Sprintf("opengl: invalid blend operation %d", o))
|
||||
}
|
||||
}
|
||||
|
||||
type (
|
||||
textureNative uint32
|
||||
renderbufferNative uint32
|
||||
framebufferNative uint32
|
||||
shader uint32
|
||||
program uint32
|
||||
buffer uint32
|
||||
)
|
||||
|
||||
type (
|
||||
uniformLocation int32
|
||||
attribLocation int32
|
||||
)
|
||||
|
||||
const (
|
||||
invalidFramebuffer = (1 << 32) - 1
|
||||
invalidUniform = -1
|
||||
)
|
||||
|
||||
type context struct {
|
||||
ctx gl.Context
|
||||
|
||||
locationCache *locationCache
|
||||
screenFramebuffer framebufferNative // This might not be the default frame buffer '0' (e.g. iOS).
|
||||
lastFramebuffer framebufferNative
|
||||
lastTexture textureNative
|
||||
lastRenderbuffer renderbufferNative
|
||||
lastViewportWidth int
|
||||
lastViewportHeight int
|
||||
lastBlend graphicsdriver.Blend
|
||||
maxTextureSize int
|
||||
maxTextureSizeOnce sync.Once
|
||||
highp bool
|
||||
highpOnce sync.Once
|
||||
initOnce sync.Once
|
||||
}
|
||||
|
||||
func (c *context) bindTexture(t textureNative) {
|
||||
if c.lastTexture == t {
|
||||
return
|
||||
}
|
||||
c.ctx.BindTexture(gl.TEXTURE_2D, uint32(t))
|
||||
c.lastTexture = t
|
||||
}
|
||||
|
||||
func (c *context) bindRenderbuffer(r renderbufferNative) {
|
||||
if c.lastRenderbuffer == r {
|
||||
return
|
||||
}
|
||||
c.ctx.BindRenderbuffer(gl.RENDERBUFFER, uint32(r))
|
||||
c.lastRenderbuffer = r
|
||||
}
|
||||
|
||||
func (c *context) bindFramebuffer(f framebufferNative) {
|
||||
if c.lastFramebuffer == f {
|
||||
return
|
||||
}
|
||||
c.ctx.BindFramebuffer(gl.FRAMEBUFFER, uint32(f))
|
||||
c.lastFramebuffer = f
|
||||
}
|
||||
|
||||
func (c *context) setViewport(f *framebuffer) {
|
||||
c.bindFramebuffer(f.native)
|
||||
if c.lastViewportWidth == f.width && c.lastViewportHeight == f.height {
|
||||
return
|
||||
}
|
||||
|
||||
// On some environments, viewport size must be within the framebuffer size.
|
||||
// e.g. Edge (#71), Chrome on GPD Pocket (#420), macOS Mojave (#691).
|
||||
// Use the same size of the framebuffer here.
|
||||
c.ctx.Viewport(0, 0, int32(f.width), int32(f.height))
|
||||
|
||||
// glViewport must be called at least at every frame on iOS.
|
||||
// As the screen framebuffer is the last render target, next SetViewport should be
|
||||
// the first call at a frame.
|
||||
if f.native == c.screenFramebuffer {
|
||||
c.lastViewportWidth = 0
|
||||
c.lastViewportHeight = 0
|
||||
} else {
|
||||
c.lastViewportWidth = f.width
|
||||
c.lastViewportHeight = f.height
|
||||
}
|
||||
}
|
||||
|
||||
func (c *context) newScreenFramebuffer(width, height int) *framebuffer {
|
||||
return &framebuffer{
|
||||
native: c.screenFramebuffer,
|
||||
width: width,
|
||||
height: height,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *context) getMaxTextureSize() int {
|
||||
c.maxTextureSizeOnce.Do(func() {
|
||||
c.maxTextureSize = c.ctx.GetInteger(gl.MAX_TEXTURE_SIZE)
|
||||
})
|
||||
return c.maxTextureSize
|
||||
}
|
||||
|
||||
func (c *context) reset() error {
|
||||
var err1 error
|
||||
c.initOnce.Do(func() {
|
||||
// Load OpenGL functions after WGL is initialized especially for Windows (#2452).
|
||||
if err := c.ctx.LoadFunctions(); err != nil {
|
||||
err1 = err
|
||||
return
|
||||
}
|
||||
})
|
||||
if err1 != nil {
|
||||
return err1
|
||||
}
|
||||
|
||||
c.locationCache = newLocationCache()
|
||||
c.lastTexture = 0
|
||||
c.lastFramebuffer = invalidFramebuffer
|
||||
c.lastViewportWidth = 0
|
||||
c.lastViewportHeight = 0
|
||||
c.lastBlend = graphicsdriver.Blend{}
|
||||
|
||||
c.ctx.Enable(gl.BLEND)
|
||||
c.ctx.Enable(gl.SCISSOR_TEST)
|
||||
c.blend(graphicsdriver.BlendSourceOver)
|
||||
c.screenFramebuffer = framebufferNative(c.ctx.GetInteger(gl.FRAMEBUFFER_BINDING))
|
||||
// TODO: Need to update screenFramebufferWidth/Height?
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *context) blend(blend graphicsdriver.Blend) {
|
||||
if c.lastBlend == blend {
|
||||
return
|
||||
}
|
||||
c.lastBlend = blend
|
||||
c.ctx.BlendFuncSeparate(
|
||||
uint32(convertBlendFactor(blend.BlendFactorSourceRGB)),
|
||||
uint32(convertBlendFactor(blend.BlendFactorDestinationRGB)),
|
||||
uint32(convertBlendFactor(blend.BlendFactorSourceAlpha)),
|
||||
uint32(convertBlendFactor(blend.BlendFactorDestinationAlpha)),
|
||||
)
|
||||
c.ctx.BlendEquationSeparate(
|
||||
uint32(convertBlendOperation(blend.BlendOperationRGB)),
|
||||
uint32(convertBlendOperation(blend.BlendOperationAlpha)),
|
||||
)
|
||||
}
|
||||
|
||||
func (c *context) newTexture(width, height int) (textureNative, error) {
|
||||
t := c.ctx.CreateTexture()
|
||||
if t <= 0 {
|
||||
return 0, errors.New("opengl: creating texture failed")
|
||||
}
|
||||
c.bindTexture(textureNative(t))
|
||||
|
||||
c.ctx.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
|
||||
c.ctx.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
|
||||
c.ctx.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
|
||||
c.ctx.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
|
||||
c.ctx.PixelStorei(gl.UNPACK_ALIGNMENT, 4)
|
||||
|
||||
// Firefox warns the usage of textures without specifying pixels (#629, #2077)
|
||||
//
|
||||
// Error: WebGL warning: drawElements: This operation requires zeroing texture data. This is slow.
|
||||
//
|
||||
// In Ebitengine, textures are filled with pixels later by the filter that ignores destination, so it is fine
|
||||
// to leave textures as uninitialized here. Rather, extra memory allocating for initialization should be
|
||||
// avoided.
|
||||
//
|
||||
// See also https://stackoverflow.com/questions/57734645.
|
||||
c.ctx.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int32(width), int32(height), gl.RGBA, gl.UNSIGNED_BYTE, nil)
|
||||
|
||||
return textureNative(t), nil
|
||||
}
|
||||
|
||||
func (c *context) framebufferPixels(buf []byte, f *framebuffer, region image.Rectangle) error {
|
||||
if got, want := len(buf), 4*region.Dx()*region.Dy(); got != want {
|
||||
return fmt.Errorf("opengl: len(buf) must be %d but was %d at framebufferPixels", got, want)
|
||||
}
|
||||
|
||||
c.ctx.Flush()
|
||||
c.bindFramebuffer(f.native)
|
||||
x := int32(region.Min.X)
|
||||
y := int32(region.Min.Y)
|
||||
width := int32(region.Dx())
|
||||
height := int32(region.Dy())
|
||||
c.ctx.ReadPixels(buf, x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *context) framebufferPixelsToBuffer(f *framebuffer, buffer buffer, width, height int) {
|
||||
c.ctx.Flush()
|
||||
|
||||
c.bindFramebuffer(f.native)
|
||||
|
||||
c.ctx.BindBuffer(gl.PIXEL_PACK_BUFFER, uint32(buffer))
|
||||
c.ctx.ReadPixels(nil, 0, 0, int32(width), int32(height), gl.RGBA, gl.UNSIGNED_BYTE)
|
||||
c.ctx.BindBuffer(gl.PIXEL_PACK_BUFFER, 0)
|
||||
}
|
||||
|
||||
func (c *context) deleteTexture(t textureNative) {
|
||||
if c.lastTexture == t {
|
||||
c.lastTexture = 0
|
||||
}
|
||||
c.ctx.DeleteTexture(uint32(t))
|
||||
}
|
||||
|
||||
func (c *context) newRenderbuffer(width, height int) (renderbufferNative, error) {
|
||||
r := c.ctx.CreateRenderbuffer()
|
||||
if r <= 0 {
|
||||
return 0, errors.New("opengl: creating renderbuffer failed")
|
||||
}
|
||||
|
||||
renderbuffer := renderbufferNative(r)
|
||||
c.bindRenderbuffer(renderbuffer)
|
||||
|
||||
var stencilFormat uint32
|
||||
if c.ctx.IsES() {
|
||||
// https://docs.gl/es2/glRenderbufferStorage
|
||||
// > Must be one of the following symbolic constants: GL_RGBA4, GL_RGB565, GL_RGB5_A1,
|
||||
// > GL_DEPTH_COMPONENT16, or GL_STENCIL_INDEX8.
|
||||
//
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/renderbufferStorage
|
||||
// > A GLenum specifying the internal format of the renderbuffer. Possible values:
|
||||
// > * gl.RGBA4: 4 red bits, 4 green bits, 4 blue bits 4 alpha bits.
|
||||
// > * gl.RGB565: 5 red bits, 6 green bits, 5 blue bits.
|
||||
// > * gl.RGB5_A1: 5 red bits, 5 green bits, 5 blue bits, 1 alpha bit.
|
||||
// > * gl.DEPTH_COMPONENT16: 16 depth bits.
|
||||
// > * gl.STENCIL_INDEX8: 8 stencil bits.
|
||||
// > * gl.DEPTH_STENCIL
|
||||
stencilFormat = gl.STENCIL_INDEX8
|
||||
} else {
|
||||
// GL_STENCIL_INDEX8 might not be available with OpenGL 2.1.
|
||||
// https://www.khronos.org/opengl/wiki/Image_Format
|
||||
// > There are only 2 depth/stencil formats, each providing 8 stencil bits: GL_DEPTH24_STENCIL8 and GL_DEPTH32F_STENCIL8.
|
||||
// > [...]
|
||||
// > Stencil formats can only be used for Textures if OpenGL 4.4 or ARB_texture_stencil8 is available.
|
||||
stencilFormat = gl.DEPTH24_STENCIL8
|
||||
}
|
||||
c.ctx.RenderbufferStorage(gl.RENDERBUFFER, stencilFormat, int32(width), int32(height))
|
||||
|
||||
return renderbuffer, nil
|
||||
}
|
||||
|
||||
func (c *context) deleteRenderbuffer(r renderbufferNative) {
|
||||
if !c.ctx.IsRenderbuffer(uint32(r)) {
|
||||
return
|
||||
}
|
||||
if c.lastRenderbuffer == r {
|
||||
c.lastRenderbuffer = 0
|
||||
}
|
||||
c.ctx.DeleteRenderbuffer(uint32(r))
|
||||
}
|
||||
|
||||
func (c *context) newFramebuffer(texture textureNative, width, height int) (*framebuffer, error) {
|
||||
f := c.ctx.CreateFramebuffer()
|
||||
if f <= 0 {
|
||||
return nil, fmt.Errorf("opengl: creating framebuffer failed: the returned value is not positive but %d", f)
|
||||
}
|
||||
c.bindFramebuffer(framebufferNative(f))
|
||||
|
||||
c.ctx.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, uint32(texture), 0)
|
||||
if s := c.ctx.CheckFramebufferStatus(gl.FRAMEBUFFER); s != gl.FRAMEBUFFER_COMPLETE {
|
||||
if s != 0 {
|
||||
return nil, fmt.Errorf("opengl: creating framebuffer failed: %v", s)
|
||||
}
|
||||
if e := c.ctx.GetError(); e != gl.NO_ERROR {
|
||||
return nil, fmt.Errorf("opengl: creating framebuffer failed: (glGetError) %d", e)
|
||||
}
|
||||
return nil, fmt.Errorf("opengl: creating framebuffer failed: unknown error")
|
||||
}
|
||||
return &framebuffer{
|
||||
native: framebufferNative(f),
|
||||
width: width,
|
||||
height: height,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *context) bindStencilBuffer(f framebufferNative, r renderbufferNative) error {
|
||||
c.bindFramebuffer(f)
|
||||
|
||||
c.ctx.FramebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, uint32(r))
|
||||
if s := c.ctx.CheckFramebufferStatus(gl.FRAMEBUFFER); s != gl.FRAMEBUFFER_COMPLETE {
|
||||
return errors.New(fmt.Sprintf("opengl: glFramebufferRenderbuffer failed: %d", s))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *context) deleteFramebuffer(f framebufferNative) {
|
||||
if f == c.screenFramebuffer {
|
||||
return
|
||||
}
|
||||
if !c.ctx.IsFramebuffer(uint32(f)) {
|
||||
return
|
||||
}
|
||||
// If a framebuffer to be deleted is bound, a newly bound framebuffer
|
||||
// will be a default framebuffer.
|
||||
// https://www.khronos.org/opengles/sdk/docs/man/xhtml/glDeleteFramebuffers.xml
|
||||
if c.lastFramebuffer == f {
|
||||
c.lastFramebuffer = invalidFramebuffer
|
||||
c.lastViewportWidth = 0
|
||||
c.lastViewportHeight = 0
|
||||
}
|
||||
c.ctx.DeleteFramebuffer(uint32(f))
|
||||
}
|
||||
|
||||
func (c *context) newShader(shaderType uint32, source string) (shader, error) {
|
||||
s := c.ctx.CreateShader(shaderType)
|
||||
if s == 0 {
|
||||
return 0, fmt.Errorf("opengl: glCreateShader failed: shader type: %d", shaderType)
|
||||
}
|
||||
|
||||
c.ctx.ShaderSource(s, source)
|
||||
c.ctx.CompileShader(s)
|
||||
|
||||
if c.ctx.GetShaderi(s, gl.COMPILE_STATUS) == gl.FALSE {
|
||||
log := c.ctx.GetShaderInfoLog(s)
|
||||
return 0, fmt.Errorf("opengl: shader compile failed: %s", log)
|
||||
}
|
||||
return shader(s), nil
|
||||
}
|
||||
|
||||
func (c *context) newProgram(shaders []shader, attributes []string) (program, error) {
|
||||
p := c.ctx.CreateProgram()
|
||||
if p == 0 {
|
||||
return 0, errors.New("opengl: glCreateProgram failed")
|
||||
}
|
||||
|
||||
for _, shader := range shaders {
|
||||
c.ctx.AttachShader(p, uint32(shader))
|
||||
}
|
||||
|
||||
for i, name := range attributes {
|
||||
c.ctx.BindAttribLocation(p, uint32(i), name)
|
||||
}
|
||||
|
||||
c.ctx.LinkProgram(p)
|
||||
if c.ctx.GetProgrami(p, gl.LINK_STATUS) == gl.FALSE {
|
||||
info := c.ctx.GetProgramInfoLog(p)
|
||||
return 0, fmt.Errorf("opengl: program error: %s", info)
|
||||
}
|
||||
return program(p), nil
|
||||
}
|
||||
|
||||
func (c *context) deleteProgram(p program) {
|
||||
c.locationCache.deleteProgram(p)
|
||||
|
||||
if !c.ctx.IsProgram(uint32(p)) {
|
||||
return
|
||||
}
|
||||
c.ctx.DeleteProgram(uint32(p))
|
||||
}
|
||||
|
||||
func (c *context) uniformInt(p program, location string, v int) bool {
|
||||
l := c.locationCache.GetUniformLocation(c, p, location)
|
||||
if l == invalidUniform {
|
||||
return false
|
||||
}
|
||||
c.ctx.Uniform1i(int32(l), int32(v))
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *context) uniforms(p program, location string, v []uint32, typ shaderir.Type) bool {
|
||||
l := c.locationCache.GetUniformLocation(c, p, location)
|
||||
if l == invalidUniform {
|
||||
return false
|
||||
}
|
||||
|
||||
base := typ.Main
|
||||
if base == shaderir.Array {
|
||||
base = typ.Sub[0].Main
|
||||
}
|
||||
|
||||
switch base {
|
||||
case shaderir.Float:
|
||||
c.ctx.Uniform1fv(int32(l), uint32sToFloat32s(v))
|
||||
case shaderir.Int:
|
||||
c.ctx.Uniform1iv(int32(l), uint32sToInt32s(v))
|
||||
case shaderir.Vec2:
|
||||
c.ctx.Uniform2fv(int32(l), uint32sToFloat32s(v))
|
||||
case shaderir.Vec3:
|
||||
c.ctx.Uniform3fv(int32(l), uint32sToFloat32s(v))
|
||||
case shaderir.Vec4:
|
||||
c.ctx.Uniform4fv(int32(l), uint32sToFloat32s(v))
|
||||
case shaderir.IVec2:
|
||||
c.ctx.Uniform2iv(int32(l), uint32sToInt32s(v))
|
||||
case shaderir.IVec3:
|
||||
c.ctx.Uniform3iv(int32(l), uint32sToInt32s(v))
|
||||
case shaderir.IVec4:
|
||||
c.ctx.Uniform4iv(int32(l), uint32sToInt32s(v))
|
||||
case shaderir.Mat2:
|
||||
c.ctx.UniformMatrix2fv(int32(l), uint32sToFloat32s(v))
|
||||
case shaderir.Mat3:
|
||||
c.ctx.UniformMatrix3fv(int32(l), uint32sToFloat32s(v))
|
||||
case shaderir.Mat4:
|
||||
c.ctx.UniformMatrix4fv(int32(l), uint32sToFloat32s(v))
|
||||
default:
|
||||
panic(fmt.Sprintf("opengl: unexpected type: %s", typ.String()))
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *context) newArrayBuffer(size int) buffer {
|
||||
b := c.ctx.CreateBuffer()
|
||||
c.ctx.BindBuffer(gl.ARRAY_BUFFER, b)
|
||||
c.ctx.BufferInit(gl.ARRAY_BUFFER, size, gl.DYNAMIC_DRAW)
|
||||
return buffer(b)
|
||||
}
|
||||
|
||||
func (c *context) newElementArrayBuffer(size int) buffer {
|
||||
b := c.ctx.CreateBuffer()
|
||||
c.ctx.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, b)
|
||||
c.ctx.BufferInit(gl.ELEMENT_ARRAY_BUFFER, size, gl.DYNAMIC_DRAW)
|
||||
return buffer(b)
|
||||
}
|
||||
|
||||
func (c *context) glslVersion() glsl.GLSLVersion {
|
||||
if c.ctx.IsES() {
|
||||
return glsl.GLSLVersionES300
|
||||
}
|
||||
return glsl.GLSLVersionDefault
|
||||
}
|
||||
Generated
Vendored
+100
@@ -0,0 +1,100 @@
|
||||
// Copyright 2023 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 nintendosdk
|
||||
|
||||
package opengl
|
||||
|
||||
// #cgo !darwin LDFLAGS: -Wl,-unresolved-symbols=ignore-all
|
||||
// #cgo darwin LDFLAGS: -Wl,-undefined,dynamic_lookup
|
||||
//
|
||||
// #include <EGL/egl.h>
|
||||
// #include <EGL/eglext.h>
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type egl struct {
|
||||
display C.EGLDisplay
|
||||
surface C.EGLSurface
|
||||
context C.EGLContext
|
||||
}
|
||||
|
||||
func newEGL(nativeWindowHandle uintptr) (*egl, error) {
|
||||
e := &egl{}
|
||||
|
||||
e.display = C.eglGetDisplay(C.NativeDisplayType(C.EGL_DEFAULT_DISPLAY))
|
||||
if e.display == 0 {
|
||||
return nil, fmt.Errorf("opengl: eglGetDisplay failed")
|
||||
}
|
||||
|
||||
if r := C.eglInitialize(e.display, nil, nil); r == 0 {
|
||||
return nil, fmt.Errorf("opengl: eglInitialize failed")
|
||||
}
|
||||
|
||||
configAttribs := []C.EGLint{
|
||||
C.EGL_RENDERABLE_TYPE, C.EGL_OPENGL_BIT,
|
||||
C.EGL_SURFACE_TYPE, C.EGL_WINDOW_BIT,
|
||||
C.EGL_RED_SIZE, 8,
|
||||
C.EGL_GREEN_SIZE, 8,
|
||||
C.EGL_BLUE_SIZE, 8,
|
||||
C.EGL_ALPHA_SIZE, 8,
|
||||
C.EGL_NONE}
|
||||
var numConfigs C.EGLint
|
||||
var config C.EGLConfig
|
||||
if r := C.eglChooseConfig(e.display, &configAttribs[0], &config, 1, &numConfigs); r == 0 {
|
||||
return nil, fmt.Errorf("opengl: eglChooseConfig failed")
|
||||
}
|
||||
if numConfigs != 1 {
|
||||
return nil, fmt.Errorf("opengl: eglChooseConfig failed: numConfigs must be 1 but %d", numConfigs)
|
||||
}
|
||||
|
||||
e.surface = C.eglCreateWindowSurface(e.display, config, C.NativeWindowType(nativeWindowHandle), nil)
|
||||
if e.surface == C.EGLSurface(C.EGL_NO_SURFACE) {
|
||||
return nil, fmt.Errorf("opengl: eglCreateWindowSurface failed")
|
||||
}
|
||||
|
||||
// Set the current rendering API.
|
||||
if r := C.eglBindAPI(C.EGL_OPENGL_API); r == 0 {
|
||||
return nil, fmt.Errorf("opengl: eglBindAPI failed")
|
||||
}
|
||||
|
||||
// Create new context and set it as current.
|
||||
contextAttribs := []C.EGLint{
|
||||
// Set target graphics api version.
|
||||
C.EGL_CONTEXT_MAJOR_VERSION, 3,
|
||||
C.EGL_CONTEXT_MINOR_VERSION, 2,
|
||||
// For debug callback
|
||||
C.EGL_CONTEXT_FLAGS_KHR, C.EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR,
|
||||
C.EGL_NONE}
|
||||
e.context = C.eglCreateContext(e.display, config, C.EGLContext(C.EGL_NO_CONTEXT), &contextAttribs[0])
|
||||
if e.context == C.EGLContext(C.EGL_NO_CONTEXT) {
|
||||
return nil, fmt.Errorf("opengl: eglCreateContext failed: error: %d", C.eglGetError())
|
||||
}
|
||||
|
||||
return e, nil
|
||||
}
|
||||
|
||||
func (e *egl) makeContextCurrent() error {
|
||||
if r := C.eglMakeCurrent(e.display, e.surface, e.surface, e.context); r == 0 {
|
||||
return fmt.Errorf("opengl: eglMakeCurrent failed")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *egl) swapBuffers() {
|
||||
C.eglSwapBuffers(e.display, e.surface)
|
||||
}
|
||||
Generated
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
This is a fork of `github.com/go-gl/gl/v2.1/gl` with the below patch. This is now modified manually.
|
||||
|
||||
The original version is generated from `github.com/hajimehoshi/glow`'s `nocgo` branch. This enables to remove dependencies on Cgo on Windows.
|
||||
|
||||
Now we are working on committing this 'no-cgo' change to the official gl package. See https://github.com/go-gl/glow/pull/102.
|
||||
Generated
Vendored
+90
@@ -0,0 +1,90 @@
|
||||
// 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 !playstation5
|
||||
|
||||
package gl
|
||||
|
||||
const (
|
||||
ALWAYS = 0x0207
|
||||
ARRAY_BUFFER = 0x8892
|
||||
BACK = 0x0405
|
||||
BLEND = 0x0BE2
|
||||
CLAMP_TO_EDGE = 0x812F
|
||||
COLOR_ATTACHMENT0 = 0x8CE0
|
||||
COMPILE_STATUS = 0x8B81
|
||||
DECR_WRAP = 0x8508
|
||||
DEPTH24_STENCIL8 = 0x88F0
|
||||
DST_ALPHA = 0x0304
|
||||
DST_COLOR = 0x0306
|
||||
DYNAMIC_DRAW = 0x88E8
|
||||
ELEMENT_ARRAY_BUFFER = 0x8893
|
||||
FALSE = 0
|
||||
FLOAT = 0x1406
|
||||
FRAGMENT_SHADER = 0x8B30
|
||||
FRAMEBUFFER = 0x8D40
|
||||
FRAMEBUFFER_BINDING = 0x8CA6
|
||||
FRAMEBUFFER_COMPLETE = 0x8CD5
|
||||
FRONT = 0x0404
|
||||
FRONT_AND_BACK = 0x0408
|
||||
FUNC_ADD = 0x8006
|
||||
FUNC_REVERSE_SUBTRACT = 0x800b
|
||||
FUNC_SUBTRACT = 0x800a
|
||||
HIGH_FLOAT = 0x8DF2
|
||||
INCR_WRAP = 0x8507
|
||||
INFO_LOG_LENGTH = 0x8B84
|
||||
INVERT = 0x150A
|
||||
KEEP = 0x1E00
|
||||
LINK_STATUS = 0x8B82
|
||||
MAX = 0x8008
|
||||
MAX_TEXTURE_SIZE = 0x0D33
|
||||
MIN = 0x8007
|
||||
NEAREST = 0x2600
|
||||
NO_ERROR = 0
|
||||
NOTEQUAL = 0x0205
|
||||
ONE = 1
|
||||
ONE_MINUS_DST_ALPHA = 0x0305
|
||||
ONE_MINUS_DST_COLOR = 0x0307
|
||||
ONE_MINUS_SRC_ALPHA = 0x0303
|
||||
ONE_MINUS_SRC_COLOR = 0x0301
|
||||
PIXEL_PACK_BUFFER = 0x88EB
|
||||
PIXEL_UNPACK_BUFFER = 0x88EC
|
||||
READ_WRITE = 0x88BA
|
||||
RENDERBUFFER = 0x8D41
|
||||
RGBA = 0x1908
|
||||
SCISSOR_TEST = 0x0C11
|
||||
SHORT = 0x1402
|
||||
SRC_ALPHA = 0x0302
|
||||
SRC_ALPHA_SATURATE = 0x0308
|
||||
SRC_COLOR = 0x0300
|
||||
STENCIL_ATTACHMENT = 0x8D20
|
||||
STENCIL_BUFFER_BIT = 0x0400
|
||||
STENCIL_INDEX8 = 0x8D48
|
||||
STENCIL_TEST = 0x0B90
|
||||
STREAM_DRAW = 0x88E0
|
||||
TEXTURE0 = 0x84C0
|
||||
TEXTURE_2D = 0x0DE1
|
||||
TEXTURE_MAG_FILTER = 0x2800
|
||||
TEXTURE_MIN_FILTER = 0x2801
|
||||
TEXTURE_WRAP_S = 0x2802
|
||||
TEXTURE_WRAP_T = 0x2803
|
||||
TRIANGLES = 0x0004
|
||||
TRUE = 1
|
||||
UNPACK_ALIGNMENT = 0x0CF5
|
||||
UNSIGNED_BYTE = 0x1401
|
||||
UNSIGNED_INT = 0x1405
|
||||
VERTEX_SHADER = 0x8B31
|
||||
WRITE_ONLY = 0x88B9
|
||||
ZERO = 0
|
||||
)
|
||||
Generated
Vendored
+647
@@ -0,0 +1,647 @@
|
||||
// Copyright 2023 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.
|
||||
|
||||
// Code generated by genkeys.go using 'go generate'. DO NOT EDIT.
|
||||
|
||||
//go:build !playstation5
|
||||
|
||||
package gl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
type DebugContext struct {
|
||||
Context Context
|
||||
}
|
||||
|
||||
var _ Context = (*DebugContext)(nil)
|
||||
|
||||
func (d *DebugContext) ActiveTexture(arg0 uint32) {
|
||||
d.Context.ActiveTexture(arg0)
|
||||
fmt.Fprintln(os.Stderr, "ActiveTexture")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at ActiveTexture", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) AttachShader(arg0 uint32, arg1 uint32) {
|
||||
d.Context.AttachShader(arg0, arg1)
|
||||
fmt.Fprintln(os.Stderr, "AttachShader")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at AttachShader", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) BindAttribLocation(arg0 uint32, arg1 uint32, arg2 string) {
|
||||
d.Context.BindAttribLocation(arg0, arg1, arg2)
|
||||
fmt.Fprintln(os.Stderr, "BindAttribLocation")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at BindAttribLocation", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) BindBuffer(arg0 uint32, arg1 uint32) {
|
||||
d.Context.BindBuffer(arg0, arg1)
|
||||
fmt.Fprintln(os.Stderr, "BindBuffer")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at BindBuffer", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) BindFramebuffer(arg0 uint32, arg1 uint32) {
|
||||
d.Context.BindFramebuffer(arg0, arg1)
|
||||
fmt.Fprintln(os.Stderr, "BindFramebuffer")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at BindFramebuffer", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) BindRenderbuffer(arg0 uint32, arg1 uint32) {
|
||||
d.Context.BindRenderbuffer(arg0, arg1)
|
||||
fmt.Fprintln(os.Stderr, "BindRenderbuffer")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at BindRenderbuffer", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) BindTexture(arg0 uint32, arg1 uint32) {
|
||||
d.Context.BindTexture(arg0, arg1)
|
||||
fmt.Fprintln(os.Stderr, "BindTexture")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at BindTexture", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) BindVertexArray(arg0 uint32) {
|
||||
d.Context.BindVertexArray(arg0)
|
||||
fmt.Fprintln(os.Stderr, "BindVertexArray")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at BindVertexArray", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) BlendEquationSeparate(arg0 uint32, arg1 uint32) {
|
||||
d.Context.BlendEquationSeparate(arg0, arg1)
|
||||
fmt.Fprintln(os.Stderr, "BlendEquationSeparate")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at BlendEquationSeparate", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) BlendFuncSeparate(arg0 uint32, arg1 uint32, arg2 uint32, arg3 uint32) {
|
||||
d.Context.BlendFuncSeparate(arg0, arg1, arg2, arg3)
|
||||
fmt.Fprintln(os.Stderr, "BlendFuncSeparate")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at BlendFuncSeparate", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) BufferInit(arg0 uint32, arg1 int, arg2 uint32) {
|
||||
d.Context.BufferInit(arg0, arg1, arg2)
|
||||
fmt.Fprintln(os.Stderr, "BufferInit")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at BufferInit", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) BufferSubData(arg0 uint32, arg1 int, arg2 []uint8) {
|
||||
d.Context.BufferSubData(arg0, arg1, arg2)
|
||||
fmt.Fprintln(os.Stderr, "BufferSubData")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at BufferSubData", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) CheckFramebufferStatus(arg0 uint32) uint32 {
|
||||
out0 := d.Context.CheckFramebufferStatus(arg0)
|
||||
fmt.Fprintln(os.Stderr, "CheckFramebufferStatus")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at CheckFramebufferStatus", e))
|
||||
}
|
||||
return out0
|
||||
}
|
||||
|
||||
func (d *DebugContext) Clear(arg0 uint32) {
|
||||
d.Context.Clear(arg0)
|
||||
fmt.Fprintln(os.Stderr, "Clear")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at Clear", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) ColorMask(arg0 bool, arg1 bool, arg2 bool, arg3 bool) {
|
||||
d.Context.ColorMask(arg0, arg1, arg2, arg3)
|
||||
fmt.Fprintln(os.Stderr, "ColorMask")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at ColorMask", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) CompileShader(arg0 uint32) {
|
||||
d.Context.CompileShader(arg0)
|
||||
fmt.Fprintln(os.Stderr, "CompileShader")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at CompileShader", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) CreateBuffer() uint32 {
|
||||
out0 := d.Context.CreateBuffer()
|
||||
fmt.Fprintln(os.Stderr, "CreateBuffer")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at CreateBuffer", e))
|
||||
}
|
||||
return out0
|
||||
}
|
||||
|
||||
func (d *DebugContext) CreateFramebuffer() uint32 {
|
||||
out0 := d.Context.CreateFramebuffer()
|
||||
fmt.Fprintln(os.Stderr, "CreateFramebuffer")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at CreateFramebuffer", e))
|
||||
}
|
||||
return out0
|
||||
}
|
||||
|
||||
func (d *DebugContext) CreateProgram() uint32 {
|
||||
out0 := d.Context.CreateProgram()
|
||||
fmt.Fprintln(os.Stderr, "CreateProgram")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at CreateProgram", e))
|
||||
}
|
||||
return out0
|
||||
}
|
||||
|
||||
func (d *DebugContext) CreateRenderbuffer() uint32 {
|
||||
out0 := d.Context.CreateRenderbuffer()
|
||||
fmt.Fprintln(os.Stderr, "CreateRenderbuffer")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at CreateRenderbuffer", e))
|
||||
}
|
||||
return out0
|
||||
}
|
||||
|
||||
func (d *DebugContext) CreateShader(arg0 uint32) uint32 {
|
||||
out0 := d.Context.CreateShader(arg0)
|
||||
fmt.Fprintln(os.Stderr, "CreateShader")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at CreateShader", e))
|
||||
}
|
||||
return out0
|
||||
}
|
||||
|
||||
func (d *DebugContext) CreateTexture() uint32 {
|
||||
out0 := d.Context.CreateTexture()
|
||||
fmt.Fprintln(os.Stderr, "CreateTexture")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at CreateTexture", e))
|
||||
}
|
||||
return out0
|
||||
}
|
||||
|
||||
func (d *DebugContext) CreateVertexArray() uint32 {
|
||||
out0 := d.Context.CreateVertexArray()
|
||||
fmt.Fprintln(os.Stderr, "CreateVertexArray")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at CreateVertexArray", e))
|
||||
}
|
||||
return out0
|
||||
}
|
||||
|
||||
func (d *DebugContext) DeleteBuffer(arg0 uint32) {
|
||||
d.Context.DeleteBuffer(arg0)
|
||||
fmt.Fprintln(os.Stderr, "DeleteBuffer")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at DeleteBuffer", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) DeleteFramebuffer(arg0 uint32) {
|
||||
d.Context.DeleteFramebuffer(arg0)
|
||||
fmt.Fprintln(os.Stderr, "DeleteFramebuffer")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at DeleteFramebuffer", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) DeleteProgram(arg0 uint32) {
|
||||
d.Context.DeleteProgram(arg0)
|
||||
fmt.Fprintln(os.Stderr, "DeleteProgram")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at DeleteProgram", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) DeleteRenderbuffer(arg0 uint32) {
|
||||
d.Context.DeleteRenderbuffer(arg0)
|
||||
fmt.Fprintln(os.Stderr, "DeleteRenderbuffer")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at DeleteRenderbuffer", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) DeleteShader(arg0 uint32) {
|
||||
d.Context.DeleteShader(arg0)
|
||||
fmt.Fprintln(os.Stderr, "DeleteShader")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at DeleteShader", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) DeleteTexture(arg0 uint32) {
|
||||
d.Context.DeleteTexture(arg0)
|
||||
fmt.Fprintln(os.Stderr, "DeleteTexture")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at DeleteTexture", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) DeleteVertexArray(arg0 uint32) {
|
||||
d.Context.DeleteVertexArray(arg0)
|
||||
fmt.Fprintln(os.Stderr, "DeleteVertexArray")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at DeleteVertexArray", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) Disable(arg0 uint32) {
|
||||
d.Context.Disable(arg0)
|
||||
fmt.Fprintln(os.Stderr, "Disable")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at Disable", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) DisableVertexAttribArray(arg0 uint32) {
|
||||
d.Context.DisableVertexAttribArray(arg0)
|
||||
fmt.Fprintln(os.Stderr, "DisableVertexAttribArray")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at DisableVertexAttribArray", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) DrawElements(arg0 uint32, arg1 int32, arg2 uint32, arg3 int) {
|
||||
d.Context.DrawElements(arg0, arg1, arg2, arg3)
|
||||
fmt.Fprintln(os.Stderr, "DrawElements")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at DrawElements", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) Enable(arg0 uint32) {
|
||||
d.Context.Enable(arg0)
|
||||
fmt.Fprintln(os.Stderr, "Enable")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at Enable", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) EnableVertexAttribArray(arg0 uint32) {
|
||||
d.Context.EnableVertexAttribArray(arg0)
|
||||
fmt.Fprintln(os.Stderr, "EnableVertexAttribArray")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at EnableVertexAttribArray", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) Flush() {
|
||||
d.Context.Flush()
|
||||
fmt.Fprintln(os.Stderr, "Flush")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at Flush", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) FramebufferRenderbuffer(arg0 uint32, arg1 uint32, arg2 uint32, arg3 uint32) {
|
||||
d.Context.FramebufferRenderbuffer(arg0, arg1, arg2, arg3)
|
||||
fmt.Fprintln(os.Stderr, "FramebufferRenderbuffer")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at FramebufferRenderbuffer", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) FramebufferTexture2D(arg0 uint32, arg1 uint32, arg2 uint32, arg3 uint32, arg4 int32) {
|
||||
d.Context.FramebufferTexture2D(arg0, arg1, arg2, arg3, arg4)
|
||||
fmt.Fprintln(os.Stderr, "FramebufferTexture2D")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at FramebufferTexture2D", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) GetError() uint32 {
|
||||
out0 := d.Context.GetError()
|
||||
fmt.Fprintln(os.Stderr, "GetError")
|
||||
return out0
|
||||
}
|
||||
|
||||
func (d *DebugContext) GetInteger(arg0 uint32) int {
|
||||
out0 := d.Context.GetInteger(arg0)
|
||||
fmt.Fprintln(os.Stderr, "GetInteger")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at GetInteger", e))
|
||||
}
|
||||
return out0
|
||||
}
|
||||
|
||||
func (d *DebugContext) GetProgramInfoLog(arg0 uint32) string {
|
||||
out0 := d.Context.GetProgramInfoLog(arg0)
|
||||
fmt.Fprintln(os.Stderr, "GetProgramInfoLog")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at GetProgramInfoLog", e))
|
||||
}
|
||||
return out0
|
||||
}
|
||||
|
||||
func (d *DebugContext) GetProgrami(arg0 uint32, arg1 uint32) int {
|
||||
out0 := d.Context.GetProgrami(arg0, arg1)
|
||||
fmt.Fprintln(os.Stderr, "GetProgrami")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at GetProgrami", e))
|
||||
}
|
||||
return out0
|
||||
}
|
||||
|
||||
func (d *DebugContext) GetShaderInfoLog(arg0 uint32) string {
|
||||
out0 := d.Context.GetShaderInfoLog(arg0)
|
||||
fmt.Fprintln(os.Stderr, "GetShaderInfoLog")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at GetShaderInfoLog", e))
|
||||
}
|
||||
return out0
|
||||
}
|
||||
|
||||
func (d *DebugContext) GetShaderi(arg0 uint32, arg1 uint32) int {
|
||||
out0 := d.Context.GetShaderi(arg0, arg1)
|
||||
fmt.Fprintln(os.Stderr, "GetShaderi")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at GetShaderi", e))
|
||||
}
|
||||
return out0
|
||||
}
|
||||
|
||||
func (d *DebugContext) GetUniformLocation(arg0 uint32, arg1 string) int32 {
|
||||
out0 := d.Context.GetUniformLocation(arg0, arg1)
|
||||
fmt.Fprintln(os.Stderr, "GetUniformLocation")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at GetUniformLocation", e))
|
||||
}
|
||||
return out0
|
||||
}
|
||||
|
||||
func (d *DebugContext) IsES() bool {
|
||||
out0 := d.Context.IsES()
|
||||
return out0
|
||||
}
|
||||
|
||||
func (d *DebugContext) IsFramebuffer(arg0 uint32) bool {
|
||||
out0 := d.Context.IsFramebuffer(arg0)
|
||||
fmt.Fprintln(os.Stderr, "IsFramebuffer")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at IsFramebuffer", e))
|
||||
}
|
||||
return out0
|
||||
}
|
||||
|
||||
func (d *DebugContext) IsProgram(arg0 uint32) bool {
|
||||
out0 := d.Context.IsProgram(arg0)
|
||||
fmt.Fprintln(os.Stderr, "IsProgram")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at IsProgram", e))
|
||||
}
|
||||
return out0
|
||||
}
|
||||
|
||||
func (d *DebugContext) IsRenderbuffer(arg0 uint32) bool {
|
||||
out0 := d.Context.IsRenderbuffer(arg0)
|
||||
fmt.Fprintln(os.Stderr, "IsRenderbuffer")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at IsRenderbuffer", e))
|
||||
}
|
||||
return out0
|
||||
}
|
||||
|
||||
func (d *DebugContext) LinkProgram(arg0 uint32) {
|
||||
d.Context.LinkProgram(arg0)
|
||||
fmt.Fprintln(os.Stderr, "LinkProgram")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at LinkProgram", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) LoadFunctions() error {
|
||||
out0 := d.Context.LoadFunctions()
|
||||
return out0
|
||||
}
|
||||
|
||||
func (d *DebugContext) PixelStorei(arg0 uint32, arg1 int32) {
|
||||
d.Context.PixelStorei(arg0, arg1)
|
||||
fmt.Fprintln(os.Stderr, "PixelStorei")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at PixelStorei", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) ReadPixels(arg0 []uint8, arg1 int32, arg2 int32, arg3 int32, arg4 int32, arg5 uint32, arg6 uint32) {
|
||||
d.Context.ReadPixels(arg0, arg1, arg2, arg3, arg4, arg5, arg6)
|
||||
fmt.Fprintln(os.Stderr, "ReadPixels")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at ReadPixels", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) RenderbufferStorage(arg0 uint32, arg1 uint32, arg2 int32, arg3 int32) {
|
||||
d.Context.RenderbufferStorage(arg0, arg1, arg2, arg3)
|
||||
fmt.Fprintln(os.Stderr, "RenderbufferStorage")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at RenderbufferStorage", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) Scissor(arg0 int32, arg1 int32, arg2 int32, arg3 int32) {
|
||||
d.Context.Scissor(arg0, arg1, arg2, arg3)
|
||||
fmt.Fprintln(os.Stderr, "Scissor")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at Scissor", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) ShaderSource(arg0 uint32, arg1 string) {
|
||||
d.Context.ShaderSource(arg0, arg1)
|
||||
fmt.Fprintln(os.Stderr, "ShaderSource")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at ShaderSource", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) StencilFunc(arg0 uint32, arg1 int32, arg2 uint32) {
|
||||
d.Context.StencilFunc(arg0, arg1, arg2)
|
||||
fmt.Fprintln(os.Stderr, "StencilFunc")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at StencilFunc", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) StencilOpSeparate(arg0 uint32, arg1 uint32, arg2 uint32, arg3 uint32) {
|
||||
d.Context.StencilOpSeparate(arg0, arg1, arg2, arg3)
|
||||
fmt.Fprintln(os.Stderr, "StencilOpSeparate")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at StencilOpSeparate", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) TexImage2D(arg0 uint32, arg1 int32, arg2 int32, arg3 int32, arg4 int32, arg5 uint32, arg6 uint32, arg7 []uint8) {
|
||||
d.Context.TexImage2D(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
|
||||
fmt.Fprintln(os.Stderr, "TexImage2D")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at TexImage2D", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) TexParameteri(arg0 uint32, arg1 uint32, arg2 int32) {
|
||||
d.Context.TexParameteri(arg0, arg1, arg2)
|
||||
fmt.Fprintln(os.Stderr, "TexParameteri")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at TexParameteri", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) TexSubImage2D(arg0 uint32, arg1 int32, arg2 int32, arg3 int32, arg4 int32, arg5 int32, arg6 uint32, arg7 uint32, arg8 []uint8) {
|
||||
d.Context.TexSubImage2D(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
|
||||
fmt.Fprintln(os.Stderr, "TexSubImage2D")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at TexSubImage2D", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) Uniform1fv(arg0 int32, arg1 []float32) {
|
||||
d.Context.Uniform1fv(arg0, arg1)
|
||||
fmt.Fprintln(os.Stderr, "Uniform1fv")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at Uniform1fv", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) Uniform1i(arg0 int32, arg1 int32) {
|
||||
d.Context.Uniform1i(arg0, arg1)
|
||||
fmt.Fprintln(os.Stderr, "Uniform1i")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at Uniform1i", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) Uniform1iv(arg0 int32, arg1 []int32) {
|
||||
d.Context.Uniform1iv(arg0, arg1)
|
||||
fmt.Fprintln(os.Stderr, "Uniform1iv")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at Uniform1iv", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) Uniform2fv(arg0 int32, arg1 []float32) {
|
||||
d.Context.Uniform2fv(arg0, arg1)
|
||||
fmt.Fprintln(os.Stderr, "Uniform2fv")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at Uniform2fv", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) Uniform2iv(arg0 int32, arg1 []int32) {
|
||||
d.Context.Uniform2iv(arg0, arg1)
|
||||
fmt.Fprintln(os.Stderr, "Uniform2iv")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at Uniform2iv", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) Uniform3fv(arg0 int32, arg1 []float32) {
|
||||
d.Context.Uniform3fv(arg0, arg1)
|
||||
fmt.Fprintln(os.Stderr, "Uniform3fv")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at Uniform3fv", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) Uniform3iv(arg0 int32, arg1 []int32) {
|
||||
d.Context.Uniform3iv(arg0, arg1)
|
||||
fmt.Fprintln(os.Stderr, "Uniform3iv")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at Uniform3iv", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) Uniform4fv(arg0 int32, arg1 []float32) {
|
||||
d.Context.Uniform4fv(arg0, arg1)
|
||||
fmt.Fprintln(os.Stderr, "Uniform4fv")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at Uniform4fv", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) Uniform4iv(arg0 int32, arg1 []int32) {
|
||||
d.Context.Uniform4iv(arg0, arg1)
|
||||
fmt.Fprintln(os.Stderr, "Uniform4iv")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at Uniform4iv", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) UniformMatrix2fv(arg0 int32, arg1 []float32) {
|
||||
d.Context.UniformMatrix2fv(arg0, arg1)
|
||||
fmt.Fprintln(os.Stderr, "UniformMatrix2fv")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at UniformMatrix2fv", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) UniformMatrix3fv(arg0 int32, arg1 []float32) {
|
||||
d.Context.UniformMatrix3fv(arg0, arg1)
|
||||
fmt.Fprintln(os.Stderr, "UniformMatrix3fv")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at UniformMatrix3fv", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) UniformMatrix4fv(arg0 int32, arg1 []float32) {
|
||||
d.Context.UniformMatrix4fv(arg0, arg1)
|
||||
fmt.Fprintln(os.Stderr, "UniformMatrix4fv")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at UniformMatrix4fv", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) UseProgram(arg0 uint32) {
|
||||
d.Context.UseProgram(arg0)
|
||||
fmt.Fprintln(os.Stderr, "UseProgram")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at UseProgram", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) VertexAttribPointer(arg0 uint32, arg1 int32, arg2 uint32, arg3 bool, arg4 int32, arg5 int) {
|
||||
d.Context.VertexAttribPointer(arg0, arg1, arg2, arg3, arg4, arg5)
|
||||
fmt.Fprintln(os.Stderr, "VertexAttribPointer")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at VertexAttribPointer", e))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DebugContext) Viewport(arg0 int32, arg1 int32, arg2 int32, arg3 int32) {
|
||||
d.Context.Viewport(arg0, arg1, arg2, arg3)
|
||||
fmt.Fprintln(os.Stderr, "Viewport")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at Viewport", e))
|
||||
}
|
||||
}
|
||||
Generated
Vendored
+853
@@ -0,0 +1,853 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2014 Eric Woroshow
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !darwin && !js && !windows && !playstation5
|
||||
|
||||
package gl
|
||||
|
||||
// #include <stdint.h>
|
||||
// #include <stdlib.h>
|
||||
//
|
||||
// typedef unsigned int GLenum;
|
||||
// typedef unsigned char GLboolean;
|
||||
// typedef unsigned int GLbitfield;
|
||||
// typedef int GLint;
|
||||
// typedef unsigned int GLuint;
|
||||
// typedef int GLsizei;
|
||||
// typedef float GLfloat;
|
||||
// typedef char GLchar;
|
||||
// typedef ptrdiff_t GLintptr;
|
||||
// typedef ptrdiff_t GLsizeiptr;
|
||||
//
|
||||
// static void glowActiveTexture(uintptr_t fnptr, GLenum texture) {
|
||||
// typedef void (*fn)(GLenum texture);
|
||||
// ((fn)(fnptr))(texture);
|
||||
// }
|
||||
// static void glowAttachShader(uintptr_t fnptr, GLuint program, GLuint shader) {
|
||||
// typedef void (*fn)(GLuint program, GLuint shader);
|
||||
// ((fn)(fnptr))(program, shader);
|
||||
// }
|
||||
// static void glowBindAttribLocation(uintptr_t fnptr, GLuint program, GLuint index, const GLchar* name) {
|
||||
// typedef void (*fn)(GLuint program, GLuint index, const GLchar* name);
|
||||
// ((fn)(fnptr))(program, index, name);
|
||||
// }
|
||||
// static void glowBindBuffer(uintptr_t fnptr, GLenum target, GLuint buffer) {
|
||||
// typedef void (*fn)(GLenum target, GLuint buffer);
|
||||
// ((fn)(fnptr))(target, buffer);
|
||||
// }
|
||||
// static void glowBindFramebuffer(uintptr_t fnptr, GLenum target, GLuint framebuffer) {
|
||||
// typedef void (*fn)(GLenum target, GLuint framebuffer);
|
||||
// ((fn)(fnptr))(target, framebuffer);
|
||||
// }
|
||||
// static void glowBindRenderbuffer(uintptr_t fnptr, GLenum target, GLuint renderbuffer) {
|
||||
// typedef void (*fn)(GLenum target, GLuint renderbuffer);
|
||||
// ((fn)(fnptr))(target, renderbuffer);
|
||||
// }
|
||||
// static void glowBindTexture(uintptr_t fnptr, GLenum target, GLuint texture) {
|
||||
// typedef void (*fn)(GLenum target, GLuint texture);
|
||||
// ((fn)(fnptr))(target, texture);
|
||||
// }
|
||||
// static void glowBindVertexArray(uintptr_t fnptr, GLuint array) {
|
||||
// typedef void (*fn)(GLuint array);
|
||||
// ((fn)(fnptr))(array);
|
||||
// }
|
||||
// static void glowBlendEquationSeparate(uintptr_t fnptr, GLenum modeRGB, GLenum modeAlpha) {
|
||||
// typedef void (*fn)(GLenum modeRGB, GLenum modeAlpha);
|
||||
// ((fn)(fnptr))(modeRGB, modeAlpha);
|
||||
// }
|
||||
// static void glowBlendFuncSeparate(uintptr_t fnptr, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) {
|
||||
// typedef void (*fn)(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
|
||||
// ((fn)(fnptr))(srcRGB, dstRGB, srcAlpha, dstAlpha);
|
||||
// }
|
||||
// static void glowBufferData(uintptr_t fnptr, GLenum target, GLsizeiptr size, const void* data, GLenum usage) {
|
||||
// typedef void (*fn)(GLenum target, GLsizeiptr size, const void* data, GLenum usage);
|
||||
// ((fn)(fnptr))(target, size, data, usage);
|
||||
// }
|
||||
// static void glowBufferSubData(uintptr_t fnptr, GLenum target, GLintptr offset, GLsizeiptr size, const void* data) {
|
||||
// typedef void (*fn)(GLenum target, GLintptr offset, GLsizeiptr size, const void* data);
|
||||
// ((fn)(fnptr))(target, offset, size, data);
|
||||
// }
|
||||
// static GLenum glowCheckFramebufferStatus(uintptr_t fnptr, GLenum target) {
|
||||
// typedef GLenum (*fn)(GLenum target);
|
||||
// return ((fn)(fnptr))(target);
|
||||
// }
|
||||
// static void glowClear(uintptr_t fnptr, GLbitfield mask) {
|
||||
// typedef void (*fn)(GLbitfield mask);
|
||||
// ((fn)(fnptr))(mask);
|
||||
// }
|
||||
// static void glowColorMask(uintptr_t fnptr, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {
|
||||
// typedef void (*fn)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
|
||||
// ((fn)(fnptr))(red, green, blue, alpha);
|
||||
// }
|
||||
// static void glowCompileShader(uintptr_t fnptr, GLuint shader) {
|
||||
// typedef void (*fn)(GLuint shader);
|
||||
// ((fn)(fnptr))(shader);
|
||||
// }
|
||||
// static GLuint glowCreateProgram(uintptr_t fnptr) {
|
||||
// typedef GLuint (*fn)();
|
||||
// return ((fn)(fnptr))();
|
||||
// }
|
||||
// static GLuint glowCreateShader(uintptr_t fnptr, GLenum type) {
|
||||
// typedef GLuint (*fn)(GLenum type);
|
||||
// return ((fn)(fnptr))(type);
|
||||
// }
|
||||
// static void glowDeleteBuffers(uintptr_t fnptr, GLsizei n, const GLuint* buffers) {
|
||||
// typedef void (*fn)(GLsizei n, const GLuint* buffers);
|
||||
// ((fn)(fnptr))(n, buffers);
|
||||
// }
|
||||
// static void glowDeleteFramebuffers(uintptr_t fnptr, GLsizei n, const GLuint* framebuffers) {
|
||||
// typedef void (*fn)(GLsizei n, const GLuint* framebuffers);
|
||||
// ((fn)(fnptr))(n, framebuffers);
|
||||
// }
|
||||
// static void glowDeleteProgram(uintptr_t fnptr, GLuint program) {
|
||||
// typedef void (*fn)(GLuint program);
|
||||
// ((fn)(fnptr))(program);
|
||||
// }
|
||||
// static void glowDeleteRenderbuffers(uintptr_t fnptr, GLsizei n, const GLuint* renderbuffers) {
|
||||
// typedef void (*fn)(GLsizei n, const GLuint* renderbuffers);
|
||||
// ((fn)(fnptr))(n, renderbuffers);
|
||||
// }
|
||||
// static void glowDeleteShader(uintptr_t fnptr, GLuint shader) {
|
||||
// typedef void (*fn)(GLuint shader);
|
||||
// ((fn)(fnptr))(shader);
|
||||
// }
|
||||
// static void glowDeleteTextures(uintptr_t fnptr, GLsizei n, const GLuint* textures) {
|
||||
// typedef void (*fn)(GLsizei n, const GLuint* textures);
|
||||
// ((fn)(fnptr))(n, textures);
|
||||
// }
|
||||
// static void glowDeleteVertexArrays(uintptr_t fnptr, GLsizei n, const GLuint* arrays) {
|
||||
// typedef void (*fn)(GLsizei n, const GLuint* arrays);
|
||||
// ((fn)(fnptr))(n, arrays);
|
||||
// }
|
||||
// static void glowDisable(uintptr_t fnptr, GLenum cap) {
|
||||
// typedef void (*fn)(GLenum cap);
|
||||
// ((fn)(fnptr))(cap);
|
||||
// }
|
||||
// static void glowDisableVertexAttribArray(uintptr_t fnptr, GLuint index) {
|
||||
// typedef void (*fn)(GLuint index);
|
||||
// ((fn)(fnptr))(index);
|
||||
// }
|
||||
// static void glowDrawElements(uintptr_t fnptr, GLenum mode, GLsizei count, GLenum type, const uintptr_t indices) {
|
||||
// typedef void (*fn)(GLenum mode, GLsizei count, GLenum type, const uintptr_t indices);
|
||||
// ((fn)(fnptr))(mode, count, type, indices);
|
||||
// }
|
||||
// static void glowEnable(uintptr_t fnptr, GLenum cap) {
|
||||
// typedef void (*fn)(GLenum cap);
|
||||
// ((fn)(fnptr))(cap);
|
||||
// }
|
||||
// static void glowEnableVertexAttribArray(uintptr_t fnptr, GLuint index) {
|
||||
// typedef void (*fn)(GLuint index);
|
||||
// ((fn)(fnptr))(index);
|
||||
// }
|
||||
// static void glowFlush(uintptr_t fnptr) {
|
||||
// typedef void (*fn)();
|
||||
// ((fn)(fnptr))();
|
||||
// }
|
||||
// static void glowFramebufferRenderbuffer(uintptr_t fnptr, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) {
|
||||
// typedef void (*fn)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
|
||||
// ((fn)(fnptr))(target, attachment, renderbuffertarget, renderbuffer);
|
||||
// }
|
||||
// static void glowFramebufferTexture2D(uintptr_t fnptr, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) {
|
||||
// typedef void (*fn)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
|
||||
// ((fn)(fnptr))(target, attachment, textarget, texture, level);
|
||||
// }
|
||||
// static void glowGenBuffers(uintptr_t fnptr, GLsizei n, GLuint* buffers) {
|
||||
// typedef void (*fn)(GLsizei n, GLuint* buffers);
|
||||
// ((fn)(fnptr))(n, buffers);
|
||||
// }
|
||||
// static void glowGenFramebuffers(uintptr_t fnptr, GLsizei n, GLuint* framebuffers) {
|
||||
// typedef void (*fn)(GLsizei n, GLuint* framebuffers);
|
||||
// ((fn)(fnptr))(n, framebuffers);
|
||||
// }
|
||||
// static void glowGenRenderbuffers(uintptr_t fnptr, GLsizei n, GLuint* renderbuffers) {
|
||||
// typedef void (*fn)(GLsizei n, GLuint* renderbuffers);
|
||||
// ((fn)(fnptr))(n, renderbuffers);
|
||||
// }
|
||||
// static void glowGenTextures(uintptr_t fnptr, GLsizei n, GLuint* textures) {
|
||||
// typedef void (*fn)(GLsizei n, GLuint* textures);
|
||||
// ((fn)(fnptr))(n, textures);
|
||||
// }
|
||||
// static void glowGenVertexArrays(uintptr_t fnptr, GLsizei n, GLuint* arrays) {
|
||||
// typedef void (*fn)(GLsizei n, GLuint* arrays);
|
||||
// ((fn)(fnptr))(n, arrays);
|
||||
// }
|
||||
// static GLenum glowGetError(uintptr_t fnptr) {
|
||||
// typedef GLenum (*fn)();
|
||||
// return ((fn)(fnptr))();
|
||||
// }
|
||||
// static void glowGetIntegerv(uintptr_t fnptr, GLenum pname, GLint* data) {
|
||||
// typedef void (*fn)(GLenum pname, GLint* data);
|
||||
// ((fn)(fnptr))(pname, data);
|
||||
// }
|
||||
// static void glowGetProgramInfoLog(uintptr_t fnptr, GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog) {
|
||||
// typedef void (*fn)(GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog);
|
||||
// ((fn)(fnptr))(program, bufSize, length, infoLog);
|
||||
// }
|
||||
// static void glowGetProgramiv(uintptr_t fnptr, GLuint program, GLenum pname, GLint* params) {
|
||||
// typedef void (*fn)(GLuint program, GLenum pname, GLint* params);
|
||||
// ((fn)(fnptr))(program, pname, params);
|
||||
// }
|
||||
// static void glowGetShaderInfoLog(uintptr_t fnptr, GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog) {
|
||||
// typedef void (*fn)(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog);
|
||||
// ((fn)(fnptr))(shader, bufSize, length, infoLog);
|
||||
// }
|
||||
// static void glowGetShaderiv(uintptr_t fnptr, GLuint shader, GLenum pname, GLint* params) {
|
||||
// typedef void (*fn)(GLuint shader, GLenum pname, GLint* params);
|
||||
// ((fn)(fnptr))(shader, pname, params);
|
||||
// }
|
||||
// static GLint glowGetUniformLocation(uintptr_t fnptr, GLuint program, const GLchar* name) {
|
||||
// typedef GLint (*fn)(GLuint program, const GLchar* name);
|
||||
// return ((fn)(fnptr))(program, name);
|
||||
// }
|
||||
// static GLboolean glowIsFramebuffer(uintptr_t fnptr, GLuint framebuffer) {
|
||||
// typedef GLboolean (*fn)(GLuint framebuffer);
|
||||
// return ((fn)(fnptr))(framebuffer);
|
||||
// }
|
||||
// static GLboolean glowIsProgram(uintptr_t fnptr, GLuint program) {
|
||||
// typedef GLboolean (*fn)(GLuint program);
|
||||
// return ((fn)(fnptr))(program);
|
||||
// }
|
||||
// static GLboolean glowIsRenderbuffer(uintptr_t fnptr, GLuint renderbuffer) {
|
||||
// typedef GLboolean (*fn)(GLuint renderbuffer);
|
||||
// return ((fn)(fnptr))(renderbuffer);
|
||||
// }
|
||||
// static void glowLinkProgram(uintptr_t fnptr, GLuint program) {
|
||||
// typedef void (*fn)(GLuint program);
|
||||
// ((fn)(fnptr))(program);
|
||||
// }
|
||||
// static void glowPixelStorei(uintptr_t fnptr, GLenum pname, GLint param) {
|
||||
// typedef void (*fn)(GLenum pname, GLint param);
|
||||
// ((fn)(fnptr))(pname, param);
|
||||
// }
|
||||
// static void glowReadPixels(uintptr_t fnptr, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) {
|
||||
// typedef void (*fn)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels);
|
||||
// ((fn)(fnptr))(x, y, width, height, format, type, pixels);
|
||||
// }
|
||||
// static void glowRenderbufferStorage(uintptr_t fnptr, GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
|
||||
// typedef void (*fn)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
|
||||
// ((fn)(fnptr))(target, internalformat, width, height);
|
||||
// }
|
||||
// static void glowScissor(uintptr_t fnptr, GLint x, GLint y, GLsizei width, GLsizei height) {
|
||||
// typedef void (*fn)(GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
// ((fn)(fnptr))(x, y, width, height);
|
||||
// }
|
||||
// static void glowShaderSource(uintptr_t fnptr, GLuint shader, GLsizei count, const GLchar*const* string, const GLint* length) {
|
||||
// typedef void (*fn)(GLuint shader, GLsizei count, const GLchar*const* string, const GLint* length);
|
||||
// ((fn)(fnptr))(shader, count, string, length);
|
||||
// }
|
||||
// static void glowStencilFunc(uintptr_t fnptr, GLenum func, GLint ref, GLuint mask) {
|
||||
// typedef void (*fn)(GLenum func, GLint ref, GLuint mask);
|
||||
// ((fn)(fnptr))(func, ref, mask);
|
||||
// }
|
||||
// static void glowStencilOpSeparate(uintptr_t fnptr, GLenum face, GLenum fail, GLenum zfail, GLenum zpass) {
|
||||
// typedef void (*fn)(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
|
||||
// ((fn)(fnptr))(face, fail, zfail, zpass);
|
||||
// }
|
||||
// static void glowTexImage2D(uintptr_t fnptr, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels) {
|
||||
// typedef void (*fn)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels);
|
||||
// ((fn)(fnptr))(target, level, internalformat, width, height, border, format, type, pixels);
|
||||
// }
|
||||
// static void glowTexParameteri(uintptr_t fnptr, GLenum target, GLenum pname, GLint param) {
|
||||
// typedef void (*fn)(GLenum target, GLenum pname, GLint param);
|
||||
// ((fn)(fnptr))(target, pname, param);
|
||||
// }
|
||||
// static void glowTexSubImage2D(uintptr_t fnptr, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels) {
|
||||
// typedef void (*fn)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels);
|
||||
// ((fn)(fnptr))(target, level, xoffset, yoffset, width, height, format, type, pixels);
|
||||
// }
|
||||
// static void glowUniform1fv(uintptr_t fnptr, GLint location, GLsizei count, const GLfloat* value) {
|
||||
// typedef void (*fn)(GLint location, GLsizei count, const GLfloat* value);
|
||||
// ((fn)(fnptr))(location, count, value);
|
||||
// }
|
||||
// static void glowUniform1i(uintptr_t fnptr, GLint location, GLint v0) {
|
||||
// typedef void (*fn)(GLint location, GLint v0);
|
||||
// ((fn)(fnptr))(location, v0);
|
||||
// }
|
||||
// static void glowUniform1iv(uintptr_t fnptr, GLint location, GLsizei count, const GLint* value) {
|
||||
// typedef void (*fn)(GLint location, GLsizei count, const GLint* value);
|
||||
// ((fn)(fnptr))(location, count, value);
|
||||
// }
|
||||
// static void glowUniform2fv(uintptr_t fnptr, GLint location, GLsizei count, const GLfloat* value) {
|
||||
// typedef void (*fn)(GLint location, GLsizei count, const GLfloat* value);
|
||||
// ((fn)(fnptr))(location, count, value);
|
||||
// }
|
||||
// static void glowUniform2iv(uintptr_t fnptr, GLint location, GLsizei count, const GLint* value) {
|
||||
// typedef void (*fn)(GLint location, GLsizei count, const GLint* value);
|
||||
// ((fn)(fnptr))(location, count, value);
|
||||
// }
|
||||
// static void glowUniform3fv(uintptr_t fnptr, GLint location, GLsizei count, const GLfloat* value) {
|
||||
// typedef void (*fn)(GLint location, GLsizei count, const GLfloat* value);
|
||||
// ((fn)(fnptr))(location, count, value);
|
||||
// }
|
||||
// static void glowUniform3iv(uintptr_t fnptr, GLint location, GLsizei count, const GLint* value) {
|
||||
// typedef void (*fn)(GLint location, GLsizei count, const GLint* value);
|
||||
// ((fn)(fnptr))(location, count, value);
|
||||
// }
|
||||
// static void glowUniform4fv(uintptr_t fnptr, GLint location, GLsizei count, const GLfloat* value) {
|
||||
// typedef void (*fn)(GLint location, GLsizei count, const GLfloat* value);
|
||||
// ((fn)(fnptr))(location, count, value);
|
||||
// }
|
||||
// static void glowUniform4iv(uintptr_t fnptr, GLint location, GLsizei count, const GLint* value) {
|
||||
// typedef void (*fn)(GLint location, GLsizei count, const GLint* value);
|
||||
// ((fn)(fnptr))(location, count, value);
|
||||
// }
|
||||
// static void glowUniformMatrix2fv(uintptr_t fnptr, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) {
|
||||
// typedef void (*fn)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
|
||||
// ((fn)(fnptr))(location, count, transpose, value);
|
||||
// }
|
||||
// static void glowUniformMatrix3fv(uintptr_t fnptr, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) {
|
||||
// typedef void (*fn)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
|
||||
// ((fn)(fnptr))(location, count, transpose, value);
|
||||
// }
|
||||
// static void glowUniformMatrix4fv(uintptr_t fnptr, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) {
|
||||
// typedef void (*fn)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
|
||||
// ((fn)(fnptr))(location, count, transpose, value);
|
||||
// }
|
||||
// static void glowUseProgram(uintptr_t fnptr, GLuint program) {
|
||||
// typedef void (*fn)(GLuint program);
|
||||
// ((fn)(fnptr))(program);
|
||||
// }
|
||||
// static void glowVertexAttribPointer(uintptr_t fnptr, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const uintptr_t pointer) {
|
||||
// typedef void (*fn)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const uintptr_t pointer);
|
||||
// ((fn)(fnptr))(index, size, type, normalized, stride, pointer);
|
||||
// }
|
||||
// static void glowViewport(uintptr_t fnptr, GLint x, GLint y, GLsizei width, GLsizei height) {
|
||||
// typedef void (*fn)(GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
// ((fn)(fnptr))(x, y, width, height);
|
||||
// }
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type defaultContext struct {
|
||||
gpActiveTexture C.uintptr_t
|
||||
gpAttachShader C.uintptr_t
|
||||
gpBindAttribLocation C.uintptr_t
|
||||
gpBindBuffer C.uintptr_t
|
||||
gpBindFramebuffer C.uintptr_t
|
||||
gpBindRenderbuffer C.uintptr_t
|
||||
gpBindTexture C.uintptr_t
|
||||
gpBindVertexArray C.uintptr_t
|
||||
gpBlendEquationSeparate C.uintptr_t
|
||||
gpBlendFuncSeparate C.uintptr_t
|
||||
gpBufferData C.uintptr_t
|
||||
gpBufferSubData C.uintptr_t
|
||||
gpCheckFramebufferStatus C.uintptr_t
|
||||
gpClear C.uintptr_t
|
||||
gpColorMask C.uintptr_t
|
||||
gpCompileShader C.uintptr_t
|
||||
gpCreateProgram C.uintptr_t
|
||||
gpCreateShader C.uintptr_t
|
||||
gpDeleteBuffers C.uintptr_t
|
||||
gpDeleteFramebuffers C.uintptr_t
|
||||
gpDeleteProgram C.uintptr_t
|
||||
gpDeleteRenderbuffers C.uintptr_t
|
||||
gpDeleteShader C.uintptr_t
|
||||
gpDeleteTextures C.uintptr_t
|
||||
gpDeleteVertexArrays C.uintptr_t
|
||||
gpDisable C.uintptr_t
|
||||
gpDisableVertexAttribArray C.uintptr_t
|
||||
gpDrawElements C.uintptr_t
|
||||
gpEnable C.uintptr_t
|
||||
gpEnableVertexAttribArray C.uintptr_t
|
||||
gpFlush C.uintptr_t
|
||||
gpFramebufferRenderbuffer C.uintptr_t
|
||||
gpFramebufferTexture2D C.uintptr_t
|
||||
gpGenBuffers C.uintptr_t
|
||||
gpGenFramebuffers C.uintptr_t
|
||||
gpGenRenderbuffers C.uintptr_t
|
||||
gpGenTextures C.uintptr_t
|
||||
gpGenVertexArrays C.uintptr_t
|
||||
gpGetError C.uintptr_t
|
||||
gpGetIntegerv C.uintptr_t
|
||||
gpGetProgramInfoLog C.uintptr_t
|
||||
gpGetProgramiv C.uintptr_t
|
||||
gpGetShaderInfoLog C.uintptr_t
|
||||
gpGetShaderiv C.uintptr_t
|
||||
gpGetUniformLocation C.uintptr_t
|
||||
gpIsFramebuffer C.uintptr_t
|
||||
gpIsProgram C.uintptr_t
|
||||
gpIsRenderbuffer C.uintptr_t
|
||||
gpLinkProgram C.uintptr_t
|
||||
gpPixelStorei C.uintptr_t
|
||||
gpReadPixels C.uintptr_t
|
||||
gpRenderbufferStorage C.uintptr_t
|
||||
gpScissor C.uintptr_t
|
||||
gpShaderSource C.uintptr_t
|
||||
gpStencilFunc C.uintptr_t
|
||||
gpStencilOpSeparate C.uintptr_t
|
||||
gpTexImage2D C.uintptr_t
|
||||
gpTexParameteri C.uintptr_t
|
||||
gpTexSubImage2D C.uintptr_t
|
||||
gpUniform1fv C.uintptr_t
|
||||
gpUniform1i C.uintptr_t
|
||||
gpUniform1iv C.uintptr_t
|
||||
gpUniform2fv C.uintptr_t
|
||||
gpUniform2iv C.uintptr_t
|
||||
gpUniform3fv C.uintptr_t
|
||||
gpUniform3iv C.uintptr_t
|
||||
gpUniform4fv C.uintptr_t
|
||||
gpUniform4iv C.uintptr_t
|
||||
gpUniformMatrix2fv C.uintptr_t
|
||||
gpUniformMatrix3fv C.uintptr_t
|
||||
gpUniformMatrix4fv C.uintptr_t
|
||||
gpUseProgram C.uintptr_t
|
||||
gpVertexAttribPointer C.uintptr_t
|
||||
gpViewport C.uintptr_t
|
||||
|
||||
isES bool
|
||||
}
|
||||
|
||||
func NewDefaultContext() (Context, error) {
|
||||
ctx := &defaultContext{}
|
||||
if err := ctx.init(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
func boolToInt(b bool) int {
|
||||
if b {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (c *defaultContext) IsES() bool {
|
||||
return c.isES
|
||||
}
|
||||
|
||||
func (c *defaultContext) ActiveTexture(texture uint32) {
|
||||
C.glowActiveTexture(c.gpActiveTexture, C.GLenum(texture))
|
||||
}
|
||||
|
||||
func (c *defaultContext) AttachShader(program uint32, shader uint32) {
|
||||
C.glowAttachShader(c.gpAttachShader, C.GLuint(program), C.GLuint(shader))
|
||||
}
|
||||
|
||||
func (c *defaultContext) BindAttribLocation(program uint32, index uint32, name string) {
|
||||
cname := C.CString(name)
|
||||
defer C.free(unsafe.Pointer(cname))
|
||||
C.glowBindAttribLocation(c.gpBindAttribLocation, C.GLuint(program), C.GLuint(index), (*C.GLchar)(unsafe.Pointer(cname)))
|
||||
}
|
||||
|
||||
func (c *defaultContext) BindBuffer(target uint32, buffer uint32) {
|
||||
C.glowBindBuffer(c.gpBindBuffer, C.GLenum(target), C.GLuint(buffer))
|
||||
}
|
||||
|
||||
func (c *defaultContext) BindFramebuffer(target uint32, framebuffer uint32) {
|
||||
C.glowBindFramebuffer(c.gpBindFramebuffer, C.GLenum(target), C.GLuint(framebuffer))
|
||||
}
|
||||
|
||||
func (c *defaultContext) BindRenderbuffer(target uint32, renderbuffer uint32) {
|
||||
C.glowBindRenderbuffer(c.gpBindRenderbuffer, C.GLenum(target), C.GLuint(renderbuffer))
|
||||
}
|
||||
|
||||
func (c *defaultContext) BindTexture(target uint32, texture uint32) {
|
||||
C.glowBindTexture(c.gpBindTexture, C.GLenum(target), C.GLuint(texture))
|
||||
}
|
||||
|
||||
func (c *defaultContext) BindVertexArray(array uint32) {
|
||||
C.glowBindVertexArray(c.gpBindVertexArray, C.GLuint(array))
|
||||
}
|
||||
|
||||
func (c *defaultContext) BlendEquationSeparate(modeRGB uint32, modeAlpha uint32) {
|
||||
C.glowBlendEquationSeparate(c.gpBlendEquationSeparate, C.GLenum(modeRGB), C.GLenum(modeAlpha))
|
||||
}
|
||||
|
||||
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 (c *defaultContext) BufferInit(target uint32, size int, usage uint32) {
|
||||
C.glowBufferData(c.gpBufferData, C.GLenum(target), C.GLsizeiptr(size), nil, C.GLenum(usage))
|
||||
}
|
||||
|
||||
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 (c *defaultContext) CheckFramebufferStatus(target uint32) uint32 {
|
||||
ret := C.glowCheckFramebufferStatus(c.gpCheckFramebufferStatus, C.GLenum(target))
|
||||
return uint32(ret)
|
||||
}
|
||||
|
||||
func (c *defaultContext) Clear(mask uint32) {
|
||||
C.glowClear(c.gpClear, C.GLbitfield(mask))
|
||||
}
|
||||
|
||||
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 (c *defaultContext) CompileShader(shader uint32) {
|
||||
C.glowCompileShader(c.gpCompileShader, C.GLuint(shader))
|
||||
}
|
||||
|
||||
func (c *defaultContext) CreateBuffer() uint32 {
|
||||
var buffer uint32
|
||||
C.glowGenBuffers(c.gpGenBuffers, 1, (*C.GLuint)(unsafe.Pointer(&buffer)))
|
||||
return buffer
|
||||
}
|
||||
|
||||
func (c *defaultContext) CreateFramebuffer() uint32 {
|
||||
var framebuffer uint32
|
||||
C.glowGenFramebuffers(c.gpGenFramebuffers, 1, (*C.GLuint)(unsafe.Pointer(&framebuffer)))
|
||||
return framebuffer
|
||||
}
|
||||
|
||||
func (c *defaultContext) CreateProgram() uint32 {
|
||||
ret := C.glowCreateProgram(c.gpCreateProgram)
|
||||
return uint32(ret)
|
||||
}
|
||||
|
||||
func (c *defaultContext) CreateRenderbuffer() uint32 {
|
||||
var renderbuffer uint32
|
||||
C.glowGenRenderbuffers(c.gpGenRenderbuffers, 1, (*C.GLuint)(unsafe.Pointer(&renderbuffer)))
|
||||
return renderbuffer
|
||||
}
|
||||
|
||||
func (c *defaultContext) CreateShader(xtype uint32) uint32 {
|
||||
ret := C.glowCreateShader(c.gpCreateShader, C.GLenum(xtype))
|
||||
return uint32(ret)
|
||||
}
|
||||
|
||||
func (c *defaultContext) CreateTexture() uint32 {
|
||||
var texture uint32
|
||||
C.glowGenTextures(c.gpGenTextures, 1, (*C.GLuint)(unsafe.Pointer(&texture)))
|
||||
return texture
|
||||
}
|
||||
|
||||
func (c *defaultContext) CreateVertexArray() uint32 {
|
||||
var array uint32
|
||||
C.glowGenVertexArrays(c.gpGenVertexArrays, 1, (*C.GLuint)(unsafe.Pointer(&array)))
|
||||
return array
|
||||
}
|
||||
|
||||
func (c *defaultContext) DeleteBuffer(buffer uint32) {
|
||||
C.glowDeleteBuffers(c.gpDeleteBuffers, 1, (*C.GLuint)(unsafe.Pointer(&buffer)))
|
||||
}
|
||||
|
||||
func (c *defaultContext) DeleteFramebuffer(framebuffer uint32) {
|
||||
C.glowDeleteFramebuffers(c.gpDeleteFramebuffers, 1, (*C.GLuint)(unsafe.Pointer(&framebuffer)))
|
||||
}
|
||||
|
||||
func (c *defaultContext) DeleteProgram(program uint32) {
|
||||
C.glowDeleteProgram(c.gpDeleteProgram, C.GLuint(program))
|
||||
}
|
||||
|
||||
func (c *defaultContext) DeleteRenderbuffer(renderbuffer uint32) {
|
||||
C.glowDeleteRenderbuffers(c.gpDeleteRenderbuffers, 1, (*C.GLuint)(unsafe.Pointer(&renderbuffer)))
|
||||
}
|
||||
|
||||
func (c *defaultContext) DeleteShader(shader uint32) {
|
||||
C.glowDeleteShader(c.gpDeleteShader, C.GLuint(shader))
|
||||
}
|
||||
|
||||
func (c *defaultContext) DeleteTexture(texture uint32) {
|
||||
C.glowDeleteTextures(c.gpDeleteTextures, 1, (*C.GLuint)(unsafe.Pointer(&texture)))
|
||||
}
|
||||
|
||||
func (c *defaultContext) DeleteVertexArray(array uint32) {
|
||||
C.glowDeleteVertexArrays(c.gpDeleteVertexArrays, 1, (*C.GLuint)(unsafe.Pointer(&array)))
|
||||
}
|
||||
|
||||
func (c *defaultContext) Disable(cap uint32) {
|
||||
C.glowDisable(c.gpDisable, C.GLenum(cap))
|
||||
}
|
||||
|
||||
func (c *defaultContext) DisableVertexAttribArray(index uint32) {
|
||||
C.glowDisableVertexAttribArray(c.gpDisableVertexAttribArray, C.GLuint(index))
|
||||
}
|
||||
|
||||
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 (c *defaultContext) Enable(cap uint32) {
|
||||
C.glowEnable(c.gpEnable, C.GLenum(cap))
|
||||
}
|
||||
|
||||
func (c *defaultContext) EnableVertexAttribArray(index uint32) {
|
||||
C.glowEnableVertexAttribArray(c.gpEnableVertexAttribArray, C.GLuint(index))
|
||||
}
|
||||
|
||||
func (c *defaultContext) Flush() {
|
||||
C.glowFlush(c.gpFlush)
|
||||
}
|
||||
|
||||
func (c *defaultContext) FramebufferRenderbuffer(target uint32, attachment uint32, renderbuffertarget uint32, renderbuffer uint32) {
|
||||
C.glowFramebufferRenderbuffer(c.gpFramebufferRenderbuffer, C.GLenum(target), C.GLenum(attachment), C.GLenum(renderbuffertarget), C.GLuint(renderbuffer))
|
||||
}
|
||||
|
||||
func (c *defaultContext) FramebufferTexture2D(target uint32, attachment uint32, textarget uint32, texture uint32, level int32) {
|
||||
C.glowFramebufferTexture2D(c.gpFramebufferTexture2D, C.GLenum(target), C.GLenum(attachment), C.GLenum(textarget), C.GLuint(texture), C.GLint(level))
|
||||
}
|
||||
|
||||
func (c *defaultContext) GetError() uint32 {
|
||||
ret := C.glowGetError(c.gpGetError)
|
||||
return uint32(ret)
|
||||
}
|
||||
|
||||
func (c *defaultContext) GetInteger(pname uint32) int {
|
||||
var dst int32
|
||||
C.glowGetIntegerv(c.gpGetIntegerv, C.GLenum(pname), (*C.GLint)(unsafe.Pointer(&dst)))
|
||||
return int(dst)
|
||||
}
|
||||
|
||||
func (c *defaultContext) GetProgramInfoLog(program uint32) string {
|
||||
bufSize := c.GetProgrami(program, INFO_LOG_LENGTH)
|
||||
infoLog := make([]byte, bufSize)
|
||||
C.glowGetProgramInfoLog(c.gpGetProgramInfoLog, C.GLuint(program), C.GLsizei(bufSize), nil, (*C.GLchar)(unsafe.Pointer(&infoLog[0])))
|
||||
return string(infoLog)
|
||||
}
|
||||
|
||||
func (c *defaultContext) GetProgrami(program uint32, pname uint32) int {
|
||||
var dst int32
|
||||
C.glowGetProgramiv(c.gpGetProgramiv, C.GLuint(program), C.GLenum(pname), (*C.GLint)(unsafe.Pointer(&dst)))
|
||||
return int(dst)
|
||||
}
|
||||
|
||||
func (c *defaultContext) GetShaderInfoLog(shader uint32) string {
|
||||
bufSize := c.GetShaderi(shader, INFO_LOG_LENGTH)
|
||||
infoLog := make([]byte, bufSize)
|
||||
C.glowGetShaderInfoLog(c.gpGetShaderInfoLog, C.GLuint(shader), C.GLsizei(bufSize), nil, (*C.GLchar)(unsafe.Pointer(&infoLog[0])))
|
||||
return string(infoLog)
|
||||
}
|
||||
|
||||
func (c *defaultContext) GetShaderi(shader uint32, pname uint32) int {
|
||||
var dst int32
|
||||
C.glowGetShaderiv(c.gpGetShaderiv, C.GLuint(shader), C.GLenum(pname), (*C.GLint)(unsafe.Pointer(&dst)))
|
||||
return int(dst)
|
||||
}
|
||||
|
||||
func (c *defaultContext) GetUniformLocation(program uint32, name string) int32 {
|
||||
cname := C.CString(name)
|
||||
defer C.free(unsafe.Pointer(cname))
|
||||
ret := C.glowGetUniformLocation(c.gpGetUniformLocation, C.GLuint(program), (*C.GLchar)(unsafe.Pointer(cname)))
|
||||
return int32(ret)
|
||||
}
|
||||
|
||||
func (c *defaultContext) IsFramebuffer(framebuffer uint32) bool {
|
||||
ret := C.glowIsFramebuffer(c.gpIsFramebuffer, C.GLuint(framebuffer))
|
||||
return ret == TRUE
|
||||
}
|
||||
|
||||
func (c *defaultContext) IsProgram(program uint32) bool {
|
||||
ret := C.glowIsProgram(c.gpIsProgram, C.GLuint(program))
|
||||
return ret == TRUE
|
||||
}
|
||||
|
||||
func (c *defaultContext) IsRenderbuffer(renderbuffer uint32) bool {
|
||||
ret := C.glowIsRenderbuffer(c.gpIsRenderbuffer, C.GLuint(renderbuffer))
|
||||
return ret == TRUE
|
||||
}
|
||||
|
||||
func (c *defaultContext) LinkProgram(program uint32) {
|
||||
C.glowLinkProgram(c.gpLinkProgram, C.GLuint(program))
|
||||
}
|
||||
|
||||
func (c *defaultContext) PixelStorei(pname uint32, param int32) {
|
||||
C.glowPixelStorei(c.gpPixelStorei, C.GLenum(pname), C.GLint(param))
|
||||
}
|
||||
|
||||
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 (c *defaultContext) RenderbufferStorage(target uint32, internalformat uint32, width int32, height int32) {
|
||||
C.glowRenderbufferStorage(c.gpRenderbufferStorage, C.GLenum(target), C.GLenum(internalformat), 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 (c *defaultContext) ShaderSource(shader uint32, xstring string) {
|
||||
cstring := C.CString(xstring)
|
||||
defer C.free(unsafe.Pointer(cstring))
|
||||
C.glowShaderSource(c.gpShaderSource, C.GLuint(shader), 1, (**C.GLchar)(unsafe.Pointer(&cstring)), nil)
|
||||
}
|
||||
|
||||
func (c *defaultContext) StencilFunc(xfunc uint32, ref int32, mask uint32) {
|
||||
C.glowStencilFunc(c.gpStencilFunc, C.GLenum(xfunc), C.GLint(ref), C.GLuint(mask))
|
||||
}
|
||||
|
||||
func (c *defaultContext) StencilOpSeparate(face uint32, fail uint32, zfail uint32, zpass uint32) {
|
||||
C.glowStencilOpSeparate(c.gpStencilOpSeparate, C.GLenum(face), C.GLenum(fail), C.GLenum(zfail), C.GLenum(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]
|
||||
}
|
||||
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 (c *defaultContext) TexParameteri(target uint32, pname uint32, param int32) {
|
||||
C.glowTexParameteri(c.gpTexParameteri, C.GLenum(target), C.GLenum(pname), C.GLint(param))
|
||||
}
|
||||
|
||||
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 (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 (c *defaultContext) Uniform1i(location int32, v0 int32) {
|
||||
C.glowUniform1i(c.gpUniform1i, C.GLint(location), C.GLint(v0))
|
||||
}
|
||||
|
||||
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 (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 (c *defaultContext) Uniform2iv(location int32, value []int32) {
|
||||
C.glowUniform2iv(c.gpUniform2iv, C.GLint(location), C.GLsizei(len(value)/2), (*C.GLint)(unsafe.Pointer(&value[0])))
|
||||
runtime.KeepAlive(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 (c *defaultContext) Uniform3iv(location int32, value []int32) {
|
||||
C.glowUniform3iv(c.gpUniform3iv, C.GLint(location), C.GLsizei(len(value)/3), (*C.GLint)(unsafe.Pointer(&value[0])))
|
||||
runtime.KeepAlive(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 (c *defaultContext) Uniform4iv(location int32, value []int32) {
|
||||
C.glowUniform4iv(c.gpUniform4iv, C.GLint(location), C.GLsizei(len(value)/4), (*C.GLint)(unsafe.Pointer(&value[0])))
|
||||
runtime.KeepAlive(value)
|
||||
}
|
||||
|
||||
func (c *defaultContext) UniformMatrix2fv(location int32, value []float32) {
|
||||
C.glowUniformMatrix2fv(c.gpUniformMatrix2fv, C.GLint(location), C.GLsizei(len(value)/4), 0, (*C.GLfloat)(unsafe.Pointer(&value[0])))
|
||||
runtime.KeepAlive(value)
|
||||
}
|
||||
|
||||
func (c *defaultContext) UniformMatrix3fv(location int32, value []float32) {
|
||||
C.glowUniformMatrix3fv(c.gpUniformMatrix3fv, C.GLint(location), C.GLsizei(len(value)/9), 0, (*C.GLfloat)(unsafe.Pointer(&value[0])))
|
||||
runtime.KeepAlive(value)
|
||||
}
|
||||
|
||||
func (c *defaultContext) UniformMatrix4fv(location int32, value []float32) {
|
||||
C.glowUniformMatrix4fv(c.gpUniformMatrix4fv, C.GLint(location), C.GLsizei(len(value)/16), 0, (*C.GLfloat)(unsafe.Pointer(&value[0])))
|
||||
runtime.KeepAlive(value)
|
||||
}
|
||||
|
||||
func (c *defaultContext) UseProgram(program uint32) {
|
||||
C.glowUseProgram(c.gpUseProgram, C.GLuint(program))
|
||||
}
|
||||
|
||||
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 (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))
|
||||
}
|
||||
|
||||
func (c *defaultContext) LoadFunctions() error {
|
||||
g := procAddressGetter{ctx: c}
|
||||
|
||||
c.gpActiveTexture = C.uintptr_t(g.get("glActiveTexture"))
|
||||
c.gpAttachShader = C.uintptr_t(g.get("glAttachShader"))
|
||||
c.gpBindAttribLocation = C.uintptr_t(g.get("glBindAttribLocation"))
|
||||
c.gpBindBuffer = C.uintptr_t(g.get("glBindBuffer"))
|
||||
c.gpBindFramebuffer = C.uintptr_t(g.get("glBindFramebuffer"))
|
||||
c.gpBindRenderbuffer = C.uintptr_t(g.get("glBindRenderbuffer"))
|
||||
c.gpBindTexture = C.uintptr_t(g.get("glBindTexture"))
|
||||
c.gpBindVertexArray = C.uintptr_t(g.get("glBindVertexArray"))
|
||||
c.gpBlendEquationSeparate = C.uintptr_t(g.get("glBlendEquationSeparate"))
|
||||
c.gpBlendFuncSeparate = C.uintptr_t(g.get("glBlendFuncSeparate"))
|
||||
c.gpBufferData = C.uintptr_t(g.get("glBufferData"))
|
||||
c.gpBufferSubData = C.uintptr_t(g.get("glBufferSubData"))
|
||||
c.gpCheckFramebufferStatus = C.uintptr_t(g.get("glCheckFramebufferStatus"))
|
||||
c.gpClear = C.uintptr_t(g.get("glClear"))
|
||||
c.gpColorMask = C.uintptr_t(g.get("glColorMask"))
|
||||
c.gpCompileShader = C.uintptr_t(g.get("glCompileShader"))
|
||||
c.gpCreateProgram = C.uintptr_t(g.get("glCreateProgram"))
|
||||
c.gpCreateShader = C.uintptr_t(g.get("glCreateShader"))
|
||||
c.gpDeleteBuffers = C.uintptr_t(g.get("glDeleteBuffers"))
|
||||
c.gpDeleteFramebuffers = C.uintptr_t(g.get("glDeleteFramebuffers"))
|
||||
c.gpDeleteProgram = C.uintptr_t(g.get("glDeleteProgram"))
|
||||
c.gpDeleteRenderbuffers = C.uintptr_t(g.get("glDeleteRenderbuffers"))
|
||||
c.gpDeleteShader = C.uintptr_t(g.get("glDeleteShader"))
|
||||
c.gpDeleteTextures = C.uintptr_t(g.get("glDeleteTextures"))
|
||||
c.gpDeleteVertexArrays = C.uintptr_t(g.get("glDeleteVertexArrays"))
|
||||
c.gpDisable = C.uintptr_t(g.get("glDisable"))
|
||||
c.gpDisableVertexAttribArray = C.uintptr_t(g.get("glDisableVertexAttribArray"))
|
||||
c.gpDrawElements = C.uintptr_t(g.get("glDrawElements"))
|
||||
c.gpEnable = C.uintptr_t(g.get("glEnable"))
|
||||
c.gpEnableVertexAttribArray = C.uintptr_t(g.get("glEnableVertexAttribArray"))
|
||||
c.gpFlush = C.uintptr_t(g.get("glFlush"))
|
||||
c.gpFramebufferRenderbuffer = C.uintptr_t(g.get("glFramebufferRenderbuffer"))
|
||||
c.gpFramebufferTexture2D = C.uintptr_t(g.get("glFramebufferTexture2D"))
|
||||
c.gpGenBuffers = C.uintptr_t(g.get("glGenBuffers"))
|
||||
c.gpGenFramebuffers = C.uintptr_t(g.get("glGenFramebuffers"))
|
||||
c.gpGenRenderbuffers = C.uintptr_t(g.get("glGenRenderbuffers"))
|
||||
c.gpGenTextures = C.uintptr_t(g.get("glGenTextures"))
|
||||
c.gpGenVertexArrays = C.uintptr_t(g.get("glGenVertexArrays"))
|
||||
c.gpGetError = C.uintptr_t(g.get("glGetError"))
|
||||
c.gpGetIntegerv = C.uintptr_t(g.get("glGetIntegerv"))
|
||||
c.gpGetProgramInfoLog = C.uintptr_t(g.get("glGetProgramInfoLog"))
|
||||
c.gpGetProgramiv = C.uintptr_t(g.get("glGetProgramiv"))
|
||||
c.gpGetShaderInfoLog = C.uintptr_t(g.get("glGetShaderInfoLog"))
|
||||
c.gpGetShaderiv = C.uintptr_t(g.get("glGetShaderiv"))
|
||||
c.gpGetUniformLocation = C.uintptr_t(g.get("glGetUniformLocation"))
|
||||
c.gpIsFramebuffer = C.uintptr_t(g.get("glIsFramebuffer"))
|
||||
c.gpIsProgram = C.uintptr_t(g.get("glIsProgram"))
|
||||
c.gpIsRenderbuffer = C.uintptr_t(g.get("glIsRenderbuffer"))
|
||||
c.gpLinkProgram = C.uintptr_t(g.get("glLinkProgram"))
|
||||
c.gpPixelStorei = C.uintptr_t(g.get("glPixelStorei"))
|
||||
c.gpReadPixels = C.uintptr_t(g.get("glReadPixels"))
|
||||
c.gpRenderbufferStorage = C.uintptr_t(g.get("glRenderbufferStorage"))
|
||||
c.gpScissor = C.uintptr_t(g.get("glScissor"))
|
||||
c.gpShaderSource = C.uintptr_t(g.get("glShaderSource"))
|
||||
c.gpStencilFunc = C.uintptr_t(g.get("glStencilFunc"))
|
||||
c.gpStencilOpSeparate = C.uintptr_t(g.get("glStencilOpSeparate"))
|
||||
c.gpTexImage2D = C.uintptr_t(g.get("glTexImage2D"))
|
||||
c.gpTexParameteri = C.uintptr_t(g.get("glTexParameteri"))
|
||||
c.gpTexSubImage2D = C.uintptr_t(g.get("glTexSubImage2D"))
|
||||
c.gpUniform1fv = C.uintptr_t(g.get("glUniform1fv"))
|
||||
c.gpUniform1i = C.uintptr_t(g.get("glUniform1i"))
|
||||
c.gpUniform1iv = C.uintptr_t(g.get("glUniform1iv"))
|
||||
c.gpUniform2fv = C.uintptr_t(g.get("glUniform2fv"))
|
||||
c.gpUniform2iv = C.uintptr_t(g.get("glUniform2iv"))
|
||||
c.gpUniform3fv = C.uintptr_t(g.get("glUniform3fv"))
|
||||
c.gpUniform3iv = C.uintptr_t(g.get("glUniform3iv"))
|
||||
c.gpUniform4fv = C.uintptr_t(g.get("glUniform4fv"))
|
||||
c.gpUniform4iv = C.uintptr_t(g.get("glUniform4iv"))
|
||||
c.gpUniformMatrix2fv = C.uintptr_t(g.get("glUniformMatrix2fv"))
|
||||
c.gpUniformMatrix3fv = C.uintptr_t(g.get("glUniformMatrix3fv"))
|
||||
c.gpUniformMatrix4fv = C.uintptr_t(g.get("glUniformMatrix4fv"))
|
||||
c.gpUseProgram = C.uintptr_t(g.get("glUseProgram"))
|
||||
c.gpVertexAttribPointer = C.uintptr_t(g.get("glVertexAttribPointer"))
|
||||
c.gpViewport = C.uintptr_t(g.get("glViewport"))
|
||||
|
||||
return g.error()
|
||||
}
|
||||
Generated
Vendored
+634
@@ -0,0 +1,634 @@
|
||||
// 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.
|
||||
|
||||
package gl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall/js"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/jsutil"
|
||||
)
|
||||
|
||||
type defaultContext struct {
|
||||
fnActiveTexture js.Value
|
||||
fnAttachShader js.Value
|
||||
fnBindAttribLocation js.Value
|
||||
fnBindBuffer js.Value
|
||||
fnBindFramebuffer js.Value
|
||||
fnBindRenderbuffer js.Value
|
||||
fnBindTexture js.Value
|
||||
fnBindVertexArray js.Value
|
||||
fnBlendEquationSeparate js.Value
|
||||
fnBlendFuncSeparate js.Value
|
||||
fnBufferData js.Value
|
||||
fnBufferSubData js.Value
|
||||
fnCheckFramebufferStatus js.Value
|
||||
fnClear js.Value
|
||||
fnColorMask js.Value
|
||||
fnCompileShader js.Value
|
||||
fnCreateBuffer js.Value
|
||||
fnCreateFramebuffer js.Value
|
||||
fnCreateProgram js.Value
|
||||
fnCreateRenderbuffer js.Value
|
||||
fnCreateShader js.Value
|
||||
fnCreateTexture js.Value
|
||||
fnCreateVertexArray js.Value
|
||||
fnDeleteBuffer js.Value
|
||||
fnDeleteFramebuffer js.Value
|
||||
fnDeleteProgram js.Value
|
||||
fnDeleteRenderbuffer js.Value
|
||||
fnDeleteShader js.Value
|
||||
fnDeleteTexture js.Value
|
||||
fnDeleteVertexArray js.Value
|
||||
fnDisable js.Value
|
||||
fnDisableVertexAttribArray js.Value
|
||||
fnDrawElements js.Value
|
||||
fnEnable js.Value
|
||||
fnEnableVertexAttribArray js.Value
|
||||
fnFramebufferRenderbuffer js.Value
|
||||
fnFramebufferTexture2D js.Value
|
||||
fnFlush js.Value
|
||||
fnGetError js.Value
|
||||
fnGetParameter js.Value
|
||||
fnGetProgramInfoLog js.Value
|
||||
fnGetProgramParameter js.Value
|
||||
fnGetShaderInfoLog js.Value
|
||||
fnGetShaderParameter js.Value
|
||||
fnGetUniformLocation js.Value
|
||||
fnIsFramebuffer js.Value
|
||||
fnIsProgram js.Value
|
||||
fnIsRenderbuffer js.Value
|
||||
fnLinkProgram js.Value
|
||||
fnPixelStorei js.Value
|
||||
fnReadPixels js.Value
|
||||
fnRenderbufferStorage js.Value
|
||||
fnScissor js.Value
|
||||
fnShaderSource js.Value
|
||||
fnStencilFunc js.Value
|
||||
fnStencilMask js.Value
|
||||
fnStencilOpSeparate js.Value
|
||||
fnTexImage2D js.Value
|
||||
fnTexSubImage2D js.Value
|
||||
fnTexParameteri js.Value
|
||||
fnUniform1fv js.Value
|
||||
fnUniform1i js.Value
|
||||
fnUniform1iv js.Value
|
||||
fnUniform2fv js.Value
|
||||
fnUniform2iv js.Value
|
||||
fnUniform3fv js.Value
|
||||
fnUniform3iv js.Value
|
||||
fnUniform4fv js.Value
|
||||
fnUniform4iv js.Value
|
||||
fnUniformMatrix2fv js.Value
|
||||
fnUniformMatrix3fv js.Value
|
||||
fnUniformMatrix4fv js.Value
|
||||
fnUseProgram js.Value
|
||||
fnVertexAttribPointer js.Value
|
||||
fnViewport js.Value
|
||||
|
||||
buffers values
|
||||
framebuffers values
|
||||
programs values
|
||||
renderbuffers values
|
||||
shaders values
|
||||
textures values
|
||||
vertexArrays values
|
||||
uniformLocations map[uint32]*values
|
||||
}
|
||||
|
||||
type values struct {
|
||||
idToValue map[uint32]js.Value
|
||||
lastID uint32
|
||||
}
|
||||
|
||||
func (v *values) create(value js.Value) uint32 {
|
||||
v.lastID++
|
||||
id := v.lastID
|
||||
if v.idToValue == nil {
|
||||
v.idToValue = map[uint32]js.Value{}
|
||||
}
|
||||
v.idToValue[id] = value
|
||||
return id
|
||||
}
|
||||
|
||||
func (v *values) get(id uint32) js.Value {
|
||||
return v.idToValue[id]
|
||||
}
|
||||
|
||||
func (v *values) getID(value js.Value) (uint32, bool) {
|
||||
for id, v := range v.idToValue {
|
||||
if v.Equal(value) {
|
||||
return id, true
|
||||
}
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func (v *values) getOrCreate(value js.Value) uint32 {
|
||||
id, ok := v.getID(value)
|
||||
if ok {
|
||||
return id
|
||||
}
|
||||
return v.create(value)
|
||||
}
|
||||
|
||||
func (v *values) delete(id uint32) {
|
||||
delete(v.idToValue, id)
|
||||
}
|
||||
|
||||
func NewDefaultContext(v js.Value) (Context, error) {
|
||||
// Passing a Go string to the JS world is expensive. This causes conversion to UTF-16 (#1438).
|
||||
// In order to reduce the cost when calling functions, create the function objects by bind and use them.
|
||||
g := &defaultContext{
|
||||
fnActiveTexture: v.Get("activeTexture").Call("bind", v),
|
||||
fnAttachShader: v.Get("attachShader").Call("bind", v),
|
||||
fnBindAttribLocation: v.Get("bindAttribLocation").Call("bind", v),
|
||||
fnBindBuffer: v.Get("bindBuffer").Call("bind", v),
|
||||
fnBindFramebuffer: v.Get("bindFramebuffer").Call("bind", v),
|
||||
fnBindRenderbuffer: v.Get("bindRenderbuffer").Call("bind", v),
|
||||
fnBindTexture: v.Get("bindTexture").Call("bind", v),
|
||||
fnBindVertexArray: v.Get("bindVertexArray").Call("bind", v),
|
||||
fnBlendEquationSeparate: v.Get("blendEquationSeparate").Call("bind", v),
|
||||
fnBlendFuncSeparate: v.Get("blendFuncSeparate").Call("bind", v),
|
||||
fnBufferData: v.Get("bufferData").Call("bind", v),
|
||||
fnBufferSubData: v.Get("bufferSubData").Call("bind", v),
|
||||
fnCheckFramebufferStatus: v.Get("checkFramebufferStatus").Call("bind", v),
|
||||
fnClear: v.Get("clear").Call("bind", v),
|
||||
fnColorMask: v.Get("colorMask").Call("bind", v),
|
||||
fnCompileShader: v.Get("compileShader").Call("bind", v),
|
||||
fnCreateBuffer: v.Get("createBuffer").Call("bind", v),
|
||||
fnCreateFramebuffer: v.Get("createFramebuffer").Call("bind", v),
|
||||
fnCreateProgram: v.Get("createProgram").Call("bind", v),
|
||||
fnCreateRenderbuffer: v.Get("createRenderbuffer").Call("bind", v),
|
||||
fnCreateShader: v.Get("createShader").Call("bind", v),
|
||||
fnCreateTexture: v.Get("createTexture").Call("bind", v),
|
||||
fnCreateVertexArray: v.Get("createVertexArray").Call("bind", v),
|
||||
fnDeleteBuffer: v.Get("deleteBuffer").Call("bind", v),
|
||||
fnDeleteFramebuffer: v.Get("deleteFramebuffer").Call("bind", v),
|
||||
fnDeleteProgram: v.Get("deleteProgram").Call("bind", v),
|
||||
fnDeleteRenderbuffer: v.Get("deleteRenderbuffer").Call("bind", v),
|
||||
fnDeleteShader: v.Get("deleteShader").Call("bind", v),
|
||||
fnDeleteTexture: v.Get("deleteTexture").Call("bind", v),
|
||||
fnDeleteVertexArray: v.Get("deleteVertexArray").Call("bind", v),
|
||||
fnDisable: v.Get("disable").Call("bind", v),
|
||||
fnDisableVertexAttribArray: v.Get("disableVertexAttribArray").Call("bind", v),
|
||||
fnDrawElements: v.Get("drawElements").Call("bind", v),
|
||||
fnEnable: v.Get("enable").Call("bind", v),
|
||||
fnEnableVertexAttribArray: v.Get("enableVertexAttribArray").Call("bind", v),
|
||||
fnFramebufferRenderbuffer: v.Get("framebufferRenderbuffer").Call("bind", v),
|
||||
fnFramebufferTexture2D: v.Get("framebufferTexture2D").Call("bind", v),
|
||||
fnFlush: v.Get("flush").Call("bind", v),
|
||||
fnGetError: v.Get("getError").Call("bind", v),
|
||||
fnGetParameter: v.Get("getParameter").Call("bind", v),
|
||||
fnGetProgramInfoLog: v.Get("getProgramInfoLog").Call("bind", v),
|
||||
fnGetProgramParameter: v.Get("getProgramParameter").Call("bind", v),
|
||||
fnGetShaderInfoLog: v.Get("getShaderInfoLog").Call("bind", v),
|
||||
fnGetShaderParameter: v.Get("getShaderParameter").Call("bind", v),
|
||||
fnGetUniformLocation: v.Get("getUniformLocation").Call("bind", v),
|
||||
fnIsFramebuffer: v.Get("isFramebuffer").Call("bind", v),
|
||||
fnIsProgram: v.Get("isProgram").Call("bind", v),
|
||||
fnIsRenderbuffer: v.Get("isRenderbuffer").Call("bind", v),
|
||||
fnLinkProgram: v.Get("linkProgram").Call("bind", v),
|
||||
fnPixelStorei: v.Get("pixelStorei").Call("bind", v),
|
||||
fnReadPixels: v.Get("readPixels").Call("bind", v),
|
||||
fnRenderbufferStorage: v.Get("renderbufferStorage").Call("bind", v),
|
||||
fnScissor: v.Get("scissor").Call("bind", v),
|
||||
fnShaderSource: v.Get("shaderSource").Call("bind", v),
|
||||
fnStencilFunc: v.Get("stencilFunc").Call("bind", v),
|
||||
fnStencilMask: v.Get("stencilMask").Call("bind", v),
|
||||
fnStencilOpSeparate: v.Get("stencilOpSeparate").Call("bind", v),
|
||||
fnTexImage2D: v.Get("texImage2D").Call("bind", v),
|
||||
fnTexSubImage2D: v.Get("texSubImage2D").Call("bind", v),
|
||||
fnTexParameteri: v.Get("texParameteri").Call("bind", v),
|
||||
fnUniform1fv: v.Get("uniform1fv").Call("bind", v),
|
||||
fnUniform1i: v.Get("uniform1i").Call("bind", v),
|
||||
fnUniform1iv: v.Get("uniform1iv").Call("bind", v),
|
||||
fnUniform2fv: v.Get("uniform2fv").Call("bind", v),
|
||||
fnUniform2iv: v.Get("uniform2iv").Call("bind", v),
|
||||
fnUniform3fv: v.Get("uniform3fv").Call("bind", v),
|
||||
fnUniform3iv: v.Get("uniform3iv").Call("bind", v),
|
||||
fnUniform4fv: v.Get("uniform4fv").Call("bind", v),
|
||||
fnUniform4iv: v.Get("uniform4iv").Call("bind", v),
|
||||
fnUniformMatrix2fv: v.Get("uniformMatrix2fv").Call("bind", v),
|
||||
fnUniformMatrix3fv: v.Get("uniformMatrix3fv").Call("bind", v),
|
||||
fnUniformMatrix4fv: v.Get("uniformMatrix4fv").Call("bind", v),
|
||||
fnUseProgram: v.Get("useProgram").Call("bind", v),
|
||||
fnVertexAttribPointer: v.Get("vertexAttribPointer").Call("bind", v),
|
||||
fnViewport: v.Get("viewport").Call("bind", v),
|
||||
}
|
||||
|
||||
return g, nil
|
||||
}
|
||||
|
||||
func (c *defaultContext) getUniformLocation(location int32) js.Value {
|
||||
program := uint32(location) >> 5
|
||||
return c.uniformLocations[program].get(uint32(location) & ((1 << 5) - 1))
|
||||
}
|
||||
|
||||
func (c *defaultContext) LoadFunctions() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *defaultContext) IsES() bool {
|
||||
// WebGL is compatible with GLES.
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *defaultContext) ActiveTexture(texture uint32) {
|
||||
c.fnActiveTexture.Invoke(texture)
|
||||
}
|
||||
|
||||
func (c *defaultContext) AttachShader(program uint32, shader uint32) {
|
||||
c.fnAttachShader.Invoke(c.programs.get(program), c.shaders.get(shader))
|
||||
}
|
||||
|
||||
func (c *defaultContext) BindAttribLocation(program uint32, index uint32, name string) {
|
||||
c.fnBindAttribLocation.Invoke(c.programs.get(program), index, name)
|
||||
}
|
||||
|
||||
func (c *defaultContext) BindBuffer(target uint32, buffer uint32) {
|
||||
c.fnBindBuffer.Invoke(target, c.buffers.get(buffer))
|
||||
}
|
||||
|
||||
func (c *defaultContext) BindFramebuffer(target uint32, framebuffer uint32) {
|
||||
c.fnBindFramebuffer.Invoke(target, c.framebuffers.get(framebuffer))
|
||||
}
|
||||
|
||||
func (c *defaultContext) BindRenderbuffer(target uint32, renderbuffer uint32) {
|
||||
c.fnBindRenderbuffer.Invoke(target, c.renderbuffers.get(renderbuffer))
|
||||
}
|
||||
|
||||
func (c *defaultContext) BindTexture(target uint32, texture uint32) {
|
||||
c.fnBindTexture.Invoke(target, c.textures.get(texture))
|
||||
}
|
||||
|
||||
func (c *defaultContext) BindVertexArray(array uint32) {
|
||||
c.fnBindVertexArray.Invoke(c.vertexArrays.get(array))
|
||||
}
|
||||
|
||||
func (c *defaultContext) BlendEquationSeparate(modeRGB uint32, modeAlpha uint32) {
|
||||
c.fnBlendEquationSeparate.Invoke(modeRGB, modeAlpha)
|
||||
}
|
||||
|
||||
func (c *defaultContext) BlendFuncSeparate(srcRGB uint32, dstRGB uint32, srcAlpha uint32, dstAlpha uint32) {
|
||||
c.fnBlendFuncSeparate.Invoke(srcRGB, dstRGB, srcAlpha, dstAlpha)
|
||||
}
|
||||
|
||||
func (c *defaultContext) BufferInit(target uint32, size int, usage uint32) {
|
||||
c.fnBufferData.Invoke(target, size, usage)
|
||||
}
|
||||
|
||||
func (c *defaultContext) BufferSubData(target uint32, offset int, data []byte) {
|
||||
l := len(data)
|
||||
arr := jsutil.TemporaryUint8ArrayFromUint8Slice(l, data)
|
||||
c.fnBufferSubData.Invoke(target, offset, arr, 0, l)
|
||||
}
|
||||
|
||||
func (c *defaultContext) CheckFramebufferStatus(target uint32) uint32 {
|
||||
return uint32(c.fnCheckFramebufferStatus.Invoke(target).Int())
|
||||
}
|
||||
|
||||
func (c *defaultContext) Clear(mask uint32) {
|
||||
c.fnClear.Invoke(mask)
|
||||
}
|
||||
|
||||
func (c *defaultContext) ColorMask(red, green, blue, alpha bool) {
|
||||
c.fnColorMask.Invoke(red, green, blue, alpha)
|
||||
}
|
||||
|
||||
func (c *defaultContext) CompileShader(shader uint32) {
|
||||
c.fnCompileShader.Invoke(c.shaders.get(shader))
|
||||
}
|
||||
|
||||
func (c *defaultContext) CreateBuffer() uint32 {
|
||||
return c.buffers.create(c.fnCreateBuffer.Invoke())
|
||||
}
|
||||
|
||||
func (c *defaultContext) CreateFramebuffer() uint32 {
|
||||
return c.framebuffers.create(c.fnCreateFramebuffer.Invoke())
|
||||
}
|
||||
|
||||
func (c *defaultContext) CreateProgram() uint32 {
|
||||
return c.programs.create(c.fnCreateProgram.Invoke())
|
||||
}
|
||||
|
||||
func (c *defaultContext) CreateRenderbuffer() uint32 {
|
||||
return c.renderbuffers.create(c.fnCreateRenderbuffer.Invoke())
|
||||
}
|
||||
|
||||
func (c *defaultContext) CreateShader(xtype uint32) uint32 {
|
||||
return c.shaders.create(c.fnCreateShader.Invoke(xtype))
|
||||
}
|
||||
|
||||
func (c *defaultContext) CreateTexture() uint32 {
|
||||
return c.textures.create(c.fnCreateTexture.Invoke())
|
||||
}
|
||||
|
||||
func (c *defaultContext) CreateVertexArray() uint32 {
|
||||
return c.vertexArrays.create(c.fnCreateVertexArray.Invoke())
|
||||
}
|
||||
|
||||
func (c *defaultContext) DeleteBuffer(buffer uint32) {
|
||||
c.fnDeleteBuffer.Invoke(c.buffers.get(buffer))
|
||||
c.buffers.delete(buffer)
|
||||
}
|
||||
|
||||
func (c *defaultContext) DeleteFramebuffer(framebuffer uint32) {
|
||||
c.fnDeleteFramebuffer.Invoke(c.framebuffers.get(framebuffer))
|
||||
c.framebuffers.delete(framebuffer)
|
||||
}
|
||||
|
||||
func (c *defaultContext) DeleteProgram(program uint32) {
|
||||
c.fnDeleteProgram.Invoke(c.programs.get(program))
|
||||
c.programs.delete(program)
|
||||
delete(c.uniformLocations, program)
|
||||
}
|
||||
|
||||
func (c *defaultContext) DeleteRenderbuffer(renderbuffer uint32) {
|
||||
c.fnDeleteRenderbuffer.Invoke(c.renderbuffers.get(renderbuffer))
|
||||
c.renderbuffers.delete(renderbuffer)
|
||||
}
|
||||
|
||||
func (c *defaultContext) DeleteShader(shader uint32) {
|
||||
c.fnDeleteShader.Invoke(c.shaders.get(shader))
|
||||
c.shaders.delete(shader)
|
||||
}
|
||||
|
||||
func (c *defaultContext) DeleteTexture(texture uint32) {
|
||||
c.fnDeleteTexture.Invoke(c.textures.get(texture))
|
||||
c.textures.delete(texture)
|
||||
}
|
||||
|
||||
func (c *defaultContext) DeleteVertexArray(array uint32) {
|
||||
c.fnDeleteVertexArray.Invoke(c.vertexArrays.get(array))
|
||||
c.textures.delete(array)
|
||||
}
|
||||
|
||||
func (c *defaultContext) Disable(cap uint32) {
|
||||
c.fnDisable.Invoke(cap)
|
||||
}
|
||||
|
||||
func (c *defaultContext) DisableVertexAttribArray(index uint32) {
|
||||
c.fnDisableVertexAttribArray.Invoke(index)
|
||||
}
|
||||
|
||||
func (c *defaultContext) DrawElements(mode uint32, count int32, xtype uint32, offset int) {
|
||||
c.fnDrawElements.Invoke(mode, count, xtype, offset)
|
||||
}
|
||||
|
||||
func (c *defaultContext) Enable(cap uint32) {
|
||||
c.fnEnable.Invoke(cap)
|
||||
}
|
||||
|
||||
func (c *defaultContext) EnableVertexAttribArray(index uint32) {
|
||||
c.fnEnableVertexAttribArray.Invoke(index)
|
||||
}
|
||||
|
||||
func (c *defaultContext) Flush() {
|
||||
c.fnFlush.Invoke()
|
||||
}
|
||||
|
||||
func (c *defaultContext) FramebufferRenderbuffer(target uint32, attachment uint32, renderbuffertarget uint32, renderbuffer uint32) {
|
||||
c.fnFramebufferRenderbuffer.Invoke(target, attachment, renderbuffertarget, c.renderbuffers.get(renderbuffer))
|
||||
}
|
||||
|
||||
func (c *defaultContext) FramebufferTexture2D(target uint32, attachment uint32, textarget uint32, texture uint32, level int32) {
|
||||
c.fnFramebufferTexture2D.Invoke(target, attachment, textarget, c.textures.get(texture), level)
|
||||
}
|
||||
|
||||
func (c *defaultContext) GetError() uint32 {
|
||||
return uint32(c.fnGetError.Invoke().Int())
|
||||
}
|
||||
|
||||
func (c *defaultContext) GetInteger(pname uint32) int {
|
||||
ret := c.fnGetParameter.Invoke(pname)
|
||||
switch pname {
|
||||
case FRAMEBUFFER_BINDING:
|
||||
id, ok := c.framebuffers.getID(ret)
|
||||
if !ok {
|
||||
return 0
|
||||
}
|
||||
return int(id)
|
||||
case MAX_TEXTURE_SIZE:
|
||||
return ret.Int()
|
||||
default:
|
||||
panic(fmt.Sprintf("gl: unexpected pname at GetInteger: %d", pname))
|
||||
}
|
||||
}
|
||||
|
||||
func (c *defaultContext) GetProgramInfoLog(program uint32) string {
|
||||
return c.fnGetProgramInfoLog.Invoke(c.programs.get(program)).String()
|
||||
}
|
||||
|
||||
func (c *defaultContext) GetProgrami(program uint32, pname uint32) int {
|
||||
v := c.fnGetProgramParameter.Invoke(c.programs.get(program), pname)
|
||||
switch v.Type() {
|
||||
case js.TypeNumber:
|
||||
return v.Int()
|
||||
case js.TypeBoolean:
|
||||
if v.Bool() {
|
||||
return TRUE
|
||||
}
|
||||
return FALSE
|
||||
default:
|
||||
panic(fmt.Sprintf("gl: unexpected return type at GetProgrami: %v", v))
|
||||
}
|
||||
}
|
||||
|
||||
func (c *defaultContext) GetShaderInfoLog(shader uint32) string {
|
||||
return c.fnGetShaderInfoLog.Invoke(c.shaders.get(shader)).String()
|
||||
}
|
||||
|
||||
func (c *defaultContext) GetShaderi(shader uint32, pname uint32) int {
|
||||
v := c.fnGetShaderParameter.Invoke(c.shaders.get(shader), pname)
|
||||
switch v.Type() {
|
||||
case js.TypeNumber:
|
||||
return v.Int()
|
||||
case js.TypeBoolean:
|
||||
if v.Bool() {
|
||||
return TRUE
|
||||
}
|
||||
return FALSE
|
||||
default:
|
||||
panic(fmt.Sprintf("gl: unexpected return type at GetShaderi: %v", v))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (c *defaultContext) GetUniformLocation(program uint32, name string) int32 {
|
||||
location := c.fnGetUniformLocation.Invoke(c.programs.get(program), name)
|
||||
if c.uniformLocations == nil {
|
||||
c.uniformLocations = map[uint32]*values{}
|
||||
}
|
||||
vs, ok := c.uniformLocations[program]
|
||||
if !ok {
|
||||
vs = &values{}
|
||||
c.uniformLocations[program] = vs
|
||||
}
|
||||
idx := vs.getOrCreate(location)
|
||||
return int32((program << 5) | idx)
|
||||
}
|
||||
|
||||
func (c *defaultContext) IsFramebuffer(framebuffer uint32) bool {
|
||||
return c.fnIsFramebuffer.Invoke(c.framebuffers.get(framebuffer)).Bool()
|
||||
}
|
||||
|
||||
func (c *defaultContext) IsProgram(program uint32) bool {
|
||||
return c.fnIsProgram.Invoke(c.programs.get(program)).Bool()
|
||||
}
|
||||
|
||||
func (c *defaultContext) IsRenderbuffer(renderbuffer uint32) bool {
|
||||
return c.fnIsRenderbuffer.Invoke(c.renderbuffers.get(renderbuffer)).Bool()
|
||||
}
|
||||
|
||||
func (c *defaultContext) LinkProgram(program uint32) {
|
||||
c.fnLinkProgram.Invoke(c.programs.get(program))
|
||||
}
|
||||
|
||||
func (c *defaultContext) PixelStorei(pname uint32, param int32) {
|
||||
c.fnPixelStorei.Invoke(pname, param)
|
||||
}
|
||||
|
||||
func (c *defaultContext) ReadPixels(dst []byte, x int32, y int32, width int32, height int32, format uint32, xtype uint32) {
|
||||
if dst == nil {
|
||||
c.fnReadPixels.Invoke(x, y, width, height, format, xtype, 0)
|
||||
return
|
||||
}
|
||||
p := jsutil.TemporaryUint8ArrayFromUint8Slice(len(dst), nil)
|
||||
c.fnReadPixels.Invoke(x, y, width, height, format, xtype, p)
|
||||
js.CopyBytesToGo(dst, p)
|
||||
}
|
||||
|
||||
func (c *defaultContext) RenderbufferStorage(target uint32, internalFormat uint32, width int32, height int32) {
|
||||
c.fnRenderbufferStorage.Invoke(target, internalFormat, width, height)
|
||||
}
|
||||
|
||||
func (c *defaultContext) Scissor(x, y, width, height int32) {
|
||||
c.fnScissor.Invoke(x, y, width, height)
|
||||
}
|
||||
|
||||
func (c *defaultContext) ShaderSource(shader uint32, xstring string) {
|
||||
c.fnShaderSource.Invoke(c.shaders.get(shader), xstring)
|
||||
}
|
||||
|
||||
func (c *defaultContext) StencilFunc(func_ uint32, ref int32, mask uint32) {
|
||||
c.fnStencilFunc.Invoke(func_, ref, mask)
|
||||
}
|
||||
|
||||
func (c *defaultContext) StencilOpSeparate(face, sfail, dpfail, dppass uint32) {
|
||||
c.fnStencilOpSeparate.Invoke(face, sfail, dpfail, dppass)
|
||||
}
|
||||
|
||||
func (c *defaultContext) TexImage2D(target uint32, level int32, internalformat int32, width int32, height int32, format uint32, xtype uint32, pixels []byte) {
|
||||
if pixels != nil {
|
||||
panic("gl: TexImage2D with non-nil pixels is not implemented")
|
||||
}
|
||||
c.fnTexImage2D.Invoke(target, level, internalformat, width, height, 0, format, xtype, nil)
|
||||
}
|
||||
|
||||
func (c *defaultContext) TexParameteri(target uint32, pname uint32, param int32) {
|
||||
c.fnTexParameteri.Invoke(target, pname, param)
|
||||
}
|
||||
|
||||
func (c *defaultContext) TexSubImage2D(target uint32, level int32, xoffset int32, yoffset int32, width int32, height int32, format uint32, xtype uint32, pixels []byte) {
|
||||
arr := jsutil.TemporaryUint8ArrayFromUint8Slice(len(pixels), pixels)
|
||||
// void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
|
||||
// GLsizei width, GLsizei height,
|
||||
// GLenum format, GLenum type, ArrayBufferView pixels, srcOffset);
|
||||
c.fnTexSubImage2D.Invoke(target, level, xoffset, yoffset, width, height, format, xtype, arr, 0)
|
||||
}
|
||||
|
||||
func (c *defaultContext) Uniform1fv(location int32, value []float32) {
|
||||
l := c.getUniformLocation(location)
|
||||
arr := jsutil.TemporaryFloat32Array(len(value), value)
|
||||
c.fnUniform1fv.Invoke(l, arr, 0, len(value))
|
||||
}
|
||||
|
||||
func (c *defaultContext) Uniform1i(location int32, v0 int32) {
|
||||
l := c.getUniformLocation(location)
|
||||
c.fnUniform1i.Invoke(l, v0)
|
||||
}
|
||||
|
||||
func (c *defaultContext) Uniform1iv(location int32, value []int32) {
|
||||
l := c.getUniformLocation(location)
|
||||
arr := jsutil.TemporaryInt32Array(len(value), value)
|
||||
c.fnUniform1iv.Invoke(l, arr, 0, len(value))
|
||||
}
|
||||
|
||||
func (c *defaultContext) Uniform2fv(location int32, value []float32) {
|
||||
l := c.getUniformLocation(location)
|
||||
arr := jsutil.TemporaryFloat32Array(len(value), value)
|
||||
c.fnUniform2fv.Invoke(l, arr, 0, len(value))
|
||||
}
|
||||
|
||||
func (c *defaultContext) Uniform2iv(location int32, value []int32) {
|
||||
l := c.getUniformLocation(location)
|
||||
arr := jsutil.TemporaryInt32Array(len(value), value)
|
||||
c.fnUniform2iv.Invoke(l, arr, 0, len(value))
|
||||
}
|
||||
|
||||
func (c *defaultContext) Uniform3fv(location int32, value []float32) {
|
||||
l := c.getUniformLocation(location)
|
||||
arr := jsutil.TemporaryFloat32Array(len(value), value)
|
||||
c.fnUniform3fv.Invoke(l, arr, 0, len(value))
|
||||
}
|
||||
|
||||
func (c *defaultContext) Uniform3iv(location int32, value []int32) {
|
||||
l := c.getUniformLocation(location)
|
||||
arr := jsutil.TemporaryInt32Array(len(value), value)
|
||||
c.fnUniform3iv.Invoke(l, arr, 0, len(value))
|
||||
}
|
||||
|
||||
func (c *defaultContext) Uniform4fv(location int32, value []float32) {
|
||||
l := c.getUniformLocation(location)
|
||||
arr := jsutil.TemporaryFloat32Array(len(value), value)
|
||||
c.fnUniform4fv.Invoke(l, arr, 0, len(value))
|
||||
}
|
||||
|
||||
func (c *defaultContext) Uniform4iv(location int32, value []int32) {
|
||||
l := c.getUniformLocation(location)
|
||||
arr := jsutil.TemporaryInt32Array(len(value), value)
|
||||
c.fnUniform4iv.Invoke(l, arr, 0, len(value))
|
||||
}
|
||||
|
||||
func (c *defaultContext) UniformMatrix2fv(location int32, value []float32) {
|
||||
l := c.getUniformLocation(location)
|
||||
arr := jsutil.TemporaryFloat32Array(len(value), value)
|
||||
c.fnUniformMatrix2fv.Invoke(l, false, arr, 0, len(value))
|
||||
}
|
||||
|
||||
func (c *defaultContext) UniformMatrix3fv(location int32, value []float32) {
|
||||
l := c.getUniformLocation(location)
|
||||
arr := jsutil.TemporaryFloat32Array(len(value), value)
|
||||
c.fnUniformMatrix3fv.Invoke(l, false, arr, 0, len(value))
|
||||
}
|
||||
|
||||
func (c *defaultContext) UniformMatrix4fv(location int32, value []float32) {
|
||||
l := c.getUniformLocation(location)
|
||||
arr := jsutil.TemporaryFloat32Array(len(value), value)
|
||||
c.fnUniformMatrix4fv.Invoke(l, false, arr, 0, len(value))
|
||||
}
|
||||
|
||||
func (c *defaultContext) UseProgram(program uint32) {
|
||||
c.fnUseProgram.Invoke(c.programs.get(program))
|
||||
}
|
||||
|
||||
func (c *defaultContext) VertexAttribPointer(index uint32, size int32, xtype uint32, normalized bool, stride int32, offset int) {
|
||||
c.fnVertexAttribPointer.Invoke(index, size, xtype, normalized, stride, offset)
|
||||
}
|
||||
|
||||
func (c *defaultContext) Viewport(x int32, y int32, width int32, height int32) {
|
||||
c.fnViewport.Invoke(x, y, width, height)
|
||||
}
|
||||
Generated
Vendored
+569
@@ -0,0 +1,569 @@
|
||||
// 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
|
||||
|
||||
package gl
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"unsafe"
|
||||
|
||||
"github.com/ebitengine/purego"
|
||||
)
|
||||
|
||||
type defaultContext struct {
|
||||
gpActiveTexture uintptr
|
||||
gpAttachShader uintptr
|
||||
gpBindAttribLocation uintptr
|
||||
gpBindBuffer uintptr
|
||||
gpBindFramebuffer uintptr
|
||||
gpBindRenderbuffer uintptr
|
||||
gpBindTexture uintptr
|
||||
gpBindVertexArray uintptr
|
||||
gpBlendEquationSeparate uintptr
|
||||
gpBlendFuncSeparate uintptr
|
||||
gpBufferData uintptr
|
||||
gpBufferSubData uintptr
|
||||
gpCheckFramebufferStatus uintptr
|
||||
gpClear uintptr
|
||||
gpColorMask uintptr
|
||||
gpCompileShader uintptr
|
||||
gpCreateProgram uintptr
|
||||
gpCreateShader uintptr
|
||||
gpDeleteBuffers uintptr
|
||||
gpDeleteFramebuffers uintptr
|
||||
gpDeleteProgram uintptr
|
||||
gpDeleteRenderbuffers uintptr
|
||||
gpDeleteShader uintptr
|
||||
gpDeleteTextures uintptr
|
||||
gpDeleteVertexArrays uintptr
|
||||
gpDisable uintptr
|
||||
gpDisableVertexAttribArray uintptr
|
||||
gpDrawElements uintptr
|
||||
gpEnable uintptr
|
||||
gpEnableVertexAttribArray uintptr
|
||||
gpFlush uintptr
|
||||
gpFramebufferRenderbuffer uintptr
|
||||
gpFramebufferTexture2D uintptr
|
||||
gpGenBuffers uintptr
|
||||
gpGenFramebuffers uintptr
|
||||
gpGenRenderbuffers uintptr
|
||||
gpGenTextures uintptr
|
||||
gpGenVertexArrays uintptr
|
||||
gpGetError uintptr
|
||||
gpGetIntegerv uintptr
|
||||
gpGetProgramInfoLog uintptr
|
||||
gpGetProgramiv uintptr
|
||||
gpGetShaderInfoLog uintptr
|
||||
gpGetShaderiv uintptr
|
||||
gpGetUniformLocation uintptr
|
||||
gpIsFramebuffer uintptr
|
||||
gpIsProgram uintptr
|
||||
gpIsRenderbuffer uintptr
|
||||
gpLinkProgram uintptr
|
||||
gpPixelStorei uintptr
|
||||
gpReadPixels uintptr
|
||||
gpRenderbufferStorage uintptr
|
||||
gpScissor uintptr
|
||||
gpShaderSource uintptr
|
||||
gpStencilFunc uintptr
|
||||
gpStencilOpSeparate uintptr
|
||||
gpTexImage2D uintptr
|
||||
gpTexParameteri uintptr
|
||||
gpTexSubImage2D uintptr
|
||||
gpUniform1fv uintptr
|
||||
gpUniform1i uintptr
|
||||
gpUniform1iv uintptr
|
||||
gpUniform2fv uintptr
|
||||
gpUniform2iv uintptr
|
||||
gpUniform3fv uintptr
|
||||
gpUniform3iv uintptr
|
||||
gpUniform4fv uintptr
|
||||
gpUniform4iv uintptr
|
||||
gpUniformMatrix2fv uintptr
|
||||
gpUniformMatrix3fv uintptr
|
||||
gpUniformMatrix4fv uintptr
|
||||
gpUseProgram uintptr
|
||||
gpVertexAttribPointer uintptr
|
||||
gpViewport uintptr
|
||||
|
||||
isES bool
|
||||
}
|
||||
|
||||
func NewDefaultContext() (Context, error) {
|
||||
ctx := &defaultContext{}
|
||||
if err := ctx.init(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
func boolToInt(b bool) int {
|
||||
if b {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (c *defaultContext) IsES() bool {
|
||||
return c.isES
|
||||
}
|
||||
|
||||
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.gpBindFramebuffer, uintptr(target), uintptr(framebuffer))
|
||||
}
|
||||
|
||||
func (c *defaultContext) BindRenderbuffer(target uint32, renderbuffer uint32) {
|
||||
purego.SyscallN(c.gpBindRenderbuffer, uintptr(target), uintptr(renderbuffer))
|
||||
}
|
||||
|
||||
func (c *defaultContext) BindTexture(target uint32, texture uint32) {
|
||||
purego.SyscallN(c.gpBindTexture, uintptr(target), uintptr(texture))
|
||||
}
|
||||
|
||||
func (c *defaultContext) BindVertexArray(array uint32) {
|
||||
purego.SyscallN(c.gpBindVertexArray, uintptr(array))
|
||||
}
|
||||
|
||||
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) BufferInit(target uint32, size int, usage uint32) {
|
||||
purego.SyscallN(c.gpBufferData, uintptr(target), uintptr(size), 0, uintptr(usage))
|
||||
}
|
||||
|
||||
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.gpCheckFramebufferStatus, 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) CreateBuffer() uint32 {
|
||||
var buffer uint32
|
||||
purego.SyscallN(c.gpGenBuffers, 1, uintptr(unsafe.Pointer(&buffer)))
|
||||
return buffer
|
||||
}
|
||||
|
||||
func (c *defaultContext) CreateFramebuffer() uint32 {
|
||||
var framebuffer uint32
|
||||
purego.SyscallN(c.gpGenFramebuffers, 1, uintptr(unsafe.Pointer(&framebuffer)))
|
||||
return framebuffer
|
||||
}
|
||||
|
||||
func (c *defaultContext) CreateProgram() uint32 {
|
||||
ret, _, _ := purego.SyscallN(c.gpCreateProgram)
|
||||
return uint32(ret)
|
||||
}
|
||||
|
||||
func (c *defaultContext) CreateRenderbuffer() uint32 {
|
||||
var renderbuffer uint32
|
||||
purego.SyscallN(c.gpGenRenderbuffers, 1, uintptr(unsafe.Pointer(&renderbuffer)))
|
||||
return renderbuffer
|
||||
}
|
||||
|
||||
func (c *defaultContext) CreateShader(xtype uint32) uint32 {
|
||||
ret, _, _ := purego.SyscallN(c.gpCreateShader, uintptr(xtype))
|
||||
return uint32(ret)
|
||||
}
|
||||
|
||||
func (c *defaultContext) CreateTexture() uint32 {
|
||||
var texture uint32
|
||||
purego.SyscallN(c.gpGenTextures, 1, uintptr(unsafe.Pointer(&texture)))
|
||||
return texture
|
||||
}
|
||||
|
||||
func (c *defaultContext) CreateVertexArray() uint32 {
|
||||
var array uint32
|
||||
purego.SyscallN(c.gpGenVertexArrays, 1, uintptr(unsafe.Pointer(&array)))
|
||||
return array
|
||||
}
|
||||
|
||||
func (c *defaultContext) DeleteBuffer(buffer uint32) {
|
||||
purego.SyscallN(c.gpDeleteBuffers, 1, uintptr(unsafe.Pointer(&buffer)))
|
||||
}
|
||||
|
||||
func (c *defaultContext) DeleteFramebuffer(framebuffer uint32) {
|
||||
purego.SyscallN(c.gpDeleteFramebuffers, 1, uintptr(unsafe.Pointer(&framebuffer)))
|
||||
}
|
||||
|
||||
func (c *defaultContext) DeleteProgram(program uint32) {
|
||||
purego.SyscallN(c.gpDeleteProgram, uintptr(program))
|
||||
}
|
||||
|
||||
func (c *defaultContext) DeleteRenderbuffer(renderbuffer uint32) {
|
||||
purego.SyscallN(c.gpDeleteRenderbuffers, 1, uintptr(unsafe.Pointer(&renderbuffer)))
|
||||
}
|
||||
|
||||
func (c *defaultContext) DeleteShader(shader uint32) {
|
||||
purego.SyscallN(c.gpDeleteShader, uintptr(shader))
|
||||
}
|
||||
|
||||
func (c *defaultContext) DeleteTexture(texture uint32) {
|
||||
purego.SyscallN(c.gpDeleteTextures, 1, uintptr(unsafe.Pointer(&texture)))
|
||||
}
|
||||
|
||||
func (c *defaultContext) DeleteVertexArray(array uint32) {
|
||||
purego.SyscallN(c.gpDeleteVertexArrays, 1, uintptr(unsafe.Pointer(&array)))
|
||||
}
|
||||
|
||||
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.gpFramebufferRenderbuffer, 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.gpFramebufferTexture2D, uintptr(target), uintptr(attachment), uintptr(textarget), uintptr(texture), uintptr(level))
|
||||
}
|
||||
|
||||
func (c *defaultContext) GetError() uint32 {
|
||||
ret, _, _ := purego.SyscallN(c.gpGetError)
|
||||
return uint32(ret)
|
||||
}
|
||||
|
||||
func (c *defaultContext) GetInteger(pname uint32) int {
|
||||
var dst int32
|
||||
purego.SyscallN(c.gpGetIntegerv, uintptr(pname), uintptr(unsafe.Pointer(&dst)))
|
||||
return int(dst)
|
||||
}
|
||||
|
||||
func (c *defaultContext) GetProgramInfoLog(program uint32) string {
|
||||
bufSize := c.GetProgrami(program, INFO_LOG_LENGTH)
|
||||
infoLog := make([]byte, bufSize)
|
||||
purego.SyscallN(c.gpGetProgramInfoLog, uintptr(program), uintptr(bufSize), 0, uintptr(unsafe.Pointer(&infoLog[0])))
|
||||
return string(infoLog)
|
||||
}
|
||||
|
||||
func (c *defaultContext) GetProgrami(program uint32, pname uint32) int {
|
||||
var dst int32
|
||||
purego.SyscallN(c.gpGetProgramiv, uintptr(program), uintptr(pname), uintptr(unsafe.Pointer(&dst)))
|
||||
return int(dst)
|
||||
}
|
||||
|
||||
func (c *defaultContext) GetShaderInfoLog(shader uint32) string {
|
||||
bufSize := c.GetShaderi(shader, INFO_LOG_LENGTH)
|
||||
infoLog := make([]byte, bufSize)
|
||||
purego.SyscallN(c.gpGetShaderInfoLog, uintptr(shader), uintptr(bufSize), 0, uintptr(unsafe.Pointer(&infoLog[0])))
|
||||
return string(infoLog)
|
||||
}
|
||||
|
||||
func (c *defaultContext) GetShaderi(shader uint32, pname uint32) int {
|
||||
var dst int32
|
||||
purego.SyscallN(c.gpGetShaderiv, uintptr(shader), uintptr(pname), uintptr(unsafe.Pointer(&dst)))
|
||||
return int(dst)
|
||||
}
|
||||
|
||||
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.gpIsFramebuffer, 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.gpIsRenderbuffer, uintptr(renderbuffer))
|
||||
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.gpRenderbufferStorage, 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) StencilOpSeparate(face uint32, fail uint32, zfail uint32, zpass uint32) {
|
||||
purego.SyscallN(c.gpStencilOpSeparate, uintptr(face), 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) Uniform2iv(location int32, value []int32) {
|
||||
purego.SyscallN(c.gpUniform2iv, 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) Uniform3iv(location int32, value []int32) {
|
||||
purego.SyscallN(c.gpUniform3iv, 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) Uniform4iv(location int32, value []int32) {
|
||||
purego.SyscallN(c.gpUniform4iv, uintptr(location), uintptr(len(value)/4), uintptr(unsafe.Pointer(&value[0])))
|
||||
runtime.KeepAlive(value)
|
||||
}
|
||||
|
||||
func (c *defaultContext) UniformMatrix2fv(location int32, value []float32) {
|
||||
purego.SyscallN(c.gpUniformMatrix2fv, uintptr(location), uintptr(len(value)/4), 0, uintptr(unsafe.Pointer(&value[0])))
|
||||
runtime.KeepAlive(value)
|
||||
}
|
||||
|
||||
func (c *defaultContext) UniformMatrix3fv(location int32, value []float32) {
|
||||
purego.SyscallN(c.gpUniformMatrix3fv, uintptr(location), uintptr(len(value)/9), 0, uintptr(unsafe.Pointer(&value[0])))
|
||||
runtime.KeepAlive(value)
|
||||
}
|
||||
|
||||
func (c *defaultContext) UniformMatrix4fv(location int32, value []float32) {
|
||||
purego.SyscallN(c.gpUniformMatrix4fv, uintptr(location), uintptr(len(value)/16), 0, 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) LoadFunctions() error {
|
||||
g := procAddressGetter{ctx: c}
|
||||
|
||||
c.gpActiveTexture = g.get("glActiveTexture")
|
||||
c.gpAttachShader = g.get("glAttachShader")
|
||||
c.gpBindAttribLocation = g.get("glBindAttribLocation")
|
||||
c.gpBindBuffer = g.get("glBindBuffer")
|
||||
c.gpBindFramebuffer = g.get("glBindFramebuffer")
|
||||
c.gpBindRenderbuffer = g.get("glBindRenderbuffer")
|
||||
c.gpBindTexture = g.get("glBindTexture")
|
||||
c.gpBindVertexArray = g.get("glBindVertexArray")
|
||||
c.gpBlendEquationSeparate = g.get("glBlendEquationSeparate")
|
||||
c.gpBlendFuncSeparate = g.get("glBlendFuncSeparate")
|
||||
c.gpBufferData = g.get("glBufferData")
|
||||
c.gpBufferSubData = g.get("glBufferSubData")
|
||||
c.gpCheckFramebufferStatus = g.get("glCheckFramebufferStatus")
|
||||
c.gpClear = g.get("glClear")
|
||||
c.gpColorMask = g.get("glColorMask")
|
||||
c.gpCompileShader = g.get("glCompileShader")
|
||||
c.gpCreateProgram = g.get("glCreateProgram")
|
||||
c.gpCreateShader = g.get("glCreateShader")
|
||||
c.gpDeleteBuffers = g.get("glDeleteBuffers")
|
||||
c.gpDeleteFramebuffers = g.get("glDeleteFramebuffers")
|
||||
c.gpDeleteProgram = g.get("glDeleteProgram")
|
||||
c.gpDeleteRenderbuffers = g.get("glDeleteRenderbuffers")
|
||||
c.gpDeleteShader = g.get("glDeleteShader")
|
||||
c.gpDeleteTextures = g.get("glDeleteTextures")
|
||||
c.gpDeleteVertexArrays = g.get("glDeleteVertexArrays")
|
||||
c.gpDisable = g.get("glDisable")
|
||||
c.gpDisableVertexAttribArray = g.get("glDisableVertexAttribArray")
|
||||
c.gpDrawElements = g.get("glDrawElements")
|
||||
c.gpEnable = g.get("glEnable")
|
||||
c.gpEnableVertexAttribArray = g.get("glEnableVertexAttribArray")
|
||||
c.gpFlush = g.get("glFlush")
|
||||
c.gpFramebufferRenderbuffer = g.get("glFramebufferRenderbuffer")
|
||||
c.gpFramebufferTexture2D = g.get("glFramebufferTexture2D")
|
||||
c.gpGenBuffers = g.get("glGenBuffers")
|
||||
c.gpGenFramebuffers = g.get("glGenFramebuffers")
|
||||
c.gpGenRenderbuffers = g.get("glGenRenderbuffers")
|
||||
c.gpGenTextures = g.get("glGenTextures")
|
||||
c.gpGenVertexArrays = g.get("glGenVertexArrays")
|
||||
c.gpGetError = g.get("glGetError")
|
||||
c.gpGetIntegerv = g.get("glGetIntegerv")
|
||||
c.gpGetProgramInfoLog = g.get("glGetProgramInfoLog")
|
||||
c.gpGetProgramiv = g.get("glGetProgramiv")
|
||||
c.gpGetShaderInfoLog = g.get("glGetShaderInfoLog")
|
||||
c.gpGetShaderiv = g.get("glGetShaderiv")
|
||||
c.gpGetUniformLocation = g.get("glGetUniformLocation")
|
||||
c.gpIsFramebuffer = g.get("glIsFramebuffer")
|
||||
c.gpIsProgram = g.get("glIsProgram")
|
||||
c.gpIsRenderbuffer = g.get("glIsRenderbuffer")
|
||||
c.gpLinkProgram = g.get("glLinkProgram")
|
||||
c.gpPixelStorei = g.get("glPixelStorei")
|
||||
c.gpReadPixels = g.get("glReadPixels")
|
||||
c.gpRenderbufferStorage = g.get("glRenderbufferStorage")
|
||||
c.gpScissor = g.get("glScissor")
|
||||
c.gpShaderSource = g.get("glShaderSource")
|
||||
c.gpStencilFunc = g.get("glStencilFunc")
|
||||
c.gpStencilOpSeparate = g.get("glStencilOpSeparate")
|
||||
c.gpTexImage2D = g.get("glTexImage2D")
|
||||
c.gpTexParameteri = g.get("glTexParameteri")
|
||||
c.gpTexSubImage2D = g.get("glTexSubImage2D")
|
||||
c.gpUniform1fv = g.get("glUniform1fv")
|
||||
c.gpUniform1i = g.get("glUniform1i")
|
||||
c.gpUniform1iv = g.get("glUniform1iv")
|
||||
c.gpUniform2fv = g.get("glUniform2fv")
|
||||
c.gpUniform2iv = g.get("glUniform2iv")
|
||||
c.gpUniform3fv = g.get("glUniform3fv")
|
||||
c.gpUniform3iv = g.get("glUniform3iv")
|
||||
c.gpUniform4fv = g.get("glUniform4fv")
|
||||
c.gpUniform4iv = g.get("glUniform4iv")
|
||||
c.gpUniformMatrix2fv = g.get("glUniformMatrix2fv")
|
||||
c.gpUniformMatrix3fv = g.get("glUniformMatrix3fv")
|
||||
c.gpUniformMatrix4fv = g.get("glUniformMatrix4fv")
|
||||
c.gpUseProgram = g.get("glUseProgram")
|
||||
c.gpVertexAttribPointer = g.get("glVertexAttribPointer")
|
||||
c.gpViewport = g.get("glViewport")
|
||||
|
||||
return g.error()
|
||||
}
|
||||
|
||||
// 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()) {
|
||||
bs := []byte(str)
|
||||
if len(bs) == 0 || bs[len(bs)-1] != 0 {
|
||||
bs = append(bs, 0)
|
||||
}
|
||||
return &bs[0], func() {
|
||||
runtime.KeepAlive(bs)
|
||||
bs = nil
|
||||
}
|
||||
}
|
||||
Generated
Vendored
+104
@@ -0,0 +1,104 @@
|
||||
// Copyright 2020 The Ebiten Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build !playstation5
|
||||
|
||||
package gl
|
||||
|
||||
//go:generate go run gen.go
|
||||
//go:generate gofmt -s -w .
|
||||
|
||||
// Context is a context for OpenGL (ES) functions.
|
||||
//
|
||||
// Context is basically the same as gomobile's gl.Context.
|
||||
// See https://pkg.go.dev/github.com/ebitengine/gomobile/gl#Context
|
||||
type Context interface {
|
||||
LoadFunctions() error
|
||||
IsES() bool
|
||||
|
||||
ActiveTexture(texture uint32)
|
||||
AttachShader(program uint32, shader uint32)
|
||||
BindAttribLocation(program uint32, index uint32, name string)
|
||||
BindBuffer(target uint32, buffer uint32)
|
||||
BindFramebuffer(target uint32, framebuffer uint32)
|
||||
BindRenderbuffer(target uint32, renderbuffer uint32)
|
||||
BindTexture(target uint32, texture uint32)
|
||||
BindVertexArray(array uint32)
|
||||
BlendEquationSeparate(modeRGB uint32, modeAlpha uint32)
|
||||
BlendFuncSeparate(srcRGB uint32, dstRGB uint32, srcAlpha uint32, dstAlpha uint32)
|
||||
BufferInit(target uint32, size int, usage uint32)
|
||||
BufferSubData(target uint32, offset int, data []byte)
|
||||
CheckFramebufferStatus(target uint32) uint32
|
||||
Clear(mask uint32)
|
||||
ColorMask(red, green, blue, alpha bool)
|
||||
CompileShader(shader uint32)
|
||||
CreateBuffer() uint32
|
||||
CreateFramebuffer() uint32
|
||||
CreateProgram() uint32
|
||||
CreateRenderbuffer() uint32
|
||||
CreateShader(xtype uint32) uint32
|
||||
CreateTexture() uint32
|
||||
CreateVertexArray() uint32
|
||||
DeleteBuffer(buffer uint32)
|
||||
DeleteFramebuffer(framebuffer uint32)
|
||||
DeleteProgram(program uint32)
|
||||
DeleteRenderbuffer(renderbuffer uint32)
|
||||
DeleteShader(shader uint32)
|
||||
DeleteTexture(texture uint32)
|
||||
DeleteVertexArray(array uint32)
|
||||
Disable(cap uint32)
|
||||
DisableVertexAttribArray(index uint32)
|
||||
DrawElements(mode uint32, count int32, xtype uint32, offset int)
|
||||
Enable(cap uint32)
|
||||
EnableVertexAttribArray(index uint32)
|
||||
Flush()
|
||||
FramebufferRenderbuffer(target uint32, attachment uint32, renderbuffertarget uint32, renderbuffer uint32)
|
||||
FramebufferTexture2D(target uint32, attachment uint32, textarget uint32, texture uint32, level int32)
|
||||
GetError() uint32
|
||||
GetInteger(pname uint32) int
|
||||
GetProgramInfoLog(program uint32) string
|
||||
GetProgrami(program uint32, pname uint32) int
|
||||
GetShaderInfoLog(shader uint32) string
|
||||
GetShaderi(shader uint32, pname uint32) int
|
||||
GetUniformLocation(program uint32, name string) int32
|
||||
IsFramebuffer(framebuffer uint32) bool
|
||||
IsProgram(program uint32) bool
|
||||
IsRenderbuffer(renderbuffer uint32) bool
|
||||
LinkProgram(program uint32)
|
||||
PixelStorei(pname uint32, param int32)
|
||||
ReadPixels(dst []byte, x int32, y int32, width int32, height int32, format uint32, xtype uint32)
|
||||
RenderbufferStorage(target uint32, internalFormat uint32, width int32, height int32)
|
||||
Scissor(x, y, width, height int32)
|
||||
ShaderSource(shader uint32, xstring string)
|
||||
StencilFunc(func_ uint32, ref int32, mask uint32)
|
||||
StencilOpSeparate(face, sfail, dpfail, dppass uint32)
|
||||
TexImage2D(target uint32, level int32, internalformat int32, width int32, height int32, format uint32, xtype uint32, pixels []byte)
|
||||
TexParameteri(target uint32, pname uint32, param int32)
|
||||
TexSubImage2D(target uint32, level int32, xoffset int32, yoffset int32, width int32, height int32, format uint32, xtype uint32, pixels []byte)
|
||||
Uniform1fv(location int32, value []float32)
|
||||
Uniform1i(location int32, v0 int32)
|
||||
Uniform1iv(location int32, value []int32)
|
||||
Uniform2fv(location int32, value []float32)
|
||||
Uniform2iv(location int32, value []int32)
|
||||
Uniform3fv(location int32, value []float32)
|
||||
Uniform3iv(location int32, value []int32)
|
||||
Uniform4fv(location int32, value []float32)
|
||||
Uniform4iv(location int32, value []int32)
|
||||
UniformMatrix2fv(location int32, value []float32)
|
||||
UniformMatrix3fv(location int32, value []float32)
|
||||
UniformMatrix4fv(location int32, value []float32)
|
||||
UseProgram(program uint32)
|
||||
VertexAttribPointer(index uint32, size int32, xtype uint32, normalized bool, stride int32, offset int)
|
||||
Viewport(x int32, y int32, width int32, height int32)
|
||||
}
|
||||
Generated
Vendored
+43
@@ -0,0 +1,43 @@
|
||||
// Copyright 2023 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 !js && !playstation5
|
||||
|
||||
package gl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type procAddressGetter struct {
|
||||
ctx *defaultContext
|
||||
err error
|
||||
}
|
||||
|
||||
func (p *procAddressGetter) get(name string) uintptr {
|
||||
proc, err := p.ctx.getProcAddress(name)
|
||||
if err != nil {
|
||||
p.err = fmt.Errorf("gl: %s is missing: %w", name, err)
|
||||
return 0
|
||||
}
|
||||
if proc == 0 {
|
||||
p.err = fmt.Errorf("gl: %s is missing", name)
|
||||
return 0
|
||||
}
|
||||
return proc
|
||||
}
|
||||
|
||||
func (p *procAddressGetter) error() error {
|
||||
return p.err
|
||||
}
|
||||
Generated
Vendored
+51
@@ -0,0 +1,51 @@
|
||||
// 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.
|
||||
|
||||
package gl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/ebitengine/purego"
|
||||
)
|
||||
|
||||
var (
|
||||
opengl uintptr
|
||||
)
|
||||
|
||||
func (c *defaultContext) init() error {
|
||||
lib, errGLES := purego.Dlopen("/System/Library/Frameworks/OpenGLES.framework/OpenGLES", purego.RTLD_LAZY|purego.RTLD_GLOBAL)
|
||||
if errGLES == nil {
|
||||
c.isES = true
|
||||
opengl = lib
|
||||
return nil
|
||||
}
|
||||
|
||||
lib, errGL := purego.Dlopen("/System/Library/Frameworks/OpenGL.framework/OpenGL", purego.RTLD_LAZY|purego.RTLD_GLOBAL)
|
||||
if errGL == nil {
|
||||
opengl = lib
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO: Use multiple %w-s as of Go 1.20
|
||||
return fmt.Errorf("gl: failed to load: OpenGL.framework: %v, OpenGLES.framework: %v", errGL, errGLES)
|
||||
}
|
||||
|
||||
func (c *defaultContext) getProcAddress(name string) (uintptr, error) {
|
||||
proc, err := purego.Dlsym(opengl, name)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return proc, nil
|
||||
}
|
||||
Generated
Vendored
+114
@@ -0,0 +1,114 @@
|
||||
// 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 (freebsd || linux || netbsd || openbsd) && !nintendosdk && !playstation5
|
||||
|
||||
package gl
|
||||
|
||||
// #cgo LDFLAGS: -ldl
|
||||
//
|
||||
// #include <dlfcn.h>
|
||||
// #include <stdlib.h>
|
||||
//
|
||||
// static void* getProcAddressGL(void* libGL, const char* name) {
|
||||
// static void*(*glXGetProcAddress)(const char*);
|
||||
// if (!glXGetProcAddress) {
|
||||
// glXGetProcAddress = dlsym(libGL, "glXGetProcAddress");
|
||||
// if (!glXGetProcAddress) {
|
||||
// glXGetProcAddress = dlsym(libGL, "glXGetProcAddressARB");
|
||||
// }
|
||||
// }
|
||||
// return glXGetProcAddress(name);
|
||||
// }
|
||||
//
|
||||
// static void* getProcAddressGLES(void* libGLES, const char* name) {
|
||||
// return dlsym(libGLES, name);
|
||||
// }
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
libGL unsafe.Pointer
|
||||
libGLES unsafe.Pointer
|
||||
)
|
||||
|
||||
func (c *defaultContext) init() error {
|
||||
var preferES bool
|
||||
if runtime.GOOS == "android" {
|
||||
preferES = true
|
||||
}
|
||||
if !preferES {
|
||||
for _, t := range strings.Split(os.Getenv("EBITENGINE_OPENGL"), ",") {
|
||||
switch strings.TrimSpace(t) {
|
||||
case "es":
|
||||
preferES = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Try OpenGL first. OpenGL is preferable as this doesn't cause context losses.
|
||||
if !preferES {
|
||||
// Usually libGL.so or libGL.so.1 is used. libGL.so.2 might exist only on NetBSD.
|
||||
for _, name := range []string{"libGL.so", "libGL.so.2", "libGL.so.1", "libGL.so.0"} {
|
||||
cname := C.CString(name)
|
||||
lib := C.dlopen(cname, C.RTLD_LAZY|C.RTLD_GLOBAL)
|
||||
C.free(unsafe.Pointer(cname))
|
||||
if lib != nil {
|
||||
libGL = lib
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Try OpenGL ES.
|
||||
for _, name := range []string{"libGLESv2.so", "libGLESv2.so.2", "libGLESv2.so.1", "libGLESv2.so.0"} {
|
||||
cname := C.CString(name)
|
||||
lib := C.dlopen(cname, C.RTLD_LAZY|C.RTLD_GLOBAL)
|
||||
C.free(unsafe.Pointer(cname))
|
||||
if lib != nil {
|
||||
libGLES = lib
|
||||
c.isES = true
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("gl: failed to load libGL.so and libGLESv2.so")
|
||||
}
|
||||
|
||||
func (c *defaultContext) getProcAddress(name string) (uintptr, error) {
|
||||
if c.isES {
|
||||
return getProcAddressGLES(name), nil
|
||||
}
|
||||
return getProcAddressGL(name), nil
|
||||
}
|
||||
|
||||
func getProcAddressGL(name string) uintptr {
|
||||
cname := C.CString(name)
|
||||
defer C.free(unsafe.Pointer(cname))
|
||||
return uintptr(C.getProcAddressGL(libGL, cname))
|
||||
}
|
||||
|
||||
func getProcAddressGLES(name string) uintptr {
|
||||
cname := C.CString(name)
|
||||
defer C.free(unsafe.Pointer(cname))
|
||||
return uintptr(C.getProcAddressGLES(libGLES, cname))
|
||||
}
|
||||
Generated
Vendored
+39
@@ -0,0 +1,39 @@
|
||||
// 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 nintendosdk
|
||||
|
||||
package gl
|
||||
|
||||
// #cgo LDFLAGS: -Wl,-unresolved-symbols=ignore-all
|
||||
//
|
||||
// #include <stdlib.h>
|
||||
// #include <EGL/egl.h>
|
||||
//
|
||||
// static void* getProcAddress(const char* name) {
|
||||
// return eglGetProcAddress(name);
|
||||
// }
|
||||
import "C"
|
||||
|
||||
import "unsafe"
|
||||
|
||||
func (c *defaultContext) init() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *defaultContext) getProcAddress(name string) (uintptr, error) {
|
||||
cname := C.CString(name)
|
||||
defer C.free(unsafe.Pointer(cname))
|
||||
return uintptr(C.getProcAddress(cname)), nil
|
||||
}
|
||||
Generated
Vendored
+52
@@ -0,0 +1,52 @@
|
||||
// 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.
|
||||
|
||||
package gl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
var (
|
||||
opengl32 = windows.NewLazySystemDLL("opengl32")
|
||||
procWglGetProcAddress = opengl32.NewProc("wglGetProcAddress")
|
||||
)
|
||||
|
||||
func (c *defaultContext) init() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *defaultContext) getProcAddress(namea string) (uintptr, error) {
|
||||
cname, err := windows.BytePtrFromString(namea)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
r, _, err := procWglGetProcAddress.Call(uintptr(unsafe.Pointer(cname)))
|
||||
if r != 0 {
|
||||
return r, nil
|
||||
}
|
||||
if err != nil && err != windows.ERROR_SUCCESS && err != windows.ERROR_PROC_NOT_FOUND {
|
||||
return 0, fmt.Errorf("gl: wglGetProcAddress failed for %s: %w", namea, err)
|
||||
}
|
||||
|
||||
p := opengl32.NewProc(namea)
|
||||
if err := p.Find(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return p.Addr(), nil
|
||||
}
|
||||
Generated
Vendored
+341
@@ -0,0 +1,341 @@
|
||||
// Copyright 2018 The Ebiten Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build !playstation5
|
||||
|
||||
package opengl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl/gl"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/shaderir"
|
||||
)
|
||||
|
||||
type activatedTexture struct {
|
||||
textureNative textureNative
|
||||
index int
|
||||
}
|
||||
|
||||
type Graphics struct {
|
||||
state openGLState
|
||||
context context
|
||||
vsync bool
|
||||
|
||||
nextImageID graphicsdriver.ImageID
|
||||
images map[graphicsdriver.ImageID]*Image
|
||||
|
||||
nextShaderID graphicsdriver.ShaderID
|
||||
shaders map[graphicsdriver.ShaderID]*Shader
|
||||
|
||||
// drawCalled is true just after Draw is called. This holds true until WritePixels is called.
|
||||
drawCalled bool
|
||||
|
||||
uniformVariableNameCache map[int]string
|
||||
textureVariableNameCache map[int]string
|
||||
|
||||
uniformVars []uniformVariable
|
||||
|
||||
// activatedTextures is a set of activated textures.
|
||||
// textureNative cannot be a map key unfortunately.
|
||||
activatedTextures []activatedTexture
|
||||
|
||||
graphicsPlatform
|
||||
}
|
||||
|
||||
func newGraphics(ctx gl.Context) *Graphics {
|
||||
g := &Graphics{
|
||||
vsync: true,
|
||||
}
|
||||
if isDebug {
|
||||
g.context.ctx = &gl.DebugContext{Context: ctx}
|
||||
} else {
|
||||
g.context.ctx = ctx
|
||||
}
|
||||
return g
|
||||
}
|
||||
|
||||
func (g *Graphics) Begin() error {
|
||||
// Do nothing.
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Graphics) End(present bool) error {
|
||||
// Call glFlush to prevent black flicking (especially on Android (#226) and iOS).
|
||||
// TODO: examples/sprites worked without this. Is this really needed?
|
||||
g.context.ctx.Flush()
|
||||
|
||||
// The last uniforms must be reset before swapping the buffer (#2517).
|
||||
if present {
|
||||
g.state.resetLastUniforms()
|
||||
if err := g.swapBuffers(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Graphics) SetTransparent(transparent bool) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
func (g *Graphics) checkSize(width, height int) {
|
||||
if width < 1 {
|
||||
panic(fmt.Sprintf("opengl: width (%d) must be equal or more than %d", width, 1))
|
||||
}
|
||||
if height < 1 {
|
||||
panic(fmt.Sprintf("opengl: height (%d) must be equal or more than %d", height, 1))
|
||||
}
|
||||
m := g.context.getMaxTextureSize()
|
||||
if width > m {
|
||||
panic(fmt.Sprintf("opengl: width (%d) must be less than or equal to %d", width, m))
|
||||
}
|
||||
if height > m {
|
||||
panic(fmt.Sprintf("opengl: height (%d) must be less than or equal to %d", height, m))
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Graphics) genNextImageID() graphicsdriver.ImageID {
|
||||
g.nextImageID++
|
||||
return g.nextImageID
|
||||
}
|
||||
|
||||
func (g *Graphics) genNextShaderID() graphicsdriver.ShaderID {
|
||||
g.nextShaderID++
|
||||
return g.nextShaderID
|
||||
}
|
||||
|
||||
func (g *Graphics) NewImage(width, height int) (graphicsdriver.Image, error) {
|
||||
i := &Image{
|
||||
id: g.genNextImageID(),
|
||||
graphics: g,
|
||||
width: width,
|
||||
height: height,
|
||||
}
|
||||
w := graphics.InternalImageSize(width)
|
||||
h := graphics.InternalImageSize(height)
|
||||
g.checkSize(w, h)
|
||||
t, err := g.context.newTexture(w, h)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
i.texture = t
|
||||
g.addImage(i)
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func (g *Graphics) NewScreenFramebufferImage(width, height int) (graphicsdriver.Image, error) {
|
||||
g.checkSize(width, height)
|
||||
i := &Image{
|
||||
id: g.genNextImageID(),
|
||||
graphics: g,
|
||||
width: width,
|
||||
height: height,
|
||||
screen: true,
|
||||
}
|
||||
g.addImage(i)
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func (g *Graphics) addImage(img *Image) {
|
||||
if g.images == nil {
|
||||
g.images = map[graphicsdriver.ImageID]*Image{}
|
||||
}
|
||||
if _, ok := g.images[img.id]; ok {
|
||||
panic(fmt.Sprintf("opengl: image ID %d was already registered", img.id))
|
||||
}
|
||||
g.images[img.id] = img
|
||||
}
|
||||
|
||||
func (g *Graphics) removeImage(img *Image) {
|
||||
delete(g.images, img.id)
|
||||
}
|
||||
|
||||
func (g *Graphics) Initialize() error {
|
||||
if err := g.makeContextCurrent(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.state.reset(&g.context); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Reset resets or initializes the current OpenGL state.
|
||||
func (g *Graphics) Reset() error {
|
||||
return g.state.reset(&g.context)
|
||||
}
|
||||
|
||||
func (g *Graphics) SetVertices(vertices []float32, indices []uint32) error {
|
||||
g.state.setVertices(&g.context, vertices, indices)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Graphics) uniformVariableName(idx int) string {
|
||||
if v, ok := g.uniformVariableNameCache[idx]; ok {
|
||||
return v
|
||||
}
|
||||
if g.uniformVariableNameCache == nil {
|
||||
g.uniformVariableNameCache = map[int]string{}
|
||||
}
|
||||
name := fmt.Sprintf("U%d", idx)
|
||||
g.uniformVariableNameCache[idx] = name
|
||||
return name
|
||||
}
|
||||
|
||||
func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.ShaderImageCount]graphicsdriver.ImageID, shaderID graphicsdriver.ShaderID, dstRegions []graphicsdriver.DstRegion, indexOffset int, blend graphicsdriver.Blend, uniforms []uint32, fillRule graphicsdriver.FillRule) error {
|
||||
if shaderID == graphicsdriver.InvalidShaderID {
|
||||
return fmt.Errorf("opengl: shader ID is invalid")
|
||||
}
|
||||
|
||||
destination := g.images[dstID]
|
||||
|
||||
g.drawCalled = true
|
||||
|
||||
if err := destination.setViewport(); err != nil {
|
||||
return err
|
||||
}
|
||||
g.context.blend(blend)
|
||||
|
||||
shader := g.shaders[shaderID]
|
||||
program := shader.p
|
||||
|
||||
ulen := len(shader.ir.Uniforms)
|
||||
if cap(g.uniformVars) < ulen {
|
||||
g.uniformVars = make([]uniformVariable, ulen)
|
||||
} else {
|
||||
g.uniformVars = g.uniformVars[:ulen]
|
||||
}
|
||||
|
||||
var idx int
|
||||
for i, typ := range shader.ir.Uniforms {
|
||||
n := typ.Uint32Count()
|
||||
g.uniformVars[i].name = g.uniformVariableName(i)
|
||||
g.uniformVars[i].value = uniforms[idx : idx+n]
|
||||
g.uniformVars[i].typ = typ
|
||||
idx += n
|
||||
}
|
||||
|
||||
// In OpenGL, the NDC's Y direction is upward, so flip the Y direction for the final framebuffer.
|
||||
if destination.screen {
|
||||
const idx = graphics.ProjectionMatrixUniformVariableIndex
|
||||
// Invert the sign bits as float32 values.
|
||||
g.uniformVars[idx].value[1] ^= 1 << 31
|
||||
g.uniformVars[idx].value[5] ^= 1 << 31
|
||||
g.uniformVars[idx].value[9] ^= 1 << 31
|
||||
g.uniformVars[idx].value[13] ^= 1 << 31
|
||||
}
|
||||
|
||||
var imgs [graphics.ShaderImageCount]textureVariable
|
||||
for i, srcID := range srcIDs {
|
||||
if srcID == graphicsdriver.InvalidImageID {
|
||||
continue
|
||||
}
|
||||
imgs[i].valid = true
|
||||
imgs[i].native = g.images[srcID].texture
|
||||
}
|
||||
|
||||
if err := g.useProgram(program, g.uniformVars, imgs); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := range g.uniformVars {
|
||||
g.uniformVars[i] = uniformVariable{}
|
||||
}
|
||||
g.uniformVars = g.uniformVars[:0]
|
||||
|
||||
if fillRule != graphicsdriver.FillAll {
|
||||
if err := destination.ensureStencilBuffer(); err != nil {
|
||||
return err
|
||||
}
|
||||
g.context.ctx.Enable(gl.STENCIL_TEST)
|
||||
}
|
||||
|
||||
for _, dstRegion := range dstRegions {
|
||||
g.context.ctx.Scissor(
|
||||
int32(dstRegion.Region.Min.X),
|
||||
int32(dstRegion.Region.Min.Y),
|
||||
int32(dstRegion.Region.Dx()),
|
||||
int32(dstRegion.Region.Dy()),
|
||||
)
|
||||
switch fillRule {
|
||||
case graphicsdriver.NonZero:
|
||||
g.context.ctx.Clear(gl.STENCIL_BUFFER_BIT)
|
||||
g.context.ctx.StencilFunc(gl.ALWAYS, 0x00, 0xff)
|
||||
g.context.ctx.StencilOpSeparate(gl.FRONT, gl.KEEP, gl.KEEP, gl.INCR_WRAP)
|
||||
g.context.ctx.StencilOpSeparate(gl.BACK, gl.KEEP, gl.KEEP, gl.DECR_WRAP)
|
||||
g.context.ctx.ColorMask(false, false, false, false)
|
||||
g.context.ctx.DrawElements(gl.TRIANGLES, int32(dstRegion.IndexCount), gl.UNSIGNED_INT, indexOffset*int(unsafe.Sizeof(uint32(0))))
|
||||
case graphicsdriver.EvenOdd:
|
||||
g.context.ctx.Clear(gl.STENCIL_BUFFER_BIT)
|
||||
g.context.ctx.StencilFunc(gl.ALWAYS, 0x00, 0xff)
|
||||
g.context.ctx.StencilOpSeparate(gl.FRONT_AND_BACK, gl.KEEP, gl.KEEP, gl.INVERT)
|
||||
g.context.ctx.ColorMask(false, false, false, false)
|
||||
|
||||
g.context.ctx.DrawElements(gl.TRIANGLES, int32(dstRegion.IndexCount), gl.UNSIGNED_INT, indexOffset*int(unsafe.Sizeof(uint32(0))))
|
||||
}
|
||||
if fillRule != graphicsdriver.FillAll {
|
||||
g.context.ctx.StencilFunc(gl.NOTEQUAL, 0x00, 0xff)
|
||||
g.context.ctx.StencilOpSeparate(gl.FRONT_AND_BACK, gl.KEEP, gl.KEEP, gl.KEEP)
|
||||
g.context.ctx.ColorMask(true, true, true, true)
|
||||
}
|
||||
g.context.ctx.DrawElements(gl.TRIANGLES, int32(dstRegion.IndexCount), gl.UNSIGNED_INT, indexOffset*int(unsafe.Sizeof(uint32(0))))
|
||||
indexOffset += dstRegion.IndexCount
|
||||
}
|
||||
|
||||
if fillRule != graphicsdriver.FillAll {
|
||||
g.context.ctx.Disable(gl.STENCIL_TEST)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Graphics) SetVsyncEnabled(enabled bool) {
|
||||
g.vsync = enabled
|
||||
}
|
||||
|
||||
func (g *Graphics) NeedsClearingScreen() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (g *Graphics) MaxImageSize() int {
|
||||
return g.context.getMaxTextureSize()
|
||||
}
|
||||
|
||||
func (g *Graphics) NewShader(program *shaderir.Program) (graphicsdriver.Shader, error) {
|
||||
s, err := newShader(g.genNextShaderID(), g, program)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
g.addShader(s)
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (g *Graphics) addShader(shader *Shader) {
|
||||
if g.shaders == nil {
|
||||
g.shaders = map[graphicsdriver.ShaderID]*Shader{}
|
||||
}
|
||||
if _, ok := g.shaders[shader.id]; ok {
|
||||
panic(fmt.Sprintf("opengl: shader ID %d was already registered", shader.id))
|
||||
}
|
||||
g.shaders[shader.id] = shader
|
||||
}
|
||||
|
||||
func (g *Graphics) removeShader(shader *Shader) {
|
||||
delete(g.shaders, shader.id)
|
||||
}
|
||||
Generated
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
// Copyright 2023 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 ebitenginegldebug
|
||||
|
||||
package opengl
|
||||
|
||||
const isDebug = true
|
||||
Generated
Vendored
+119
@@ -0,0 +1,119 @@
|
||||
// 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 && !nintendosdk && !playstation5
|
||||
|
||||
package opengl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/glfw"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl/gl"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/microsoftgdk"
|
||||
)
|
||||
|
||||
type graphicsPlatform struct {
|
||||
window *glfw.Window
|
||||
}
|
||||
|
||||
// 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) {
|
||||
if microsoftgdk.IsXbox() {
|
||||
return nil, fmt.Errorf("opengl: OpenGL is not supported on Xbox")
|
||||
}
|
||||
|
||||
ctx, err := gl.NewDefaultContext()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := setGLFWClientAPI(ctx.IsES()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return newGraphics(ctx), nil
|
||||
}
|
||||
|
||||
func setGLFWClientAPI(isES bool) error {
|
||||
if isES {
|
||||
if err := glfw.WindowHint(glfw.ClientAPI, glfw.OpenGLESAPI); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := glfw.WindowHint(glfw.ContextVersionMajor, 3); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := glfw.WindowHint(glfw.ContextVersionMinor, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := glfw.WindowHint(glfw.ContextCreationAPI, glfw.EGLContextAPI); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := glfw.WindowHint(glfw.ClientAPI, glfw.OpenGLAPI); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := glfw.WindowHint(glfw.ContextVersionMajor, 3); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := glfw.WindowHint(glfw.ContextVersionMinor, 2); err != nil {
|
||||
return err
|
||||
}
|
||||
// macOS requires forward-compatible and a core profile.
|
||||
if runtime.GOOS == "darwin" {
|
||||
if err := glfw.WindowHint(glfw.OpenGLForwardCompat, glfw.True); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Graphics) SetGLFWWindow(window *glfw.Window) {
|
||||
g.window = window
|
||||
}
|
||||
|
||||
func (g *Graphics) makeContextCurrent() error {
|
||||
return g.window.MakeContextCurrent()
|
||||
}
|
||||
|
||||
func (g *Graphics) swapBuffers() error {
|
||||
// Call SwapIntervals even though vsync is not changed.
|
||||
// When toggling to fullscreen, vsync state might be reset unexpectedly (#1787).
|
||||
|
||||
// SwapInterval is affected by the current monitor of the window.
|
||||
// This needs to be called at least after SetMonitor.
|
||||
// Without SwapInterval after SetMonitor, vsynch doesn't work (#375).
|
||||
if g.vsync {
|
||||
if err := glfw.SwapInterval(1); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := glfw.SwapInterval(0); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := g.window.SwapBuffers(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Generated
Vendored
+58
@@ -0,0 +1,58 @@
|
||||
// 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.
|
||||
|
||||
package opengl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall/js"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl/gl"
|
||||
)
|
||||
|
||||
type graphicsPlatform struct {
|
||||
}
|
||||
|
||||
// NewGraphics creates an implementation of graphicsdriver.Graphics for OpenGL.
|
||||
// The returned graphics value is nil iff the error is not nil.
|
||||
func NewGraphics(canvas js.Value) (graphicsdriver.Graphics, error) {
|
||||
var glContext js.Value
|
||||
|
||||
attr := js.Global().Get("Object").New()
|
||||
attr.Set("alpha", true)
|
||||
attr.Set("premultipliedAlpha", true)
|
||||
attr.Set("stencil", true)
|
||||
|
||||
glContext = canvas.Call("getContext", "webgl2", attr)
|
||||
|
||||
if !glContext.Truthy() {
|
||||
return nil, fmt.Errorf("opengl: getContext for webgl2 failed")
|
||||
}
|
||||
|
||||
ctx, err := gl.NewDefaultContext(glContext)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return newGraphics(ctx), nil
|
||||
}
|
||||
|
||||
func (g *Graphics) makeContextCurrent() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Graphics) swapBuffers() error {
|
||||
return nil
|
||||
}
|
||||
Generated
Vendored
+43
@@ -0,0 +1,43 @@
|
||||
// Copyright 2018 The Ebiten Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build android || ios
|
||||
|
||||
package opengl
|
||||
|
||||
import (
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl/gl"
|
||||
)
|
||||
|
||||
type graphicsPlatform struct {
|
||||
}
|
||||
|
||||
// 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) {
|
||||
ctx, err := gl.NewDefaultContext()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newGraphics(ctx), nil
|
||||
}
|
||||
|
||||
func (g *Graphics) makeContextCurrent() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Graphics) swapBuffers() error {
|
||||
return nil
|
||||
}
|
||||
Generated
Vendored
+49
@@ -0,0 +1,49 @@
|
||||
// Copyright 2023 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 nintendosdk
|
||||
|
||||
package opengl
|
||||
|
||||
import (
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl/gl"
|
||||
)
|
||||
|
||||
type graphicsPlatform struct {
|
||||
egl *egl
|
||||
}
|
||||
|
||||
func NewGraphics(nativeWindowType uintptr) (graphicsdriver.Graphics, error) {
|
||||
ctx, err := gl.NewDefaultContext()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
g := newGraphics(ctx)
|
||||
e, err := newEGL(nativeWindowType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
g.egl = e
|
||||
return g, nil
|
||||
}
|
||||
|
||||
func (g *Graphics) makeContextCurrent() error {
|
||||
return g.egl.makeContextCurrent()
|
||||
}
|
||||
|
||||
func (g *Graphics) swapBuffers() error {
|
||||
g.egl.swapBuffers()
|
||||
return nil
|
||||
}
|
||||
Generated
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
// Copyright 2023 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 !ebitenginegldebug
|
||||
|
||||
package opengl
|
||||
|
||||
const isDebug = false
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
// Copyright 2018 The Ebiten Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build !playstation5
|
||||
|
||||
package opengl
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl/gl"
|
||||
)
|
||||
|
||||
type Image struct {
|
||||
id graphicsdriver.ImageID
|
||||
graphics *Graphics
|
||||
texture textureNative
|
||||
stencil renderbufferNative
|
||||
framebuffer *framebuffer
|
||||
width int
|
||||
height int
|
||||
screen bool
|
||||
}
|
||||
|
||||
// framebuffer is a wrapper of OpenGL's framebuffer.
|
||||
type framebuffer struct {
|
||||
graphics *Graphics
|
||||
native framebufferNative
|
||||
width int
|
||||
height int
|
||||
}
|
||||
|
||||
func (i *Image) ID() graphicsdriver.ImageID {
|
||||
return i.id
|
||||
}
|
||||
|
||||
func (i *Image) Dispose() {
|
||||
if i.framebuffer != nil {
|
||||
i.graphics.context.deleteFramebuffer(i.framebuffer.native)
|
||||
}
|
||||
if i.texture != 0 {
|
||||
i.graphics.context.deleteTexture(i.texture)
|
||||
}
|
||||
if i.stencil != 0 {
|
||||
i.graphics.context.deleteRenderbuffer(i.stencil)
|
||||
}
|
||||
|
||||
i.graphics.removeImage(i)
|
||||
}
|
||||
|
||||
func (i *Image) setViewport() error {
|
||||
if err := i.ensureFramebuffer(); err != nil {
|
||||
return err
|
||||
}
|
||||
i.graphics.context.setViewport(i.framebuffer)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *Image) ReadPixels(args []graphicsdriver.PixelsArgs) error {
|
||||
if err := i.ensureFramebuffer(); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, arg := range args {
|
||||
if err := i.graphics.context.framebufferPixels(arg.Pixels, i.framebuffer, arg.Region); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *Image) framebufferSize() (int, int) {
|
||||
if i.screen {
|
||||
// The (default) framebuffer size can't be converted to a power of 2.
|
||||
// On browsers, i.width and i.height are used as viewport size and
|
||||
// Edge can't treat a bigger viewport than the drawing area (#71).
|
||||
return i.width, i.height
|
||||
}
|
||||
return graphics.InternalImageSize(i.width), graphics.InternalImageSize(i.height)
|
||||
}
|
||||
|
||||
func (i *Image) ensureFramebuffer() error {
|
||||
if i.framebuffer != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
w, h := i.framebufferSize()
|
||||
if i.screen {
|
||||
i.framebuffer = i.graphics.context.newScreenFramebuffer(w, h)
|
||||
return nil
|
||||
}
|
||||
f, err := i.graphics.context.newFramebuffer(i.texture, w, h)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i.framebuffer = f
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *Image) ensureStencilBuffer() error {
|
||||
if i.stencil != 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := i.ensureFramebuffer(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r, err := i.graphics.context.newRenderbuffer(i.framebufferSize())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i.stencil = r
|
||||
|
||||
if err := i.graphics.context.bindStencilBuffer(i.framebuffer.native, i.stencil); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *Image) WritePixels(args []graphicsdriver.PixelsArgs) error {
|
||||
if i.screen {
|
||||
return errors.New("opengl: WritePixels cannot be called on the screen")
|
||||
}
|
||||
if len(args) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// glFlush is necessary on Android.
|
||||
// glTexSubImage2D didn't work without this hack at least on Nexus 5x and NuAns NEO [Reloaded] (#211).
|
||||
if i.graphics.drawCalled {
|
||||
i.graphics.context.ctx.Flush()
|
||||
}
|
||||
i.graphics.drawCalled = false
|
||||
|
||||
i.graphics.context.bindTexture(i.texture)
|
||||
for _, a := range args {
|
||||
x := int32(a.Region.Min.X)
|
||||
y := int32(a.Region.Min.Y)
|
||||
width := int32(a.Region.Dx())
|
||||
height := int32(a.Region.Dy())
|
||||
i.graphics.context.ctx.TexSubImage2D(gl.TEXTURE_2D, 0, x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, a.Pixels)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Generated
Vendored
+43
@@ -0,0 +1,43 @@
|
||||
// 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 !playstation5
|
||||
|
||||
package opengl
|
||||
|
||||
type locationCache struct {
|
||||
uniformLocationCache map[program]map[string]uniformLocation
|
||||
}
|
||||
|
||||
func newLocationCache() *locationCache {
|
||||
return &locationCache{
|
||||
uniformLocationCache: map[program]map[string]uniformLocation{},
|
||||
}
|
||||
}
|
||||
|
||||
func (c *locationCache) GetUniformLocation(context *context, p program, location string) uniformLocation {
|
||||
if _, ok := c.uniformLocationCache[p]; !ok {
|
||||
c.uniformLocationCache[p] = map[string]uniformLocation{}
|
||||
}
|
||||
l, ok := c.uniformLocationCache[p][location]
|
||||
if !ok {
|
||||
l = uniformLocation(context.ctx.GetUniformLocation(uint32(p), location))
|
||||
c.uniformLocationCache[p][location] = l
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
func (c *locationCache) deleteProgram(p program) {
|
||||
delete(c.uniformLocationCache, p)
|
||||
}
|
||||
Generated
Vendored
+344
@@ -0,0 +1,344 @@
|
||||
// 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 !playstation5
|
||||
|
||||
package opengl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"runtime"
|
||||
"unsafe"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl/gl"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/shaderir"
|
||||
)
|
||||
|
||||
const floatSizeInBytes = 4
|
||||
|
||||
// arrayBufferLayoutPart is a part of an array buffer layout.
|
||||
type arrayBufferLayoutPart struct {
|
||||
// TODO: This struct should belong to a program and know it.
|
||||
name string
|
||||
num int
|
||||
}
|
||||
|
||||
// arrayBufferLayout is an array buffer layout.
|
||||
//
|
||||
// An array buffer in OpenGL is a buffer representing vertices and
|
||||
// is passed to a vertex shader.
|
||||
type arrayBufferLayout struct {
|
||||
parts []arrayBufferLayoutPart
|
||||
total int
|
||||
}
|
||||
|
||||
func (a *arrayBufferLayout) names() []string {
|
||||
ns := make([]string, len(a.parts))
|
||||
for i, p := range a.parts {
|
||||
ns[i] = p.name
|
||||
}
|
||||
return ns
|
||||
}
|
||||
|
||||
// totalBytes returns the size in bytes for one element of the array buffer.
|
||||
func (a *arrayBufferLayout) totalBytes() int {
|
||||
if a.total != 0 {
|
||||
return a.total
|
||||
}
|
||||
t := 0
|
||||
for _, p := range a.parts {
|
||||
t += floatSizeInBytes * p.num
|
||||
}
|
||||
a.total = t
|
||||
return a.total
|
||||
}
|
||||
|
||||
// enable starts using the array buffer.
|
||||
func (a *arrayBufferLayout) enable(context *context) {
|
||||
for i := range a.parts {
|
||||
context.ctx.EnableVertexAttribArray(uint32(i))
|
||||
}
|
||||
total := a.totalBytes()
|
||||
offset := 0
|
||||
for i, p := range a.parts {
|
||||
context.ctx.VertexAttribPointer(uint32(i), int32(p.num), gl.FLOAT, false, int32(total), offset)
|
||||
offset += floatSizeInBytes * p.num
|
||||
}
|
||||
}
|
||||
|
||||
// disable stops using the array buffer.
|
||||
func (a *arrayBufferLayout) disable(context *context) {
|
||||
// TODO: Disabling should be done in reversed order?
|
||||
for i := range a.parts {
|
||||
context.ctx.DisableVertexAttribArray(uint32(i))
|
||||
}
|
||||
}
|
||||
|
||||
// theArrayBufferLayout is the array buffer layout for Ebitengine.
|
||||
var theArrayBufferLayout = arrayBufferLayout{
|
||||
// Note that GL_MAX_VERTEX_ATTRIBS is at least 16.
|
||||
parts: []arrayBufferLayoutPart{
|
||||
{
|
||||
name: "A0",
|
||||
num: 2,
|
||||
},
|
||||
{
|
||||
name: "A1",
|
||||
num: 2,
|
||||
},
|
||||
{
|
||||
name: "A2",
|
||||
num: 4,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
vertexFloatCount := theArrayBufferLayout.totalBytes() / floatSizeInBytes
|
||||
if graphics.VertexFloatCount != vertexFloatCount {
|
||||
panic(fmt.Sprintf("vertex float num must be %d but %d", graphics.VertexFloatCount, vertexFloatCount))
|
||||
}
|
||||
}
|
||||
|
||||
type openGLState struct {
|
||||
vertexArray uint32
|
||||
|
||||
// arrayBuffer is OpenGL's array buffer (vertices data).
|
||||
arrayBuffer buffer
|
||||
|
||||
arrayBufferSizeInBytes int
|
||||
|
||||
// elementArrayBuffer is OpenGL's element array buffer (indices data).
|
||||
elementArrayBuffer buffer
|
||||
|
||||
elementArrayBufferSizeInBytes int
|
||||
|
||||
lastProgram program
|
||||
lastUniforms map[string][]uint32
|
||||
lastActiveTexture int
|
||||
}
|
||||
|
||||
// reset resets or initializes the OpenGL state.
|
||||
func (s *openGLState) reset(context *context) error {
|
||||
if err := context.reset(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.lastProgram = 0
|
||||
context.ctx.UseProgram(0)
|
||||
for key := range s.lastUniforms {
|
||||
delete(s.lastUniforms, key)
|
||||
}
|
||||
|
||||
// On browsers (at least Chrome), buffers are already detached from the context
|
||||
// and must not be deleted by DeleteBuffer.
|
||||
if runtime.GOOS != "js" {
|
||||
if s.arrayBuffer != 0 {
|
||||
context.ctx.DeleteBuffer(uint32(s.arrayBuffer))
|
||||
}
|
||||
if s.elementArrayBuffer != 0 {
|
||||
context.ctx.DeleteBuffer(uint32(s.elementArrayBuffer))
|
||||
}
|
||||
if s.vertexArray != 0 {
|
||||
context.ctx.DeleteVertexArray(s.vertexArray)
|
||||
}
|
||||
}
|
||||
|
||||
s.arrayBuffer = 0
|
||||
s.arrayBufferSizeInBytes = 0
|
||||
s.elementArrayBuffer = 0
|
||||
s.elementArrayBufferSizeInBytes = 0
|
||||
s.vertexArray = 0
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func pow2(x int) int {
|
||||
if x > (math.MaxInt+1)/2 {
|
||||
return math.MaxInt
|
||||
}
|
||||
|
||||
p2 := 1
|
||||
for p2 < x {
|
||||
p2 *= 2
|
||||
}
|
||||
return p2
|
||||
}
|
||||
|
||||
func (s *openGLState) setVertices(context *context, vertices []float32, indices []uint32) {
|
||||
if s.vertexArray == 0 {
|
||||
s.vertexArray = context.ctx.CreateVertexArray()
|
||||
}
|
||||
context.ctx.BindVertexArray(s.vertexArray)
|
||||
|
||||
if size := len(vertices) * int(unsafe.Sizeof(vertices[0])); s.arrayBufferSizeInBytes < size {
|
||||
if s.arrayBuffer != 0 {
|
||||
context.ctx.DeleteBuffer(uint32(s.arrayBuffer))
|
||||
}
|
||||
|
||||
newSize := pow2(size)
|
||||
// newArrayBuffer calls BindBuffer.
|
||||
s.arrayBuffer = context.newArrayBuffer(newSize)
|
||||
s.arrayBufferSizeInBytes = newSize
|
||||
|
||||
// Reenable the array buffer layout explicitly after resetting the array buffer.
|
||||
theArrayBufferLayout.enable(context)
|
||||
}
|
||||
|
||||
if size := len(indices) * int(unsafe.Sizeof(indices[0])); s.elementArrayBufferSizeInBytes < size {
|
||||
if s.elementArrayBuffer != 0 {
|
||||
context.ctx.DeleteBuffer(uint32(s.elementArrayBuffer))
|
||||
}
|
||||
|
||||
newSize := pow2(size)
|
||||
// newElementArrayBuffer calls BindBuffer.
|
||||
s.elementArrayBuffer = context.newElementArrayBuffer(newSize)
|
||||
s.elementArrayBufferSizeInBytes = newSize
|
||||
}
|
||||
|
||||
// Note that the vertices and the indices passed to BufferSubData is not under GC management in the gl package.
|
||||
vs := unsafe.Slice((*byte)(unsafe.Pointer(&vertices[0])), len(vertices)*int(unsafe.Sizeof(vertices[0])))
|
||||
context.ctx.BufferSubData(gl.ARRAY_BUFFER, 0, vs)
|
||||
is := unsafe.Slice((*byte)(unsafe.Pointer(&indices[0])), len(indices)*int(unsafe.Sizeof(indices[0])))
|
||||
context.ctx.BufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, is)
|
||||
}
|
||||
|
||||
func (s *openGLState) resetLastUniforms() {
|
||||
for k := range s.lastUniforms {
|
||||
delete(s.lastUniforms, k)
|
||||
}
|
||||
}
|
||||
|
||||
// areSameUint32Array returns a boolean indicating if a and b are deeply equal.
|
||||
func areSameUint32Array(a, b []uint32) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
for i := 0; i < len(a); i++ {
|
||||
if a[i] != b[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
type uniformVariable struct {
|
||||
name string
|
||||
value []uint32
|
||||
typ shaderir.Type
|
||||
}
|
||||
|
||||
type textureVariable struct {
|
||||
valid bool
|
||||
native textureNative
|
||||
}
|
||||
|
||||
func (g *Graphics) textureVariableName(idx int) string {
|
||||
if v, ok := g.textureVariableNameCache[idx]; ok {
|
||||
return v
|
||||
}
|
||||
if g.textureVariableNameCache == nil {
|
||||
g.textureVariableNameCache = map[int]string{}
|
||||
}
|
||||
name := fmt.Sprintf("T%d", idx)
|
||||
g.textureVariableNameCache[idx] = name
|
||||
return name
|
||||
}
|
||||
|
||||
// useProgram uses the program (programTexture).
|
||||
func (g *Graphics) useProgram(program program, uniforms []uniformVariable, textures [graphics.ShaderImageCount]textureVariable) error {
|
||||
if g.state.lastProgram != program {
|
||||
g.context.ctx.UseProgram(uint32(program))
|
||||
|
||||
g.state.lastProgram = program
|
||||
for k := range g.state.lastUniforms {
|
||||
delete(g.state.lastUniforms, k)
|
||||
}
|
||||
g.state.lastActiveTexture = 0
|
||||
g.context.ctx.ActiveTexture(gl.TEXTURE0)
|
||||
g.context.lastTexture = 0 // Make sure next bindTexture call actually does something.
|
||||
}
|
||||
|
||||
for _, u := range uniforms {
|
||||
if u.value == nil {
|
||||
continue
|
||||
}
|
||||
if got, expected := len(u.value), u.typ.Uint32Count(); got != expected {
|
||||
// Copy a shaderir.Type value once. Do not pass u.typ directly to fmt.Errorf arguments, or
|
||||
// the value u would be allocated on heap.
|
||||
typ := u.typ
|
||||
return fmt.Errorf("opengl: length of a uniform variables %s (%s) doesn't match: expected %d but %d", u.name, typ.String(), expected, got)
|
||||
}
|
||||
|
||||
cached, ok := g.state.lastUniforms[u.name]
|
||||
if ok && areSameUint32Array(cached, u.value) {
|
||||
continue
|
||||
}
|
||||
g.context.uniforms(program, u.name, u.value, u.typ)
|
||||
if g.state.lastUniforms == nil {
|
||||
g.state.lastUniforms = map[string][]uint32{}
|
||||
}
|
||||
g.state.lastUniforms[u.name] = u.value
|
||||
}
|
||||
|
||||
var idx int
|
||||
loop:
|
||||
for i, t := range textures {
|
||||
if !t.valid {
|
||||
continue
|
||||
}
|
||||
|
||||
// If the texture is already bound, set the texture variable to point to the texture.
|
||||
// Rebinding the same texture seems problematic (#1193).
|
||||
for _, at := range g.activatedTextures {
|
||||
if t.native == at.textureNative {
|
||||
g.context.uniformInt(program, g.textureVariableName(i), at.index)
|
||||
continue loop
|
||||
}
|
||||
}
|
||||
|
||||
g.activatedTextures = append(g.activatedTextures, activatedTexture{
|
||||
textureNative: t.native,
|
||||
index: idx,
|
||||
})
|
||||
g.context.uniformInt(program, g.textureVariableName(i), idx)
|
||||
if g.state.lastActiveTexture != idx {
|
||||
g.context.ctx.ActiveTexture(uint32(gl.TEXTURE0 + idx))
|
||||
g.state.lastActiveTexture = idx
|
||||
g.context.lastTexture = 0 // Make sure next bindTexture call actually does something.
|
||||
}
|
||||
|
||||
// Apparently, a texture must be bound every time. The cache is not used here.
|
||||
g.context.bindTexture(t.native)
|
||||
|
||||
idx++
|
||||
}
|
||||
|
||||
for i := range g.activatedTextures {
|
||||
g.activatedTextures[i] = activatedTexture{}
|
||||
}
|
||||
g.activatedTextures = g.activatedTextures[:0]
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func uint32sToFloat32s(s []uint32) []float32 {
|
||||
return unsafe.Slice((*float32)(unsafe.Pointer(&s[0])), len(s))
|
||||
}
|
||||
|
||||
func uint32sToInt32s(s []uint32) []int32 {
|
||||
return unsafe.Slice((*int32)(unsafe.Pointer(&s[0])), len(s))
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
// Copyright 2020 The Ebiten Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build !playstation5
|
||||
|
||||
package opengl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl/gl"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/shaderir"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/shaderir/glsl"
|
||||
)
|
||||
|
||||
type Shader struct {
|
||||
id graphicsdriver.ShaderID
|
||||
graphics *Graphics
|
||||
|
||||
ir *shaderir.Program
|
||||
p program
|
||||
}
|
||||
|
||||
func newShader(id graphicsdriver.ShaderID, graphics *Graphics, program *shaderir.Program) (*Shader, error) {
|
||||
s := &Shader{
|
||||
id: id,
|
||||
graphics: graphics,
|
||||
ir: program,
|
||||
}
|
||||
if err := s.compile(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (s *Shader) ID() graphicsdriver.ShaderID {
|
||||
return s.id
|
||||
}
|
||||
|
||||
func (s *Shader) Dispose() {
|
||||
s.graphics.context.deleteProgram(s.p)
|
||||
s.graphics.removeShader(s)
|
||||
}
|
||||
|
||||
func (s *Shader) compile() error {
|
||||
vssrc, fssrc := glsl.Compile(s.ir, s.graphics.context.glslVersion())
|
||||
|
||||
vs, err := s.graphics.context.newShader(gl.VERTEX_SHADER, vssrc)
|
||||
if err != nil {
|
||||
return fmt.Errorf("opengl: vertex shader compile error: %v, source:\n%s", err, vssrc)
|
||||
}
|
||||
defer s.graphics.context.ctx.DeleteShader(uint32(vs))
|
||||
|
||||
fs, err := s.graphics.context.newShader(gl.FRAGMENT_SHADER, fssrc)
|
||||
if err != nil {
|
||||
return fmt.Errorf("opengl: fragment shader compile error: %v, source:\n%s", err, fssrc)
|
||||
}
|
||||
defer s.graphics.context.ctx.DeleteShader(uint32(fs))
|
||||
|
||||
p, err := s.graphics.context.newProgram([]shader{vs, fs}, theArrayBufferLayout.names())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.p = p
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user