all: initial import

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2019-03-30 13:18:49 +01:00
commit 0f05231c35
102 changed files with 17926 additions and 0 deletions
+473
View File
@@ -0,0 +1,473 @@
// 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{}
func (f *Functions) ActiveTexture(texture Enum) {
C.glActiveTexture(C.GLenum(texture))
}
func (f *Functions) AttachShader(p Program, s Shader) {
C.glAttachShader(C.GLuint(p), C.GLuint(s))
}
func (f *Functions) BeginQuery(target Enum, query Query) {
C.gio_glBeginQuery(C.GLenum(target), C.GLenum(query))
}
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), C.GLuint(a), cname)
}
func (f *Functions) BindBuffer(target Enum, b Buffer) {
C.glBindBuffer(C.GLenum(target), C.GLuint(b))
}
func (f *Functions) BindFramebuffer(target Enum, fb Framebuffer) {
C.glBindFramebuffer(C.GLenum(target), C.GLuint(fb))
}
func (f *Functions) BindRenderbuffer(target Enum, fb Renderbuffer) {
C.glBindRenderbuffer(C.GLenum(target), C.GLuint(fb))
}
func (f *Functions) BindTexture(target Enum, t Texture) {
C.glBindTexture(C.GLenum(target), C.GLuint(t))
}
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))
}
func (f *Functions) CreateBuffer() Buffer {
var handle C.GLuint
C.glGenBuffers(1, &handle)
return Buffer(handle)
}
func (f *Functions) CreateFramebuffer() Framebuffer {
var handle C.GLuint
C.glGenFramebuffers(1, &handle)
return Framebuffer(handle)
}
func (f *Functions) CreateProgram() Program {
return Program(C.glCreateProgram())
}
func (f *Functions) CreateQuery() Query {
var handle C.GLuint
C.gio_glGenQueries(1, &handle)
return Query(handle)
}
func (f *Functions) CreateRenderbuffer() Renderbuffer {
var handle C.GLuint
C.glGenRenderbuffers(1, &handle)
return Renderbuffer(handle)
}
func (f *Functions) CreateShader(ty Enum) Shader {
return Shader(C.glCreateShader(C.GLenum(ty)))
}
func (f *Functions) CreateTexture() Texture {
var handle C.GLuint
C.glGenTextures(1, &handle)
return Texture(handle)
}
func (f *Functions) DeleteBuffer(v Buffer) {
handle := C.GLuint(v)
C.glDeleteBuffers(1, &handle)
}
func (f *Functions) DeleteFramebuffer(v Framebuffer) {
handle := C.GLuint(v)
C.glDeleteFramebuffers(1, &handle)
}
func (f *Functions) DeleteProgram(p Program) {
C.glDeleteProgram(C.GLuint(p))
}
func (f *Functions) DeleteQuery(query Query) {
handle := C.GLuint(query)
C.gio_glDeleteQueries(1, &handle)
}
func (f *Functions) DeleteRenderbuffer(v Renderbuffer) {
handle := C.GLuint(v)
C.glDeleteRenderbuffers(1, &handle)
}
func (f *Functions) DeleteShader(s Shader) {
C.glDeleteShader(C.GLuint(s))
}
func (f *Functions) DeleteTexture(v Texture) {
handle := C.GLuint(v)
C.glDeleteTextures(1, &handle)
}
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))
}
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), C.GLint(level))
}
func (f *Functions) GetError() Enum {
return Enum(C.glGetError())
}
func (f *Functions) GetRenderbufferParameteri(target, pname Enum) int {
// Hope this is enough room.
var buf [100]C.GLint
C.glGetRenderbufferParameteriv(C.GLenum(target), C.GLenum(pname), &buf[0])
return int(buf[0])
}
func (f *Functions) GetFramebufferAttachmentParameteri(target, attachment, pname Enum) int {
// Hope this is enough room.
var buf [100]C.GLint
C.glGetFramebufferAttachmentParameteriv(C.GLenum(target), C.GLenum(attachment), C.GLenum(pname), &buf[0])
return int(buf[0])
}
func (f *Functions) GetInteger(pname Enum) int {
// Hope this is enough room.
var buf [100]C.GLint
C.glGetIntegerv(C.GLenum(pname), &buf[0])
return int(buf[0])
}
func (f *Functions) GetProgrami(p Program, pname Enum) int {
// Hope this is enough room.
var buf [100]C.GLint
C.glGetProgramiv(C.GLuint(p), C.GLenum(pname), &buf[0])
return int(buf[0])
}
func (f *Functions) GetProgramInfoLog(p Program) string {
var plen C.GLsizei
C.glGetProgramInfoLog(C.GLuint(p), 0, &plen, nil)
if plen == 0 {
return ""
}
// Make room for the string and the null terminator.
buf := make([]byte, plen+1)
C.glGetProgramInfoLog(C.GLuint(p), C.GLsizei(len(buf)), &plen, (*C.GLchar)(unsafe.Pointer(&buf[0])))
return string(buf[:len(buf)-1])
}
func (f *Functions) GetQueryObjectuiv(query Query, pname Enum) uint {
// Hope this is enough room.
var buf [100]C.GLuint
C.gio_glGetQueryObjectuiv(C.GLuint(query), C.GLenum(pname), &buf[0])
return uint(buf[0])
}
func (f *Functions) GetShaderi(s Shader, pname Enum) int {
// Hope this is enough room.
var buf [100]C.GLint
C.glGetShaderiv(C.GLuint(s), C.GLenum(pname), &buf[0])
return int(buf[0])
}
func (f *Functions) GetShaderInfoLog(s Shader) string {
var plen C.GLsizei
C.glGetShaderInfoLog(C.GLuint(s), 0, &plen, nil)
if plen == 0 {
return ""
}
// Make room for the string and the null terminator.
buf := make([]byte, plen+1)
C.glGetShaderInfoLog(C.GLuint(s), C.GLsizei(len(buf)), &plen, (*C.GLchar)(unsafe.Pointer(&buf[0])))
return string(buf[:len(buf)-1])
}
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(C.glGetUniformLocation(C.GLuint(p), 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))
}
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) 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), 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), C.GLfloat(v))
}
func (f *Functions) Uniform1i(dst Uniform, v int) {
C.glUniform1i(C.GLint(dst), C.GLint(v))
}
func (f *Functions) Uniform2f(dst Uniform, v0 float32, v1 float32) {
C.glUniform2f(C.GLint(dst), C.GLfloat(v0), C.GLfloat(v1))
}
func (f *Functions) Uniform3f(dst Uniform, v0 float32, v1 float32, v2 float32) {
C.glUniform3f(C.GLint(dst), 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), C.GLfloat(v0), C.GLfloat(v1), C.GLfloat(v2), C.GLfloat(v3))
}
func (f *Functions) UseProgram(p Program) {
C.glUseProgram(C.GLuint(p))
}
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))
}
+166
View File
@@ -0,0 +1,166 @@
// SPDX-License-Identifier: Unlicense OR MIT
package gl
type (
Attrib uint
Buffer uint
Enum uint
Framebuffer uint
Program uint
Renderbuffer uint
Shader uint
Texture uint
Uniform int
Query uint
)
type Context interface {
Functions() *Functions
Present() error
MakeCurrent() error
Release()
}
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
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
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)
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)
+397
View File
@@ -0,0 +1,397 @@
// SPDX-License-Identifier: Unlicense OR MIT
package gl
import (
"math"
"reflect"
"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")
_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{}
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), uintptr(s), 0)
}
func (f *Functions) BeginQuery(target Enum, query Query) {
syscall.Syscall(_glBeginQuery.Addr(), 2, uintptr(target), uintptr(query), 0)
}
func (c *Functions) BindAttribLocation(p Program, a Attrib, name string) {
cname := cString(name)
syscall.Syscall(_glBindAttribLocation.Addr(), 3, uintptr(p), uintptr(a), uintptr(unsafe.Pointer(&cname[0])))
}
func (c *Functions) BindBuffer(target Enum, b Buffer) {
syscall.Syscall(_glBindBuffer.Addr(), 2, uintptr(target), uintptr(b), 0)
}
func (c *Functions) BindFramebuffer(target Enum, fb Framebuffer) {
syscall.Syscall(_glBindFramebuffer.Addr(), 2, uintptr(target), uintptr(fb), 0)
}
func (c *Functions) BindRenderbuffer(target Enum, rb Renderbuffer) {
syscall.Syscall(_glBindRenderbuffer.Addr(), 2, uintptr(target), uintptr(rb), 0)
}
func (c *Functions) BindTexture(target Enum, t Texture) {
syscall.Syscall(_glBindTexture.Addr(), 2, uintptr(target), uintptr(t), 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 {
syscall.Syscall6(_glBufferData.Addr(), 4, uintptr(target), uintptr(n), uintptr(unsafe.Pointer(&src[0])), uintptr(usage), 0, 0)
}
}
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), 0, 0)
}
func (c *Functions) CreateBuffer() Buffer {
var buf uintptr
syscall.Syscall(_glGenBuffers.Addr(), 2, 1, uintptr(unsafe.Pointer(&buf)), 0)
return Buffer(buf)
}
func (c *Functions) CreateFramebuffer() Framebuffer {
var fb uintptr
syscall.Syscall(_glGenFramebuffers.Addr(), 2, 1, uintptr(unsafe.Pointer(&fb)), 0)
return Framebuffer(fb)
}
func (c *Functions) CreateProgram() Program {
p, _, _ := syscall.Syscall(_glCreateProgram.Addr(), 0, 0, 0, 0)
return Program(p)
}
func (f *Functions) CreateQuery() Query {
var q uintptr
syscall.Syscall(_glGenQueries.Addr(), 2, 1, uintptr(unsafe.Pointer(&q)), 0)
return Query(q)
}
func (c *Functions) CreateRenderbuffer() Renderbuffer {
var rb uintptr
syscall.Syscall(_glGenRenderbuffers.Addr(), 2, 1, uintptr(unsafe.Pointer(&rb)), 0)
return Renderbuffer(rb)
}
func (c *Functions) CreateShader(ty Enum) Shader {
s, _, _ := syscall.Syscall(_glCreateShader.Addr(), 1, uintptr(ty), 0, 0)
return Shader(s)
}
func (c *Functions) CreateTexture() Texture {
var t uintptr
syscall.Syscall(_glGenTextures.Addr(), 2, 1, uintptr(unsafe.Pointer(&t)), 0)
return Texture(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)), 0)
}
func (c *Functions) DeleteProgram(p Program) {
syscall.Syscall(_glDeleteProgram.Addr(), 1, uintptr(p), 0, 0)
}
func (f *Functions) DeleteQuery(query Query) {
syscall.Syscall(_glDeleteQueries.Addr(), 2, 1, uintptr(unsafe.Pointer(&query)), 0)
}
func (c *Functions) DeleteShader(s Shader) {
syscall.Syscall(_glDeleteShader.Addr(), 1, uintptr(s), 0, 0)
}
func (c *Functions) DeleteRenderbuffer(v Renderbuffer) {
syscall.Syscall(_glDeleteRenderbuffers.Addr(), 2, 1, uintptr(unsafe.Pointer(&v)), 0)
}
func (c *Functions) DeleteTexture(v Texture) {
syscall.Syscall(_glDeleteTextures.Addr(), 2, 1, uintptr(unsafe.Pointer(&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), 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), uintptr(level), 0)
}
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 {
// Hopefully enough room.
var params [100]int32
syscall.Syscall(_glGetIntegerv.Addr(), 2, uintptr(pname), uintptr(unsafe.Pointer(&params[0])), 0)
return int(params[0])
}
func (c *Functions) GetProgrami(p Program, pname Enum) int {
// Hopefully enough space.
var params [100]int32
syscall.Syscall(_glGetProgramiv.Addr(), 3, uintptr(p), uintptr(pname), uintptr(unsafe.Pointer(&params[0])))
return int(params[0])
}
func (c *Functions) GetProgramInfoLog(p Program) string {
var n uintptr
syscall.Syscall6(_glGetProgramInfoLog.Addr(), 4, uintptr(p), 0, uintptr(unsafe.Pointer(&n)), 0, 0, 0)
if n == 0 {
return ""
}
// Make space for the null terminator.
buf := make([]byte, n+1)
syscall.Syscall6(_glGetProgramInfoLog.Addr(), 4, uintptr(p), uintptr(len(buf)), uintptr(unsafe.Pointer(&n)), uintptr(unsafe.Pointer(&buf[0])), 0, 0)
return string(buf[:len(buf)-1])
}
func (f *Functions) GetQueryObjectuiv(query Query, pname Enum) uint {
// Hope this is enough room.
var buf [100]int32
syscall.Syscall(_glGetQueryObjectuiv.Addr(), 3, uintptr(query), uintptr(pname), uintptr(unsafe.Pointer(&buf[0])))
return uint(buf[0])
}
func (c *Functions) GetShaderi(s Shader, pname Enum) int {
// Hopefully enough room.
var params [100]int32
syscall.Syscall(_glGetShaderiv.Addr(), 3, uintptr(s), uintptr(pname), uintptr(unsafe.Pointer(&params[0])))
return int(params[0])
}
func (c *Functions) GetShaderInfoLog(s Shader) string {
var n uintptr
syscall.Syscall6(_glGetShaderInfoLog.Addr(), 4, uintptr(s), 0, uintptr(unsafe.Pointer(&n)), 0, 0, 0)
if n == 0 {
return ""
}
// Make space for the null terminator.
buf := make([]byte, n+1)
syscall.Syscall6(_glGetShaderInfoLog.Addr(), 4, uintptr(s), uintptr(len(buf)), uintptr(unsafe.Pointer(&n)), uintptr(unsafe.Pointer(&buf[0])), 0, 0)
return string(buf[:len(buf)-1])
}
func (c *Functions) GetString(pname Enum) string {
s, _, _ := syscall.Syscall(_glGetString.Addr(), 1, uintptr(pname), 0, 0)
return goString(s)
}
func (c *Functions) GetUniformLocation(p Program, name string) Uniform {
cname := cString(name)
u, _, _ := syscall.Syscall(_glGetUniformLocation.Addr(), 2, uintptr(p), uintptr(unsafe.Pointer(&cname[0])), 0)
return Uniform(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), 0, 0)
}
func (c *Functions) PixelStorei(pname Enum, param int32) {
syscall.Syscall(_glPixelStorei.Addr(), 2, uintptr(pname), uintptr(param), 0)
}
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))
syscall.Syscall6(_glShaderSource.Addr(), 4, uintptr(s), 1, uintptr(unsafe.Pointer(&src)), uintptr(unsafe.Pointer(&n)), 0, 0)
}
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 {
syscall.Syscall9(_glTexImage2D.Addr(), 9, uintptr(target), uintptr(level), uintptr(internalFormat), uintptr(width), uintptr(height), 0, uintptr(format), uintptr(ty), uintptr(unsafe.Pointer(&data[0])))
}
}
func (c *Functions) TexSubImage2D(target Enum, level int, x, y, width, height int, format, ty Enum, data []byte) {
syscall.Syscall9(_glTexSubImage2D.Addr(), 9, uintptr(target), uintptr(level), uintptr(x), uintptr(y), uintptr(width), uintptr(height), uintptr(format), uintptr(ty), uintptr(unsafe.Pointer(&data[0])))
}
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), uintptr(math.Float32bits(v)), 0)
}
func (c *Functions) Uniform1i(dst Uniform, v int) {
syscall.Syscall(_glUniform1i.Addr(), 2, uintptr(dst), uintptr(v), 0)
}
func (c *Functions) Uniform2f(dst Uniform, v0, v1 float32) {
syscall.Syscall(_glUniform2f.Addr(), 3, uintptr(dst), 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), 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), 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), 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
}
func goString(s uintptr) string {
if s == 0 {
return ""
}
sh := reflect.SliceHeader{
Data: s,
Len: 1 << 30,
Cap: 1 << 30,
}
sl := *(*[]byte)(unsafe.Pointer(&sh))
var v string
for i, c := range sl {
if c == 0 {
if i > 0 {
v = string(sl[:i-1])
}
break
}
}
return v
}
+160
View File
@@ -0,0 +1,160 @@
// SPDX-License-Identifier: Unlicense OR MIT
package gl
import (
"fmt"
"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, fmt.Errorf("failed to parse OpenGL ES version (%s): %v", glVer, 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, 0)
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, 0)
s.c.DisableVertexAttribArray(0)
s.c.DisableVertexAttribArray(1)
s.c.InvalidateFramebuffer(FRAMEBUFFER, COLOR_ATTACHMENT0)
s.c.InvalidateFramebuffer(FRAMEBUFFER, DEPTH_ATTACHMENT)
// The Android emulator requires framebuffer 0 bound at eglSwapBuffer time.
// Bind the default sRGB framebuffer in afterPresent.
}
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.GetInteger(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())
}
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;
void main() {
vec4 col = texture2D(tex, vUV);
vec3 rgb = col.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));
rgb = vec3(cut.r ? lin.r : exp.r, cut.g ? lin.g : exp.g, cut.b ? lin.b : exp.b);
gl_FragColor = vec4(rgb, col.a);
}
`
)
+85
View File
@@ -0,0 +1,85 @@
// 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 0, err
}
defer ctx.DeleteShader(vs)
fs, err := createShader(ctx, FRAGMENT_SHADER, fsSrc)
if err != nil {
return 0, err
}
defer ctx.DeleteShader(fs)
prog := ctx.CreateProgram()
if prog == 0 {
return 0, 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 0, 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 == -1 {
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 == 0 {
return 0, 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 0, 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 {
if _, err := fmt.Sscanf(glVer, "%d.%d", &ver[0], &ver[1]); err != nil {
return [2]int{}, fmt.Errorf("failed to parse OpenGL ES version (%s): %v", glVer, err)
}
}
return ver, nil
}