internal/graphicsdriver/opengl/gl: automatically choose OpenGL and OpenGL ES

Updates #292
This commit is contained in:
Hajime Hoshi 2022-11-14 03:42:37 +09:00
parent fcf454ef20
commit f6f7ed3e3d
16 changed files with 308 additions and 264 deletions

View File

@ -134,7 +134,7 @@ jobs:
if: runner.os == 'Linux' if: runner.os == 'Linux'
run: | run: |
sudo apt-get install libgles2-mesa-dev 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) - name: go test (Windows 386)
if: runner.os == 'Windows' if: runner.os == 'Windows'

3
doc.go
View File

@ -84,6 +84,7 @@
// `EBITENGINE_OPENGL` environment variable specifies various parameters for OpenGL. // `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). // 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. // "webgl1": Use WebGL 1. This is valid only on browsers.
// //
// # Build tags // # Build tags
@ -99,6 +100,4 @@
// `microsoftgdk` is for Microsoft GDK (e.g. Xbox). // `microsoftgdk` is for Microsoft GDK (e.g. Xbox).
// //
// `nintendosdk` is for NintendoSDK (e.g. Nintendo Switch). // `nintendosdk` is for NintendoSDK (e.g. Nintendo Switch).
//
// `opengles` uses OpenGL ES (2) instead of OpenGL.
package ebiten package ebiten

View File

