Added grahpics/opengl

This commit is contained in:
Hajime Hoshi 2013-06-19 08:49:54 +09:00
parent 0ab7dca5e4
commit 493748ec9e
9 changed files with 100 additions and 44 deletions

View File

@ -3,19 +3,20 @@ package ebiten
import (
"time"
"github.com/hajimehoshi/go-ebiten/graphics"
"github.com/hajimehoshi/go-ebiten/graphics/opengl"
"github.com/hajimehoshi/go-ebiten/ui"
)
type Game interface {
Update()
Draw(g *graphics.GraphicsContext, offscreen *graphics.Texture)
Draw(g graphics.GraphicsContext, offscreen graphics.Texture)
}
func Run(game Game, u ui.UI) {
ch := make(chan bool, 1)
device := graphics.NewDevice(
device := opengl.NewDevice(
u.ScreenWidth(), u.ScreenHeight(), u.ScreenScale(),
func(g *graphics.GraphicsContext, offscreen *graphics.Texture) {
func(g graphics.GraphicsContext, offscreen graphics.Texture) {
ticket := <-ch
game.Draw(g, offscreen)
ch<- ticket

View File

@ -28,7 +28,7 @@ type GlutUI struct{
screenWidth int
screenHeight int
screenScale int
device *graphics.Device
device graphics.Device
}
var currentUI *GlutUI
@ -85,13 +85,13 @@ func (ui *GlutUI) ScreenScale() int {
return ui.screenScale
}
func (ui *GlutUI) Run(device *graphics.Device) {
func (ui *GlutUI) Run(device graphics.Device) {
ui.device = device
C.glutMainLoop()
}
type DemoGame struct {
ebitenTexture *graphics.Texture
ebitenTexture graphics.Texture
x int
}
@ -108,12 +108,13 @@ func (game *DemoGame) Update() {
panic(err)
}
// TODO: It looks strange to get a texture from the device.
game.ebitenTexture = currentUI.device.NewTextureFromImage(img)
}
game.x++
}
func (game *DemoGame) Draw(g *graphics.GraphicsContext, offscreen *graphics.Texture) {
func (game *DemoGame) Draw(g graphics.GraphicsContext, offscreen graphics.Texture) {
g.Fill(&color.RGBA{R: 128, G: 128, B: 255, A: 255})
if game.ebitenTexture == nil {
return
@ -122,7 +123,7 @@ func (game *DemoGame) Draw(g *graphics.GraphicsContext, offscreen *graphics.Text
geometryMatrix.SetTx(graphics.AffineMatrixElement(game.x))
geometryMatrix.SetTy(graphics.AffineMatrixElement(game.x))
g.DrawTexture(game.ebitenTexture,
0, 0, game.ebitenTexture.Width, game.ebitenTexture.Height,
0, 0, game.ebitenTexture.Width(), game.ebitenTexture.Height(),
geometryMatrix,
graphics.IdentityColorMatrix())
}

29
graphics/graphics.go Normal file
View File

@ -0,0 +1,29 @@
package graphics
import (
"image"
"image/color"
)
type Device interface {
Update()
// TODO: Move somewhere
NewTexture(width, height int) Texture
NewTextureFromImage(img image.Image) Texture
}
type GraphicsContext interface {
Clear()
Fill(color color.Color)
DrawTexture(texture Texture,
srcX, srcY, srcWidth, srcHeight int,
geometryMatrix *GeometryMatrix, colorMatrix *ColorMatrix)
SetOffscreen(texture Texture)
}
type Texture interface {
Width() int
Height() int
TextureWidth() int
TextureHeight() int
}

View File

@ -1,4 +1,4 @@
package graphics
package opengl
// #cgo LDFLAGS: -framework OpenGL
//
@ -7,6 +7,7 @@ package graphics
import "C"
import (
"image"
"github.com/hajimehoshi/go-ebiten/graphics"
)
type Device struct {
@ -15,12 +16,12 @@ type Device struct {
screenScale int
graphicsContext *GraphicsContext
offscreenTexture *Texture
drawFunc func(*GraphicsContext, *Texture)
drawFunc func(graphics.GraphicsContext, graphics.Texture)
funcs []func()
}
func NewDevice(screenWidth, screenHeight, screenScale int,
drawFunc func(*GraphicsContext, *Texture)) *Device {
drawFunc func(graphics.GraphicsContext, graphics.Texture)) *Device {
device := &Device{
screenWidth: screenWidth,
screenHeight: screenHeight,
@ -29,7 +30,7 @@ func NewDevice(screenWidth, screenHeight, screenScale int,
drawFunc: drawFunc,
funcs: []func(){},
}
device.offscreenTexture = device.NewTexture(screenWidth, screenHeight)
device.offscreenTexture = device.NewTexture(screenWidth, screenHeight).(*Texture)
return device
}
@ -52,20 +53,20 @@ func (device *Device) Update() {
C.glTexParameteri(C.GL_TEXTURE_2D, C.GL_TEXTURE_MAG_FILTER, C.GL_LINEAR)
g.resetOffscreen()
g.Clear()
geometryMatrix := IdentityGeometryMatrix()
geometryMatrix.SetA(AffineMatrixElement(g.screenScale))
geometryMatrix.SetD(AffineMatrixElement(g.screenScale))
geometryMatrix := graphics.IdentityGeometryMatrix()
geometryMatrix.SetA(graphics.AffineMatrixElement(g.screenScale))
geometryMatrix.SetD(graphics.AffineMatrixElement(g.screenScale))
g.DrawTexture(device.offscreenTexture,
0, 0, device.screenWidth, device.screenHeight,
geometryMatrix, IdentityColorMatrix())
geometryMatrix, graphics.IdentityColorMatrix())
g.flush()
}
func (device *Device) NewTexture(width, height int) *Texture {
func (device *Device) NewTexture(width, height int) graphics.Texture {
return createTexture(device, width, height, nil)
}
func (device *Device) NewTextureFromImage(img image.Image) *Texture {
func (device *Device) NewTextureFromImage(img image.Image) graphics.Texture {
var pix []uint8
switch img.(type) {
case *image.RGBA:

View File

@ -1,4 +1,4 @@
package graphics
package opengl
// #cgo LDFLAGS: -framework OpenGL
//
@ -9,6 +9,7 @@ import (
"fmt"
"image/color"
"unsafe"
"github.com/hajimehoshi/go-ebiten/graphics"
)
type GraphicsContext struct {
@ -45,8 +46,8 @@ func (context *GraphicsContext) Clear() {
C.glClear(C.GL_COLOR_BUFFER_BIT)
}
func (context *GraphicsContext) Fill(color color.Color) {
r, g, b, a := color.RGBA()
func (context *GraphicsContext) Fill(clr color.Color) {
r, g, b, a := clr.RGBA()
max := 65535.0
C.glClearColor(
C.GLclampf(float64(r) / max),
@ -56,16 +57,18 @@ func (context *GraphicsContext) Fill(color color.Color) {
C.glClear(C.GL_COLOR_BUFFER_BIT)
}
func (context *GraphicsContext) DrawRect(x, y, width, height int, color color.Color) {
func (context *GraphicsContext) DrawRect(x, y, width, height int, clr color.Color) {
// TODO: implement!
}
func (context *GraphicsContext) DrawTexture(texture *Texture,
func (context *GraphicsContext) DrawTexture(tex graphics.Texture,
srcX, srcY, srcWidth, srcHeight int,
geometryMatrix *GeometryMatrix, colorMatrix *ColorMatrix) {
geometryMatrix *graphics.GeometryMatrix, colorMatrix *graphics.ColorMatrix) {
geometryMatrix = geometryMatrix.Clone()
colorMatrix = colorMatrix.Clone()
texture := tex.(*Texture)
context.setShaderProgram(geometryMatrix, colorMatrix)
C.glBindTexture(C.GL_TEXTURE_2D, texture.id)
@ -80,10 +83,10 @@ func (context *GraphicsContext) DrawTexture(texture *Texture,
x2, y2,
}
tu1 := float32(srcX) / float32(texture.TextureWidth)
tu2 := float32(srcX + srcWidth) / float32(texture.TextureWidth)
tv1 := float32(srcY) / float32(texture.TextureHeight)
tv2 := float32(srcY + srcHeight) / float32(texture.TextureHeight)
tu1 := float32(srcX) / float32(texture.textureWidth)
tu2 := float32(srcX + srcWidth) / float32(texture.textureWidth)
tv1 := float32(srcY) / float32(texture.textureHeight)
tv2 := float32(srcY + srcHeight) / float32(texture.textureHeight)
texCoord := [...]float32{
tu1, tv1,
tu2, tv1,
@ -116,7 +119,12 @@ func abs(x int) int {
return x
}
func (context *GraphicsContext) SetOffscreen(texture *Texture) {
func (context *GraphicsContext) SetOffscreen(tex graphics.Texture) {
var texture *Texture = nil
if tex != nil {
texture = tex.(*Texture)
}
// TODO: glFlush() here?
framebuffer := C.GLuint(0)
if texture != nil {
framebuffer = context.getFramebuffer(texture)
@ -135,8 +143,8 @@ func (context *GraphicsContext) SetOffscreen(texture *Texture) {
width, height, tx, ty := 0, 0, 0, 0
if framebuffer != context.mainFramebuffer {
width = texture.TextureWidth
height = texture.TextureHeight
width = texture.textureWidth
height = texture.textureHeight
tx = -1
ty = -1
} else {
@ -169,7 +177,7 @@ func (context *GraphicsContext) flush() {
// This method should be called on the UI thread.
func (context *GraphicsContext) setShaderProgram(
geometryMatrix *GeometryMatrix, colorMatrix *ColorMatrix) {
geometryMatrix *graphics.GeometryMatrix, colorMatrix *graphics.ColorMatrix) {
program := C.GLuint(0)
if colorMatrix.IsIdentity() {
program = regularShaderProgram

View File

@ -1,4 +1,4 @@
package graphics
package opengl
// #cgo LDFLAGS: -framework OpenGL
//

View File

@ -1,4 +1,4 @@
package graphics
package opengl
// #cgo LDFLAGS: -framework OpenGL
//
@ -21,10 +21,10 @@ func Clp2(x uint64) uint64 {
type Texture struct {
id C.GLuint
Width int
Height int
TextureWidth int
TextureHeight int
width int
height int
textureWidth int
textureHeight int
}
func createTexture(device *Device, width, height int, pixels []uint8) *Texture{
@ -40,10 +40,10 @@ func createTexture(device *Device, width, height int, pixels []uint8) *Texture{
}
texture := &Texture{
id: 0,
Width: width,
Height: height,
TextureWidth: textureWidth,
TextureHeight: textureHeight,
width: width,
height: height,
textureWidth: textureWidth,
textureHeight: textureHeight,
}
device.executeWhenDrawing(func() {
@ -74,6 +74,22 @@ func createTexture(device *Device, width, height int, pixels []uint8) *Texture{
return texture
}
func (texture *Texture) Width() int {
return texture.width
}
func (texture *Texture) Height() int {
return texture.height
}
func (texture *Texture) TextureWidth() int {
return texture.textureWidth
}
func (texture *Texture) TextureHeight() int {
return texture.textureHeight
}
func (texture *Texture) IsAvailable() bool {
return texture.id != 0
}

View File

@ -1,4 +1,4 @@
package graphics_test
package opengl_test
import (
"testing"

View File

@ -8,5 +8,5 @@ type UI interface {
ScreenWidth() int
ScreenHeight() int
ScreenScale() int
Run(device *graphics.Device)
Run(device graphics.Device)
}