mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-11 19:48:54 +01:00
graphicsdriver/opengl: Rename Driver -> Graphics
This commit is contained in:
parent
01d1afa25c
commit
eabe4152a7
@ -16,10 +16,10 @@ package opengl
|
|||||||
|
|
||||||
// framebuffer is a wrapper of OpenGL's framebuffer.
|
// framebuffer is a wrapper of OpenGL's framebuffer.
|
||||||
type framebuffer struct {
|
type framebuffer struct {
|
||||||
driver *Driver
|
graphics *Graphics
|
||||||
native framebufferNative
|
native framebufferNative
|
||||||
width int
|
width int
|
||||||
height int
|
height int
|
||||||
}
|
}
|
||||||
|
|
||||||
// newFramebufferFromTexture creates a framebuffer from the given texture.
|
// newFramebufferFromTexture creates a framebuffer from the given texture.
|
||||||
|
@ -23,13 +23,13 @@ import (
|
|||||||
"github.com/hajimehoshi/ebiten/internal/thread"
|
"github.com/hajimehoshi/ebiten/internal/thread"
|
||||||
)
|
)
|
||||||
|
|
||||||
var theDriver Driver
|
var theGraphics Graphics
|
||||||
|
|
||||||
func Get() *Driver {
|
func Get() *Graphics {
|
||||||
return &theDriver
|
return &theGraphics
|
||||||
}
|
}
|
||||||
|
|
||||||
type Driver struct {
|
type Graphics struct {
|
||||||
state openGLState
|
state openGLState
|
||||||
context context
|
context context
|
||||||
|
|
||||||
@ -37,32 +37,32 @@ type Driver struct {
|
|||||||
drawCalled bool
|
drawCalled bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) SetThread(thread *thread.Thread) {
|
func (g *Graphics) SetThread(thread *thread.Thread) {
|
||||||
d.context.t = thread
|
g.context.t = thread
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) Begin() {
|
func (g *Graphics) Begin() {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) End() {
|
func (g *Graphics) End() {
|
||||||
// Call glFlush to prevent black flicking (especially on Android (#226) and iOS).
|
// Call glFlush to prevent black flicking (especially on Android (#226) and iOS).
|
||||||
// TODO: examples/sprites worked without this. Is this really needed?
|
// TODO: examples/sprites worked without this. Is this really needed?
|
||||||
d.context.flush()
|
g.context.flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) SetTransparent(transparent bool) {
|
func (g *Graphics) SetTransparent(transparent bool) {
|
||||||
// Do nothings.
|
// Do nothings.
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) checkSize(width, height int) {
|
func (g *Graphics) checkSize(width, height int) {
|
||||||
if width < 1 {
|
if width < 1 {
|
||||||
panic(fmt.Sprintf("opengl: width (%d) must be equal or more than %d", width, 1))
|
panic(fmt.Sprintf("opengl: width (%d) must be equal or more than %d", width, 1))
|
||||||
}
|
}
|
||||||
if height < 1 {
|
if height < 1 {
|
||||||
panic(fmt.Sprintf("opengl: height (%d) must be equal or more than %d", height, 1))
|
panic(fmt.Sprintf("opengl: height (%d) must be equal or more than %d", height, 1))
|
||||||
}
|
}
|
||||||
m := d.context.getMaxTextureSize()
|
m := g.context.getMaxTextureSize()
|
||||||
if width > m {
|
if width > m {
|
||||||
panic(fmt.Sprintf("opengl: width (%d) must be less than or equal to %d", width, m))
|
panic(fmt.Sprintf("opengl: width (%d) must be less than or equal to %d", width, m))
|
||||||
}
|
}
|
||||||
@ -71,16 +71,16 @@ func (d *Driver) checkSize(width, height int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) NewImage(width, height int) (driver.Image, error) {
|
func (g *Graphics) NewImage(width, height int) (driver.Image, error) {
|
||||||
i := &Image{
|
i := &Image{
|
||||||
driver: d,
|
graphics: g,
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
}
|
}
|
||||||
w := graphics.InternalImageSize(width)
|
w := graphics.InternalImageSize(width)
|
||||||
h := graphics.InternalImageSize(height)
|
h := graphics.InternalImageSize(height)
|
||||||
d.checkSize(w, h)
|
g.checkSize(w, h)
|
||||||
t, err := d.context.newTexture(w, h)
|
t, err := g.context.newTexture(w, h)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -88,63 +88,63 @@ func (d *Driver) NewImage(width, height int) (driver.Image, error) {
|
|||||||
return i, nil
|
return i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) NewScreenFramebufferImage(width, height int) (driver.Image, error) {
|
func (g *Graphics) NewScreenFramebufferImage(width, height int) (driver.Image, error) {
|
||||||
d.checkSize(width, height)
|
g.checkSize(width, height)
|
||||||
i := &Image{
|
i := &Image{
|
||||||
driver: d,
|
graphics: g,
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
screen: true,
|
screen: true,
|
||||||
}
|
}
|
||||||
return i, nil
|
return i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset resets or initializes the current OpenGL state.
|
// Reset resets or initializes the current OpenGL state.
|
||||||
func (d *Driver) Reset() error {
|
func (g *Graphics) Reset() error {
|
||||||
return d.state.reset(&d.context)
|
return g.state.reset(&g.context)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) SetVertices(vertices []float32, indices []uint16) {
|
func (g *Graphics) SetVertices(vertices []float32, indices []uint16) {
|
||||||
// Note that the vertices passed to BufferSubData is not under GC management
|
// Note that the vertices passed to BufferSubData is not under GC management
|
||||||
// in opengl package due to unsafe-way.
|
// in opengl package due to unsafe-way.
|
||||||
// See BufferSubData in context_mobile.go.
|
// See BufferSubData in context_mobile.go.
|
||||||
d.context.arrayBufferSubData(vertices)
|
g.context.arrayBufferSubData(vertices)
|
||||||
d.context.elementArrayBufferSubData(indices)
|
g.context.elementArrayBufferSubData(indices)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) Draw(indexLen int, indexOffset int, mode driver.CompositeMode, colorM *affine.ColorM, filter driver.Filter, address driver.Address) error {
|
func (g *Graphics) Draw(indexLen int, indexOffset int, mode driver.CompositeMode, colorM *affine.ColorM, filter driver.Filter, address driver.Address) error {
|
||||||
d.drawCalled = true
|
g.drawCalled = true
|
||||||
if err := d.useProgram(mode, colorM, filter, address); err != nil {
|
if err := g.useProgram(mode, colorM, filter, address); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
d.context.drawElements(indexLen, indexOffset*2) // 2 is uint16 size in bytes
|
g.context.drawElements(indexLen, indexOffset*2) // 2 is uint16 size in bytes
|
||||||
// glFlush() might be necessary at least on MacBook Pro (a smilar problem at #419),
|
// glFlush() might be necessary at least on MacBook Pro (a smilar problem at #419),
|
||||||
// but basically this pass the tests (esp. TestImageTooManyFill).
|
// but basically this pass the tests (esp. TestImageTooManyFill).
|
||||||
// As glFlush() causes performance problems, this should be avoided as much as possible.
|
// As glFlush() causes performance problems, this should be avoided as much as possible.
|
||||||
// Let's wait and see, and file a new issue when this problem is newly found.
|
// Let's wait and see, and file a new issue when this problem is newly foung.
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) SetVsyncEnabled(enabled bool) {
|
func (g *Graphics) SetVsyncEnabled(enabled bool) {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) VDirection() driver.VDirection {
|
func (g *Graphics) VDirection() driver.VDirection {
|
||||||
return driver.VDownward
|
return driver.VDownward
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) NeedsRestoring() bool {
|
func (g *Graphics) NeedsRestoring() bool {
|
||||||
return d.context.needsRestoring()
|
return g.context.needsRestoring()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) IsGL() bool {
|
func (g *Graphics) IsGL() bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) HasHighPrecisionFloat() bool {
|
func (g *Graphics) HasHighPrecisionFloat() bool {
|
||||||
return d.context.hasHighPrecisionFloat()
|
return g.context.hasHighPrecisionFloat()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) MaxImageSize() int {
|
func (g *Graphics) MaxImageSize() int {
|
||||||
return d.context.getMaxTextureSize()
|
return g.context.getMaxTextureSize()
|
||||||
}
|
}
|
@ -20,6 +20,6 @@ import (
|
|||||||
"golang.org/x/mobile/gl"
|
"golang.org/x/mobile/gl"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (d *Driver) SetMobileGLContext(context gl.Context) {
|
func (g *Graphics) SetMobileGLContext(context gl.Context) {
|
||||||
d.context.gl = context
|
g.context.gl = context
|
||||||
}
|
}
|
@ -20,7 +20,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Image struct {
|
type Image struct {
|
||||||
driver *Driver
|
graphics *Graphics
|
||||||
textureNative textureNative
|
textureNative textureNative
|
||||||
framebuffer *framebuffer
|
framebuffer *framebuffer
|
||||||
pbo buffer
|
pbo buffer
|
||||||
@ -30,30 +30,30 @@ type Image struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) IsInvalidated() bool {
|
func (i *Image) IsInvalidated() bool {
|
||||||
return !i.driver.context.isTexture(i.textureNative)
|
return !i.graphics.context.isTexture(i.textureNative)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) Dispose() {
|
func (i *Image) Dispose() {
|
||||||
if !i.pbo.equal(*new(buffer)) {
|
if !i.pbo.equal(*new(buffer)) {
|
||||||
i.driver.context.deleteBuffer(i.pbo)
|
i.graphics.context.deleteBuffer(i.pbo)
|
||||||
}
|
}
|
||||||
if i.framebuffer != nil {
|
if i.framebuffer != nil {
|
||||||
i.framebuffer.delete(&i.driver.context)
|
i.framebuffer.delete(&i.graphics.context)
|
||||||
}
|
}
|
||||||
if !i.textureNative.equal(*new(textureNative)) {
|
if !i.textureNative.equal(*new(textureNative)) {
|
||||||
i.driver.context.deleteTexture(i.textureNative)
|
i.graphics.context.deleteTexture(i.textureNative)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) SetAsDestination() {
|
func (i *Image) SetAsDestination() {
|
||||||
i.driver.state.destination = i
|
i.graphics.state.destination = i
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) setViewport() error {
|
func (i *Image) setViewport() error {
|
||||||
if err := i.ensureFramebuffer(); err != nil {
|
if err := i.ensureFramebuffer(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
i.driver.context.setViewport(i.framebuffer)
|
i.graphics.context.setViewport(i.framebuffer)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ func (i *Image) Pixels() ([]byte, error) {
|
|||||||
if err := i.ensureFramebuffer(); err != nil {
|
if err := i.ensureFramebuffer(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
p, err := i.driver.context.framebufferPixels(i.framebuffer, i.width, i.height)
|
p, err := i.graphics.context.framebufferPixels(i.framebuffer, i.width, i.height)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -77,12 +77,12 @@ func (i *Image) ensureFramebuffer() error {
|
|||||||
// The (default) framebuffer size can't be converted to a power of 2.
|
// The (default) framebuffer size can't be converted to a power of 2.
|
||||||
// On browsers, c.width and c.height are used as viewport size and
|
// On browsers, c.width and c.height are used as viewport size and
|
||||||
// Edge can't treat a bigger viewport than the drawing area (#71).
|
// Edge can't treat a bigger viewport than the drawing area (#71).
|
||||||
i.framebuffer = newScreenFramebuffer(&i.driver.context, i.width, i.height)
|
i.framebuffer = newScreenFramebuffer(&i.graphics.context, i.width, i.height)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
w, h := graphics.InternalImageSize(i.width), graphics.InternalImageSize(i.height)
|
w, h := graphics.InternalImageSize(i.width), graphics.InternalImageSize(i.height)
|
||||||
f, err := newFramebufferFromTexture(&i.driver.context, i.textureNative, w, h)
|
f, err := newFramebufferFromTexture(&i.graphics.context, i.textureNative, w, h)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -100,26 +100,26 @@ func (i *Image) ReplacePixels(args []*driver.ReplacePixelsArgs) {
|
|||||||
|
|
||||||
// glFlush is necessary on Android.
|
// glFlush is necessary on Android.
|
||||||
// glTexSubImage2D didn't work without this hack at least on Nexus 5x and NuAns NEO [Reloaded] (#211).
|
// glTexSubImage2D didn't work without this hack at least on Nexus 5x and NuAns NEO [Reloaded] (#211).
|
||||||
if i.driver.drawCalled {
|
if i.graphics.drawCalled {
|
||||||
i.driver.context.flush()
|
i.graphics.context.flush()
|
||||||
}
|
}
|
||||||
i.driver.drawCalled = false
|
i.graphics.drawCalled = false
|
||||||
|
|
||||||
w, h := i.width, i.height
|
w, h := i.width, i.height
|
||||||
if !i.driver.context.canUsePBO() {
|
if !i.graphics.context.canUsePBO() {
|
||||||
i.driver.context.texSubImage2D(i.textureNative, w, h, args)
|
i.graphics.context.texSubImage2D(i.textureNative, w, h, args)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if i.pbo.equal(*new(buffer)) {
|
if i.pbo.equal(*new(buffer)) {
|
||||||
i.pbo = i.driver.context.newPixelBufferObject(w, h)
|
i.pbo = i.graphics.context.newPixelBufferObject(w, h)
|
||||||
}
|
}
|
||||||
if i.pbo.equal(*new(buffer)) {
|
if i.pbo.equal(*new(buffer)) {
|
||||||
panic("opengl: newPixelBufferObject failed")
|
panic("opengl: newPixelBufferObject failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
i.driver.context.replacePixelsWithPBO(i.pbo, i.textureNative, w, h, args)
|
i.graphics.context.replacePixelsWithPBO(i.pbo, i.textureNative, w, h, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) SetAsSource() {
|
func (i *Image) SetAsSource() {
|
||||||
i.driver.state.source = i
|
i.graphics.state.source = i
|
||||||
}
|
}
|
||||||
|
@ -255,12 +255,12 @@ func areSameFloat32Array(a, b []float32) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// useProgram uses the program (programTexture).
|
// useProgram uses the program (programTexture).
|
||||||
func (d *Driver) useProgram(mode driver.CompositeMode, colorM *affine.ColorM, filter driver.Filter, address driver.Address) error {
|
func (g *Graphics) useProgram(mode driver.CompositeMode, colorM *affine.ColorM, filter driver.Filter, address driver.Address) error {
|
||||||
destination := d.state.destination
|
destination := g.state.destination
|
||||||
if destination == nil {
|
if destination == nil {
|
||||||
panic("destination image is not set")
|
panic("destination image is not set")
|
||||||
}
|
}
|
||||||
source := d.state.source
|
source := g.state.source
|
||||||
if source == nil {
|
if source == nil {
|
||||||
panic("source image is not set")
|
panic("source image is not set")
|
||||||
}
|
}
|
||||||
@ -271,73 +271,73 @@ func (d *Driver) useProgram(mode driver.CompositeMode, colorM *affine.ColorM, fi
|
|||||||
dstW := destination.width
|
dstW := destination.width
|
||||||
srcW, srcH := source.width, source.height
|
srcW, srcH := source.width, source.height
|
||||||
|
|
||||||
d.context.blendFunc(mode)
|
g.context.blendFunc(mode)
|
||||||
|
|
||||||
program := d.state.programs[programKey{
|
program := g.state.programs[programKey{
|
||||||
useColorM: colorM != nil,
|
useColorM: colorM != nil,
|
||||||
filter: filter,
|
filter: filter,
|
||||||
address: address,
|
address: address,
|
||||||
}]
|
}]
|
||||||
if !d.state.lastProgram.equal(program) {
|
if !g.state.lastProgram.equal(program) {
|
||||||
d.context.useProgram(program)
|
g.context.useProgram(program)
|
||||||
if d.state.lastProgram.equal(zeroProgram) {
|
if g.state.lastProgram.equal(zeroProgram) {
|
||||||
theArrayBufferLayout.enable(&d.context, program)
|
theArrayBufferLayout.enable(&g.context, program)
|
||||||
d.context.bindBuffer(arrayBuffer, d.state.arrayBuffer)
|
g.context.bindBuffer(arrayBuffer, g.state.arrayBuffer)
|
||||||
d.context.bindBuffer(elementArrayBuffer, d.state.elementArrayBuffer)
|
g.context.bindBuffer(elementArrayBuffer, g.state.elementArrayBuffer)
|
||||||
d.context.uniformInt(program, "texture", 0)
|
g.context.uniformInt(program, "texture", 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
d.state.lastProgram = program
|
g.state.lastProgram = program
|
||||||
d.state.lastViewportWidth = 0
|
g.state.lastViewportWidth = 0
|
||||||
d.state.lastViewportHeight = 0
|
g.state.lastViewportHeight = 0
|
||||||
d.state.lastColorMatrix = nil
|
g.state.lastColorMatrix = nil
|
||||||
d.state.lastColorMatrixTranslation = nil
|
g.state.lastColorMatrixTranslation = nil
|
||||||
d.state.lastSourceWidth = 0
|
g.state.lastSourceWidth = 0
|
||||||
d.state.lastSourceHeight = 0
|
g.state.lastSourceHeight = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
vw := destination.framebuffer.width
|
vw := destination.framebuffer.width
|
||||||
vh := destination.framebuffer.height
|
vh := destination.framebuffer.height
|
||||||
if d.state.lastViewportWidth != vw || d.state.lastViewportHeight != vh {
|
if g.state.lastViewportWidth != vw || g.state.lastViewportHeight != vh {
|
||||||
d.context.uniformFloats(program, "viewport_size", []float32{float32(vw), float32(vh)})
|
g.context.uniformFloats(program, "viewport_size", []float32{float32(vw), float32(vh)})
|
||||||
d.state.lastViewportWidth = vw
|
g.state.lastViewportWidth = vw
|
||||||
d.state.lastViewportHeight = vh
|
g.state.lastViewportHeight = vh
|
||||||
}
|
}
|
||||||
|
|
||||||
if colorM != nil {
|
if colorM != nil {
|
||||||
esBody, esTranslate := colorM.UnsafeElements()
|
esBody, esTranslate := colorM.UnsafeElements()
|
||||||
if !areSameFloat32Array(d.state.lastColorMatrix, esBody) {
|
if !areSameFloat32Array(g.state.lastColorMatrix, esBody) {
|
||||||
d.context.uniformFloats(program, "color_matrix_body", esBody)
|
g.context.uniformFloats(program, "color_matrix_body", esBody)
|
||||||
// ColorM's elements are immutable. It's OK to hold the reference without copying.
|
// ColorM's elements are immutable. It's OK to hold the reference without copying.
|
||||||
d.state.lastColorMatrix = esBody
|
g.state.lastColorMatrix = esBody
|
||||||
}
|
}
|
||||||
if !areSameFloat32Array(d.state.lastColorMatrixTranslation, esTranslate) {
|
if !areSameFloat32Array(g.state.lastColorMatrixTranslation, esTranslate) {
|
||||||
d.context.uniformFloats(program, "color_matrix_translation", esTranslate)
|
g.context.uniformFloats(program, "color_matrix_translation", esTranslate)
|
||||||
// ColorM's elements are immutable. It's OK to hold the reference without copying.
|
// ColorM's elements are immutable. It's OK to hold the reference without copying.
|
||||||
d.state.lastColorMatrixTranslation = esTranslate
|
g.state.lastColorMatrixTranslation = esTranslate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if filter != driver.FilterNearest {
|
if filter != driver.FilterNearest {
|
||||||
sw := graphics.InternalImageSize(srcW)
|
sw := graphics.InternalImageSize(srcW)
|
||||||
sh := graphics.InternalImageSize(srcH)
|
sh := graphics.InternalImageSize(srcH)
|
||||||
if d.state.lastSourceWidth != sw || d.state.lastSourceHeight != sh {
|
if g.state.lastSourceWidth != sw || g.state.lastSourceHeight != sh {
|
||||||
d.context.uniformFloats(program, "source_size", []float32{float32(sw), float32(sh)})
|
g.context.uniformFloats(program, "source_size", []float32{float32(sw), float32(sh)})
|
||||||
d.state.lastSourceWidth = sw
|
g.state.lastSourceWidth = sw
|
||||||
d.state.lastSourceHeight = sh
|
g.state.lastSourceHeight = sh
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if filter == driver.FilterScreen {
|
if filter == driver.FilterScreen {
|
||||||
scale := float32(dstW) / float32(srcW)
|
scale := float32(dstW) / float32(srcW)
|
||||||
d.context.uniformFloat(program, "scale", scale)
|
g.context.uniformFloat(program, "scale", scale)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't have to call gl.ActiveTexture here: GL_TEXTURE0 is the default active texture
|
// We don't have to call gl.ActiveTexture here: GL_TEXTURE0 is the default active texture
|
||||||
// See also: https://www.opengl.org/sdk/docs/man2/xhtml/glActiveTexture.xml
|
// See also: https://www.opengl.org/sdk/docs/man2/xhtml/glActiveTexture.xml
|
||||||
d.context.bindTexture(source.textureNative)
|
g.context.bindTexture(source.textureNative)
|
||||||
|
|
||||||
d.state.source = nil
|
g.state.source = nil
|
||||||
d.state.destination = nil
|
g.state.destination = nil
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -290,7 +290,7 @@ func (u *UserInterface) run(context driver.UIContext, mainloop bool) (err error)
|
|||||||
} else {
|
} else {
|
||||||
ctx, u.glWorker = gl.NewContext()
|
ctx, u.glWorker = gl.NewContext()
|
||||||
}
|
}
|
||||||
u.Graphics().(*opengl.Driver).SetMobileGLContext(ctx)
|
u.Graphics().(*opengl.Graphics).SetMobileGLContext(ctx)
|
||||||
} else {
|
} else {
|
||||||
u.t = thread.New()
|
u.t = thread.New()
|
||||||
u.Graphics().SetThread(u.t)
|
u.Graphics().SetThread(u.t)
|
||||||
|
Loading…
Reference in New Issue
Block a user