updated ebiten version from 2.7.9 to 2.9.9
This commit is contained in:
Generated
Vendored
+62
-47
@@ -20,6 +20,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"image"
|
||||
"runtime"
|
||||
"sync"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||
@@ -89,7 +90,6 @@ type (
|
||||
|
||||
type (
|
||||
uniformLocation int32
|
||||
attribLocation int32
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -100,19 +100,19 @@ const (
|
||||
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
|
||||
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
|
||||
initOnce sync.Once
|
||||
hasKHRParallelShaderCompile bool
|
||||
hasKHRParallelShaderCompileOnce sync.Once
|
||||
}
|
||||
|
||||
func (c *context) bindTexture(t textureNative) {
|
||||
@@ -141,14 +141,14 @@ func (c *context) bindFramebuffer(f framebufferNative) {
|
||||
|
||||
func (c *context) setViewport(f *framebuffer) {
|
||||
c.bindFramebuffer(f.native)
|
||||
if c.lastViewportWidth == f.width && c.lastViewportHeight == f.height {
|
||||
if c.lastViewportWidth == f.viewportWidth && c.lastViewportHeight == f.viewportHeight {
|
||||
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))
|
||||
c.ctx.Viewport(0, 0, int32(f.viewportWidth), int32(f.viewportHeight))
|
||||
|
||||
// glViewport must be called at least at every frame on iOS.
|
||||
// As the screen framebuffer is the last render target, next SetViewport should be
|
||||
@@ -157,16 +157,16 @@ func (c *context) setViewport(f *framebuffer) {
|
||||
c.lastViewportWidth = 0
|
||||
c.lastViewportHeight = 0
|
||||
} else {
|
||||
c.lastViewportWidth = f.width
|
||||
c.lastViewportHeight = f.height
|
||||
c.lastViewportWidth = f.viewportWidth
|
||||
c.lastViewportHeight = f.viewportHeight
|
||||
}
|
||||
}
|
||||
|
||||
func (c *context) newScreenFramebuffer(width, height int) *framebuffer {
|
||||
return &framebuffer{
|
||||
native: c.screenFramebuffer,
|
||||
width: width,
|
||||
height: height,
|
||||
native: c.screenFramebuffer,
|
||||
viewportWidth: width,
|
||||
viewportHeight: height,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -319,9 +319,6 @@ func (c *context) newRenderbuffer(width, height int) (renderbufferNative, error)
|
||||
}
|
||||
|
||||
func (c *context) deleteRenderbuffer(r renderbufferNative) {
|
||||
if !c.ctx.IsRenderbuffer(uint32(r)) {
|
||||
return
|
||||
}
|
||||
if c.lastRenderbuffer == r {
|
||||
c.lastRenderbuffer = 0
|
||||
}
|
||||
@@ -336,19 +333,23 @@ func (c *context) newFramebuffer(texture textureNative, width, height int) (*fra
|
||||
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 shouldCheckFramebufferStatus() {
|
||||
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")
|
||||
}
|
||||
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,
|
||||
native: framebufferNative(f),
|
||||
viewportWidth: width,
|
||||
viewportHeight: height,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -356,9 +357,13 @@ func (c *context) bindStencilBuffer(f framebufferNative, r renderbufferNative) e
|
||||
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))
|
||||
|
||||
if shouldCheckFramebufferStatus() {
|
||||
if s := c.ctx.CheckFramebufferStatus(gl.FRAMEBUFFER); s != gl.FRAMEBUFFER_COMPLETE {
|
||||
return fmt.Errorf("opengl: glFramebufferRenderbuffer failed: %d", s)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -366,9 +371,6 @@ 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
|
||||
@@ -389,10 +391,6 @@ func (c *context) newShader(shaderType uint32, source string) (shader, error) {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -411,10 +409,6 @@ func (c *context) newProgram(shaders []shader, attributes []string) (program, er
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@@ -448,6 +442,8 @@ func (c *context) uniforms(p program, location string, v []uint32, typ shaderir.
|
||||
}
|
||||
|
||||
switch base {
|
||||
case shaderir.Bool:
|
||||
c.ctx.Uniform1iv(int32(l), uint32sToInt32s(v))
|
||||
case shaderir.Float:
|
||||
c.ctx.Uniform1fv(int32(l), uint32sToFloat32s(v))
|
||||
case shaderir.Int:
|
||||
@@ -496,3 +492,22 @@ func (c *context) glslVersion() glsl.GLSLVersion {
|
||||
}
|
||||
return glsl.GLSLVersionDefault
|
||||
}
|
||||
|
||||
func shouldCheckFramebufferStatus() bool {
|
||||
// CheckFramebufferStatus is slow and should be avoided especially in browsers.
|
||||
// See https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#avoid_blocking_api_calls_in_production
|
||||
//
|
||||
// TODO: Should this be avoided in all environments?
|
||||
return runtime.GOOS != "js"
|
||||
}
|
||||
|
||||
func (c *context) hasParallelShaderCompile() bool {
|
||||
c.hasKHRParallelShaderCompileOnce.Do(func() {
|
||||
if runtime.GOOS != "js" {
|
||||
return
|
||||
}
|
||||
ext := c.ctx.GetExtension("KHR_parallel_shader_compile")
|
||||
c.hasKHRParallelShaderCompile = ext != nil
|
||||
})
|
||||
return c.hasKHRParallelShaderCompile
|
||||
}
|
||||
|
||||
Generated
Vendored
+103
@@ -0,0 +1,103 @@
|
||||
// Copyright 2019 The Ebiten Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package gl
|
||||
|
||||
import (
|
||||
"syscall/js"
|
||||
)
|
||||
|
||||
var (
|
||||
object = js.Global().Get("Object")
|
||||
arrayBuffer = js.Global().Get("ArrayBuffer")
|
||||
uint8Array = js.Global().Get("Uint8Array")
|
||||
float32Array = js.Global().Get("Float32Array")
|
||||
int32Array = js.Global().Get("Int32Array")
|
||||
)
|
||||
|
||||
var (
|
||||
tmpArrayBufferByteLength = 16
|
||||
|
||||
// tmpArrayBuffer is a temporary buffer used at gl.readPixels or gl.texSubImage2D.
|
||||
// The read data is converted to Go's byte slice as soon as possible.
|
||||
// To avoid often allocating ArrayBuffer, reuse the buffer whenever possible.
|
||||
tmpArrayBuffer = arrayBuffer.New(tmpArrayBufferByteLength)
|
||||
|
||||
// tmpUint8Array is a Uint8ArrayBuffer whose underlying buffer is always temporaryArrayBuffer.
|
||||
tmpUint8Array = uint8Array.New(tmpArrayBuffer)
|
||||
|
||||
// tmpFloat32Array is a Float32ArrayBuffer whose underlying buffer is always temporaryArrayBuffer.
|
||||
tmpFloat32Array = float32Array.New(tmpArrayBuffer)
|
||||
|
||||
// tmpInt32Array is a Float32ArrayBuffer whose underlying buffer is always temporaryArrayBuffer.
|
||||
tmpInt32Array = int32Array.New(tmpArrayBuffer)
|
||||
)
|
||||
|
||||
func ensureTemporaryArrayBufferSize(byteLength int) {
|
||||
if bufl := tmpArrayBufferByteLength; bufl < byteLength {
|
||||
for bufl < byteLength {
|
||||
bufl *= 2
|
||||
}
|
||||
tmpArrayBufferByteLength = bufl
|
||||
tmpArrayBuffer = arrayBuffer.New(bufl)
|
||||
tmpUint8Array = uint8Array.New(tmpArrayBuffer)
|
||||
tmpFloat32Array = float32Array.New(tmpArrayBuffer)
|
||||
tmpInt32Array = int32Array.New(tmpArrayBuffer)
|
||||
}
|
||||
}
|
||||
|
||||
// tmpUint8ArrayFromUint8Slice returns a Uint8Array whose length is at least minLength from an uint8 slice.
|
||||
// Be careful that the length can exceed the given minLength.
|
||||
// data must be a slice of a numeric type for initialization, or nil if you don't need initialization.
|
||||
func tmpUint8ArrayFromUint8Slice(minLength int, data []uint8) js.Value {
|
||||
ensureTemporaryArrayBufferSize(minLength)
|
||||
copyUint8SliceToTemporaryArrayBuffer(data)
|
||||
return tmpUint8Array
|
||||
}
|
||||
|
||||
// tmpUint8ArrayFromUint16Slice returns a Uint8Array whose length is at least minLength from an uint16 slice.
|
||||
// Be careful that the length can exceed the given minLength.
|
||||
// data must be a slice of a numeric type for initialization, or nil if you don't need initialization.
|
||||
func tmpUint8ArrayFromUint16Slice(minLength int, data []uint16) js.Value {
|
||||
ensureTemporaryArrayBufferSize(minLength * 2)
|
||||
copySliceToTemporaryArrayBuffer(data)
|
||||
return tmpUint8Array
|
||||
}
|
||||
|
||||
// tmpUint8ArrayFromFloat32Slice returns a Uint8Array whose length is at least minLength from a float32 slice.
|
||||
// Be careful that the length can exceed the given minLength.
|
||||
// data must be a slice of a numeric type for initialization, or nil if you don't need initialization.
|
||||
func tmpUint8ArrayFromFloat32Slice(minLength int, data []float32) js.Value {
|
||||
ensureTemporaryArrayBufferSize(minLength * 4)
|
||||
copySliceToTemporaryArrayBuffer(data)
|
||||
return tmpUint8Array
|
||||
}
|
||||
|
||||
// tmpFloat32ArrayFromFloat32Slice returns a Float32Array whose length is at least minLength.
|
||||
// Be careful that the length can exceed the given minLength.
|
||||
// data must be a slice of a numeric type for initialization, or nil if you don't need initialization.
|
||||
func tmpFloat32ArrayFromFloat32Slice(minLength int, data []float32) js.Value {
|
||||
ensureTemporaryArrayBufferSize(minLength * 4)
|
||||
copySliceToTemporaryArrayBuffer(data)
|
||||
return tmpFloat32Array
|
||||
}
|
||||
|
||||
// tmpInt32ArrayFromInt32Slice returns a Int32Array whose length is at least minLength.
|
||||
// Be careful that the length can exceed the given minLength.
|
||||
// data must be a slice of a numeric type for initialization, or nil if you don't need initialization.
|
||||
func tmpInt32ArrayFromInt32Slice(minLength int, data []int32) js.Value {
|
||||
ensureTemporaryArrayBufferSize(minLength * 4)
|
||||
copySliceToTemporaryArrayBuffer(data)
|
||||
return tmpInt32Array
|
||||
}
|
||||
Generated
Vendored
+1
@@ -23,6 +23,7 @@ const (
|
||||
BLEND = 0x0BE2
|
||||
CLAMP_TO_EDGE = 0x812F
|
||||
COLOR_ATTACHMENT0 = 0x8CE0
|
||||
COMPLETION_STATUS_KHR = 0x91B1
|
||||
COMPILE_STATUS = 0x8B81
|
||||
DECR_WRAP = 0x8508
|
||||
DEPTH24_STENCIL8 = 0x88F0
|
||||
|
||||
Generated
Vendored
+9
-18
@@ -347,6 +347,15 @@ func (d *DebugContext) GetError() uint32 {
|
||||
return out0
|
||||
}
|
||||
|
||||
func (d *DebugContext) GetExtension(arg0 string) any {
|
||||
out0 := d.Context.GetExtension(arg0)
|
||||
fmt.Fprintln(os.Stderr, "GetExtension")
|
||||
if e := d.Context.GetError(); e != NO_ERROR {
|
||||
panic(fmt.Sprintf("gl: GetError() returned %d at GetExtension", e))
|
||||
}
|
||||
return out0
|
||||
}
|
||||
|
||||
func (d *DebugContext) GetInteger(arg0 uint32) int {
|
||||
out0 := d.Context.GetInteger(arg0)
|
||||
fmt.Fprintln(os.Stderr, "GetInteger")
|
||||
@@ -406,15 +415,6 @@ func (d *DebugContext) IsES() bool {
|
||||
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")
|
||||
@@ -424,15 +424,6 @@ func (d *DebugContext) IsProgram(arg0 uint32) bool {
|
||||
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")
|
||||
|
||||
Generated
Vendored
+226
-23
@@ -2,7 +2,7 @@
|
||||
// SPDX-FileCopyrightText: 2014 Eric Woroshow
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !darwin && !js && !windows && !playstation5
|
||||
//go:build nintendosdk
|
||||
|
||||
package gl
|
||||
|
||||
@@ -20,298 +20,505 @@ package gl
|
||||
// typedef ptrdiff_t GLintptr;
|
||||
// typedef ptrdiff_t GLsizeiptr;
|
||||
//
|
||||
// #cgo noescape glowActiveTexture
|
||||
// #cgo nocallback glowActiveTexture
|
||||
// static void glowActiveTexture(uintptr_t fnptr, GLenum texture) {
|
||||
// typedef void (*fn)(GLenum texture);
|
||||
// ((fn)(fnptr))(texture);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowAttachShader
|
||||
// #cgo nocallback glowAttachShader
|
||||
// static void glowAttachShader(uintptr_t fnptr, GLuint program, GLuint shader) {
|
||||
// typedef void (*fn)(GLuint program, GLuint shader);
|
||||
// ((fn)(fnptr))(program, shader);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowBindAttribLocation
|
||||
// #cgo nocallback glowBindAttribLocation
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowBindBuffer
|
||||
// #cgo nocallback glowBindBuffer
|
||||
// static void glowBindBuffer(uintptr_t fnptr, GLenum target, GLuint buffer) {
|
||||
// typedef void (*fn)(GLenum target, GLuint buffer);
|
||||
// ((fn)(fnptr))(target, buffer);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowBindFramebuffer
|
||||
// #cgo nocallback glowBindFramebuffer
|
||||
// static void glowBindFramebuffer(uintptr_t fnptr, GLenum target, GLuint framebuffer) {
|
||||
// typedef void (*fn)(GLenum target, GLuint framebuffer);
|
||||
// ((fn)(fnptr))(target, framebuffer);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowBindRenderbuffer
|
||||
// #cgo nocallback glowBindRenderbuffer
|
||||
// static void glowBindRenderbuffer(uintptr_t fnptr, GLenum target, GLuint renderbuffer) {
|
||||
// typedef void (*fn)(GLenum target, GLuint renderbuffer);
|
||||
// ((fn)(fnptr))(target, renderbuffer);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowBindTexture
|
||||
// #cgo nocallback glowBindTexture
|
||||
// static void glowBindTexture(uintptr_t fnptr, GLenum target, GLuint texture) {
|
||||
// typedef void (*fn)(GLenum target, GLuint texture);
|
||||
// ((fn)(fnptr))(target, texture);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowBindVertexArray
|
||||
// #cgo nocallback glowBindVertexArray
|
||||
// static void glowBindVertexArray(uintptr_t fnptr, GLuint array) {
|
||||
// typedef void (*fn)(GLuint array);
|
||||
// ((fn)(fnptr))(array);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowBlendEquationSeparate
|
||||
// #cgo nocallback glowBlendEquationSeparate
|
||||
// static void glowBlendEquationSeparate(uintptr_t fnptr, GLenum modeRGB, GLenum modeAlpha) {
|
||||
// typedef void (*fn)(GLenum modeRGB, GLenum modeAlpha);
|
||||
// ((fn)(fnptr))(modeRGB, modeAlpha);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowBlendFuncSeparate
|
||||
// #cgo nocallback glowBlendFuncSeparate
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowBufferData
|
||||
// #cgo nocallback glowBufferData
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowBufferSubData
|
||||
// #cgo nocallback glowBufferSubData
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowCheckFramebufferStatus
|
||||
// #cgo nocallback glowCheckFramebufferStatus
|
||||
// static GLenum glowCheckFramebufferStatus(uintptr_t fnptr, GLenum target) {
|
||||
// typedef GLenum (*fn)(GLenum target);
|
||||
// return ((fn)(fnptr))(target);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowClear
|
||||
// #cgo nocallback glowClear
|
||||
// static void glowClear(uintptr_t fnptr, GLbitfield mask) {
|
||||
// typedef void (*fn)(GLbitfield mask);
|
||||
// ((fn)(fnptr))(mask);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowColorMask
|
||||
// #cgo nocallback glowColorMask
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowCompileShader
|
||||
// #cgo nocallback glowCompileShader
|
||||
// static void glowCompileShader(uintptr_t fnptr, GLuint shader) {
|
||||
// typedef void (*fn)(GLuint shader);
|
||||
// ((fn)(fnptr))(shader);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowCreateProgram
|
||||
// #cgo nocallback glowCreateProgram
|
||||
// static GLuint glowCreateProgram(uintptr_t fnptr) {
|
||||
// typedef GLuint (*fn)();
|
||||
// return ((fn)(fnptr))();
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowCreateShader
|
||||
// #cgo nocallback glowCreateShader
|
||||
// static GLuint glowCreateShader(uintptr_t fnptr, GLenum type) {
|
||||
// typedef GLuint (*fn)(GLenum type);
|
||||
// return ((fn)(fnptr))(type);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowDeleteBuffers
|
||||
// #cgo nocallback glowDeleteBuffers
|
||||
// static void glowDeleteBuffers(uintptr_t fnptr, GLsizei n, const GLuint* buffers) {
|
||||
// typedef void (*fn)(GLsizei n, const GLuint* buffers);
|
||||
// ((fn)(fnptr))(n, buffers);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowDeleteFramebuffers
|
||||
// #cgo nocallback glowDeleteFramebuffers
|
||||
// static void glowDeleteFramebuffers(uintptr_t fnptr, GLsizei n, const GLuint* framebuffers) {
|
||||
// typedef void (*fn)(GLsizei n, const GLuint* framebuffers);
|
||||
// ((fn)(fnptr))(n, framebuffers);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowDeleteProgram
|
||||
// #cgo nocallback glowDeleteProgram
|
||||
// static void glowDeleteProgram(uintptr_t fnptr, GLuint program) {
|
||||
// typedef void (*fn)(GLuint program);
|
||||
// ((fn)(fnptr))(program);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowDeleteRenderbuffers
|
||||
// #cgo nocallback glowDeleteRenderbuffers
|
||||
// static void glowDeleteRenderbuffers(uintptr_t fnptr, GLsizei n, const GLuint* renderbuffers) {
|
||||
// typedef void (*fn)(GLsizei n, const GLuint* renderbuffers);
|
||||
// ((fn)(fnptr))(n, renderbuffers);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowDeleteShader
|
||||
// #cgo nocallback glowDeleteShader
|
||||
// static void glowDeleteShader(uintptr_t fnptr, GLuint shader) {
|
||||
// typedef void (*fn)(GLuint shader);
|
||||
// ((fn)(fnptr))(shader);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowDeleteTextures
|
||||
// #cgo nocallback glowDeleteTextures
|
||||
// static void glowDeleteTextures(uintptr_t fnptr, GLsizei n, const GLuint* textures) {
|
||||
// typedef void (*fn)(GLsizei n, const GLuint* textures);
|
||||
// ((fn)(fnptr))(n, textures);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowDeleteVertexArrays
|
||||
// #cgo nocallback glowDeleteVertexArrays
|
||||
// static void glowDeleteVertexArrays(uintptr_t fnptr, GLsizei n, const GLuint* arrays) {
|
||||
// typedef void (*fn)(GLsizei n, const GLuint* arrays);
|
||||
// ((fn)(fnptr))(n, arrays);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowDisable
|
||||
// #cgo nocallback glowDisable
|
||||
// static void glowDisable(uintptr_t fnptr, GLenum cap) {
|
||||
// typedef void (*fn)(GLenum cap);
|
||||
// ((fn)(fnptr))(cap);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowDisableVertexAttribArray
|
||||
// #cgo nocallback glowDisableVertexAttribArray
|
||||
// static void glowDisableVertexAttribArray(uintptr_t fnptr, GLuint index) {
|
||||
// typedef void (*fn)(GLuint index);
|
||||
// ((fn)(fnptr))(index);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowDrawElements
|
||||
// #cgo nocallback glowDrawElements
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowEnable
|
||||
// #cgo nocallback glowEnable
|
||||
// static void glowEnable(uintptr_t fnptr, GLenum cap) {
|
||||
// typedef void (*fn)(GLenum cap);
|
||||
// ((fn)(fnptr))(cap);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowEnableVertexAttribArray
|
||||
// #cgo nocallback glowEnableVertexAttribArray
|
||||
// static void glowEnableVertexAttribArray(uintptr_t fnptr, GLuint index) {
|
||||
// typedef void (*fn)(GLuint index);
|
||||
// ((fn)(fnptr))(index);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowFlush
|
||||
// #cgo nocallback glowFlush
|
||||
// static void glowFlush(uintptr_t fnptr) {
|
||||
// typedef void (*fn)();
|
||||
// ((fn)(fnptr))();
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowFramebufferRenderbuffer
|
||||
// #cgo nocallback glowFramebufferRenderbuffer
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowFramebufferTexture2D
|
||||
// #cgo nocallback glowFramebufferTexture2D
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowGenBuffers
|
||||
// #cgo nocallback glowGenBuffers
|
||||
// static void glowGenBuffers(uintptr_t fnptr, GLsizei n, GLuint* buffers) {
|
||||
// typedef void (*fn)(GLsizei n, GLuint* buffers);
|
||||
// ((fn)(fnptr))(n, buffers);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowGenFramebuffers
|
||||
// #cgo nocallback glowGenFramebuffers
|
||||
// static void glowGenFramebuffers(uintptr_t fnptr, GLsizei n, GLuint* framebuffers) {
|
||||
// typedef void (*fn)(GLsizei n, GLuint* framebuffers);
|
||||
// ((fn)(fnptr))(n, framebuffers);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowGenRenderbuffers
|
||||
// #cgo nocallback glowGenRenderbuffers
|
||||
// static void glowGenRenderbuffers(uintptr_t fnptr, GLsizei n, GLuint* renderbuffers) {
|
||||
// typedef void (*fn)(GLsizei n, GLuint* renderbuffers);
|
||||
// ((fn)(fnptr))(n, renderbuffers);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowGenTextures
|
||||
// #cgo nocallback glowGenTextures
|
||||
// static void glowGenTextures(uintptr_t fnptr, GLsizei n, GLuint* textures) {
|
||||
// typedef void (*fn)(GLsizei n, GLuint* textures);
|
||||
// ((fn)(fnptr))(n, textures);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowGenVertexArrays
|
||||
// #cgo nocallback glowGenVertexArrays
|
||||
// static void glowGenVertexArrays(uintptr_t fnptr, GLsizei n, GLuint* arrays) {
|
||||
// typedef void (*fn)(GLsizei n, GLuint* arrays);
|
||||
// ((fn)(fnptr))(n, arrays);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowGetError
|
||||
// #cgo nocallback glowGetError
|
||||
// static GLenum glowGetError(uintptr_t fnptr) {
|
||||
// typedef GLenum (*fn)();
|
||||
// return ((fn)(fnptr))();
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowGetIntegerv
|
||||
// #cgo nocallback glowGetIntegerv
|
||||
// static void glowGetIntegerv(uintptr_t fnptr, GLenum pname, GLint* data) {
|
||||
// typedef void (*fn)(GLenum pname, GLint* data);
|
||||
// ((fn)(fnptr))(pname, data);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowGetProgramInfoLog
|
||||
// #cgo nocallback glowGetProgramInfoLog
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowGetProgramiv
|
||||
// #cgo nocallback glowGetProgramiv
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowGetShaderInfoLog
|
||||
// #cgo nocallback glowGetShaderInfoLog
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowGetShaderiv
|
||||
// #cgo nocallback glowGetShaderiv
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowGetUniformLocation
|
||||
// #cgo nocallback glowGetUniformLocation
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowIsProgram
|
||||
// #cgo nocallback glowIsProgram
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowLinkProgram
|
||||
// #cgo nocallback glowLinkProgram
|
||||
// static void glowLinkProgram(uintptr_t fnptr, GLuint program) {
|
||||
// typedef void (*fn)(GLuint program);
|
||||
// ((fn)(fnptr))(program);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowPixelStorei
|
||||
// #cgo nocallback glowPixelStorei
|
||||
// static void glowPixelStorei(uintptr_t fnptr, GLenum pname, GLint param) {
|
||||
// typedef void (*fn)(GLenum pname, GLint param);
|
||||
// ((fn)(fnptr))(pname, param);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowReadPixels
|
||||
// #cgo nocallback glowReadPixels
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowRenderbufferStorage
|
||||
// #cgo nocallback glowRenderbufferStorage
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowScissor
|
||||
// #cgo nocallback glowScissor
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowShaderSource
|
||||
// #cgo nocallback glowShaderSource
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowStencilFunc
|
||||
// #cgo nocallback glowStencilFunc
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowStencilOpSeparate
|
||||
// #cgo nocallback glowStencilOpSeparate
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowTexImage2D
|
||||
// #cgo nocallback glowTexImage2D
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowTexParameteri
|
||||
// #cgo nocallback glowTexParameteri
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowTexSubImage2D
|
||||
// #cgo nocallback glowTexSubImage2D
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowUniform1fv
|
||||
// #cgo nocallback glowUniform1fv
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowUniform1i
|
||||
// #cgo nocallback glowUniform1i
|
||||
// static void glowUniform1i(uintptr_t fnptr, GLint location, GLint v0) {
|
||||
// typedef void (*fn)(GLint location, GLint v0);
|
||||
// ((fn)(fnptr))(location, v0);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowUniform1iv
|
||||
// #cgo nocallback glowUniform1iv
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowUniform2fv
|
||||
// #cgo nocallback glowUniform2fv
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowUniform2iv
|
||||
// #cgo nocallback glowUniform2iv
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowUniform3fv
|
||||
// #cgo nocallback glowUniform3fv
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowUniform3iv
|
||||
// #cgo nocallback glowUniform3iv
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowUniform4fv
|
||||
// #cgo nocallback glowUniform4fv
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowUniform4iv
|
||||
// #cgo nocallback glowUniform4iv
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowUniformMatrix2fv
|
||||
// #cgo nocallback glowUniformMatrix2fv
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowUniformMatrix3fv
|
||||
// #cgo nocallback glowUniformMatrix3fv
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowUniformMatrix4fv
|
||||
// #cgo nocallback glowUniformMatrix4fv
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowUseProgram
|
||||
// #cgo nocallback glowUseProgram
|
||||
// static void glowUseProgram(uintptr_t fnptr, GLuint program) {
|
||||
// typedef void (*fn)(GLuint program);
|
||||
// ((fn)(fnptr))(program);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowVertexAttribPointer
|
||||
// #cgo nocallback glowVertexAttribPointer
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// #cgo noescape glowViewport
|
||||
// #cgo nocallback glowViewport
|
||||
// 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);
|
||||
@@ -369,9 +576,7 @@ type defaultContext struct {
|
||||
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
|
||||
@@ -594,6 +799,10 @@ func (c *defaultContext) GetError() uint32 {
|
||||
return uint32(ret)
|
||||
}
|
||||
|
||||
func (c *defaultContext) GetExtension(name string) any {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *defaultContext) GetInteger(pname uint32) int {
|
||||
var dst int32
|
||||
C.glowGetIntegerv(c.gpGetIntegerv, C.GLenum(pname), (*C.GLint)(unsafe.Pointer(&dst)))
|
||||
@@ -602,6 +811,9 @@ func (c *defaultContext) GetInteger(pname uint32) int {
|
||||
|
||||
func (c *defaultContext) GetProgramInfoLog(program uint32) string {
|
||||
bufSize := c.GetProgrami(program, INFO_LOG_LENGTH)
|
||||
if bufSize == 0 {
|
||||
return ""
|
||||
}
|
||||
infoLog := make([]byte, bufSize)
|
||||
C.glowGetProgramInfoLog(c.gpGetProgramInfoLog, C.GLuint(program), C.GLsizei(bufSize), nil, (*C.GLchar)(unsafe.Pointer(&infoLog[0])))
|
||||
return string(infoLog)
|
||||
@@ -615,6 +827,9 @@ func (c *defaultContext) GetProgrami(program uint32, pname uint32) int {
|
||||
|
||||
func (c *defaultContext) GetShaderInfoLog(shader uint32) string {
|
||||
bufSize := c.GetShaderi(shader, INFO_LOG_LENGTH)
|
||||
if bufSize == 0 {
|
||||
return ""
|
||||
}
|
||||
infoLog := make([]byte, bufSize)
|
||||
C.glowGetShaderInfoLog(c.gpGetShaderInfoLog, C.GLuint(shader), C.GLsizei(bufSize), nil, (*C.GLchar)(unsafe.Pointer(&infoLog[0])))
|
||||
return string(infoLog)
|
||||
@@ -633,21 +848,11 @@ func (c *defaultContext) GetUniformLocation(program uint32, name string) int32 {
|
||||
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))
|
||||
}
|
||||
@@ -819,9 +1024,7 @@ func (c *defaultContext) LoadFunctions() error {
|
||||
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"))
|
||||
|
||||
Generated
Vendored
+25
-29
@@ -17,8 +17,6 @@ package gl
|
||||
import (
|
||||
"fmt"
|
||||
"syscall/js"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/jsutil"
|
||||
)
|
||||
|
||||
type defaultContext struct {
|
||||
@@ -61,15 +59,14 @@ type defaultContext struct {
|
||||
fnFramebufferTexture2D js.Value
|
||||
fnFlush js.Value
|
||||
fnGetError js.Value
|
||||
fnGetExtension 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
|
||||
@@ -191,15 +188,14 @@ func NewDefaultContext(v js.Value) (Context, error) {
|
||||
fnFramebufferTexture2D: v.Get("framebufferTexture2D").Call("bind", v),
|
||||
fnFlush: v.Get("flush").Call("bind", v),
|
||||
fnGetError: v.Get("getError").Call("bind", v),
|
||||
fnGetExtension: v.Get("getExtension").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),
|
||||
@@ -292,7 +288,7 @@ func (c *defaultContext) BufferInit(target uint32, size int, usage uint32) {
|
||||
|
||||
func (c *defaultContext) BufferSubData(target uint32, offset int, data []byte) {
|
||||
l := len(data)
|
||||
arr := jsutil.TemporaryUint8ArrayFromUint8Slice(l, data)
|
||||
arr := tmpUint8ArrayFromUint8Slice(l, data)
|
||||
c.fnBufferSubData.Invoke(target, offset, arr, 0, l)
|
||||
}
|
||||
|
||||
@@ -373,7 +369,7 @@ func (c *defaultContext) DeleteTexture(texture uint32) {
|
||||
|
||||
func (c *defaultContext) DeleteVertexArray(array uint32) {
|
||||
c.fnDeleteVertexArray.Invoke(c.vertexArrays.get(array))
|
||||
c.textures.delete(array)
|
||||
c.vertexArrays.delete(array)
|
||||
}
|
||||
|
||||
func (c *defaultContext) Disable(cap uint32) {
|
||||
@@ -412,6 +408,14 @@ func (c *defaultContext) GetError() uint32 {
|
||||
return uint32(c.fnGetError.Invoke().Int())
|
||||
}
|
||||
|
||||
func (c *defaultContext) GetExtension(name string) any {
|
||||
ext := c.fnGetExtension.Invoke(name)
|
||||
if ext.IsNull() || ext.IsUndefined() {
|
||||
return nil
|
||||
}
|
||||
return ext
|
||||
}
|
||||
|
||||
func (c *defaultContext) GetInteger(pname uint32) int {
|
||||
ret := c.fnGetParameter.Invoke(pname)
|
||||
switch pname {
|
||||
@@ -481,18 +485,10 @@ func (c *defaultContext) GetUniformLocation(program uint32, name string) int32 {
|
||||
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))
|
||||
}
|
||||
@@ -506,7 +502,7 @@ func (c *defaultContext) ReadPixels(dst []byte, x int32, y int32, width int32, h
|
||||
c.fnReadPixels.Invoke(x, y, width, height, format, xtype, 0)
|
||||
return
|
||||
}
|
||||
p := jsutil.TemporaryUint8ArrayFromUint8Slice(len(dst), nil)
|
||||
p := tmpUint8ArrayFromUint8Slice(len(dst), nil)
|
||||
c.fnReadPixels.Invoke(x, y, width, height, format, xtype, p)
|
||||
js.CopyBytesToGo(dst, p)
|
||||
}
|
||||
@@ -543,7 +539,7 @@ func (c *defaultContext) TexParameteri(target uint32, pname uint32, param int32)
|
||||
}
|
||||
|
||||
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)
|
||||
arr := tmpUint8ArrayFromUint8Slice(len(pixels), pixels)
|
||||
// void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
|
||||
// GLsizei width, GLsizei height,
|
||||
// GLenum format, GLenum type, ArrayBufferView pixels, srcOffset);
|
||||
@@ -552,7 +548,7 @@ func (c *defaultContext) TexSubImage2D(target uint32, level int32, xoffset int32
|
||||
|
||||
func (c *defaultContext) Uniform1fv(location int32, value []float32) {
|
||||
l := c.getUniformLocation(location)
|
||||
arr := jsutil.TemporaryFloat32Array(len(value), value)
|
||||
arr := tmpFloat32ArrayFromFloat32Slice(len(value), value)
|
||||
c.fnUniform1fv.Invoke(l, arr, 0, len(value))
|
||||
}
|
||||
|
||||
@@ -563,61 +559,61 @@ func (c *defaultContext) Uniform1i(location int32, v0 int32) {
|
||||
|
||||
func (c *defaultContext) Uniform1iv(location int32, value []int32) {
|
||||
l := c.getUniformLocation(location)
|
||||
arr := jsutil.TemporaryInt32Array(len(value), value)
|
||||
arr := tmpInt32ArrayFromInt32Slice(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)
|
||||
arr := tmpFloat32ArrayFromFloat32Slice(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)
|
||||
arr := tmpInt32ArrayFromInt32Slice(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)
|
||||
arr := tmpFloat32ArrayFromFloat32Slice(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)
|
||||
arr := tmpInt32ArrayFromInt32Slice(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)
|
||||
arr := tmpFloat32ArrayFromFloat32Slice(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)
|
||||
arr := tmpInt32ArrayFromInt32Slice(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)
|
||||
arr := tmpFloat32ArrayFromFloat32Slice(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)
|
||||
arr := tmpFloat32ArrayFromFloat32Slice(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)
|
||||
arr := tmpFloat32ArrayFromFloat32Slice(len(value), value)
|
||||
c.fnUniformMatrix4fv.Invoke(l, false, arr, 0, len(value))
|
||||
}
|
||||
|
||||
|
||||
Generated
Vendored
+11
-15
@@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build darwin || windows
|
||||
//go:build (darwin || freebsd || linux || netbsd || openbsd || windows) && !nintendosdk && !playstation5
|
||||
|
||||
package gl
|
||||
|
||||
@@ -69,9 +69,7 @@ type defaultContext struct {
|
||||
gpGetShaderInfoLog uintptr
|
||||
gpGetShaderiv uintptr
|
||||
gpGetUniformLocation uintptr
|
||||
gpIsFramebuffer uintptr
|
||||
gpIsProgram uintptr
|
||||
gpIsRenderbuffer uintptr
|
||||
gpLinkProgram uintptr
|
||||
gpPixelStorei uintptr
|
||||
gpReadPixels uintptr
|
||||
@@ -294,6 +292,10 @@ func (c *defaultContext) GetError() uint32 {
|
||||
return uint32(ret)
|
||||
}
|
||||
|
||||
func (c *defaultContext) GetExtension(name string) any {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *defaultContext) GetInteger(pname uint32) int {
|
||||
var dst int32
|
||||
purego.SyscallN(c.gpGetIntegerv, uintptr(pname), uintptr(unsafe.Pointer(&dst)))
|
||||
@@ -302,6 +304,9 @@ func (c *defaultContext) GetInteger(pname uint32) int {
|
||||
|
||||
func (c *defaultContext) GetProgramInfoLog(program uint32) string {
|
||||
bufSize := c.GetProgrami(program, INFO_LOG_LENGTH)
|
||||
if bufSize == 0 {
|
||||
return ""
|
||||
}
|
||||
infoLog := make([]byte, bufSize)
|
||||
purego.SyscallN(c.gpGetProgramInfoLog, uintptr(program), uintptr(bufSize), 0, uintptr(unsafe.Pointer(&infoLog[0])))
|
||||
return string(infoLog)
|
||||
@@ -315,6 +320,9 @@ func (c *defaultContext) GetProgrami(program uint32, pname uint32) int {
|
||||
|
||||
func (c *defaultContext) GetShaderInfoLog(shader uint32) string {
|
||||
bufSize := c.GetShaderi(shader, INFO_LOG_LENGTH)
|
||||
if bufSize == 0 {
|
||||
return ""
|
||||
}
|
||||
infoLog := make([]byte, bufSize)
|
||||
purego.SyscallN(c.gpGetShaderInfoLog, uintptr(shader), uintptr(bufSize), 0, uintptr(unsafe.Pointer(&infoLog[0])))
|
||||
return string(infoLog)
|
||||
@@ -333,21 +341,11 @@ func (c *defaultContext) GetUniformLocation(program uint32, name string) int32 {
|
||||
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))
|
||||
}
|
||||
@@ -519,9 +517,7 @@ func (c *defaultContext) LoadFunctions() error {
|
||||
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")
|
||||
|
||||
Generated
Vendored
+1
-2
@@ -66,15 +66,14 @@ type Context interface {
|
||||
FramebufferRenderbuffer(target uint32, attachment uint32, renderbuffertarget uint32, renderbuffer uint32)
|
||||
FramebufferTexture2D(target uint32, attachment uint32, textarget uint32, texture uint32, level int32)
|
||||
GetError() uint32
|
||||
GetExtension(name string) any
|
||||
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)
|
||||
|
||||
Generated
Vendored
+1
-2
@@ -38,8 +38,7 @@ func (c *defaultContext) init() error {
|
||||
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)
|
||||
return fmt.Errorf("gl: failed to load: OpenGL.framework: %w, OpenGLES.framework: %w", errGL, errGLES)
|
||||
}
|
||||
|
||||
func (c *defaultContext) getProcAddress(name string) (uintptr, error) {
|
||||
|
||||
Generated
Vendored
+52
-67
@@ -16,99 +16,84 @@
|
||||
|
||||
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 (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"unsafe"
|
||||
|
||||
"github.com/ebitengine/purego"
|
||||
)
|
||||
|
||||
var (
|
||||
libGL unsafe.Pointer
|
||||
libGLES unsafe.Pointer
|
||||
libGL uintptr
|
||||
libGLES uintptr
|
||||
)
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
var errs []error
|
||||
|
||||
// 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
|
||||
// Try OpenGL ES first. Some machines like Android and Raspberry Pi might work only with OpenGL ES.
|
||||
//
|
||||
// Do not use OpenGL ES for Steam, as overlays might not work properly (#3338).
|
||||
// With Steam, OpenGL (not ES) should be available anyway.
|
||||
if os.Getenv("SteamEnv") != "1" {
|
||||
for _, name := range []string{"libGLESv2.so", "libGLESv2.so.2", "libGLESv2.so.1", "libGLESv2.so.0"} {
|
||||
lib, err := purego.Dlopen(name, purego.RTLD_LAZY|purego.RTLD_GLOBAL)
|
||||
if err == nil {
|
||||
libGLES = lib
|
||||
c.isES = true
|
||||
return nil
|
||||
}
|
||||
errs = append(errs, fmt.Errorf("gl: Dlopen failed: name: %s: %w", name, err))
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
// Try OpenGL next.
|
||||
// Usually libGL.so or libGL.so.1 is used. libGL.so.2 might exist only on NetBSD.
|
||||
// TODO: Should "libOpenGL.so.0" [1] and "libGLX.so.0" [2] be added? These were added as of GLFW 3.3.9.
|
||||
// [1] https://github.com/glfw/glfw/commit/55aad3c37b67f17279378db52da0a3ab81bbf26d
|
||||
// [2] https://github.com/glfw/glfw/commit/c18851f52ec9704eb06464058a600845ec1eada1
|
||||
for _, name := range []string{"libGL.so", "libGL.so.2", "libGL.so.1", "libGL.so.0"} {
|
||||
lib, err := purego.Dlopen(name, purego.RTLD_LAZY|purego.RTLD_GLOBAL)
|
||||
if err == nil {
|
||||
libGL = lib
|
||||
return nil
|
||||
}
|
||||
errs = append(errs, fmt.Errorf("gl: Dlopen failed: name: %s: %w", name, err))
|
||||
}
|
||||
|
||||
return fmt.Errorf("gl: failed to load libGL.so and libGLESv2.so")
|
||||
errs = append([]error{fmt.Errorf("gl: failed to load libGL.so and libGLESv2.so: ")}, errs...)
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
|
||||
func (c *defaultContext) getProcAddress(name string) (uintptr, error) {
|
||||
if c.isES {
|
||||
return getProcAddressGLES(name), nil
|
||||
return getProcAddressGLES(name)
|
||||
}
|
||||
return getProcAddressGL(name), nil
|
||||
return getProcAddressGL(name)
|
||||
}
|
||||
|
||||
func getProcAddressGL(name string) uintptr {
|
||||
cname := C.CString(name)
|
||||
defer C.free(unsafe.Pointer(cname))
|
||||
return uintptr(C.getProcAddressGL(libGL, cname))
|
||||
var glXGetProcAddress func(name string) uintptr
|
||||
|
||||
func getProcAddressGL(name string) (uintptr, error) {
|
||||
if glXGetProcAddress == nil {
|
||||
if _, err := purego.Dlsym(libGL, "glXGetProcAddress"); err == nil {
|
||||
purego.RegisterLibFunc(&glXGetProcAddress, libGL, "glXGetProcAddress")
|
||||
} else if _, err := purego.Dlsym(libGL, "glXGetProcAddressARB"); err == nil {
|
||||
purego.RegisterLibFunc(&glXGetProcAddress, libGL, "glXGetProcAddressARB")
|
||||
}
|
||||
}
|
||||
if glXGetProcAddress == nil {
|
||||
return 0, fmt.Errorf("gl: failed to find glXGetProcAddress or glXGetProcAddressARB in libGL.so")
|
||||
}
|
||||
|
||||
return glXGetProcAddress(name), nil
|
||||
}
|
||||
|
||||
func getProcAddressGLES(name string) uintptr {
|
||||
cname := C.CString(name)
|
||||
defer C.free(unsafe.Pointer(cname))
|
||||
return uintptr(C.getProcAddressGLES(libGLES, cname))
|
||||
func getProcAddressGLES(name string) (uintptr, error) {
|
||||
proc, err := purego.Dlsym(libGLES, name)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return proc, nil
|
||||
}
|
||||
|
||||
Generated
Vendored
+2
@@ -21,6 +21,8 @@ package gl
|
||||
// #include <stdlib.h>
|
||||
// #include <EGL/egl.h>
|
||||
//
|
||||
// #cgo noescape getProcAddress
|
||||
// #cgo nocallback getProcAddress
|
||||
// static void* getProcAddress(const char* name) {
|
||||
// return eglGetProcAddress(name);
|
||||
// }
|
||||
|
||||
Generated
Vendored
+40
@@ -0,0 +1,40 @@
|
||||
// Copyright 2019 The Ebiten Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package gl
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"syscall/js"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func copyUint8SliceToTemporaryArrayBuffer(src []uint8) {
|
||||
if len(src) == 0 {
|
||||
return
|
||||
}
|
||||
js.CopyBytesToJS(tmpUint8Array, src)
|
||||
}
|
||||
|
||||
type numeric interface {
|
||||
~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | ~float32 | ~float64
|
||||
}
|
||||
|
||||
func copySliceToTemporaryArrayBuffer[T numeric](src []T) {
|
||||
if len(src) == 0 {
|
||||
return
|
||||
}
|
||||
js.CopyBytesToJS(tmpUint8Array, unsafe.Slice((*byte)(unsafe.Pointer(&src[0])), len(src)*int(unsafe.Sizeof(T(0)))))
|
||||
runtime.KeepAlive(src)
|
||||
}
|
||||
Generated
Vendored
+8
-8
@@ -198,7 +198,7 @@ func (g *Graphics) uniformVariableName(idx int) string {
|
||||
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 {
|
||||
func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.ShaderSrcImageCount]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")
|
||||
}
|
||||
@@ -224,7 +224,7 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
|
||||
|
||||
var idx int
|
||||
for i, typ := range shader.ir.Uniforms {
|
||||
n := typ.Uint32Count()
|
||||
n := typ.DwordCount()
|
||||
g.uniformVars[i].name = g.uniformVariableName(i)
|
||||
g.uniformVars[i].value = uniforms[idx : idx+n]
|
||||
g.uniformVars[i].typ = typ
|
||||
@@ -241,7 +241,7 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
|
||||
g.uniformVars[idx].value[13] ^= 1 << 31
|
||||
}
|
||||
|
||||
var imgs [graphics.ShaderImageCount]textureVariable
|
||||
var imgs [graphics.ShaderSrcImageCount]textureVariable
|
||||
for i, srcID := range srcIDs {
|
||||
if srcID == graphicsdriver.InvalidImageID {
|
||||
continue
|
||||
@@ -259,7 +259,7 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
|
||||
}
|
||||
g.uniformVars = g.uniformVars[:0]
|
||||
|
||||
if fillRule != graphicsdriver.FillAll {
|
||||
if fillRule != graphicsdriver.FillRuleFillAll {
|
||||
if err := destination.ensureStencilBuffer(); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -274,14 +274,14 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
|
||||
int32(dstRegion.Region.Dy()),
|
||||
)
|
||||
switch fillRule {
|
||||
case graphicsdriver.NonZero:
|
||||
case graphicsdriver.FillRuleNonZero:
|
||||
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:
|
||||
case graphicsdriver.FillRuleEvenOdd:
|
||||
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)
|
||||
@@ -289,7 +289,7 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
|
||||
|
||||
g.context.ctx.DrawElements(gl.TRIANGLES, int32(dstRegion.IndexCount), gl.UNSIGNED_INT, indexOffset*int(unsafe.Sizeof(uint32(0))))
|
||||
}
|
||||
if fillRule != graphicsdriver.FillAll {
|
||||
if fillRule != graphicsdriver.FillRuleFillAll {
|
||||
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)
|
||||
@@ -298,7 +298,7 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
|
||||
indexOffset += dstRegion.IndexCount
|
||||
}
|
||||
|
||||
if fillRule != graphicsdriver.FillAll {
|
||||
if fillRule != graphicsdriver.FillRuleFillAll {
|
||||
g.context.ctx.Disable(gl.STENCIL_TEST)
|
||||
}
|
||||
|
||||
|
||||
Generated
Vendored
+1
-1
@@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build ebitenginegldebug
|
||||
//go:build !playstation5 && ebitenginegldebug
|
||||
|
||||
package opengl
|
||||
|
||||
|
||||
Generated
Vendored
+8
-1
@@ -27,7 +27,7 @@ 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) {
|
||||
func NewGraphics(canvas js.Value, colorSpace graphicsdriver.ColorSpace) (graphicsdriver.Graphics, error) {
|
||||
var glContext js.Value
|
||||
|
||||
attr := js.Global().Get("Object").New()
|
||||
@@ -41,6 +41,13 @@ func NewGraphics(canvas js.Value) (graphicsdriver.Graphics, error) {
|
||||
return nil, fmt.Errorf("opengl: getContext for webgl2 failed")
|
||||
}
|
||||
|
||||
switch colorSpace {
|
||||
case graphicsdriver.ColorSpaceSRGB:
|
||||
glContext.Set("drawingBufferColorSpace", "srgb")
|
||||
case graphicsdriver.ColorSpaceDisplayP3:
|
||||
glContext.Set("drawingBufferColorSpace", "display-p3")
|
||||
}
|
||||
|
||||
ctx, err := gl.NewDefaultContext(glContext)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
+53
-21
@@ -12,20 +12,61 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build !android && !ios && !js && !nintendosdk && !playstation5
|
||||
//go:build (freebsd || linux || netbsd || openbsd) && !android && !nintendosdk && !playstation5
|
||||
|
||||
package opengl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"bufio"
|
||||
"bytes"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
func isGLXExtensionForGL2Available() bool {
|
||||
var buf bytes.Buffer
|
||||
cmd := exec.Command("glxinfo")
|
||||
cmd.Stdout = &buf
|
||||
if err := cmd.Run(); err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
const (
|
||||
indent = " "
|
||||
ext = "GLX_EXT_create_context_es2_profile"
|
||||
)
|
||||
|
||||
var listingExtensions bool
|
||||
s := bufio.NewScanner(&buf)
|
||||
for s.Scan() {
|
||||
line := s.Text()
|
||||
if !listingExtensions {
|
||||
if line == "GLX extensions:" {
|
||||
listingExtensions = true
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(line, indent) {
|
||||
listingExtensions = false
|
||||
break
|
||||
}
|
||||
|
||||
for len(line) > 0 {
|
||||
head, tail, _ := strings.Cut(line, ",")
|
||||
if strings.TrimSpace(head) == ext {
|
||||
return true
|
||||
}
|
||||
line = tail
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type graphicsPlatform struct {
|
||||
window *glfw.Window
|
||||
}
|
||||
@@ -33,10 +74,6 @@ 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) {
|
||||
if microsoftgdk.IsXbox() {
|
||||
return nil, fmt.Errorf("opengl: OpenGL is not supported on Xbox")
|
||||
}
|
||||
|
||||
ctx, err := gl.NewDefaultContext()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -60,8 +97,12 @@ func setGLFWClientAPI(isES bool) error {
|
||||
if err := glfw.WindowHint(glfw.ContextVersionMinor, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := glfw.WindowHint(glfw.ContextCreationAPI, glfw.EGLContextAPI); err != nil {
|
||||
return err
|
||||
// Use GLX if the extension allows, or use EGL otherwise.
|
||||
// Prefer GLX since EGL might not work well on Wayland (#3152).
|
||||
if !isGLXExtensionForGL2Available() {
|
||||
if err := glfw.WindowHint(glfw.ContextCreationAPI, glfw.EGLContextAPI); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -75,15 +116,6 @@ func setGLFWClientAPI(isES bool) error {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -103,11 +135,11 @@ func (g *Graphics) swapBuffers() error {
|
||||
// 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 {
|
||||
if err := g.window.SwapInterval(1); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := glfw.SwapInterval(0); err != nil {
|
||||
if err := g.window.SwapInterval(0); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
Generated
Vendored
+86
@@ -0,0 +1,86 @@
|
||||
// Copyright 2024 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 && !ios
|
||||
|
||||
package opengl
|
||||
|
||||
import (
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/glfw"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl/gl"
|
||||
)
|
||||
|
||||
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) {
|
||||
ctx, err := gl.NewDefaultContext()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := glfw.WindowHint(glfw.ClientAPI, glfw.OpenGLAPI); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := glfw.WindowHint(glfw.ContextVersionMajor, 3); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := glfw.WindowHint(glfw.ContextVersionMinor, 2); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// macOS requires forward-compatible and a core profile.
|
||||
if err := glfw.WindowHint(glfw.OpenGLForwardCompat, glfw.True); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return newGraphics(ctx), 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 := g.window.SwapInterval(1); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := g.window.SwapInterval(0); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := g.window.SwapBuffers(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Generated
Vendored
+1
-1
@@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build !ebitenginegldebug
|
||||
//go:build !playstation5 && !ebitenginegldebug
|
||||
|
||||
package opengl
|
||||
|
||||
|
||||
Generated
Vendored
+84
@@ -0,0 +1,84 @@
|
||||
// Copyright 2024 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"
|
||||
|
||||
"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 := glfw.WindowHint(glfw.ClientAPI, glfw.OpenGLAPI); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := glfw.WindowHint(glfw.ContextVersionMajor, 3); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := glfw.WindowHint(glfw.ContextVersionMinor, 2); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return newGraphics(ctx), 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 := g.window.SwapInterval(1); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := g.window.SwapInterval(0); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := g.window.SwapBuffers(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
+7
-7
@@ -37,10 +37,9 @@ type Image struct {
|
||||
|
||||
// framebuffer is a wrapper of OpenGL's framebuffer.
|
||||
type framebuffer struct {
|
||||
graphics *Graphics
|
||||
native framebufferNative
|
||||
width int
|
||||
height int
|
||||
native framebufferNative
|
||||
viewportWidth int
|
||||
viewportHeight int
|
||||
}
|
||||
|
||||
func (i *Image) ID() graphicsdriver.ImageID {
|
||||
@@ -81,7 +80,7 @@ func (i *Image) ReadPixels(args []graphicsdriver.PixelsArgs) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *Image) framebufferSize() (int, int) {
|
||||
func (i *Image) viewportSize() (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
|
||||
@@ -96,11 +95,12 @@ func (i *Image) ensureFramebuffer() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
w, h := i.framebufferSize()
|
||||
w, h := i.viewportSize()
|
||||
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
|
||||
@@ -118,7 +118,7 @@ func (i *Image) ensureStencilBuffer() error {
|
||||
return err
|
||||
}
|
||||
|
||||
r, err := i.graphics.context.newRenderbuffer(i.framebufferSize())
|
||||
r, err := i.graphics.context.newRenderbuffer(i.viewportSize())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Generated
Vendored
+43
-27
@@ -53,28 +53,33 @@ func (a *arrayBufferLayout) names() []string {
|
||||
return ns
|
||||
}
|
||||
|
||||
// totalBytes returns the size in bytes for one element of the array buffer.
|
||||
func (a *arrayBufferLayout) totalBytes() int {
|
||||
// float32Count returns the total float32 count for one element of the array buffer.
|
||||
func (a *arrayBufferLayout) float32Count() int {
|
||||
if a.total != 0 {
|
||||
return a.total
|
||||
}
|
||||
t := 0
|
||||
for _, p := range a.parts {
|
||||
t += floatSizeInBytes * p.num
|
||||
t += p.num
|
||||
}
|
||||
a.total = t
|
||||
return a.total
|
||||
}
|
||||
|
||||
func (a *arrayBufferLayout) addPart(part arrayBufferLayoutPart) {
|
||||
a.parts = append(a.parts, part)
|
||||
a.total = 0
|
||||
}
|
||||
|
||||
// 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()
|
||||
total := a.float32Count()
|
||||
offset := 0
|
||||
for i, p := range a.parts {
|
||||
context.ctx.VertexAttribPointer(uint32(i), int32(p.num), gl.FLOAT, false, int32(total), offset)
|
||||
context.ctx.VertexAttribPointer(uint32(i), int32(p.num), gl.FLOAT, false, int32(floatSizeInBytes*total), offset)
|
||||
offset += floatSizeInBytes * p.num
|
||||
}
|
||||
}
|
||||
@@ -88,28 +93,39 @@ func (a *arrayBufferLayout) disable(context *context) {
|
||||
}
|
||||
|
||||
// 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,
|
||||
},
|
||||
},
|
||||
}
|
||||
var theArrayBufferLayout arrayBufferLayout
|
||||
|
||||
func init() {
|
||||
vertexFloatCount := theArrayBufferLayout.totalBytes() / floatSizeInBytes
|
||||
if graphics.VertexFloatCount != vertexFloatCount {
|
||||
panic(fmt.Sprintf("vertex float num must be %d but %d", graphics.VertexFloatCount, vertexFloatCount))
|
||||
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,
|
||||
},
|
||||
},
|
||||
}
|
||||
n := theArrayBufferLayout.float32Count()
|
||||
diff := graphics.VertexFloatCount - n
|
||||
if diff == 0 {
|
||||
return
|
||||
}
|
||||
if diff%4 != 0 {
|
||||
panic("opengl: unexpected attribute layout")
|
||||
}
|
||||
for i := 0; i < diff/4; i++ {
|
||||
theArrayBufferLayout.addPart(arrayBufferLayoutPart{
|
||||
name: fmt.Sprintf("A%d", i+3),
|
||||
num: 4,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,7 +275,7 @@ func (g *Graphics) textureVariableName(idx int) string {
|
||||
}
|
||||
|
||||
// useProgram uses the program (programTexture).
|
||||
func (g *Graphics) useProgram(program program, uniforms []uniformVariable, textures [graphics.ShaderImageCount]textureVariable) error {
|
||||
func (g *Graphics) useProgram(program program, uniforms []uniformVariable, textures [graphics.ShaderSrcImageCount]textureVariable) error {
|
||||
if g.state.lastProgram != program {
|
||||
g.context.ctx.UseProgram(uint32(program))
|
||||
|
||||
@@ -276,7 +292,7 @@ func (g *Graphics) useProgram(program program, uniforms []uniformVariable, textu
|
||||
if u.value == nil {
|
||||
continue
|
||||
}
|
||||
if got, expected := len(u.value), u.typ.Uint32Count(); got != expected {
|
||||
if got, expected := len(u.value), u.typ.DwordCount(); 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
|
||||
|
||||
+23
-2
@@ -18,6 +18,7 @@ package opengl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl/gl"
|
||||
@@ -59,13 +60,13 @@ func (s *Shader) compile() error {
|
||||
|
||||
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)
|
||||
return err
|
||||
}
|
||||
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)
|
||||
return err
|
||||
}
|
||||
defer s.graphics.context.ctx.DeleteShader(uint32(fs))
|
||||
|
||||
@@ -74,6 +75,26 @@ func (s *Shader) compile() error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Check the shader compile status asynchronously if possible.
|
||||
// The function 'compile' itself is still blocking, but at least this gives a chance to other goroutines to run
|
||||
// while waiting for the shader compilation.
|
||||
if s.graphics.context.hasParallelShaderCompile() {
|
||||
for s.graphics.context.ctx.GetShaderi(uint32(vs), gl.COMPLETION_STATUS_KHR) != gl.TRUE ||
|
||||
s.graphics.context.ctx.GetShaderi(uint32(fs), gl.COMPLETION_STATUS_KHR) != gl.TRUE {
|
||||
runtime.Gosched()
|
||||
}
|
||||
}
|
||||
|
||||
// Check errors only after linking fails.
|
||||
// See https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#dont_check_shader_compile_status_unless_linking_fails
|
||||
if s.graphics.context.ctx.GetProgrami(uint32(p), gl.LINK_STATUS) == gl.FALSE {
|
||||
programInfo := s.graphics.context.ctx.GetProgramInfoLog(uint32(p))
|
||||
vertexShaderInfo := s.graphics.context.ctx.GetShaderInfoLog(uint32(vs))
|
||||
fragmentShaderInfo := s.graphics.context.ctx.GetShaderInfoLog(uint32(fs))
|
||||
return fmt.Errorf("opengl: program error: %s\nvertex shader error: %s\nvertex shader source: %s\nfragment shader error: %s\nfragment shader source: %s",
|
||||
programInfo, vertexShaderInfo, vssrc, fragmentShaderInfo, fssrc)
|
||||
}
|
||||
|
||||
s.p = p
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user