mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +01:00
graphics: Add commands to create textures/framebuffers
This commit is contained in:
parent
2a58c095b8
commit
32c2cb3ead
24
image.go
24
image.go
@ -311,15 +311,12 @@ func (i *imageImpl) restorePixels(context *opengl.Context) error {
|
|||||||
for j := 0; j < i.height; j++ {
|
for j := 0; j < i.height; j++ {
|
||||||
copy(img.Pix[j*img.Stride:], i.pixels[j*i.width*4:(j+1)*i.width*4])
|
copy(img.Pix[j*img.Stride:], i.pixels[j*i.width*4:(j+1)*i.width*4])
|
||||||
}
|
}
|
||||||
var err error
|
texture, framebuffer, err := graphics.NewImageFromImage(img, glFilter(ui.GLContext(), i.filter))
|
||||||
i.texture, err = graphics.NewTextureFromImage(ui.GLContext(), img, glFilter(ui.GLContext(), i.filter))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
i.framebuffer, err = graphics.NewFramebufferFromTexture(ui.GLContext(), i.texture)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
i.texture = texture
|
||||||
|
i.framebuffer = framebuffer
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -400,15 +397,10 @@ func NewImage(width, height int, filter Filter) (*Image, error) {
|
|||||||
f := func() error {
|
f := func() error {
|
||||||
imageM.Lock()
|
imageM.Lock()
|
||||||
defer imageM.Unlock()
|
defer imageM.Unlock()
|
||||||
texture, err := graphics.NewTexture(ui.GLContext(), width, height, glFilter(ui.GLContext(), filter))
|
texture, framebuffer, err := graphics.NewImage(width, height, glFilter(ui.GLContext(), filter))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
framebuffer, err := graphics.NewFramebufferFromTexture(ui.GLContext(), texture)
|
|
||||||
if err != nil {
|
|
||||||
// TODO: texture should be removed here?
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
image.framebuffer = framebuffer
|
image.framebuffer = framebuffer
|
||||||
image.texture = texture
|
image.texture = texture
|
||||||
runtime.SetFinalizer(image, (*imageImpl).Dispose)
|
runtime.SetFinalizer(image, (*imageImpl).Dispose)
|
||||||
@ -455,11 +447,7 @@ func NewImageFromImage(source image.Image, filter Filter) (*Image, error) {
|
|||||||
}
|
}
|
||||||
imageM.Lock()
|
imageM.Lock()
|
||||||
defer imageM.Unlock()
|
defer imageM.Unlock()
|
||||||
texture, err := graphics.NewTextureFromImage(ui.GLContext(), rgbaImg, glFilter(ui.GLContext(), filter))
|
texture, framebuffer, err := graphics.NewImageFromImage(rgbaImg, glFilter(ui.GLContext(), filter))
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
framebuffer, err := graphics.NewFramebufferFromTexture(ui.GLContext(), texture)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: texture should be removed here?
|
// TODO: texture should be removed here?
|
||||||
return err
|
return err
|
||||||
@ -489,7 +477,7 @@ func newImageWithZeroFramebuffer(width, height int) (*Image, error) {
|
|||||||
func newImageWithZeroFramebufferImpl(width, height int) (*Image, error) {
|
func newImageWithZeroFramebufferImpl(width, height int) (*Image, error) {
|
||||||
imageM.Lock()
|
imageM.Lock()
|
||||||
defer imageM.Unlock()
|
defer imageM.Unlock()
|
||||||
f, err := graphics.NewZeroFramebuffer(ui.GLContext(), width, height)
|
f, err := graphics.NewZeroFramebuffer(width, height)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ package graphics
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"image"
|
||||||
"image/color"
|
"image/color"
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
@ -159,3 +160,63 @@ func (c *disposeCommand) Exec(context *opengl.Context) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type newImageFromImageCommand struct {
|
||||||
|
texture *Texture
|
||||||
|
framebuffer *Framebuffer
|
||||||
|
img *image.RGBA
|
||||||
|
filter opengl.Filter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *newImageFromImageCommand) Exec(context *opengl.Context) error {
|
||||||
|
origSize := c.img.Bounds().Size()
|
||||||
|
if origSize.X < 4 {
|
||||||
|
return errors.New("graphics: width must be equal or more than 4.")
|
||||||
|
}
|
||||||
|
if origSize.Y < 4 {
|
||||||
|
return errors.New("graphics: height must be equal or more than 4.")
|
||||||
|
}
|
||||||
|
adjustedImage := adjustImageForTexture(c.img)
|
||||||
|
size := adjustedImage.Bounds().Size()
|
||||||
|
native, err := context.NewTexture(size.X, size.Y, adjustedImage.Pix, c.filter)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
c.texture.native = native
|
||||||
|
c.texture.width = origSize.X
|
||||||
|
c.texture.height = origSize.Y
|
||||||
|
if err := c.framebuffer.initFromTexture(context, c.texture); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type newImageCommand struct {
|
||||||
|
texture *Texture
|
||||||
|
framebuffer *Framebuffer
|
||||||
|
width int
|
||||||
|
height int
|
||||||
|
filter opengl.Filter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *newImageCommand) Exec(context *opengl.Context) error {
|
||||||
|
w := int(NextPowerOf2Int32(int32(c.width)))
|
||||||
|
h := int(NextPowerOf2Int32(int32(c.height)))
|
||||||
|
if w < 4 {
|
||||||
|
return errors.New("graphics: width must be equal or more than 4.")
|
||||||
|
}
|
||||||
|
if h < 4 {
|
||||||
|
return errors.New("graphics: height must be equal or more than 4.")
|
||||||
|
}
|
||||||
|
native, err := context.NewTexture(w, h, nil, c.filter)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
c.texture.native = native
|
||||||
|
c.texture.width = c.width
|
||||||
|
c.texture.height = c.height
|
||||||
|
if err := c.framebuffer.initFromTexture(context, c.texture); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -42,7 +42,7 @@ type Framebuffer struct {
|
|||||||
proMatrix *[4][4]float64
|
proMatrix *[4][4]float64
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewZeroFramebuffer(c *opengl.Context, width, height int) (*Framebuffer, error) {
|
func NewZeroFramebuffer(width, height int) (*Framebuffer, error) {
|
||||||
f := &Framebuffer{
|
f := &Framebuffer{
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
@ -51,17 +51,15 @@ func NewZeroFramebuffer(c *opengl.Context, width, height int) (*Framebuffer, err
|
|||||||
return f, nil
|
return f, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFramebufferFromTexture(c *opengl.Context, texture *Texture) (*Framebuffer, error) {
|
func (f *Framebuffer) initFromTexture(context *opengl.Context, texture *Texture) error {
|
||||||
native, err := c.NewFramebuffer(opengl.Texture(texture.native))
|
native, err := context.NewFramebuffer(opengl.Texture(texture.native))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
f := &Framebuffer{
|
f.native = native
|
||||||
native: native,
|
f.width = texture.width
|
||||||
width: texture.width,
|
f.height = texture.height
|
||||||
height: texture.height,
|
return nil
|
||||||
}
|
|
||||||
return f, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Dispose(texture *Texture, framebuffer *Framebuffer) error {
|
func Dispose(texture *Texture, framebuffer *Framebuffer) error {
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
package graphics
|
package graphics
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"image"
|
"image"
|
||||||
"image/draw"
|
"image/draw"
|
||||||
|
|
||||||
@ -50,35 +49,29 @@ type Texture struct {
|
|||||||
height int
|
height int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTexture(c *opengl.Context, width, height int, filter opengl.Filter) (*Texture, error) {
|
func NewImage(width, height int, filter opengl.Filter) (*Texture, *Framebuffer, error) {
|
||||||
w := int(NextPowerOf2Int32(int32(width)))
|
texture := &Texture{}
|
||||||
h := int(NextPowerOf2Int32(int32(height)))
|
framebuffer := &Framebuffer{}
|
||||||
if w < 4 {
|
c := &newImageCommand{
|
||||||
return nil, errors.New("width must be equal or more than 4.")
|
texture: texture,
|
||||||
|
framebuffer: framebuffer,
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
filter: filter,
|
||||||
}
|
}
|
||||||
if h < 4 {
|
theCommandQueue.Enqueue(c)
|
||||||
return nil, errors.New("height must be equal or more than 4.")
|
return texture, framebuffer, nil
|
||||||
}
|
|
||||||
native, err := c.NewTexture(w, h, nil, filter)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &Texture{native, width, height}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTextureFromImage(c *opengl.Context, img *image.RGBA, filter opengl.Filter) (*Texture, error) {
|
func NewImageFromImage(img *image.RGBA, filter opengl.Filter) (*Texture, *Framebuffer, error) {
|
||||||
origSize := img.Bounds().Size()
|
texture := &Texture{}
|
||||||
if origSize.X < 4 {
|
framebuffer := &Framebuffer{}
|
||||||
return nil, errors.New("width must be equal or more than 4.")
|
c := &newImageFromImageCommand{
|
||||||
|
texture: texture,
|
||||||
|
framebuffer: framebuffer,
|
||||||
|
img: img,
|
||||||
|
filter: filter,
|
||||||
}
|
}
|
||||||
if origSize.Y < 4 {
|
theCommandQueue.Enqueue(c)
|
||||||
return nil, errors.New("height must be equal or more than 4.")
|
return texture, framebuffer, nil
|
||||||
}
|
|
||||||
adjustedImage := adjustImageForTexture(img)
|
|
||||||
size := adjustedImage.Bounds().Size()
|
|
||||||
native, err := c.NewTexture(size.X, size.Y, adjustedImage.Pix, filter)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &Texture{native, origSize.X, origSize.Y}, nil
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user