mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-27 11:12:44 +01:00
Refactoring
This commit is contained in:
parent
562d04cacc
commit
f0356748be
@ -4,6 +4,19 @@ import (
|
|||||||
"github.com/hajimehoshi/go-ebiten/graphics/matrix"
|
"github.com/hajimehoshi/go-ebiten/graphics/matrix"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Rect struct {
|
||||||
|
X int
|
||||||
|
Y int
|
||||||
|
Width int
|
||||||
|
Height int
|
||||||
|
}
|
||||||
|
|
||||||
|
type TexturePart struct {
|
||||||
|
LocationX int
|
||||||
|
LocationY int
|
||||||
|
Source Rect
|
||||||
|
}
|
||||||
|
|
||||||
type Drawer interface {
|
type Drawer interface {
|
||||||
Draw(geometryMatrix matrix.Geometry,
|
Draw(geometryMatrix matrix.Geometry,
|
||||||
colorMatrix matrix.Color)
|
colorMatrix matrix.Color)
|
||||||
|
@ -1,31 +1,5 @@
|
|||||||
package graphics
|
package graphics
|
||||||
|
|
||||||
type Rect struct {
|
|
||||||
X int
|
|
||||||
Y int
|
|
||||||
Width int
|
|
||||||
Height int
|
|
||||||
}
|
|
||||||
|
|
||||||
type TexturePart struct {
|
|
||||||
LocationX int
|
|
||||||
LocationY int
|
|
||||||
Source Rect
|
|
||||||
}
|
|
||||||
|
|
||||||
type Filter int
|
|
||||||
|
|
||||||
const (
|
|
||||||
FilterNearest Filter = iota
|
|
||||||
FilterLinear
|
|
||||||
)
|
|
||||||
|
|
||||||
type TextureId int
|
|
||||||
|
|
||||||
// A render target is essentially same as a texture, but it is assumed that the
|
|
||||||
// all alpha of a render target is maximum.
|
|
||||||
type RenderTargetId int
|
|
||||||
|
|
||||||
func OrthoProjectionMatrix(left, right, bottom, top int) [4][4]float64 {
|
func OrthoProjectionMatrix(left, right, bottom, top int) [4][4]float64 {
|
||||||
e11 := float64(2) / float64(right-left)
|
e11 := float64(2) / float64(right-left)
|
||||||
e22 := float64(2) / float64(top-bottom)
|
e22 := float64(2) / float64(top-bottom)
|
||||||
|
@ -21,10 +21,10 @@ func newContext(ids *ids, screenWidth, screenHeight, screenScale int) *Context {
|
|||||||
mainRenderTarget := newRTWithCurrentFramebuffer(
|
mainRenderTarget := newRTWithCurrentFramebuffer(
|
||||||
screenWidth*screenScale,
|
screenWidth*screenScale,
|
||||||
screenHeight*screenScale)
|
screenHeight*screenScale)
|
||||||
context.mainId = context.ids.AddRenderTarget(mainRenderTarget)
|
context.mainId = context.ids.addRenderTarget(mainRenderTarget)
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
context.screenId, err = ids.CreateRenderTarget(
|
context.screenId, err = ids.createRenderTarget(
|
||||||
screenWidth, screenHeight, graphics.FilterNearest)
|
screenWidth, screenHeight, graphics.FilterNearest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("initializing the offscreen failed: " + err.Error())
|
panic("initializing the offscreen failed: " + err.Error())
|
||||||
@ -39,7 +39,7 @@ func newContext(ids *ids, screenWidth, screenHeight, screenScale int) *Context {
|
|||||||
|
|
||||||
func (context *Context) Dispose() {
|
func (context *Context) Dispose() {
|
||||||
// TODO: remove main framebuffer?
|
// TODO: remove main framebuffer?
|
||||||
context.ids.DeleteRenderTarget(context.screenId)
|
context.ids.deleteRenderTarget(context.screenId)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (context *Context) Update(draw func(graphics.Context)) {
|
func (context *Context) Update(draw func(graphics.Context)) {
|
||||||
@ -54,7 +54,8 @@ func (context *Context) Update(draw func(graphics.Context)) {
|
|||||||
scale := float64(context.screenScale)
|
scale := float64(context.screenScale)
|
||||||
geometryMatrix := matrix.IdentityGeometry()
|
geometryMatrix := matrix.IdentityGeometry()
|
||||||
geometryMatrix.Scale(scale, scale)
|
geometryMatrix.Scale(scale, scale)
|
||||||
context.RenderTarget(context.screenId).Draw(geometryMatrix, matrix.IdentityColor())
|
context.RenderTarget(context.screenId).Draw(
|
||||||
|
geometryMatrix, matrix.IdentityColor())
|
||||||
|
|
||||||
flush()
|
flush()
|
||||||
}
|
}
|
||||||
@ -64,7 +65,7 @@ func (c *Context) Clear() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) Fill(r, g, b uint8) {
|
func (c *Context) Fill(r, g, b uint8) {
|
||||||
c.ids.FillRenderTarget(c.currentId, r, g, b)
|
c.ids.fillRenderTarget(c.currentId, r, g, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) Texture(id graphics.TextureId) graphics.Drawer {
|
func (c *Context) Texture(id graphics.TextureId) graphics.Drawer {
|
||||||
@ -72,7 +73,7 @@ func (c *Context) Texture(id graphics.TextureId) graphics.Drawer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) RenderTarget(id graphics.RenderTargetId) graphics.Drawer {
|
func (c *Context) RenderTarget(id graphics.RenderTargetId) graphics.Drawer {
|
||||||
return &RenderTargetWithContext{id, c}
|
return &TextureWithContext{c.ids.toTexture(id), c}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (context *Context) ResetOffscreen() {
|
func (context *Context) ResetOffscreen() {
|
||||||
@ -89,22 +90,12 @@ type TextureWithContext struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *TextureWithContext) Draw(geo matrix.Geometry, color matrix.Color) {
|
func (t *TextureWithContext) Draw(geo matrix.Geometry, color matrix.Color) {
|
||||||
t.context.ids.DrawTexture(t.context.currentId, t.id, geo, color)
|
t.context.ids.drawTexture(t.context.currentId, t.id, geo, color)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TextureWithContext) DrawParts(parts []graphics.TexturePart, geo matrix.Geometry, color matrix.Color) {
|
func (t *TextureWithContext) DrawParts(
|
||||||
t.context.ids.DrawTextureParts(t.context.currentId, t.id, parts, geo, color)
|
parts []graphics.TexturePart,
|
||||||
}
|
geo matrix.Geometry,
|
||||||
|
color matrix.Color) {
|
||||||
type RenderTargetWithContext struct {
|
t.context.ids.drawTextureParts(t.context.currentId, t.id, parts, geo, color)
|
||||||
id graphics.RenderTargetId
|
|
||||||
context *Context
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *RenderTargetWithContext) Draw(geo matrix.Geometry, color matrix.Color) {
|
|
||||||
r.context.ids.DrawRenderTarget(r.context.currentId, r.id, geo, color)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *RenderTargetWithContext) DrawParts(parts []graphics.TexturePart, geo matrix.Geometry, color matrix.Color) {
|
|
||||||
r.context.ids.DrawRenderTargetParts(r.context.currentId, r.id, parts, geo, color)
|
|
||||||
}
|
}
|
||||||
|
@ -7,12 +7,31 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var idsInstance *ids = newIds()
|
||||||
|
|
||||||
|
func CreateContext(
|
||||||
|
screenWidth, screenHeight, screenScale int) *Context {
|
||||||
|
return newContext(idsInstance, screenWidth, screenHeight, screenScale)
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateRenderTarget(
|
||||||
|
width, height int,
|
||||||
|
filter graphics.Filter) (graphics.RenderTargetId, error) {
|
||||||
|
return idsInstance.createRenderTarget(width, height, filter)
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateTexture(
|
||||||
|
img image.Image,
|
||||||
|
filter graphics.Filter) (graphics.TextureId, error) {
|
||||||
|
return idsInstance.createTexture(img, filter)
|
||||||
|
}
|
||||||
|
|
||||||
type ids struct {
|
type ids struct {
|
||||||
lock sync.RWMutex
|
|
||||||
textures map[graphics.TextureId]*Texture
|
textures map[graphics.TextureId]*Texture
|
||||||
renderTargets map[graphics.RenderTargetId]*RenderTarget
|
renderTargets map[graphics.RenderTargetId]*RenderTarget
|
||||||
renderTargetToTexture map[graphics.RenderTargetId]graphics.TextureId
|
renderTargetToTexture map[graphics.RenderTargetId]graphics.TextureId
|
||||||
counts chan int
|
counts chan int
|
||||||
|
sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func newIds() *ids {
|
func newIds() *ids {
|
||||||
@ -31,24 +50,24 @@ func newIds() *ids {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *ids) textureAt(id graphics.TextureId) *Texture {
|
func (i *ids) textureAt(id graphics.TextureId) *Texture {
|
||||||
i.lock.RLock()
|
i.RLock()
|
||||||
defer i.lock.RUnlock()
|
defer i.RUnlock()
|
||||||
return i.textures[id]
|
return i.textures[id]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ids) renderTargetAt(id graphics.RenderTargetId) *RenderTarget {
|
func (i *ids) renderTargetAt(id graphics.RenderTargetId) *RenderTarget {
|
||||||
i.lock.RLock()
|
i.RLock()
|
||||||
defer i.lock.RUnlock()
|
defer i.RUnlock()
|
||||||
return i.renderTargets[id]
|
return i.renderTargets[id]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ids) toTexture(id graphics.RenderTargetId) graphics.TextureId {
|
func (i *ids) toTexture(id graphics.RenderTargetId) graphics.TextureId {
|
||||||
i.lock.RLock()
|
i.RLock()
|
||||||
defer i.lock.RUnlock()
|
defer i.RUnlock()
|
||||||
return i.renderTargetToTexture[id]
|
return i.renderTargetToTexture[id]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ids) CreateTexture(img image.Image, filter graphics.Filter) (
|
func (i *ids) createTexture(img image.Image, filter graphics.Filter) (
|
||||||
graphics.TextureId, error) {
|
graphics.TextureId, error) {
|
||||||
texture, err := createTextureFromImage(img, filter)
|
texture, err := createTextureFromImage(img, filter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -56,13 +75,13 @@ func (i *ids) CreateTexture(img image.Image, filter graphics.Filter) (
|
|||||||
}
|
}
|
||||||
textureId := graphics.TextureId(<-i.counts)
|
textureId := graphics.TextureId(<-i.counts)
|
||||||
|
|
||||||
i.lock.Lock()
|
i.Lock()
|
||||||
defer i.lock.Unlock()
|
defer i.Unlock()
|
||||||
i.textures[textureId] = texture
|
i.textures[textureId] = texture
|
||||||
return textureId, nil
|
return textureId, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ids) CreateRenderTarget(width, height int, filter graphics.Filter) (
|
func (i *ids) createRenderTarget(width, height int, filter graphics.Filter) (
|
||||||
graphics.RenderTargetId, error) {
|
graphics.RenderTargetId, error) {
|
||||||
|
|
||||||
texture, err := createTexture(width, height, filter)
|
texture, err := createTexture(width, height, filter)
|
||||||
@ -75,8 +94,8 @@ func (i *ids) CreateRenderTarget(width, height int, filter graphics.Filter) (
|
|||||||
textureId := graphics.TextureId(<-i.counts)
|
textureId := graphics.TextureId(<-i.counts)
|
||||||
renderTargetId := graphics.RenderTargetId(<-i.counts)
|
renderTargetId := graphics.RenderTargetId(<-i.counts)
|
||||||
|
|
||||||
i.lock.Lock()
|
i.Lock()
|
||||||
defer i.lock.Unlock()
|
defer i.Unlock()
|
||||||
i.textures[textureId] = texture
|
i.textures[textureId] = texture
|
||||||
i.renderTargets[renderTargetId] = renderTarget
|
i.renderTargets[renderTargetId] = renderTarget
|
||||||
i.renderTargetToTexture[renderTargetId] = textureId
|
i.renderTargetToTexture[renderTargetId] = textureId
|
||||||
@ -85,54 +104,52 @@ func (i *ids) CreateRenderTarget(width, height int, filter graphics.Filter) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: renderTarget can't be used as a texture.
|
// 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 {
|
||||||
id := graphics.RenderTargetId(<-i.counts)
|
id := graphics.RenderTargetId(<-i.counts)
|
||||||
|
|
||||||
i.lock.Lock()
|
i.Lock()
|
||||||
defer i.lock.Unlock()
|
defer i.Unlock()
|
||||||
i.renderTargets[id] = renderTarget
|
i.renderTargets[id] = renderTarget
|
||||||
|
|
||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ids) DeleteRenderTarget(id graphics.RenderTargetId) {
|
func (i *ids) deleteRenderTarget(id graphics.RenderTargetId) {
|
||||||
i.lock.Lock()
|
i.Lock()
|
||||||
defer i.lock.Unlock()
|
defer i.Unlock()
|
||||||
|
|
||||||
renderTarget := i.renderTargets[id]
|
renderTarget := i.renderTargets[id]
|
||||||
textureId := i.renderTargetToTexture[id]
|
textureId := i.renderTargetToTexture[id]
|
||||||
texture := i.textures[textureId]
|
texture := i.textures[textureId]
|
||||||
|
|
||||||
renderTarget.Dispose()
|
renderTarget.dispose()
|
||||||
texture.Dispose()
|
texture.dispose()
|
||||||
|
|
||||||
delete(i.renderTargets, id)
|
delete(i.renderTargets, id)
|
||||||
delete(i.renderTargetToTexture, id)
|
delete(i.renderTargetToTexture, id)
|
||||||
delete(i.textures, textureId)
|
delete(i.textures, textureId)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ids) FillRenderTarget(id graphics.RenderTargetId, r, g, b uint8) {
|
func (i *ids) fillRenderTarget(id graphics.RenderTargetId, r, g, b uint8) {
|
||||||
i.renderTargetAt(id).Fill(r, g, b)
|
i.renderTargetAt(id).fill(r, g, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ids) DrawTexture(target graphics.RenderTargetId, id graphics.TextureId,
|
func (i *ids) drawTexture(
|
||||||
geo matrix.Geometry, color matrix.Color) {
|
target graphics.RenderTargetId,
|
||||||
|
id graphics.TextureId,
|
||||||
|
geo matrix.Geometry,
|
||||||
|
color matrix.Color) {
|
||||||
texture := i.textureAt(id)
|
texture := i.textureAt(id)
|
||||||
i.renderTargetAt(target).DrawTexture(texture, geo, color)
|
parts := []graphics.TexturePart{
|
||||||
|
{0, 0, graphics.Rect{0, 0, texture.width, texture.height}},
|
||||||
|
}
|
||||||
|
i.renderTargetAt(target).drawTexture(texture, parts, geo, color)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ids) DrawTextureParts(target graphics.RenderTargetId, id graphics.TextureId,
|
func (i *ids) drawTextureParts(
|
||||||
|
target graphics.RenderTargetId,
|
||||||
|
id graphics.TextureId,
|
||||||
parts []graphics.TexturePart, geo matrix.Geometry, color matrix.Color) {
|
parts []graphics.TexturePart, geo matrix.Geometry, color matrix.Color) {
|
||||||
texture := i.textureAt(id)
|
texture := i.textureAt(id)
|
||||||
i.renderTargetAt(target).DrawTextureParts(texture, parts, geo, color)
|
i.renderTargetAt(target).drawTexture(texture, parts, geo, color)
|
||||||
}
|
|
||||||
|
|
||||||
func (i *ids) DrawRenderTarget(target graphics.RenderTargetId, id graphics.RenderTargetId,
|
|
||||||
geo matrix.Geometry, color matrix.Color) {
|
|
||||||
i.DrawTexture(target, i.toTexture(id), geo, color)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *ids) DrawRenderTargetParts(target graphics.RenderTargetId, id graphics.RenderTargetId,
|
|
||||||
parts []graphics.TexturePart, geo matrix.Geometry, color matrix.Color) {
|
|
||||||
i.DrawTextureParts(target, i.toTexture(id), parts, geo, color)
|
|
||||||
}
|
}
|
||||||
|
@ -8,9 +8,20 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"github.com/hajimehoshi/go-ebiten/graphics"
|
"github.com/hajimehoshi/go-ebiten/graphics"
|
||||||
"github.com/hajimehoshi/go-ebiten/graphics/matrix"
|
"github.com/hajimehoshi/go-ebiten/graphics/matrix"
|
||||||
|
"github.com/hajimehoshi/go-ebiten/graphics/opengl/shader"
|
||||||
"math"
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func glMatrix(matrix [4][4]float64) [16]float32 {
|
||||||
|
result := [16]float32{}
|
||||||
|
for j := 0; j < 4; j++ {
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
result[i+j*4] = float32(matrix[i][j])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
type RenderTarget struct {
|
type RenderTarget struct {
|
||||||
framebuffer C.GLuint
|
framebuffer C.GLuint
|
||||||
width int
|
width int
|
||||||
@ -84,11 +95,11 @@ func (r *RenderTarget) projectionMatrix() [4][4]float64 {
|
|||||||
return matrix
|
return matrix
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RenderTarget) Dispose() {
|
func (r *RenderTarget) dispose() {
|
||||||
C.glDeleteFramebuffers(1, &r.framebuffer)
|
C.glDeleteFramebuffers(1, &r.framebuffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RenderTarget) Fill(red, green, blue uint8) {
|
func (r *RenderTarget) fill(red, green, blue uint8) {
|
||||||
r.setAsViewport()
|
r.setAsViewport()
|
||||||
const max = float64(math.MaxUint8)
|
const max = float64(math.MaxUint8)
|
||||||
C.glClearColor(
|
C.glClearColor(
|
||||||
@ -99,17 +110,18 @@ func (r *RenderTarget) Fill(red, green, blue uint8) {
|
|||||||
C.glClear(C.GL_COLOR_BUFFER_BIT)
|
C.glClear(C.GL_COLOR_BUFFER_BIT)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RenderTarget) DrawTexture(texture *Texture,
|
func (r *RenderTarget) drawTexture(
|
||||||
geometryMatrix matrix.Geometry, colorMatrix matrix.Color) {
|
texture *Texture,
|
||||||
r.setAsViewport()
|
|
||||||
projectionMatrix := r.projectionMatrix()
|
|
||||||
texture.Draw(projectionMatrix, geometryMatrix, colorMatrix)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *RenderTarget) DrawTextureParts(texture *Texture,
|
|
||||||
parts []graphics.TexturePart,
|
parts []graphics.TexturePart,
|
||||||
geometryMatrix matrix.Geometry, colorMatrix matrix.Color) {
|
geometryMatrix matrix.Geometry,
|
||||||
|
colorMatrix matrix.Color) {
|
||||||
r.setAsViewport()
|
r.setAsViewport()
|
||||||
projectionMatrix := r.projectionMatrix()
|
projectionMatrix := r.projectionMatrix()
|
||||||
texture.DrawParts(parts, projectionMatrix, geometryMatrix, colorMatrix)
|
quads := graphics.TextureQuads(parts, texture.width, texture.height)
|
||||||
|
shader.DrawTexture(
|
||||||
|
shader.NativeTexture(texture.native),
|
||||||
|
glMatrix(projectionMatrix),
|
||||||
|
quads,
|
||||||
|
geometryMatrix,
|
||||||
|
colorMatrix)
|
||||||
}
|
}
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
package opengl
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hajimehoshi/go-ebiten/graphics"
|
|
||||||
"image"
|
|
||||||
)
|
|
||||||
|
|
||||||
type SharedContext struct {
|
|
||||||
ids *ids
|
|
||||||
}
|
|
||||||
|
|
||||||
var sharedContext *SharedContext = nil
|
|
||||||
|
|
||||||
func Initialize() *SharedContext {
|
|
||||||
if sharedContext != nil {
|
|
||||||
panic("OpenGL is already initialized")
|
|
||||||
}
|
|
||||||
sharedContext = &SharedContext{
|
|
||||||
ids: newIds(),
|
|
||||||
}
|
|
||||||
return sharedContext
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SharedContext) CreateContext(screenWidth, screenHeight, screenScale int) *Context {
|
|
||||||
return newContext(s.ids, screenWidth, screenHeight, screenScale)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SharedContext) CreateRenderTarget(width, height int, filter graphics.Filter) (graphics.RenderTargetId, error) {
|
|
||||||
return s.ids.CreateRenderTarget(width, height, filter)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SharedContext) CreateTexture(img image.Image, filter graphics.Filter) (graphics.TextureId, error) {
|
|
||||||
return s.ids.CreateTexture(img, filter)
|
|
||||||
}
|
|
@ -6,8 +6,6 @@ package opengl
|
|||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/go-ebiten/graphics"
|
"github.com/hajimehoshi/go-ebiten/graphics"
|
||||||
"github.com/hajimehoshi/go-ebiten/graphics/matrix"
|
|
||||||
"github.com/hajimehoshi/go-ebiten/graphics/opengl/shader"
|
|
||||||
"image"
|
"image"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
@ -18,17 +16,9 @@ type Texture struct {
|
|||||||
height int
|
height int
|
||||||
}
|
}
|
||||||
|
|
||||||
func glMatrix(matrix [4][4]float64) [16]float32 {
|
func createNativeTexture(
|
||||||
result := [16]float32{}
|
textureWidth, textureHeight int,
|
||||||
for j := 0; j < 4; j++ {
|
pixels []uint8,
|
||||||
for i := 0; i < 4; i++ {
|
|
||||||
result[i+j*4] = float32(matrix[i][j])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
func createNativeTexture(textureWidth, textureHeight int, pixels []uint8,
|
|
||||||
filter graphics.Filter) C.GLuint {
|
filter graphics.Filter) C.GLuint {
|
||||||
nativeTexture := C.GLuint(0)
|
nativeTexture := C.GLuint(0)
|
||||||
|
|
||||||
@ -63,35 +53,26 @@ func createNativeTexture(textureWidth, textureHeight int, pixels []uint8,
|
|||||||
return nativeTexture
|
return nativeTexture
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTexture(width, height int, filter graphics.Filter) (*Texture, error) {
|
func createTexture(
|
||||||
|
width, height int,
|
||||||
|
filter graphics.Filter) (*Texture, error) {
|
||||||
native := createNativeTexture(
|
native := createNativeTexture(
|
||||||
graphics.AdjustSizeForTexture(width),
|
graphics.AdjustSizeForTexture(width),
|
||||||
graphics.AdjustSizeForTexture(height), nil, filter)
|
graphics.AdjustSizeForTexture(height),
|
||||||
|
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 := graphics.AdjustImageForTexture(img)
|
adjustedImage := graphics.AdjustImageForTexture(img)
|
||||||
size := adjustedImage.Bounds().Size()
|
size := adjustedImage.Bounds().Size()
|
||||||
native := createNativeTexture(size.X, size.Y, adjustedImage.Pix, filter)
|
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) Draw(projectionMatrix [4][4]float64, geometryMatrix matrix.Geometry, colorMatrix matrix.Color) {
|
func (t *Texture) dispose() {
|
||||||
quad := graphics.TextureQuadForTexture(t.width, t.height)
|
|
||||||
shader.DrawTexture(shader.NativeTexture(t.native),
|
|
||||||
glMatrix(projectionMatrix), []graphics.TextureQuad{quad},
|
|
||||||
geometryMatrix, colorMatrix)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *Texture) DrawParts(parts []graphics.TexturePart, projectionMatrix [4][4]float64,
|
|
||||||
geometryMatrix matrix.Geometry, colorMatrix matrix.Color) {
|
|
||||||
quads := graphics.TextureQuadsForTextureParts(parts, t.width, t.height)
|
|
||||||
shader.DrawTexture(shader.NativeTexture(t.native),
|
|
||||||
glMatrix(projectionMatrix), quads,
|
|
||||||
geometryMatrix, colorMatrix)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *Texture) Dispose() {
|
|
||||||
C.glDeleteTextures(1, &t.native)
|
C.glDeleteTextures(1, &t.native)
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,19 @@ import (
|
|||||||
"image"
|
"image"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Filter int
|
||||||
|
|
||||||
|
const (
|
||||||
|
FilterNearest Filter = iota
|
||||||
|
FilterLinear
|
||||||
|
)
|
||||||
|
|
||||||
|
type TextureId int
|
||||||
|
|
||||||
|
// A render target is essentially same as a texture, but it is assumed that the
|
||||||
|
// all alpha of a render target is maximum.
|
||||||
|
type RenderTargetId int
|
||||||
|
|
||||||
type TextureCreatedEvent struct {
|
type TextureCreatedEvent struct {
|
||||||
Tag interface{}
|
Tag interface{}
|
||||||
Id TextureId
|
Id TextureId
|
||||||
|
@ -62,20 +62,7 @@ func v(y int, height int) float32 {
|
|||||||
return float32(y) / float32(AdjustSizeForTexture(height))
|
return float32(y) / float32(AdjustSizeForTexture(height))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Remove this if possible
|
func TextureQuads(parts []TexturePart, width, height int) []TextureQuad {
|
||||||
func TextureQuadForTexture(width, height int) TextureQuad {
|
|
||||||
x1 := float32(0)
|
|
||||||
x2 := float32(width)
|
|
||||||
y1 := float32(0)
|
|
||||||
y2 := float32(height)
|
|
||||||
u1 := u(0, width)
|
|
||||||
u2 := u(width, width)
|
|
||||||
v1 := v(0, height)
|
|
||||||
v2 := v(height, height)
|
|
||||||
return TextureQuad{x1, x2, y1, y2, u1, u2, v1, v2}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TextureQuadsForTextureParts(parts []TexturePart, width, height int) []TextureQuad {
|
|
||||||
quads := []TextureQuad{}
|
quads := []TextureQuad{}
|
||||||
for _, part := range parts {
|
for _, part := range parts {
|
||||||
x1 := float32(part.LocationX)
|
x1 := float32(part.LocationX)
|
||||||
|
@ -53,7 +53,7 @@ func newGameWindow(width, height, scale int, title string) *GameWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *GameWindow) run(graphicsSharedContext *opengl.SharedContext, sharedGLContext *C.NSOpenGLContext) {
|
func (w *GameWindow) run(sharedGLContext *C.NSOpenGLContext) {
|
||||||
cTitle := C.CString(w.title)
|
cTitle := C.CString(w.title)
|
||||||
defer C.free(unsafe.Pointer(cTitle))
|
defer C.free(unsafe.Pointer(cTitle))
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ func (w *GameWindow) run(graphicsSharedContext *opengl.SharedContext, sharedGLCo
|
|||||||
close(ch)
|
close(ch)
|
||||||
|
|
||||||
C.UseGLContext(glContext)
|
C.UseGLContext(glContext)
|
||||||
context := graphicsSharedContext.CreateContext(
|
context := opengl.CreateContext(
|
||||||
w.screenWidth, w.screenHeight, w.screenScale)
|
w.screenWidth, w.screenHeight, w.screenScale)
|
||||||
C.UnuseGLContext()
|
C.UnuseGLContext()
|
||||||
|
|
||||||
|
@ -15,12 +15,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type sharedContext struct {
|
type sharedContext struct {
|
||||||
inited chan struct{}
|
inited chan struct{}
|
||||||
sharedContext *opengl.SharedContext
|
events chan interface{}
|
||||||
events chan interface{}
|
funcs chan func()
|
||||||
funcs chan func()
|
funcsDone chan struct{}
|
||||||
funcsDone chan struct{}
|
gameWindows chan *GameWindow
|
||||||
gameWindows chan *GameWindow
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSharedContext() *sharedContext {
|
func newSharedContext() *sharedContext {
|
||||||
@ -36,7 +35,6 @@ func (t *sharedContext) run() {
|
|||||||
var sharedGLContext *C.NSOpenGLContext
|
var sharedGLContext *C.NSOpenGLContext
|
||||||
go func() {
|
go func() {
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
t.sharedContext = opengl.Initialize()
|
|
||||||
sharedGLContext = C.CreateGLContext(nil)
|
sharedGLContext = C.CreateGLContext(nil)
|
||||||
close(t.inited)
|
close(t.inited)
|
||||||
t.loop(sharedGLContext)
|
t.loop(sharedGLContext)
|
||||||
@ -44,7 +42,7 @@ func (t *sharedContext) run() {
|
|||||||
<-t.inited
|
<-t.inited
|
||||||
go func() {
|
go func() {
|
||||||
for w := range t.gameWindows {
|
for w := range t.gameWindows {
|
||||||
w.run(t.sharedContext, sharedGLContext)
|
w.run(sharedGLContext)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
@ -88,7 +86,7 @@ func (t *sharedContext) CreateTexture(tag interface{}, img image.Image, filter g
|
|||||||
var id graphics.TextureId
|
var id graphics.TextureId
|
||||||
var err error
|
var err error
|
||||||
t.useGLContext(func() {
|
t.useGLContext(func() {
|
||||||
id, err = t.sharedContext.CreateTexture(img, filter)
|
id, err = opengl.CreateTexture(img, filter)
|
||||||
})
|
})
|
||||||
if t.events == nil {
|
if t.events == nil {
|
||||||
return
|
return
|
||||||
@ -107,7 +105,7 @@ func (t *sharedContext) CreateRenderTarget(tag interface{}, width, height int, f
|
|||||||
var id graphics.RenderTargetId
|
var id graphics.RenderTargetId
|
||||||
var err error
|
var err error
|
||||||
t.useGLContext(func() {
|
t.useGLContext(func() {
|
||||||
id, err = t.sharedContext.CreateRenderTarget(width, height, filter)
|
id, err = opengl.CreateRenderTarget(width, height, filter)
|
||||||
})
|
})
|
||||||
if t.events == nil {
|
if t.events == nil {
|
||||||
return
|
return
|
||||||
|
Loading…
Reference in New Issue
Block a user