diff --git a/graphics/opengl/context.go b/graphics/opengl/context.go index c524948d2..e46a039d1 100644 --- a/graphics/opengl/context.go +++ b/graphics/opengl/context.go @@ -6,7 +6,6 @@ package opengl // #include import "C" import ( - "fmt" "github.com/hajimehoshi/go-ebiten/graphics" "github.com/hajimehoshi/go-ebiten/graphics/matrix" "github.com/hajimehoshi/go-ebiten/graphics/opengl/rendertarget" @@ -115,46 +114,16 @@ func (context *Context) SetOffscreen(renderTargetId graphics.RenderTargetId) { context.setOffscreen(renderTarget) } -func (context *Context) doSetOffscreen( - usingMainFramebuffer bool, - framebuffer interface{}, x, y, width, height int) { - f := framebuffer.(rendertarget.Framebuffer) - C.glBindFramebuffer(C.GL_FRAMEBUFFER, C.GLuint(f)) - err := C.glCheckFramebufferStatus(C.GL_FRAMEBUFFER) - if err != C.GL_FRAMEBUFFER_COMPLETE { - panic(fmt.Sprintf("glBindFramebuffer failed: %d", err)) - } - - C.glBlendFuncSeparate(C.GL_SRC_ALPHA, C.GL_ONE_MINUS_SRC_ALPHA, - C.GL_ZERO, C.GL_ONE) - - C.glViewport(C.GLint(x), C.GLint(y), - C.GLsizei(width), C.GLsizei(height)) - - matrix := graphics.OrthoProjectionMatrix(x, width, y, height) - if usingMainFramebuffer { - actualScreenHeight := context.screenHeight * context.screenScale - // Flip Y and move to fit with the top of the window. - matrix[1][1] *= -1 - matrix[1][3] += float64(actualScreenHeight) / float64(height) * 2 - } - - for j := 0; j < 4; j++ { - for i := 0; i < 4; i++ { - context.projectionMatrix[i+j*4] = float32(matrix[i][j]) - } - } -} - func (context *Context) setOffscreen(rt *grendertarget.RenderTarget) { C.glFlush() - usingMainFramebuffer := rt == context.mainFramebufferTexture - rt.SetAsOffscreen(func(framebuffer interface{}, - x, y, width, height int) { - context.doSetOffscreen(usingMainFramebuffer, framebuffer, - x, y, width, height) - }) + setter := &OffscreenSetter{ + context.screenHeight, + context.screenScale, + rt == context.mainFramebufferTexture, + &context.projectionMatrix, + } + rt.SetAsOffscreen(setter) } func (context *Context) setMainFramebufferOffscreen() { diff --git a/graphics/opengl/offscreen.go b/graphics/opengl/offscreen.go new file mode 100644 index 000000000..7672ab36c --- /dev/null +++ b/graphics/opengl/offscreen.go @@ -0,0 +1,48 @@ +package opengl + +// #cgo LDFLAGS: -framework OpenGL +// +// #include +// #include +import "C" +import ( + "fmt" + "github.com/hajimehoshi/go-ebiten/graphics" + "github.com/hajimehoshi/go-ebiten/graphics/opengl/rendertarget" +) + +type OffscreenSetter struct { + screenHeight int + screenScale int + usingMainFramebuffer bool + projectionMatrix *[16]float32 +} + +func (s *OffscreenSetter) Set(framebuffer interface{}, x, y, width, height int) { + f := framebuffer.(rendertarget.Framebuffer) + C.glBindFramebuffer(C.GL_FRAMEBUFFER, C.GLuint(f)) + err := C.glCheckFramebufferStatus(C.GL_FRAMEBUFFER) + if err != C.GL_FRAMEBUFFER_COMPLETE { + panic(fmt.Sprintf("glBindFramebuffer failed: %d", err)) + } + + C.glBlendFuncSeparate(C.GL_SRC_ALPHA, C.GL_ONE_MINUS_SRC_ALPHA, + C.GL_ZERO, C.GL_ONE) + + C.glViewport(C.GLint(x), C.GLint(y), + C.GLsizei(width), C.GLsizei(height)) + + matrix := graphics.OrthoProjectionMatrix(x, width, y, height) + if s.usingMainFramebuffer { + actualScreenHeight := s.screenHeight * s.screenScale + // Flip Y and move to fit with the top of the window. + matrix[1][1] *= -1 + matrix[1][3] += float64(actualScreenHeight) / float64(height) * 2 + } + + for j := 0; j < 4; j++ { + for i := 0; i < 4; i++ { + s.projectionMatrix[i+j*4] = float32(matrix[i][j]) + } + } +} diff --git a/graphics/opengl/texture/texture.go b/graphics/opengl/texture/texture.go index 2de71ab69..1fd8e7902 100644 --- a/graphics/opengl/texture/texture.go +++ b/graphics/opengl/texture/texture.go @@ -56,8 +56,7 @@ func createNativeTexture(textureWidth, textureHeight int, pixels []uint8, func create(textureWidth, textureHeight int, filter Filter) ( interface{}, error) { - return createNativeTexture(textureWidth, textureHeight, - nil, filter), nil + return createNativeTexture(textureWidth, textureHeight, nil, filter), nil } func createFromImage(img *image.NRGBA) (interface{}, error) { diff --git a/graphics/rendertarget/render_target.go b/graphics/rendertarget/render_target.go index d3c02e054..105106464 100644 --- a/graphics/rendertarget/render_target.go +++ b/graphics/rendertarget/render_target.go @@ -4,6 +4,10 @@ import ( "github.com/hajimehoshi/go-ebiten/graphics/texture" ) +type OffscreenSetter interface { + Set(framebuffer interface{}, x, y, width, height int) +} + type RenderTarget struct { texture *texture.Texture framebuffer interface{} @@ -16,9 +20,8 @@ func NewWithFramebuffer(texture *texture.Texture, framebuffer interface{}) *Rend } } -func (renderTarget *RenderTarget) SetAsOffscreen( - setter func(framebuffer interface{}, x, y, width, height int)) { +func (renderTarget *RenderTarget) SetAsOffscreen(setter OffscreenSetter) { renderTarget.texture.SetAsViewport(func(x, y, width, height int) { - setter(renderTarget.framebuffer, x, y, width, height) + setter.Set(renderTarget.framebuffer, x, y, width, height) }) }