Refactoring

This commit is contained in:
Hajime Hoshi 2013-11-27 01:46:07 +09:00
parent c921f4fc3b
commit 991d0a975b
4 changed files with 138 additions and 93 deletions

View File

@ -8,11 +8,11 @@ import "C"
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/offscreen"
// "github.com/hajimehoshi/go-ebiten/graphics/opengl/shader"
"github.com/hajimehoshi/go-ebiten/graphics/opengl/texture"
grendertarget "github.com/hajimehoshi/go-ebiten/graphics/rendertarget"
gtexture "github.com/hajimehoshi/go-ebiten/graphics/texture"
// gtexture "github.com/hajimehoshi/go-ebiten/graphics/texture"
"image"
"math"
)
@ -23,8 +23,9 @@ type Context struct {
screenHeight int
screenScale int
ids *ids
mainFramebufferTexture *grendertarget.RenderTarget
projectionMatrix [16]float32
//mainFramebufferTexture *grendertarget.RenderTarget
//projectionMatrix [16]float32
offscreen *offscreen.Offscreen
}
func newContext(screenWidth, screenHeight, screenScale int) *Context {
@ -33,22 +34,10 @@ func newContext(screenWidth, screenHeight, screenScale int) *Context {
screenHeight: screenHeight,
screenScale: screenScale,
ids: newIds(),
offscreen: offscreen.New(screenWidth, screenHeight, screenScale),
}
// The main framebuffer should be created sooner than any other
// framebuffers!
mainFramebuffer := C.GLint(0)
C.glGetIntegerv(C.GL_FRAMEBUFFER_BINDING, &mainFramebuffer)
var err error
context.mainFramebufferTexture, err = rendertarget.NewWithFramebuffer(
context.screenWidth*context.screenScale,
context.screenHeight*context.screenScale,
rendertarget.Framebuffer(mainFramebuffer))
if err != nil {
panic("creating main framebuffer failed: " + err.Error())
}
context.screenId, err = context.createRenderTarget(
context.screenWidth, context.screenHeight, texture.FilterNearest)
if err != nil {
@ -82,22 +71,14 @@ func (context *Context) DrawTexture(
textureId graphics.TextureId,
geometryMatrix matrix.Geometry, colorMatrix matrix.Color) {
tex := context.ids.TextureAt(textureId)
tex.Draw(func(native interface{}, quads []gtexture.Quad) {
shader.DrawTexture(native.(texture.Native),
context.projectionMatrix, quads,
geometryMatrix, colorMatrix)
})
context.offscreen.DrawTexture(tex, geometryMatrix, colorMatrix)
}
func (context *Context) DrawTextureParts(
textureId graphics.TextureId, parts []graphics.TexturePart,
geometryMatrix matrix.Geometry, colorMatrix matrix.Color) {
tex := context.ids.TextureAt(textureId)
tex.DrawParts(parts, func(native interface{}, quads []gtexture.Quad) {
shader.DrawTexture(native.(texture.Native),
context.projectionMatrix, quads,
geometryMatrix, colorMatrix)
})
context.offscreen.DrawTextureParts(tex, parts, geometryMatrix, colorMatrix)
}
func (context *Context) Init() {
@ -115,19 +96,16 @@ func (context *Context) SetOffscreen(renderTargetId graphics.RenderTargetId) {
}
func (context *Context) setOffscreen(rt *grendertarget.RenderTarget) {
C.glFlush()
/*C.glFlush()
setter := &OffscreenSetter{
context.screenHeight,
context.screenScale,
rt == context.mainFramebufferTexture,
&context.projectionMatrix,
}
rt.SetAsOffscreen(setter)
rt.SetAsOffscreen(context.offscreen)
context.projectionMatrix = setter.projectionMatrix*/
context.offscreen.Set(rt)
}
func (context *Context) setMainFramebufferOffscreen() {
context.setOffscreen(context.mainFramebufferTexture)
//context.setOffscreen(context.mainFramebufferTexture)
context.offscreen.SetMainFramebuffer()
}
func (context *Context) flush() {

View File

@ -1,48 +0,0 @@
package opengl
// #cgo LDFLAGS: -framework OpenGL
//
// #include <stdlib.h>
// #include <OpenGL/gl.h>
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])
}
}
}

