diff --git a/graphics/opengl/offscreen/offscreen.go b/graphics/opengl/offscreen/offscreen.go index 0eb44403d..a3c72b2d8 100644 --- a/graphics/opengl/offscreen/offscreen.go +++ b/graphics/opengl/offscreen/offscreen.go @@ -9,7 +9,6 @@ import ( "github.com/hajimehoshi/go-ebiten/graphics" "github.com/hajimehoshi/go-ebiten/graphics/matrix" "github.com/hajimehoshi/go-ebiten/graphics/opengl/rendertarget" - "github.com/hajimehoshi/go-ebiten/graphics/opengl/shader" "github.com/hajimehoshi/go-ebiten/graphics/opengl/texture" ) @@ -33,7 +32,7 @@ func New(screenWidth, screenHeight, screenScale int) *Offscreen { offscreen.mainFramebufferTexture, err = rendertarget.CreateWithFramebuffer( screenWidth*screenScale, screenHeight*screenScale, - rendertarget.Framebuffer(mainFramebuffer)) + texture.Framebuffer(mainFramebuffer)) if err != nil { panic("creating main framebuffer failed: " + err.Error()) } @@ -55,20 +54,14 @@ func (o *Offscreen) SetMainFramebuffer() { func (o *Offscreen) DrawTexture(texture *texture.Texture, geometryMatrix matrix.Geometry, colorMatrix matrix.Color) { projectionMatrix := o.projectionMatrix() - quad := graphics.TextureQuadForTexture(texture.Width, texture.Height) - shader.DrawTexture(texture.Native, - projectionMatrix, []graphics.TextureQuad{quad}, - geometryMatrix, colorMatrix) + texture.Draw(projectionMatrix, geometryMatrix, colorMatrix) } func (o *Offscreen) DrawTextureParts(texture *texture.Texture, parts []graphics.TexturePart, geometryMatrix matrix.Geometry, colorMatrix matrix.Color) { projectionMatrix := o.projectionMatrix() - quads := graphics.TextureQuadsForTextureParts(parts, texture.Width, texture.Height) - shader.DrawTexture(texture.Native, - projectionMatrix, quads, - geometryMatrix, colorMatrix) + texture.DrawParts(parts, projectionMatrix, geometryMatrix, colorMatrix) } func (o *Offscreen) projectionMatrix() [16]float32 { diff --git a/graphics/opengl/rendertarget/render_target.go b/graphics/opengl/rendertarget/render_target.go index b477a86f5..fb479df05 100644 --- a/graphics/opengl/rendertarget/render_target.go +++ b/graphics/opengl/rendertarget/render_target.go @@ -10,37 +10,10 @@ import ( "github.com/hajimehoshi/go-ebiten/graphics/opengl/texture" ) -type Framebuffer C.GLuint - type RenderTarget struct { - framebuffer Framebuffer - width int - height int -} - -func createFramebuffer(nativeTexture C.GLuint) Framebuffer { - framebuffer := C.GLuint(0) - C.glGenFramebuffers(1, &framebuffer) - - origFramebuffer := C.GLint(0) - C.glGetIntegerv(C.GL_FRAMEBUFFER_BINDING, &origFramebuffer) - - C.glBindFramebuffer(C.GL_FRAMEBUFFER, framebuffer) - defer C.glBindFramebuffer(C.GL_FRAMEBUFFER, C.GLuint(origFramebuffer)) - - C.glFramebufferTexture2D(C.GL_FRAMEBUFFER, C.GL_COLOR_ATTACHMENT0, - C.GL_TEXTURE_2D, nativeTexture, 0) - if C.glCheckFramebufferStatus(C.GL_FRAMEBUFFER) != - C.GL_FRAMEBUFFER_COMPLETE { - panic("creating framebuffer failed") - } - - // Set this framebuffer opaque because alpha values on a target might be - // confusing. - C.glClearColor(0, 0, 0, 1) - C.glClear(C.GL_COLOR_BUFFER_BIT) - - return Framebuffer(framebuffer) + framebuffer texture.Framebuffer + width int + height int } func Create(width, height int, filter graphics.Filter) ( @@ -49,11 +22,11 @@ func Create(width, height int, filter graphics.Filter) ( if err != nil { return nil, nil, err } - framebuffer := createFramebuffer(C.GLuint(tex.Native)) - return &RenderTarget{framebuffer, tex.Width, tex.Height}, tex, nil + framebuffer := tex.CreateFramebuffer() + return &RenderTarget{framebuffer, width, height}, tex, nil } -func CreateWithFramebuffer(width, height int, framebuffer Framebuffer) ( +func CreateWithFramebuffer(width, height int, framebuffer texture.Framebuffer) ( *RenderTarget, error) { return &RenderTarget{framebuffer, width, height}, nil } diff --git a/graphics/opengl/shader/draw_texture.go b/graphics/opengl/shader/draw_texture.go index 4f18189ac..bf9252114 100644 --- a/graphics/opengl/shader/draw_texture.go +++ b/graphics/opengl/shader/draw_texture.go @@ -8,14 +8,16 @@ import "C" import ( "github.com/hajimehoshi/go-ebiten/graphics" "github.com/hajimehoshi/go-ebiten/graphics/matrix" - "github.com/hajimehoshi/go-ebiten/graphics/opengl/texture" "sync" "unsafe" ) +type NativeTexture C.GLuint + var once sync.Once -func DrawTexture(native texture.Native, projectionMatrix [16]float32, quads []graphics.TextureQuad, geometryMatrix matrix.Geometry, colorMatrix matrix.Color) { +func DrawTexture(native NativeTexture, projectionMatrix [16]float32, + quads []graphics.TextureQuad, geometryMatrix matrix.Geometry, colorMatrix matrix.Color) { once.Do(func() { initialize() }) diff --git a/graphics/opengl/texture/texture.go b/graphics/opengl/texture/texture.go index 9bb09ece3..5fe78ec3c 100644 --- a/graphics/opengl/texture/texture.go +++ b/graphics/opengl/texture/texture.go @@ -6,20 +6,22 @@ package texture import "C" import ( "github.com/hajimehoshi/go-ebiten/graphics" + "github.com/hajimehoshi/go-ebiten/graphics/matrix" + "github.com/hajimehoshi/go-ebiten/graphics/opengl/shader" "image" "unsafe" ) -type Native C.GLuint +type Framebuffer C.GLuint type Texture struct { - Native - Width int - Height int + native shader.NativeTexture + width int + height int } func createNativeTexture(textureWidth, textureHeight int, pixels []uint8, - filter graphics.Filter) Native { + filter graphics.Filter) shader.NativeTexture { nativeTexture := C.GLuint(0) C.glGenTextures(1, (*C.GLuint)(&nativeTexture)) @@ -50,7 +52,7 @@ func createNativeTexture(textureWidth, textureHeight int, pixels []uint8, C.GLsizei(textureWidth), C.GLsizei(textureHeight), 0, C.GL_RGBA, C.GL_UNSIGNED_BYTE, ptr) - return Native(nativeTexture) + return shader.NativeTexture(nativeTexture) } func Create(width, height int, filter graphics.Filter) (*Texture, error) { @@ -66,3 +68,47 @@ func CreateFromImage(img image.Image, filter graphics.Filter) (*Texture, error) native := createNativeTexture(size.X, size.Y, adjustedImage.Pix, filter) return &Texture{native, size.X, size.Y}, nil } + +func createFramebuffer(nativeTexture C.GLuint) Framebuffer { + framebuffer := C.GLuint(0) + C.glGenFramebuffers(1, &framebuffer) + + origFramebuffer := C.GLint(0) + C.glGetIntegerv(C.GL_FRAMEBUFFER_BINDING, &origFramebuffer) + + C.glBindFramebuffer(C.GL_FRAMEBUFFER, framebuffer) + defer C.glBindFramebuffer(C.GL_FRAMEBUFFER, C.GLuint(origFramebuffer)) + + C.glFramebufferTexture2D(C.GL_FRAMEBUFFER, C.GL_COLOR_ATTACHMENT0, + C.GL_TEXTURE_2D, nativeTexture, 0) + if C.glCheckFramebufferStatus(C.GL_FRAMEBUFFER) != + C.GL_FRAMEBUFFER_COMPLETE { + panic("creating framebuffer failed") + } + + // Set this framebuffer opaque because alpha values on a target might be + // confusing. + C.glClearColor(0, 0, 0, 1) + C.glClear(C.GL_COLOR_BUFFER_BIT) + + return Framebuffer(framebuffer) +} + +func (t *Texture) CreateFramebuffer() Framebuffer { + return createFramebuffer(C.GLuint(t.native)) +} + +func (t *Texture) Draw(projectionMatrix [16]float32, geometryMatrix matrix.Geometry, colorMatrix matrix.Color) { + quad := graphics.TextureQuadForTexture(t.width, t.height) + shader.DrawTexture(t.native, + projectionMatrix, []graphics.TextureQuad{quad}, + geometryMatrix, colorMatrix) +} + +func (t *Texture) DrawParts(parts []graphics.TexturePart, projectionMatrix [16]float32, + geometryMatrix matrix.Geometry, colorMatrix matrix.Color) { + quads := graphics.TextureQuadsForTextureParts(parts, t.width, t.height) + shader.DrawTexture(t.native, + projectionMatrix, quads, + geometryMatrix, colorMatrix) +}