This commit is contained in:
Hajime Hoshi 2014-05-04 02:13:43 +09:00
parent 26122aa120
commit 52e7817c1d
3 changed files with 49 additions and 56 deletions

View File

@ -22,7 +22,7 @@ func flush() {
type Context struct {
screenId graphics.RenderTargetId
mainId graphics.RenderTargetId
defaultId graphics.RenderTargetId
currentId graphics.RenderTargetId
ids *ids
screenWidth int
@ -37,10 +37,13 @@ func newContext(ids *ids, screenWidth, screenHeight, screenScale int) *Context {
screenHeight: screenHeight,
screenScale: screenScale,
}
mainRenderTarget := newRTWithCurrentFramebuffer(
screenWidth*screenScale,
screenHeight*screenScale)
context.mainId = context.ids.addRenderTarget(mainRenderTarget)
defaultRenderTarget := &RenderTarget{
framebuffer: C.GLuint(0),
width: screenWidth * screenScale,
height: screenHeight * screenScale,
flipY: true,
}
context.defaultId = context.ids.addRenderTarget(defaultRenderTarget)
var err error
context.screenId, err = ids.createRenderTarget(
@ -57,7 +60,7 @@ func newContext(ids *ids, screenWidth, screenHeight, screenScale int) *Context {
}
func (c *Context) Dispose() {
// TODO: remove main framebuffer?
// TODO: remove the default framebuffer?
c.ids.deleteRenderTarget(c.screenId)
}
@ -67,7 +70,7 @@ func (c *Context) Update(draw func(graphics.Context)) {
draw(c)
c.SetOffscreen(c.mainId)
c.SetOffscreen(c.defaultId)
c.Clear()
scale := float64(c.screenScale)

View File

@ -1,9 +1,15 @@
package opengl
// #cgo LDFLAGS: -framework OpenGL
//
// #include <OpenGL/gl.h>
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"
"math"
"sync"
)
@ -30,6 +36,7 @@ type ids struct {
renderTargets map[graphics.RenderTargetId]*RenderTarget
renderTargetToTexture map[graphics.RenderTargetId]graphics.TextureId
counts chan int
currentRenderTargetId graphics.RenderTargetId
sync.RWMutex
}
@ -39,6 +46,7 @@ func newIds() *ids {
renderTargets: map[graphics.RenderTargetId]*RenderTarget{},
renderTargetToTexture: map[graphics.RenderTargetId]graphics.TextureId{},
counts: make(chan int),
currentRenderTargetId: -1,
}
go func() {
for i := 1; ; i++ {
@ -88,6 +96,8 @@ func (i *ids) createRenderTarget(width, height int, filter graphics.Filter) (
return 0, err
}
framebuffer := createFramebuffer(texture.native)
// The current binded framebuffer can be changed.
i.currentRenderTargetId = -1
renderTarget := &RenderTarget{framebuffer, texture.width, texture.height, false}
textureId := graphics.TextureId(<-i.counts)
@ -130,13 +140,39 @@ func (i *ids) deleteRenderTarget(id graphics.RenderTargetId) {
}
func (i *ids) fillRenderTarget(id graphics.RenderTargetId, r, g, b uint8) {
i.renderTargetAt(id).fill(r, g, b)
i.setViewportIfNeeded(id)
const max = float64(math.MaxUint8)
C.glClearColor(
C.GLclampf(float64(r)/max),
C.GLclampf(float64(g)/max),
C.GLclampf(float64(b)/max),
1)
C.glClear(C.GL_COLOR_BUFFER_BIT)
}
func (i *ids) drawTexture(
target graphics.RenderTargetId,
id graphics.TextureId,
parts []graphics.TexturePart, geo matrix.Geometry, color matrix.Color) {
parts []graphics.TexturePart,
geo matrix.Geometry,
color matrix.Color) {
texture := i.textureAt(id)
i.renderTargetAt(target).drawTexture(texture, parts, geo, color)
i.setViewportIfNeeded(target)
r := i.renderTargetAt(target)
projectionMatrix := r.projectionMatrix()
quads := graphics.TextureQuads(parts, texture.width, texture.height)
shader.DrawTexture(
shader.NativeTexture(texture.native),
glMatrix(projectionMatrix),
quads,
geo,
color)
}
func (i *ids) setViewportIfNeeded(id graphics.RenderTargetId) {
r := i.renderTargetAt(id)
if i.currentRenderTargetId != id {
r.setAsViewport()
i.currentRenderTargetId = id
}
}

View File

@ -7,9 +7,6 @@ import "C"
import (
"fmt"
"github.com/hajimehoshi/go-ebiten/graphics"
"github.com/hajimehoshi/go-ebiten/graphics/matrix"
"github.com/hajimehoshi/go-ebiten/graphics/opengl/shader"
"math"
)
func glMatrix(matrix [4][4]float64) [16]float32 {
@ -29,21 +26,11 @@ type RenderTarget struct {
flipY bool
}
func newRTWithCurrentFramebuffer(width, height int) *RenderTarget {
framebuffer := C.GLint(0)
C.glGetIntegerv(C.GL_FRAMEBUFFER_BINDING, &framebuffer)
return &RenderTarget{C.GLuint(framebuffer), width, height, true}
}
func createFramebuffer(nativeTexture C.GLuint) C.GLuint {
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)
@ -61,12 +48,6 @@ func createFramebuffer(nativeTexture C.GLuint) C.GLuint {
}
func (r *RenderTarget) setAsViewport() {
current := C.GLint(0)
C.glGetIntegerv(C.GL_FRAMEBUFFER_BINDING, &current)
if C.GLuint(current) == r.framebuffer {
return
}
C.glFlush()
C.glBindFramebuffer(C.GL_FRAMEBUFFER, C.GLuint(r.framebuffer))
@ -98,30 +79,3 @@ func (r *RenderTarget) projectionMatrix() [4][4]float64 {
func (r *RenderTarget) dispose() {
C.glDeleteFramebuffers(1, &r.framebuffer)
}
func (r *RenderTarget) fill(red, green, blue uint8) {
r.setAsViewport()
const max = float64(math.MaxUint8)
C.glClearColor(
C.GLclampf(float64(red)/max),
C.GLclampf(float64(green)/max),
C.GLclampf(float64(blue)/max),
1)
C.glClear(C.GL_COLOR_BUFFER_BIT)
}
func (r *RenderTarget) drawTexture(
texture *Texture,
parts []graphics.TexturePart,
geometryMatrix matrix.Geometry,
colorMatrix matrix.Color) {
r.setAsViewport()
projectionMatrix := r.projectionMatrix()
quads := graphics.TextureQuads(parts, texture.width, texture.height)
shader.DrawTexture(
shader.NativeTexture(texture.native),
glMatrix(projectionMatrix),
quads,
geometryMatrix,
colorMatrix)
}