Remove panic

This commit is contained in:
Hajime Hoshi 2014-12-14 21:38:54 +09:00
parent 6f3e45098b
commit c1fa38ebed
5 changed files with 52 additions and 32 deletions

View File

@ -38,21 +38,21 @@ type TexturePart struct {
// A Drawer is the interface that draws itself. // A Drawer is the interface that draws itself.
type Drawer interface { type Drawer interface {
Draw(parts []TexturePart, geo GeometryMatrix, color ColorMatrix) Draw(parts []TexturePart, geo GeometryMatrix, color ColorMatrix) error
} }
// DrawWhole draws the whole texture. // DrawWhole draws the whole texture.
func DrawWhole(drawer Drawer, width, height int, geo GeometryMatrix, color ColorMatrix) { func DrawWhole(drawer Drawer, width, height int, geo GeometryMatrix, color ColorMatrix) error {
parts := []TexturePart{ parts := []TexturePart{
{0, 0, Rect{0, 0, width, height}}, {0, 0, Rect{0, 0, width, height}},
} }
drawer.Draw(parts, geo, color) return drawer.Draw(parts, geo, color)
} }
// A Context is the interface that means a context of rendering. // A Context is the interface that means a context of rendering.
type GraphicsContext interface { type GraphicsContext interface {
Clear() Clear() error
Fill(r, g, b uint8) Fill(r, g, b uint8) error
Texture(id TextureID) Drawer Texture(id TextureID) Drawer
RenderTarget(id RenderTargetID) Drawer RenderTarget(id RenderTargetID) Drawer
// TODO: ScreenRenderTarget() Drawer // TODO: ScreenRenderTarget() Drawer

View File

@ -64,12 +64,12 @@ func (c *graphicsContext) dispose() {
idsInstance.deleteRenderTarget(c.screenID) idsInstance.deleteRenderTarget(c.screenID)
} }
func (c *graphicsContext) Clear() { func (c *graphicsContext) Clear() error {
c.Fill(0, 0, 0) return c.Fill(0, 0, 0)
} }
func (c *graphicsContext) Fill(r, g, b uint8) { func (c *graphicsContext) Fill(r, g, b uint8) error {
idsInstance.fillRenderTarget(c.currentIDs[len(c.currentIDs)-1], r, g, b) return idsInstance.fillRenderTarget(c.currentIDs[len(c.currentIDs)-1], r, g, b)
} }
func (c *graphicsContext) Texture(id TextureID) Drawer { func (c *graphicsContext) Texture(id TextureID) Drawer {
@ -112,7 +112,7 @@ type textureWithContext struct {
context *graphicsContext context *graphicsContext
} }
func (t *textureWithContext) Draw(parts []TexturePart, geo GeometryMatrix, color ColorMatrix) { func (t *textureWithContext) Draw(parts []TexturePart, geo GeometryMatrix, color ColorMatrix) error {
currentID := t.context.currentIDs[len(t.context.currentIDs)-1] currentID := t.context.currentIDs[len(t.context.currentIDs)-1]
idsInstance.drawTexture(currentID, t.id, parts, geo, color) return idsInstance.drawTexture(currentID, t.id, parts, geo, color)
} }

26
ids.go
View File

@ -81,7 +81,10 @@ func (i *ids) createRenderTarget(width, height int, filter int) (RenderTargetID,
// The current binded framebuffer can be changed. // The current binded framebuffer can be changed.
i.currentRenderTargetId = -1 i.currentRenderTargetId = -1
r := opengl.NewRenderTargetFromTexture(texture) r, err := opengl.NewRenderTargetFromTexture(texture)
if err != nil {
return 0, err
}
i.Lock() i.Lock()
defer i.Unlock() defer i.Unlock()
@ -124,26 +127,35 @@ func (i *ids) deleteRenderTarget(id RenderTargetID) {
delete(i.textures, textureId) delete(i.textures, textureId)
} }
func (i *ids) fillRenderTarget(id RenderTargetID, r, g, b uint8) { func (i *ids) fillRenderTarget(id RenderTargetID, r, g, b uint8) error {
i.setViewportIfNeeded(id) if err := i.setViewportIfNeeded(id); err != nil {
return err
}
const max = float64(math.MaxUint8) const max = float64(math.MaxUint8)
gl.ClearColor(gl.GLclampf(float64(r)/max), gl.GLclampf(float64(g)/max), gl.GLclampf(float64(b)/max), 1) gl.ClearColor(gl.GLclampf(float64(r)/max), gl.GLclampf(float64(g)/max), gl.GLclampf(float64(b)/max), 1)
gl.Clear(gl.COLOR_BUFFER_BIT) gl.Clear(gl.COLOR_BUFFER_BIT)
return nil
} }
func (i *ids) drawTexture(target RenderTargetID, id TextureID, parts []TexturePart, geo GeometryMatrix, color ColorMatrix) { func (i *ids) drawTexture(target RenderTargetID, id TextureID, parts []TexturePart, geo GeometryMatrix, color ColorMatrix) error {
texture := i.textureAt(id) texture := i.textureAt(id)
i.setViewportIfNeeded(target) if err := i.setViewportIfNeeded(target); err != nil {
return err
}
r := i.renderTargetAt(target) r := i.renderTargetAt(target)
projectionMatrix := r.ProjectionMatrix() projectionMatrix := r.ProjectionMatrix()
quads := textureQuads(parts, texture.Width(), texture.Height()) quads := textureQuads(parts, texture.Width(), texture.Height())
shader.DrawTexture(texture.Native(), projectionMatrix, quads, &geo, &color) shader.DrawTexture(texture.Native(), projectionMatrix, quads, &geo, &color)
return nil
} }
func (i *ids) setViewportIfNeeded(id RenderTargetID) { func (i *ids) setViewportIfNeeded(id RenderTargetID) error {
r := i.renderTargetAt(id) r := i.renderTargetAt(id)
if i.currentRenderTargetId != id { if i.currentRenderTargetId != id {
r.SetAsViewport() if err := r.SetAsViewport(); err != nil {
return err
}
i.currentRenderTargetId = id i.currentRenderTargetId = id
} }
return nil
} }

View File

@ -17,6 +17,7 @@ limitations under the License.
package opengl package opengl
import ( import (
"errors"
"fmt" "fmt"
"github.com/go-gl/gl" "github.com/go-gl/gl"
) )
@ -50,13 +51,16 @@ func NewRenderTarget(width, height int, flipY bool) *RenderTarget {
} }
} }
func NewRenderTargetFromTexture(texture *Texture) *RenderTarget { func NewRenderTargetFromTexture(texture *Texture) (*RenderTarget, error) {
framebuffer := createFramebuffer(texture.Native()) framebuffer, err := createFramebuffer(texture.Native())
if err != nil {
return nil, err
}
return &RenderTarget{ return &RenderTarget{
framebuffer: framebuffer, framebuffer: framebuffer,
width: texture.Width(), width: texture.Width(),
height: texture.Height(), height: texture.Height(),
} }, nil
} }
func (r *RenderTarget) Width() int { func (r *RenderTarget) Width() int {
@ -75,13 +79,13 @@ func (r *RenderTarget) Dispose() {
r.framebuffer.Delete() r.framebuffer.Delete()
} }
func createFramebuffer(nativeTexture gl.Texture) gl.Framebuffer { func createFramebuffer(nativeTexture gl.Texture) (gl.Framebuffer, error) {
framebuffer := gl.GenFramebuffer() framebuffer := gl.GenFramebuffer()
framebuffer.Bind() framebuffer.Bind()
gl.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, nativeTexture, 0) gl.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, nativeTexture, 0)
if gl.CheckFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE { if gl.CheckFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE {
panic("creating framebuffer failed") return 0, errors.New("creating framebuffer failed")
} }
// Set this framebuffer opaque because alpha values on a target might be // Set this framebuffer opaque because alpha values on a target might be
@ -89,15 +93,15 @@ func createFramebuffer(nativeTexture gl.Texture) gl.Framebuffer {
gl.ClearColor(0, 0, 0, 1) gl.ClearColor(0, 0, 0, 1)
gl.Clear(gl.COLOR_BUFFER_BIT) gl.Clear(gl.COLOR_BUFFER_BIT)
return framebuffer return framebuffer, nil
} }
func (r *RenderTarget) SetAsViewport() { func (r *RenderTarget) SetAsViewport() error {
gl.Flush() gl.Flush()
r.framebuffer.Bind() r.framebuffer.Bind()
err := gl.CheckFramebufferStatus(gl.FRAMEBUFFER) err := gl.CheckFramebufferStatus(gl.FRAMEBUFFER)
if err != gl.FRAMEBUFFER_COMPLETE { if err != gl.FRAMEBUFFER_COMPLETE {
panic(fmt.Sprintf("glBindFramebuffer failed: %d", err)) return errors.New(fmt.Sprintf("glBindFramebuffer failed: %d", err))
} }
gl.BlendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ZERO, gl.ONE) gl.BlendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ZERO, gl.ONE)
@ -105,6 +109,7 @@ func (r *RenderTarget) SetAsViewport() {
width := AdjustSizeForTexture(r.width) width := AdjustSizeForTexture(r.width)
height := AdjustSizeForTexture(r.height) height := AdjustSizeForTexture(r.height)
gl.Viewport(0, 0, width, height) gl.Viewport(0, 0, width, height)
return nil
} }
func (r *RenderTarget) ProjectionMatrix() [4][4]float64 { func (r *RenderTarget) ProjectionMatrix() [4][4]float64 {

View File

@ -27,16 +27,18 @@ type syncGraphicsContext struct {
var _ GraphicsContext = new(syncGraphicsContext) var _ GraphicsContext = new(syncGraphicsContext)
func (c *syncGraphicsContext) Clear() { func (c *syncGraphicsContext) Clear() (err error) {
c.syncer.Sync(func() { c.syncer.Sync(func() {
c.innerGraphicsContext.Clear() err = c.innerGraphicsContext.Clear()
}) })
return
} }
func (c *syncGraphicsContext) Fill(r, g, b uint8) { func (c *syncGraphicsContext) Fill(r, g, b uint8) (err error) {
c.syncer.Sync(func() { c.syncer.Sync(func() {
c.innerGraphicsContext.Fill(r, g, b) err = c.innerGraphicsContext.Fill(r, g, b)
}) })
return
} }
func (c *syncGraphicsContext) Texture(id TextureID) (d Drawer) { func (c *syncGraphicsContext) Texture(id TextureID) (d Drawer) {
@ -78,8 +80,9 @@ type drawer struct {
var _ Drawer = new(drawer) var _ Drawer = new(drawer)
func (d *drawer) Draw(parts []TexturePart, geo GeometryMatrix, color ColorMatrix) { func (d *drawer) Draw(parts []TexturePart, geo GeometryMatrix, color ColorMatrix) (err error) {
d.syncer.Sync(func() { d.syncer.Sync(func() {
d.innerDrawer.Draw(parts, geo, color) err = d.innerDrawer.Draw(parts, geo, color)
}) })
return
} }