mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 02:38:53 +01:00
internal/graphicsdriver: refactoring: use image.Rectangle
This commit is contained in:
parent
d2c991b774
commit
e98acd3dc7
@ -16,6 +16,7 @@ package graphicscommand
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image"
|
||||
"math"
|
||||
"strings"
|
||||
|
||||
@ -427,15 +428,12 @@ func (c *writePixelsCommand) Exec(graphicsDriver graphicsdriver.Graphics, indexO
|
||||
type readPixelsCommand struct {
|
||||
result []byte
|
||||
img *Image
|
||||
x int
|
||||
y int
|
||||
width int
|
||||
height int
|
||||
region image.Rectangle
|
||||
}
|
||||
|
||||
// Exec executes a readPixelsCommand.
|
||||
func (c *readPixelsCommand) Exec(graphicsDriver graphicsdriver.Graphics, indexOffset int) error {
|
||||
if err := c.img.image.ReadPixels(c.result, c.x, c.y, c.width, c.height); err != nil {
|
||||
if err := c.img.image.ReadPixels(c.result, c.region); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
@ -163,14 +163,11 @@ func (i *Image) DrawTriangles(srcs [graphics.ShaderImageCount]*Image, offsets [g
|
||||
|
||||
// ReadPixels reads the image's pixels.
|
||||
// ReadPixels returns an error when an error happens in the graphics driver.
|
||||
func (i *Image) ReadPixels(graphicsDriver graphicsdriver.Graphics, buf []byte, x, y, width, height int) error {
|
||||
func (i *Image) ReadPixels(graphicsDriver graphicsdriver.Graphics, buf []byte, region image.Rectangle) error {
|
||||
i.flushBufferedWritePixels()
|
||||
c := &readPixelsCommand{
|
||||
img: i,
|
||||
x: x,
|
||||
y: y,
|
||||
width: width,
|
||||
height: height,
|
||||
region: region,
|
||||
result: buf,
|
||||
}
|
||||
theCommandQueue.Enqueue(c)
|
||||
@ -180,13 +177,10 @@ func (i *Image) ReadPixels(graphicsDriver graphicsdriver.Graphics, buf []byte, x
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *Image) WritePixels(pixels []byte, x, y, width, height int) {
|
||||
func (i *Image) WritePixels(pixels []byte, region image.Rectangle) {
|
||||
i.bufferedWP = append(i.bufferedWP, &graphicsdriver.WritePixelsArgs{
|
||||
Pixels: pixels,
|
||||
X: x,
|
||||
Y: y,
|
||||
Width: width,
|
||||
Height: height,
|
||||
Region: region,
|
||||
})
|
||||
addImageWithBuffer(i)
|
||||
}
|
||||
@ -228,7 +222,7 @@ func (i *Image) dumpTo(w io.Writer, graphicsDriver graphicsdriver.Graphics, blac
|
||||
}
|
||||
|
||||
pix := make([]byte, 4*i.width*i.height)
|
||||
if err := i.ReadPixels(graphicsDriver, pix, 0, 0, i.width, i.height); err != nil {
|
||||
if err := i.ReadPixels(graphicsDriver, pix, image.Rect(0, 0, i.width, i.height)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ package graphicscommand_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image"
|
||||
"image/color"
|
||||
"testing"
|
||||
|
||||
@ -66,7 +67,7 @@ func TestClear(t *testing.T) {
|
||||
dst.DrawTriangles([graphics.ShaderImageCount]*graphicscommand.Image{src}, [graphics.ShaderImageCount - 1][2]float32{}, vs, is, graphicsdriver.BlendClear, dr, graphicsdriver.Region{}, nearestFilterShader, nil, false)
|
||||
|
||||
pix := make([]byte, 4*w*h)
|
||||
if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), pix, 0, 0, w, h); err != nil {
|
||||
if err := dst.ReadPixels(ui.GraphicsDriverForTesting(), pix, image.Rect(0, 0, w, h)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for j := 0; j < h/2; j++ {
|
||||
@ -96,7 +97,7 @@ func TestWritePixelsPartAfterDrawTriangles(t *testing.T) {
|
||||
}
|
||||
dst.DrawTriangles([graphics.ShaderImageCount]*graphicscommand.Image{clr}, [graphics.ShaderImageCount - 1][2]float32{}, vs, is, graphicsdriver.BlendClear, dr, graphicsdriver.Region{}, nearestFilterShader, nil, false)
|
||||
dst.DrawTriangles([graphics.ShaderImageCount]*graphicscommand.Image{src}, [graphics.ShaderImageCount - 1][2]float32{}, vs, is, graphicsdriver.BlendSourceOver, dr, graphicsdriver.Region{}, nearestFilterShader, nil, false)
|
||||
dst.WritePixels(make([]byte, 4), 0, 0, 1, 1)
|
||||
dst.WritePixels(make([]byte, 4), image.Rect(0, 0, 1, 1))
|
||||
|
||||
// TODO: Check the result.
|
||||
}
|
||||
@ -120,7 +121,7 @@ func TestShader(t *testing.T) {
|
||||
dst.DrawTriangles([graphics.ShaderImageCount]*graphicscommand.Image{}, [graphics.ShaderImageCount - 1][2]float32{}, vs, is, graphicsdriver.BlendSourceOver, dr, graphicsdriver.Region{}, s, nil, false)
|
||||
|
||||
pix := make([]byte, 4*w*h)
|
||||
if err := dst.ReadPixels(g, pix, 0, 0, w, h); err != nil {
|
||||
if err := dst.ReadPixels(g, pix, image.Rect(0, 0, w, h)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for j := 0; j < h; j++ {
|
||||
|
@ -16,6 +16,7 @@ package directx
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image"
|
||||
"unsafe"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
|
||||
@ -79,10 +80,10 @@ func (i *image11) IsInvalidated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (i *image11) ReadPixels(buf []byte, x, y, width, height int) error {
|
||||
func (i *image11) ReadPixels(buf []byte, region image.Rectangle) error {
|
||||
staging, err := i.graphics.device.CreateTexture2D(&_D3D11_TEXTURE2D_DESC{
|
||||
Width: uint32(width),
|
||||
Height: uint32(height),
|
||||
Width: uint32(region.Dx()),
|
||||
Height: uint32(region.Dy()),
|
||||
MipLevels: 0,
|
||||
ArraySize: 1,
|
||||
Format: _DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||
@ -101,11 +102,11 @@ func (i *image11) ReadPixels(buf []byte, x, y, width, height int) error {
|
||||
defer staging.Release()
|
||||
|
||||
i.graphics.deviceContext.CopySubresourceRegion(unsafe.Pointer(staging), 0, 0, 0, 0, unsafe.Pointer(i.texture), 0, &_D3D11_BOX{
|
||||
left: uint32(x),
|
||||
top: uint32(y),
|
||||
left: uint32(region.Min.X),
|
||||
top: uint32(region.Min.Y),
|
||||
front: 0,
|
||||
right: uint32(x + width),
|
||||
bottom: uint32(y + height),
|
||||
right: uint32(region.Max.X),
|
||||
bottom: uint32(region.Max.Y),
|
||||
back: 1,
|
||||
})
|
||||
|
||||
@ -115,12 +116,12 @@ func (i *image11) ReadPixels(buf []byte, x, y, width, height int) error {
|
||||
}
|
||||
|
||||
stride := int(mapped.RowPitch)
|
||||
src := unsafe.Slice((*byte)(mapped.pData), stride*height)
|
||||
if stride == 4*width {
|
||||
src := unsafe.Slice((*byte)(mapped.pData), stride*region.Dy())
|
||||
if stride == 4*region.Dx() {
|
||||
copy(buf, src)
|
||||
} else {
|
||||
for j := 0; j < height; j++ {
|
||||
copy(buf[j*4*width:(j+1)*4*width], src[j*stride:j*stride+4*width])
|
||||
for j := 0; j < region.Dy(); j++ {
|
||||
copy(buf[j*4*region.Dx():(j+1)*4*region.Dx()], src[j*stride:j*stride+4*region.Dx()])
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,13 +133,13 @@ func (i *image11) ReadPixels(buf []byte, x, y, width, height int) error {
|
||||
func (i *image11) WritePixels(args []*graphicsdriver.WritePixelsArgs) error {
|
||||
for _, a := range args {
|
||||
i.graphics.deviceContext.UpdateSubresource(unsafe.Pointer(i.texture), 0, &_D3D11_BOX{
|
||||
left: uint32(a.X),
|
||||
top: uint32(a.Y),
|
||||
left: uint32(a.Region.Min.X),
|
||||
top: uint32(a.Region.Min.Y),
|
||||
front: 0,
|
||||
right: uint32(a.X + a.Width),
|
||||
bottom: uint32(a.Y + a.Height),
|
||||
right: uint32(a.Region.Max.X),
|
||||
bottom: uint32(a.Region.Max.Y),
|
||||
back: 1,
|
||||
}, unsafe.Pointer(&a.Pixels[0]), uint32(4*a.Width), 0)
|
||||
}, unsafe.Pointer(&a.Pixels[0]), uint32(4*a.Region.Dx()), 0)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ package directx
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"image"
|
||||
"unsafe"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
|
||||
@ -71,7 +72,7 @@ func (*image12) IsInvalidated() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (i *image12) ReadPixels(buf []byte, x, y, width, height int) error {
|
||||
func (i *image12) ReadPixels(buf []byte, region image.Rectangle) error {
|
||||
if i.screen {
|
||||
return errors.New("directx: Pixels cannot be called on the screen")
|
||||
}
|
||||
@ -83,8 +84,8 @@ func (i *image12) ReadPixels(buf []byte, x, y, width, height int) error {
|
||||
desc := _D3D12_RESOURCE_DESC{
|
||||
Dimension: _D3D12_RESOURCE_DIMENSION_TEXTURE2D,
|
||||
Alignment: 0,
|
||||
Width: uint64(width),
|
||||
Height: uint32(height),
|
||||
Width: uint64(region.Dx()),
|
||||
Height: uint32(region.Dy()),
|
||||
DepthOrArraySize: 1,
|
||||
MipLevels: 0,
|
||||
Format: _DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||
@ -126,11 +127,11 @@ func (i *image12) ReadPixels(buf []byte, x, y, width, height int) error {
|
||||
i.graphics.needFlushCopyCommandList = true
|
||||
i.graphics.copyCommandList.CopyTextureRegion_PlacedFootPrint_SubresourceIndex(
|
||||
&dst, 0, 0, 0, &src, &_D3D12_BOX{
|
||||
left: uint32(x),
|
||||
top: uint32(y),
|
||||
left: uint32(region.Min.X),
|
||||
top: uint32(region.Min.Y),
|
||||
front: 0,
|
||||
right: uint32(x + width),
|
||||
bottom: uint32(y + height),
|
||||
right: uint32(region.Max.X),
|
||||
bottom: uint32(region.Max.Y),
|
||||
back: 1,
|
||||
})
|
||||
|
||||
@ -139,8 +140,8 @@ func (i *image12) ReadPixels(buf []byte, x, y, width, height int) error {
|
||||
}
|
||||
|
||||
dstBytes := unsafe.Slice((*byte)(unsafe.Pointer(m)), totalBytes)
|
||||
for j := 0; j < height; j++ {
|
||||
copy(buf[j*width*4:(j+1)*width*4], dstBytes[j*int(layouts.Footprint.RowPitch):])
|
||||
for j := 0; j < region.Dy(); j++ {
|
||||
copy(buf[j*region.Dx()*4:(j+1)*region.Dx()*4], dstBytes[j*int(layouts.Footprint.RowPitch):])
|
||||
}
|
||||
|
||||
readingStagingBuffer.Unmap(0, nil)
|
||||
@ -157,30 +158,16 @@ func (i *image12) WritePixels(args []*graphicsdriver.WritePixelsArgs) error {
|
||||
return err
|
||||
}
|
||||
|
||||
minX := i.width
|
||||
minY := i.height
|
||||
maxX := 0
|
||||
maxY := 0
|
||||
var region image.Rectangle
|
||||
for _, a := range args {
|
||||
if minX > a.X {
|
||||
minX = a.X
|
||||
}
|
||||
if minY > a.Y {
|
||||
minY = a.Y
|
||||
}
|
||||
if maxX < a.X+a.Width {
|
||||
maxX = a.X + a.Width
|
||||
}
|
||||
if maxY < a.Y+a.Height {
|
||||
maxY = a.Y + a.Height
|
||||
}
|
||||
region = region.Union(a.Region)
|
||||
}
|
||||
|
||||
desc := _D3D12_RESOURCE_DESC{
|
||||
Dimension: _D3D12_RESOURCE_DIMENSION_TEXTURE2D,
|
||||
Alignment: 0,
|
||||
Width: uint64(maxX - minX),
|
||||
Height: uint32(maxY - minY),
|
||||
Width: uint64(region.Dx()),
|
||||
Height: uint32(region.Dy()),
|
||||
DepthOrArraySize: 1,
|
||||
MipLevels: 0,
|
||||
Format: _DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||
@ -211,8 +198,8 @@ func (i *image12) WritePixels(args []*graphicsdriver.WritePixelsArgs) error {
|
||||
|
||||
srcBytes := unsafe.Slice((*byte)(unsafe.Pointer(m)), totalBytes)
|
||||
for _, a := range args {
|
||||
for j := 0; j < a.Height; j++ {
|
||||
copy(srcBytes[((a.Y-minY)+j)*int(layouts.Footprint.RowPitch)+(a.X-minX)*4:], a.Pixels[j*a.Width*4:(j+1)*a.Width*4])
|
||||
for j := 0; j < a.Region.Dy(); j++ {
|
||||
copy(srcBytes[((a.Region.Min.Y-region.Min.Y)+j)*int(layouts.Footprint.RowPitch)+(a.Region.Min.X-region.Min.X)*4:], a.Pixels[j*a.Region.Dx()*4:(j+1)*a.Region.Dx()*4])
|
||||
}
|
||||
}
|
||||
|
||||
@ -228,12 +215,12 @@ func (i *image12) WritePixels(args []*graphicsdriver.WritePixelsArgs) error {
|
||||
PlacedFootprint: layouts,
|
||||
}
|
||||
i.graphics.copyCommandList.CopyTextureRegion_SubresourceIndex_PlacedFootPrint(
|
||||
&dst, uint32(a.X), uint32(a.Y), 0, &src, &_D3D12_BOX{
|
||||
left: uint32(a.X - minX),
|
||||
top: uint32(a.Y - minY),
|
||||
&dst, uint32(a.Region.Min.X), uint32(a.Region.Min.Y), 0, &src, &_D3D12_BOX{
|
||||
left: uint32(a.Region.Min.X - region.Min.X),
|
||||
top: uint32(a.Region.Min.Y - region.Min.Y),
|
||||
front: 0,
|
||||
right: uint32(a.X - minX + a.Width),
|
||||
bottom: uint32(a.Y - minY + a.Height),
|
||||
right: uint32(a.Region.Max.X - region.Min.X),
|
||||
bottom: uint32(a.Region.Max.Y - region.Min.Y),
|
||||
back: 1,
|
||||
})
|
||||
}
|
||||
|
@ -15,6 +15,8 @@
|
||||
package graphicsdriver
|
||||
|
||||
import (
|
||||
"image"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/shaderir"
|
||||
)
|
||||
@ -65,7 +67,7 @@ type Image interface {
|
||||
ID() ImageID
|
||||
Dispose()
|
||||
IsInvalidated() bool
|
||||
ReadPixels(buf []byte, x, y, width, height int) error
|
||||
ReadPixels(buf []byte, region image.Rectangle) error
|
||||
WritePixels(args []*WritePixelsArgs) error
|
||||
}
|
||||
|
||||
@ -73,10 +75,7 @@ type ImageID int
|
||||
|
||||
type WritePixelsArgs struct {
|
||||
Pixels []byte
|
||||
X int
|
||||
Y int
|
||||
Width int
|
||||
Height int
|
||||
Region image.Rectangle
|
||||
}
|
||||
|
||||
type Shader interface {
|
||||
|
@ -16,6 +16,7 @@ package metal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image"
|
||||
"math"
|
||||
"runtime"
|
||||
"sort"
|
||||
@ -815,17 +816,17 @@ func (i *Image) syncTexture() {
|
||||
cb.WaitUntilCompleted()
|
||||
}
|
||||
|
||||
func (i *Image) ReadPixels(buf []byte, x, y, width, height int) error {
|
||||
if got, want := len(buf), 4*width*height; got != want {
|
||||
func (i *Image) ReadPixels(buf []byte, region image.Rectangle) error {
|
||||
if got, want := len(buf), 4*region.Dx()*region.Dy(); got != want {
|
||||
return fmt.Errorf("metal: len(buf) must be %d but %d at ReadPixels", want, got)
|
||||
}
|
||||
|
||||
i.graphics.flushIfNeeded(false)
|
||||
i.syncTexture()
|
||||
|
||||
i.texture.GetBytes(&buf[0], uintptr(4*width), mtl.Region{
|
||||
Origin: mtl.Origin{X: x, Y: y},
|
||||
Size: mtl.Size{Width: width, Height: height, Depth: 1},
|
||||
i.texture.GetBytes(&buf[0], uintptr(4*region.Dx()), mtl.Region{
|
||||
Origin: mtl.Origin{X: region.Min.X, Y: region.Min.Y},
|
||||
Size: mtl.Size{Width: region.Dx(), Height: region.Dy(), Depth: 1},
|
||||
}, 0)
|
||||
return nil
|
||||
}
|
||||
@ -836,26 +837,10 @@ func (i *Image) WritePixels(args []*graphicsdriver.WritePixelsArgs) error {
|
||||
g.flushRenderCommandEncoderIfNeeded()
|
||||
|
||||
// Calculate the smallest texture size to include all the values in args.
|
||||
minX := math.MaxInt32
|
||||
minY := math.MaxInt32
|
||||
maxX := 0
|
||||
maxY := 0
|
||||
var region image.Rectangle
|
||||
for _, a := range args {
|
||||
if minX > a.X {
|
||||
minX = a.X
|
||||
}
|
||||
if maxX < a.X+a.Width {
|
||||
maxX = a.X + a.Width
|
||||
}
|
||||
if minY > a.Y {
|
||||
minY = a.Y
|
||||
}
|
||||
if maxY < a.Y+a.Height {
|
||||
maxY = a.Y + a.Height
|
||||
}
|
||||
region = region.Union(a.Region)
|
||||
}
|
||||
w := maxX - minX
|
||||
h := maxY - minY
|
||||
|
||||
// Use a temporary texture to send pixels asynchronously, whichever the memory is shared (e.g., iOS) or
|
||||
// managed (e.g., macOS). A temporary texture is needed since ReplaceRegion tries to sync the pixel
|
||||
@ -864,8 +849,8 @@ func (i *Image) WritePixels(args []*graphicsdriver.WritePixelsArgs) error {
|
||||
td := mtl.TextureDescriptor{
|
||||
TextureType: mtl.TextureType2D,
|
||||
PixelFormat: mtl.PixelFormatRGBA8UNorm,
|
||||
Width: w,
|
||||
Height: h,
|
||||
Width: region.Dx(),
|
||||
Height: region.Dy(),
|
||||
StorageMode: storageMode,
|
||||
Usage: mtl.TextureUsageShaderRead | mtl.TextureUsageRenderTarget,
|
||||
}
|
||||
@ -874,9 +859,9 @@ func (i *Image) WritePixels(args []*graphicsdriver.WritePixelsArgs) error {
|
||||
|
||||
for _, a := range args {
|
||||
t.ReplaceRegion(mtl.Region{
|
||||
Origin: mtl.Origin{X: a.X - minX, Y: a.Y - minY, Z: 0},
|
||||
Size: mtl.Size{Width: a.Width, Height: a.Height, Depth: 1},
|
||||
}, 0, unsafe.Pointer(&a.Pixels[0]), 4*a.Width)
|
||||
Origin: mtl.Origin{X: a.Region.Min.X - region.Min.X, Y: a.Region.Min.Y - region.Min.Y, Z: 0},
|
||||
Size: mtl.Size{Width: a.Region.Dx(), Height: a.Region.Dy(), Depth: 1},
|
||||
}, 0, unsafe.Pointer(&a.Pixels[0]), 4*a.Region.Dx())
|
||||
}
|
||||
|
||||
if g.cb == (mtl.CommandBuffer{}) {
|
||||
@ -884,9 +869,9 @@ func (i *Image) WritePixels(args []*graphicsdriver.WritePixelsArgs) error {
|
||||
}
|
||||
bce := g.cb.MakeBlitCommandEncoder()
|
||||
for _, a := range args {
|
||||
so := mtl.Origin{X: a.X - minX, Y: a.Y - minY, Z: 0}
|
||||
ss := mtl.Size{Width: a.Width, Height: a.Height, Depth: 1}
|
||||
do := mtl.Origin{X: a.X, Y: a.Y, Z: 0}
|
||||
so := mtl.Origin{X: a.Region.Min.X - region.Min.X, Y: a.Region.Min.Y - region.Min.Y, Z: 0}
|
||||
ss := mtl.Size{Width: a.Region.Dx(), Height: a.Region.Dy(), Depth: 1}
|
||||
do := mtl.Origin{X: a.Region.Min.X, Y: a.Region.Min.Y, Z: 0}
|
||||
bce.CopyFromTexture(t, 0, 0, so, ss, i.texture, 0, 0, do)
|
||||
}
|
||||
bce.EndEncoding()
|
||||
|
@ -17,6 +17,7 @@ package opengl
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"image"
|
||||
"sync"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||
@ -242,14 +243,18 @@ func (c *context) newTexture(width, height int) (textureNative, error) {
|
||||
return textureNative(t), nil
|
||||
}
|
||||
|
||||
func (c *context) framebufferPixels(buf []byte, f *framebuffer, x, y, width, height int) error {
|
||||
if got, want := len(buf), 4*width*height; got != want {
|
||||
func (c *context) framebufferPixels(buf []byte, f *framebuffer, region image.Rectangle) error {
|
||||
if got, want := len(buf), 4*region.Dx()*region.Dy(); got != want {
|
||||
return fmt.Errorf("opengl: len(buf) must be %d but was %d at framebufferPixels", got, want)
|
||||
}
|
||||
|
||||
c.ctx.Flush()
|
||||
c.bindFramebuffer(f.native)
|
||||
c.ctx.ReadPixels(buf, int32(x), int32(y), int32(width), int32(height), gl.RGBA, gl.UNSIGNED_BYTE)
|
||||
x := int32(region.Min.X)
|
||||
y := int32(region.Min.Y)
|
||||
width := int32(region.Dx())
|
||||
height := int32(region.Dy())
|
||||
c.ctx.ReadPixels(buf, x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ package opengl
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"image"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||
@ -71,11 +72,11 @@ func (i *Image) setViewport() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *Image) ReadPixels(buf []byte, x, y, width, height int) error {
|
||||
func (i *Image) ReadPixels(buf []byte, region image.Rectangle) error {
|
||||
if err := i.ensureFramebuffer(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := i.graphics.context.framebufferPixels(buf, i.framebuffer, x, y, width, height); err != nil {
|
||||
if err := i.graphics.context.framebufferPixels(buf, i.framebuffer, region); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@ -147,7 +148,11 @@ func (i *Image) WritePixels(args []*graphicsdriver.WritePixelsArgs) error {
|
||||
|
||||
i.graphics.context.bindTexture(i.texture)
|
||||
for _, a := range args {
|
||||
i.graphics.context.ctx.TexSubImage2D(gl.TEXTURE_2D, 0, int32(a.X), int32(a.Y), int32(a.Width), int32(a.Height), gl.RGBA, gl.UNSIGNED_BYTE, a.Pixels)
|
||||
x := int32(a.Region.Min.X)
|
||||
y := int32(a.Region.Min.Y)
|
||||
width := int32(a.Region.Dx())
|
||||
height := int32(a.Region.Dy())
|
||||
i.graphics.context.ctx.TexSubImage2D(gl.TEXTURE_2D, 0, x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, a.Pixels)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -282,12 +282,12 @@ func (i *Image) WritePixels(pixels []byte, region image.Rectangle) {
|
||||
theImages.makeStaleIfDependingOn(i)
|
||||
|
||||
if pixels != nil {
|
||||
i.image.WritePixels(pixels, region.Min.X, region.Min.Y, region.Dx(), region.Dy())
|
||||
i.image.WritePixels(pixels, region)
|
||||
} else {
|
||||
// TODO: When pixels == nil, we don't have to care the pixel state there. In such cases, the image
|
||||
// accepts only WritePixels and not Fill or DrawTriangles.
|
||||
// TODO: Separate Image struct into two: images for WritePixels-only, and the others.
|
||||
i.image.WritePixels(make([]byte, 4*region.Dx()*region.Dy()), region.Min.X, region.Min.Y, region.Dx(), region.Dy())
|
||||
i.image.WritePixels(make([]byte, 4*region.Dx()*region.Dy()), region)
|
||||
}
|
||||
|
||||
// Even if the image is already stale, call makeStale to extend the stale region.
|
||||
@ -429,7 +429,7 @@ func (i *Image) readPixelsFromGPUIfNeeded(graphicsDriver graphicsdriver.Graphics
|
||||
|
||||
func (i *Image) ReadPixels(graphicsDriver graphicsdriver.Graphics, pixels []byte, region image.Rectangle) error {
|
||||
if AlwaysReadPixelsFromGPU() {
|
||||
if err := i.image.ReadPixels(graphicsDriver, pixels, region.Min.X, region.Min.Y, region.Dx(), region.Dy()); err != nil {
|
||||
if err := i.image.ReadPixels(graphicsDriver, pixels, region); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@ -494,7 +494,7 @@ func (i *Image) readPixelsFromGPU(graphicsDriver graphicsdriver.Graphics) error
|
||||
pix = make([]byte, 4*r.Dx()*r.Dy())
|
||||
i.pixelsCache[r] = pix
|
||||
}
|
||||
if err := i.image.ReadPixels(graphicsDriver, pix, r.Min.X, r.Min.Y, r.Dx(), r.Dy()); err != nil {
|
||||
if err := i.image.ReadPixels(graphicsDriver, pix, r); err != nil {
|
||||
return err
|
||||
}
|
||||
i.basePixels.AddOrReplace(pix, r)
|
||||
@ -633,7 +633,7 @@ func (i *Image) restore(graphicsDriver graphicsdriver.Graphics) error {
|
||||
pix = make([]byte, 4*r.Dx()*r.Dy())
|
||||
i.pixelsCache[r] = pix
|
||||
}
|
||||
if err := gimg.ReadPixels(graphicsDriver, pix, r.Min.X, r.Min.Y, r.Dx(), r.Dy()); err != nil {
|
||||
if err := gimg.ReadPixels(graphicsDriver, pix, r); err != nil {
|
||||
return err
|
||||
}
|
||||
i.basePixels.AddOrReplace(pix, r)
|
||||
|
@ -122,7 +122,7 @@ func (pr *pixelsRecords) readPixels(pixels []byte, region image.Rectangle, image
|
||||
func (pr *pixelsRecords) apply(img *graphicscommand.Image) {
|
||||
// TODO: Isn't this too heavy? Can we merge the operations?
|
||||
for _, r := range pr.records {
|
||||
img.WritePixels(r.pix, r.rect.Min.X, r.rect.Min.Y, r.rect.Dx(), r.rect.Dy())
|
||||
img.WritePixels(r.pix, r.rect)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user