Merge pull request #4 from hajimehoshi/remove-glget

Remove unnecessary glGet* in the render loop
This commit is contained in:
Hajime Hoshi 2014-05-04 02:40:03 +09:00
commit a6bf0f6634
3 changed files with 49 additions and 56 deletions

View File

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

View File

@ -1,9 +1,15 @@
package opengl package opengl
// #cgo LDFLAGS: -framework OpenGL
//
// #include <OpenGL/gl.h>
import "C"
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/shader"
"image" "image"
"math"
"sync" "sync"
) )
@ -30,6 +36,7 @@ type ids struct {
renderTargets map[graphics.RenderTargetId]*RenderTarget renderTargets map[graphics.RenderTargetId]*RenderTarget
renderTargetToTexture map[graphics.RenderTargetId]graphics.TextureId renderTargetToTexture map[graphics.RenderTargetId]graphics.TextureId
counts chan int counts chan int
currentRenderTargetId graphics.RenderTargetId
sync.RWMutex sync.RWMutex
} }
@ -39,6 +46,7 @@ func newIds() *ids {
renderTargets: map[graphics.RenderTargetId]*RenderTarget{}, renderTargets: map[graphics.RenderTargetId]*RenderTarget{},
renderTargetToTexture: map[graphics.RenderTargetId]graphics.TextureId{}, renderTargetToTexture: map[graphics.RenderTargetId]graphics.TextureId{},
counts: make(chan int), counts: make(chan int),
currentRenderTargetId: -1,
} }
go func() { go func() {
for i := 1; ; i++ { for i := 1; ; i++ {
@ -88,6 +96,8 @@ func (i *ids) createRenderTarget(width, height int, filter graphics.Filter) (
return 0, err return 0, err
} }
framebuffer := createFramebuffer(texture.native) framebuffer := createFramebuffer(texture.native)
// The current binded framebuffer can be changed.
i.currentRenderTargetId = -1
renderTarget := &RenderTarget{framebuffer, texture.width, texture.height, false} renderTarget := &RenderTarget{framebuffer, texture.width, texture.height, false}
textureId := graphics.TextureId(<-i.counts) 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) { 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( func (i *ids) drawTexture(
target graphics.RenderTargetId, target graphics.RenderTargetId,
id graphics.TextureId, 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) 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 ( import (
"fmt" "fmt"
"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/opengl/shader"
"math"
) )
func glMatrix(matrix [4][4]float64) [16]float32 { func glMatrix(matrix [4][4]float64) [16]float32 {
@ -29,21 +26,11 @@ type RenderTarget struct {
flipY bool 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 { func createFramebuffer(nativeTexture C.GLuint) C.GLuint {
framebuffer := C.GLuint(0) framebuffer := C.GLuint(0)
C.glGenFramebuffers(1, &framebuffer) C.glGenFramebuffers(1, &framebuffer)
origFramebuffer := C.GLint(0)
C.glGetIntegerv(C.GL_FRAMEBUFFER_BINDING, &origFramebuffer)
C.glBindFramebuffer(C.GL_FRAMEBUFFER, framebuffer) 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.glFramebufferTexture2D(C.GL_FRAMEBUFFER, C.GL_COLOR_ATTACHMENT0,
C.GL_TEXTURE_2D, nativeTexture, 0) C.GL_TEXTURE_2D, nativeTexture, 0)
@ -61,12 +48,6 @@ func createFramebuffer(nativeTexture C.GLuint) C.GLuint {
} }
func (r *RenderTarget) setAsViewport() { 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.glFlush()
C.glBindFramebuffer(C.GL_FRAMEBUFFER, C.GLuint(r.framebuffer)) C.glBindFramebuffer(C.GL_FRAMEBUFFER, C.GLuint(r.framebuffer))
@ -98,30 +79,3 @@ func (r *RenderTarget) projectionMatrix() [4][4]float64 {
func (r *RenderTarget) dispose() { func (r *RenderTarget) dispose() {
C.glDeleteFramebuffers(1, &r.framebuffer) 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)
}