From ca99e94b5cd81098a31dbd66d478f06b8b12b9f3 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Mon, 8 Dec 2014 00:07:36 +0900 Subject: [PATCH] Remove TODOs; Hide some structs --- example/blocks/field.go | 22 ++++---- example/blocks/piece.go | 3 +- graphics/matrix/geometry_test.go | 17 +++--- graphics/opengl/context.go | 92 ++++++++++++++++++-------------- graphics/opengl/ids.go | 18 +++---- graphics/opengl/rendertarget.go | 8 +-- graphics/opengl/texture.go | 12 ++--- ui/glfw/canvas.go | 14 ++--- 8 files changed, 99 insertions(+), 87 deletions(-) diff --git a/example/blocks/field.go b/example/blocks/field.go index 74717ad3f..ae24d7843 100644 --- a/example/blocks/field.go +++ b/example/blocks/field.go @@ -67,6 +67,19 @@ func (f *Field) AbsorbPiece(piece *Piece, x, y int, angle Angle) { f.Flush() } +func (f *Field) setBlock(x, y int, blockType BlockType) { + f.blocks[x][y] = blockType +} + +func (f *Field) Flush() { + flushedLineNum := 0 + for j := fieldBlockNumY - 1; 0 <= j; j-- { + if f.flushLine(j + flushedLineNum) { + flushedLineNum++ + } + } +} + func (f *Field) flushLine(j int) bool { for i := 0; i < fieldBlockNumX; i++ { if f.blocks[i][j] == BlockTypeNone { @@ -84,15 +97,6 @@ func (f *Field) flushLine(j int) bool { return true } -func (f *Field) Flush() { - flushedLineNum := 0 - for j := fieldBlockNumY - 1; 0 <= j; j-- { - if f.flushLine(j + flushedLineNum) { - flushedLineNum++ - } - } -} - func (f *Field) Draw(context graphics.Context, textures *Textures, geo matrix.Geometry) { blocks := make([][]BlockType, len(f.blocks)) for i, blockCol := range f.blocks { diff --git a/example/blocks/piece.go b/example/blocks/piece.go index e5ff86e2d..9c115b7e8 100644 --- a/example/blocks/piece.go +++ b/example/blocks/piece.go @@ -198,8 +198,7 @@ func (p *Piece) AbsorbInto(field *Field, x, y int, angle Angle) { for i := 0; i < size; i++ { for j := 0; j < size; j++ { if p.isBlocked(i, j, angle) { - // TODO: Is it OK to access field.block directly? - field.blocks[x+i][y+j] = p.blockType + field.setBlock(x+i, y+j, p.blockType) } } } diff --git a/graphics/matrix/geometry_test.go b/graphics/matrix/geometry_test.go index ae43742dc..6fa117010 100644 --- a/graphics/matrix/geometry_test.go +++ b/graphics/matrix/geometry_test.go @@ -26,37 +26,36 @@ func TestGeometryConcat(t *testing.T) { {0, 1, 1}, } - // TODO: 'matrix1x2' may not be a good name. - matrix1x2 := matrix1 - matrix1x2.Concat(matrix2) + matrix3 := matrix1 + matrix3.Concat(matrix2) expected := [][]float64{ {2, 0, 1}, {0, 2, 1}, } for i := 0; i < 2; i++ { for j := 0; j < 3; j++ { - got := matrix1x2.Elements[i][j] + got := matrix3.Elements[i][j] want := expected[i][j] if want != got { - t.Errorf("matrix1x2.Element(%d, %d) = %f,"+ + t.Errorf("matrix3.Element(%d, %d) = %f,"+ " want %f", i, j, got, want) } } } - matrix2x1 := matrix2 - matrix2x1.Concat(matrix1) + matrix4 := matrix2 + matrix4.Concat(matrix1) expected = [][]float64{ {2, 0, 2}, {0, 2, 2}, } for i := 0; i < 2; i++ { for j := 0; j < 3; j++ { - got := matrix2x1.Elements[i][j] + got := matrix4.Elements[i][j] want := expected[i][j] if want != got { - t.Errorf("matrix2x1.Element(%d, %d) = %f, want %f", + t.Errorf("matrix4.Element(%d, %d) = %f, want %f", i, j, got, want) } } diff --git a/graphics/opengl/context.go b/graphics/opengl/context.go index 8ddfc5d3e..0c6c1d878 100644 --- a/graphics/opengl/context.go +++ b/graphics/opengl/context.go @@ -8,13 +8,23 @@ import ( "sync" ) -func flush() { - gl.Flush() +type ContextUpdater struct { + context *context +} + +func NewContextUpdater(screenWidth, screenHeight, screenScale int) *ContextUpdater { + return &ContextUpdater{ + context: newContext(screenWidth, screenHeight, screenScale), + } +} + +func (u *ContextUpdater) Update(drawer ui.Drawer) error { + return u.context.update(drawer) } var onceInit sync.Once -type Context struct { +type context struct { screenId graphics.RenderTargetID defaultId graphics.RenderTargetID currentId graphics.RenderTargetID @@ -23,44 +33,68 @@ type Context struct { screenScale int } -func NewContext(screenWidth, screenHeight, screenScale int) *Context { +func newContext(screenWidth, screenHeight, screenScale int) *context { onceInit.Do(func() { gl.Init() gl.Enable(gl.TEXTURE_2D) gl.Enable(gl.BLEND) }) - context := &Context{ + c := &context{ screenWidth: screenWidth, screenHeight: screenHeight, screenScale: screenScale, } - defaultRenderTarget := &RenderTarget{ + // The defualt framebuffer should be 0. + defaultRenderTarget := &renderTarget{ width: screenWidth * screenScale, height: screenHeight * screenScale, flipY: true, } - context.defaultId = idsInstance.addRenderTarget(defaultRenderTarget) + c.defaultId = idsInstance.addRenderTarget(defaultRenderTarget) var err error - context.screenId, err = idsInstance.createRenderTarget(screenWidth, screenHeight, graphics.FilterNearest) + c.screenId, err = idsInstance.createRenderTarget(screenWidth, screenHeight, graphics.FilterNearest) if err != nil { panic("opengl.NewContext: initializing the offscreen failed: " + err.Error()) } - context.ResetOffscreen() - context.Clear() + c.ResetOffscreen() + c.Clear() - return context + return c } -func (c *Context) Dispose() { - // TODO: remove the default framebuffer? +func (c *context) dispose() { + // NOTE: Now this method is not used anywhere. idsInstance.deleteRenderTarget(c.screenId) } -// TODO: This interface is confusing: Can we change this? -func (c *Context) Update(drawer ui.Drawer) error { +func (c *context) Clear() { + c.Fill(0, 0, 0) +} + +func (c *context) Fill(r, g, b uint8) { + idsInstance.fillRenderTarget(c.currentId, r, g, b) +} + +func (c *context) Texture(id graphics.TextureID) graphics.Drawer { + return &textureWithContext{id, c} +} + +func (c *context) RenderTarget(id graphics.RenderTargetID) graphics.Drawer { + return &textureWithContext{idsInstance.toTexture(id), c} +} + +func (c *context) ResetOffscreen() { + c.currentId = c.screenId +} + +func (c *context) SetOffscreen(renderTargetId graphics.RenderTargetID) { + c.currentId = renderTargetId +} + +func (c *context) update(drawer ui.Drawer) error { c.ResetOffscreen() c.Clear() @@ -76,37 +110,13 @@ func (c *Context) Update(drawer ui.Drawer) error { geo.Scale(scale, scale) graphics.DrawWhole(c.RenderTarget(c.screenId), c.screenWidth, c.screenHeight, geo, matrix.ColorI()) - flush() + gl.Flush() return nil } -func (c *Context) Clear() { - c.Fill(0, 0, 0) -} - -func (c *Context) Fill(r, g, b uint8) { - idsInstance.fillRenderTarget(c.currentId, r, g, b) -} - -func (c *Context) Texture(id graphics.TextureID) graphics.Drawer { - return &textureWithContext{id, c} -} - -func (c *Context) RenderTarget(id graphics.RenderTargetID) graphics.Drawer { - return &textureWithContext{idsInstance.toTexture(id), c} -} - -func (c *Context) ResetOffscreen() { - c.currentId = c.screenId -} - -func (c *Context) SetOffscreen(renderTargetId graphics.RenderTargetID) { - c.currentId = renderTargetId -} - type textureWithContext struct { id graphics.TextureID - context *Context + context *context } func (t *textureWithContext) Draw(parts []graphics.TexturePart, geo matrix.Geometry, color matrix.Color) { diff --git a/graphics/opengl/ids.go b/graphics/opengl/ids.go index 18c8f0f68..2aeae3a04 100644 --- a/graphics/opengl/ids.go +++ b/graphics/opengl/ids.go @@ -11,8 +11,8 @@ import ( ) type ids struct { - textures map[graphics.TextureID]*Texture - renderTargets map[graphics.RenderTargetID]*RenderTarget + textures map[graphics.TextureID]*texture + renderTargets map[graphics.RenderTargetID]*renderTarget renderTargetToTexture map[graphics.RenderTargetID]graphics.TextureID lastId int currentRenderTargetId graphics.RenderTargetID @@ -20,8 +20,8 @@ type ids struct { } var idsInstance = &ids{ - textures: map[graphics.TextureID]*Texture{}, - renderTargets: map[graphics.RenderTargetID]*RenderTarget{}, + textures: map[graphics.TextureID]*texture{}, + renderTargets: map[graphics.RenderTargetID]*renderTarget{}, renderTargetToTexture: map[graphics.RenderTargetID]graphics.TextureID{}, currentRenderTargetId: -1, } @@ -34,13 +34,13 @@ func NewTextureID(img image.Image, filter graphics.Filter) (graphics.TextureID, return idsInstance.createTexture(img, filter) } -func (i *ids) textureAt(id graphics.TextureID) *Texture { +func (i *ids) textureAt(id graphics.TextureID) *texture { i.RLock() defer i.RUnlock() return i.textures[id] } -func (i *ids) renderTargetAt(id graphics.RenderTargetID) *RenderTarget { +func (i *ids) renderTargetAt(id graphics.RenderTargetID) *renderTarget { i.RLock() defer i.RUnlock() return i.renderTargets[id] @@ -74,7 +74,7 @@ func (i *ids) createRenderTarget(width, height int, filter graphics.Filter) (gra framebuffer := createFramebuffer(gl.Texture(texture.native)) // The current binded framebuffer can be changed. i.currentRenderTargetId = -1 - renderTarget := &RenderTarget{ + r := &renderTarget{ framebuffer: framebuffer, width: texture.width, height: texture.height, @@ -88,14 +88,14 @@ func (i *ids) createRenderTarget(width, height int, filter graphics.Filter) (gra renderTargetId := graphics.RenderTargetID(i.lastId) i.textures[textureId] = texture - i.renderTargets[renderTargetId] = renderTarget + i.renderTargets[renderTargetId] = r i.renderTargetToTexture[renderTargetId] = textureId return renderTargetId, nil } // NOTE: renderTarget can't be used as a texture. -func (i *ids) addRenderTarget(renderTarget *RenderTarget) graphics.RenderTargetID { +func (i *ids) addRenderTarget(renderTarget *renderTarget) graphics.RenderTargetID { i.Lock() defer i.Unlock() i.lastId++ diff --git a/graphics/opengl/rendertarget.go b/graphics/opengl/rendertarget.go index a8afe2449..e6afea804 100644 --- a/graphics/opengl/rendertarget.go +++ b/graphics/opengl/rendertarget.go @@ -20,7 +20,7 @@ func orthoProjectionMatrix(left, right, bottom, top int) [4][4]float64 { } } -type RenderTarget struct { +type renderTarget struct { framebuffer gl.Framebuffer width int height int @@ -45,7 +45,7 @@ func createFramebuffer(nativeTexture gl.Texture) gl.Framebuffer { return framebuffer } -func (r *RenderTarget) setAsViewport() { +func (r *renderTarget) setAsViewport() { gl.Flush() r.framebuffer.Bind() err := gl.CheckFramebufferStatus(gl.FRAMEBUFFER) @@ -60,7 +60,7 @@ func (r *RenderTarget) setAsViewport() { gl.Viewport(0, 0, width, height) } -func (r *RenderTarget) projectionMatrix() [4][4]float64 { +func (r *renderTarget) projectionMatrix() [4][4]float64 { width := shader.AdjustSizeForTexture(r.width) height := shader.AdjustSizeForTexture(r.height) matrix := orthoProjectionMatrix(0, width, 0, height) @@ -71,6 +71,6 @@ func (r *RenderTarget) projectionMatrix() [4][4]float64 { return matrix } -func (r *RenderTarget) dispose() { +func (r *renderTarget) dispose() { r.framebuffer.Delete() } diff --git a/graphics/opengl/texture.go b/graphics/opengl/texture.go index 0d26ac906..cde290f00 100644 --- a/graphics/opengl/texture.go +++ b/graphics/opengl/texture.go @@ -31,7 +31,7 @@ func adjustImageForTexture(img image.Image) *image.NRGBA { return adjustedImage } -type Texture struct { +type texture struct { native gl.Texture width int height int @@ -67,20 +67,20 @@ func createNativeTexture(textureWidth, textureHeight int, pixels []uint8, filter return nativeTexture } -func createTexture(width, height int, filter graphics.Filter) (*Texture, error) { +func createTexture(width, height int, filter graphics.Filter) (*texture, error) { w := shader.AdjustSizeForTexture(width) h := shader.AdjustSizeForTexture(height) native := createNativeTexture(w, h, nil, filter) - return &Texture{native, width, height}, nil + return &texture{native, width, height}, nil } -func createTextureFromImage(img image.Image, filter graphics.Filter) (*Texture, error) { +func createTextureFromImage(img image.Image, filter graphics.Filter) (*texture, error) { adjustedImage := adjustImageForTexture(img) size := adjustedImage.Bounds().Size() native := createNativeTexture(size.X, size.Y, adjustedImage.Pix, filter) - return &Texture{native, size.X, size.Y}, nil + return &texture{native, size.X, size.Y}, nil } -func (t *Texture) dispose() { +func (t *texture) dispose() { t.native.Delete() } diff --git a/ui/glfw/canvas.go b/ui/glfw/canvas.go index f368a6a53..987b218ee 100644 --- a/ui/glfw/canvas.go +++ b/ui/glfw/canvas.go @@ -11,11 +11,11 @@ import ( ) type canvas struct { - window *glfw.Window - context *opengl.Context - keyboard *keyboard - funcs chan func() - funcsDone chan struct{} + window *glfw.Window + contextUpdater *opengl.ContextUpdater + keyboard *keyboard + funcs chan func() + funcsDone chan struct{} } func newCanvas(width, height, scale int, title string) *canvas { @@ -39,14 +39,14 @@ func newCanvas(width, height, scale int, title string) *canvas { canvas.run() canvas.use(func() { - canvas.context = opengl.NewContext(width, height, realScale) + canvas.contextUpdater = opengl.NewContextUpdater(width, height, realScale) }) return canvas } func (c *canvas) Draw(d ui.Drawer) (err error) { c.use(func() { - err = c.context.Update(d) + err = c.contextUpdater.Update(d) c.window.SwapBuffers() }) return