diff --git a/graphics.go b/graphics.go index 866394cc3..04df95954 100644 --- a/graphics.go +++ b/graphics.go @@ -15,14 +15,24 @@ package ebiten import ( - "github.com/hajimehoshi/ebiten/internal/graphics" + "github.com/hajimehoshi/ebiten/internal/opengl" ) // Filter represents the type of filter to be used when an image is maginified or minified. -type Filter graphics.Filter +type Filter int // Filters const ( - FilterNearest = Filter(graphics.FilterNearest) - FilterLinear = Filter(graphics.FilterLinear) + FilterNearest Filter = iota + FilterLinear ) + +func glFilter(c *opengl.Context, filter Filter) opengl.Filter { + switch filter { + case FilterNearest: + return c.Nearest + case FilterLinear: + return c.Linear + } + panic("not reach") +} diff --git a/graphicscontext.go b/graphicscontext.go index d54e877e7..a53a8fbf8 100644 --- a/graphicscontext.go +++ b/graphicscontext.go @@ -16,15 +16,16 @@ package ebiten import ( "github.com/hajimehoshi/ebiten/internal/graphics" + "github.com/hajimehoshi/ebiten/internal/opengl" ) -func newGraphicsContext(screenWidth, screenHeight, screenScale int) (*graphicsContext, error) { +func newGraphicsContext(c *opengl.Context, screenWidth, screenHeight, screenScale int) (*graphicsContext, error) { f, err := graphics.NewZeroFramebuffer(screenWidth*screenScale, screenHeight*screenScale) if err != nil { return nil, err } - texture, err := graphics.NewTexture(screenWidth, screenHeight, graphics.Filter(FilterNearest)) + texture, err := graphics.NewTexture(c, screenWidth, screenHeight, c.Nearest) if err != nil { return nil, err } @@ -33,12 +34,12 @@ func newGraphicsContext(screenWidth, screenHeight, screenScale int) (*graphicsCo return nil, err } - c := &graphicsContext{ + gc := &graphicsContext{ defaultR: &innerImage{f, nil}, screen: screen, screenScale: screenScale, } - return c, nil + return gc, nil } type graphicsContext struct { diff --git a/internal/graphics/framebuffer.go b/internal/graphics/framebuffer.go index 7835e0a84..d2e9a9051 100644 --- a/internal/graphics/framebuffer.go +++ b/internal/graphics/framebuffer.go @@ -53,7 +53,7 @@ func NewZeroFramebuffer(width, height int) (*Framebuffer, error) { } func NewFramebufferFromTexture(texture *Texture) (*Framebuffer, error) { - framebuffer, err := createFramebuffer(texture.Native()) + framebuffer, err := createFramebuffer(gl.Texture(texture.native)) if err != nil { return nil, err } @@ -138,5 +138,5 @@ func (f *Framebuffer) DrawTexture(t *Texture, quads TextureQuads, geo, clr Matri } projectionMatrix := f.projectionMatrix() // TODO: Define texture.Draw() - return shader.DrawTexture(t.native, projectionMatrix, quads, geo, clr) + return shader.DrawTexture(gl.Texture(t.native), projectionMatrix, quads, geo, clr) } diff --git a/internal/graphics/gl.go b/internal/graphics/gl.go deleted file mode 100644 index 9dc9790f3..000000000 --- a/internal/graphics/gl.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2014 Hajime Hoshi -// -// 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. - -package graphics - -import ( - "github.com/go-gl/gl" -) - -type Filter int - -const ( - FilterNearest Filter = gl.NEAREST - FilterLinear = gl.LINEAR -) diff --git a/internal/graphics/texture.go b/internal/graphics/texture.go index 935ff817b..37abd4993 100644 --- a/internal/graphics/texture.go +++ b/internal/graphics/texture.go @@ -19,6 +19,7 @@ import ( "fmt" "github.com/go-gl/gl" "github.com/hajimehoshi/ebiten/internal" + "github.com/hajimehoshi/ebiten/internal/opengl" "image" "image/draw" ) @@ -46,37 +47,16 @@ func adjustImageForTexture(img image.Image) *image.RGBA { } type Texture struct { - native gl.Texture + native opengl.Texture width int height int } -func (t *Texture) Native() gl.Texture { - return t.native -} - func (t *Texture) Size() (width, height int) { return t.width, t.height } -func createNativeTexture(textureWidth, textureHeight int, pixels []uint8, filter Filter) (gl.Texture, error) { - nativeTexture := gl.GenTexture() - if nativeTexture < 0 { - return 0, errors.New("glGenTexture failed") - } - gl.PixelStorei(gl.UNPACK_ALIGNMENT, 4) - nativeTexture.Bind(gl.TEXTURE_2D) - defer gl.Texture(0).Bind(gl.TEXTURE_2D) - - gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, int(filter)) - gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, int(filter)) - - gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, textureWidth, textureHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, pixels) - - return nativeTexture, nil -} - -func NewTexture(width, height int, filter Filter) (*Texture, error) { +func NewTexture(c *opengl.Context, width, height int, filter opengl.Filter) (*Texture, error) { w := internal.NextPowerOf2Int(width) h := internal.NextPowerOf2Int(height) if w < 4 { @@ -85,14 +65,14 @@ func NewTexture(width, height int, filter Filter) (*Texture, error) { if h < 4 { return nil, errors.New("height must be equal or more than 4.") } - native, err := createNativeTexture(w, h, nil, filter) + native, err := c.NewTexture(w, h, nil, filter) if err != nil { return nil, err } return &Texture{native, width, height}, nil } -func NewTextureFromImage(img image.Image, filter Filter) (*Texture, error) { +func NewTextureFromImage(c *opengl.Context, img image.Image, filter opengl.Filter) (*Texture, error) { origSize := img.Bounds().Size() if origSize.X < 4 { return nil, errors.New("width must be equal or more than 4.") @@ -102,7 +82,7 @@ func NewTextureFromImage(img image.Image, filter Filter) (*Texture, error) { } adjustedImage := adjustImageForTexture(img) size := adjustedImage.Bounds().Size() - native, err := createNativeTexture(size.X, size.Y, adjustedImage.Pix, filter) + native, err := c.NewTexture(size.X, size.Y, adjustedImage.Pix, filter) if err != nil { return nil, err } @@ -110,13 +90,13 @@ func NewTextureFromImage(img image.Image, filter Filter) (*Texture, error) { } func (t *Texture) Dispose() { - t.native.Delete() + gl.Texture(t.native).Delete() } func (t *Texture) Pixels() ([]uint8, error) { w, h := internal.NextPowerOf2Int(t.width), internal.NextPowerOf2Int(t.height) pixels := make([]uint8, 4*w*h) - t.native.Bind(gl.TEXTURE_2D) + gl.Texture(t.native).Bind(gl.TEXTURE_2D) gl.GetTexImage(gl.TEXTURE_2D, 0, gl.RGBA, gl.UNSIGNED_BYTE, pixels) if e := gl.GetError(); e != gl.NO_ERROR { // TODO: Use glu.ErrorString diff --git a/internal/opengl/context.go b/internal/opengl/context.go index 0c916c5fb..538e3d0a1 100644 --- a/internal/opengl/context.go +++ b/internal/opengl/context.go @@ -15,14 +15,29 @@ package opengl import ( + "errors" "github.com/go-gl/gl" ) +type Filter int + +const ( + filterNearest Filter = gl.NEAREST + filterLinear = gl.LINEAR +) + type Context struct { + Nearest Filter + Linear Filter } +type Texture gl.Texture + func NewContext() *Context { - c := &Context{} + c := &Context{ + Nearest: filterNearest, + Linear: filterLinear, + } c.init() return c } @@ -34,3 +49,20 @@ func (c *Context) init() { gl.Enable(gl.BLEND) gl.BlendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) } + +func (c *Context) NewTexture(width, height int, pixels []uint8, filter Filter) (Texture, error) { + t := gl.GenTexture() + if t < 0 { + return 0, errors.New("glGenTexture failed") + } + gl.PixelStorei(gl.UNPACK_ALIGNMENT, 4) + t.Bind(gl.TEXTURE_2D) + defer gl.Texture(0).Bind(gl.TEXTURE_2D) + + gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, int(filter)) + gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, int(filter)) + + gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, pixels) + + return Texture(t), nil +} diff --git a/ui.go b/ui.go index f91af44f8..1fbafa0d3 100644 --- a/ui.go +++ b/ui.go @@ -104,7 +104,7 @@ func startUI(width, height, scale int, title string) error { windowWidth, _ := window.GetFramebufferSize() realScale := windowWidth / width ui.use(func() { - ui.graphicsContext, err = newGraphicsContext(width, height, realScale) + ui.graphicsContext, err = newGraphicsContext(ui.glContext, width, height, realScale) }) return err } @@ -152,7 +152,7 @@ func (u *ui) newImageFromImage(img image.Image, filter Filter) (*Image, error) { var err error u.use(func() { var texture *graphics.Texture - texture, err = graphics.NewTextureFromImage(img, graphics.Filter(filter)) + texture, err = graphics.NewTextureFromImage(u.glContext, img, glFilter(u.glContext, filter)) if err != nil { return } @@ -169,7 +169,7 @@ func (u *ui) newImage(width, height int, filter Filter) (*Image, error) { var err error u.use(func() { var texture *graphics.Texture - texture, err = graphics.NewTexture(width, height, graphics.Filter(filter)) + texture, err = graphics.NewTexture(u.glContext, width, height, glFilter(u.glContext, filter)) if err != nil { return }