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.
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

View File

@ -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)
}

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.
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
}

View File

@ -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 {

View File

@ -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
}