mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +01:00
graphicsdriver/opengl: Rename Driver -> Graphics
This commit is contained in:
parent
01d1afa25c
commit
eabe4152a7
@ -16,7 +16,7 @@ package opengl
|
||||
|
||||
// framebuffer is a wrapper of OpenGL's framebuffer.
|
||||
type framebuffer struct {
|
||||
driver *Driver
|
||||
graphics *Graphics
|
||||
native framebufferNative
|
||||
width int
|
||||
height int
|
||||
|
@ -23,13 +23,13 @@ import (
|
||||
"github.com/hajimehoshi/ebiten/internal/thread"
|
||||
)
|
||||
|
||||
var theDriver Driver
|
||||
var theGraphics Graphics
|
||||
|
||||
func Get() *Driver {
|
||||
return &theDriver
|
||||
func Get() *Graphics {
|
||||
return &theGraphics
|
||||
}
|
||||
|
||||
type Driver struct {
|
||||
type Graphics struct {
|
||||
state openGLState
|
||||
context context
|
||||
|
||||
@ -37,32 +37,32 @@ type Driver struct {
|
||||
drawCalled bool
|
||||
}
|
||||
|
||||
func (d *Driver) SetThread(thread *thread.Thread) {
|
||||
d.context.t = thread
|
||||
func (g *Graphics) SetThread(thread *thread.Thread) {
|
||||
g.context.t = thread
|
||||
}
|
||||
|
||||
func (d *Driver) Begin() {
|
||||
func (g *Graphics) Begin() {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
func (d *Driver) End() {
|
||||
func (g *Graphics) End() {
|
||||
// Call glFlush to prevent black flicking (especially on Android (#226) and iOS).
|
||||
// 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.
|
||||
}
|
||||
|
||||
func (d *Driver) checkSize(width, height int) {
|
||||
func (g *Graphics) checkSize(width, height int) {
|
||||
if width < 1 {
|
||||
panic(fmt.Sprintf("opengl: width (%d) must be equal or more than %d", width, 1))
|
||||
}
|
||||
if 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 {
|
||||
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{
|
||||
driver: d,
|
||||
graphics: g,
|
||||
width: width,
|
||||
height: height,
|
||||
}
|
||||
w := graphics.InternalImageSize(width)
|
||||
h := graphics.InternalImageSize(height)
|
||||
d.checkSize(w, h)
|
||||
t, err := d.context.newTexture(w, h)
|
||||
g.checkSize(w, h)
|
||||
t, err := g.context.newTexture(w, h)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -88,10 +88,10 @@ func (d *Driver) NewImage(width, height int) (driver.Image, error) {
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func (d *Driver) NewScreenFramebufferImage(width, height int) (driver.Image, error) {
|
||||
d.checkSize(width, height)
|
||||
func (g *Graphics) NewScreenFramebufferImage(width, height int) (driver.Image, error) {
|
||||
g.checkSize(width, height)
|
||||
i := &Image{
|
||||
driver: d,
|
||||
graphics: g,
|
||||
width: width,
|
||||
height: height,
|
||||
screen: true,
|
||||
@ -100,51 +100,51 @@ func (d *Driver) NewScreenFramebufferImage(width, height int) (driver.Image, err
|
||||
}
|
||||
|
||||
// Reset resets or initializes the current OpenGL state.
|
||||
func (d *Driver) Reset() error {
|
||||
return d.state.reset(&d.context)
|
||||
func (g *Graphics) Reset() error {
|
||||
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
|
||||
// in opengl package due to unsafe-way.
|
||||
// See BufferSubData in context_mobile.go.
|
||||
d.context.arrayBufferSubData(vertices)
|
||||
d.context.elementArrayBufferSubData(indices)
|
||||
g.context.arrayBufferSubData(vertices)
|
||||
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 {
|
||||
d.drawCalled = true
|
||||
if err := d.useProgram(mode, colorM, filter, address); err != nil {
|
||||
func (g *Graphics) Draw(indexLen int, indexOffset int, mode driver.CompositeMode, colorM *affine.ColorM, filter driver.Filter, address driver.Address) error {
|
||||
g.drawCalled = true
|
||||
if err := g.useProgram(mode, colorM, filter, address); err != nil {
|
||||
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),
|
||||
// but basically this pass the tests (esp. TestImageTooManyFill).
|
||||
// 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
|
||||
}
|
||||
|
||||
func (d *Driver) SetVsyncEnabled(enabled bool) {
|
||||
func (g *Graphics) SetVsyncEnabled(enabled bool) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
func (d *Driver) VDirection() driver.VDirection {
|
||||
func (g *Graphics) VDirection() driver.VDirection {
|
||||
return driver.VDownward
|
||||
}
|
||||
|
||||
func (d *Driver) NeedsRestoring() bool {
|
||||
return d.context.needsRestoring()
|
||||
func (g *Graphics) NeedsRestoring() bool {
|
||||
return g.context.needsRestoring()
|
||||
}
|
||||
|
||||
func (d *Driver) IsGL() bool {
|
||||
func (g *Graphics) IsGL() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (d *Driver) HasHighPrecisionFloat() bool {
|
||||
return d.context.hasHighPrecisionFloat()
|
||||
func (g *Graphics) HasHighPrecisionFloat() bool {
|
||||
return g.context.hasHighPrecisionFloat()
|
||||
}
|
||||
|
||||
func (d *Driver) MaxImageSize() int {
|
||||
return d.context.getMaxTextureSize()
|
||||
func (g *Graphics) MaxImageSize() int {
|
||||
return g.context.getMaxTextureSize()
|
||||
}
|
@ -20,6 +20,6 @@ import (
|
||||
"golang.org/x/mobile/gl"
|
||||
)
|
||||
|
||||
func (d *Driver) SetMobileGLContext(context gl.Context) {
|
||||
d.context.gl = context
|
||||
func (g *Graphics) SetMobileGLContext(context gl.Context) {
|
||||
g.context.gl = context
|
||||
}
|
@ -20,7 +20,7 @@ import (
|
||||
)
|
||||
|
||||
type Image struct {
|
||||
driver *Driver
|
||||
graphics *Graphics
|
||||
textureNative textureNative
|
||||
framebuffer *framebuffer
|
||||
pbo buffer
|
||||
@ -30,30 +30,30 @@ type Image struct {
|
||||
}
|
||||
|
||||
func (i *Image) IsInvalidated() bool {
|
||||
return !i.driver.context.isTexture(i.textureNative)
|
||||
return !i.graphics.context.isTexture(i.textureNative)
|
||||
}
|
||||
|
||||
func (i *Image) Dispose() {
|
||||
if !i.pbo.equal(*new(buffer)) {
|
||||
i.driver.context.deleteBuffer(i.pbo)
|
||||
i.graphics.context.deleteBuffer(i.pbo)
|
||||
}
|
||||
if i.framebuffer != nil {
|
||||
i.framebuffer.delete(&i.driver.context)
|
||||
i.framebuffer.delete(&i.graphics.context)
|
||||
}
|
||||
if !i.textureNative.equal(*new(textureNative)) {
|
||||
i.driver.context.deleteTexture(i.textureNative)
|
||||
i.graphics.context.deleteTexture(i.textureNative)
|
||||
}
|
||||
}
|
||||
|
||||
func (i *Image) SetAsDestination() {
|
||||
i.driver.state.destination = i
|
||||
i.graphics.state.destination = i
|
||||
}
|
||||
|
||||
func (i *Image) setViewport() error {
|
||||
if err := i.ensureFramebuffer(); err != nil {
|
||||
return err
|
||||
}
|
||||
i.driver.context.setViewport(i.framebuffer)
|
||||
i.graphics.context.setViewport(i.framebuffer)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -61,7 +61,7 @@ func (i *Image) Pixels() ([]byte, error) {
|
||||
if err := i.ensureFramebuffer(); err != nil {
|
||||
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 {
|
||||
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.
|
||||
// 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).
|
||||
i.framebuffer = newScreenFramebuffer(&i.driver.context, i.width, i.height)
|
||||
i.framebuffer = newScreenFramebuffer(&i.graphics.context, i.width, i.height)
|
||||
return nil
|
||||
}
|
||||
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
@ -100,26 +100,26 @@ func (i *Image) ReplacePixels(args []*driver.ReplacePixelsArgs) {
|
||||
|
||||
// glFlush is necessary on Android.
|
||||
// glTexSubImage2D didn't work without this hack at least on Nexus 5x and NuAns NEO [Reloaded] (#211).
|
||||
if i.driver.drawCalled {
|
||||
i.driver.context.flush()
|
||||
if i.graphics.drawCalled {
|
||||
i.graphics.context.flush()
|
||||
}
|
||||
i.driver.drawCalled = false
|
||||
i.graphics.drawCalled = false
|
||||
|
||||
w, h := i.width, i.height
|
||||
if !i.driver.context.canUsePBO() {
|
||||
i.driver.context.texSubImage2D(i.textureNative, w, h, args)
|
||||
if !i.graphics.context.canUsePBO() {
|
||||
i.graphics.context.texSubImage2D(i.textureNative, w, h, args)
|
||||
return
|
||||
}
|
||||
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)) {
|
||||
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() {
|
||||
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).
|
||||
func (d *Driver) useProgram(mode driver.CompositeMode, colorM *affine.ColorM, filter driver.Filter, address driver.Address) error {
|
||||
destination := d.state.destination
|
||||
func (g *Graphics) useProgram(mode driver.CompositeMode, colorM *affine.ColorM, filter driver.Filter, address driver.Address) error {
|
||||
destination := g.state.destination
|
||||
if destination == nil {
|
||||
panic("destination image is not set")
|
||||
}
|
||||
source := d.state.source
|
||||
source := g.state.source
|
||||
if source == nil {
|
||||
panic("source image is not set")
|
||||
}
|
||||
@ -271,73 +271,73 @@ func (d *Driver) useProgram(mode driver.CompositeMode, colorM *affine.ColorM, fi
|
||||
dstW := destination.width
|
||||
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,
|
||||
filter: filter,
|
||||
address: address,
|
||||
}]
|
||||
if !d.state.lastProgram.equal(program) {
|
||||
d.context.useProgram(program)
|
||||
if d.state.lastProgram.equal(zeroProgram) {
|
||||
theArrayBufferLayout.enable(&d.context, program)
|
||||
d.context.bindBuffer(arrayBuffer, d.state.arrayBuffer)
|
||||
d.context.bindBuffer(elementArrayBuffer, d.state.elementArrayBuffer)
|
||||
d.context.uniformInt(program, "texture", 0)
|
||||
if !g.state.lastProgram.equal(program) {
|
||||
g.context.useProgram(program)
|
||||
if g.state.lastProgram.equal(zeroProgram) {
|
||||
theArrayBufferLayout.enable(&g.context, program)
|
||||
g.context.bindBuffer(arrayBuffer, g.state.arrayBuffer)
|
||||
g.context.bindBuffer(elementArrayBuffer, g.state.elementArrayBuffer)
|
||||
g.context.uniformInt(program, "texture", 0)
|
||||
}
|
||||
|
||||
d.state.lastProgram = program
|
||||
d.state.lastViewportWidth = 0
|
||||
d.state.lastViewportHeight = 0
|
||||
d.state.lastColorMatrix = nil
|
||||
d.state.lastColorMatrixTranslation = nil
|
||||
d.state.lastSourceWidth = 0
|
||||
d.state.lastSourceHeight = 0
|
||||
g.state.lastProgram = program
|
||||
g.state.lastViewportWidth = 0
|
||||
g.state.lastViewportHeight = 0
|
||||
g.state.lastColorMatrix = nil
|
||||
g.state.lastColorMatrixTranslation = nil
|
||||
g.state.lastSourceWidth = 0
|
||||
g.state.lastSourceHeight = 0
|
||||
}
|
||||
|
||||
vw := destination.framebuffer.width
|
||||
vh := destination.framebuffer.height
|
||||
if d.state.lastViewportWidth != vw || d.state.lastViewportHeight != vh {
|
||||
d.context.uniformFloats(program, "viewport_size", []float32{float32(vw), float32(vh)})
|
||||
d.state.lastViewportWidth = vw
|
||||
d.state.lastViewportHeight = vh
|
||||
if g.state.lastViewportWidth != vw || g.state.lastViewportHeight != vh {
|
||||
g.context.uniformFloats(program, "viewport_size", []float32{float32(vw), float32(vh)})
|
||||
g.state.lastViewportWidth = vw
|
||||
g.state.lastViewportHeight = vh
|
||||
}
|
||||
|
||||
if colorM != nil {
|
||||
esBody, esTranslate := colorM.UnsafeElements()
|
||||
if !areSameFloat32Array(d.state.lastColorMatrix, esBody) {
|
||||
d.context.uniformFloats(program, "color_matrix_body", esBody)
|
||||
if !areSameFloat32Array(g.state.lastColorMatrix, esBody) {
|
||||
g.context.uniformFloats(program, "color_matrix_body", esBody)
|
||||
// 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) {
|
||||
d.context.uniformFloats(program, "color_matrix_translation", esTranslate)
|
||||
if !areSameFloat32Array(g.state.lastColorMatrixTranslation, esTranslate) {
|
||||
g.context.uniformFloats(program, "color_matrix_translation", esTranslate)
|
||||
// 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 {
|
||||
sw := graphics.InternalImageSize(srcW)
|
||||
sh := graphics.InternalImageSize(srcH)
|
||||
if d.state.lastSourceWidth != sw || d.state.lastSourceHeight != sh {
|
||||
d.context.uniformFloats(program, "source_size", []float32{float32(sw), float32(sh)})
|
||||
d.state.lastSourceWidth = sw
|
||||
d.state.lastSourceHeight = sh
|
||||
if g.state.lastSourceWidth != sw || g.state.lastSourceHeight != sh {
|
||||
g.context.uniformFloats(program, "source_size", []float32{float32(sw), float32(sh)})
|
||||
g.state.lastSourceWidth = sw
|
||||
g.state.lastSourceHeight = sh
|
||||
}
|
||||
}
|
||||
|
||||
if filter == driver.FilterScreen {
|
||||
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
|
||||
// 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
|
||||
d.state.destination = nil
|
||||
g.state.source = nil
|
||||
g.state.destination = nil
|
||||
return nil
|
||||
}
|
||||
|
@ -290,7 +290,7 @@ func (u *UserInterface) run(context driver.UIContext, mainloop bool) (err error)
|
||||
} else {
|
||||
ctx, u.glWorker = gl.NewContext()
|
||||
}
|
||||
u.Graphics().(*opengl.Driver).SetMobileGLContext(ctx)
|
||||
u.Graphics().(*opengl.Graphics).SetMobileGLContext(ctx)
|
||||
} else {
|
||||
u.t = thread.New()
|
||||
u.Graphics().SetThread(u.t)
|
||||
|
Loading…
Reference in New Issue
Block a user