mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-07 02:15:34 +00:00
gpu/internal/opengl: restore BeginFrame state in EndFrame
To ease the integration with foreign OpenGL contexts, carefully save the context state before rendering a frame and restore it afterwards. Gio rendering can then be mixed with OpenGL code that expects exclusive control over context state. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+26
-1
@@ -8,26 +8,38 @@ type (
|
||||
)
|
||||
|
||||
const (
|
||||
ACTIVE_TEXTURE = 0x84E0
|
||||
ALL_BARRIER_BITS = 0xffffffff
|
||||
ARRAY_BUFFER = 0x8892
|
||||
ARRAY_BUFFER_BINDING = 0x8894
|
||||
BACK = 0x0405
|
||||
BLEND = 0xbe2
|
||||
BLEND_DST_RGB = 0x80C8
|
||||
BLEND_SRC_RGB = 0x80C9
|
||||
BLEND_DST_ALPHA = 0x80CA
|
||||
BLEND_SRC_ALPHA = 0x80CB
|
||||
CLAMP_TO_EDGE = 0x812f
|
||||
COLOR_ATTACHMENT0 = 0x8ce0
|
||||
COLOR_BUFFER_BIT = 0x4000
|
||||
COLOR_CLEAR_VALUE = 0x0C22
|
||||
COMPILE_STATUS = 0x8b81
|
||||
COMPUTE_SHADER = 0x91B9
|
||||
DEPTH_BUFFER_BIT = 0x100
|
||||
CURRENT_PROGRAM = 0x8B8D
|
||||
DEPTH_ATTACHMENT = 0x8d00
|
||||
DEPTH_BUFFER_BIT = 0x100
|
||||
DEPTH_CLEAR_VALUE = 0x0B73
|
||||
DEPTH_COMPONENT16 = 0x81a5
|
||||
DEPTH_COMPONENT24 = 0x81A6
|
||||
DEPTH_COMPONENT32F = 0x8CAC
|
||||
DEPTH_FUNC = 0x0B74
|
||||
DEPTH_TEST = 0xb71
|
||||
DEPTH_WRITEMASK = 0x0B72
|
||||
DRAW_FRAMEBUFFER = 0x8CA9
|
||||
DST_COLOR = 0x306
|
||||
DYNAMIC_DRAW = 0x88E8
|
||||
DYNAMIC_READ = 0x88E9
|
||||
ELEMENT_ARRAY_BUFFER = 0x8893
|
||||
ELEMENT_ARRAY_BUFFER_BINDING = 0x8895
|
||||
EXTENSIONS = 0x1f03
|
||||
FALSE = 0
|
||||
FLOAT = 0x1406
|
||||
@@ -59,6 +71,7 @@ const (
|
||||
R16F = 0x822d
|
||||
R8 = 0x8229
|
||||
READ_FRAMEBUFFER = 0x8ca8
|
||||
READ_FRAMEBUFFER_BINDING = 0x8CAA
|
||||
READ_ONLY = 0x88B8
|
||||
READ_WRITE = 0x88BA
|
||||
RED = 0x1903
|
||||
@@ -71,6 +84,7 @@ const (
|
||||
RGBA = 0x1908
|
||||
RGBA8 = 0x8058
|
||||
SHADER_STORAGE_BUFFER = 0x90D2
|
||||
SHADER_STORAGE_BUFFER_BINDING = 0x90D3
|
||||
SHORT = 0x1402
|
||||
SRGB = 0x8c40
|
||||
SRGB_ALPHA_EXT = 0x8c42
|
||||
@@ -79,6 +93,7 @@ const (
|
||||
STATIC_DRAW = 0x88e4
|
||||
STENCIL_BUFFER_BIT = 0x00000400
|
||||
TEXTURE_2D = 0xde1
|
||||
TEXTURE_BINDING_2D = 0x8069
|
||||
TEXTURE_MAG_FILTER = 0x2800
|
||||
TEXTURE_MIN_FILTER = 0x2801
|
||||
TEXTURE_WRAP_S = 0x2802
|
||||
@@ -89,11 +104,21 @@ const (
|
||||
TRIANGLES = 0x4
|
||||
TRUE = 1
|
||||
UNIFORM_BUFFER = 0x8A11
|
||||
UNIFORM_BUFFER_BINDING = 0x8A28
|
||||
UNPACK_ALIGNMENT = 0xcf5
|
||||
UNSIGNED_BYTE = 0x1401
|
||||
UNSIGNED_SHORT = 0x1403
|
||||
VIEWPORT = 0x0BA2
|
||||
VERSION = 0x1f02
|
||||
VERTEX_ARRAY_BINDING = 0x85B5
|
||||
VERTEX_SHADER = 0x8b31
|
||||
VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F
|
||||
VERTEX_ATTRIB_ARRAY_ENABLED = 0x8622
|
||||
VERTEX_ATTRIB_ARRAY_POINTER = 0x8645
|
||||
VERTEX_ATTRIB_ARRAY_NORMALIZED = 0x886A
|
||||
VERTEX_ATTRIB_ARRAY_SIZE = 0x8623
|
||||
VERTEX_ATTRIB_ARRAY_STRIDE = 0x8624
|
||||
VERTEX_ATTRIB_ARRAY_TYPE = 0x8625
|
||||
WRITE_ONLY = 0x88B9
|
||||
ZERO = 0x0
|
||||
|
||||
|
||||
+46
-3
@@ -101,8 +101,8 @@ func (f *Functions) BindVertexArray(a VertexArray) {
|
||||
func (f *Functions) BlendEquation(mode Enum) {
|
||||
f.Ctx.Call("blendEquation", int(mode))
|
||||
}
|
||||
func (f *Functions) BlendFunc(sfactor, dfactor Enum) {
|
||||
f.Ctx.Call("blendFunc", int(sfactor), int(dfactor))
|
||||
func (f *Functions) BlendFuncSeparate(srcRGB, dstRGB, srcA, dstA Enum) {
|
||||
f.Ctx.Call("blendFunc", int(srcRGB), int(dstRGB), int(srcA), int(dstA))
|
||||
}
|
||||
func (f *Functions) BlitFramebuffer(sx0, sy0, sx1, sy1, dx0, dy0, dx1, dy1 int, mask Enum, filter Enum) {
|
||||
panic("not implemented")
|
||||
@@ -241,11 +241,41 @@ func (f *Functions) GetFramebufferAttachmentParameteri(target, attachment, pname
|
||||
return paramVal(f.Ctx.Call("getFramebufferAttachmentParameter", int(target), int(attachment), int(pname)))
|
||||
}
|
||||
func (f *Functions) GetBinding(pname Enum) Object {
|
||||
return Object(f.Ctx.Call("getParameter", int(pname)))
|
||||
obj := f.Ctx.Call("getParameter", int(pname))
|
||||
if !obj.Truthy() {
|
||||
return Object{}
|
||||
}
|
||||
return Object(obj)
|
||||
}
|
||||
func (f *Functions) GetBindingi(pname Enum, idx int) Object {
|
||||
obj := f.Ctx.Call("getIndexedParameter", int(pname), idx)
|
||||
if !obj.Truthy() {
|
||||
return Object{}
|
||||
}
|
||||
return Object(obj)
|
||||
}
|
||||
func (f *Functions) GetInteger(pname Enum) int {
|
||||
return paramVal(f.Ctx.Call("getParameter", int(pname)))
|
||||
}
|
||||
func (f *Functions) GetFloat(pname Enum) float32 {
|
||||
return float32(f.Ctx.Call("getParameter", int(pname)).Float())
|
||||
}
|
||||
func (f *Functions) GetInteger4(pname Enum) [4]int {
|
||||
arr := f.Ctx.Call("getParameter", int(pname))
|
||||
var res [4]int
|
||||
for i := range res {
|
||||
res[i] = arr.Index(i).Int()
|
||||
}
|
||||
return res
|
||||
}
|
||||
func (f *Functions) GetFloat4(pname Enum) [4]float32 {
|
||||
arr := f.Ctx.Call("getParameter", int(pname))
|
||||
var res [4]float32
|
||||
for i := range res {
|
||||
res[i] = float32(arr.Index(i).Float())
|
||||
}
|
||||
return res
|
||||
}
|
||||
func (f *Functions) GetProgrami(p Program, pname Enum) int {
|
||||
return paramVal(f.Ctx.Call("getProgramParameter", js.Value(p), int(pname)))
|
||||
}
|
||||
@@ -284,6 +314,19 @@ func (f *Functions) GetUniformBlockIndex(p Program, name string) uint {
|
||||
func (f *Functions) GetUniformLocation(p Program, name string) Uniform {
|
||||
return Uniform(f.Ctx.Call("getUniformLocation", js.Value(p), name))
|
||||
}
|
||||
func (f *Functions) GetVertexAttrib(index int, pname Enum) int {
|
||||
return paramVal(f.Ctx.Call("getVertexAttrib", index, int(pname)))
|
||||
}
|
||||
func (f *Functions) GetVertexAttribBinding(index int, pname Enum) Object {
|
||||
obj := f.Ctx.Call("getVertexAttrib", index, int(pname))
|
||||
if !obj.Truthy() {
|
||||
return Object{}
|
||||
}
|
||||
return Object(obj)
|
||||
}
|
||||
func (f *Functions) GetVertexAttribPointer(index int, pname Enum) uintptr {
|
||||
return uintptr(f.Ctx.Call("getVertexAttribOffset", index, int(pname)).Int())
|
||||
}
|
||||
func (f *Functions) InvalidateFramebuffer(target, attachment Enum) {
|
||||
fn := f.Ctx.Get("invalidateFramebuffer")
|
||||
if !fn.IsUndefined() {
|
||||
|
||||
+74
-9
@@ -42,7 +42,7 @@ typedef struct {
|
||||
void (*glBindRenderbuffer)(GLenum target, GLuint renderbuffer);
|
||||
void (*glBindTexture)(GLenum target, GLuint texture);
|
||||
void (*glBlendEquation)(GLenum mode);
|
||||
void (*glBlendFunc)(GLenum sfactor, GLenum dfactor);
|
||||
void (*glBlendFuncSeparate)(GLenum srcRGB, GLenum dstRGB, GLenum srcA, GLenum dstA);
|
||||
void (*glBufferData)(GLenum target, GLsizeiptr size, const void *data, GLenum usage);
|
||||
void (*glBufferSubData)(GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
|
||||
GLenum (*glCheckFramebufferStatus)(GLenum target);
|
||||
@@ -76,7 +76,9 @@ typedef struct {
|
||||
void (*glGenTextures)(GLsizei n, GLuint *textures);
|
||||
GLenum (*glGetError)(void);
|
||||
void (*glGetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment, GLenum pname, GLint *params);
|
||||
void (*glGetFloatv)(GLenum pname, GLfloat *data);
|
||||
void (*glGetIntegerv)(GLenum pname, GLint *data);
|
||||
void (*glGetIntegeri_v)(GLenum pname, GLuint idx, GLint *data);
|
||||
void (*glGetProgramiv)(GLuint program, GLenum pname, GLint *params);
|
||||
void (*glGetProgramInfoLog)(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
|
||||
void (*glGetRenderbufferParameteriv)(GLenum target, GLenum pname, GLint *params);
|
||||
@@ -84,6 +86,8 @@ typedef struct {
|
||||
void (*glGetShaderInfoLog)(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
|
||||
const GLubyte *(*glGetString)(GLenum name);
|
||||
GLint (*glGetUniformLocation)(GLuint program, const GLchar *name);
|
||||
void (*glGetVertexAttribiv)(GLuint index, GLenum pname, GLint *params);
|
||||
void (*glGetVertexAttribPointerv)(GLuint index, GLenum pname, void **params);
|
||||
GLboolean (*glIsEnabled)(GLenum cap);
|
||||
void (*glLinkProgram)(GLuint program);
|
||||
void (*glPixelStorei)(GLenum pname, GLint param);
|
||||
@@ -162,8 +166,8 @@ static void glBlendEquation(glFunctions *f, GLenum mode) {
|
||||
f->glBlendEquation(mode);
|
||||
}
|
||||
|
||||
static void glBlendFunc(glFunctions *f, GLenum sfactor, GLenum dfactor) {
|
||||
f->glBlendFunc(sfactor, dfactor);
|
||||
static void glBlendFuncSeparate(glFunctions *f, GLenum srcRGB, GLenum dstRGB, GLenum srcA, GLenum dstA) {
|
||||
f->glBlendFuncSeparate(srcRGB, dstRGB, srcA, dstA);
|
||||
}
|
||||
|
||||
static void glBufferData(glFunctions *f, GLenum target, GLsizeiptr size, const void *data, GLenum usage) {
|
||||
@@ -303,6 +307,14 @@ static void glGetIntegerv(glFunctions *f, GLenum pname, GLint *data) {
|
||||
f->glGetIntegerv(pname, data);
|
||||
}
|
||||
|
||||
static void glGetFloatv(glFunctions *f, GLenum pname, GLfloat *data) {
|
||||
f->glGetFloatv(pname, data);
|
||||
}
|
||||
|
||||
static void glGetIntegeri_v(glFunctions *f, GLenum pname, GLuint idx, GLint *data) {
|
||||
f->glGetIntegeri_v(pname, idx, data);
|
||||
}
|
||||
|
||||
static void glGetProgramiv(glFunctions *f, GLuint program, GLenum pname, GLint *params) {
|
||||
f->glGetProgramiv(program, pname, params);
|
||||
}
|
||||
@@ -331,6 +343,17 @@ static GLint glGetUniformLocation(glFunctions *f, GLuint program, const GLchar *
|
||||
return f->glGetUniformLocation(program, name);
|
||||
}
|
||||
|
||||
static void glGetVertexAttribiv(glFunctions *f, GLuint index, GLenum pname, GLint *data) {
|
||||
f->glGetVertexAttribiv(index, pname, data);
|
||||
}
|
||||
|
||||
// Return uintptr_t to avoid Cgo pointer check.
|
||||
static uintptr_t glGetVertexAttribPointerv(glFunctions *f, GLuint index, GLenum pname) {
|
||||
void *ptrs;
|
||||
f->glGetVertexAttribPointerv(index, pname, &ptrs);
|
||||
return (uintptr_t)ptrs;
|
||||
}
|
||||
|
||||
static GLboolean glIsEnabled(glFunctions *f, GLenum cap) {
|
||||
return f->glIsEnabled(cap);
|
||||
}
|
||||
@@ -493,8 +516,9 @@ type Context interface{}
|
||||
|
||||
type Functions struct {
|
||||
// Query caches.
|
||||
uints [100]C.GLuint
|
||||
ints [100]C.GLint
|
||||
uints [100]C.GLuint
|
||||
ints [100]C.GLint
|
||||
floats [100]C.GLfloat
|
||||
|
||||
f C.glFunctions
|
||||
}
|
||||
@@ -571,7 +595,7 @@ func (f *Functions) load(forceES bool) error {
|
||||
f.f.glBindRenderbuffer = must("glBindRenderbuffer")
|
||||
f.f.glBindTexture = must("glBindTexture")
|
||||
f.f.glBlendEquation = must("glBlendEquation")
|
||||
f.f.glBlendFunc = must("glBlendFunc")
|
||||
f.f.glBlendFuncSeparate = must("glBlendFuncSeparate")
|
||||
f.f.glBufferData = must("glBufferData")
|
||||
f.f.glBufferSubData = must("glBufferSubData")
|
||||
f.f.glCheckFramebufferStatus = must("glCheckFramebufferStatus")
|
||||
@@ -606,6 +630,7 @@ func (f *Functions) load(forceES bool) error {
|
||||
f.f.glGetError = must("glGetError")
|
||||
f.f.glGetFramebufferAttachmentParameteriv = must("glGetFramebufferAttachmentParameteriv")
|
||||
f.f.glGetIntegerv = must("glGetIntegerv")
|
||||
f.f.glGetFloatv = must("glGetFloatv")
|
||||
f.f.glGetProgramiv = must("glGetProgramiv")
|
||||
f.f.glGetProgramInfoLog = must("glGetProgramInfoLog")
|
||||
f.f.glGetRenderbufferParameteriv = must("glGetRenderbufferParameteriv")
|
||||
@@ -613,6 +638,8 @@ func (f *Functions) load(forceES bool) error {
|
||||
f.f.glGetShaderInfoLog = must("glGetShaderInfoLog")
|
||||
f.f.glGetString = must("glGetString")
|
||||
f.f.glGetUniformLocation = must("glGetUniformLocation")
|
||||
f.f.glGetVertexAttribiv = must("glGetVertexAttribiv")
|
||||
f.f.glGetVertexAttribPointerv = must("glGetVertexAttribPointerv")
|
||||
f.f.glIsEnabled = must("glIsEnabled")
|
||||
f.f.glLinkProgram = must("glLinkProgram")
|
||||
f.f.glPixelStorei = must("glPixelStorei")
|
||||
@@ -634,7 +661,8 @@ func (f *Functions) load(forceES bool) error {
|
||||
|
||||
// Extensions and GL ES 3 functions.
|
||||
f.f.glBindBufferBase = load("glBindBufferBase")
|
||||
f.f.glBindVertexArray = must("glBindVertexArray")
|
||||
f.f.glBindVertexArray = load("glBindVertexArray")
|
||||
f.f.glGetIntegeri_v = load("glGetIntegeri_v")
|
||||
f.f.glGetUniformBlockIndex = load("glGetUniformBlockIndex")
|
||||
f.f.glUniformBlockBinding = load("glUniformBlockBinding")
|
||||
f.f.glInvalidateFramebuffer = load("glInvalidateFramebuffer")
|
||||
@@ -733,8 +761,8 @@ func (f *Functions) BlendEquation(mode Enum) {
|
||||
C.glBlendEquation(&f.f, C.GLenum(mode))
|
||||
}
|
||||
|
||||
func (f *Functions) BlendFunc(sfactor, dfactor Enum) {
|
||||
C.glBlendFunc(&f.f, C.GLenum(sfactor), C.GLenum(dfactor))
|
||||
func (f *Functions) BlendFuncSeparate(srcRGB, dstRGB, srcA, dstA Enum) {
|
||||
C.glBlendFuncSeparate(&f.f, C.GLenum(srcRGB), C.GLenum(dstRGB), C.GLenum(srcA), C.GLenum(dstA))
|
||||
}
|
||||
|
||||
func (f *Functions) BlitFramebuffer(sx0, sy0, sx1, sy1, dx0, dy0, dx1, dy1 int, mask Enum, filter Enum) {
|
||||
@@ -917,6 +945,10 @@ func (c *Functions) GetBinding(pname Enum) Object {
|
||||
return Object{uint(c.GetInteger(pname))}
|
||||
}
|
||||
|
||||
func (c *Functions) GetBindingi(pname Enum, idx int) Object {
|
||||
return Object{uint(c.GetIntegeri(pname, idx))}
|
||||
}
|
||||
|
||||
func (f *Functions) GetError() Enum {
|
||||
return Enum(C.glGetError(&f.f))
|
||||
}
|
||||
@@ -931,6 +963,20 @@ func (f *Functions) GetFramebufferAttachmentParameteri(target, attachment, pname
|
||||
return int(f.ints[0])
|
||||
}
|
||||
|
||||
func (f *Functions) GetFloat4(pname Enum) [4]float32 {
|
||||
C.glGetFloatv(&f.f, C.GLenum(pname), &f.floats[0])
|
||||
var r [4]float32
|
||||
for i := range r {
|
||||
r[i] = float32(f.floats[i])
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func (f *Functions) GetFloat(pname Enum) float32 {
|
||||
C.glGetFloatv(&f.f, C.GLenum(pname), &f.floats[0])
|
||||
return float32(f.floats[0])
|
||||
}
|
||||
|
||||
func (f *Functions) GetInteger4(pname Enum) [4]int {
|
||||
C.glGetIntegerv(&f.f, C.GLenum(pname), &f.ints[0])
|
||||
var r [4]int
|
||||
@@ -945,6 +991,11 @@ func (f *Functions) GetInteger(pname Enum) int {
|
||||
return int(f.ints[0])
|
||||
}
|
||||
|
||||
func (f *Functions) GetIntegeri(pname Enum, idx int) int {
|
||||
C.glGetIntegeri_v(&f.f, C.GLenum(pname), C.GLuint(idx), &f.ints[0])
|
||||
return int(f.ints[0])
|
||||
}
|
||||
|
||||
func (f *Functions) GetProgrami(p Program, pname Enum) int {
|
||||
C.glGetProgramiv(&f.f, C.GLuint(p.V), C.GLenum(pname), &f.ints[0])
|
||||
return int(f.ints[0])
|
||||
@@ -1023,6 +1074,20 @@ func (f *Functions) GetUniformLocation(p Program, name string) Uniform {
|
||||
return Uniform{int(C.glGetUniformLocation(&f.f, C.GLuint(p.V), cname))}
|
||||
}
|
||||
|
||||
func (f *Functions) GetVertexAttrib(index int, pname Enum) int {
|
||||
C.glGetVertexAttribiv(&f.f, C.GLuint(index), C.GLenum(pname), &f.ints[0])
|
||||
return int(f.ints[0])
|
||||
}
|
||||
|
||||
func (f *Functions) GetVertexAttribBinding(index int, pname Enum) Object {
|
||||
return Object{uint(f.GetVertexAttrib(index, pname))}
|
||||
}
|
||||
|
||||
func (f *Functions) GetVertexAttribPointer(index int, pname Enum) uintptr {
|
||||
ptr := C.glGetVertexAttribPointerv(&f.f, C.GLuint(index), C.GLenum(pname))
|
||||
return uintptr(ptr)
|
||||
}
|
||||
|
||||
func (f *Functions) InvalidateFramebuffer(target, attachment Enum) {
|
||||
C.glInvalidateFramebuffer(&f.f, C.GLenum(target), C.GLenum(attachment))
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ var (
|
||||
_glBindTexture = LibGLESv2.NewProc("glBindTexture")
|
||||
_glBindVertexArray = LibGLESv2.NewProc("glBindVertexArray")
|
||||
_glBlendEquation = LibGLESv2.NewProc("glBlendEquation")
|
||||
_glBlendFunc = LibGLESv2.NewProc("glBlendFunc")
|
||||
_glBlendFuncSeparate = LibGLESv2.NewProc("glBlendFuncSeparate")
|
||||
_glBufferData = LibGLESv2.NewProc("glBufferData")
|
||||
_glBufferSubData = LibGLESv2.NewProc("glBufferSubData")
|
||||
_glCheckFramebufferStatus = LibGLESv2.NewProc("glCheckFramebufferStatus")
|
||||
@@ -64,8 +64,10 @@ var (
|
||||
_glGenQueries = LibGLESv2.NewProc("glGenQueries")
|
||||
_glGetError = LibGLESv2.NewProc("glGetError")
|
||||
_glGetRenderbufferParameteriv = LibGLESv2.NewProc("glGetRenderbufferParameteriv")
|
||||
_glGetFloatv = LibGLESv2.NewProc("glGetFloatv")
|
||||
_glGetFramebufferAttachmentParameteriv = LibGLESv2.NewProc("glGetFramebufferAttachmentParameteriv")
|
||||
_glGetIntegerv = LibGLESv2.NewProc("glGetIntegerv")
|
||||
_glGetIntegeri_v = LibGLESv2.NewProc("glGetIntegeri_v")
|
||||
_glGetProgramiv = LibGLESv2.NewProc("glGetProgramiv")
|
||||
_glGetProgramInfoLog = LibGLESv2.NewProc("glGetProgramInfoLog")
|
||||
_glGetQueryObjectuiv = LibGLESv2.NewProc("glGetQueryObjectuiv")
|
||||
@@ -73,6 +75,8 @@ var (
|
||||
_glGetShaderInfoLog = LibGLESv2.NewProc("glGetShaderInfoLog")
|
||||
_glGetString = LibGLESv2.NewProc("glGetString")
|
||||
_glGetUniformLocation = LibGLESv2.NewProc("glGetUniformLocation")
|
||||
_glGetVertexAttribiv = LibGLESv2.NewProc("glGetVertexAttribiv")
|
||||
_glGetVertexAttribPointerv = LibGLESv2.NewProc("glGetVertexAttribPointerv")
|
||||
_glInvalidateFramebuffer = LibGLESv2.NewProc("glInvalidateFramebuffer")
|
||||
_glIsEnabled = LibGLESv2.NewProc("glIsEnabled")
|
||||
_glLinkProgram = LibGLESv2.NewProc("glLinkProgram")
|
||||
@@ -98,7 +102,9 @@ var (
|
||||
|
||||
type Functions struct {
|
||||
// Query caches.
|
||||
int32s [100]int32
|
||||
int32s [100]int32
|
||||
float32s [100]float32
|
||||
uintptrs [100]uintptr
|
||||
}
|
||||
|
||||
type Context interface{}
|
||||
@@ -149,8 +155,8 @@ func (c *Functions) BindVertexArray(a VertexArray) {
|
||||
func (c *Functions) BlendEquation(mode Enum) {
|
||||
syscall.Syscall(_glBlendEquation.Addr(), 1, uintptr(mode), 0, 0)
|
||||
}
|
||||
func (c *Functions) BlendFunc(sfactor, dfactor Enum) {
|
||||
syscall.Syscall(_glBlendFunc.Addr(), 2, uintptr(sfactor), uintptr(dfactor), 0)
|
||||
func (c *Functions) BlendFuncSeparate(srcRGB, dstRGB, srcA, dstA Enum) {
|
||||
syscall.Syscall6(_glBlendFuncSeparate.Addr(), 4, uintptr(srcRGB), uintptr(dstRGB), uintptr(srcA), uintptr(dstA), 0, 0)
|
||||
}
|
||||
func (f *Functions) BlitFramebuffer(sx0, sy0, sx1, sy1, dx0, dy0, dx1, dy1 int, mask Enum, filter Enum) {
|
||||
panic("not implemented")
|
||||
@@ -299,6 +305,9 @@ func (f *Functions) GetUniformBlockIndex(p Program, name string) uint {
|
||||
func (c *Functions) GetBinding(pname Enum) Object {
|
||||
return Object{uint(c.GetInteger(pname))}
|
||||
}
|
||||
func (c *Functions) GetBindingi(pname Enum, idx int) Object {
|
||||
return Object{uint(c.GetIntegeri(pname, idx))}
|
||||
}
|
||||
func (c *Functions) GetError() Enum {
|
||||
e, _, _ := syscall.Syscall(_glGetError.Addr(), 0, 0, 0, 0)
|
||||
return Enum(e)
|
||||
@@ -323,6 +332,20 @@ func (c *Functions) GetInteger(pname Enum) int {
|
||||
syscall.Syscall(_glGetIntegerv.Addr(), 2, uintptr(pname), uintptr(unsafe.Pointer(&c.int32s[0])), 0)
|
||||
return int(c.int32s[0])
|
||||
}
|
||||
func (c *Functions) GetIntegeri(pname Enum, idx int) int {
|
||||
syscall.Syscall(_glGetIntegeri_v.Addr(), 3, uintptr(pname), uintptr(idx), uintptr(unsafe.Pointer(&c.int32s[0])))
|
||||
return int(c.int32s[0])
|
||||
}
|
||||
func (c *Functions) GetFloat(pname Enum) float32 {
|
||||
syscall.Syscall(_glGetFloatv.Addr(), 2, uintptr(pname), uintptr(unsafe.Pointer(&c.float32s[0])), 0)
|
||||
return c.float32s[0]
|
||||
}
|
||||
func (c *Functions) GetFloat4(pname Enum) [4]float32 {
|
||||
syscall.Syscall(_glGetFloatv.Addr(), 2, uintptr(pname), uintptr(unsafe.Pointer(&c.float32s[0])), 0)
|
||||
var r [4]float32
|
||||
copy(r[:], c.float32s[:])
|
||||
return r
|
||||
}
|
||||
func (c *Functions) GetProgrami(p Program, pname Enum) int {
|
||||
syscall.Syscall(_glGetProgramiv.Addr(), 3, uintptr(p.V), uintptr(pname), uintptr(unsafe.Pointer(&c.int32s[0])))
|
||||
return int(c.int32s[0])
|
||||
@@ -358,6 +381,19 @@ func (c *Functions) GetUniformLocation(p Program, name string) Uniform {
|
||||
issue34474KeepAlive(c0)
|
||||
return Uniform{int(u)}
|
||||
}
|
||||
func (c *Functions) GetVertexAttrib(index int, pname Enum) int {
|
||||
syscall.Syscall(_glGetVertexAttribiv.Addr(), 3, uintptr(index), uintptr(pname), uintptr(unsafe.Pointer(&c.int32s[0])))
|
||||
return int(c.int32s[0])
|
||||
}
|
||||
|
||||
func (c *Functions) GetVertexAttribBinding(index int, pname Enum) Object {
|
||||
return Object{uint(c.GetVertexAttrib(index, pname))}
|
||||
}
|
||||
|
||||
func (c *Functions) GetVertexAttribPointer(index int, pname Enum) uintptr {
|
||||
syscall.Syscall(_glGetVertexAttribPointerv.Addr(), 3, uintptr(index), uintptr(pname), uintptr(unsafe.Pointer(&c.uintptrs[0])))
|
||||
return c.uintptrs[0]
|
||||
}
|
||||
func (c *Functions) InvalidateFramebuffer(target, attachment Enum) {
|
||||
addr := _glInvalidateFramebuffer.Addr()
|
||||
if addr == 0 {
|
||||
|
||||
+53
-13
@@ -3,20 +3,28 @@
|
||||
package gl
|
||||
|
||||
type (
|
||||
Buffer struct{ V uint }
|
||||
Framebuffer struct{ V uint }
|
||||
Program struct{ V uint }
|
||||
Renderbuffer struct{ V uint }
|
||||
Shader struct{ V uint }
|
||||
Texture struct{ V uint }
|
||||
Query struct{ V uint }
|
||||
Uniform struct{ V int }
|
||||
VertexArray struct{ V uint }
|
||||
Object struct{ V uint }
|
||||
Buffer Object
|
||||
Framebuffer Object
|
||||
Program Object
|
||||
Renderbuffer Object
|
||||
Shader Object
|
||||
Texture Object
|
||||
Query Object
|
||||
Uniform struct{ V int }
|
||||
VertexArray Object
|
||||
)
|
||||
|
||||
func (o Object) valid() bool {
|
||||
return o.V != 0
|
||||
}
|
||||
|
||||
func (o Object) equal(o2 Object) bool {
|
||||
return o == o2
|
||||
}
|
||||
|
||||
func (u Framebuffer) Valid() bool {
|
||||
return u.V != 0
|
||||
return Object(u).valid()
|
||||
}
|
||||
|
||||
func (u Uniform) Valid() bool {
|
||||
@@ -24,13 +32,45 @@ func (u Uniform) Valid() bool {
|
||||
}
|
||||
|
||||
func (p Program) Valid() bool {
|
||||
return p.V != 0
|
||||
return Object(p).valid()
|
||||
}
|
||||
|
||||
func (s Shader) Valid() bool {
|
||||
return s.V != 0
|
||||
return Object(s).valid()
|
||||
}
|
||||
|
||||
func (a VertexArray) Valid() bool {
|
||||
return a.V != 0
|
||||
return Object(a).valid()
|
||||
}
|
||||
|
||||
func (f Framebuffer) Equal(f2 Framebuffer) bool {
|
||||
return Object(f).equal(Object(f2))
|
||||
}
|
||||
|
||||
func (p Program) Equal(p2 Program) bool {
|
||||
return Object(p).equal(Object(p2))
|
||||
}
|
||||
|
||||
func (s Shader) Equal(s2 Shader) bool {
|
||||
return Object(s).equal(Object(s2))
|
||||
}
|
||||
|
||||
func (u Uniform) Equal(u2 Uniform) bool {
|
||||
return u == u2
|
||||
}
|
||||
|
||||
func (a VertexArray) Equal(a2 VertexArray) bool {
|
||||
return Object(a).equal(Object(a2))
|
||||
}
|
||||
|
||||
func (r Renderbuffer) Equal(r2 Renderbuffer) bool {
|
||||
return Object(r).equal(Object(r2))
|
||||
}
|
||||
|
||||
func (t Texture) Equal(t2 Texture) bool {
|
||||
return Object(t).equal(Object(t2))
|
||||
}
|
||||
|
||||
func (b Buffer) Equal(b2 Buffer) bool {
|
||||
return Object(b).equal(Object(b2))
|
||||
}
|
||||
|
||||
+66
-14
@@ -5,34 +5,86 @@ package gl
|
||||
import "syscall/js"
|
||||
|
||||
type (
|
||||
Buffer js.Value
|
||||
Framebuffer js.Value
|
||||
Program js.Value
|
||||
Renderbuffer js.Value
|
||||
Shader js.Value
|
||||
Texture js.Value
|
||||
Query js.Value
|
||||
Uniform js.Value
|
||||
VertexArray js.Value
|
||||
Object js.Value
|
||||
Buffer Object
|
||||
Framebuffer Object
|
||||
Program Object
|
||||
Renderbuffer Object
|
||||
Shader Object
|
||||
Texture Object
|
||||
Query Object
|
||||
Uniform Object
|
||||
VertexArray Object
|
||||
)
|
||||
|
||||
func (o Object) valid() bool {
|
||||
return js.Value(o).Truthy()
|
||||
}
|
||||
|
||||
func (o Object) equal(o2 Object) bool {
|
||||
return js.Value(o).Equal(js.Value(o2))
|
||||
}
|
||||
|
||||
func (b Buffer) Valid() bool {
|
||||
return Object(b).valid()
|
||||
}
|
||||
|
||||
func (f Framebuffer) Valid() bool {
|
||||
return !js.Value(f).IsUndefined() && !js.Value(f).IsNull()
|
||||
return Object(f).valid()
|
||||
}
|
||||
|
||||
func (p Program) Valid() bool {
|
||||
return !js.Value(p).IsUndefined() && !js.Value(p).IsNull()
|
||||
return Object(p).valid()
|
||||
}
|
||||
|
||||
func (r Renderbuffer) Valid() bool {
|
||||
return Object(r).valid()
|
||||
}
|
||||
|
||||
func (s Shader) Valid() bool {
|
||||
return !js.Value(s).IsUndefined() && !js.Value(s).IsNull()
|
||||
return Object(s).valid()
|
||||
}
|
||||
|
||||
func (t Texture) Valid() bool {
|
||||
return Object(t).valid()
|
||||
}
|
||||
|
||||
func (u Uniform) Valid() bool {
|
||||
return !js.Value(u).IsUndefined() && !js.Value(u).IsNull()
|
||||
return Object(u).valid()
|
||||
}
|
||||
|
||||
func (a VertexArray) Valid() bool {
|
||||
return !js.Value(a).IsUndefined() && !js.Value(a).IsNull()
|
||||
return Object(a).valid()
|
||||
}
|
||||
|
||||
func (f Framebuffer) Equal(f2 Framebuffer) bool {
|
||||
return Object(f).equal(Object(f2))
|
||||
}
|
||||
|
||||
func (p Program) Equal(p2 Program) bool {
|
||||
return Object(p).equal(Object(p2))
|
||||
}
|
||||
|
||||
func (s Shader) Equal(s2 Shader) bool {
|
||||
return Object(s).equal(Object(s2))
|
||||
}
|
||||
|
||||
func (u Uniform) Equal(u2 Uniform) bool {
|
||||
return Object(u).equal(Object(u2))
|
||||
}
|
||||
|
||||
func (a VertexArray) Equal(a2 VertexArray) bool {
|
||||
return Object(a).equal(Object(a2))
|
||||
}
|
||||
|
||||
func (r Renderbuffer) Equal(r2 Renderbuffer) bool {
|
||||
return Object(r).equal(Object(r2))
|
||||
}
|
||||
|
||||
func (t Texture) Equal(t2 Texture) bool {
|
||||
return Object(t).equal(Object(t2))
|
||||
}
|
||||
|
||||
func (b Buffer) Equal(b2 Buffer) bool {
|
||||
return Object(b).equal(Object(b2))
|
||||
}
|
||||
|
||||
@@ -1,195 +0,0 @@
|
||||
// SPDX-License-Identifier: Unlicense OR MIT
|
||||
|
||||
package srgb
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"image"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"gioui.org/internal/byteslice"
|
||||
"gioui.org/internal/gl"
|
||||
)
|
||||
|
||||
// FBO implements an intermediate sRGB FBO
|
||||
// for gamma-correct rendering on platforms without
|
||||
// sRGB enabled native framebuffers.
|
||||
type FBO struct {
|
||||
c *gl.Functions
|
||||
viewport image.Point
|
||||
srgbBuffer gl.Framebuffer
|
||||
depthBuffer gl.Renderbuffer
|
||||
colorTex gl.Texture
|
||||
blitted bool
|
||||
quad gl.Buffer
|
||||
prog gl.Program
|
||||
gl3 bool
|
||||
}
|
||||
|
||||
func New(f *gl.Functions) (*FBO, error) {
|
||||
var gl3 bool
|
||||
glVer := f.GetString(gl.VERSION)
|
||||
ver, _, err := gl.ParseGLVersion(glVer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ver[0] >= 3 {
|
||||
gl3 = true
|
||||
} else {
|
||||
exts := f.GetString(gl.EXTENSIONS)
|
||||
if !strings.Contains(exts, "EXT_sRGB") {
|
||||
return nil, fmt.Errorf("no support for OpenGL ES 3 nor EXT_sRGB")
|
||||
}
|
||||
}
|
||||
s := &FBO{
|
||||
c: f,
|
||||
gl3: gl3,
|
||||
srgbBuffer: f.CreateFramebuffer(),
|
||||
colorTex: f.CreateTexture(),
|
||||
depthBuffer: f.CreateRenderbuffer(),
|
||||
}
|
||||
f.BindTexture(gl.TEXTURE_2D, s.colorTex)
|
||||
f.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
|
||||
f.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
|
||||
f.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
|
||||
f.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (s *FBO) Blit() {
|
||||
if !s.blitted {
|
||||
prog, err := gl.CreateProgram(s.c, blitVSrc, blitFSrc, []string{"pos", "uv"})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
s.prog = prog
|
||||
s.c.UseProgram(prog)
|
||||
s.c.Uniform1i(s.c.GetUniformLocation(prog, "tex"), 0)
|
||||
s.quad = s.c.CreateBuffer()
|
||||
s.c.BindBuffer(gl.ARRAY_BUFFER, s.quad)
|
||||
coords := byteslice.Slice([]float32{
|
||||
-1, +1, 0, 1,
|
||||
+1, +1, 1, 1,
|
||||
-1, -1, 0, 0,
|
||||
+1, -1, 1, 0,
|
||||
})
|
||||
s.c.BufferData(gl.ARRAY_BUFFER, len(coords), gl.STATIC_DRAW)
|
||||
s.c.BufferSubData(gl.ARRAY_BUFFER, 0, coords)
|
||||
s.blitted = true
|
||||
}
|
||||
s.c.UseProgram(s.prog)
|
||||
s.c.BindTexture(gl.TEXTURE_2D, s.colorTex)
|
||||
s.c.BindBuffer(gl.ARRAY_BUFFER, s.quad)
|
||||
s.c.VertexAttribPointer(0 /* pos */, 2, gl.FLOAT, false, 4*4, 0)
|
||||
s.c.VertexAttribPointer(1 /* uv */, 2, gl.FLOAT, false, 4*4, 4*2)
|
||||
s.c.EnableVertexAttribArray(0)
|
||||
s.c.EnableVertexAttribArray(1)
|
||||
s.c.DrawArrays(gl.TRIANGLE_STRIP, 0, 4)
|
||||
s.c.BindTexture(gl.TEXTURE_2D, gl.Texture{})
|
||||
s.c.DisableVertexAttribArray(0)
|
||||
s.c.DisableVertexAttribArray(1)
|
||||
s.c.BindFramebuffer(gl.FRAMEBUFFER, s.srgbBuffer)
|
||||
s.c.InvalidateFramebuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0)
|
||||
s.c.InvalidateFramebuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT)
|
||||
}
|
||||
|
||||
func (s *FBO) Framebuffer() gl.Framebuffer {
|
||||
return s.srgbBuffer
|
||||
}
|
||||
|
||||
func (s *FBO) Refresh(viewport image.Point) error {
|
||||
if viewport.X == 0 || viewport.Y == 0 {
|
||||
return errors.New("srgb: zero-sized framebuffer")
|
||||
}
|
||||
if s.viewport == viewport {
|
||||
return nil
|
||||
}
|
||||
s.viewport = viewport
|
||||
s.c.BindTexture(gl.TEXTURE_2D, s.colorTex)
|
||||
if s.gl3 {
|
||||
s.c.TexImage2D(gl.TEXTURE_2D, 0, gl.SRGB8_ALPHA8, viewport.X, viewport.Y, gl.RGBA, gl.UNSIGNED_BYTE)
|
||||
} else /* EXT_sRGB */ {
|
||||
s.c.TexImage2D(gl.TEXTURE_2D, 0, gl.SRGB_ALPHA_EXT, viewport.X, viewport.Y, gl.SRGB_ALPHA_EXT, gl.UNSIGNED_BYTE)
|
||||
}
|
||||
currentRB := gl.Renderbuffer(s.c.GetBinding(gl.RENDERBUFFER_BINDING))
|
||||
s.c.BindRenderbuffer(gl.RENDERBUFFER, s.depthBuffer)
|
||||
s.c.RenderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, viewport.X, viewport.Y)
|
||||
s.c.BindRenderbuffer(gl.RENDERBUFFER, currentRB)
|
||||
s.c.BindFramebuffer(gl.FRAMEBUFFER, s.srgbBuffer)
|
||||
s.c.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, s.colorTex, 0)
|
||||
s.c.FramebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, s.depthBuffer)
|
||||
if st := s.c.CheckFramebufferStatus(gl.FRAMEBUFFER); st != gl.FRAMEBUFFER_COMPLETE {
|
||||
return fmt.Errorf("sRGB framebuffer incomplete (%dx%d), status: %#x error: %x", viewport.X, viewport.Y, st, s.c.GetError())
|
||||
}
|
||||
|
||||
if runtime.GOOS == "js" {
|
||||
// With macOS Safari, rendering to and then reading from a SRGB8_ALPHA8
|
||||
// texture result in twice gamma corrected colors. Using a plain RGBA
|
||||
// texture seems to work.
|
||||
s.c.ClearColor(.5, .5, .5, 1.0)
|
||||
s.c.Clear(gl.COLOR_BUFFER_BIT)
|
||||
var pixel [4]byte
|
||||
s.c.ReadPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixel[:])
|
||||
if pixel[0] == 128 { // Correct sRGB color value is ~188
|
||||
s.c.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, viewport.X, viewport.Y, gl.RGBA, gl.UNSIGNED_BYTE)
|
||||
if st := s.c.CheckFramebufferStatus(gl.FRAMEBUFFER); st != gl.FRAMEBUFFER_COMPLETE {
|
||||
return fmt.Errorf("fallback RGBA framebuffer incomplete (%dx%d), status: %#x error: %x", viewport.X, viewport.Y, st, s.c.GetError())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *FBO) Release() {
|
||||
s.c.DeleteFramebuffer(s.srgbBuffer)
|
||||
s.c.DeleteTexture(s.colorTex)
|
||||
s.c.DeleteRenderbuffer(s.depthBuffer)
|
||||
if s.blitted {
|
||||
s.c.DeleteBuffer(s.quad)
|
||||
s.c.DeleteProgram(s.prog)
|
||||
}
|
||||
s.c = nil
|
||||
}
|
||||
|
||||
const (
|
||||
blitVSrc = `
|
||||
#version 100
|
||||
|
||||
precision highp float;
|
||||
|
||||
attribute vec2 pos;
|
||||
attribute vec2 uv;
|
||||
|
||||
varying vec2 vUV;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(pos, 0, 1);
|
||||
vUV = uv;
|
||||
}
|
||||
`
|
||||
blitFSrc = `
|
||||
#version 100
|
||||
|
||||
precision mediump float;
|
||||
|
||||
uniform sampler2D tex;
|
||||
varying vec2 vUV;
|
||||
|
||||
vec3 gamma(vec3 rgb) {
|
||||
vec3 exp = vec3(1.055)*pow(rgb, vec3(0.41666)) - vec3(0.055);
|
||||
vec3 lin = rgb * vec3(12.92);
|
||||
bvec3 cut = lessThan(rgb, vec3(0.0031308));
|
||||
return vec3(cut.r ? lin.r : exp.r, cut.g ? lin.g : exp.g, cut.b ? lin.b : exp.b);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 col = texture2D(tex, vUV);
|
||||
vec3 rgb = col.rgb;
|
||||
rgb = gamma(rgb);
|
||||
gl_FragColor = vec4(rgb, col.a);
|
||||
}
|
||||
`
|
||||
)
|
||||
Reference in New Issue
Block a user