graphics: Replace textures/framebuffers with images in commands

This commit is contained in:
Hajime Hoshi 2016-06-12 22:44:23 +09:00
parent 2a0ca3c393
commit 8d258b3c38
3 changed files with 60 additions and 67 deletions

View File

@ -73,12 +73,12 @@ func FlushCommands(context *opengl.Context) error {
} }
type fillCommand struct { type fillCommand struct {
dst *framebuffer dst *Image
color color.Color color color.Color
} }
func (c *fillCommand) Exec(context *opengl.Context) error { func (c *fillCommand) Exec(context *opengl.Context) error {
if err := c.dst.setAsViewport(context); err != nil { if err := c.dst.framebuffer.setAsViewport(context); err != nil {
return err return err
} }
cr, cg, cb, ca := c.color.RGBA() cr, cg, cb, ca := c.color.RGBA()
@ -91,8 +91,8 @@ func (c *fillCommand) Exec(context *opengl.Context) error {
} }
type drawImageCommand struct { type drawImageCommand struct {
dst *framebuffer dst *Image
src *texture src *Image
vertices []int16 vertices []int16
geo Matrix geo Matrix
color Matrix color Matrix
@ -100,7 +100,7 @@ type drawImageCommand struct {
} }
func (c *drawImageCommand) Exec(context *opengl.Context) error { func (c *drawImageCommand) Exec(context *opengl.Context) error {
if err := c.dst.setAsViewport(context); err != nil { if err := c.dst.framebuffer.setAsViewport(context); err != nil {
return err return err
} }
context.BlendFunc(c.mode) context.BlendFunc(c.mode)
@ -113,8 +113,8 @@ func (c *drawImageCommand) Exec(context *opengl.Context) error {
state: &theOpenGLState, state: &theOpenGLState,
program: theOpenGLState.programTexture, program: theOpenGLState.programTexture,
context: context, context: context,
projectionMatrix: glMatrix(c.dst.projectionMatrix()), projectionMatrix: glMatrix(c.dst.framebuffer.projectionMatrix()),
texture: c.src.native, texture: c.src.texture.native,
geoM: c.geo, geoM: c.geo,
colorM: c.color, colorM: c.color,
} }
@ -128,45 +128,42 @@ func (c *drawImageCommand) Exec(context *opengl.Context) error {
} }
type replacePixelsCommand struct { type replacePixelsCommand struct {
dst *framebuffer dst *Image
texture *texture pixels []uint8
pixels []uint8
} }
func (c *replacePixelsCommand) Exec(context *opengl.Context) error { func (c *replacePixelsCommand) Exec(context *opengl.Context) error {
// Filling with non black or white color is required here for glTexSubImage2D. // Filling with non black or white color is required here for glTexSubImage2D.
// Very mysterious but this actually works (Issue #186) // Very mysterious but this actually works (Issue #186)
if err := c.dst.setAsViewport(context); err != nil { if err := c.dst.framebuffer.setAsViewport(context); err != nil {
return err return err
} }
if err := context.FillFramebuffer(0, 0, 0.5, 1); err != nil { if err := context.FillFramebuffer(0, 0, 0.5, 1); err != nil {
return err return err
} }
context.BindTexture(c.texture.native) context.BindTexture(c.dst.texture.native)
context.TexSubImage2D(c.pixels, c.texture.width, c.texture.height) context.TexSubImage2D(c.pixels, c.dst.texture.width, c.dst.texture.height)
return nil return nil
} }
type disposeCommand struct { type disposeCommand struct {
framebuffer *framebuffer target *Image
texture *texture
} }
func (c *disposeCommand) Exec(context *opengl.Context) error { func (c *disposeCommand) Exec(context *opengl.Context) error {
if c.framebuffer != nil && c.framebuffer.native != opengl.ZeroFramebuffer { if c.target.framebuffer != nil && c.target.framebuffer.native != opengl.ZeroFramebuffer {
context.DeleteFramebuffer(c.framebuffer.native) context.DeleteFramebuffer(c.target.framebuffer.native)
} }
if c.texture != nil { if c.target.texture != nil {
context.DeleteTexture(c.texture.native) context.DeleteTexture(c.target.texture.native)
} }
return nil return nil
} }
type newImageFromImageCommand struct { type newImageFromImageCommand struct {
texture *texture result *Image
framebuffer *framebuffer img *image.RGBA
img *image.RGBA filter opengl.Filter
filter opengl.Filter
} }
func adjustImageForTexture(img *image.RGBA) *image.RGBA { func adjustImageForTexture(img *image.RGBA) *image.RGBA {
@ -205,21 +202,23 @@ func (c *newImageFromImageCommand) Exec(context *opengl.Context) error {
if err != nil { if err != nil {
return err return err
} }
c.texture.native = native c.result.texture = &texture{
c.texture.width = origSize.X native: native,
c.texture.height = origSize.Y width: origSize.X,
if err := c.framebuffer.initFromTexture(context, c.texture); err != nil { height: origSize.Y,
}
c.result.framebuffer, err = newFramebufferFromTexture(context, c.result.texture)
if err != nil {
return err return err
} }
return nil return nil
} }
type newImageCommand struct { type newImageCommand struct {
texture *texture result *Image
framebuffer *framebuffer width int
width int height int
height int filter opengl.Filter
filter opengl.Filter
} }
func (c *newImageCommand) Exec(context *opengl.Context) error { func (c *newImageCommand) Exec(context *opengl.Context) error {
@ -235,10 +234,13 @@ func (c *newImageCommand) Exec(context *opengl.Context) error {
if err != nil { if err != nil {
return err return err
} }
c.texture.native = native c.result.texture = &texture{
c.texture.width = c.width native: native,
c.texture.height = c.height width: c.width,
if err := c.framebuffer.initFromTexture(context, c.texture); err != nil { height: c.height,
}
c.result.framebuffer, err = newFramebufferFromTexture(context, c.result.texture)
if err != nil {
return err return err
} }
return nil return nil

View File

@ -40,15 +40,16 @@ type framebuffer struct {
proMatrix *[4][4]float64 proMatrix *[4][4]float64
} }
func (f *framebuffer) initFromTexture(context *opengl.Context, texture *texture) error { func newFramebufferFromTexture(context *opengl.Context, texture *texture) (*framebuffer, error) {
native, err := context.NewFramebuffer(opengl.Texture(texture.native)) native, err := context.NewFramebuffer(opengl.Texture(texture.native))
if err != nil { if err != nil {
return err return nil, err
} }
f.native = native return &framebuffer{
f.width = texture.width native: native,
f.height = texture.height width: texture.width,
return nil height: texture.height,
}, nil
} }
const viewportSize = 4096 const viewportSize = 4096

View File

@ -27,31 +27,23 @@ type Image struct {
} }
func NewImage(width, height int, filter opengl.Filter) (*Image, error) { func NewImage(width, height int, filter opengl.Filter) (*Image, error) {
i := &Image{ i := &Image{}
texture: &texture{},
framebuffer: &framebuffer{},
}
c := &newImageCommand{ c := &newImageCommand{
texture: i.texture, result: i,
framebuffer: i.framebuffer, width: width,
width: width, height: height,
height: height, filter: filter,
filter: filter,
} }
theCommandQueue.Enqueue(c) theCommandQueue.Enqueue(c)
return i, nil return i, nil
} }
func NewImageFromImage(img *image.RGBA, filter opengl.Filter) (*Image, error) { func NewImageFromImage(img *image.RGBA, filter opengl.Filter) (*Image, error) {
i := &Image{ i := &Image{}
texture: &texture{},
framebuffer: &framebuffer{},
}
c := &newImageFromImageCommand{ c := &newImageFromImageCommand{
texture: i.texture, result: i,
framebuffer: i.framebuffer, img: img,
img: img, filter: filter,
filter: filter,
} }
theCommandQueue.Enqueue(c) theCommandQueue.Enqueue(c)
return i, nil return i, nil
@ -70,8 +62,7 @@ func NewZeroFramebufferImage(width, height int) (*Image, error) {
func (i *Image) Dispose() error { func (i *Image) Dispose() error {
c := &disposeCommand{ c := &disposeCommand{
framebuffer: i.framebuffer, target: i,
texture: i.texture,
} }
theCommandQueue.Enqueue(c) theCommandQueue.Enqueue(c)
return nil return nil
@ -79,7 +70,7 @@ func (i *Image) Dispose() error {
func (i *Image) Fill(clr color.Color) error { func (i *Image) Fill(clr color.Color) error {
c := &fillCommand{ c := &fillCommand{
dst: i.framebuffer, dst: i,
color: clr, color: clr,
} }
theCommandQueue.Enqueue(c) theCommandQueue.Enqueue(c)
@ -88,8 +79,8 @@ func (i *Image) Fill(clr color.Color) error {
func (i *Image) DrawImage(src *Image, vertices []int16, geo, clr Matrix, mode opengl.CompositeMode) error { func (i *Image) DrawImage(src *Image, vertices []int16, geo, clr Matrix, mode opengl.CompositeMode) error {
c := &drawImageCommand{ c := &drawImageCommand{
dst: i.framebuffer, dst: i,
src: src.texture, src: src,
vertices: vertices, vertices: vertices,
geo: geo, geo: geo,
color: clr, color: clr,
@ -110,9 +101,8 @@ func (i *Image) Pixels(context *opengl.Context) ([]uint8, error) {
func (i *Image) ReplacePixels(p []uint8) error { func (i *Image) ReplacePixels(p []uint8) error {
c := &replacePixelsCommand{ c := &replacePixelsCommand{
dst: i.framebuffer, dst: i,
texture: i.texture, pixels: p,
pixels: p,
} }
theCommandQueue.Enqueue(c) theCommandQueue.Enqueue(c)
return nil return nil