@ -89,8 +89,8 @@ type contextImpl struct {
func (c *context) reset() error { func (c *context) reset() error {
if !c.init { if !c.init {
// Initialize OpenGL after WGL is initialized especially for Windows (#2452). // Load OpenGL functions after WGL is initialized especially for Windows (#2452).
if err := c.ctx.Init(); err != nil { if err := c.ctx.LoadFunctions(); err != nil {
return err return err
} }
c.init = true c.init = true

View File

@ -33,11 +33,11 @@ func glBool(x bool) C.GLboolean {
type defaultContext struct{} type defaultContext struct{}
func NewDefaultContext() Context { func NewDefaultContext() (Context, error) {
return defaultContext{} return defaultContext{}, nil
} }
func (defaultContext) Init() error { func (defaultContext) LoadFunctions() error {
return nil return nil
} }

View File

@ -393,10 +393,16 @@ type defaultContext struct {
gpUseProgram C.GPUSEPROGRAM gpUseProgram C.GPUSEPROGRAM
gpVertexAttribPointer C.GPVERTEXATTRIBPOINTER gpVertexAttribPointer C.GPVERTEXATTRIBPOINTER
gpViewport C.GPVIEWPORT gpViewport C.GPVIEWPORT
isES bool
} }
func NewDefaultContext() Context { func NewDefaultContext() (Context, error) {
return &defaultContext{} ctx := &defaultContext{}
if err := ctx.init(); err != nil {
return nil, err
}
return ctx, nil
} }
func boolToInt(b bool) int { func boolToInt(b bool) int {
@ -407,7 +413,7 @@ func boolToInt(b bool) int {
} }
func (c *defaultContext) IsES() bool { func (c *defaultContext) IsES() bool {
return isES return c.isES
} }
func (c *defaultContext) ActiveTexture(texture uint32) { 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)) C.glowViewport(c.gpViewport, (C.GLint)(x), (C.GLint)(y), (C.GLsizei)(width), (C.GLsizei)(height))
} }
func (c *defaultContext) Init() error { func (c *defaultContext) LoadFunctions() error {
c.gpActiveTexture = (C.GPACTIVETEXTURE)(getProcAddress("glActiveTexture")) c.gpActiveTexture = (C.GPACTIVETEXTURE)(c.getProcAddress("glActiveTexture"))
if c.gpActiveTexture == nil { if c.gpActiveTexture == nil {
return errors.New("gl: glActiveTexture is missing") return errors.New("gl: glActiveTexture is missing")
} }
c.gpAttachShader = (C.GPATTACHSHADER)(getProcAddress("glAttachShader")) c.gpAttachShader = (C.GPATTACHSHADER)(c.getProcAddress("glAttachShader"))
if c.gpAttachShader == nil { if c.gpAttachShader == nil {
return errors.New("gl: glAttachShader is missing") return errors.New("gl: glAttachShader is missing")
} }
c.gpBindAttribLocation = (C.GPBINDATTRIBLOCATION)(getProcAddress("glBindAttribLocation")) c.gpBindAttribLocation = (C.GPBINDATTRIBLOCATION)(c.getProcAddress("glBindAttribLocation"))
if c.gpBindAttribLocation == nil { if c.gpBindAttribLocation == nil {
return errors.New("gl: glBindAttribLocation is missing") return errors.New("gl: glBindAttribLocation is missing")
} }
c.gpBindBuffer = (C.GPBINDBUFFER)(getProcAddress("glBindBuffer")) c.gpBindBuffer = (C.GPBINDBUFFER)(c.getProcAddress("glBindBuffer"))
if c.gpBindBuffer == nil { if c.gpBindBuffer == nil {
return errors.New("gl: glBindBuffer is missing") return errors.New("gl: glBindBuffer is missing")
} }
c.gpBindFramebufferEXT = (C.GPBINDFRAMEBUFFEREXT)(getProcAddress("glBindFramebufferEXT")) c.gpBindFramebufferEXT = (C.GPBINDFRAMEBUFFEREXT)(c.getProcAddress("glBindFramebufferEXT"))
c.gpBindRenderbufferEXT = (C.GPBINDRENDERBUFFEREXT)(getProcAddress("glBindRenderbufferEXT")) c.gpBindRenderbufferEXT = (C.GPBINDRENDERBUFFEREXT)(c.getProcAddress("glBindRenderbufferEXT"))
c.gpBindTexture = (C.GPBINDTEXTURE)(getProcAddress("glBindTexture")) c.gpBindTexture = (C.GPBINDTEXTURE)(c.getProcAddress("glBindTexture"))
if c.gpBindTexture == nil { if c.gpBindTexture == nil {
return errors.New("gl: glBindTexture is missing") return errors.New("gl: glBindTexture is missing")
} }
c.gpBlendEquationSeparate = (C.GPBLENDEQUATIONSEPARATE)(getProcAddress("glBlendEquationSeparate")) c.gpBlendEquationSeparate = (C.GPBLENDEQUATIONSEPARATE)(c.getProcAddress("glBlendEquationSeparate"))
if c.gpBlendEquationSeparate == nil { if c.gpBlendEquationSeparate == nil {
return errors.New("gl: glBlendEquationSeparate is missing") return errors.New("gl: glBlendEquationSeparate is missing")
} }
c.gpBlendFuncSeparate = (C.GPBLENDFUNCSEPARATE)(getProcAddress("glBlendFuncSeparate")) c.gpBlendFuncSeparate = (C.GPBLENDFUNCSEPARATE)(c.getProcAddress("glBlendFuncSeparate"))
if c.gpBlendFuncSeparate == nil { if c.gpBlendFuncSeparate == nil {
return errors.New("gl: glBlendFuncSeparate is missing") return errors.New("gl: glBlendFuncSeparate is missing")
} }
c.gpBufferData = (C.GPBUFFERDATA)(getProcAddress("glBufferData")) c.gpBufferData = (C.GPBUFFERDATA)(c.getProcAddress("glBufferData"))
if c.gpBufferData == nil { if c.gpBufferData == nil {
return errors.New("gl: glBufferData is missing") return errors.New("gl: glBufferData is missing")
} }
c.gpBufferSubData = (C.GPBUFFERSUBDATA)(getProcAddress("glBufferSubData")) c.gpBufferSubData = (C.GPBUFFERSUBDATA)(c.getProcAddress("glBufferSubData"))
if c.gpBufferSubData == nil { if c.gpBufferSubData == nil {
return errors.New("gl: glBufferSubData is missing") return errors.New("gl: glBufferSubData is missing")
} }
c.gpCheckFramebufferStatusEXT = (C.GPCHECKFRAMEBUFFERSTATUSEXT)(getProcAddress("glCheckFramebufferStatusEXT")) c.gpCheckFramebufferStatusEXT = (C.GPCHECKFRAMEBUFFERSTATUSEXT)(c.getProcAddress("glCheckFramebufferStatusEXT"))
c.gpClear = (C.GPCLEAR)(getProcAddress("glClear")) c.gpClear = (C.GPCLEAR)(c.getProcAddress("glClear"))
if c.gpClear == nil { if c.gpClear == nil {
return errors.New("gl: glClear is missing") return errors.New("gl: glClear is missing")
} }
c.gpColorMask = (C.GPCOLORMASK)(getProcAddress("glColorMask")) c.gpColorMask = (C.GPCOLORMASK)(c.getProcAddress("glColorMask"))
if c.gpColorMask == nil { if c.gpColorMask == nil {
return errors.New("gl: glColorMask is missing") return errors.New("gl: glColorMask is missing")
} }
c.gpCompileShader = (C.GPCOMPILESHADER)(getProcAddress("glCompileShader")) c.gpCompileShader = (C.GPCOMPILESHADER)(c.getProcAddress("glCompileShader"))
if c.gpCompileShader == nil { if c.gpCompileShader == nil {
return errors.New("gl: glCompileShader is missing") return errors.New("gl: glCompileShader is missing")
} }
c.gpCreateProgram = (C.GPCREATEPROGRAM)(getProcAddress("glCreateProgram")) c.gpCreateProgram = (C.GPCREATEPROGRAM)(c.getProcAddress("glCreateProgram"))
if c.gpCreateProgram == nil { if c.gpCreateProgram == nil {
return errors.New("gl: glCreateProgram is missing") return errors.New("gl: glCreateProgram is missing")
} }
c.gpCreateShader = (C.GPCREATESHADER)(getProcAddress("glCreateShader")) c.gpCreateShader = (C.GPCREATESHADER)(c.getProcAddress("glCreateShader"))
if c.gpCreateShader == nil { if c.gpCreateShader == nil {
return errors.New("gl: glCreateShader is missing") return errors.New("gl: glCreateShader is missing")
} }
c.gpDeleteBuffers = (C.GPDELETEBUFFERS)(getProcAddress("glDeleteBuffers")) c.gpDeleteBuffers = (C.GPDELETEBUFFERS)(c.getProcAddress("glDeleteBuffers"))
if c.gpDeleteBuffers == nil { if c.gpDeleteBuffers == nil {
return errors.New("gl: glDeleteBuffers is missing") return errors.New("gl: glDeleteBuffers is missing")
} }
c.gpDeleteFramebuffersEXT = (C.GPDELETEFRAMEBUFFERSEXT)(getProcAddress("glDeleteFramebuffersEXT")) c.gpDeleteFramebuffersEXT = (C.GPDELETEFRAMEBUFFERSEXT)(c.getProcAddress("glDeleteFramebuffersEXT"))
c.gpDeleteProgram = (C.GPDELETEPROGRAM)(getProcAddress("glDeleteProgram")) c.gpDeleteProgram = (C.GPDELETEPROGRAM)(c.getProcAddress("glDeleteProgram"))
if c.gpDeleteProgram == nil { if c.gpDeleteProgram == nil {
return errors.New("gl: glDeleteProgram is missing") return errors.New("gl: glDeleteProgram is missing")
} }
c.gpDeleteRenderbuffersEXT = (C.GPDELETERENDERBUFFERSEXT)(getProcAddress("glDeleteRenderbuffersEXT")) c.gpDeleteRenderbuffersEXT = (C.GPDELETERENDERBUFFERSEXT)(c.getProcAddress("glDeleteRenderbuffersEXT"))
c.gpDeleteShader = (C.GPDELETESHADER)(getProcAddress("glDeleteShader")) c.gpDeleteShader = (C.GPDELETESHADER)(c.getProcAddress("glDeleteShader"))
if c.gpDeleteShader == nil { if c.gpDeleteShader == nil {
return errors.New("gl: glDeleteShader is missing") return errors.New("gl: glDeleteShader is missing")
} }
c.gpDeleteTextures = (C.GPDELETETEXTURES)(getProcAddress("glDeleteTextures")) c.gpDeleteTextures = (C.GPDELETETEXTURES)(c.getProcAddress("glDeleteTextures"))
if c.gpDeleteTextures == nil { if c.gpDeleteTextures == nil {
return errors.New("gl: glDeleteTextures is missing") return errors.New("gl: glDeleteTextures is missing")
} }
c.gpDisable = (C.GPDISABLE)(getProcAddress("glDisable")) c.gpDisable = (C.GPDISABLE)(c.getProcAddress("glDisable"))
if c.gpDisable == nil { if c.gpDisable == nil {
return errors.New("gl: glDisable is missing") return errors.New("gl: glDisable is missing")
} }
c.gpDisableVertexAttribArray = (C.GPDISABLEVERTEXATTRIBARRAY)(getProcAddress("glDisableVertexAttribArray")) c.gpDisableVertexAttribArray = (C.GPDISABLEVERTEXATTRIBARRAY)(c.getProcAddress("glDisableVertexAttribArray"))
if c.gpDisableVertexAttribArray == nil { if c.gpDisableVertexAttribArray == nil {
return errors.New("gl: glDisableVertexAttribArray is missing") return errors.New("gl: glDisableVertexAttribArray is missing")
} }
c.gpDrawElements = (C.GPDRAWELEMENTS)(getProcAddress("glDrawElements")) c.gpDrawElements = (C.GPDRAWELEMENTS)(c.getProcAddress("glDrawElements"))
if c.gpDrawElements == nil { if c.gpDrawElements == nil {
return errors.New("gl: glDrawElements is missing") return errors.New("gl: glDrawElements is missing")
} }
c.gpEnable = (C.GPENABLE)(getProcAddress("glEnable")) c.gpEnable = (C.GPENABLE)(c.getProcAddress("glEnable"))
if c.gpEnable == nil { if c.gpEnable == nil {
return errors.New("gl: glEnable is missing") return errors.New("gl: glEnable is missing")
} }
c.gpEnableVertexAttribArray = (C.GPENABLEVERTEXATTRIBARRAY)(getProcAddress("glEnableVertexAttribArray")) c.gpEnableVertexAttribArray = (C.GPENABLEVERTEXATTRIBARRAY)(c.getProcAddress("glEnableVertexAttribArray"))
if c.gpEnableVertexAttribArray == nil { if c.gpEnableVertexAttribArray == nil {
return errors.New("gl: glEnableVertexAttribArray is missing") return errors.New("gl: glEnableVertexAttribArray is missing")
} }
c.gpFlush = (C.GPFLUSH)(getProcAddress("glFlush")) c.gpFlush = (C.GPFLUSH)(c.getProcAddress("glFlush"))
if c.gpFlush == nil { if c.gpFlush == nil {
return errors.New("gl: glFlush is missing") return errors.New("gl: glFlush is missing")
} }
c.gpFramebufferRenderbufferEXT = (C.GPFRAMEBUFFERRENDERBUFFEREXT)(getProcAddress("glFramebufferRenderbufferEXT")) c.gpFramebufferRenderbufferEXT = (C.GPFRAMEBUFFERRENDERBUFFEREXT)(c.getProcAddress("glFramebufferRenderbufferEXT"))
c.gpFramebufferTexture2DEXT = (C.GPFRAMEBUFFERTEXTURE2DEXT)(getProcAddress("glFramebufferTexture2DEXT")) c.gpFramebufferTexture2DEXT = (C.GPFRAMEBUFFERTEXTURE2DEXT)(c.getProcAddress("glFramebufferTexture2DEXT"))
c.gpGenBuffers = (C.GPGENBUFFERS)(getProcAddress("glGenBuffers")) c.gpGenBuffers = (C.GPGENBUFFERS)(c.getProcAddress("glGenBuffers"))
if c.gpGenBuffers == nil { if c.gpGenBuffers == nil {
return errors.New("gl: glGenBuffers is missing") return errors.New("gl: glGenBuffers is missing")
} }
c.gpGenFramebuffersEXT = (C.GPGENFRAMEBUFFERSEXT)(getProcAddress("glGenFramebuffersEXT")) c.gpGenFramebuffersEXT = (C.GPGENFRAMEBUFFERSEXT)(c.getProcAddress("glGenFramebuffersEXT"))
c.gpGenRenderbuffersEXT = (C.GPGENRENDERBUFFERSEXT)(getProcAddress("glGenRenderbuffersEXT")) c.gpGenRenderbuffersEXT = (C.GPGENRENDERBUFFERSEXT)(c.getProcAddress("glGenRenderbuffersEXT"))
c.gpGenTextures = (C.GPGENTEXTURES)(getProcAddress("glGenTextures")) c.gpGenTextures = (C.GPGENTEXTURES)(c.getProcAddress("glGenTextures"))
if c.gpGenTextures == nil { if c.gpGenTextures == nil {
return errors.New("gl: glGenTextures is missing") return errors.New("gl: glGenTextures is missing")
} }
c.gpGetError = (C.GPGETERROR)(getProcAddress("glGetError")) c.gpGetError = (C.GPGETERROR)(c.getProcAddress("glGetError"))
if c.gpGetError == nil { if c.gpGetError == nil {
return errors.New("gl: glGetError is missing") return errors.New("gl: glGetError is missing")
} }
c.gpGetIntegerv = (C.GPGETINTEGERV)(getProcAddress("glGetIntegerv")) c.gpGetIntegerv = (C.GPGETINTEGERV)(c.getProcAddress("glGetIntegerv"))
if c.gpGetIntegerv == nil { if c.gpGetIntegerv == nil {
return errors.New("gl: glGetIntegerv is missing") return errors.New("gl: glGetIntegerv is missing")
} }
c.gpGetProgramInfoLog = (C.GPGETPROGRAMINFOLOG)(getProcAddress("glGetProgramInfoLog")) c.gpGetProgramInfoLog = (C.GPGETPROGRAMINFOLOG)(c.getProcAddress("glGetProgramInfoLog"))
if c.gpGetProgramInfoLog == nil { if c.gpGetProgramInfoLog == nil {
return errors.New("gl: glGetProgramInfoLog is missing") return errors.New("gl: glGetProgramInfoLog is missing")
} }
c.gpGetProgramiv = (C.GPGETPROGRAMIV)(getProcAddress("glGetProgramiv")) c.gpGetProgramiv = (C.GPGETPROGRAMIV)(c.getProcAddress("glGetProgramiv"))
if c.gpGetProgramiv == nil { if c.gpGetProgramiv == nil {
return errors.New("gl: glGetProgramiv is missing") return errors.New("gl: glGetProgramiv is missing")
} }
c.gpGetShaderInfoLog = (C.GPGETSHADERINFOLOG)(getProcAddress("glGetShaderInfoLog")) c.gpGetShaderInfoLog = (C.GPGETSHADERINFOLOG)(c.getProcAddress("glGetShaderInfoLog"))
if c.gpGetShaderInfoLog == nil { if c.gpGetShaderInfoLog == nil {
return errors.New("gl: glGetShaderInfoLog is missing") return errors.New("gl: glGetShaderInfoLog is missing")
} }
c.gpGetShaderiv = (C.GPGETSHADERIV)(getProcAddress("glGetShaderiv")) c.gpGetShaderiv = (C.GPGETSHADERIV)(c.getProcAddress("glGetShaderiv"))
if c.gpGetShaderiv == nil { if c.gpGetShaderiv == nil {
return errors.New("gl: glGetShaderiv is missing") return errors.New("gl: glGetShaderiv is missing")
} }
c.gpGetUniformLocation = (C.GPGETUNIFORMLOCATION)(getProcAddress("glGetUniformLocation")) c.gpGetUniformLocation = (C.GPGETUNIFORMLOCATION)(c.getProcAddress("glGetUniformLocation"))
if c.gpGetUniformLocation == nil { if c.gpGetUniformLocation == nil {
return errors.New("gl: glGetUniformLocation is missing") return errors.New("gl: glGetUniformLocation is missing")
} }
c.gpIsFramebufferEXT = (C.GPISFRAMEBUFFEREXT)(getProcAddress("glIsFramebufferEXT")) c.gpIsFramebufferEXT = (C.GPISFRAMEBUFFEREXT)(c.getProcAddress("glIsFramebufferEXT"))
c.gpIsProgram = (C.GPISPROGRAM)(getProcAddress("glIsProgram")) c.gpIsProgram = (C.GPISPROGRAM)(c.getProcAddress("glIsProgram"))
if c.gpIsProgram == nil { if c.gpIsProgram == nil {
return errors.New("gl: glIsProgram is missing") return errors.New("gl: glIsProgram is missing")
} }
c.gpIsRenderbufferEXT = (C.GPISRENDERBUFFEREXT)(getProcAddress("glIsRenderbufferEXT")) c.gpIsRenderbufferEXT = (C.GPISRENDERBUFFEREXT)(c.getProcAddress("glIsRenderbufferEXT"))
c.gpIsTexture = (C.GPISTEXTURE)(getProcAddress("glIsTexture")) c.gpIsTexture = (C.GPISTEXTURE)(c.getProcAddress("glIsTexture"))
if c.gpIsTexture == nil { if c.gpIsTexture == nil {
return errors.New("gl: glIsTexture is missing") return errors.New("gl: glIsTexture is missing")
} }
c.gpLinkProgram = (C.GPLINKPROGRAM)(getProcAddress("glLinkProgram")) c.gpLinkProgram = (C.GPLINKPROGRAM)(c.getProcAddress("glLinkProgram"))
if c.gpLinkProgram == nil { if c.gpLinkProgram == nil {
return errors.New("gl: glLinkProgram is missing") return errors.New("gl: glLinkProgram is missing")
} }
c.gpPixelStorei = (C.GPPIXELSTOREI)(getProcAddress("glPixelStorei")) c.gpPixelStorei = (C.GPPIXELSTOREI)(c.getProcAddress("glPixelStorei"))
if c.gpPixelStorei == nil { if c.gpPixelStorei == nil {
return errors.New("gl: glPixelStorei is missing") return errors.New("gl: glPixelStorei is missing")
} }
c.gpReadPixels = (C.GPREADPIXELS)(getProcAddress("glReadPixels")) c.gpReadPixels = (C.GPREADPIXELS)(c.getProcAddress("glReadPixels"))
if c.gpReadPixels == nil { if c.gpReadPixels == nil {
return errors.New("gl: glReadPixels is missing") return errors.New("gl: glReadPixels is missing")
} }
c.gpRenderbufferStorageEXT = (C.GPRENDERBUFFERSTORAGEEXT)(getProcAddress("glRenderbufferStorageEXT")) c.gpRenderbufferStorageEXT = (C.GPRENDERBUFFERSTORAGEEXT)(c.getProcAddress("glRenderbufferStorageEXT"))
c.gpScissor = (C.GPSCISSOR)(getProcAddress("glScissor")) c.gpScissor = (C.GPSCISSOR)(c.getProcAddress("glScissor"))
if c.gpScissor == nil { if c.gpScissor == nil {
return errors.New("gl: glScissor is missing") return errors.New("gl: glScissor is missing")
} }
c.gpShaderSource = (C.GPSHADERSOURCE)(getProcAddress("glShaderSource")) c.gpShaderSource = (C.GPSHADERSOURCE)(c.getProcAddress("glShaderSource"))
if c.gpShaderSource == nil { if c.gpShaderSource == nil {
return errors.New("gl: glShaderSource is missing") return errors.New("gl: glShaderSource is missing")
} }
c.gpStencilFunc = (C.GPSTENCILFUNC)(getProcAddress("glStencilFunc")) c.gpStencilFunc = (C.GPSTENCILFUNC)(c.getProcAddress("glStencilFunc"))
if c.gpStencilFunc == nil { if c.gpStencilFunc == nil {
return errors.New("gl: glStencilFunc is missing") return errors.New("gl: glStencilFunc is missing")
} }
c.gpStencilOp = (C.GPSTENCILOP)(getProcAddress("glStencilOp")) c.gpStencilOp = (C.GPSTENCILOP)(c.getProcAddress("glStencilOp"))
if c.gpStencilOp == nil { if c.gpStencilOp == nil {
return errors.New("gl: glStencilOp is missing") return errors.New("gl: glStencilOp is missing")
} }
c.gpTexImage2D = (C.GPTEXIMAGE2D)(getProcAddress("glTexImage2D")) c.gpTexImage2D = (C.GPTEXIMAGE2D)(c.getProcAddress("glTexImage2D"))
if c.gpTexImage2D == nil { if c.gpTexImage2D == nil {
return errors.New("gl: glTexImage2D is missing") return errors.New("gl: glTexImage2D is missing")
} }
c.gpTexParameteri = (C.GPTEXPARAMETERI)(getProcAddress("glTexParameteri")) c.gpTexParameteri = (C.GPTEXPARAMETERI)(c.getProcAddress("glTexParameteri"))
if c.gpTexParameteri == nil { if c.gpTexParameteri == nil {
return errors.New("gl: glTexParameteri is missing") return errors.New("gl: glTexParameteri is missing")
} }
c.gpTexSubImage2D = (C.GPTEXSUBIMAGE2D)(getProcAddress("glTexSubImage2D")) c.gpTexSubImage2D = (C.GPTEXSUBIMAGE2D)(c.getProcAddress("glTexSubImage2D"))
if c.gpTexSubImage2D == nil { if c.gpTexSubImage2D == nil {
return errors.New("gl: glTexSubImage2D is missing") return errors.New("gl: glTexSubImage2D is missing")
} }
c.gpUniform1fv = (C.GPUNIFORM1FV)(getProcAddress("glUniform1fv")) c.gpUniform1fv = (C.GPUNIFORM1FV)(c.getProcAddress("glUniform1fv"))
if c.gpUniform1fv == nil { if c.gpUniform1fv == nil {
return errors.New("gl: glUniform1fv is missing") return errors.New("gl: glUniform1fv is missing")
} }
c.gpUniform1i = (C.GPUNIFORM1I)(getProcAddress("glUniform1i")) c.gpUniform1i = (C.GPUNIFORM1I)(c.getProcAddress("glUniform1i"))
if c.gpUniform1i == nil { if c.gpUniform1i == nil {
return errors.New("gl: glUniform1i is missing") return errors.New("gl: glUniform1i is missing")
} }
c.gpUniform1iv = (C.GPUNIFORM1IV)(getProcAddress("glUniform1iv")) c.gpUniform1iv = (C.GPUNIFORM1IV)(c.getProcAddress("glUniform1iv"))
if c.gpUniform1iv == nil { if c.gpUniform1iv == nil {
return errors.New("gl: glUniform1iv is missing") return errors.New("gl: glUniform1iv is missing")
} }
c.gpUniform2fv = (C.GPUNIFORM2FV)(getProcAddress("glUniform2fv")) c.gpUniform2fv = (C.GPUNIFORM2FV)(c.getProcAddress("glUniform2fv"))
if c.gpUniform2fv == nil { if c.gpUniform2fv == nil {
return errors.New("gl: glUniform2fv is missing") return errors.New("gl: glUniform2fv is missing")
} }
c.gpUniform3fv = (C.GPUNIFORM3FV)(getProcAddress("glUniform3fv")) c.gpUniform3fv = (C.GPUNIFORM3FV)(c.getProcAddress("glUniform3fv"))
if c.gpUniform3fv == nil { if c.gpUniform3fv == nil {
return errors.New("gl: glUniform3fv is missing") return errors.New("gl: glUniform3fv is missing")
} }
c.gpUniform4fv = (C.GPUNIFORM4FV)(getProcAddress("glUniform4fv")) c.gpUniform4fv = (C.GPUNIFORM4FV)(c.getProcAddress("glUniform4fv"))
if c.gpUniform4fv == nil { if c.gpUniform4fv == nil {
return errors.New("gl: glUniform4fv is missing") return errors.New("gl: glUniform4fv is missing")
} }
c.gpUniformMatrix2fv = (C.GPUNIFORMMATRIX2FV)(getProcAddress("glUniformMatrix2fv")) c.gpUniformMatrix2fv = (C.GPUNIFORMMATRIX2FV)(c.getProcAddress("glUniformMatrix2fv"))
if c.gpUniformMatrix2fv == nil { if c.gpUniformMatrix2fv == nil {
return errors.New("gl: glUniformMatrix2fv is missing") return errors.New("gl: glUniformMatrix2fv is missing")
} }
c.gpUniformMatrix3fv = (C.GPUNIFORMMATRIX3FV)(getProcAddress("glUniformMatrix3fv")) c.gpUniformMatrix3fv = (C.GPUNIFORMMATRIX3FV)(c.getProcAddress("glUniformMatrix3fv"))
if c.gpUniformMatrix3fv == nil { if c.gpUniformMatrix3fv == nil {
return errors.New("gl: glUniformMatrix3fv is missing") return errors.New("gl: glUniformMatrix3fv is missing")
} }
c.gpUniformMatrix4fv = (C.GPUNIFORMMATRIX4FV)(getProcAddress("glUniformMatrix4fv")) c.gpUniformMatrix4fv = (C.GPUNIFORMMATRIX4FV)(c.getProcAddress("glUniformMatrix4fv"))
if c.gpUniformMatrix4fv == nil { if c.gpUniformMatrix4fv == nil {
return errors.New("gl: glUniformMatrix4fv is missing") return errors.New("gl: glUniformMatrix4fv is missing")
} }
c.gpUseProgram = (C.GPUSEPROGRAM)(getProcAddress("glUseProgram")) c.gpUseProgram = (C.GPUSEPROGRAM)(c.getProcAddress("glUseProgram"))
if c.gpUseProgram == nil { if c.gpUseProgram == nil {
return errors.New("gl: glUseProgram is missing") return errors.New("gl: glUseProgram is missing")
} }
c.gpVertexAttribPointer = (C.GPVERTEXATTRIBPOINTER)(getProcAddress("glVertexAttribPointer")) c.gpVertexAttribPointer = (C.GPVERTEXATTRIBPOINTER)(c.getProcAddress("glVertexAttribPointer"))
if c.gpVertexAttribPointer == nil { if c.gpVertexAttribPointer == nil {
return errors.New("gl: glVertexAttribPointer is missing") return errors.New("gl: glVertexAttribPointer is missing")
} }
c.gpViewport = (C.GPVIEWPORT)(getProcAddress("glViewport")) c.gpViewport = (C.GPVIEWPORT)(c.getProcAddress("glViewport"))
if c.gpViewport == nil { if c.gpViewport == nil {
return errors.New("gl: glViewport is missing") return errors.New("gl: glViewport is missing")
} }

View File

@ -94,10 +94,16 @@ type defaultContext struct {
gpUseProgram uintptr gpUseProgram uintptr
gpVertexAttribPointer uintptr gpVertexAttribPointer uintptr
gpViewport uintptr gpViewport uintptr
isES bool
} }
func NewDefaultContext() Context { func NewDefaultContext() (Context, error) {
return &defaultContext{} ctx := &defaultContext{}
if err := ctx.init(); err != nil {
return nil, err
}
return ctx, nil
} }
func boolToInt(b bool) int { func boolToInt(b bool) int {
@ -108,7 +114,7 @@ func boolToInt(b bool) int {
} }
func (c *defaultContext) IsES() bool { func (c *defaultContext) IsES() bool {
return isES return c.isES
} }
func (c *defaultContext) ActiveTexture(texture uint32) { 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)) purego.SyscallN(c.gpViewport, uintptr(x), uintptr(y), uintptr(width), uintptr(height))
} }
func (c *defaultContext) Init() error { func (c *defaultContext) LoadFunctions() error {
c.gpActiveTexture = getProcAddress("glActiveTexture") c.gpActiveTexture = c.getProcAddress("glActiveTexture")
if c.gpActiveTexture == 0 { if c.gpActiveTexture == 0 {
return errors.New("gl: glActiveTexture is missing") return errors.New("gl: glActiveTexture is missing")
} }
c.gpAttachShader = getProcAddress("glAttachShader") c.gpAttachShader = c.getProcAddress("glAttachShader")
if c.gpAttachShader == 0 { if c.gpAttachShader == 0 {
return errors.New("gl: glAttachShader is missing") return errors.New("gl: glAttachShader is missing")
} }
c.gpBindAttribLocation = getProcAddress("glBindAttribLocation") c.gpBindAttribLocation = c.getProcAddress("glBindAttribLocation")
if c.gpBindAttribLocation == 0 { if c.gpBindAttribLocation == 0 {
return errors.New("gl: glBindAttribLocation is missing") return errors.New("gl: glBindAttribLocation is missing")
} }
c.gpBindBuffer = getProcAddress("glBindBuffer") c.gpBindBuffer = c.getProcAddress("glBindBuffer")
if c.gpBindBuffer == 0 { if c.gpBindBuffer == 0 {
return errors.New("gl: glBindBuffer is missing") return errors.New("gl: glBindBuffer is missing")
} }
c.gpBindFramebufferEXT = getProcAddress("glBindFramebufferEXT") c.gpBindFramebufferEXT = c.getProcAddress("glBindFramebufferEXT")
c.gpBindRenderbufferEXT = getProcAddress("glBindRenderbufferEXT") c.gpBindRenderbufferEXT = c.getProcAddress("glBindRenderbufferEXT")
c.gpBindTexture = getProcAddress("glBindTexture") c.gpBindTexture = c.getProcAddress("glBindTexture")
if c.gpBindTexture == 0 { if c.gpBindTexture == 0 {
return errors.New("gl: glBindTexture is missing") return errors.New("gl: glBindTexture is missing")
} }
c.gpBlendEquationSeparate = getProcAddress("glBlendEquationSeparate") c.gpBlendEquationSeparate = c.getProcAddress("glBlendEquationSeparate")
if c.gpBlendEquationSeparate == 0 { if c.gpBlendEquationSeparate == 0 {
return errors.New("gl: glBlendEquationSeparate is missing") return errors.New("gl: glBlendEquationSeparate is missing")
} }
c.gpBlendFuncSeparate = getProcAddress("glBlendFuncSeparate") c.gpBlendFuncSeparate = c.getProcAddress("glBlendFuncSeparate")
if c.gpBlendFuncSeparate == 0 { if c.gpBlendFuncSeparate == 0 {
return errors.New("gl: glBlendFuncSeparate is missing") return errors.New("gl: glBlendFuncSeparate is missing")
} }
c.gpBufferData = getProcAddress("glBufferData") c.gpBufferData = c.getProcAddress("glBufferData")
if c.gpBufferData == 0 { if c.gpBufferData == 0 {
return errors.New("gl: glBufferData is missing") return errors.New("gl: glBufferData is missing")
} }
c.gpBufferSubData = getProcAddress("glBufferSubData") c.gpBufferSubData = c.getProcAddress("glBufferSubData")
if c.gpBufferSubData == 0 { if c.gpBufferSubData == 0 {
return errors.New("gl: glBufferSubData is missing") return errors.New("gl: glBufferSubData is missing")
} }
c.gpCheckFramebufferStatusEXT = getProcAddress("glCheckFramebufferStatusEXT") c.gpCheckFramebufferStatusEXT = c.getProcAddress("glCheckFramebufferStatusEXT")
c.gpClear = getProcAddress("glClear") c.gpClear = c.getProcAddress("glClear")
if c.gpClear == 0 { if c.gpClear == 0 {
return errors.New("gl: glClear is missing") return errors.New("gl: glClear is missing")
} }
c.gpColorMask = getProcAddress("glColorMask") c.gpColorMask = c.getProcAddress("glColorMask")
if c.gpColorMask == 0 { if c.gpColorMask == 0 {
return errors.New("gl: glColorMask is missing") return errors.New("gl: glColorMask is missing")
} }
c.gpCompileShader = getProcAddress("glCompileShader") c.gpCompileShader = c.getProcAddress("glCompileShader")
if c.gpCompileShader == 0 { if c.gpCompileShader == 0 {
return errors.New("gl: glCompileShader is missing") return errors.New("gl: glCompileShader is missing")
} }
c.gpCreateProgram = getProcAddress("glCreateProgram") c.gpCreateProgram = c.getProcAddress("glCreateProgram")
if c.gpCreateProgram == 0 { if c.gpCreateProgram == 0 {
return errors.New("gl: glCreateProgram is missing") return errors.New("gl: glCreateProgram is missing")
} }
c.gpCreateShader = getProcAddress("glCreateShader") c.gpCreateShader = c.getProcAddress("glCreateShader")
if c.gpCreateShader == 0 { if c.gpCreateShader == 0 {
return errors.New("gl: glCreateShader is missing") return errors.New("gl: glCreateShader is missing")
} }
c.gpDeleteBuffers = getProcAddress("glDeleteBuffers") c.gpDeleteBuffers = c.getProcAddress("glDeleteBuffers")
if c.gpDeleteBuffers == 0 { if c.gpDeleteBuffers == 0 {
return errors.New("gl: glDeleteBuffers is missing") return errors.New("gl: glDeleteBuffers is missing")
} }
c.gpDeleteFramebuffersEXT = getProcAddress("glDeleteFramebuffersEXT") c.gpDeleteFramebuffersEXT = c.getProcAddress("glDeleteFramebuffersEXT")
c.gpDeleteProgram = getProcAddress("glDeleteProgram") c.gpDeleteProgram = c.getProcAddress("glDeleteProgram")
if c.gpDeleteProgram == 0 { if c.gpDeleteProgram == 0 {
return errors.New("gl: glDeleteProgram is missing") return errors.New("gl: glDeleteProgram is missing")
} }
c.gpDeleteRenderbuffersEXT = getProcAddress("glDeleteRenderbuffersEXT") c.gpDeleteRenderbuffersEXT = c.getProcAddress("glDeleteRenderbuffersEXT")
c.gpDeleteShader = getProcAddress("glDeleteShader") c.gpDeleteShader = c.getProcAddress("glDeleteShader")
if c.gpDeleteShader == 0 { if c.gpDeleteShader == 0 {
return errors.New("gl: glDeleteShader is missing") return errors.New("gl: glDeleteShader is missing")
} }
c.gpDeleteTextures = getProcAddress("glDeleteTextures") c.gpDeleteTextures = c.getProcAddress("glDeleteTextures")
if c.gpDeleteTextures == 0 { if c.gpDeleteTextures == 0 {
return errors.New("gl: glDeleteTextures is missing") return errors.New("gl: glDeleteTextures is missing")
} }
c.gpDisable = getProcAddress("glDisable") c.gpDisable = c.getProcAddress("glDisable")
if c.gpDisable == 0 { if c.gpDisable == 0 {
return errors.New("gl: glDisable is missing") return errors.New("gl: glDisable is missing")
} }
c.gpDisableVertexAttribArray = getProcAddress("glDisableVertexAttribArray") c.gpDisableVertexAttribArray = c.getProcAddress("glDisableVertexAttribArray")
if c.gpDisableVertexAttribArray == 0 { if c.gpDisableVertexAttribArray == 0 {
return errors.New("gl: glDisableVertexAttribArray is missing") return errors.New("gl: glDisableVertexAttribArray is missing")
} }
c.gpDrawElements = getProcAddress("glDrawElements") c.gpDrawElements = c.getProcAddress("glDrawElements")
if c.gpDrawElements == 0 { if c.gpDrawElements == 0 {
return errors.New("gl: glDrawElements is missing") return errors.New("gl: glDrawElements is missing")
} }
c.gpEnable = getProcAddress("glEnable") c.gpEnable = c.getProcAddress("glEnable")
if c.gpEnable == 0 { if c.gpEnable == 0 {
return errors.New("gl: glEnable is missing") return errors.New("gl: glEnable is missing")
} }
c.gpEnableVertexAttribArray = getProcAddress("glEnableVertexAttribArray") c.gpEnableVertexAttribArray = c.getProcAddress("glEnableVertexAttribArray")
if c.gpEnableVertexAttribArray == 0 { if c.gpEnableVertexAttribArray == 0 {
return errors.New("gl: glEnableVertexAttribArray is missing") return errors.New("gl: glEnableVertexAttribArray is missing")
} }
c.gpFlush = getProcAddress("glFlush") c.gpFlush = c.getProcAddress("glFlush")
if c.gpFlush == 0 { if c.gpFlush == 0 {
return errors.New("gl: glFlush is missing") return errors.New("gl: glFlush is missing")
} }
c.gpFramebufferRenderbufferEXT = getProcAddress("glFramebufferRenderbufferEXT") c.gpFramebufferRenderbufferEXT = c.getProcAddress("glFramebufferRenderbufferEXT")
c.gpFramebufferTexture2DEXT = getProcAddress("glFramebufferTexture2DEXT") c.gpFramebufferTexture2DEXT = c.getProcAddress("glFramebufferTexture2DEXT")
c.gpGenBuffers = getProcAddress("glGenBuffers") c.gpGenBuffers = c.getProcAddress("glGenBuffers")
if c.gpGenBuffers == 0 { if c.gpGenBuffers == 0 {
return errors.New("gl: glGenBuffers is missing") return errors.New("gl: glGenBuffers is missing")
} }
c.gpGenFramebuffersEXT = getProcAddress("glGenFramebuffersEXT") c.gpGenFramebuffersEXT = c.getProcAddress("glGenFramebuffersEXT")
c.gpGenRenderbuffersEXT = getProcAddress("glGenRenderbuffersEXT") c.gpGenRenderbuffersEXT = c.getProcAddress("glGenRenderbuffersEXT")
c.gpGenTextures = getProcAddress("glGenTextures") c.gpGenTextures = c.getProcAddress("glGenTextures")
if c.gpGenTextures == 0 { if c.gpGenTextures == 0 {
return errors.New("gl: glGenTextures is missing") return errors.New("gl: glGenTextures is missing")
} }
c.gpGetError = getProcAddress("glGetError") c.gpGetError = c.getProcAddress("glGetError")
if c.gpGetError == 0 { if c.gpGetError == 0 {
return errors.New("gl: glGetError is missing") return errors.New("gl: glGetError is missing")
} }
c.gpGetIntegerv = getProcAddress("glGetIntegerv") c.gpGetIntegerv = c.getProcAddress("glGetIntegerv")
if c.gpGetIntegerv == 0 { if c.gpGetIntegerv == 0 {
return errors.New("gl: glGetIntegerv is missing") return errors.New("gl: glGetIntegerv is missing")
} }
c.gpGetProgramInfoLog = getProcAddress("glGetProgramInfoLog") c.gpGetProgramInfoLog = c.getProcAddress("glGetProgramInfoLog")
if c.gpGetProgramInfoLog == 0 { if c.gpGetProgramInfoLog == 0 {
return errors.New("gl: glGetProgramInfoLog is missing") return errors.New("gl: glGetProgramInfoLog is missing")
} }
c.gpGetProgramiv = getProcAddress("glGetProgramiv") c.gpGetProgramiv = c.getProcAddress("glGetProgramiv")
if c.gpGetProgramiv == 0 { if c.gpGetProgramiv == 0 {
return errors.New("gl: glGetProgramiv is missing") return errors.New("gl: glGetProgramiv is missing")
} }
c.gpGetShaderInfoLog = getProcAddress("glGetShaderInfoLog") c.gpGetShaderInfoLog = c.getProcAddress("glGetShaderInfoLog")
if c.gpGetShaderInfoLog == 0 { if c.gpGetShaderInfoLog == 0 {
return errors.New("gl: glGetShaderInfoLog is missing") return errors.New("gl: glGetShaderInfoLog is missing")
} }
c.gpGetShaderiv = getProcAddress("glGetShaderiv") c.gpGetShaderiv = c.getProcAddress("glGetShaderiv")
if c.gpGetShaderiv == 0 { if c.gpGetShaderiv == 0 {
return errors.New("gl: glGetShaderiv is missing") return errors.New("gl: glGetShaderiv is missing")
} }
c.gpGetUniformLocation = getProcAddress("glGetUniformLocation") c.gpGetUniformLocation = c.getProcAddress("glGetUniformLocation")
if c.gpGetUniformLocation == 0 { if c.gpGetUniformLocation == 0 {
return errors.New("gl: glGetUniformLocation is missing") return errors.New("gl: glGetUniformLocation is missing")
} }
c.gpIsFramebufferEXT = getProcAddress("glIsFramebufferEXT") c.gpIsFramebufferEXT = c.getProcAddress("glIsFramebufferEXT")
c.gpIsProgram = getProcAddress("glIsProgram") c.gpIsProgram = c.getProcAddress("glIsProgram")
if c.gpIsProgram == 0 { if c.gpIsProgram == 0 {
return errors.New("gl: glIsProgram is missing") return errors.New("gl: glIsProgram is missing")
} }
c.gpIsRenderbufferEXT = getProcAddress("glIsRenderbufferEXT") c.gpIsRenderbufferEXT = c.getProcAddress("glIsRenderbufferEXT")
c.gpIsTexture = getProcAddress("glIsTexture") c.gpIsTexture = c.getProcAddress("glIsTexture")
if c.gpIsTexture == 0 { if c.gpIsTexture == 0 {
return errors.New("gl: glIsTexture is missing") return errors.New("gl: glIsTexture is missing")
} }
c.gpLinkProgram = getProcAddress("glLinkProgram") c.gpLinkProgram = c.getProcAddress("glLinkProgram")
if c.gpLinkProgram == 0 { if c.gpLinkProgram == 0 {
return errors.New("gl: glLinkProgram is missing") return errors.New("gl: glLinkProgram is missing")
} }
c.gpPixelStorei = getProcAddress("glPixelStorei") c.gpPixelStorei = c.getProcAddress("glPixelStorei")
if c.gpPixelStorei == 0 { if c.gpPixelStorei == 0 {
return errors.New("gl: glPixelStorei is missing") return errors.New("gl: glPixelStorei is missing")
} }
c.gpReadPixels = getProcAddress("glReadPixels") c.gpReadPixels = c.getProcAddress("glReadPixels")
if c.gpReadPixels == 0 { if c.gpReadPixels == 0 {
return errors.New("gl: glReadPixels is missing") return errors.New("gl: glReadPixels is missing")
} }
c.gpRenderbufferStorageEXT = getProcAddress("glRenderbufferStorageEXT") c.gpRenderbufferStorageEXT = c.getProcAddress("glRenderbufferStorageEXT")
c.gpScissor = getProcAddress("glScissor") c.gpScissor = c.getProcAddress("glScissor")
if c.gpScissor == 0 { if c.gpScissor == 0 {
return errors.New("gl: glScissor is missing") return errors.New("gl: glScissor is missing")
} }
c.gpShaderSource = getProcAddress("glShaderSource") c.gpShaderSource = c.getProcAddress("glShaderSource")
if c.gpShaderSource == 0 { if c.gpShaderSource == 0 {
return errors.New("gl: glShaderSource is missing") return errors.New("gl: glShaderSource is missing")
} }
c.gpStencilFunc = getProcAddress("glStencilFunc") c.gpStencilFunc = c.getProcAddress("glStencilFunc")
if c.gpStencilFunc == 0 { if c.gpStencilFunc == 0 {
return errors.New("gl: glStencilFunc is missing") return errors.New("gl: glStencilFunc is missing")
} }
c.gpStencilOp = getProcAddress("glStencilOp") c.gpStencilOp = c.getProcAddress("glStencilOp")
if c.gpStencilOp == 0 { if c.gpStencilOp == 0 {
return errors.New("gl: glStencilOp is missing") return errors.New("gl: glStencilOp is missing")
} }
c.gpTexImage2D = getProcAddress("glTexImage2D") c.gpTexImage2D = c.getProcAddress("glTexImage2D")
if c.gpTexImage2D == 0 { if c.gpTexImage2D == 0 {
return errors.New("gl: glTexImage2D is missing") return errors.New("gl: glTexImage2D is missing")
} }
c.gpTexParameteri = getProcAddress("glTexParameteri") c.gpTexParameteri = c.getProcAddress("glTexParameteri")
if c.gpTexParameteri == 0 { if c.gpTexParameteri == 0 {
return errors.New("gl: glTexParameteri is missing") return errors.New("gl: glTexParameteri is missing")
} }
c.gpTexSubImage2D = getProcAddress("glTexSubImage2D") c.gpTexSubImage2D = c.getProcAddress("glTexSubImage2D")
if c.gpTexSubImage2D == 0 { if c.gpTexSubImage2D == 0 {
return errors.New("gl: glTexSubImage2D is missing") return errors.New("gl: glTexSubImage2D is missing")
} }
c.gpUniform1fv = getProcAddress("glUniform1fv") c.gpUniform1fv = c.getProcAddress("glUniform1fv")
if c.gpUniform1fv == 0 { if c.gpUniform1fv == 0 {
return errors.New("gl: glUniform1fv is missing") return errors.New("gl: glUniform1fv is missing")
} }
c.gpUniform1i = getProcAddress("glUniform1i") c.gpUniform1i = c.getProcAddress("glUniform1i")
if c.gpUniform1i == 0 { if c.gpUniform1i == 0 {
return errors.New("gl: glUniform1i is missing") return errors.New("gl: glUniform1i is missing")
} }
c.gpUniform1iv = getProcAddress("glUniform1iv") c.gpUniform1iv = c.getProcAddress("glUniform1iv")
if c.gpUniform1iv == 0 { if c.gpUniform1iv == 0 {
return errors.New("gl: glUniform1iv is missing") return errors.New("gl: glUniform1iv is missing")
} }
c.gpUniform2fv = getProcAddress("glUniform2fv") c.gpUniform2fv = c.getProcAddress("glUniform2fv")
if c.gpUniform2fv == 0 { if c.gpUniform2fv == 0 {
return errors.New("gl: glUniform2fv is missing") return errors.New("gl: glUniform2fv is missing")
} }
c.gpUniform3fv = getProcAddress("glUniform3fv") c.gpUniform3fv = c.getProcAddress("glUniform3fv")
if c.gpUniform3fv == 0 { if c.gpUniform3fv == 0 {
return errors.New("gl: glUniform3fv is missing") return errors.New("gl: glUniform3fv is missing")
} }
c.gpUniform4fv = getProcAddress("glUniform4fv") c.gpUniform4fv = c.getProcAddress("glUniform4fv")
if c.gpUniform4fv == 0 { if c.gpUniform4fv == 0 {
return errors.New("gl: glUniform4fv is missing") return errors.New("gl: glUniform4fv is missing")
} }
c.gpUniformMatrix2fv = getProcAddress("glUniformMatrix2fv") c.gpUniformMatrix2fv = c.getProcAddress("glUniformMatrix2fv")
if c.gpUniformMatrix2fv == 0 { if c.gpUniformMatrix2fv == 0 {
return errors.New("gl: glUniformMatrix2fv is missing") return errors.New("gl: glUniformMatrix2fv is missing")
} }
c.gpUniformMatrix3fv = getProcAddress("glUniformMatrix3fv") c.gpUniformMatrix3fv = c.getProcAddress("glUniformMatrix3fv")
if c.gpUniformMatrix3fv == 0 { if c.gpUniformMatrix3fv == 0 {
return errors.New("gl: glUniformMatrix3fv is missing") return errors.New("gl: glUniformMatrix3fv is missing")
} }
c.gpUniformMatrix4fv = getProcAddress("glUniformMatrix4fv") c.gpUniformMatrix4fv = c.getProcAddress("glUniformMatrix4fv")
if c.gpUniformMatrix4fv == 0 { if c.gpUniformMatrix4fv == 0 {
return errors.New("gl: glUniformMatrix4fv is missing") return errors.New("gl: glUniformMatrix4fv is missing")
} }
c.gpUseProgram = getProcAddress("glUseProgram") c.gpUseProgram = c.getProcAddress("glUseProgram")
if c.gpUseProgram == 0 { if c.gpUseProgram == 0 {
return errors.New("gl: glUseProgram is missing") return errors.New("gl: glUseProgram is missing")
} }
c.gpVertexAttribPointer = getProcAddress("glVertexAttribPointer") c.gpVertexAttribPointer = c.getProcAddress("glVertexAttribPointer")
if c.gpVertexAttribPointer == 0 { if c.gpVertexAttribPointer == 0 {
return errors.New("gl: glVertexAttribPointer is missing") return errors.New("gl: glVertexAttribPointer is missing")
} }
c.gpViewport = getProcAddress("glViewport") c.gpViewport = c.getProcAddress("glViewport")
if c.gpViewport == 0 { if c.gpViewport == 0 {
return errors.New("gl: glViewport is missing") return errors.New("gl: glViewport is missing")
} }

View File

@ -35,7 +35,7 @@ func NewGomobileContext(ctx gl.Context) Context {
return &gomobileContext{ctx} return &gomobileContext{ctx}
} }
func (g *gomobileContext) Init() error { func (g *gomobileContext) LoadFunctions() error {
return nil return nil
} }

View File

@ -19,7 +19,7 @@ package gl
// Context is basically the same as gomobile's gl.Context. // Context is basically the same as gomobile's gl.Context.
// See https://pkg.go.dev/golang.org/x/mobile/gl#Context // See https://pkg.go.dev/golang.org/x/mobile/gl#Context
type Context interface { type Context interface {
Init() error LoadFunctions() error
IsES() bool IsES() bool
ActiveTexture(texture uint32) ActiveTexture(texture uint32)

View File

@ -15,23 +15,28 @@
package gl package gl
import ( import (
"fmt"
"github.com/ebitengine/purego" "github.com/ebitengine/purego"
) )
var ( var (
opengl uintptr 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) opengl = purego.Dlopen("/System/Library/Frameworks/OpenGLES.framework/Versions/Current/OpenGLES", purego.RTLD_LAZY|purego.RTLD_GLOBAL)
if opengl != 0 { if opengl != 0 {
isES = true c.isES = true
return return nil
} }
opengl = purego.Dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", purego.RTLD_LAZY|purego.RTLD_GLOBAL) 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) return purego.Dlsym(opengl, name)
} }

View File

@ -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 <dlfcn.h>
// #include <stdlib.h>
//
// 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)
}

View File

@ -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 <dlfcn.h>
// #include <stdlib.h>
//
// 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)
}

View File

@ -28,10 +28,12 @@ import "C"
import "unsafe" import "unsafe"
var isES = false func (c *defaultContext) init() error {
return nil
}
func getProcAddress(namea string) unsafe.Pointer { func (c *defaultContext) getProcAddress(name string) unsafe.Pointer {
cname := C.CString(namea) cname := C.CString(name)
defer C.free(unsafe.Pointer(cname)) defer C.free(unsafe.Pointer(cname))
return C.getProcAddress(cname) return C.getProcAddress(cname)
} }

View File

@ -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 <dlfcn.h>
// #include <stdlib.h>
//
// 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)
}

View File

@ -24,10 +24,13 @@ import (
var ( var (
opengl32 = windows.NewLazySystemDLL("opengl32") opengl32 = windows.NewLazySystemDLL("opengl32")
procWglGetProcAddress = opengl32.NewProc("wglGetProcAddress") 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) cname, err := windows.BytePtrFromString(namea)
if err != nil { if err != nil {
panic(err) panic(err)

View File

@ -31,7 +31,12 @@ func NewGraphics() (graphicsdriver.Graphics, error) {
return nil, fmt.Errorf("opengl: OpenGL is not supported on Xbox") return nil, fmt.Errorf("opengl: OpenGL is not supported on Xbox")
} }
ctx, err := gl.NewDefaultContext()
if err != nil {
return nil, err
}
g := &Graphics{} g := &Graphics{}
g.context.ctx = gl.NewDefaultContext() g.context.ctx = ctx
return g, nil return g, nil
} }

View File

@ -30,7 +30,11 @@ func NewGraphics(context mgl.Context) (graphicsdriver.Graphics, error) {
if context != nil { if context != nil {
ctx = gl.NewGomobileContext(context.(mgl.Context)) ctx = gl.NewGomobileContext(context.(mgl.Context))
} else { } else {
ctx = gl.NewDefaultContext() var err error
ctx, err = gl.NewDefaultContext()
if err != nil {
return nil, err
}
} }
g := &Graphics{} g := &Graphics{}