Refactoring

This commit is contained in:
Hajime Hoshi 2014-01-10 21:28:50 +09:00
parent 29e5aa331f
commit 1c10c45f69
4 changed files with 65 additions and 50 deletions

View File

@ -9,6 +9,7 @@ import (
"github.com/hajimehoshi/go-ebiten/graphics" "github.com/hajimehoshi/go-ebiten/graphics"
"github.com/hajimehoshi/go-ebiten/graphics/matrix" "github.com/hajimehoshi/go-ebiten/graphics/matrix"
"github.com/hajimehoshi/go-ebiten/graphics/opengl/offscreen" "github.com/hajimehoshi/go-ebiten/graphics/opengl/offscreen"
"github.com/hajimehoshi/go-ebiten/graphics/opengl/rendertarget"
"math" "math"
) )
@ -20,9 +21,12 @@ type Context struct {
} }
func newContext(ids *ids, screenWidth, screenHeight, screenScale int) *Context { func newContext(ids *ids, screenWidth, screenHeight, screenScale int) *Context {
mainFramebuffer := rendertarget.NewWithCurrentFramebuffer(
screenWidth*screenScale,
screenHeight*screenScale)
context := &Context{ context := &Context{
ids: ids, ids: ids,
offscreen: offscreen.New(screenWidth, screenHeight, screenScale), offscreen: offscreen.New(mainFramebuffer),
screenScale: screenScale, screenScale: screenScale,
} }

View File

@ -3,67 +3,49 @@ package offscreen
import ( import (
"github.com/hajimehoshi/go-ebiten/graphics" "github.com/hajimehoshi/go-ebiten/graphics"
"github.com/hajimehoshi/go-ebiten/graphics/matrix" "github.com/hajimehoshi/go-ebiten/graphics/matrix"
"github.com/hajimehoshi/go-ebiten/graphics/opengl/rendertarget"
"github.com/hajimehoshi/go-ebiten/graphics/opengl/texture"
) )
type Texture interface {
Draw(projectionMatrix [4][4]float64,
geometryMatrix matrix.Geometry, colorMatrix matrix.Color)
DrawParts(parts []graphics.TexturePart, projectionMatrix [4][4]float64,
geometryMatrix matrix.Geometry, colorMatrix matrix.Color)
}
type RenderTarget interface {
SetAsViewport()
ProjectionMatrix() [4][4]float64
}
type Offscreen struct { type Offscreen struct {
screenHeight int currentRenderTarget RenderTarget
screenScale int mainFramebuffer RenderTarget
currentRenderTarget *rendertarget.RenderTarget
mainFramebufferTexture *rendertarget.RenderTarget
} }
func New(screenWidth, screenHeight, screenScale int) *Offscreen { func New(mainFramebuffer RenderTarget) *Offscreen {
offscreen := &Offscreen{ return &Offscreen{
screenHeight: screenHeight, mainFramebuffer: mainFramebuffer,
screenScale: screenScale, }
} }
offscreen.mainFramebufferTexture = rendertarget.NewWithCurrentFramebuffer( func (o *Offscreen) Set(rt RenderTarget) {
screenWidth*screenScale,
screenHeight*screenScale)
return offscreen
}
func (o *Offscreen) Set(rt *rendertarget.RenderTarget) {
o.currentRenderTarget = rt o.currentRenderTarget = rt
rt.SetAsViewport() rt.SetAsViewport()
} }
func (o *Offscreen) SetMainFramebuffer() { func (o *Offscreen) SetMainFramebuffer() {
o.Set(o.mainFramebufferTexture) o.Set(o.mainFramebuffer)
} }
func (o *Offscreen) DrawTexture(texture *texture.Texture, func (o *Offscreen) DrawTexture(texture Texture,
geometryMatrix matrix.Geometry, colorMatrix matrix.Color) { geometryMatrix matrix.Geometry, colorMatrix matrix.Color) {
projectionMatrix := o.projectionMatrix() projectionMatrix := o.currentRenderTarget.ProjectionMatrix()
texture.Draw(projectionMatrix, geometryMatrix, colorMatrix) texture.Draw(projectionMatrix, geometryMatrix, colorMatrix)
} }
func (o *Offscreen) DrawTextureParts(texture *texture.Texture, func (o *Offscreen) DrawTextureParts(texture Texture,
parts []graphics.TexturePart, parts []graphics.TexturePart,
geometryMatrix matrix.Geometry, colorMatrix matrix.Color) { geometryMatrix matrix.Geometry, colorMatrix matrix.Color) {
projectionMatrix := o.projectionMatrix() projectionMatrix := o.currentRenderTarget.ProjectionMatrix()
texture.DrawParts(parts, projectionMatrix, geometryMatrix, colorMatrix) texture.DrawParts(parts, projectionMatrix, geometryMatrix, colorMatrix)
} }
func (o *Offscreen) projectionMatrix() [16]float32 {
matrix := o.currentRenderTarget.ProjectionMatrix()
if o.currentRenderTarget == o.mainFramebufferTexture {
actualScreenHeight := o.screenHeight * o.screenScale
// Flip Y and move to fit with the top of the window.
matrix[1][1] *= -1
matrix[1][3] += float64(actualScreenHeight) /
float64(graphics.AdjustSizeForTexture(actualScreenHeight)) * 2
}
projectionMatrix := [16]float32{}
for j := 0; j < 4; j++ {
for i := 0; i < 4; i++ {
projectionMatrix[i+j*4] = float32(matrix[i][j])
}
}
return projectionMatrix
}

View File

@ -15,12 +15,15 @@ type RenderTarget struct {
framebuffer C.GLuint framebuffer C.GLuint
width int width int
height int height int
flipY bool
} }
func NewWithCurrentFramebuffer(width, height int) *RenderTarget { func NewWithCurrentFramebuffer(width, height int) *RenderTarget {
framebuffer := C.GLint(0) framebuffer := C.GLint(0)
C.glGetIntegerv(C.GL_FRAMEBUFFER_BINDING, &framebuffer) C.glGetIntegerv(C.GL_FRAMEBUFFER_BINDING, &framebuffer)
return &RenderTarget{C.GLuint(framebuffer), width, height} rt := &RenderTarget{C.GLuint(framebuffer), width, height, true}
rt.setAsViewport()
return rt
} }
func createFramebuffer(nativeTexture C.GLuint) C.GLuint { func createFramebuffer(nativeTexture C.GLuint) C.GLuint {
@ -50,10 +53,10 @@ func createFramebuffer(nativeTexture C.GLuint) C.GLuint {
func CreateFromTexture(native NativeTexture, width, height int) *RenderTarget { func CreateFromTexture(native NativeTexture, width, height int) *RenderTarget {
framebuffer := createFramebuffer(C.GLuint(native)) framebuffer := createFramebuffer(C.GLuint(native))
return &RenderTarget{framebuffer, width, height} return &RenderTarget{framebuffer, width, height, false}
} }
func (r *RenderTarget) SetAsViewport() { func (r *RenderTarget) setAsViewport() {
C.glFlush() C.glFlush()
C.glBindFramebuffer(C.GL_FRAMEBUFFER, C.GLuint(r.framebuffer)) C.glBindFramebuffer(C.GL_FRAMEBUFFER, C.GLuint(r.framebuffer))
@ -70,10 +73,26 @@ func (r *RenderTarget) SetAsViewport() {
C.glViewport(0, 0, C.GLsizei(width), C.GLsizei(height)) C.glViewport(0, 0, C.GLsizei(width), C.GLsizei(height))
} }
func (r *RenderTarget) SetAsViewport() {
current := C.GLint(0)
C.glGetIntegerv(C.GL_FRAMEBUFFER_BINDING, &current)
if C.GLuint(current) == r.framebuffer {
return
}
r.setAsViewport()
}
func (r *RenderTarget) ProjectionMatrix() [4][4]float64 { func (r *RenderTarget) ProjectionMatrix() [4][4]float64 {
width := graphics.AdjustSizeForTexture(r.width) width := graphics.AdjustSizeForTexture(r.width)
height := graphics.AdjustSizeForTexture(r.height) height := graphics.AdjustSizeForTexture(r.height)
return graphics.OrthoProjectionMatrix(0, width, 0, height) matrix := graphics.OrthoProjectionMatrix(0, width, 0, height)
if r.flipY {
// Flip Y and move to fit with the top of the window.
matrix[1][1] *= -1
matrix[1][3] += float64(r.height) /
float64(graphics.AdjustSizeForTexture(r.height)) * 2
}
return matrix
} }
func (r *RenderTarget) Dispose() { func (r *RenderTarget) Dispose() {

View File

@ -19,6 +19,16 @@ type Texture struct {
height int height int
} }
func glMatrix(matrix [4][4]float64) [16]float32 {
result := [16]float32{}
for j := 0; j < 4; j++ {
for i := 0; i < 4; i++ {
result[i+j*4] = float32(matrix[i][j])
}
}
return result
}
func createNativeTexture(textureWidth, textureHeight int, pixels []uint8, func createNativeTexture(textureWidth, textureHeight int, pixels []uint8,
filter graphics.Filter) C.GLuint { filter graphics.Filter) C.GLuint {
nativeTexture := C.GLuint(0) nativeTexture := C.GLuint(0)
@ -73,18 +83,18 @@ func (t *Texture) CreateRenderTarget() *rendertarget.RenderTarget {
rendertarget.NativeTexture(t.native), t.width, t.height) rendertarget.NativeTexture(t.native), t.width, t.height)
} }
func (t *Texture) Draw(projectionMatrix [16]float32, geometryMatrix matrix.Geometry, colorMatrix matrix.Color) { func (t *Texture) Draw(projectionMatrix [4][4]float64, geometryMatrix matrix.Geometry, colorMatrix matrix.Color) {
quad := graphics.TextureQuadForTexture(t.width, t.height) quad := graphics.TextureQuadForTexture(t.width, t.height)
shader.DrawTexture(shader.NativeTexture(t.native), shader.DrawTexture(shader.NativeTexture(t.native),
projectionMatrix, []graphics.TextureQuad{quad}, glMatrix(projectionMatrix), []graphics.TextureQuad{quad},
geometryMatrix, colorMatrix) geometryMatrix, colorMatrix)
} }
func (t *Texture) DrawParts(parts []graphics.TexturePart, projectionMatrix [16]float32, func (t *Texture) DrawParts(parts []graphics.TexturePart, projectionMatrix [4][4]float64,
geometryMatrix matrix.Geometry, colorMatrix matrix.Color) { geometryMatrix matrix.Geometry, colorMatrix matrix.Color) {
quads := graphics.TextureQuadsForTextureParts(parts, t.width, t.height) quads := graphics.TextureQuadsForTextureParts(parts, t.width, t.height)
shader.DrawTexture(shader.NativeTexture(t.native), shader.DrawTexture(shader.NativeTexture(t.native),
projectionMatrix, quads, glMatrix(projectionMatrix), quads,
geometryMatrix, colorMatrix) geometryMatrix, colorMatrix)
} }