opengl: Update context_mobile.go

This commit is contained in:
Hajime Hoshi 2016-05-07 19:12:19 +09:00
parent e99736d5a5
commit de541bdd7d

View File

@ -14,7 +14,7 @@
// NOTICE: This file is not maintained well. // NOTICE: This file is not maintained well.
// +build android ios // +build android
package opengl package opengl
@ -48,16 +48,11 @@ func (p Program) id() programID {
} }
type context struct { type context struct {
locationCache *locationCache gl mgl.Context
worker mgl.Worker locationCache *locationCache
funcs chan func() lastCompositeMode CompositeMode
} }
// TODO: This variable can be in the context struct.
var (
gl mgl.Context
)
func NewContext() *Context { func NewContext() *Context {
c := &Context{ c := &Context{
Nearest: mgl.NEAREST, Nearest: mgl.NEAREST,
@ -72,42 +67,36 @@ func NewContext() *Context {
Lines: mgl.LINES, Lines: mgl.LINES,
} }
c.locationCache = newLocationCache() c.locationCache = newLocationCache()
c.funcs = make(chan func()) c.lastCompositeMode = CompositeModeUnknown
gl, c.worker = mgl.NewContext()
return c return c
} }
func (c *Context) Loop() { func (c *Context) SetContext(gl mgl.Context) {
for { c.gl = gl
select { if gl == nil {
case <-c.worker.WorkAvailable(): return
c.worker.DoWork()
case f := <-c.funcs:
f()
}
} }
}
func (c *Context) Init() {
// This initialization must be done after Loop is called.
// This is why Init is separated from NewContext.
// Textures' pixel formats are alpha premultiplied. // Textures' pixel formats are alpha premultiplied.
gl.Enable(mgl.BLEND) gl.Enable(mgl.BLEND)
gl.BlendFunc(mgl.ONE, mgl.ONE_MINUS_SRC_ALPHA) c.BlendFunc(CompositeModeSourceOver)
} }
func (c *Context) RunOnContextThread(f func()) { func (c *Context) IsGLContextNil() bool {
ch := make(chan struct{}) return c.gl == nil
c.funcs <- func() { }
f()
close(ch) func (c *Context) BlendFunc(mode CompositeMode) {
gl := c.gl
if c.lastCompositeMode == mode {
return
} }
<-ch c.lastCompositeMode = mode
return s, d := c.operations(mode)
gl.BlendFunc(mgl.Enum(s), mgl.Enum(d))
} }
func (c *Context) NewTexture(width, height int, pixels []uint8, filter Filter) (Texture, error) { func (c *Context) NewTexture(width, height int, pixels []uint8, filter Filter) (Texture, error) {
gl := c.gl
t := gl.CreateTexture() t := gl.CreateTexture()
if t.Value <= 0 { if t.Value <= 0 {
return Texture{}, errors.New("opengl: creating texture failed") return Texture{}, errors.New("opengl: creating texture failed")
@ -128,6 +117,7 @@ func (c *Context) NewTexture(width, height int, pixels []uint8, filter Filter) (
} }
func (c *Context) FramebufferPixels(f Framebuffer, width, height int) ([]uint8, error) { func (c *Context) FramebufferPixels(f Framebuffer, width, height int) ([]uint8, error) {
gl := c.gl
gl.Flush() gl.Flush()
gl.BindFramebuffer(mgl.FRAMEBUFFER, mgl.Framebuffer(f)) gl.BindFramebuffer(mgl.FRAMEBUFFER, mgl.Framebuffer(f))
@ -141,22 +131,27 @@ func (c *Context) FramebufferPixels(f Framebuffer, width, height int) ([]uint8,
} }
func (c *Context) BindTexture(t Texture) { func (c *Context) BindTexture(t Texture) {
gl := c.gl
gl.BindTexture(mgl.TEXTURE_2D, mgl.Texture(t)) gl.BindTexture(mgl.TEXTURE_2D, mgl.Texture(t))
} }
func (c *Context) DeleteTexture(t Texture) { func (c *Context) DeleteTexture(t Texture) {
gl := c.gl
gl.DeleteTexture(mgl.Texture(t)) gl.DeleteTexture(mgl.Texture(t))
} }
func (c *Context) TexSubImage2D(p []uint8, width, height int) { func (c *Context) TexSubImage2D(p []uint8, width, height int) {
gl := c.gl
gl.TexSubImage2D(mgl.TEXTURE_2D, 0, 0, 0, width, height, mgl.RGBA, mgl.UNSIGNED_BYTE, p) gl.TexSubImage2D(mgl.TEXTURE_2D, 0, 0, 0, width, height, mgl.RGBA, mgl.UNSIGNED_BYTE, p)
} }
func (c *Context) BindZeroFramebuffer() { func (c *Context) BindZeroFramebuffer() {
gl := c.gl
gl.BindFramebuffer(mgl.FRAMEBUFFER, mgl.Framebuffer(ZeroFramebuffer)) gl.BindFramebuffer(mgl.FRAMEBUFFER, mgl.Framebuffer(ZeroFramebuffer))
} }
func (c *Context) NewFramebuffer(texture Texture) (Framebuffer, error) { func (c *Context) NewFramebuffer(texture Texture) (Framebuffer, error) {
gl := c.gl
f := gl.CreateFramebuffer() f := gl.CreateFramebuffer()
if f.Value <= 0 { if f.Value <= 0 {
return Framebuffer{}, errors.New("opengl: creating framebuffer failed: gl.IsFramebuffer returns false") return Framebuffer{}, errors.New("opengl: creating framebuffer failed: gl.IsFramebuffer returns false")
@ -179,6 +174,7 @@ func (c *Context) NewFramebuffer(texture Texture) (Framebuffer, error) {
} }
func (c *Context) SetViewport(f Framebuffer, width, height int) error { func (c *Context) SetViewport(f Framebuffer, width, height int) error {
gl := c.gl
gl.Flush() gl.Flush()
gl.BindFramebuffer(mgl.FRAMEBUFFER, mgl.Framebuffer(f)) gl.BindFramebuffer(mgl.FRAMEBUFFER, mgl.Framebuffer(f))
if err := gl.CheckFramebufferStatus(mgl.FRAMEBUFFER); err != mgl.FRAMEBUFFER_COMPLETE { if err := gl.CheckFramebufferStatus(mgl.FRAMEBUFFER); err != mgl.FRAMEBUFFER_COMPLETE {
@ -192,16 +188,19 @@ func (c *Context) SetViewport(f Framebuffer, width, height int) error {
} }
func (c *Context) FillFramebuffer(r, g, b, a float64) error { func (c *Context) FillFramebuffer(r, g, b, a float64) error {
gl := c.gl
gl.ClearColor(float32(r), float32(g), float32(b), float32(a)) gl.ClearColor(float32(r), float32(g), float32(b), float32(a))
gl.Clear(mgl.COLOR_BUFFER_BIT) gl.Clear(mgl.COLOR_BUFFER_BIT)
return nil return nil
} }
func (c *Context) DeleteFramebuffer(f Framebuffer) { func (c *Context) DeleteFramebuffer(f Framebuffer) {
gl := c.gl
gl.DeleteFramebuffer(mgl.Framebuffer(f)) gl.DeleteFramebuffer(mgl.Framebuffer(f))
} }
func (c *Context) NewShader(shaderType ShaderType, source string) (Shader, error) { func (c *Context) NewShader(shaderType ShaderType, source string) (Shader, error) {
gl := c.gl
s := gl.CreateShader(mgl.Enum(shaderType)) s := gl.CreateShader(mgl.Enum(shaderType))
if s.Value == 0 { if s.Value == 0 {
return Shader{}, errors.New("opengl: glCreateShader failed") return Shader{}, errors.New("opengl: glCreateShader failed")
@ -218,14 +217,17 @@ func (c *Context) NewShader(shaderType ShaderType, source string) (Shader, error
} }
func (c *Context) DeleteShader(s Shader) { func (c *Context) DeleteShader(s Shader) {
gl := c.gl
gl.DeleteShader(mgl.Shader(s)) gl.DeleteShader(mgl.Shader(s))
} }
func (c *Context) GlslHighpSupported() bool { func (c *Context) GlslHighpSupported() bool {
// TODO: Fix this
return false return false
} }
func (c *Context) NewProgram(shaders []Shader) (Program, error) { func (c *Context) NewProgram(shaders []Shader) (Program, error) {
gl := c.gl
p := gl.CreateProgram() p := gl.CreateProgram()
if p.Value == 0 { if p.Value == 0 {
return Program{}, errors.New("opengl: glCreateProgram failed") return Program{}, errors.New("opengl: glCreateProgram failed")
@ -243,10 +245,12 @@ func (c *Context) NewProgram(shaders []Shader) (Program, error) {
} }
func (c *Context) UseProgram(p Program) { func (c *Context) UseProgram(p Program) {
gl := c.gl
gl.UseProgram(mgl.Program(p)) gl.UseProgram(mgl.Program(p))
} }
func (c *Context) getUniformLocation(p Program, location string) uniformLocation { func (c *Context) getUniformLocation(p Program, location string) uniformLocation {
gl := c.gl
u := uniformLocation(gl.GetUniformLocation(mgl.Program(p), location)) u := uniformLocation(gl.GetUniformLocation(mgl.Program(p), location))
if u.Value == -1 { if u.Value == -1 {
panic("invalid uniform location: " + location) panic("invalid uniform location: " + location)
@ -255,10 +259,12 @@ func (c *Context) getUniformLocation(p Program, location string) uniformLocation
} }
func (c *Context) UniformInt(p Program, location string, v int) { func (c *Context) UniformInt(p Program, location string, v int) {
gl := c.gl
gl.Uniform1i(mgl.Uniform(c.locationCache.GetUniformLocation(c, p, location)), v) gl.Uniform1i(mgl.Uniform(c.locationCache.GetUniformLocation(c, p, location)), v)
} }
func (c *Context) UniformFloats(p Program, location string, v []float32) { func (c *Context) UniformFloats(p Program, location string, v []float32) {
gl := c.gl
l := mgl.Uniform(c.locationCache.GetUniformLocation(c, p, location)) l := mgl.Uniform(c.locationCache.GetUniformLocation(c, p, location))
switch len(v) { switch len(v) {
case 4: case 4:
@ -271,6 +277,7 @@ func (c *Context) UniformFloats(p Program, location string, v []float32) {
} }
func (c *Context) getAttribLocation(p Program, location string) attribLocation { func (c *Context) getAttribLocation(p Program, location string) attribLocation {
gl := c.gl
a := attribLocation(gl.GetAttribLocation(mgl.Program(p), location)) a := attribLocation(gl.GetAttribLocation(mgl.Program(p), location))
if a.Value == ^uint(0) { if a.Value == ^uint(0) {
panic("invalid attrib location: " + location) panic("invalid attrib location: " + location)
@ -279,16 +286,19 @@ func (c *Context) getAttribLocation(p Program, location string) attribLocation {
} }
func (c *Context) VertexAttribPointer(p Program, location string, normalize bool, stride int, size int, v int) { func (c *Context) VertexAttribPointer(p Program, location string, normalize bool, stride int, size int, v int) {
gl := c.gl
l := c.locationCache.GetAttribLocation(c, p, location) l := c.locationCache.GetAttribLocation(c, p, location)
gl.VertexAttribPointer(mgl.Attrib(l), size, mgl.SHORT, normalize, stride, v) gl.VertexAttribPointer(mgl.Attrib(l), size, mgl.SHORT, normalize, stride, v)
} }
func (c *Context) EnableVertexAttribArray(p Program, location string) { func (c *Context) EnableVertexAttribArray(p Program, location string) {
gl := c.gl
l := c.locationCache.GetAttribLocation(c, p, location) l := c.locationCache.GetAttribLocation(c, p, location)
gl.EnableVertexAttribArray(mgl.Attrib(l)) gl.EnableVertexAttribArray(mgl.Attrib(l))
} }
func (c *Context) DisableVertexAttribArray(p Program, location string) { func (c *Context) DisableVertexAttribArray(p Program, location string) {
gl := c.gl
l := c.locationCache.GetAttribLocation(c, p, location) l := c.locationCache.GetAttribLocation(c, p, location)
gl.DisableVertexAttribArray(mgl.Attrib(l)) gl.DisableVertexAttribArray(mgl.Attrib(l))
} }
@ -312,6 +322,7 @@ func int16ToBytes(v []int16) []byte {
} }
func (c *Context) NewBuffer(bufferType BufferType, v interface{}, bufferUsage BufferUsage) Buffer { func (c *Context) NewBuffer(bufferType BufferType, v interface{}, bufferUsage BufferUsage) Buffer {
gl := c.gl
b := gl.CreateBuffer() b := gl.CreateBuffer()
gl.BindBuffer(mgl.Enum(bufferType), b) gl.BindBuffer(mgl.Enum(bufferType), b)
switch v := v.(type) { switch v := v.(type) {
@ -327,13 +338,16 @@ func (c *Context) NewBuffer(bufferType BufferType, v interface{}, bufferUsage Bu
} }
func (c *Context) BindElementArrayBuffer(b Buffer) { func (c *Context) BindElementArrayBuffer(b Buffer) {
gl := c.gl
gl.BindBuffer(mgl.ELEMENT_ARRAY_BUFFER, mgl.Buffer(b)) gl.BindBuffer(mgl.ELEMENT_ARRAY_BUFFER, mgl.Buffer(b))
} }
func (c *Context) BufferSubData(bufferType BufferType, data []int16) { func (c *Context) BufferSubData(bufferType BufferType, data []int16) {
gl := c.gl
gl.BufferSubData(mgl.Enum(bufferType), 0, int16ToBytes(data)) gl.BufferSubData(mgl.Enum(bufferType), 0, int16ToBytes(data))
} }
func (c *Context) DrawElements(mode Mode, len int) { func (c *Context) DrawElements(mode Mode, len int) {
gl := c.gl
gl.DrawElements(mgl.Enum(mode), len, mgl.UNSIGNED_SHORT, 0) gl.DrawElements(mgl.Enum(mode), len, mgl.UNSIGNED_SHORT, 0)
} }