View File

@ -0,0 +1,115 @@
package offscreen
// #cgo LDFLAGS: -framework OpenGL
//
// #include <stdlib.h>
// #include <OpenGL/gl.h>
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"
"github.com/hajimehoshi/go-ebiten/graphics/opengl/shader"
"github.com/hajimehoshi/go-ebiten/graphics/opengl/texture"
grendertarget "github.com/hajimehoshi/go-ebiten/graphics/rendertarget"
gtexture "github.com/hajimehoshi/go-ebiten/graphics/texture"
)
type Offscreen struct {
screenHeight int
screenScale int
mainFramebufferTexture *grendertarget.RenderTarget
projectionMatrix [16]float32
}
func New(screenWidth, screenHeight, screenScale int) *Offscreen {
offscreen := &Offscreen{
screenHeight: screenHeight,
screenScale: screenScale,
}
// The main framebuffer should be created sooner than any other
// framebuffers!
mainFramebuffer := C.GLint(0)
C.glGetIntegerv(C.GL_FRAMEBUFFER_BINDING, &mainFramebuffer)
var err error
offscreen.mainFramebufferTexture, err = rendertarget.NewWithFramebuffer(
screenWidth*screenScale,
screenHeight*screenScale,
rendertarget.Framebuffer(mainFramebuffer))
if err != nil {
panic("creating main framebuffer failed: " + err.Error())
}
return offscreen
}
func (o *Offscreen) Set(rt *grendertarget.RenderTarget) {
C.glFlush()
rt.SetAsOffscreen(&setter{o, rt == o.mainFramebufferTexture})
}
func (o *Offscreen) SetMainFramebuffer() {
o.Set(o.mainFramebufferTexture)
}
func (o *Offscreen) DrawTexture(texture *gtexture.Texture,
geometryMatrix matrix.Geometry, colorMatrix matrix.Color) {
d := &drawable{o, geometryMatrix, colorMatrix}
texture.Draw(d.Draw)
}
func (o *Offscreen) DrawTextureParts(texture *gtexture.Texture,
parts []graphics.TexturePart,
geometryMatrix matrix.Geometry, colorMatrix matrix.Color) {
d := &drawable{o, geometryMatrix, colorMatrix}
texture.DrawParts(parts, d.Draw)
}
type setter struct {
offscreen *Offscreen
usingMainFramebuffer bool
}
func (s *setter) 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.offscreen.screenHeight * s.offscreen.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.offscreen.projectionMatrix[i+j*4] = float32(matrix[i][j])
}
}
}
type drawable struct {
offscreen *Offscreen
geometryMatrix matrix.Geometry
colorMatrix matrix.Color
}
func (d *drawable) Draw(native interface{}, quads []gtexture.Quad) {
shader.DrawTexture(native.(texture.Native),
d.offscreen.projectionMatrix, quads,
d.geometryMatrix, d.colorMatrix)
}

View File

@ -80,14 +80,14 @@ func New(screenWidth, screenHeight, screenScale int, title string) *UI {
C.StartApplication()
context := C.CreateGLContext(unsafe.Pointer(nil))
C.SetCurrentGLContext(context);
C.SetCurrentGLContext(context)
ui.graphicsDevice = opengl.NewDevice(
ui.screenWidth,
ui.screenHeight,
ui.screenScale)
ui.window = C.CreateWindow(C.size_t(ui.screenWidth * ui.screenScale),
C.size_t(ui.screenHeight * ui.screenScale),
ui.window = C.CreateWindow(C.size_t(ui.screenWidth*ui.screenScale),
C.size_t(ui.screenHeight*ui.screenScale),
cTitle,
context)
currentUI = ui