mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-11 19:48:54 +01:00
164 lines
3.8 KiB
Go
164 lines
3.8 KiB
Go
// Copyright 2016 Hajime Hoshi
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package ebiten
|
|
|
|
import (
|
|
"errors"
|
|
"image"
|
|
"image/color"
|
|
"runtime"
|
|
|
|
"github.com/hajimehoshi/ebiten/internal/graphics"
|
|
"github.com/hajimehoshi/ebiten/internal/graphics/opengl"
|
|
)
|
|
|
|
// Commands are used only before the GL Context is created.
|
|
|
|
type imageCommand interface {
|
|
Exec() error
|
|
}
|
|
|
|
var (
|
|
imageCommandQueue = []imageCommand{}
|
|
)
|
|
|
|
func execBufferedImageCommands() error {
|
|
imageM.Lock()
|
|
defer imageM.Unlock()
|
|
for _, c := range imageCommandQueue {
|
|
if err := c.Exec(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
imageCommandQueue = nil
|
|
return nil
|
|
}
|
|
|
|
type fillCommand struct {
|
|
dst *Image
|
|
color color.Color
|
|
}
|
|
|
|
func (c *fillCommand) Exec() error {
|
|
if c.dst.isDisposed() {
|
|
return errors.New("ebiten: image is already disposed")
|
|
}
|
|
c.dst.pixels = nil
|
|
return c.dst.framebuffer.Fill(glContext, c.color)
|
|
}
|
|
|
|
type drawImageCommand struct {
|
|
dst *Image
|
|
src *Image
|
|
vertices []int16
|
|
geoM GeoM
|
|
colorM ColorM
|
|
compositeMode CompositeMode
|
|
}
|
|
|
|
func (c *drawImageCommand) Exec() error {
|
|
if c.dst.isDisposed() {
|
|
return errors.New("ebiten: image is already disposed")
|
|
}
|
|
c.dst.pixels = nil
|
|
m := opengl.CompositeMode(c.compositeMode)
|
|
return c.dst.framebuffer.DrawTexture(glContext, c.src.texture, c.vertices, &c.geoM, &c.colorM, m)
|
|
}
|
|
|
|
type replacePixelsCommand struct {
|
|
dst *Image
|
|
pixels []uint8
|
|
}
|
|
|
|
func (c *replacePixelsCommand) Exec() error {
|
|
if c.dst.isDisposed() {
|
|
return errors.New("ebiten: image is already disposed")
|
|
}
|
|
return c.dst.framebuffer.ReplacePixels(glContext, c.dst.texture, c.pixels)
|
|
}
|
|
|
|
type disposeCommand struct {
|
|
image *Image
|
|
}
|
|
|
|
func (c *disposeCommand) Exec() error {
|
|
if c.image.isDisposed() {
|
|
return errors.New("ebiten: image is already disposed")
|
|
}
|
|
if c.image.framebuffer != nil {
|
|
if err := c.image.framebuffer.Dispose(glContext); err != nil {
|
|
return err
|
|
}
|
|
c.image.framebuffer = nil
|
|
}
|
|
if c.image.texture != nil {
|
|
if err := c.image.texture.Dispose(glContext); err != nil {
|
|
return err
|
|
}
|
|
c.image.texture = nil
|
|
}
|
|
c.image.pixels = nil
|
|
runtime.SetFinalizer(c.image, nil)
|
|
return nil
|
|
}
|
|
|
|
type newImageCommand struct {
|
|
result *Image
|
|
width int
|
|
height int
|
|
filter Filter
|
|
}
|
|
|
|
func (c *newImageCommand) Exec() error {
|
|
texture, err := graphics.NewTexture(glContext, c.width, c.height, glFilter(glContext, c.filter))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
framebuffer, err := graphics.NewFramebufferFromTexture(glContext, texture)
|
|
if err != nil {
|
|
// TODO: texture should be removed here?
|
|
return err
|
|
}
|
|
c.result.framebuffer = framebuffer
|
|
c.result.texture = texture
|
|
runtime.SetFinalizer(c.result, (*Image).Dispose)
|
|
if err := c.result.framebuffer.Fill(glContext, color.Transparent); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type newImageFromImageCommand struct {
|
|
image image.Image
|
|
filter Filter
|
|
result *Image
|
|
}
|
|
|
|
func (c *newImageFromImageCommand) Exec() error {
|
|
texture, err := graphics.NewTextureFromImage(glContext, c.image, glFilter(glContext, c.filter))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
framebuffer, err := graphics.NewFramebufferFromTexture(glContext, texture)
|
|
if err != nil {
|
|
// TODO: texture should be removed here?
|
|
return err
|
|
}
|
|
c.result.framebuffer = framebuffer
|
|
c.result.texture = texture
|
|
runtime.SetFinalizer(c.result, (*Image).Dispose)
|
|
return nil
|
|
}
|