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

View File

@ -40,15 +40,16 @@ type framebuffer struct {
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))
if err != nil {
return err
return nil, err
}
f.native = native
f.width = texture.width
f.height = texture.height
return nil
return &framebuffer{
native: native,
width: texture.width,
height: texture.height,
}, nil
}
const viewportSize = 4096

View File

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