From f6f7ed3e3d926b76ba087475bc6e60bedda265b5 Mon Sep 17 00:00:00 2001
From: Hajime Hoshi
Date: Mon, 14 Nov 2022 03:42:37 +0900
Subject: [PATCH] internal/graphicsdriver/opengl/gl: automatically choose
OpenGL and OpenGL ES
Updates #292
---
.github/workflows/test.yml | 2 +-
doc.go | 3 +-
.../graphicsdriver/opengl/context_notjs.go | 4 +-
.../opengl/gl/default_android.go | 6 +-
.../opengl/gl/default_notpurego.go | 152 +++++++++---------
.../opengl/gl/default_purego.go | 152 +++++++++---------
internal/graphicsdriver/opengl/gl/gomobile.go | 2 +-
.../graphicsdriver/opengl/gl/interface.go | 2 +-
.../opengl/gl/procaddr_darwin.go | 15 +-
.../graphicsdriver/opengl/gl/procaddr_gl.go | 48 ------
.../graphicsdriver/opengl/gl/procaddr_gles.go | 48 ------
.../opengl/gl/procaddr_nintendosdk.go | 8 +-
.../opengl/gl/procaddr_others.go | 110 +++++++++++++
.../opengl/gl/procaddr_windows.go | 7 +-
.../graphicsdriver/opengl/graphics_default.go | 7 +-
.../graphicsdriver/opengl/graphics_mobile.go | 6 +-
16 files changed, 308 insertions(+), 264 deletions(-)
delete mode 100644 internal/graphicsdriver/opengl/gl/procaddr_gl.go
delete mode 100644 internal/graphicsdriver/opengl/gl/procaddr_gles.go
create mode 100644 internal/graphicsdriver/opengl/gl/procaddr_others.go
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index cf2c59ede7c0..32ee9c3c4824 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -134,7 +134,7 @@ jobs:
if: runner.os == 'Linux'
run: |
sudo apt-get install libgles2-mesa-dev
- env EBITENGINE_GRAPHICS_LIBRARY=opengl go test -tags=opengles -shuffle=on -v ./...
+ env EBITENGINE_GRAPHICS_LIBRARY=opengl EBITENGINE_OPENGL=es go test -shuffle=on -v ./...
- name: go test (Windows 386)
if: runner.os == 'Windows'
diff --git a/doc.go b/doc.go
index f9acfab661ab..a2b5eec578d7 100644
--- a/doc.go
+++ b/doc.go
@@ -84,6 +84,7 @@
// `EBITENGINE_OPENGL` environment variable specifies various parameters for OpenGL.
// You can specify multiple values separated by a comma. The default value is empty (i.e. no parameters).
//
+// "es": Use OpenGL ES. Without this, OpenGL and OpenGL ES are automatically chosen.
// "webgl1": Use WebGL 1. This is valid only on browsers.
//
// # Build tags
@@ -99,6 +100,4 @@
// `microsoftgdk` is for Microsoft GDK (e.g. Xbox).
//
// `nintendosdk` is for NintendoSDK (e.g. Nintendo Switch).
-//
-// `opengles` uses OpenGL ES (2) instead of OpenGL.
package ebiten
diff --git a/internal/graphicsdriver/opengl/context_notjs.go b/internal/graphicsdriver/opengl/context_notjs.go
index 1edd2daf2d0d..fa5f9118473e 100644
--- a/internal/graphicsdriver/opengl/context_notjs.go
+++ b/internal/graphicsdriver/opengl/context_notjs.go
@@ -89,8 +89,8 @@ type contextImpl struct {
func (c *context) reset() error {
if !c.init {
- // Initialize OpenGL after WGL is initialized especially for Windows (#2452).
- if err := c.ctx.Init(); err != nil {
+ // Load OpenGL functions after WGL is initialized especially for Windows (#2452).
+ if err := c.ctx.LoadFunctions(); err != nil {
return err
}
c.init = true
diff --git a/internal/graphicsdriver/opengl/gl/default_android.go b/internal/graphicsdriver/opengl/gl/default_android.go
index 067a01ccb5e1..fd3b8879f96b 100644
--- a/internal/graphicsdriver/opengl/gl/default_android.go
+++ b/internal/graphicsdriver/opengl/gl/default_android.go
@@ -33,11 +33,11 @@ func glBool(x bool) C.GLboolean {
type defaultContext struct{}
-func NewDefaultContext() Context {
- return defaultContext{}
+func NewDefaultContext() (Context, error) {
+ return defaultContext{}, nil
}
-func (defaultContext) Init() error {
+func (defaultContext) LoadFunctions() error {
return nil
}
diff --git a/internal/graphicsdriver/opengl/gl/default_notpurego.go b/internal/graphicsdriver/opengl/gl/default_notpurego.go
index 563e1f923c0f..4a40ed239649 100644
--- a/internal/graphicsdriver/opengl/gl/default_notpurego.go
+++ b/internal/graphicsdriver/opengl/gl/default_notpurego.go
@@ -393,10 +393,16 @@ type defaultContext struct {
gpUseProgram C.GPUSEPROGRAM
gpVertexAttribPointer C.GPVERTEXATTRIBPOINTER
gpViewport C.GPVIEWPORT
+
+ isES bool
}
-func NewDefaultContext() Context {
- return &defaultContext{}
+func NewDefaultContext() (Context, error) {
+ ctx := &defaultContext{}
+ if err := ctx.init(); err != nil {
+ return nil, err
+ }
+ return ctx, nil
}
func boolToInt(b bool) int {
@@ -407,7 +413,7 @@ func boolToInt(b bool) int {
}
func (c *defaultContext) IsES() bool {
- return isES
+ return c.isES
}
func (c *defaultContext) ActiveTexture(texture uint32) {
@@ -741,244 +747,244 @@ func (c *defaultContext) Viewport(x int32, y int32, width int32, height int32) {
C.glowViewport(c.gpViewport, (C.GLint)(x), (C.GLint)(y), (C.GLsizei)(width), (C.GLsizei)(height))
}
-func (c *defaultContext) Init() error {
- c.gpActiveTexture = (C.GPACTIVETEXTURE)(getProcAddress("glActiveTexture"))
+func (c *defaultContext) LoadFunctions() error {
+ c.gpActiveTexture = (C.GPACTIVETEXTURE)(c.getProcAddress("glActiveTexture"))
if c.gpActiveTexture == nil {
return errors.New("gl: glActiveTexture is missing")
}
- c.gpAttachShader = (C.GPATTACHSHADER)(getProcAddress("glAttachShader"))
+ c.gpAttachShader = (C.GPATTACHSHADER)(c.getProcAddress("glAttachShader"))
if c.gpAttachShader == nil {
return errors.New("gl: glAttachShader is missing")
}
- c.gpBindAttribLocation = (C.GPBINDATTRIBLOCATION)(getProcAddress("glBindAttribLocation"))
+ c.gpBindAttribLocation = (C.GPBINDATTRIBLOCATION)(c.getProcAddress("glBindAttribLocation"))
if c.gpBindAttribLocation == nil {
return errors.New("gl: glBindAttribLocation is missing")
}
- c.gpBindBuffer = (C.GPBINDBUFFER)(getProcAddress("glBindBuffer"))
+ c.gpBindBuffer = (C.GPBINDBUFFER)(c.getProcAddress("glBindBuffer"))
if c.gpBindBuffer == nil {
return errors.New("gl: glBindBuffer is missing")
}
- c.gpBindFramebufferEXT = (C.GPBINDFRAMEBUFFEREXT)(getProcAddress("glBindFramebufferEXT"))
- c.gpBindRenderbufferEXT = (C.GPBINDRENDERBUFFEREXT)(getProcAddress("glBindRenderbufferEXT"))
- c.gpBindTexture = (C.GPBINDTEXTURE)(getProcAddress("glBindTexture"))
+ c.gpBindFramebufferEXT = (C.GPBINDFRAMEBUFFEREXT)(c.getProcAddress("glBindFramebufferEXT"))
+ c.gpBindRenderbufferEXT = (C.GPBINDRENDERBUFFEREXT)(c.getProcAddress("glBindRenderbufferEXT"))
+ c.gpBindTexture = (C.GPBINDTEXTURE)(c.getProcAddress("glBindTexture"))
if c.gpBindTexture == nil {
return errors.New("gl: glBindTexture is missing")
}
- c.gpBlendEquationSeparate = (C.GPBLENDEQUATIONSEPARATE)(getProcAddress("glBlendEquationSeparate"))
+ c.gpBlendEquationSeparate = (C.GPBLENDEQUATIONSEPARATE)(c.getProcAddress("glBlendEquationSeparate"))
if c.gpBlendEquationSeparate == nil {
return errors.New("gl: glBlendEquationSeparate is missing")
}
- c.gpBlendFuncSeparate = (C.GPBLENDFUNCSEPARATE)(getProcAddress("glBlendFuncSeparate"))
+ c.gpBlendFuncSeparate = (C.GPBLENDFUNCSEPARATE)(c.getProcAddress("glBlendFuncSeparate"))
if c.gpBlendFuncSeparate == nil {
return errors.New("gl: glBlendFuncSeparate is missing")
}
- c.gpBufferData = (C.GPBUFFERDATA)(getProcAddress("glBufferData"))
+ c.gpBufferData = (C.GPBUFFERDATA)(c.getProcAddress("glBufferData"))
if c.gpBufferData == nil {
return errors.New("gl: glBufferData is missing")
}
- c.gpBufferSubData = (C.GPBUFFERSUBDATA)(getProcAddress("glBufferSubData"))
+ c.gpBufferSubData = (C.GPBUFFERSUBDATA)(c.getProcAddress("glBufferSubData"))
if c.gpBufferSubData == nil {
return errors.New("gl: glBufferSubData is missing")
}
- c.gpCheckFramebufferStatusEXT = (C.GPCHECKFRAMEBUFFERSTATUSEXT)(getProcAddress("glCheckFramebufferStatusEXT"))
- c.gpClear = (C.GPCLEAR)(getProcAddress("glClear"))
+ c.gpCheckFramebufferStatusEXT = (C.GPCHECKFRAMEBUFFERSTATUSEXT)(c.getProcAddress("glCheckFramebufferStatusEXT"))
+ c.gpClear = (C.GPCLEAR)(c.getProcAddress("glClear"))
if c.gpClear == nil {
return errors.New("gl: glClear is missing")
}
- c.gpColorMask = (C.GPCOLORMASK)(getProcAddress("glColorMask"))
+ c.gpColorMask = (C.GPCOLORMASK)(c.getProcAddress("glColorMask"))
if c.gpColorMask == nil {
return errors.New("gl: glColorMask is missing")
}
- c.gpCompileShader = (C.GPCOMPILESHADER)(getProcAddress("glCompileShader"))
+ c.gpCompileShader = (C.GPCOMPILESHADER)(c.getProcAddress("glCompileShader"))
if c.gpCompileShader == nil {
return errors.New("gl: glCompileShader is missing")
}
- c.gpCreateProgram = (C.GPCREATEPROGRAM)(getProcAddress("glCreateProgram"))
+ c.gpCreateProgram = (C.GPCREATEPROGRAM)(c.getProcAddress("glCreateProgram"))
if c.gpCreateProgram == nil {
return errors.New("gl: glCreateProgram is missing")
}
- c.gpCreateShader = (C.GPCREATESHADER)(getProcAddress("glCreateShader"))
+ c.gpCreateShader = (C.GPCREATESHADER)(c.getProcAddress("glCreateShader"))
if c.gpCreateShader == nil {
return errors.New("gl: glCreateShader is missing")
}
- c.gpDeleteBuffers = (C.GPDELETEBUFFERS)(getProcAddress("glDeleteBuffers"))
+ c.gpDeleteBuffers = (C.GPDELETEBUFFERS)(c.getProcAddress("glDeleteBuffers"))
if c.gpDeleteBuffers == nil {
return errors.New("gl: glDeleteBuffers is missing")
}
- c.gpDeleteFramebuffersEXT = (C.GPDELETEFRAMEBUFFERSEXT)(getProcAddress("glDeleteFramebuffersEXT"))
- c.gpDeleteProgram = (C.GPDELETEPROGRAM)(getProcAddress("glDeleteProgram"))
+ c.gpDeleteFramebuffersEXT = (C.GPDELETEFRAMEBUFFERSEXT)(c.getProcAddress("glDeleteFramebuffersEXT"))
+ c.gpDeleteProgram = (C.GPDELETEPROGRAM)(c.getProcAddress("glDeleteProgram"))
if c.gpDeleteProgram == nil {
return errors.New("gl: glDeleteProgram is missing")
}
- c.gpDeleteRenderbuffersEXT = (C.GPDELETERENDERBUFFERSEXT)(getProcAddress("glDeleteRenderbuffersEXT"))
- c.gpDeleteShader = (C.GPDELETESHADER)(getProcAddress("glDeleteShader"))
+ c.gpDeleteRenderbuffersEXT = (C.GPDELETERENDERBUFFERSEXT)(c.getProcAddress("glDeleteRenderbuffersEXT"))
+ c.gpDeleteShader = (C.GPDELETESHADER)(c.getProcAddress("glDeleteShader"))
if c.gpDeleteShader == nil {
return errors.New("gl: glDeleteShader is missing")
}
- c.gpDeleteTextures = (C.GPDELETETEXTURES)(getProcAddress("glDeleteTextures"))
+ c.gpDeleteTextures = (C.GPDELETETEXTURES)(c.getProcAddress("glDeleteTextures"))
if c.gpDeleteTextures == nil {
return errors.New("gl: glDeleteTextures is missing")
}
- c.gpDisable = (C.GPDISABLE)(getProcAddress("glDisable"))
+ c.gpDisable = (C.GPDISABLE)(c.getProcAddress("glDisable"))
if c.gpDisable == nil {
return errors.New("gl: glDisable is missing")
}
- c.gpDisableVertexAttribArray = (C.GPDISABLEVERTEXATTRIBARRAY)(getProcAddress("glDisableVertexAttribArray"))
+ c.gpDisableVertexAttribArray = (C.GPDISABLEVERTEXATTRIBARRAY)(c.getProcAddress("glDisableVertexAttribArray"))
if c.gpDisableVertexAttribArray == nil {
return errors.New("gl: glDisableVertexAttribArray is missing")
}
- c.gpDrawElements = (C.GPDRAWELEMENTS)(getProcAddress("glDrawElements"))
+ c.gpDrawElements = (C.GPDRAWELEMENTS)(c.getProcAddress("glDrawElements"))
if c.gpDrawElements == nil {
return errors.New("gl: glDrawElements is missing")
}
- c.gpEnable = (C.GPENABLE)(getProcAddress("glEnable"))
+ c.gpEnable = (C.GPENABLE)(c.getProcAddress("glEnable"))
if c.gpEnable == nil {
return errors.New("gl: glEnable is missing")
}
- c.gpEnableVertexAttribArray = (C.GPENABLEVERTEXATTRIBARRAY)(getProcAddress("glEnableVertexAttribArray"))
+ c.gpEnableVertexAttribArray = (C.GPENABLEVERTEXATTRIBARRAY)(c.getProcAddress("glEnableVertexAttribArray"))
if c.gpEnableVertexAttribArray == nil {
return errors.New("gl: glEnableVertexAttribArray is missing")
}
- c.gpFlush = (C.GPFLUSH)(getProcAddress("glFlush"))
+ c.gpFlush = (C.GPFLUSH)(c.getProcAddress("glFlush"))
if c.gpFlush == nil {
return errors.New("gl: glFlush is missing")
}
- c.gpFramebufferRenderbufferEXT = (C.GPFRAMEBUFFERRENDERBUFFEREXT)(getProcAddress("glFramebufferRenderbufferEXT"))
- c.gpFramebufferTexture2DEXT = (C.GPFRAMEBUFFERTEXTURE2DEXT)(getProcAddress("glFramebufferTexture2DEXT"))
- c.gpGenBuffers = (C.GPGENBUFFERS)(getProcAddress("glGenBuffers"))
+ c.gpFramebufferRenderbufferEXT = (C.GPFRAMEBUFFERRENDERBUFFEREXT)(c.getProcAddress("glFramebufferRenderbufferEXT"))
+ c.gpFramebufferTexture2DEXT = (C.GPFRAMEBUFFERTEXTURE2DEXT)(c.getProcAddress("glFramebufferTexture2DEXT"))
+ c.gpGenBuffers = (C.GPGENBUFFERS)(c.getProcAddress("glGenBuffers"))
if c.gpGenBuffers == nil {
return errors.New("gl: glGenBuffers is missing")
}
- c.gpGenFramebuffersEXT = (C.GPGENFRAMEBUFFERSEXT)(getProcAddress("glGenFramebuffersEXT"))
- c.gpGenRenderbuffersEXT = (C.GPGENRENDERBUFFERSEXT)(getProcAddress("glGenRenderbuffersEXT"))
- c.gpGenTextures = (C.GPGENTEXTURES)(getProcAddress("glGenTextures"))
+ c.gpGenFramebuffersEXT = (C.GPGENFRAMEBUFFERSEXT)(c.getProcAddress("glGenFramebuffersEXT"))
+ c.gpGenRenderbuffersEXT = (C.GPGENRENDERBUFFERSEXT)(c.getProcAddress("glGenRenderbuffersEXT"))
+ c.gpGenTextures = (C.GPGENTEXTURES)(c.getProcAddress("glGenTextures"))
if c.gpGenTextures == nil {
return errors.New("gl: glGenTextures is missing")
}
- c.gpGetError = (C.GPGETERROR)(getProcAddress("glGetError"))
+ c.gpGetError = (C.GPGETERROR)(c.getProcAddress("glGetError"))
if c.gpGetError == nil {
return errors.New("gl: glGetError is missing")
}
- c.gpGetIntegerv = (C.GPGETINTEGERV)(getProcAddress("glGetIntegerv"))
+ c.gpGetIntegerv = (C.GPGETINTEGERV)(c.getProcAddress("glGetIntegerv"))
if c.gpGetIntegerv == nil {
return errors.New("gl: glGetIntegerv is missing")
}
- c.gpGetProgramInfoLog = (C.GPGETPROGRAMINFOLOG)(getProcAddress("glGetProgramInfoLog"))
+ c.gpGetProgramInfoLog = (C.GPGETPROGRAMINFOLOG)(c.getProcAddress("glGetProgramInfoLog"))
if c.gpGetProgramInfoLog == nil {
return errors.New("gl: glGetProgramInfoLog is missing")
}
- c.gpGetProgramiv = (C.GPGETPROGRAMIV)(getProcAddress("glGetProgramiv"))
+ c.gpGetProgramiv = (C.GPGETPROGRAMIV)(c.getProcAddress("glGetProgramiv"))
if c.gpGetProgramiv == nil {
return errors.New("gl: glGetProgramiv is missing")
}
- c.gpGetShaderInfoLog = (C.GPGETSHADERINFOLOG)(getProcAddress("glGetShaderInfoLog"))
+ c.gpGetShaderInfoLog = (C.GPGETSHADERINFOLOG)(c.getProcAddress("glGetShaderInfoLog"))
if c.gpGetShaderInfoLog == nil {
return errors.New("gl: glGetShaderInfoLog is missing")
}
- c.gpGetShaderiv = (C.GPGETSHADERIV)(getProcAddress("glGetShaderiv"))
+ c.gpGetShaderiv = (C.GPGETSHADERIV)(c.getProcAddress("glGetShaderiv"))
if c.gpGetShaderiv == nil {
return errors.New("gl: glGetShaderiv is missing")
}
- c.gpGetUniformLocation = (C.GPGETUNIFORMLOCATION)(getProcAddress("glGetUniformLocation"))
+ c.gpGetUniformLocation = (C.GPGETUNIFORMLOCATION)(c.getProcAddress("glGetUniformLocation"))
if c.gpGetUniformLocation == nil {
return errors.New("gl: glGetUniformLocation is missing")
}
- c.gpIsFramebufferEXT = (C.GPISFRAMEBUFFEREXT)(getProcAddress("glIsFramebufferEXT"))
- c.gpIsProgram = (C.GPISPROGRAM)(getProcAddress("glIsProgram"))
+ c.gpIsFramebufferEXT = (C.GPISFRAMEBUFFEREXT)(c.getProcAddress("glIsFramebufferEXT"))
+ c.gpIsProgram = (C.GPISPROGRAM)(c.getProcAddress("glIsProgram"))
if c.gpIsProgram == nil {
return errors.New("gl: glIsProgram is missing")
}
- c.gpIsRenderbufferEXT = (C.GPISRENDERBUFFEREXT)(getProcAddress("glIsRenderbufferEXT"))
- c.gpIsTexture = (C.GPISTEXTURE)(getProcAddress("glIsTexture"))
+ c.gpIsRenderbufferEXT = (C.GPISRENDERBUFFEREXT)(c.getProcAddress("glIsRenderbufferEXT"))
+ c.gpIsTexture = (C.GPISTEXTURE)(c.getProcAddress("glIsTexture"))
if c.gpIsTexture == nil {
return errors.New("gl: glIsTexture is missing")
}
- c.gpLinkProgram = (C.GPLINKPROGRAM)(getProcAddress("glLinkProgram"))
+ c.gpLinkProgram = (C.GPLINKPROGRAM)(c.getProcAddress("glLinkProgram"))
if c.gpLinkProgram == nil {
return errors.New("gl: glLinkProgram is missing")
}
- c.gpPixelStorei = (C.GPPIXELSTOREI)(getProcAddress("glPixelStorei"))
+ c.gpPixelStorei = (C.GPPIXELSTOREI)(c.getProcAddress("glPixelStorei"))
if c.gpPixelStorei == nil {
return errors.New("gl: glPixelStorei is missing")
}
- c.gpReadPixels = (C.GPREADPIXELS)(getProcAddress("glReadPixels"))
+ c.gpReadPixels = (C.GPREADPIXELS)(c.getProcAddress("glReadPixels"))
if c.gpReadPixels == nil {
return errors.New("gl: glReadPixels is missing")
}
- c.gpRenderbufferStorageEXT = (C.GPRENDERBUFFERSTORAGEEXT)(getProcAddress("glRenderbufferStorageEXT"))
- c.gpScissor = (C.GPSCISSOR)(getProcAddress("glScissor"))
+ c.gpRenderbufferStorageEXT = (C.GPRENDERBUFFERSTORAGEEXT)(c.getProcAddress("glRenderbufferStorageEXT"))
+ c.gpScissor = (C.GPSCISSOR)(c.getProcAddress("glScissor"))
if c.gpScissor == nil {
return errors.New("gl: glScissor is missing")
}
- c.gpShaderSource = (C.GPSHADERSOURCE)(getProcAddress("glShaderSource"))
+ c.gpShaderSource = (C.GPSHADERSOURCE)(c.getProcAddress("glShaderSource"))
if c.gpShaderSource == nil {
return errors.New("gl: glShaderSource is missing")
}
- c.gpStencilFunc = (C.GPSTENCILFUNC)(getProcAddress("glStencilFunc"))
+ c.gpStencilFunc = (C.GPSTENCILFUNC)(c.getProcAddress("glStencilFunc"))
if c.gpStencilFunc == nil {
return errors.New("gl: glStencilFunc is missing")
}
- c.gpStencilOp = (C.GPSTENCILOP)(getProcAddress("glStencilOp"))
+ c.gpStencilOp = (C.GPSTENCILOP)(c.getProcAddress("glStencilOp"))
if c.gpStencilOp == nil {
return errors.New("gl: glStencilOp is missing")
}
- c.gpTexImage2D = (C.GPTEXIMAGE2D)(getProcAddress("glTexImage2D"))
+ c.gpTexImage2D = (C.GPTEXIMAGE2D)(c.getProcAddress("glTexImage2D"))
if c.gpTexImage2D == nil {
return errors.New("gl: glTexImage2D is missing")
}
- c.gpTexParameteri = (C.GPTEXPARAMETERI)(getProcAddress("glTexParameteri"))
+ c.gpTexParameteri = (C.GPTEXPARAMETERI)(c.getProcAddress("glTexParameteri"))
if c.gpTexParameteri == nil {
return errors.New("gl: glTexParameteri is missing")
}
- c.gpTexSubImage2D = (C.GPTEXSUBIMAGE2D)(getProcAddress("glTexSubImage2D"))
+ c.gpTexSubImage2D = (C.GPTEXSUBIMAGE2D)(c.getProcAddress("glTexSubImage2D"))
if c.gpTexSubImage2D == nil {
return errors.New("gl: glTexSubImage2D is missing")
}
- c.gpUniform1fv = (C.GPUNIFORM1FV)(getProcAddress("glUniform1fv"))
+ c.gpUniform1fv = (C.GPUNIFORM1FV)(c.getProcAddress("glUniform1fv"))
if c.gpUniform1fv == nil {
return errors.New("gl: glUniform1fv is missing")
}
- c.gpUniform1i = (C.GPUNIFORM1I)(getProcAddress("glUniform1i"))
+ c.gpUniform1i = (C.GPUNIFORM1I)(c.getProcAddress("glUniform1i"))
if c.gpUniform1i == nil {
return errors.New("gl: glUniform1i is missing")
}
- c.gpUniform1iv = (C.GPUNIFORM1IV)(getProcAddress("glUniform1iv"))
+ c.gpUniform1iv = (C.GPUNIFORM1IV)(c.getProcAddress("glUniform1iv"))
if c.gpUniform1iv == nil {
return errors.New("gl: glUniform1iv is missing")
}
- c.gpUniform2fv = (C.GPUNIFORM2FV)(getProcAddress("glUniform2fv"))
+ c.gpUniform2fv = (C.GPUNIFORM2FV)(c.getProcAddress("glUniform2fv"))
if c.gpUniform2fv == nil {
return errors.New("gl: glUniform2fv is missing")
}
- c.gpUniform3fv = (C.GPUNIFORM3FV)(getProcAddress("glUniform3fv"))
+ c.gpUniform3fv = (C.GPUNIFORM3FV)(c.getProcAddress("glUniform3fv"))
if c.gpUniform3fv == nil {
return errors.New("gl: glUniform3fv is missing")
}
- c.gpUniform4fv = (C.GPUNIFORM4FV)(getProcAddress("glUniform4fv"))
+ c.gpUniform4fv = (C.GPUNIFORM4FV)(c.getProcAddress("glUniform4fv"))
if c.gpUniform4fv == nil {
return errors.New("gl: glUniform4fv is missing")
}
- c.gpUniformMatrix2fv = (C.GPUNIFORMMATRIX2FV)(getProcAddress("glUniformMatrix2fv"))
+ c.gpUniformMatrix2fv = (C.GPUNIFORMMATRIX2FV)(c.getProcAddress("glUniformMatrix2fv"))
if c.gpUniformMatrix2fv == nil {
return errors.New("gl: glUniformMatrix2fv is missing")
}
- c.gpUniformMatrix3fv = (C.GPUNIFORMMATRIX3FV)(getProcAddress("glUniformMatrix3fv"))
+ c.gpUniformMatrix3fv = (C.GPUNIFORMMATRIX3FV)(c.getProcAddress("glUniformMatrix3fv"))
if c.gpUniformMatrix3fv == nil {
return errors.New("gl: glUniformMatrix3fv is missing")
}
- c.gpUniformMatrix4fv = (C.GPUNIFORMMATRIX4FV)(getProcAddress("glUniformMatrix4fv"))
+ c.gpUniformMatrix4fv = (C.GPUNIFORMMATRIX4FV)(c.getProcAddress("glUniformMatrix4fv"))
if c.gpUniformMatrix4fv == nil {
return errors.New("gl: glUniformMatrix4fv is missing")
}
- c.gpUseProgram = (C.GPUSEPROGRAM)(getProcAddress("glUseProgram"))
+ c.gpUseProgram = (C.GPUSEPROGRAM)(c.getProcAddress("glUseProgram"))
if c.gpUseProgram == nil {
return errors.New("gl: glUseProgram is missing")
}
- c.gpVertexAttribPointer = (C.GPVERTEXATTRIBPOINTER)(getProcAddress("glVertexAttribPointer"))
+ c.gpVertexAttribPointer = (C.GPVERTEXATTRIBPOINTER)(c.getProcAddress("glVertexAttribPointer"))
if c.gpVertexAttribPointer == nil {
return errors.New("gl: glVertexAttribPointer is missing")
}
- c.gpViewport = (C.GPVIEWPORT)(getProcAddress("glViewport"))
+ c.gpViewport = (C.GPVIEWPORT)(c.getProcAddress("glViewport"))
if c.gpViewport == nil {
return errors.New("gl: glViewport is missing")
}
diff --git a/internal/graphicsdriver/opengl/gl/default_purego.go b/internal/graphicsdriver/opengl/gl/default_purego.go
index f6b02befc929..08bf6e42ed9c 100644
--- a/internal/graphicsdriver/opengl/gl/default_purego.go
+++ b/internal/graphicsdriver/opengl/gl/default_purego.go
@@ -94,10 +94,16 @@ type defaultContext struct {
gpUseProgram uintptr
gpVertexAttribPointer uintptr
gpViewport uintptr
+
+ isES bool
}
-func NewDefaultContext() Context {
- return &defaultContext{}
+func NewDefaultContext() (Context, error) {
+ ctx := &defaultContext{}
+ if err := ctx.init(); err != nil {
+ return nil, err
+ }
+ return ctx, nil
}
func boolToInt(b bool) int {
@@ -108,7 +114,7 @@ func boolToInt(b bool) int {
}
func (c *defaultContext) IsES() bool {
- return isES
+ return c.isES
}
func (c *defaultContext) ActiveTexture(texture uint32) {
@@ -440,244 +446,244 @@ func (c *defaultContext) Viewport(x int32, y int32, width int32, height int32) {
purego.SyscallN(c.gpViewport, uintptr(x), uintptr(y), uintptr(width), uintptr(height))
}
-func (c *defaultContext) Init() error {
- c.gpActiveTexture = getProcAddress("glActiveTexture")
+func (c *defaultContext) LoadFunctions() error {
+ c.gpActiveTexture = c.getProcAddress("glActiveTexture")
if c.gpActiveTexture == 0 {
return errors.New("gl: glActiveTexture is missing")
}
- c.gpAttachShader = getProcAddress("glAttachShader")
+ c.gpAttachShader = c.getProcAddress("glAttachShader")
if c.gpAttachShader == 0 {
return errors.New("gl: glAttachShader is missing")
}
- c.gpBindAttribLocation = getProcAddress("glBindAttribLocation")
+ c.gpBindAttribLocation = c.getProcAddress("glBindAttribLocation")
if c.gpBindAttribLocation == 0 {
return errors.New("gl: glBindAttribLocation is missing")
}
- c.gpBindBuffer = getProcAddress("glBindBuffer")
+ c.gpBindBuffer = c.getProcAddress("glBindBuffer")
if c.gpBindBuffer == 0 {
return errors.New("gl: glBindBuffer is missing")
}
- c.gpBindFramebufferEXT = getProcAddress("glBindFramebufferEXT")
- c.gpBindRenderbufferEXT = getProcAddress("glBindRenderbufferEXT")
- c.gpBindTexture = getProcAddress("glBindTexture")
+ c.gpBindFramebufferEXT = c.getProcAddress("glBindFramebufferEXT")
+ c.gpBindRenderbufferEXT = c.getProcAddress("glBindRenderbufferEXT")
+ c.gpBindTexture = c.getProcAddress("glBindTexture")
if c.gpBindTexture == 0 {
return errors.New("gl: glBindTexture is missing")
}
- c.gpBlendEquationSeparate = getProcAddress("glBlendEquationSeparate")
+ c.gpBlendEquationSeparate = c.getProcAddress("glBlendEquationSeparate")
if c.gpBlendEquationSeparate == 0 {
return errors.New("gl: glBlendEquationSeparate is missing")
}
- c.gpBlendFuncSeparate = getProcAddress("glBlendFuncSeparate")
+ c.gpBlendFuncSeparate = c.getProcAddress("glBlendFuncSeparate")
if c.gpBlendFuncSeparate == 0 {
return errors.New("gl: glBlendFuncSeparate is missing")
}
- c.gpBufferData = getProcAddress("glBufferData")
+ c.gpBufferData = c.getProcAddress("glBufferData")
if c.gpBufferData == 0 {
return errors.New("gl: glBufferData is missing")
}
- c.gpBufferSubData = getProcAddress("glBufferSubData")
+ c.gpBufferSubData = c.getProcAddress("glBufferSubData")
if c.gpBufferSubData == 0 {
return errors.New("gl: glBufferSubData is missing")
}
- c.gpCheckFramebufferStatusEXT = getProcAddress("glCheckFramebufferStatusEXT")
- c.gpClear = getProcAddress("glClear")
+ c.gpCheckFramebufferStatusEXT = c.getProcAddress("glCheckFramebufferStatusEXT")
+ c.gpClear = c.getProcAddress("glClear")
if c.gpClear == 0 {
return errors.New("gl: glClear is missing")
}
- c.gpColorMask = getProcAddress("glColorMask")
+ c.gpColorMask = c.getProcAddress("glColorMask")
if c.gpColorMask == 0 {
return errors.New("gl: glColorMask is missing")
}
- c.gpCompileShader = getProcAddress("glCompileShader")
+ c.gpCompileShader = c.getProcAddress("glCompileShader")
if c.gpCompileShader == 0 {
return errors.New("gl: glCompileShader is missing")
}
- c.gpCreateProgram = getProcAddress("glCreateProgram")
+ c.gpCreateProgram = c.getProcAddress("glCreateProgram")
if c.gpCreateProgram == 0 {
return errors.New("gl: glCreateProgram is missing")
}
- c.gpCreateShader = getProcAddress("glCreateShader")
+ c.gpCreateShader = c.getProcAddress("glCreateShader")
if c.gpCreateShader == 0 {
return errors.New("gl: glCreateShader is missing")
}
- c.gpDeleteBuffers = getProcAddress("glDeleteBuffers")
+ c.gpDeleteBuffers = c.getProcAddress("glDeleteBuffers")
if c.gpDeleteBuffers == 0 {
return errors.New("gl: glDeleteBuffers is missing")
}
- c.gpDeleteFramebuffersEXT = getProcAddress("glDeleteFramebuffersEXT")
- c.gpDeleteProgram = getProcAddress("glDeleteProgram")
+ c.gpDeleteFramebuffersEXT = c.getProcAddress("glDeleteFramebuffersEXT")
+ c.gpDeleteProgram = c.getProcAddress("glDeleteProgram")
if c.gpDeleteProgram == 0 {
return errors.New("gl: glDeleteProgram is missing")
}
- c.gpDeleteRenderbuffersEXT = getProcAddress("glDeleteRenderbuffersEXT")
- c.gpDeleteShader = getProcAddress("glDeleteShader")
+ c.gpDeleteRenderbuffersEXT = c.getProcAddress("glDeleteRenderbuffersEXT")
+ c.gpDeleteShader = c.getProcAddress("glDeleteShader")
if c.gpDeleteShader == 0 {
return errors.New("gl: glDeleteShader is missing")
}
- c.gpDeleteTextures = getProcAddress("glDeleteTextures")
+ c.gpDeleteTextures = c.getProcAddress("glDeleteTextures")
if c.gpDeleteTextures == 0 {
return errors.New("gl: glDeleteTextures is missing")
}
- c.gpDisable = getProcAddress("glDisable")
+ c.gpDisable = c.getProcAddress("glDisable")
if c.gpDisable == 0 {
return errors.New("gl: glDisable is missing")
}
- c.gpDisableVertexAttribArray = getProcAddress("glDisableVertexAttribArray")
+ c.gpDisableVertexAttribArray = c.getProcAddress("glDisableVertexAttribArray")
if c.gpDisableVertexAttribArray == 0 {
return errors.New("gl: glDisableVertexAttribArray is missing")
}
- c.gpDrawElements = getProcAddress("glDrawElements")
+ c.gpDrawElements = c.getProcAddress("glDrawElements")
if c.gpDrawElements == 0 {
return errors.New("gl: glDrawElements is missing")
}
- c.gpEnable = getProcAddress("glEnable")
+ c.gpEnable = c.getProcAddress("glEnable")
if c.gpEnable == 0 {
return errors.New("gl: glEnable is missing")
}
- c.gpEnableVertexAttribArray = getProcAddress("glEnableVertexAttribArray")
+ c.gpEnableVertexAttribArray = c.getProcAddress("glEnableVertexAttribArray")
if c.gpEnableVertexAttribArray == 0 {
return errors.New("gl: glEnableVertexAttribArray is missing")
}
- c.gpFlush = getProcAddress("glFlush")
+ c.gpFlush = c.getProcAddress("glFlush")
if c.gpFlush == 0 {
return errors.New("gl: glFlush is missing")
}
- c.gpFramebufferRenderbufferEXT = getProcAddress("glFramebufferRenderbufferEXT")
- c.gpFramebufferTexture2DEXT = getProcAddress("glFramebufferTexture2DEXT")
- c.gpGenBuffers = getProcAddress("glGenBuffers")
+ c.gpFramebufferRenderbufferEXT = c.getProcAddress("glFramebufferRenderbufferEXT")
+ c.gpFramebufferTexture2DEXT = c.getProcAddress("glFramebufferTexture2DEXT")
+ c.gpGenBuffers = c.getProcAddress("glGenBuffers")
if c.gpGenBuffers == 0 {
return errors.New("gl: glGenBuffers is missing")
}
- c.gpGenFramebuffersEXT = getProcAddress("glGenFramebuffersEXT")
- c.gpGenRenderbuffersEXT = getProcAddress("glGenRenderbuffersEXT")
- c.gpGenTextures = getProcAddress("glGenTextures")
+ c.gpGenFramebuffersEXT = c.getProcAddress("glGenFramebuffersEXT")
+ c.gpGenRenderbuffersEXT = c.getProcAddress("glGenRenderbuffersEXT")
+ c.gpGenTextures = c.getProcAddress("glGenTextures")
if c.gpGenTextures == 0 {
return errors.New("gl: glGenTextures is missing")
}
- c.gpGetError = getProcAddress("glGetError")
+ c.gpGetError = c.getProcAddress("glGetError")
if c.gpGetError == 0 {
return errors.New("gl: glGetError is missing")
}
- c.gpGetIntegerv = getProcAddress("glGetIntegerv")
+ c.gpGetIntegerv = c.getProcAddress("glGetIntegerv")
if c.gpGetIntegerv == 0 {
return errors.New("gl: glGetIntegerv is missing")
}
- c.gpGetProgramInfoLog = getProcAddress("glGetProgramInfoLog")
+ c.gpGetProgramInfoLog = c.getProcAddress("glGetProgramInfoLog")
if c.gpGetProgramInfoLog == 0 {
return errors.New("gl: glGetProgramInfoLog is missing")
}
- c.gpGetProgramiv = getProcAddress("glGetProgramiv")
+ c.gpGetProgramiv = c.getProcAddress("glGetProgramiv")
if c.gpGetProgramiv == 0 {
return errors.New("gl: glGetProgramiv is missing")
}
- c.gpGetShaderInfoLog = getProcAddress("glGetShaderInfoLog")
+ c.gpGetShaderInfoLog = c.getProcAddress("glGetShaderInfoLog")
if c.gpGetShaderInfoLog == 0 {
return errors.New("gl: glGetShaderInfoLog is missing")
}
- c.gpGetShaderiv = getProcAddress("glGetShaderiv")
+ c.gpGetShaderiv = c.getProcAddress("glGetShaderiv")
if c.gpGetShaderiv == 0 {
return errors.New("gl: glGetShaderiv is missing")
}
- c.gpGetUniformLocation = getProcAddress("glGetUniformLocation")
+ c.gpGetUniformLocation = c.getProcAddress("glGetUniformLocation")
if c.gpGetUniformLocation == 0 {
return errors.New("gl: glGetUniformLocation is missing")
}
- c.gpIsFramebufferEXT = getProcAddress("glIsFramebufferEXT")
- c.gpIsProgram = getProcAddress("glIsProgram")
+ c.gpIsFramebufferEXT = c.getProcAddress("glIsFramebufferEXT")
+ c.gpIsProgram = c.getProcAddress("glIsProgram")
if c.gpIsProgram == 0 {
return errors.New("gl: glIsProgram is missing")
}
- c.gpIsRenderbufferEXT = getProcAddress("glIsRenderbufferEXT")
- c.gpIsTexture = getProcAddress("glIsTexture")
+ c.gpIsRenderbufferEXT = c.getProcAddress("glIsRenderbufferEXT")
+ c.gpIsTexture = c.getProcAddress("glIsTexture")
if c.gpIsTexture == 0 {
return errors.New("gl: glIsTexture is missing")
}
- c.gpLinkProgram = getProcAddress("glLinkProgram")
+ c.gpLinkProgram = c.getProcAddress("glLinkProgram")
if c.gpLinkProgram == 0 {
return errors.New("gl: glLinkProgram is missing")
}
- c.gpPixelStorei = getProcAddress("glPixelStorei")
+ c.gpPixelStorei = c.getProcAddress("glPixelStorei")
if c.gpPixelStorei == 0 {
return errors.New("gl: glPixelStorei is missing")
}
- c.gpReadPixels = getProcAddress("glReadPixels")
+ c.gpReadPixels = c.getProcAddress("glReadPixels")
if c.gpReadPixels == 0 {
return errors.New("gl: glReadPixels is missing")
}
- c.gpRenderbufferStorageEXT = getProcAddress("glRenderbufferStorageEXT")
- c.gpScissor = getProcAddress("glScissor")
+ c.gpRenderbufferStorageEXT = c.getProcAddress("glRenderbufferStorageEXT")
+ c.gpScissor = c.getProcAddress("glScissor")
if c.gpScissor == 0 {
return errors.New("gl: glScissor is missing")
}
- c.gpShaderSource = getProcAddress("glShaderSource")
+ c.gpShaderSource = c.getProcAddress("glShaderSource")
if c.gpShaderSource == 0 {
return errors.New("gl: glShaderSource is missing")
}
- c.gpStencilFunc = getProcAddress("glStencilFunc")
+ c.gpStencilFunc = c.getProcAddress("glStencilFunc")
if c.gpStencilFunc == 0 {
return errors.New("gl: glStencilFunc is missing")
}
- c.gpStencilOp = getProcAddress("glStencilOp")
+ c.gpStencilOp = c.getProcAddress("glStencilOp")
if c.gpStencilOp == 0 {
return errors.New("gl: glStencilOp is missing")
}
- c.gpTexImage2D = getProcAddress("glTexImage2D")
+ c.gpTexImage2D = c.getProcAddress("glTexImage2D")
if c.gpTexImage2D == 0 {
return errors.New("gl: glTexImage2D is missing")
}
- c.gpTexParameteri = getProcAddress("glTexParameteri")
+ c.gpTexParameteri = c.getProcAddress("glTexParameteri")
if c.gpTexParameteri == 0 {
return errors.New("gl: glTexParameteri is missing")
}
- c.gpTexSubImage2D = getProcAddress("glTexSubImage2D")
+ c.gpTexSubImage2D = c.getProcAddress("glTexSubImage2D")
if c.gpTexSubImage2D == 0 {
return errors.New("gl: glTexSubImage2D is missing")
}
- c.gpUniform1fv = getProcAddress("glUniform1fv")
+ c.gpUniform1fv = c.getProcAddress("glUniform1fv")
if c.gpUniform1fv == 0 {
return errors.New("gl: glUniform1fv is missing")
}
- c.gpUniform1i = getProcAddress("glUniform1i")
+ c.gpUniform1i = c.getProcAddress("glUniform1i")
if c.gpUniform1i == 0 {
return errors.New("gl: glUniform1i is missing")
}
- c.gpUniform1iv = getProcAddress("glUniform1iv")
+ c.gpUniform1iv = c.getProcAddress("glUniform1iv")
if c.gpUniform1iv == 0 {
return errors.New("gl: glUniform1iv is missing")
}
- c.gpUniform2fv = getProcAddress("glUniform2fv")
+ c.gpUniform2fv = c.getProcAddress("glUniform2fv")
if c.gpUniform2fv == 0 {
return errors.New("gl: glUniform2fv is missing")
}
- c.gpUniform3fv = getProcAddress("glUniform3fv")
+ c.gpUniform3fv = c.getProcAddress("glUniform3fv")
if c.gpUniform3fv == 0 {
return errors.New("gl: glUniform3fv is missing")
}
- c.gpUniform4fv = getProcAddress("glUniform4fv")
+ c.gpUniform4fv = c.getProcAddress("glUniform4fv")
if c.gpUniform4fv == 0 {
return errors.New("gl: glUniform4fv is missing")
}
- c.gpUniformMatrix2fv = getProcAddress("glUniformMatrix2fv")
+ c.gpUniformMatrix2fv = c.getProcAddress("glUniformMatrix2fv")
if c.gpUniformMatrix2fv == 0 {
return errors.New("gl: glUniformMatrix2fv is missing")
}
- c.gpUniformMatrix3fv = getProcAddress("glUniformMatrix3fv")
+ c.gpUniformMatrix3fv = c.getProcAddress("glUniformMatrix3fv")
if c.gpUniformMatrix3fv == 0 {
return errors.New("gl: glUniformMatrix3fv is missing")
}
- c.gpUniformMatrix4fv = getProcAddress("glUniformMatrix4fv")
+ c.gpUniformMatrix4fv = c.getProcAddress("glUniformMatrix4fv")
if c.gpUniformMatrix4fv == 0 {
return errors.New("gl: glUniformMatrix4fv is missing")
}
- c.gpUseProgram = getProcAddress("glUseProgram")
+ c.gpUseProgram = c.getProcAddress("glUseProgram")
if c.gpUseProgram == 0 {
return errors.New("gl: glUseProgram is missing")
}
- c.gpVertexAttribPointer = getProcAddress("glVertexAttribPointer")
+ c.gpVertexAttribPointer = c.getProcAddress("glVertexAttribPointer")
if c.gpVertexAttribPointer == 0 {
return errors.New("gl: glVertexAttribPointer is missing")
}
- c.gpViewport = getProcAddress("glViewport")
+ c.gpViewport = c.getProcAddress("glViewport")
if c.gpViewport == 0 {
return errors.New("gl: glViewport is missing")
}
diff --git a/internal/graphicsdriver/opengl/gl/gomobile.go b/internal/graphicsdriver/opengl/gl/gomobile.go
index 45a597a2d3a9..00b4d1e7b270 100644
--- a/internal/graphicsdriver/opengl/gl/gomobile.go
+++ b/internal/graphicsdriver/opengl/gl/gomobile.go
@@ -35,7 +35,7 @@ func NewGomobileContext(ctx gl.Context) Context {
return &gomobileContext{ctx}
}
-func (g *gomobileContext) Init() error {
+func (g *gomobileContext) LoadFunctions() error {
return nil
}
diff --git a/internal/graphicsdriver/opengl/gl/interface.go b/internal/graphicsdriver/opengl/gl/interface.go
index e5a011f07de6..f06a81186d99 100644
--- a/internal/graphicsdriver/opengl/gl/interface.go
+++ b/internal/graphicsdriver/opengl/gl/interface.go
@@ -19,7 +19,7 @@ package gl
// Context is basically the same as gomobile's gl.Context.
// See https://pkg.go.dev/golang.org/x/mobile/gl#Context
type Context interface {
- Init() error
+ LoadFunctions() error
IsES() bool
ActiveTexture(texture uint32)
diff --git a/internal/graphicsdriver/opengl/gl/procaddr_darwin.go b/internal/graphicsdriver/opengl/gl/procaddr_darwin.go
index c901b24a7a75..2b2cf21ef9d7 100644
--- a/internal/graphicsdriver/opengl/gl/procaddr_darwin.go
+++ b/internal/graphicsdriver/opengl/gl/procaddr_darwin.go
@@ -15,23 +15,28 @@
package gl
import (
+ "fmt"
+
"github.com/ebitengine/purego"
)
var (
opengl uintptr
- isES bool
)
-func init() {
+func (c *defaultContext) init() error {
opengl = purego.Dlopen("/System/Library/Frameworks/OpenGLES.framework/Versions/Current/OpenGLES", purego.RTLD_LAZY|purego.RTLD_GLOBAL)
if opengl != 0 {
- isES = true
- return
+ c.isES = true
+ return nil
}
opengl = purego.Dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", purego.RTLD_LAZY|purego.RTLD_GLOBAL)
+ if opengl != 0 {
+ return nil
+ }
+ return fmt.Errorf("gl: failed to load OpenGL.framework and OpenGLES.framework")
}
-func getProcAddress(name string) uintptr {
+func (c *defaultContext) getProcAddress(name string) uintptr {
return purego.Dlsym(opengl, name)
}
diff --git a/internal/graphicsdriver/opengl/gl/procaddr_gl.go b/internal/graphicsdriver/opengl/gl/procaddr_gl.go
deleted file mode 100644
index f16d502e76d2..000000000000
--- a/internal/graphicsdriver/opengl/gl/procaddr_gl.go
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2022 The Ebitengine Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-//go:build !android && !darwin && !js && !nintendosdk && !windows && !opengles
-
-package gl
-
-// #cgo LDFLAGS: -ldl
-//
-// #include
-// #include
-//
-// static void* getProcAddress(const char* name) {
-// static void* libGL;
-// if (!libGL) {
-// libGL = dlopen("libGL.so", RTLD_LAZY | RTLD_GLOBAL);
-// }
-// static void*(*glXGetProcAddress)(const char*);
-// if (!glXGetProcAddress) {
-// glXGetProcAddress = dlsym(libGL, "glXGetProcAddress");
-// if (!glXGetProcAddress) {
-// glXGetProcAddress = dlsym(libGL, "glXGetProcAddressARB");
-// }
-// }
-// return glXGetProcAddress(name);
-// }
-import "C"
-
-import "unsafe"
-
-var isES = false
-
-func getProcAddress(namea string) unsafe.Pointer {
- cname := C.CString(namea)
- defer C.free(unsafe.Pointer(cname))
- return C.getProcAddress(cname)
-}
diff --git a/internal/graphicsdriver/opengl/gl/procaddr_gles.go b/internal/graphicsdriver/opengl/gl/procaddr_gles.go
deleted file mode 100644
index 9831887ada39..000000000000
--- a/internal/graphicsdriver/opengl/gl/procaddr_gles.go
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2022 The Ebitengine Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-//go:build !android && !darwin && !js && !nintendosdk && !windows && opengles
-
-package gl
-
-// #cgo LDFLAGS: -ldl
-//
-// #include
-// #include
-//
-// static void* getProcAddress(const char* name) {
-// static void* libGLES;
-// if (!libGLES) {
-// libGLES = dlopen("libGLESv2.so", RTLD_LAZY | RTLD_GLOBAL);
-// }
-// return dlsym(libGLES, name);
-// }
-import "C"
-
-import (
- "strings"
- "unsafe"
-)
-
-var isES = true
-
-func getProcAddress(namea string) unsafe.Pointer {
- const ext = "EXT"
- if strings.HasSuffix(namea, ext) {
- namea = namea[:len(namea)-len(ext)]
- }
- cname := C.CString(namea)
- defer C.free(unsafe.Pointer(cname))
- return C.getProcAddress(cname)
-}
diff --git a/internal/graphicsdriver/opengl/gl/procaddr_nintendosdk.go b/internal/graphicsdriver/opengl/gl/procaddr_nintendosdk.go
index cb2c26786b49..6ff409a02a7c 100644
--- a/internal/graphicsdriver/opengl/gl/procaddr_nintendosdk.go
+++ b/internal/graphicsdriver/opengl/gl/procaddr_nintendosdk.go
@@ -28,10 +28,12 @@ import "C"
import "unsafe"
-var isES = false
+func (c *defaultContext) init() error {
+ return nil
+}
-func getProcAddress(namea string) unsafe.Pointer {
- cname := C.CString(namea)
+func (c *defaultContext) getProcAddress(name string) unsafe.Pointer {
+ cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))
return C.getProcAddress(cname)
}
diff --git a/internal/graphicsdriver/opengl/gl/procaddr_others.go b/internal/graphicsdriver/opengl/gl/procaddr_others.go
new file mode 100644
index 000000000000..041c144b1c48
--- /dev/null
+++ b/internal/graphicsdriver/opengl/gl/procaddr_others.go
@@ -0,0 +1,110 @@
+// Copyright 2022 The Ebitengine Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//go:build !android && !darwin && !js && !nintendosdk && !windows
+
+package gl
+
+// #cgo LDFLAGS: -ldl
+//
+// #include
+// #include
+//
+// static void* libGL() {
+// static void* so;
+// if (!so) {
+// so = dlopen("libGL.so", RTLD_LAZY | RTLD_GLOBAL);
+// }
+// return so;
+// }
+//
+// static void* libGLES() {
+// static void* so;
+// if (!so) {
+// so = dlopen("libGLESv2.so", RTLD_LAZY | RTLD_GLOBAL);
+// }
+// return so;
+// }
+//
+// static void* getProcAddressGL(const char* name) {
+// static void*(*glXGetProcAddress)(const char*);
+// if (!glXGetProcAddress) {
+// glXGetProcAddress = dlsym(libGL(), "glXGetProcAddress");
+// if (!glXGetProcAddress) {
+// glXGetProcAddress = dlsym(libGL(), "glXGetProcAddressARB");
+// }
+// }
+// return glXGetProcAddress(name);
+// }
+//
+// static void* getProcAddressGLES(const char* name) {
+// return dlsym(libGLES(), name);
+// }
+import "C"
+
+import (
+ "fmt"
+ "os"
+ "strings"
+ "unsafe"
+)
+
+func (c *defaultContext) init() error {
+ var preferES bool
+ for _, t := range strings.Split(os.Getenv("EBITENGINE_OPENGL"), ",") {
+ switch strings.TrimSpace(t) {
+ case "es":
+ preferES = true
+ break
+ }
+ }
+
+ // Try OpenGL first. OpenGL is preferrable as this doesn't cause context losts.
+ if !preferES {
+ if C.libGL() != nil {
+ return nil
+ }
+ }
+
+ // Try OpenGL ES.
+ if C.libGLES() != nil {
+ c.isES = true
+ return nil
+ }
+
+ return fmt.Errorf("gl: failed to load libGL.so and libGLES.so")
+}
+
+func (c *defaultContext) getProcAddress(name string) unsafe.Pointer {
+ if c.isES {
+ return getProcAddressGLES(name)
+ }
+ return getProcAddressGL(name)
+}
+
+func getProcAddressGL(name string) unsafe.Pointer {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ return C.getProcAddressGL(cname)
+}
+
+func getProcAddressGLES(name string) unsafe.Pointer {
+ const ext = "EXT"
+ if strings.HasSuffix(name, ext) {
+ name = name[:len(name)-len(ext)]
+ }
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ return C.getProcAddressGLES(cname)
+}
diff --git a/internal/graphicsdriver/opengl/gl/procaddr_windows.go b/internal/graphicsdriver/opengl/gl/procaddr_windows.go
index 68bc9b9d9e11..245fef550ccc 100644
--- a/internal/graphicsdriver/opengl/gl/procaddr_windows.go
+++ b/internal/graphicsdriver/opengl/gl/procaddr_windows.go
@@ -24,10 +24,13 @@ import (
var (
opengl32 = windows.NewLazySystemDLL("opengl32")
procWglGetProcAddress = opengl32.NewProc("wglGetProcAddress")
- isES = false
)
-func getProcAddress(namea string) uintptr {
+func (c *defaultContext) init() error {
+ return nil
+}
+
+func (c *defaultContext) getProcAddress(namea string) uintptr {
cname, err := windows.BytePtrFromString(namea)
if err != nil {
panic(err)
diff --git a/internal/graphicsdriver/opengl/graphics_default.go b/internal/graphicsdriver/opengl/graphics_default.go
index 8965a97bb55d..6f132b85800f 100644
--- a/internal/graphicsdriver/opengl/graphics_default.go
+++ b/internal/graphicsdriver/opengl/graphics_default.go
@@ -31,7 +31,12 @@ func NewGraphics() (graphicsdriver.Graphics, error) {
return nil, fmt.Errorf("opengl: OpenGL is not supported on Xbox")
}
+ ctx, err := gl.NewDefaultContext()
+ if err != nil {
+ return nil, err
+ }
+
g := &Graphics{}
- g.context.ctx = gl.NewDefaultContext()
+ g.context.ctx = ctx
return g, nil
}
diff --git a/internal/graphicsdriver/opengl/graphics_mobile.go b/internal/graphicsdriver/opengl/graphics_mobile.go
index d23e6560f681..5ab8e15f67b7 100644
--- a/internal/graphicsdriver/opengl/graphics_mobile.go
+++ b/internal/graphicsdriver/opengl/graphics_mobile.go
@@ -30,7 +30,11 @@ func NewGraphics(context mgl.Context) (graphicsdriver.Graphics, error) {
if context != nil {
ctx = gl.NewGomobileContext(context.(mgl.Context))
} else {
- ctx = gl.NewDefaultContext()
+ var err error
+ ctx, err = gl.NewDefaultContext()
+ if err != nil {
+ return nil, err
+ }
}
g := &Graphics{}