all: rename the gioui.org/ui module to gioui.org

The "ui" is redundant and stutters.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2019-09-30 12:27:55 +02:00
parent ce74bc0cba
commit 22cd88df9f
102 changed files with 93 additions and 93 deletions
+462
View File
@@ -0,0 +1,462 @@
// SPDX-License-Identifier: Unlicense OR MIT
// +build darwin linux
package gl
import (
"unsafe"
)
/*
#cgo linux LDFLAGS: -lGLESv2 -ldl
#cgo darwin,!ios LDFLAGS: -framework OpenGL
#include <stdlib.h>
#ifdef __APPLE__
#cgo CFLAGS: -DGL_SILENCE_DEPRECATION
#include "TargetConditionals.h"
#if TARGET_OS_IPHONE
#include <OpenGLES/ES3/gl.h>
#else
#include <OpenGL/gl3.h>
#endif
#else
#define __USE_GNU
#include <dlfcn.h>
#include <GLES2/gl2.h>
#include <GLES3/gl3.h>
#endif
static void (*_glInvalidateFramebuffer)(GLenum target, GLsizei numAttachments, const GLenum *attachments);
static void (*_glBeginQuery)(GLenum target, GLuint id);
static void (*_glDeleteQueries)(GLsizei n, const GLuint *ids);
static void (*_glEndQuery)(GLenum target);
static void (*_glGenQueries)(GLsizei n, GLuint *ids);
static void (*_glGetQueryObjectuiv)(GLuint id, GLenum pname, GLuint *params);
// The pointer-free version of glVertexAttribPointer, to avoid the Cgo pointer checks.
__attribute__ ((visibility ("hidden"))) void gio_glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, uintptr_t offset) {
glVertexAttribPointer(index, size, type, normalized, stride, (const GLvoid *)offset);
}
// The pointer-free version of glDrawElements, to avoid the Cgo pointer checks.
__attribute__ ((visibility ("hidden"))) void gio_glDrawElements(GLenum mode, GLsizei count, GLenum type, const uintptr_t offset) {
glDrawElements(mode, count, type, (const GLvoid *)offset);
}
__attribute__ ((visibility ("hidden"))) void gio_glInvalidateFramebuffer(GLenum target, GLenum attachment) {
// Framebuffer invalidation is just a hint and can safely be ignored.
if (_glInvalidateFramebuffer != NULL) {
_glInvalidateFramebuffer(target, 1, &attachment);
}
}
__attribute__ ((visibility ("hidden"))) void gio_glBeginQuery(GLenum target, GLenum attachment) {
_glBeginQuery(target, attachment);
}
__attribute__ ((visibility ("hidden"))) void gio_glDeleteQueries(GLsizei n, const GLuint *ids) {
_glDeleteQueries(n, ids);
}
__attribute__ ((visibility ("hidden"))) void gio_glEndQuery(GLenum target) {
_glEndQuery(target);
}
__attribute__ ((visibility ("hidden"))) void gio_glGenQueries(GLsizei n, GLuint *ids) {
_glGenQueries(n, ids);
}
__attribute__ ((visibility ("hidden"))) void gio_glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params) {
_glGetQueryObjectuiv(id, pname, params);
}
__attribute__((constructor)) static void gio_loadGLFunctions() {
#ifdef __APPLE__
#if TARGET_OS_IPHONE
_glInvalidateFramebuffer = glInvalidateFramebuffer;
_glBeginQuery = glBeginQuery;
_glDeleteQueries = glDeleteQueries;
_glEndQuery = glEndQuery;
_glGenQueries = glGenQueries;
_glGetQueryObjectuiv = glGetQueryObjectuiv;
#endif
#else
// Load libGLESv3 if available.
dlopen("libGLESv3.so", RTLD_NOW | RTLD_GLOBAL);
_glInvalidateFramebuffer = dlsym(RTLD_DEFAULT, "glInvalidateFramebuffer");
// Fall back to EXT_invalidate_framebuffer if available.
if (_glInvalidateFramebuffer == NULL) {
_glInvalidateFramebuffer = dlsym(RTLD_DEFAULT, "glDiscardFramebufferEXT");
}
_glBeginQuery = dlsym(RTLD_DEFAULT, "glBeginQuery");
if (_glBeginQuery == NULL)
_glBeginQuery = dlsym(RTLD_DEFAULT, "glBeginQueryEXT");
_glDeleteQueries = dlsym(RTLD_DEFAULT, "glDeleteQueries");
if (_glDeleteQueries == NULL)
_glDeleteQueries = dlsym(RTLD_DEFAULT, "glDeleteQueriesEXT");
_glEndQuery = dlsym(RTLD_DEFAULT, "glEndQuery");
if (_glEndQuery == NULL)
_glEndQuery = dlsym(RTLD_DEFAULT, "glEndQueryEXT");
_glGenQueries = dlsym(RTLD_DEFAULT, "glGenQueries");
if (_glGenQueries == NULL)
_glGenQueries = dlsym(RTLD_DEFAULT, "glGenQueriesEXT");
_glGetQueryObjectuiv = dlsym(RTLD_DEFAULT, "glGetQueryObjectuiv");
if (_glGetQueryObjectuiv == NULL)
_glGetQueryObjectuiv = dlsym(RTLD_DEFAULT, "glGetQueryObjectuivEXT");
#endif
}
*/
import "C"
type Functions struct {
// Query caches.
uints [100]C.GLuint
ints [100]C.GLint
}
func (f *Functions) ActiveTexture(texture Enum) {
C.glActiveTexture(C.GLenum(texture))
}
func (f *Functions) AttachShader(p Program, s Shader) {
C.glAttachShader(C.GLuint(p.V), C.GLuint(s.V))
}
func (f *Functions) BeginQuery(target Enum, query Query) {
C.gio_glBeginQuery(C.GLenum(target), C.GLenum(query.V))
}
func (f *Functions) BindAttribLocation(p Program, a Attrib, name string) {
cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))
C.glBindAttribLocation(C.GLuint(p.V), C.GLuint(a), cname)
}
func (f *Functions) BindBuffer(target Enum, b Buffer) {
C.glBindBuffer(C.GLenum(target), C.GLuint(b.V))
}
func (f *Functions) BindFramebuffer(target Enum, fb Framebuffer) {
C.glBindFramebuffer(C.GLenum(target), C.GLuint(fb.V))
}
func (f *Functions) BindRenderbuffer(target Enum, fb Renderbuffer) {
C.glBindRenderbuffer(C.GLenum(target), C.GLuint(fb.V))
}
func (f *Functions) BindTexture(target Enum, t Texture) {
C.glBindTexture(C.GLenum(target), C.GLuint(t.V))
}
func (f *Functions) BlendEquation(mode Enum) {
C.glBlendEquation(C.GLenum(mode))
}
func (f *Functions) BlendFunc(sfactor, dfactor Enum) {
C.glBlendFunc(C.GLenum(sfactor), C.GLenum(dfactor))
}
func (f *Functions) BufferData(target Enum, src []byte, usage Enum) {
var p unsafe.Pointer
if len(src) > 0 {
p = unsafe.Pointer(&src[0])
}
C.glBufferData(C.GLenum(target), C.GLsizeiptr(len(src)), p, C.GLenum(usage))
}
func (f *Functions) CheckFramebufferStatus(target Enum) Enum {
return Enum(C.glCheckFramebufferStatus(C.GLenum(target)))
}
func (f *Functions) Clear(mask Enum) {
C.glClear(C.GLbitfield(mask))
}
func (f *Functions) ClearColor(red float32, green float32, blue float32, alpha float32) {
C.glClearColor(C.GLfloat(red), C.GLfloat(green), C.GLfloat(blue), C.GLfloat(alpha))
}
func (f *Functions) ClearDepthf(d float32) {
C.glClearDepthf(C.GLfloat(d))
}
func (f *Functions) CompileShader(s Shader) {
C.glCompileShader(C.GLuint(s.V))
}
func (f *Functions) CreateBuffer() Buffer {
C.glGenBuffers(1, &f.uints[0])
return Buffer{uint(f.uints[0])}
}
func (f *Functions) CreateFramebuffer() Framebuffer {
C.glGenFramebuffers(1, &f.uints[0])
return Framebuffer{uint(f.uints[0])}
}
func (f *Functions) CreateProgram() Program {
return Program{uint(C.glCreateProgram())}
}
func (f *Functions) CreateQuery() Query {
C.gio_glGenQueries(1, &f.uints[0])
return Query{uint(f.uints[0])}
}
func (f *Functions) CreateRenderbuffer() Renderbuffer {
C.glGenRenderbuffers(1, &f.uints[0])
return Renderbuffer{uint(f.uints[0])}
}
func (f *Functions) CreateShader(ty Enum) Shader {
return Shader{uint(C.glCreateShader(C.GLenum(ty)))}
}
func (f *Functions) CreateTexture() Texture {
C.glGenTextures(1, &f.uints[0])
return Texture{uint(f.uints[0])}
}
func (f *Functions) DeleteBuffer(v Buffer) {
f.uints[0] = C.GLuint(v.V)
C.glDeleteBuffers(1, &f.uints[0])
}
func (f *Functions) DeleteFramebuffer(v Framebuffer) {
f.uints[0] = C.GLuint(v.V)
C.glDeleteFramebuffers(1, &f.uints[0])
}
func (f *Functions) DeleteProgram(p Program) {
C.glDeleteProgram(C.GLuint(p.V))
}
func (f *Functions) DeleteQuery(query Query) {
f.uints[0] = C.GLuint(query.V)
C.gio_glDeleteQueries(1, &f.uints[0])
}
func (f *Functions) DeleteRenderbuffer(v Renderbuffer) {
f.uints[0] = C.GLuint(v.V)
C.glDeleteRenderbuffers(1, &f.uints[0])
}
func (f *Functions) DeleteShader(s Shader) {
C.glDeleteShader(C.GLuint(s.V))
}
func (f *Functions) DeleteTexture(v Texture) {
f.uints[0] = C.GLuint(v.V)
C.glDeleteTextures(1, &f.uints[0])
}
func (f *Functions) DepthFunc(v Enum) {
C.glDepthFunc(C.GLenum(v))
}
func (f *Functions) DepthMask(mask bool) {
m := C.GLboolean(C.GL_FALSE)
if mask {
m = C.GLboolean(C.GL_TRUE)
}
C.glDepthMask(m)
}
func (f *Functions) DisableVertexAttribArray(a Attrib) {
C.glDisableVertexAttribArray(C.GLuint(a))
}
func (f *Functions) Disable(cap Enum) {
C.glDisable(C.GLenum(cap))
}
func (f *Functions) DrawArrays(mode Enum, first int, count int) {
C.glDrawArrays(C.GLenum(mode), C.GLint(first), C.GLsizei(count))
}
func (f *Functions) DrawElements(mode Enum, count int, ty Enum, offset int) {
C.gio_glDrawElements(C.GLenum(mode), C.GLsizei(count), C.GLenum(ty), C.uintptr_t(offset))
}
func (f *Functions) Enable(cap Enum) {
C.glEnable(C.GLenum(cap))
}
func (f *Functions) EndQuery(target Enum) {
C.gio_glEndQuery(C.GLenum(target))
}
func (f *Functions) EnableVertexAttribArray(a Attrib) {
C.glEnableVertexAttribArray(C.GLuint(a))
}
func (f *Functions) Finish() {
C.glFinish()
}
func (f *Functions) FramebufferRenderbuffer(target, attachment, renderbuffertarget Enum, renderbuffer Renderbuffer) {
C.glFramebufferRenderbuffer(C.GLenum(target), C.GLenum(attachment), C.GLenum(renderbuffertarget), C.GLuint(renderbuffer.V))
}
func (f *Functions) FramebufferTexture2D(target, attachment, texTarget Enum, t Texture, level int) {
C.glFramebufferTexture2D(C.GLenum(target), C.GLenum(attachment), C.GLenum(texTarget), C.GLuint(t.V), C.GLint(level))
}
func (c *Functions) GetBinding(pname Enum) Object {
return Object{uint(c.GetInteger(pname))}
}
func (f *Functions) GetError() Enum {
return Enum(C.glGetError())
}
func (f *Functions) GetRenderbufferParameteri(target, pname Enum) int {
C.glGetRenderbufferParameteriv(C.GLenum(target), C.GLenum(pname), &f.ints[0])
return int(f.ints[0])
}
func (f *Functions) GetFramebufferAttachmentParameteri(target, attachment, pname Enum) int {
C.glGetFramebufferAttachmentParameteriv(C.GLenum(target), C.GLenum(attachment), C.GLenum(pname), &f.ints[0])
return int(f.ints[0])
}
func (f *Functions) GetInteger(pname Enum) int {
C.glGetIntegerv(C.GLenum(pname), &f.ints[0])
return int(f.ints[0])
}
func (f *Functions) GetProgrami(p Program, pname Enum) int {
C.glGetProgramiv(C.GLuint(p.V), C.GLenum(pname), &f.ints[0])
return int(f.ints[0])
}
func (f *Functions) GetProgramInfoLog(p Program) string {
n := f.GetProgrami(p, INFO_LOG_LENGTH)
buf := make([]byte, n)
C.glGetProgramInfoLog(C.GLuint(p.V), C.GLsizei(len(buf)), nil, (*C.GLchar)(unsafe.Pointer(&buf[0])))
return string(buf)
}
func (f *Functions) GetQueryObjectuiv(query Query, pname Enum) uint {
C.gio_glGetQueryObjectuiv(C.GLuint(query.V), C.GLenum(pname), &f.uints[0])
return uint(f.uints[0])
}
func (f *Functions) GetShaderi(s Shader, pname Enum) int {
C.glGetShaderiv(C.GLuint(s.V), C.GLenum(pname), &f.ints[0])
return int(f.ints[0])
}
func (f *Functions) GetShaderInfoLog(s Shader) string {
n := f.GetShaderi(s, INFO_LOG_LENGTH)
buf := make([]byte, n)
C.glGetShaderInfoLog(C.GLuint(s.V), C.GLsizei(len(buf)), nil, (*C.GLchar)(unsafe.Pointer(&buf[0])))
return string(buf)
}
func (f *Functions) GetString(pname Enum) string {
str := C.glGetString(C.GLenum(pname))
return C.GoString((*C.char)(unsafe.Pointer(str)))
}
func (f *Functions) GetUniformLocation(p Program, name string) Uniform {
cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))
return Uniform{int(C.glGetUniformLocation(C.GLuint(p.V), cname))}
}
func (f *Functions) InvalidateFramebuffer(target, attachment Enum) {
C.gio_glInvalidateFramebuffer(C.GLenum(target), C.GLenum(attachment))
}
func (f *Functions) LinkProgram(p Program) {
C.glLinkProgram(C.GLuint(p.V))
}
func (f *Functions) PixelStorei(pname Enum, param int32) {
C.glPixelStorei(C.GLenum(pname), C.GLint(param))
}
func (f *Functions) Scissor(x, y, width, height int32) {
C.glScissor(C.GLint(x), C.GLint(y), C.GLsizei(width), C.GLsizei(height))
}
func (f *Functions) ReadPixels(x, y, width, height int, format, ty Enum, data []byte) {
var p unsafe.Pointer
if len(data) > 0 {
p = unsafe.Pointer(&data[0])
}
C.glReadPixels(C.GLint(x), C.GLint(y), C.GLsizei(width), C.GLsizei(height), C.GLenum(format), C.GLenum(ty), p)
}
func (f *Functions) RenderbufferStorage(target, internalformat Enum, width, height int) {
C.glRenderbufferStorage(C.GLenum(target), C.GLenum(internalformat), C.GLsizei(width), C.GLsizei(height))
}
func (f *Functions) ShaderSource(s Shader, src string) {
csrc := C.CString(src)
defer C.free(unsafe.Pointer(csrc))
strlen := C.GLint(len(src))
C.glShaderSource(C.GLuint(s.V), 1, &csrc, &strlen)
}
func (f *Functions) TexImage2D(target Enum, level int, internalFormat int, width int, height int, format Enum, ty Enum, data []byte) {
var p unsafe.Pointer
if len(data) > 0 {
p = unsafe.Pointer(&data[0])
}
C.glTexImage2D(C.GLenum(target), C.GLint(level), C.GLint(internalFormat), C.GLsizei(width), C.GLsizei(height), 0, C.GLenum(format), C.GLenum(ty), p)
}
func (f *Functions) TexSubImage2D(target Enum, level int, x int, y int, width int, height int, format Enum, ty Enum, data []byte) {
var p unsafe.Pointer
if len(data) > 0 {
p = unsafe.Pointer(&data[0])
}
C.glTexSubImage2D(C.GLenum(target), C.GLint(level), C.GLint(x), C.GLint(y), C.GLsizei(width), C.GLsizei(height), C.GLenum(format), C.GLenum(ty), p)
}
func (f *Functions) TexParameteri(target, pname Enum, param int) {
C.glTexParameteri(C.GLenum(target), C.GLenum(pname), C.GLint(param))
}
func (f *Functions) Uniform1f(dst Uniform, v float32) {
C.glUniform1f(C.GLint(dst.V), C.GLfloat(v))
}
func (f *Functions) Uniform1i(dst Uniform, v int) {
C.glUniform1i(C.GLint(dst.V), C.GLint(v))
}
func (f *Functions) Uniform2f(dst Uniform, v0 float32, v1 float32) {
C.glUniform2f(C.GLint(dst.V), C.GLfloat(v0), C.GLfloat(v1))
}
func (f *Functions) Uniform3f(dst Uniform, v0 float32, v1 float32, v2 float32) {
C.glUniform3f(C.GLint(dst.V), C.GLfloat(v0), C.GLfloat(v1), C.GLfloat(v2))
}
func (f *Functions) Uniform4f(dst Uniform, v0 float32, v1 float32, v2 float32, v3 float32) {
C.glUniform4f(C.GLint(dst.V), C.GLfloat(v0), C.GLfloat(v1), C.GLfloat(v2), C.GLfloat(v3))
}
func (f *Functions) UseProgram(p Program) {
C.glUseProgram(C.GLuint(p.V))
}
func (f *Functions) VertexAttribPointer(dst Attrib, size int, ty Enum, normalized bool, stride int, offset int) {
var n C.GLboolean = C.GL_FALSE
if normalized {
n = C.GL_TRUE
}
C.gio_glVertexAttribPointer(C.GLuint(dst), C.GLint(size), C.GLenum(ty), n, C.GLsizei(stride), C.uintptr_t(offset))
}
func (f *Functions) Viewport(x int, y int, width int, height int) {
C.glViewport(C.GLint(x), C.GLint(y), C.GLsizei(width), C.GLsizei(height))
}
+164
View File
@@ -0,0 +1,164 @@
// SPDX-License-Identifier: Unlicense OR MIT
package gl
type (
Attrib uint
Enum uint
)
type Context interface {
Functions() *Functions
Present() error
MakeCurrent() error
Release()
Lock()
Unlock()
}
const (
ARRAY_BUFFER = 0x8892
BLEND = 0xbe2
CLAMP_TO_EDGE = 0x812f
COLOR_ATTACHMENT0 = 0x8ce0
COLOR_BUFFER_BIT = 0x4000
COMPILE_STATUS = 0x8b81
DEPTH_BUFFER_BIT = 0x100
DEPTH_ATTACHMENT = 0x8d00
DEPTH_COMPONENT16 = 0x81a5
DEPTH_TEST = 0xb71
DST_COLOR = 0x306
ELEMENT_ARRAY_BUFFER = 0x8893
EXTENSIONS = 0x1f03
FLOAT = 0x1406
FRAGMENT_SHADER = 0x8b30
FRAMEBUFFER = 0x8d40
FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING = 0x8210
FRAMEBUFFER_BINDING = 0x8ca6
FRAMEBUFFER_COMPLETE = 0x8cd5
HALF_FLOAT = 0x140b
HALF_FLOAT_OES = 0x8d61
INFO_LOG_LENGTH = 0x8B84
GREATER = 0x204
LINEAR = 0x2601
LINK_STATUS = 0x8b82
LUMINANCE = 0x1909
MAX_TEXTURE_SIZE = 0xd33
NEAREST = 0x2600
ONE = 0x1
ONE_MINUS_SRC_ALPHA = 0x303
QUERY_RESULT = 0x8866
QUERY_RESULT_AVAILABLE = 0x8867
R16F = 0x822d
R8 = 0x8229
READ_FRAMEBUFFER = 0x8ca8
RED = 0x1903
RENDERER = 0x1F01
RENDERBUFFER = 0x8d41
RENDERBUFFER_BINDING = 0x8ca7
RENDERBUFFER_HEIGHT = 0x8d43
RENDERBUFFER_WIDTH = 0x8d42
RGB = 0x1907
RGBA = 0x1908
RGBA8 = 0x8058
SHORT = 0x1402
SRGB = 0x8c40
SRGB_ALPHA_EXT = 0x8c42
SRGB8 = 0x8c41
SRGB8_ALPHA8 = 0x8c43
STATIC_DRAW = 0x88e4
TEXTURE_2D = 0xde1
TEXTURE_MAG_FILTER = 0x2800
TEXTURE_MIN_FILTER = 0x2801
TEXTURE_WRAP_S = 0x2802
TEXTURE_WRAP_T = 0x2803
TEXTURE0 = 0x84c0
TEXTURE1 = 0x84c1
TRIANGLE_STRIP = 0x5
TRIANGLES = 0x4
UNPACK_ALIGNMENT = 0xcf5
UNSIGNED_BYTE = 0x1401
UNSIGNED_SHORT = 0x1403
VERSION = 0x1f02
VERTEX_SHADER = 0x8b31
ZERO = 0x0
// EXT_disjoint_timer_query
TIME_ELAPSED_EXT = 0x88BF
GPU_DISJOINT_EXT = 0x8FBB
)
// Enforce Functions interface.
var _ interface {
ActiveTexture(texture Enum)
AttachShader(p Program, s Shader)
BeginQuery(target Enum, query Query)
BindAttribLocation(p Program, a Attrib, name string)
BindBuffer(target Enum, b Buffer)
BindFramebuffer(target Enum, fb Framebuffer)
BindRenderbuffer(target Enum, rb Renderbuffer)
BindTexture(target Enum, t Texture)
BlendEquation(mode Enum)
BlendFunc(sfactor, dfactor Enum)
BufferData(target Enum, src []byte, usage Enum)
CheckFramebufferStatus(target Enum) Enum
Clear(mask Enum)
ClearColor(red, green, blue, alpha float32)
ClearDepthf(d float32)
CompileShader(s Shader)
CreateBuffer() Buffer
CreateFramebuffer() Framebuffer
CreateProgram() Program
CreateQuery() Query
CreateRenderbuffer() Renderbuffer
CreateShader(ty Enum) Shader
CreateTexture() Texture
DeleteBuffer(v Buffer)
DeleteFramebuffer(v Framebuffer)
DeleteProgram(p Program)
DeleteQuery(query Query)
DeleteRenderbuffer(v Renderbuffer)
DeleteShader(s Shader)
DeleteTexture(v Texture)
DepthFunc(f Enum)
DepthMask(mask bool)
DisableVertexAttribArray(a Attrib)
Disable(cap Enum)
DrawArrays(mode Enum, first, count int)
DrawElements(mode Enum, count int, ty Enum, offset int)
Enable(cap Enum)
EnableVertexAttribArray(a Attrib)
EndQuery(target Enum)
Finish()
FramebufferRenderbuffer(target, attachment, renderbuffertarget Enum, renderbuffer Renderbuffer)
FramebufferTexture2D(target, attachment, texTarget Enum, t Texture, level int)
GetBinding(pname Enum) Object
GetError() Enum
GetRenderbufferParameteri(target, pname Enum) int
GetFramebufferAttachmentParameteri(target, attachment, pname Enum) int
GetInteger(pname Enum) int
GetProgrami(p Program, pname Enum) int
GetProgramInfoLog(p Program) string
GetQueryObjectuiv(query Query, pname Enum) uint
GetShaderi(s Shader, pname Enum) int
GetShaderInfoLog(s Shader) string
GetString(pname Enum) string
GetUniformLocation(p Program, name string) Uniform
InvalidateFramebuffer(target, attachment Enum)
LinkProgram(p Program)
PixelStorei(pname Enum, param int32)
RenderbufferStorage(target, internalformat Enum, width, height int)
Scissor(x, y, width, height int32)
ShaderSource(s Shader, src string)
TexImage2D(target Enum, level int, internalFormat int, width, height int, format, ty Enum, data []byte)
TexSubImage2D(target Enum, level int, x, y, width, height int, format, ty Enum, data []byte)
TexParameteri(target, pname Enum, param int)
Uniform1f(dst Uniform, v float32)
Uniform1i(dst Uniform, v int)
Uniform2f(dst Uniform, v0, v1 float32)
Uniform3f(dst Uniform, v0, v1, v2 float32)
Uniform4f(dst Uniform, v0, v1, v2, v3 float32)
UseProgram(p Program)
VertexAttribPointer(dst Attrib, size int, ty Enum, normalized bool, stride, offset int)
Viewport(x, y, width, height int)
} = (*Functions)(nil)
+328
View File
@@ -0,0 +1,328 @@
// SPDX-License-Identifier: Unlicense OR MIT
package gl
import (
"errors"
"strings"
"syscall/js"
)
type Functions struct {
Ctx js.Value
EXT_disjoint_timer_query js.Value
EXT_disjoint_timer_query_webgl2 js.Value
// Cached JS arrays.
byteBuf js.Value
int32Buf js.Value
}
func (f *Functions) Init(version int) error {
if version < 2 {
f.EXT_disjoint_timer_query = f.getExtension("EXT_disjoint_timer_query")
if f.getExtension("OES_texture_half_float") == js.Null() && f.getExtension("OES_texture_float") == js.Null() {
return errors.New("gl: no support for neither OES_texture_half_float nor OES_texture_float")
}
if f.getExtension("EXT_sRGB") == js.Null() {
return errors.New("gl: EXT_sRGB not supported")
}
} else {
// WebGL2 extensions.
f.EXT_disjoint_timer_query_webgl2 = f.getExtension("EXT_disjoint_timer_query_webgl2")
if f.getExtension("EXT_color_buffer_half_float") == js.Null() && f.getExtension("EXT_color_buffer_float") == js.Null() {
return errors.New("gl: no support for neither EXT_color_buffer_half_float nor EXT_color_buffer_float")
}
}
return nil
}
func (f *Functions) getExtension(name string) js.Value {
return f.Ctx.Call("getExtension", name)
}
func (f *Functions) ActiveTexture(t Enum) {
f.Ctx.Call("activeTexture", int(t))
}
func (f *Functions) AttachShader(p Program, s Shader) {
f.Ctx.Call("attachShader", js.Value(p), js.Value(s))
}
func (f *Functions) BeginQuery(target Enum, query Query) {
if f.EXT_disjoint_timer_query_webgl2 != js.Null() {
f.Ctx.Call("beginQuery", int(target), js.Value(query))
} else {
f.EXT_disjoint_timer_query.Call("beginQueryEXT", int(target), js.Value(query))
}
}
func (f *Functions) BindAttribLocation(p Program, a Attrib, name string) {
f.Ctx.Call("bindAttribLocation", js.Value(p), int(a), name)
}
func (f *Functions) BindBuffer(target Enum, b Buffer) {
f.Ctx.Call("bindBuffer", int(target), js.Value(b))
}
func (f *Functions) BindFramebuffer(target Enum, fb Framebuffer) {
f.Ctx.Call("bindFramebuffer", int(target), js.Value(fb))
}
func (f *Functions) BindRenderbuffer(target Enum, rb Renderbuffer) {
f.Ctx.Call("bindRenderbuffer", int(target), js.Value(rb))
}
func (f *Functions) BindTexture(target Enum, t Texture) {
f.Ctx.Call("bindTexture", int(target), js.Value(t))
}
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) BufferData(target Enum, src []byte, usage Enum) {
f.Ctx.Call("bufferData", int(target), f.byteArrayOf(src), int(usage))
}
func (f *Functions) CheckFramebufferStatus(target Enum) Enum {
return Enum(f.Ctx.Call("checkFramebufferStatus", int(target)).Int())
}
func (f *Functions) Clear(mask Enum) {
f.Ctx.Call("clear", int(mask))
}
func (f *Functions) ClearColor(red, green, blue, alpha float32) {
f.Ctx.Call("clearColor", red, green, blue, alpha)
}
func (f *Functions) ClearDepthf(d float32) {
f.Ctx.Call("clearDepth", d)
}
func (f *Functions) CompileShader(s Shader) {
f.Ctx.Call("compileShader", js.Value(s))
}
func (f *Functions) CreateBuffer() Buffer {
return Buffer(f.Ctx.Call("createBuffer"))
}
func (f *Functions) CreateFramebuffer() Framebuffer {
return Framebuffer(f.Ctx.Call("createFramebuffer"))
}
func (f *Functions) CreateProgram() Program {
return Program(f.Ctx.Call("createProgram"))
}
func (f *Functions) CreateQuery() Query {
return Query(f.Ctx.Call("createQuery"))
}
func (f *Functions) CreateRenderbuffer() Renderbuffer {
return Renderbuffer(f.Ctx.Call("createRenderbuffer"))
}
func (f *Functions) CreateShader(ty Enum) Shader {
return Shader(f.Ctx.Call("createShader", int(ty)))
}
func (f *Functions) CreateTexture() Texture {
return Texture(f.Ctx.Call("createTexture"))
}
func (f *Functions) DeleteBuffer(v Buffer) {
f.Ctx.Call("deleteBuffer", js.Value(v))
}
func (f *Functions) DeleteFramebuffer(v Framebuffer) {
f.Ctx.Call("deleteFramebuffer", js.Value(v))
}
func (f *Functions) DeleteProgram(p Program) {
f.Ctx.Call("deleteProgram", js.Value(p))
}
func (f *Functions) DeleteQuery(query Query) {
if f.EXT_disjoint_timer_query_webgl2 != js.Null() {
f.Ctx.Call("deleteQuery", js.Value(query))
} else {
f.EXT_disjoint_timer_query.Call("deleteQueryEXT", js.Value(query))
}
}
func (f *Functions) DeleteShader(s Shader) {
f.Ctx.Call("deleteShader", js.Value(s))
}
func (f *Functions) DeleteRenderbuffer(v Renderbuffer) {
f.Ctx.Call("deleteRenderbuffer", js.Value(v))
}
func (f *Functions) DeleteTexture(v Texture) {
f.Ctx.Call("deleteTexture", js.Value(v))
}
func (f *Functions) DepthFunc(fn Enum) {
f.Ctx.Call("depthFunc", int(fn))
}
func (f *Functions) DepthMask(mask bool) {
f.Ctx.Call("depthMask", mask)
}
func (f *Functions) DisableVertexAttribArray(a Attrib) {
f.Ctx.Call("disableVertexAttribArray", int(a))
}
func (f *Functions) Disable(cap Enum) {
f.Ctx.Call("disable", int(cap))
}
func (f *Functions) DrawArrays(mode Enum, first, count int) {
f.Ctx.Call("drawArrays", int(mode), first, count)
}
func (f *Functions) DrawElements(mode Enum, count int, ty Enum, offset int) {
f.Ctx.Call("drawElements", int(mode), count, int(ty), offset)
}
func (f *Functions) Enable(cap Enum) {
f.Ctx.Call("enable", int(cap))
}
func (f *Functions) EnableVertexAttribArray(a Attrib) {
f.Ctx.Call("enableVertexAttribArray", int(a))
}
func (f *Functions) EndQuery(target Enum) {
if f.EXT_disjoint_timer_query_webgl2 != js.Null() {
f.Ctx.Call("endQuery", int(target))
} else {
f.EXT_disjoint_timer_query.Call("endQueryEXT", int(target))
}
}
func (f *Functions) Finish() {
f.Ctx.Call("finish")
}
func (f *Functions) FramebufferRenderbuffer(target, attachment, renderbuffertarget Enum, renderbuffer Renderbuffer) {
f.Ctx.Call("framebufferRenderbuffer", int(target), int(attachment), int(renderbuffertarget), js.Value(renderbuffer))
}
func (f *Functions) FramebufferTexture2D(target, attachment, texTarget Enum, t Texture, level int) {
f.Ctx.Call("framebufferTexture2D", int(target), int(attachment), int(texTarget), js.Value(t), level)
}
func (f *Functions) GetError() Enum {
return Enum(f.Ctx.Call("getError").Int())
}
func (f *Functions) GetRenderbufferParameteri(target, pname Enum) int {
return paramVal(f.Ctx.Call("getRenderbufferParameteri", int(pname)))
}
func (f *Functions) GetFramebufferAttachmentParameteri(target, attachment, pname Enum) int {
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)))
}
func (f *Functions) GetInteger(pname Enum) int {
return paramVal(f.Ctx.Call("getParameter", int(pname)))
}
func (f *Functions) GetProgrami(p Program, pname Enum) int {
return paramVal(f.Ctx.Call("getProgramParameter", js.Value(p), int(pname)))
}
func (f *Functions) GetProgramInfoLog(p Program) string {
return f.Ctx.Call("getProgramInfoLog", js.Value(p)).String()
}
func (f *Functions) GetQueryObjectuiv(query Query, pname Enum) uint {
if f.EXT_disjoint_timer_query_webgl2 != js.Null() {
return uint(paramVal(f.Ctx.Call("getQueryParameter", js.Value(query), int(pname))))
} else {
return uint(paramVal(f.EXT_disjoint_timer_query.Call("getQueryObjectEXT", js.Value(query), int(pname))))
}
}
func (f *Functions) GetShaderi(s Shader, pname Enum) int {
return paramVal(f.Ctx.Call("getShaderParameter", js.Value(s), int(pname)))
}
func (f *Functions) GetShaderInfoLog(s Shader) string {
return f.Ctx.Call("getShaderInfoLog", js.Value(s)).String()
}
func (f *Functions) GetString(pname Enum) string {
switch pname {
case EXTENSIONS:
extsjs := f.Ctx.Call("getSupportedExtensions")
var exts []string
for i := 0; i < extsjs.Length(); i++ {
exts = append(exts, "GL_"+extsjs.Index(i).String())
}
return strings.Join(exts, " ")
default:
return f.Ctx.Call("getParameter", int(pname)).String()
}
}
func (f *Functions) GetUniformLocation(p Program, name string) Uniform {
return Uniform(f.Ctx.Call("getUniformLocation", js.Value(p), name))
}
func (f *Functions) InvalidateFramebuffer(target, attachment Enum) {
fn := f.Ctx.Get("invalidateFramebuffer")
if fn != js.Undefined() {
if f.int32Buf == (js.Value{}) {
f.int32Buf = js.Global().Get("Int32Array").New(1)
}
f.int32Buf.SetIndex(0, int32(attachment))
f.Ctx.Call("invalidateFramebuffer", int(target), f.int32Buf)
}
}
func (f *Functions) LinkProgram(p Program) {
f.Ctx.Call("linkProgram", js.Value(p))
}
func (f *Functions) PixelStorei(pname Enum, param int32) {
f.Ctx.Call("pixelStorei", int(pname), param)
}
func (f *Functions) RenderbufferStorage(target, internalformat Enum, width, height int) {
f.Ctx.Call("renderbufferStorage", int(target), int(internalformat), width, height)
}
func (f *Functions) ReadPixels(x, y, width, height int, format, ty Enum, data []byte) {
f.resizeByteBuffer(len(data))
f.Ctx.Call("readPixels", x, y, width, height, int(format), int(ty), f.byteBuf)
js.CopyBytesToGo(data, f.byteBuf)
}
func (f *Functions) Scissor(x, y, width, height int32) {
f.Ctx.Call("scissor", x, y, width, height)
}
func (f *Functions) ShaderSource(s Shader, src string) {
f.Ctx.Call("shaderSource", js.Value(s), src)
}
func (f *Functions) TexImage2D(target Enum, level int, internalFormat int, width, height int, format, ty Enum, data []byte) {
f.Ctx.Call("texImage2D", int(target), int(level), int(internalFormat), int(width), int(height), 0, int(format), int(ty), f.byteArrayOf(data))
}
func (f *Functions) TexSubImage2D(target Enum, level int, x, y, width, height int, format, ty Enum, data []byte) {
f.Ctx.Call("texSubImage2D", int(target), level, x, y, width, height, int(format), int(ty), f.byteArrayOf(data))
}
func (f *Functions) TexParameteri(target, pname Enum, param int) {
f.Ctx.Call("texParameteri", int(target), int(pname), int(param))
}
func (f *Functions) Uniform1f(dst Uniform, v float32) {
f.Ctx.Call("uniform1f", js.Value(dst), v)
}
func (f *Functions) Uniform1i(dst Uniform, v int) {
f.Ctx.Call("uniform1i", js.Value(dst), v)
}
func (f *Functions) Uniform2f(dst Uniform, v0, v1 float32) {
f.Ctx.Call("uniform2f", js.Value(dst), v0, v1)
}
func (f *Functions) Uniform3f(dst Uniform, v0, v1, v2 float32) {
f.Ctx.Call("uniform3f", js.Value(dst), v0, v1, v2)
}
func (f *Functions) Uniform4f(dst Uniform, v0, v1, v2, v3 float32) {
f.Ctx.Call("uniform4f", js.Value(dst), v0, v1, v2, v3)
}
func (f *Functions) UseProgram(p Program) {
f.Ctx.Call("useProgram", js.Value(p))
}
func (f *Functions) VertexAttribPointer(dst Attrib, size int, ty Enum, normalized bool, stride, offset int) {
f.Ctx.Call("vertexAttribPointer", int(dst), size, int(ty), normalized, stride, offset)
}
func (f *Functions) Viewport(x, y, width, height int) {
f.Ctx.Call("viewport", x, y, width, height)
}
func (f *Functions) byteArrayOf(data []byte) js.Value {
if len(data) == 0 {
return js.Null()
}
f.resizeByteBuffer(len(data))
js.CopyBytesToJS(f.byteBuf, data)
return f.byteBuf
}
func (f *Functions) resizeByteBuffer(n int) {
if n == 0 {
return
}
if f.byteBuf != (js.Value{}) && f.byteBuf.Length() >= n {
return
}
f.byteBuf = js.Global().Get("Uint8Array").New(n)
}
func paramVal(v js.Value) int {
switch v.Type() {
case js.TypeBoolean:
if b := v.Bool(); b {
return 1
} else {
return 0
}
case js.TypeNumber:
return v.Int()
default:
panic("unknown parameter type")
}
}
+387
View File
@@ -0,0 +1,387 @@
// SPDX-License-Identifier: Unlicense OR MIT
package gl
import (
"math"
"runtime"
"syscall"
"unsafe"
"golang.org/x/sys/windows"
)
var (
LibGLESv2 = windows.NewLazyDLL("libGLESv2.dll")
_glActiveTexture = LibGLESv2.NewProc("glActiveTexture")
_glAttachShader = LibGLESv2.NewProc("glAttachShader")
_glBeginQuery = LibGLESv2.NewProc("glBeginQuery")
_glBindAttribLocation = LibGLESv2.NewProc("glBindAttribLocation")
_glBindBuffer = LibGLESv2.NewProc("glBindBuffer")
_glBindFramebuffer = LibGLESv2.NewProc("glBindFramebuffer")
_glBindRenderbuffer = LibGLESv2.NewProc("glBindRenderbuffer")
_glBindTexture = LibGLESv2.NewProc("glBindTexture")
_glBlendEquation = LibGLESv2.NewProc("glBlendEquation")
_glBlendFunc = LibGLESv2.NewProc("glBlendFunc")
_glBufferData = LibGLESv2.NewProc("glBufferData")
_glCheckFramebufferStatus = LibGLESv2.NewProc("glCheckFramebufferStatus")
_glClear = LibGLESv2.NewProc("glClear")
_glClearColor = LibGLESv2.NewProc("glClearColor")
_glClearDepthf = LibGLESv2.NewProc("glClearDepthf")
_glDeleteQueries = LibGLESv2.NewProc("glDeleteQueries")
_glCompileShader = LibGLESv2.NewProc("glCompileShader")
_glGenBuffers = LibGLESv2.NewProc("glGenBuffers")
_glGenFramebuffers = LibGLESv2.NewProc("glGenFramebuffers")
_glCreateProgram = LibGLESv2.NewProc("glCreateProgram")
_glGenRenderbuffers = LibGLESv2.NewProc("glGenRenderbuffers")
_glCreateShader = LibGLESv2.NewProc("glCreateShader")
_glGenTextures = LibGLESv2.NewProc("glGenTextures")
_glDeleteBuffers = LibGLESv2.NewProc("glDeleteBuffers")
_glDeleteFramebuffers = LibGLESv2.NewProc("glDeleteFramebuffers")
_glDeleteProgram = LibGLESv2.NewProc("glDeleteProgram")
_glDeleteShader = LibGLESv2.NewProc("glDeleteShader")
_glDeleteRenderbuffers = LibGLESv2.NewProc("glDeleteRenderbuffers")
_glDeleteTextures = LibGLESv2.NewProc("glDeleteTextures")
_glDepthFunc = LibGLESv2.NewProc("glDepthFunc")
_glDepthMask = LibGLESv2.NewProc("glDepthMask")
_glDisableVertexAttribArray = LibGLESv2.NewProc("glDisableVertexAttribArray")
_glDisable = LibGLESv2.NewProc("glDisable")
_glDrawArrays = LibGLESv2.NewProc("glDrawArrays")
_glDrawElements = LibGLESv2.NewProc("glDrawElements")
_glEnable = LibGLESv2.NewProc("glEnable")
_glEnableVertexAttribArray = LibGLESv2.NewProc("glEnableVertexAttribArray")
_glEndQuery = LibGLESv2.NewProc("glEndQuery")
_glFinish = LibGLESv2.NewProc("glFinish")
_glFramebufferRenderbuffer = LibGLESv2.NewProc("glFramebufferRenderbuffer")
_glFramebufferTexture2D = LibGLESv2.NewProc("glFramebufferTexture2D")
_glGenQueries = LibGLESv2.NewProc("glGenQueries")
_glGetError = LibGLESv2.NewProc("glGetError")
_glGetRenderbufferParameteri = LibGLESv2.NewProc("glGetRenderbufferParameteri")
_glGetFramebufferAttachmentParameteri = LibGLESv2.NewProc("glGetFramebufferAttachmentParameteri")
_glGetIntegerv = LibGLESv2.NewProc("glGetIntegerv")
_glGetProgramiv = LibGLESv2.NewProc("glGetProgramiv")
_glGetProgramInfoLog = LibGLESv2.NewProc("glGetProgramInfoLog")
_glGetQueryObjectuiv = LibGLESv2.NewProc("glGetQueryObjectuiv")
_glGetShaderiv = LibGLESv2.NewProc("glGetShaderiv")
_glGetShaderInfoLog = LibGLESv2.NewProc("glGetShaderInfoLog")
_glGetString = LibGLESv2.NewProc("glGetString")
_glGetUniformLocation = LibGLESv2.NewProc("glGetUniformLocation")
_glInvalidateFramebuffer = LibGLESv2.NewProc("glInvalidateFramebuffer")
_glLinkProgram = LibGLESv2.NewProc("glLinkProgram")
_glPixelStorei = LibGLESv2.NewProc("glPixelStorei")
_glReadPixels = LibGLESv2.NewProc("glReadPixels")
_glRenderbufferStorage = LibGLESv2.NewProc("glRenderbufferStorage")
_glScissor = LibGLESv2.NewProc("glScissor")
_glShaderSource = LibGLESv2.NewProc("glShaderSource")
_glTexImage2D = LibGLESv2.NewProc("glTexImage2D")
_glTexSubImage2D = LibGLESv2.NewProc("glTexSubImage2D")
_glTexParameteri = LibGLESv2.NewProc("glTexParameteri")
_glUniform1f = LibGLESv2.NewProc("glUniform1f")
_glUniform1i = LibGLESv2.NewProc("glUniform1i")
_glUniform2f = LibGLESv2.NewProc("glUniform2f")
_glUniform3f = LibGLESv2.NewProc("glUniform3f")
_glUniform4f = LibGLESv2.NewProc("glUniform4f")
_glUseProgram = LibGLESv2.NewProc("glUseProgram")
_glVertexAttribPointer = LibGLESv2.NewProc("glVertexAttribPointer")
_glViewport = LibGLESv2.NewProc("glViewport")
)
type Functions struct {
// Query caches.
int32s [100]int32
}
func (c *Functions) ActiveTexture(t Enum) {
syscall.Syscall(_glActiveTexture.Addr(), 1, uintptr(t), 0, 0)
}
func (c *Functions) AttachShader(p Program, s Shader) {
syscall.Syscall(_glAttachShader.Addr(), 2, uintptr(p.V), uintptr(s.V), 0)
}
func (f *Functions) BeginQuery(target Enum, query Query) {
syscall.Syscall(_glBeginQuery.Addr(), 2, uintptr(target), uintptr(query.V), 0)
}
func (c *Functions) BindAttribLocation(p Program, a Attrib, name string) {
cname := cString(name)
c0 := &cname[0]
syscall.Syscall(_glBindAttribLocation.Addr(), 3, uintptr(p.V), uintptr(a), uintptr(unsafe.Pointer(c0)))
issue34474KeepAlive(c)
}
func (c *Functions) BindBuffer(target Enum, b Buffer) {
syscall.Syscall(_glBindBuffer.Addr(), 2, uintptr(target), uintptr(b.V), 0)
}
func (c *Functions) BindFramebuffer(target Enum, fb Framebuffer) {
syscall.Syscall(_glBindFramebuffer.Addr(), 2, uintptr(target), uintptr(fb.V), 0)
}
func (c *Functions) BindRenderbuffer(target Enum, rb Renderbuffer) {
syscall.Syscall(_glBindRenderbuffer.Addr(), 2, uintptr(target), uintptr(rb.V), 0)
}
func (c *Functions) BindTexture(target Enum, t Texture) {
syscall.Syscall(_glBindTexture.Addr(), 2, uintptr(target), uintptr(t.V), 0)
}
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) BufferData(target Enum, src []byte, usage Enum) {
if n := len(src); n == 0 {
syscall.Syscall6(_glBufferData.Addr(), 4, uintptr(target), 0, 0, uintptr(usage), 0, 0)
} else {
s0 := &src[0]
syscall.Syscall6(_glBufferData.Addr(), 4, uintptr(target), uintptr(n), uintptr(unsafe.Pointer(s0)), uintptr(usage), 0, 0)
issue34474KeepAlive(s0)
}
}
func (c *Functions) CheckFramebufferStatus(target Enum) Enum {
s, _, _ := syscall.Syscall(_glCheckFramebufferStatus.Addr(), 1, uintptr(target), 0, 0)
return Enum(s)
}
func (c *Functions) Clear(mask Enum) {
syscall.Syscall(_glClear.Addr(), 1, uintptr(mask), 0, 0)
}
func (c *Functions) ClearColor(red, green, blue, alpha float32) {
syscall.Syscall6(_glClearColor.Addr(), 4, uintptr(math.Float32bits(red)), uintptr(math.Float32bits(green)), uintptr(math.Float32bits(blue)), uintptr(math.Float32bits(alpha)), 0, 0)
}
func (c *Functions) ClearDepthf(d float32) {
syscall.Syscall(_glClearDepthf.Addr(), 1, uintptr(math.Float32bits(d)), 0, 0)
}
func (c *Functions) CompileShader(s Shader) {
syscall.Syscall(_glCompileShader.Addr(), 1, uintptr(s.V), 0, 0)
}
func (c *Functions) CreateBuffer() Buffer {
var buf uintptr
syscall.Syscall(_glGenBuffers.Addr(), 2, 1, uintptr(unsafe.Pointer(&buf)), 0)
return Buffer{uint(buf)}
}
func (c *Functions) CreateFramebuffer() Framebuffer {
var fb uintptr
syscall.Syscall(_glGenFramebuffers.Addr(), 2, 1, uintptr(unsafe.Pointer(&fb)), 0)
return Framebuffer{uint(fb)}
}
func (c *Functions) CreateProgram() Program {
p, _, _ := syscall.Syscall(_glCreateProgram.Addr(), 0, 0, 0, 0)
return Program{uint(p)}
}
func (f *Functions) CreateQuery() Query {
var q uintptr
syscall.Syscall(_glGenQueries.Addr(), 2, 1, uintptr(unsafe.Pointer(&q)), 0)
return Query{uint(q)}
}
func (c *Functions) CreateRenderbuffer() Renderbuffer {
var rb uintptr
syscall.Syscall(_glGenRenderbuffers.Addr(), 2, 1, uintptr(unsafe.Pointer(&rb)), 0)
return Renderbuffer{uint(rb)}
}
func (c *Functions) CreateShader(ty Enum) Shader {
s, _, _ := syscall.Syscall(_glCreateShader.Addr(), 1, uintptr(ty), 0, 0)
return Shader{uint(s)}
}
func (c *Functions) CreateTexture() Texture {
var t uintptr
syscall.Syscall(_glGenTextures.Addr(), 2, 1, uintptr(unsafe.Pointer(&t)), 0)
return Texture{uint(t)}
}
func (c *Functions) DeleteBuffer(v Buffer) {
syscall.Syscall(_glDeleteBuffers.Addr(), 2, 1, uintptr(unsafe.Pointer(&v)), 0)
}
func (c *Functions) DeleteFramebuffer(v Framebuffer) {
syscall.Syscall(_glDeleteFramebuffers.Addr(), 2, 1, uintptr(unsafe.Pointer(&v.V)), 0)
}
func (c *Functions) DeleteProgram(p Program) {
syscall.Syscall(_glDeleteProgram.Addr(), 1, uintptr(p.V), 0, 0)
}
func (f *Functions) DeleteQuery(query Query) {
syscall.Syscall(_glDeleteQueries.Addr(), 2, 1, uintptr(unsafe.Pointer(&query.V)), 0)
}
func (c *Functions) DeleteShader(s Shader) {
syscall.Syscall(_glDeleteShader.Addr(), 1, uintptr(s.V), 0, 0)
}
func (c *Functions) DeleteRenderbuffer(v Renderbuffer) {
syscall.Syscall(_glDeleteRenderbuffers.Addr(), 2, 1, uintptr(unsafe.Pointer(&v.V)), 0)
}
func (c *Functions) DeleteTexture(v Texture) {
syscall.Syscall(_glDeleteTextures.Addr(), 2, 1, uintptr(unsafe.Pointer(&v.V)), 0)
}
func (c *Functions) DepthFunc(f Enum) {
syscall.Syscall(_glDepthFunc.Addr(), 1, uintptr(f), 0, 0)
}
func (c *Functions) DepthMask(mask bool) {
var m uintptr
if mask {
m = 1
}
syscall.Syscall(_glDepthMask.Addr(), 1, m, 0, 0)
}
func (c *Functions) DisableVertexAttribArray(a Attrib) {
syscall.Syscall(_glDisableVertexAttribArray.Addr(), 1, uintptr(a), 0, 0)
}
func (c *Functions) Disable(cap Enum) {
syscall.Syscall(_glDisable.Addr(), 1, uintptr(cap), 0, 0)
}
func (c *Functions) DrawArrays(mode Enum, first, count int) {
syscall.Syscall(_glDrawArrays.Addr(), 3, uintptr(mode), uintptr(first), uintptr(count))
}
func (c *Functions) DrawElements(mode Enum, count int, ty Enum, offset int) {
syscall.Syscall6(_glDrawElements.Addr(), 4, uintptr(mode), uintptr(count), uintptr(ty), uintptr(offset), 0, 0)
}
func (c *Functions) Enable(cap Enum) {
syscall.Syscall(_glEnable.Addr(), 1, uintptr(cap), 0, 0)
}
func (c *Functions) EnableVertexAttribArray(a Attrib) {
syscall.Syscall(_glEnableVertexAttribArray.Addr(), 1, uintptr(a), 0, 0)
}
func (f *Functions) EndQuery(target Enum) {
syscall.Syscall(_glEndQuery.Addr(), 1, uintptr(target), 0, 0)
}
func (c *Functions) Finish() {
syscall.Syscall(_glFinish.Addr(), 0, 0, 0, 0)
}
func (c *Functions) FramebufferRenderbuffer(target, attachment, renderbuffertarget Enum, renderbuffer Renderbuffer) {
syscall.Syscall6(_glFramebufferRenderbuffer.Addr(), 4, uintptr(target), uintptr(attachment), uintptr(renderbuffertarget), uintptr(renderbuffer.V), 0, 0)
}
func (c *Functions) FramebufferTexture2D(target, attachment, texTarget Enum, t Texture, level int) {
syscall.Syscall6(_glFramebufferTexture2D.Addr(), 5, uintptr(target), uintptr(attachment), uintptr(texTarget), uintptr(t.V), uintptr(level), 0)
}
func (c *Functions) GetBinding(pname Enum) Object {
return Object{uint(c.GetInteger(pname))}
}
func (c *Functions) GetError() Enum {
e, _, _ := syscall.Syscall(_glGetError.Addr(), 0, 0, 0, 0)
return Enum(e)
}
func (c *Functions) GetRenderbufferParameteri(target, pname Enum) int {
p, _, _ := syscall.Syscall(_glGetRenderbufferParameteri.Addr(), 2, uintptr(target), uintptr(pname), 0)
return int(p)
}
func (c *Functions) GetFramebufferAttachmentParameteri(target, attachment, pname Enum) int {
p, _, _ := syscall.Syscall(_glGetFramebufferAttachmentParameteri.Addr(), 3, uintptr(target), uintptr(attachment), uintptr(pname))
return int(p)
}
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) 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])
}
func (c *Functions) GetProgramInfoLog(p Program) string {
n := c.GetProgrami(p, INFO_LOG_LENGTH)
buf := make([]byte, n)
syscall.Syscall6(_glGetProgramInfoLog.Addr(), 4, uintptr(p.V), uintptr(len(buf)), 0, uintptr(unsafe.Pointer(&buf[0])), 0, 0)
return string(buf)
}
func (c *Functions) GetQueryObjectuiv(query Query, pname Enum) uint {
syscall.Syscall(_glGetQueryObjectuiv.Addr(), 3, uintptr(query.V), uintptr(pname), uintptr(unsafe.Pointer(&c.int32s[0])))
return uint(c.int32s[0])
}
func (c *Functions) GetShaderi(s Shader, pname Enum) int {
syscall.Syscall(_glGetShaderiv.Addr(), 3, uintptr(s.V), uintptr(pname), uintptr(unsafe.Pointer(&c.int32s[0])))
return int(c.int32s[0])
}
func (c *Functions) GetShaderInfoLog(s Shader) string {
n := c.GetShaderi(s, INFO_LOG_LENGTH)
buf := make([]byte, n)
syscall.Syscall6(_glGetShaderInfoLog.Addr(), 4, uintptr(s.V), uintptr(len(buf)), 0, uintptr(unsafe.Pointer(&buf[0])), 0, 0)
return string(buf)
}
func (c *Functions) GetString(pname Enum) string {
s, _, _ := syscall.Syscall(_glGetString.Addr(), 1, uintptr(pname), 0, 0)
return GoString(SliceOf(s))
}
func (c *Functions) GetUniformLocation(p Program, name string) Uniform {
cname := cString(name)
c0 := &cname[0]
u, _, _ := syscall.Syscall(_glGetUniformLocation.Addr(), 2, uintptr(p.V), uintptr(unsafe.Pointer(c0)), 0)
issue34474KeepAlive(c)
return Uniform{int(u)}
}
func (c *Functions) InvalidateFramebuffer(target, attachment Enum) {
addr := _glInvalidateFramebuffer.Addr()
if addr == 0 {
// InvalidateFramebuffer is just a hint. Skip it if not supported.
return
}
syscall.Syscall(addr, 3, uintptr(target), 1, uintptr(unsafe.Pointer(&attachment)))
}
func (c *Functions) LinkProgram(p Program) {
syscall.Syscall(_glLinkProgram.Addr(), 1, uintptr(p.V), 0, 0)
}
func (c *Functions) PixelStorei(pname Enum, param int32) {
syscall.Syscall(_glPixelStorei.Addr(), 2, uintptr(pname), uintptr(param), 0)
}
func (f *Functions) ReadPixels(x, y, width, height int, format, ty Enum, data []byte) {
d0 := &data[0]
syscall.Syscall6(_glReadPixels.Addr(), uintptr(x), uintptr(y), uintptr(width), uintptr(height), uintptr(format), uintptr(ty), uintptr(unsafe.Pointer(d0)))
issue34474KeepAlive(d0)
}
func (c *Functions) RenderbufferStorage(target, internalformat Enum, width, height int) {
syscall.Syscall6(_glRenderbufferStorage.Addr(), 4, uintptr(target), uintptr(internalformat), uintptr(width), uintptr(height), 0, 0)
}
func (c *Functions) Scissor(x, y, width, height int32) {
syscall.Syscall6(_glScissor.Addr(), 4, uintptr(x), uintptr(y), uintptr(width), uintptr(height), 0, 0)
}
func (c *Functions) ShaderSource(s Shader, src string) {
var n uintptr = uintptr(len(src))
psrc := &src
syscall.Syscall6(_glShaderSource.Addr(), 4, uintptr(s.V), 1, uintptr(unsafe.Pointer(psrc)), uintptr(unsafe.Pointer(&n)), 0, 0)
issue34474KeepAlive(psrc)
}
func (c *Functions) TexImage2D(target Enum, level int, internalFormat int, width, height int, format, ty Enum, data []byte) {
if len(data) == 0 {
syscall.Syscall9(_glTexImage2D.Addr(), 9, uintptr(target), uintptr(level), uintptr(internalFormat), uintptr(width), uintptr(height), 0, uintptr(format), uintptr(ty), 0)
} else {
d0 := &data[0]
syscall.Syscall9(_glTexImage2D.Addr(), 9, uintptr(target), uintptr(level), uintptr(internalFormat), uintptr(width), uintptr(height), 0, uintptr(format), uintptr(ty), uintptr(unsafe.Pointer(d0)))
issue34474KeepAlive(d0)
}
}
func (c *Functions) TexSubImage2D(target Enum, level int, x, y, width, height int, format, ty Enum, data []byte) {
d0 := &data[0]
syscall.Syscall9(_glTexSubImage2D.Addr(), 9, uintptr(target), uintptr(level), uintptr(x), uintptr(y), uintptr(width), uintptr(height), uintptr(format), uintptr(ty), uintptr(unsafe.Pointer(d0)))
issue34474KeepAlive(d0)
}
func (c *Functions) TexParameteri(target, pname Enum, param int) {
syscall.Syscall(_glTexParameteri.Addr(), 3, uintptr(target), uintptr(pname), uintptr(param))
}
func (c *Functions) Uniform1f(dst Uniform, v float32) {
syscall.Syscall(_glUniform1f.Addr(), 2, uintptr(dst.V), uintptr(math.Float32bits(v)), 0)
}
func (c *Functions) Uniform1i(dst Uniform, v int) {
syscall.Syscall(_glUniform1i.Addr(), 2, uintptr(dst.V), uintptr(v), 0)
}
func (c *Functions) Uniform2f(dst Uniform, v0, v1 float32) {
syscall.Syscall(_glUniform2f.Addr(), 3, uintptr(dst.V), uintptr(math.Float32bits(v0)), uintptr(math.Float32bits(v1)))
}
func (c *Functions) Uniform3f(dst Uniform, v0, v1, v2 float32) {
syscall.Syscall6(_glUniform3f.Addr(), 4, uintptr(dst.V), uintptr(math.Float32bits(v0)), uintptr(math.Float32bits(v1)), uintptr(math.Float32bits(v2)), 0, 0)
}
func (c *Functions) Uniform4f(dst Uniform, v0, v1, v2, v3 float32) {
syscall.Syscall6(_glUniform4f.Addr(), 5, uintptr(dst.V), uintptr(math.Float32bits(v0)), uintptr(math.Float32bits(v1)), uintptr(math.Float32bits(v2)), uintptr(math.Float32bits(v3)), 0)
}
func (c *Functions) UseProgram(p Program) {
syscall.Syscall(_glUseProgram.Addr(), 1, uintptr(p.V), 0, 0)
}
func (c *Functions) VertexAttribPointer(dst Attrib, size int, ty Enum, normalized bool, stride, offset int) {
var norm uintptr
if normalized {
norm = 1
}
syscall.Syscall6(_glVertexAttribPointer.Addr(), 6, uintptr(dst), uintptr(size), uintptr(ty), norm, uintptr(stride), uintptr(offset))
}
func (c *Functions) Viewport(x, y, width, height int) {
syscall.Syscall6(_glViewport.Addr(), 4, uintptr(x), uintptr(y), uintptr(width), uintptr(height), 0, 0)
}
func cString(s string) []byte {
b := make([]byte, len(s)+1)
copy(b, s)
return b
}
// issue34474KeepAlive calls runtime.KeepAlive as a
// workaround for golang.org/issue/34474.
func issue34474KeepAlive(v interface{}) {
runtime.KeepAlive(v)
}
+184
View File
@@ -0,0 +1,184 @@
// SPDX-License-Identifier: Unlicense OR MIT
package gl
import (
"fmt"
"runtime"
"strings"
)
// SRGBFBO implements an intermediate sRGB FBO
// for gamma-correct rendering on platforms without
// sRGB enabled native framebuffers.
type SRGBFBO struct {
c *Functions
width, height int
frameBuffer Framebuffer
depthBuffer Renderbuffer
colorTex Texture
quad Buffer
prog Program
es3 bool
}
func NewSRGBFBO(f *Functions) (*SRGBFBO, error) {
var es3 bool
glVer := f.GetString(VERSION)
ver, err := ParseGLVersion(glVer)
if err != nil {
return nil, err
}
if ver[0] >= 3 {
es3 = true
} else {
exts := f.GetString(EXTENSIONS)
if !strings.Contains(exts, "EXT_sRGB") {
return nil, fmt.Errorf("no support for OpenGL ES 3 nor EXT_sRGB")
}
}
prog, err := CreateProgram(f, blitVSrc, blitFSrc, []string{"pos", "uv"})
if err != nil {
return nil, err
}
f.UseProgram(prog)
f.Uniform1i(GetUniformLocation(f, prog, "tex"), 0)
s := &SRGBFBO{
c: f,
es3: es3,
prog: prog,
frameBuffer: f.CreateFramebuffer(),
colorTex: f.CreateTexture(),
depthBuffer: f.CreateRenderbuffer(),
}
s.quad = f.CreateBuffer()
f.BindBuffer(ARRAY_BUFFER, s.quad)
f.BufferData(ARRAY_BUFFER,
BytesView([]float32{
-1, +1, 0, 1,
+1, +1, 1, 1,
-1, -1, 0, 0,
+1, -1, 1, 0,
}),
STATIC_DRAW)
f.BindTexture(TEXTURE_2D, s.colorTex)
f.TexParameteri(TEXTURE_2D, TEXTURE_WRAP_S, CLAMP_TO_EDGE)
f.TexParameteri(TEXTURE_2D, TEXTURE_WRAP_T, CLAMP_TO_EDGE)
f.TexParameteri(TEXTURE_2D, TEXTURE_MAG_FILTER, NEAREST)
f.TexParameteri(TEXTURE_2D, TEXTURE_MIN_FILTER, NEAREST)
return s, nil
}
func (s *SRGBFBO) Blit() {
s.c.BindFramebuffer(FRAMEBUFFER, Framebuffer{})
s.c.ClearColor(1, 0, 1, 1)
s.c.Clear(COLOR_BUFFER_BIT)
s.c.UseProgram(s.prog)
s.c.BindTexture(TEXTURE_2D, s.colorTex)
s.c.BindBuffer(ARRAY_BUFFER, s.quad)
s.c.VertexAttribPointer(0 /* pos */, 2, FLOAT, false, 4*4, 0)
s.c.VertexAttribPointer(1 /* uv */, 2, FLOAT, false, 4*4, 4*2)
s.c.EnableVertexAttribArray(0)
s.c.EnableVertexAttribArray(1)
s.c.DrawArrays(TRIANGLE_STRIP, 0, 4)
s.c.BindTexture(TEXTURE_2D, Texture{})
s.c.DisableVertexAttribArray(0)
s.c.DisableVertexAttribArray(1)
s.c.BindFramebuffer(FRAMEBUFFER, s.frameBuffer)
s.c.InvalidateFramebuffer(FRAMEBUFFER, COLOR_ATTACHMENT0)
s.c.InvalidateFramebuffer(FRAMEBUFFER, DEPTH_ATTACHMENT)
// The Android emulator requires framebuffer 0 bound at eglSwapBuffer time.
// Bind the sRGB framebuffer again in afterPresent.
s.c.BindFramebuffer(FRAMEBUFFER, Framebuffer{})
}
func (s *SRGBFBO) AfterPresent() {
s.c.BindFramebuffer(FRAMEBUFFER, s.frameBuffer)
}
func (s *SRGBFBO) Refresh(w, h int) error {
s.width, s.height = w, h
if w == 0 || h == 0 {
return nil
}
s.c.BindTexture(TEXTURE_2D, s.colorTex)
if s.es3 {
s.c.TexImage2D(TEXTURE_2D, 0, SRGB8_ALPHA8, w, h, RGBA, UNSIGNED_BYTE, nil)
} else /* EXT_sRGB */ {
s.c.TexImage2D(TEXTURE_2D, 0, SRGB_ALPHA_EXT, w, h, SRGB_ALPHA_EXT, UNSIGNED_BYTE, nil)
}
currentRB := Renderbuffer(s.c.GetBinding(RENDERBUFFER_BINDING))
s.c.BindRenderbuffer(RENDERBUFFER, s.depthBuffer)
s.c.RenderbufferStorage(RENDERBUFFER, DEPTH_COMPONENT16, w, h)
s.c.BindRenderbuffer(RENDERBUFFER, currentRB)
s.c.BindFramebuffer(FRAMEBUFFER, s.frameBuffer)
s.c.FramebufferTexture2D(FRAMEBUFFER, COLOR_ATTACHMENT0, TEXTURE_2D, s.colorTex, 0)
s.c.FramebufferRenderbuffer(FRAMEBUFFER, DEPTH_ATTACHMENT, RENDERBUFFER, s.depthBuffer)
if st := s.c.CheckFramebufferStatus(FRAMEBUFFER); st != FRAMEBUFFER_COMPLETE {
return fmt.Errorf("sRGB framebuffer incomplete (%dx%d), status: %#x error: %x", s.width, s.height, 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(COLOR_BUFFER_BIT)
var pixel [4]byte
s.c.ReadPixels(0, 0, 1, 1, RGBA, UNSIGNED_BYTE, pixel[:])
if pixel[0] == 128 { // Correct sRGB color value is ~188
s.c.TexImage2D(TEXTURE_2D, 0, RGBA, w, h, RGBA, UNSIGNED_BYTE, nil)
if st := s.c.CheckFramebufferStatus(FRAMEBUFFER); st != FRAMEBUFFER_COMPLETE {
return fmt.Errorf("fallback RGBA framebuffer incomplete (%dx%d), status: %#x error: %x", s.width, s.height, st, s.c.GetError())
}
}
}
return nil
}
func (s *SRGBFBO) Release() {
s.c.DeleteFramebuffer(s.frameBuffer)
s.c.DeleteTexture(s.colorTex)
s.c.DeleteRenderbuffer(s.depthBuffer)
}
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);
}
`
)
+19
View File
@@ -0,0 +1,19 @@
// +build !js
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 }
Object struct{ V uint }
)
func (u Uniform) Valid() bool {
return u.V != -1
}
+21
View File
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: Unlicense OR MIT
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
Object js.Value
)
func (u Uniform) Valid() bool {
return js.Value(u) != js.Null()
}
+114
View File
@@ -0,0 +1,114 @@
// SPDX-License-Identifier: Unlicense OR MIT
package gl
import (
"errors"
"fmt"
"reflect"
"strings"
"unsafe"
)
func CreateProgram(ctx *Functions, vsSrc, fsSrc string, attribs []string) (Program, error) {
vs, err := createShader(ctx, VERTEX_SHADER, vsSrc)
if err != nil {
return Program{}, err
}
defer ctx.DeleteShader(vs)
fs, err := createShader(ctx, FRAGMENT_SHADER, fsSrc)
if err != nil {
return Program{}, err
}
defer ctx.DeleteShader(fs)
prog := ctx.CreateProgram()
if prog == (Program{}) {
return Program{}, errors.New("glCreateProgram failed")
}
ctx.AttachShader(prog, vs)
ctx.AttachShader(prog, fs)
for i, a := range attribs {
ctx.BindAttribLocation(prog, Attrib(i), a)
}
ctx.LinkProgram(prog)
if ctx.GetProgrami(prog, LINK_STATUS) == 0 {
log := ctx.GetProgramInfoLog(prog)
ctx.DeleteProgram(prog)
return Program{}, fmt.Errorf("program link failed: %s", strings.TrimSpace(log))
}
return prog, nil
}
func GetUniformLocation(ctx *Functions, prog Program, name string) Uniform {
loc := ctx.GetUniformLocation(prog, name)
if !loc.Valid() {
panic(fmt.Errorf("uniform %s not found", name))
}
return loc
}
func createShader(ctx *Functions, typ Enum, src string) (Shader, error) {
sh := ctx.CreateShader(typ)
if sh == (Shader{}) {
return Shader{}, errors.New("glCreateShader failed")
}
ctx.ShaderSource(sh, src)
ctx.CompileShader(sh)
if ctx.GetShaderi(sh, COMPILE_STATUS) == 0 {
log := ctx.GetShaderInfoLog(sh)
ctx.DeleteShader(sh)
return Shader{}, fmt.Errorf("shader compilation failed: %s", strings.TrimSpace(log))
}
return sh, nil
}
// BytesView returns a byte slice view of a slice.
func BytesView(s interface{}) []byte {
v := reflect.ValueOf(s)
first := v.Index(0)
sz := int(first.Type().Size())
return *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
Data: uintptr(unsafe.Pointer((*reflect.SliceHeader)(unsafe.Pointer(first.UnsafeAddr())))),
Len: v.Len() * sz,
Cap: v.Cap() * sz,
}))
}
func ParseGLVersion(glVer string) ([2]int, error) {
var ver [2]int
if _, err := fmt.Sscanf(glVer, "OpenGL ES %d.%d", &ver[0], &ver[1]); err == nil {
return ver, nil
} else if _, err := fmt.Sscanf(glVer, "WebGL %d.%d", &ver[0], &ver[1]); err == nil {
// WebGL major version v corresponds to OpenGL ES version v + 1
ver[0]++
return ver, nil
} else if _, err := fmt.Sscanf(glVer, "%d.%d", &ver[0], &ver[1]); err == nil {
return ver, nil
}
return ver, fmt.Errorf("failed to parse OpenGL ES version (%s)", glVer)
}
func SliceOf(s uintptr) []byte {
if s == 0 {
return nil
}
sh := reflect.SliceHeader{
Data: s,
Len: 1 << 30,
Cap: 1 << 30,
}
return *(*[]byte)(unsafe.Pointer(&sh))
}
// GoString convert a NUL-terminated C string
// to a Go string.
func GoString(s []byte) string {
i := 0
for {
if s[i] == 0 {
break
}
i++
}
return string(s[:i])
}
+18
View File
@@ -0,0 +1,18 @@
package gl
import (
"testing"
)
func TestGoString(t *testing.T) {
tests := [][2]string{
{"Hello\x00", "Hello"},
{"\x00", ""},
}
for _, test := range tests {
got := GoString([]byte(test[0]))
if exp := test[1]; exp != got {
t.Errorf("expected %q got %q", exp, got)
}
}
}