mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 03:08:54 +01:00
Added grahpics/opengl
This commit is contained in:
parent
0ab7dca5e4
commit
493748ec9e
@ -3,19 +3,20 @@ package ebiten
|
|||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
"github.com/hajimehoshi/go-ebiten/graphics"
|
"github.com/hajimehoshi/go-ebiten/graphics"
|
||||||
|
"github.com/hajimehoshi/go-ebiten/graphics/opengl"
|
||||||
"github.com/hajimehoshi/go-ebiten/ui"
|
"github.com/hajimehoshi/go-ebiten/ui"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Game interface {
|
type Game interface {
|
||||||
Update()
|
Update()
|
||||||
Draw(g *graphics.GraphicsContext, offscreen *graphics.Texture)
|
Draw(g graphics.GraphicsContext, offscreen graphics.Texture)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Run(game Game, u ui.UI) {
|
func Run(game Game, u ui.UI) {
|
||||||
ch := make(chan bool, 1)
|
ch := make(chan bool, 1)
|
||||||
device := graphics.NewDevice(
|
device := opengl.NewDevice(
|
||||||
u.ScreenWidth(), u.ScreenHeight(), u.ScreenScale(),
|
u.ScreenWidth(), u.ScreenHeight(), u.ScreenScale(),
|
||||||
func(g *graphics.GraphicsContext, offscreen *graphics.Texture) {
|
func(g graphics.GraphicsContext, offscreen graphics.Texture) {
|
||||||
ticket := <-ch
|
ticket := <-ch
|
||||||
game.Draw(g, offscreen)
|
game.Draw(g, offscreen)
|
||||||
ch<- ticket
|
ch<- ticket
|
||||||
|
@ -28,7 +28,7 @@ type GlutUI struct{
|
|||||||
screenWidth int
|
screenWidth int
|
||||||
screenHeight int
|
screenHeight int
|
||||||
screenScale int
|
screenScale int
|
||||||
device *graphics.Device
|
device graphics.Device
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentUI *GlutUI
|
var currentUI *GlutUI
|
||||||
@ -85,13 +85,13 @@ func (ui *GlutUI) ScreenScale() int {
|
|||||||
return ui.screenScale
|
return ui.screenScale
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ui *GlutUI) Run(device *graphics.Device) {
|
func (ui *GlutUI) Run(device graphics.Device) {
|
||||||
ui.device = device
|
ui.device = device
|
||||||
C.glutMainLoop()
|
C.glutMainLoop()
|
||||||
}
|
}
|
||||||
|
|
||||||
type DemoGame struct {
|
type DemoGame struct {
|
||||||
ebitenTexture *graphics.Texture
|
ebitenTexture graphics.Texture
|
||||||
x int
|
x int
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,12 +108,13 @@ func (game *DemoGame) Update() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: It looks strange to get a texture from the device.
|
||||||
game.ebitenTexture = currentUI.device.NewTextureFromImage(img)
|
game.ebitenTexture = currentUI.device.NewTextureFromImage(img)
|
||||||
}
|
}
|
||||||
game.x++
|
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})
|
g.Fill(&color.RGBA{R: 128, G: 128, B: 255, A: 255})
|
||||||
if game.ebitenTexture == nil {
|
if game.ebitenTexture == nil {
|
||||||
return
|
return
|
||||||
@ -122,7 +123,7 @@ func (game *DemoGame) Draw(g *graphics.GraphicsContext, offscreen *graphics.Text
|
|||||||
geometryMatrix.SetTx(graphics.AffineMatrixElement(game.x))
|
geometryMatrix.SetTx(graphics.AffineMatrixElement(game.x))
|
||||||
geometryMatrix.SetTy(graphics.AffineMatrixElement(game.x))
|
geometryMatrix.SetTy(graphics.AffineMatrixElement(game.x))
|
||||||
g.DrawTexture(game.ebitenTexture,
|
g.DrawTexture(game.ebitenTexture,
|
||||||
0, 0, game.ebitenTexture.Width, game.ebitenTexture.Height,
|
0, 0, game.ebitenTexture.Width(), game.ebitenTexture.Height(),
|
||||||
geometryMatrix,
|
geometryMatrix,
|
||||||
graphics.IdentityColorMatrix())
|
graphics.IdentityColorMatrix())
|
||||||
}
|
}
|
||||||
|
29
graphics/graphics.go
Normal file
29
graphics/graphics.go
Normal 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
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package graphics
|
package opengl
|
||||||
|
|
||||||
// #cgo LDFLAGS: -framework OpenGL
|
// #cgo LDFLAGS: -framework OpenGL
|
||||||
//
|
//
|
||||||
@ -7,6 +7,7 @@ package graphics
|
|||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
"image"
|
"image"
|
||||||
|
"github.com/hajimehoshi/go-ebiten/graphics"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Device struct {
|
type Device struct {
|
||||||
@ -15,12 +16,12 @@ type Device struct {
|
|||||||
screenScale int
|
screenScale int
|
||||||
graphicsContext *GraphicsContext
|
graphicsContext *GraphicsContext
|
||||||
offscreenTexture *Texture
|
offscreenTexture *Texture
|
||||||
drawFunc func(*GraphicsContext, *Texture)
|
drawFunc func(graphics.GraphicsContext, graphics.Texture)
|
||||||
funcs []func()
|
funcs []func()
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDevice(screenWidth, screenHeight, screenScale int,
|
func NewDevice(screenWidth, screenHeight, screenScale int,
|
||||||
drawFunc func(*GraphicsContext, *Texture)) *Device {
|
drawFunc func(graphics.GraphicsContext, graphics.Texture)) *Device {
|
||||||
device := &Device{
|
device := &Device{
|
||||||
screenWidth: screenWidth,
|
screenWidth: screenWidth,
|
||||||
screenHeight: screenHeight,
|
screenHeight: screenHeight,
|
||||||
@ -29,7 +30,7 @@ func NewDevice(screenWidth, screenHeight, screenScale int,
|
|||||||
drawFunc: drawFunc,
|
drawFunc: drawFunc,
|
||||||
funcs: []func(){},
|
funcs: []func(){},
|
||||||
}
|
}
|
||||||
device.offscreenTexture = device.NewTexture(screenWidth, screenHeight)
|
device.offscreenTexture = device.NewTexture(screenWidth, screenHeight).(*Texture)
|
||||||
return device
|
return device
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,20 +53,20 @@ func (device *Device) Update() {
|
|||||||
C.glTexParameteri(C.GL_TEXTURE_2D, C.GL_TEXTURE_MAG_FILTER, C.GL_LINEAR)
|
C.glTexParameteri(C.GL_TEXTURE_2D, C.GL_TEXTURE_MAG_FILTER, C.GL_LINEAR)
|
||||||
g.resetOffscreen()
|
g.resetOffscreen()
|
||||||
g.Clear()
|
g.Clear()
|
||||||
geometryMatrix := IdentityGeometryMatrix()
|
geometryMatrix := graphics.IdentityGeometryMatrix()
|
||||||
geometryMatrix.SetA(AffineMatrixElement(g.screenScale))
|
geometryMatrix.SetA(graphics.AffineMatrixElement(g.screenScale))
|
||||||
geometryMatrix.SetD(AffineMatrixElement(g.screenScale))
|
geometryMatrix.SetD(graphics.AffineMatrixElement(g.screenScale))
|
||||||
g.DrawTexture(device.offscreenTexture,
|
g.DrawTexture(device.offscreenTexture,
|
||||||
0, 0, device.screenWidth, device.screenHeight,
|
0, 0, device.screenWidth, device.screenHeight,
|
||||||
geometryMatrix, IdentityColorMatrix())
|
geometryMatrix, graphics.IdentityColorMatrix())
|
||||||
g.flush()
|
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)
|
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
|
var pix []uint8
|
||||||
switch img.(type) {
|
switch img.(type) {
|
||||||
case *image.RGBA:
|
case *image.RGBA:
|
@ -1,4 +1,4 @@
|
|||||||
package graphics
|
package opengl
|
||||||
|
|
||||||
// #cgo LDFLAGS: -framework OpenGL
|
// #cgo LDFLAGS: -framework OpenGL
|
||||||
//
|
//
|
||||||
@ -9,6 +9,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"image/color"
|
"image/color"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
"github.com/hajimehoshi/go-ebiten/graphics"
|
||||||
)
|
)
|
||||||
|
|
||||||
type GraphicsContext struct {
|
type GraphicsContext struct {
|
||||||
@ -45,8 +46,8 @@ func (context *GraphicsContext) Clear() {
|
|||||||
C.glClear(C.GL_COLOR_BUFFER_BIT)
|
C.glClear(C.GL_COLOR_BUFFER_BIT)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (context *GraphicsContext) Fill(color color.Color) {
|
func (context *GraphicsContext) Fill(clr color.Color) {
|
||||||
r, g, b, a := color.RGBA()
|
r, g, b, a := clr.RGBA()
|
||||||
max := 65535.0
|
max := 65535.0
|
||||||
C.glClearColor(
|
C.glClearColor(
|
||||||
C.GLclampf(float64(r) / max),
|
C.GLclampf(float64(r) / max),
|
||||||
@ -56,16 +57,18 @@ func (context *GraphicsContext) Fill(color color.Color) {
|
|||||||
C.glClear(C.GL_COLOR_BUFFER_BIT)
|
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!
|
// TODO: implement!
|
||||||
}
|
}
|
||||||
|
|
||||||
func (context *GraphicsContext) DrawTexture(texture *Texture,
|
func (context *GraphicsContext) DrawTexture(tex graphics.Texture,
|
||||||
srcX, srcY, srcWidth, srcHeight int,
|
srcX, srcY, srcWidth, srcHeight int,
|
||||||
geometryMatrix *GeometryMatrix, colorMatrix *ColorMatrix) {
|
geometryMatrix *graphics.GeometryMatrix, colorMatrix *graphics.ColorMatrix) {
|
||||||
geometryMatrix = geometryMatrix.Clone()
|
geometryMatrix = geometryMatrix.Clone()
|
||||||
colorMatrix = colorMatrix.Clone()
|
colorMatrix = colorMatrix.Clone()
|
||||||
|
|
||||||
|
texture := tex.(*Texture)
|
||||||
|
|
||||||
context.setShaderProgram(geometryMatrix, colorMatrix)
|
context.setShaderProgram(geometryMatrix, colorMatrix)
|
||||||
C.glBindTexture(C.GL_TEXTURE_2D, texture.id)
|
C.glBindTexture(C.GL_TEXTURE_2D, texture.id)
|
||||||
|
|
||||||
@ -80,10 +83,10 @@ func (context *GraphicsContext) DrawTexture(texture *Texture,
|
|||||||
x2, y2,
|
x2, y2,
|
||||||
}
|
}
|
||||||
|
|
||||||
tu1 := float32(srcX) / float32(texture.TextureWidth)
|
tu1 := float32(srcX) / float32(texture.textureWidth)
|
||||||
tu2 := float32(srcX + srcWidth) / float32(texture.TextureWidth)
|
tu2 := float32(srcX + srcWidth) / float32(texture.textureWidth)
|
||||||
tv1 := float32(srcY) / float32(texture.TextureHeight)
|
tv1 := float32(srcY) / float32(texture.textureHeight)
|
||||||
tv2 := float32(srcY + srcHeight) / float32(texture.TextureHeight)
|
tv2 := float32(srcY + srcHeight) / float32(texture.textureHeight)
|
||||||
texCoord := [...]float32{
|
texCoord := [...]float32{
|
||||||
tu1, tv1,
|
tu1, tv1,
|
||||||
tu2, tv1,
|
tu2, tv1,
|
||||||
@ -116,7 +119,12 @@ func abs(x int) int {
|
|||||||
return x
|
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)
|
framebuffer := C.GLuint(0)
|
||||||
if texture != nil {
|
if texture != nil {
|
||||||
framebuffer = context.getFramebuffer(texture)
|
framebuffer = context.getFramebuffer(texture)
|
||||||
@ -135,8 +143,8 @@ func (context *GraphicsContext) SetOffscreen(texture *Texture) {
|
|||||||
|
|
||||||
width, height, tx, ty := 0, 0, 0, 0
|
width, height, tx, ty := 0, 0, 0, 0
|
||||||
if framebuffer != context.mainFramebuffer {
|
if framebuffer != context.mainFramebuffer {
|
||||||
width = texture.TextureWidth
|
width = texture.textureWidth
|
||||||
height = texture.TextureHeight
|
height = texture.textureHeight
|
||||||
tx = -1
|
tx = -1
|
||||||
ty = -1
|
ty = -1
|
||||||
} else {
|
} else {
|
||||||
@ -169,7 +177,7 @@ func (context *GraphicsContext) flush() {
|
|||||||
|
|
||||||
// This method should be called on the UI thread.
|
// This method should be called on the UI thread.
|
||||||
func (context *GraphicsContext) setShaderProgram(
|
func (context *GraphicsContext) setShaderProgram(
|
||||||
geometryMatrix *GeometryMatrix, colorMatrix *ColorMatrix) {
|
geometryMatrix *graphics.GeometryMatrix, colorMatrix *graphics.ColorMatrix) {
|
||||||
program := C.GLuint(0)
|
program := C.GLuint(0)
|
||||||
if colorMatrix.IsIdentity() {
|
if colorMatrix.IsIdentity() {
|
||||||
program = regularShaderProgram
|
program = regularShaderProgram
|
@ -1,4 +1,4 @@
|
|||||||
package graphics
|
package opengl
|
||||||
|
|
||||||
// #cgo LDFLAGS: -framework OpenGL
|
// #cgo LDFLAGS: -framework OpenGL
|
||||||
//
|
//
|
@ -1,4 +1,4 @@
|
|||||||
package graphics
|
package opengl
|
||||||
|
|
||||||
// #cgo LDFLAGS: -framework OpenGL
|
// #cgo LDFLAGS: -framework OpenGL
|
||||||
//
|
//
|
||||||
@ -21,10 +21,10 @@ func Clp2(x uint64) uint64 {
|
|||||||
|
|
||||||
type Texture struct {
|
type Texture struct {
|
||||||
id C.GLuint
|
id C.GLuint
|
||||||
Width int
|
width int
|
||||||
Height int
|
height int
|
||||||
TextureWidth int
|
textureWidth int
|
||||||
TextureHeight int
|
textureHeight int
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTexture(device *Device, width, height int, pixels []uint8) *Texture{
|
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{
|
texture := &Texture{
|
||||||
id: 0,
|
id: 0,
|
||||||
Width: width,
|
width: width,
|
||||||
Height: height,
|
height: height,
|
||||||
TextureWidth: textureWidth,
|
textureWidth: textureWidth,
|
||||||
TextureHeight: textureHeight,
|
textureHeight: textureHeight,
|
||||||
}
|
}
|
||||||
|
|
||||||
device.executeWhenDrawing(func() {
|
device.executeWhenDrawing(func() {
|
||||||
@ -74,6 +74,22 @@ func createTexture(device *Device, width, height int, pixels []uint8) *Texture{
|
|||||||
return 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 {
|
func (texture *Texture) IsAvailable() bool {
|
||||||
return texture.id != 0
|
return texture.id != 0
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package graphics_test
|
package opengl_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
Loading…
Reference in New Issue
Block a user