diff --git a/graphicscontext.go b/graphicscontext.go index 5f47f2322..ed95f3117 100644 --- a/graphicscontext.go +++ b/graphicscontext.go @@ -72,7 +72,5 @@ func (c *graphicsContext) postUpdate() error { if err := c.defaultR.drawImage(c.screen, options); err != nil { return err } - - opengl.Flush() return nil } diff --git a/image.go b/image.go index 10d622765..060a870c7 100644 --- a/image.go +++ b/image.go @@ -17,7 +17,6 @@ package ebiten import ( "github.com/hajimehoshi/ebiten/internal" "github.com/hajimehoshi/ebiten/internal/opengl" - "github.com/hajimehoshi/ebiten/internal/opengl/internal/shader" "image" "image/color" ) @@ -44,12 +43,8 @@ func (i *innerImage) Clear() error { } func (i *innerImage) Fill(clr color.Color) error { - if err := i.framebuffer.SetAsViewport(); err != nil { - return err - } r, g, b, a := internal.RGBA(clr) - opengl.Clear(r, g, b, a) - return nil + return i.framebuffer.Fill(r, g, b, a) } func (i *innerImage) drawImage(img *innerImage, options *DrawImageOptions) error { @@ -68,14 +63,9 @@ func (i *innerImage) drawImage(img *innerImage, options *DrawImageOptions) error } geo := options.GeoM clr := options.ColorM - - if err := i.framebuffer.SetAsViewport(); err != nil { - return err - } - w, h := img.texture.Size() - quads := textureQuads(parts, w, h) - projectionMatrix := i.framebuffer.ProjectionMatrix() - return shader.DrawTexture(img.texture.Native(), projectionMatrix, quads, geo, clr) + w, h := img.size() + quads := &textureQuads{parts, w, h} + return i.framebuffer.DrawTexture(img.texture, quads, geo, clr) } func u(x float64, width int) float32 { @@ -86,22 +76,25 @@ func v(y float64, height int) float32 { return float32(y) / float32(internal.NextPowerOf2Int(height)) } -func textureQuads(parts []ImagePart, width, height int) []shader.TextureQuad { - quads := make([]shader.TextureQuad, 0, len(parts)) - for _, part := range parts { - dst, src := part.Dst, part.Src - x1 := float32(dst.Min.X) - x2 := float32(dst.Max.X) - y1 := float32(dst.Min.Y) - y2 := float32(dst.Max.Y) - u1 := u(float64(src.Min.X), width) - u2 := u(float64(src.Max.X), width) - v1 := v(float64(src.Min.Y), height) - v2 := v(float64(src.Max.Y), height) - quad := shader.TextureQuad{x1, x2, y1, y2, u1, u2, v1, v2} - quads = append(quads, quad) - } - return quads +type textureQuads struct { + parts []ImagePart + width int + height int +} + +func (t *textureQuads) Len() int { + return len(t.parts) +} + +func (t *textureQuads) Vertex(i int) (x0, y0, x1, y1 float32) { + dst := t.parts[i].Dst + return float32(dst.Min.X), float32(dst.Min.Y), float32(dst.Max.X), float32(dst.Max.Y) +} + +func (t *textureQuads) Texture(i int) (u0, v0, u1, v1 float32) { + src := t.parts[i].Src + w, h := t.width, t.height + return u(float64(src.Min.X), w), v(float64(src.Min.Y), h), u(float64(src.Max.X), w), v(float64(src.Max.Y), h) } type syncer interface { diff --git a/internal/opengl/framebuffer.go b/internal/opengl/framebuffer.go index 82877d63b..c29886e5b 100644 --- a/internal/opengl/framebuffer.go +++ b/internal/opengl/framebuffer.go @@ -19,6 +19,7 @@ import ( "fmt" "github.com/go-gl/gl" "github.com/hajimehoshi/ebiten/internal" + "github.com/hajimehoshi/ebiten/internal/opengl/internal/shader" ) func orthoProjectionMatrix(left, right, bottom, top int) [4][4]float64 { @@ -84,7 +85,7 @@ func createFramebuffer(nativeTexture gl.Texture) (gl.Framebuffer, error) { return framebuffer, nil } -func (f *Framebuffer) SetAsViewport() error { +func (f *Framebuffer) setAsViewport() error { gl.Flush() f.framebuffer.Bind() err := gl.CheckFramebufferStatus(gl.FRAMEBUFFER) @@ -101,7 +102,7 @@ func (f *Framebuffer) SetAsViewport() error { return nil } -func (f *Framebuffer) ProjectionMatrix() [4][4]float64 { +func (f *Framebuffer) projectionMatrix() [4][4]float64 { width := internal.NextPowerOf2Int(f.width) height := internal.NextPowerOf2Int(f.height) m := orthoProjectionMatrix(0, width, 0, height) @@ -111,3 +112,31 @@ func (f *Framebuffer) ProjectionMatrix() [4][4]float64 { } return m } + +type Matrix interface { + Element(i, j int) float64 +} + +type TextureQuads interface { + Len() int + Vertex(i int) (x0, y0, x1, y1 float32) + Texture(i int) (u0, v0, u1, v1 float32) +} + +func (f *Framebuffer) Fill(r, g, b, a float64) error { + if err := f.setAsViewport(); err != nil { + return err + } + gl.ClearColor(gl.GLclampf(r), gl.GLclampf(g), gl.GLclampf(b), gl.GLclampf(a)) + gl.Clear(gl.COLOR_BUFFER_BIT) + return nil +} + +func (f *Framebuffer) DrawTexture(t *Texture, quads TextureQuads, geo, clr Matrix) error { + if err := f.setAsViewport(); err != nil { + return err + } + projectionMatrix := f.projectionMatrix() + // TODO: Define texture.Draw() + return shader.DrawTexture(t.native, projectionMatrix, quads, geo, clr) +} diff --git a/internal/opengl/gl.go b/internal/opengl/gl.go index a96d6a6cb..3cd92010e 100644 --- a/internal/opengl/gl.go +++ b/internal/opengl/gl.go @@ -32,12 +32,3 @@ func Init() { gl.Enable(gl.BLEND) gl.BlendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) } - -func Clear(r, g, b, a float64) { - gl.ClearColor(gl.GLclampf(r), gl.GLclampf(g), gl.GLclampf(b), gl.GLclampf(a)) - gl.Clear(gl.COLOR_BUFFER_BIT) -} - -func Flush() { - gl.Flush() -} diff --git a/internal/opengl/internal/shader/drawtexture.go b/internal/opengl/internal/shader/drawtexture.go index 89c1c7ef2..8ae6ff85b 100644 --- a/internal/opengl/internal/shader/drawtexture.go +++ b/internal/opengl/internal/shader/drawtexture.go @@ -32,6 +32,12 @@ type Matrix interface { Element(i, j int) float64 } +type TextureQuads interface { + Len() int + Vertex(i int) (x0, y0, x1, y1 float32) + Texture(i int) (u0, v0, u1, v1 float32) +} + var initialized = false const size = 10000 @@ -40,7 +46,7 @@ const size = 10000 const uint16Size = 2 const short32Size = 4 -func DrawTexture(native gl.Texture, projectionMatrix [4][4]float64, quads []TextureQuad, geo Matrix, color Matrix) error { +func DrawTexture(native gl.Texture, projectionMatrix [4][4]float64, quads TextureQuads, geo Matrix, color Matrix) error { // TODO: Check len(quads) and gl.MAX_ELEMENTS_INDICES? const stride = 4 * 4 if !initialized { @@ -69,7 +75,7 @@ func DrawTexture(native gl.Texture, projectionMatrix [4][4]float64, quads []Text initialized = true } - if len(quads) == 0 { + if quads.Len() == 0 { return nil } // TODO: Check performance @@ -92,15 +98,9 @@ func DrawTexture(native gl.Texture, projectionMatrix [4][4]float64, quads []Text texCoordAttrLocation.AttribPointer(2, gl.FLOAT, false, stride, uintptr(short32Size*2)) vertices := []float32{} - for _, quad := range quads { - x0 := quad.VertexX0 - x1 := quad.VertexX1 - y0 := quad.VertexY0 - y1 := quad.VertexY1 - u0 := quad.TextureCoordU0 - u1 := quad.TextureCoordU1 - v0 := quad.TextureCoordV0 - v1 := quad.TextureCoordV1 + for i := 0; i < quads.Len(); i++ { + x0, y0, x1, y1 := quads.Vertex(i) + u0, v0, u1, v1 := quads.Texture(i) vertices = append(vertices, x0, y0, u0, v0, x1, y0, u1, v0, @@ -109,7 +109,7 @@ func DrawTexture(native gl.Texture, projectionMatrix [4][4]float64, quads []Text ) } gl.BufferSubData(gl.ARRAY_BUFFER, 0, short32Size*len(vertices), vertices) - gl.DrawElements(gl.TRIANGLES, 6*len(quads), gl.UNSIGNED_SHORT, uintptr(0)) + gl.DrawElements(gl.TRIANGLES, 6*quads.Len(), gl.UNSIGNED_SHORT, uintptr(0)) gl.Flush() return nil diff --git a/internal/opengl/internal/shader/texturequad.go b/internal/opengl/internal/shader/texturequad.go deleted file mode 100644 index eb07e8585..000000000 --- a/internal/opengl/internal/shader/texturequad.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 shader - -type TextureQuad struct { - VertexX0 float32 - VertexX1 float32 - VertexY0 float32 - VertexY1 float32 - TextureCoordU0 float32 - TextureCoordU1 float32 - TextureCoordV0 float32 - TextureCoordV1 float32 -}