From c1fa38ebed009e32ec131d196aabe326569ca643 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sun, 14 Dec 2014 21:38:54 +0900 Subject: [PATCH] Remove panic --- graphics.go | 10 +++++----- graphicscontext.go | 12 ++++++------ ids.go | 26 +++++++++++++++++++------- internal/opengl/rendertarget.go | 21 +++++++++++++-------- syncgraphicscontext.go | 15 +++++++++------ 5 files changed, 52 insertions(+), 32 deletions(-) diff --git a/graphics.go b/graphics.go index 66dc3f2c2..ae2dfedca 100644 --- a/graphics.go +++ b/graphics.go @@ -38,21 +38,21 @@ type TexturePart struct { // A Drawer is the interface that draws itself. type Drawer interface { - Draw(parts []TexturePart, geo GeometryMatrix, color ColorMatrix) + Draw(parts []TexturePart, geo GeometryMatrix, color ColorMatrix) error } // 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{ {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. type GraphicsContext interface { - Clear() - Fill(r, g, b uint8) + Clear() error + Fill(r, g, b uint8) error Texture(id TextureID) Drawer RenderTarget(id RenderTargetID) Drawer // TODO: ScreenRenderTarget() Drawer diff --git a/graphicscontext.go b/graphicscontext.go index 14309345c..44aed9554 100644 --- a/graphicscontext.go +++ b/graphicscontext.go @@ -64,12 +64,12 @@ func (c *graphicsContext) dispose() { idsInstance.deleteRenderTarget(c.screenID) } -func (c *graphicsContext) Clear() { - c.Fill(0, 0, 0) +func (c *graphicsContext) Clear() error { + return c.Fill(0, 0, 0) } -func (c *graphicsContext) Fill(r, g, b uint8) { - idsInstance.fillRenderTarget(c.currentIDs[len(c.currentIDs)-1], r, g, b) +func (c *graphicsContext) Fill(r, g, b uint8) error { + return idsInstance.fillRenderTarget(c.currentIDs[len(c.currentIDs)-1], r, g, b) } func (c *graphicsContext) Texture(id TextureID) Drawer { @@ -112,7 +112,7 @@ type textureWithContext struct { 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] - idsInstance.drawTexture(currentID, t.id, parts, geo, color) + return idsInstance.drawTexture(currentID, t.id, parts, geo, color) } diff --git a/ids.go b/ids.go index fe01acdf6..9bb41c03c 100644 --- a/ids.go +++ b/ids.go @@ -81,7 +81,10 @@ func (i *ids) createRenderTarget(width, height int, filter int) (RenderTargetID, // The current binded framebuffer can be changed. i.currentRenderTargetId = -1 - r := opengl.NewRenderTargetFromTexture(texture) + r, err := opengl.NewRenderTargetFromTexture(texture) + if err != nil { + return 0, err + } i.Lock() defer i.Unlock() @@ -124,26 +127,35 @@ func (i *ids) deleteRenderTarget(id RenderTargetID) { delete(i.textures, textureId) } -func (i *ids) fillRenderTarget(id RenderTargetID, r, g, b uint8) { - i.setViewportIfNeeded(id) +func (i *ids) fillRenderTarget(id RenderTargetID, r, g, b uint8) error { + if err := i.setViewportIfNeeded(id); err != nil { + return err + } const max = float64(math.MaxUint8) gl.ClearColor(gl.GLclampf(float64(r)/max), gl.GLclampf(float64(g)/max), gl.GLclampf(float64(b)/max), 1) 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) - i.setViewportIfNeeded(target) + if err := i.setViewportIfNeeded(target); err != nil { + return err + } r := i.renderTargetAt(target) projectionMatrix := r.ProjectionMatrix() quads := textureQuads(parts, texture.Width(), texture.Height()) 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) if i.currentRenderTargetId != id { - r.SetAsViewport() + if err := r.SetAsViewport(); err != nil { + return err + } i.currentRenderTargetId = id } + return nil } diff --git a/internal/opengl/rendertarget.go b/internal/opengl/rendertarget.go index af8795e49..3467c4828 100644 --- a/internal/opengl/rendertarget.go +++ b/internal/opengl/rendertarget.go @@ -17,6 +17,7 @@ limitations under the License. package opengl import ( + "errors" "fmt" "github.com/go-gl/gl" ) @@ -50,13 +51,16 @@ func NewRenderTarget(width, height int, flipY bool) *RenderTarget { } } -func NewRenderTargetFromTexture(texture *Texture) *RenderTarget { - framebuffer := createFramebuffer(texture.Native()) +func NewRenderTargetFromTexture(texture *Texture) (*RenderTarget, error) { + framebuffer, err := createFramebuffer(texture.Native()) + if err != nil { + return nil, err + } return &RenderTarget{ framebuffer: framebuffer, width: texture.Width(), height: texture.Height(), - } + }, nil } func (r *RenderTarget) Width() int { @@ -75,13 +79,13 @@ func (r *RenderTarget) Dispose() { r.framebuffer.Delete() } -func createFramebuffer(nativeTexture gl.Texture) gl.Framebuffer { +func createFramebuffer(nativeTexture gl.Texture) (gl.Framebuffer, error) { framebuffer := gl.GenFramebuffer() framebuffer.Bind() gl.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, nativeTexture, 0) 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 @@ -89,15 +93,15 @@ func createFramebuffer(nativeTexture gl.Texture) gl.Framebuffer { gl.ClearColor(0, 0, 0, 1) gl.Clear(gl.COLOR_BUFFER_BIT) - return framebuffer + return framebuffer, nil } -func (r *RenderTarget) SetAsViewport() { +func (r *RenderTarget) SetAsViewport() error { gl.Flush() r.framebuffer.Bind() err := gl.CheckFramebufferStatus(gl.FRAMEBUFFER) 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) @@ -105,6 +109,7 @@ func (r *RenderTarget) SetAsViewport() { width := AdjustSizeForTexture(r.width) height := AdjustSizeForTexture(r.height) gl.Viewport(0, 0, width, height) + return nil } func (r *RenderTarget) ProjectionMatrix() [4][4]float64 { diff --git a/syncgraphicscontext.go b/syncgraphicscontext.go index ffbc458b6..106c600c1 100644 --- a/syncgraphicscontext.go +++ b/syncgraphicscontext.go @@ -27,16 +27,18 @@ type syncGraphicsContext struct { var _ GraphicsContext = new(syncGraphicsContext) -func (c *syncGraphicsContext) Clear() { +func (c *syncGraphicsContext) Clear() (err error) { 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.innerGraphicsContext.Fill(r, g, b) + err = c.innerGraphicsContext.Fill(r, g, b) }) + return } func (c *syncGraphicsContext) Texture(id TextureID) (d Drawer) { @@ -78,8 +80,9 @@ type drawer struct { 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.innerDrawer.Draw(parts, geo, color) + err = d.innerDrawer.Draw(parts, geo, color) }) + return }