mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
parent
5dd073fcbb
commit
36e9803cea
@ -60,7 +60,7 @@ type Graphics interface {
|
||||
//
|
||||
// * float32
|
||||
// * []float32
|
||||
DrawShader(dst ImageID, srcs [graphics.ShaderImageNum]ImageID, shader ShaderID, indexLen int, indexOffset int, mode CompositeMode, uniforms []interface{}) error
|
||||
DrawShader(dst ImageID, srcs [graphics.ShaderImageNum]ImageID, offsets [graphics.ShaderImageNum - 1][2]float32, shader ShaderID, indexLen int, indexOffset int, mode CompositeMode, uniforms []interface{}) error
|
||||
}
|
||||
|
||||
// GraphicsNotReady represents that the graphics driver is not ready for recovering from the context lost.
|
||||
|
@ -18,7 +18,18 @@ import (
|
||||
"github.com/hajimehoshi/ebiten/internal/web"
|
||||
)
|
||||
|
||||
const ShaderImageNum = 4
|
||||
const (
|
||||
ShaderImageNum = 4
|
||||
|
||||
// PreservedUniformVariablesNum represents the number of preserved uniform variables.
|
||||
// Any shaders in Ebiten must have these uniform variables.
|
||||
//
|
||||
// The first one is for the viewport size.
|
||||
// The second and the followings are for offsets of the second and the following images.
|
||||
//
|
||||
// All the preversed uniform variables are vec2 so far.
|
||||
PreservedUniformVariablesNum = 1 + (ShaderImageNum - 1)
|
||||
)
|
||||
|
||||
const (
|
||||
IndicesNum = (1 << 16) / 3 * 3 // Adjust num for triangles.
|
||||
|
@ -144,7 +144,7 @@ func (q *commandQueue) appendIndices(indices []uint16, offset uint16) {
|
||||
}
|
||||
|
||||
// EnqueueDrawTrianglesCommand enqueues a drawing-image command.
|
||||
func (q *commandQueue) EnqueueDrawTrianglesCommand(dst *Image, srcs [graphics.ShaderImageNum]*Image, vertices []float32, indices []uint16, color *affine.ColorM, mode driver.CompositeMode, filter driver.Filter, address driver.Address, sourceRegion driver.Region, shader *Shader, uniforms []interface{}) {
|
||||
func (q *commandQueue) EnqueueDrawTrianglesCommand(dst *Image, srcs [graphics.ShaderImageNum]*Image, offsets [graphics.ShaderImageNum - 1][2]float32, vertices []float32, indices []uint16, color *affine.ColorM, mode driver.CompositeMode, filter driver.Filter, address driver.Address, sourceRegion driver.Region, shader *Shader, uniforms []interface{}) {
|
||||
if len(indices) > graphics.IndicesNum {
|
||||
panic(fmt.Sprintf("graphicscommand: len(indices) must be <= graphics.IndicesNum but not at EnqueueDrawTrianglesCommand: len(indices): %d, graphics.IndicesNum: %d", len(indices), graphics.IndicesNum))
|
||||
}
|
||||
@ -171,6 +171,7 @@ func (q *commandQueue) EnqueueDrawTrianglesCommand(dst *Image, srcs [graphics.Sh
|
||||
|
||||
// TODO: If dst is the screen, reorder the command to be the last.
|
||||
if !split && 0 < len(q.commands) {
|
||||
// TODO: Pass offsets and uniforms when merging considers the shader.
|
||||
if last := q.commands[len(q.commands)-1]; last.CanMergeWithDrawTrianglesCommand(dst, srcs, color, mode, filter, address, sourceRegion, shader) {
|
||||
last.AddNumVertices(len(vertices))
|
||||
last.AddNumIndices(len(indices))
|
||||
@ -178,17 +179,24 @@ func (q *commandQueue) EnqueueDrawTrianglesCommand(dst *Image, srcs [graphics.Sh
|
||||
}
|
||||
}
|
||||
|
||||
if firstSrc != nil && address != driver.AddressUnsafe {
|
||||
if firstSrc != nil {
|
||||
w, h := firstSrc.InternalSize()
|
||||
sourceRegion.X /= float32(w)
|
||||
sourceRegion.Y /= float32(h)
|
||||
sourceRegion.Width /= float32(w)
|
||||
sourceRegion.Height /= float32(h)
|
||||
if address != driver.AddressUnsafe {
|
||||
sourceRegion.X /= float32(w)
|
||||
sourceRegion.Y /= float32(h)
|
||||
sourceRegion.Width /= float32(w)
|
||||
sourceRegion.Height /= float32(h)
|
||||
}
|
||||
for i := range offsets {
|
||||
offsets[i][0] /= float32(w)
|
||||
offsets[i][1] /= float32(h)
|
||||
}
|
||||
}
|
||||
|
||||
c := &drawTrianglesCommand{
|
||||
dst: dst,
|
||||
srcs: srcs,
|
||||
offsets: offsets,
|
||||
nvertices: len(vertices),
|
||||
nindices: len(indices),
|
||||
color: color,
|
||||
@ -315,6 +323,7 @@ func FlushCommands() error {
|
||||
type drawTrianglesCommand struct {
|
||||
dst *Image
|
||||
srcs [graphics.ShaderImageNum]*Image
|
||||
offsets [graphics.ShaderImageNum - 1][2]float32
|
||||
nvertices int
|
||||
nindices int
|
||||
color *affine.ColorM
|
||||
@ -424,7 +433,7 @@ func (c *drawTrianglesCommand) Exec(indexOffset int) error {
|
||||
imgs[i] = src.image.ID()
|
||||
}
|
||||
|
||||
return theGraphicsDriver.DrawShader(c.dst.image.ID(), imgs, c.shader.shader.ID(), c.nindices, indexOffset, c.mode, c.uniforms)
|
||||
return theGraphicsDriver.DrawShader(c.dst.image.ID(), imgs, c.offsets, c.shader.shader.ID(), c.nindices, indexOffset, c.mode, c.uniforms)
|
||||
}
|
||||
return theGraphicsDriver.Draw(c.dst.image.ID(), c.srcs[0].image.ID(), c.nindices, indexOffset, c.mode, c.color, c.filter, c.address, c.sourceRegion)
|
||||
}
|
||||
|
@ -147,7 +147,7 @@ func (i *Image) InternalSize() (int, int) {
|
||||
//
|
||||
// If the source image is not specified, i.e., src is nil and there is no image in the uniform variables, the
|
||||
// elements for the source image are not used.
|
||||
func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []float32, indices []uint16, clr *affine.ColorM, mode driver.CompositeMode, filter driver.Filter, address driver.Address, sourceRegion driver.Region, shader *Shader, uniforms []interface{}) {
|
||||
func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, offsets [graphics.ShaderImageNum - 1][2]float32, vertices []float32, indices []uint16, clr *affine.ColorM, mode driver.CompositeMode, filter driver.Filter, address driver.Address, sourceRegion driver.Region, shader *Shader, uniforms []interface{}) {
|
||||
if i.lastCommand == lastCommandNone {
|
||||
if !i.screen && mode != driver.CompositeModeClear {
|
||||
panic("graphicscommand: the image must be cleared first")
|
||||
@ -165,7 +165,7 @@ func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []f
|
||||
}
|
||||
i.resolveBufferedReplacePixels()
|
||||
|
||||
theCommandQueue.EnqueueDrawTrianglesCommand(i, srcs, vertices, indices, clr, mode, filter, address, sourceRegion, shader, uniforms)
|
||||
theCommandQueue.EnqueueDrawTrianglesCommand(i, srcs, offsets, vertices, indices, clr, mode, filter, address, sourceRegion, shader, uniforms)
|
||||
|
||||
if i.lastCommand == lastCommandNone && !i.screen {
|
||||
i.lastCommand = lastCommandClear
|
||||
|
@ -44,7 +44,7 @@ func TestClear(t *testing.T) {
|
||||
|
||||
vs := quadVertices(w/2, h/2)
|
||||
is := graphics.QuadIndices()
|
||||
dst.DrawTriangles([graphics.ShaderImageNum]*Image{src}, vs, is, nil, driver.CompositeModeClear, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
dst.DrawTriangles([graphics.ShaderImageNum]*Image{src}, [graphics.ShaderImageNum - 1][2]float32{}, vs, is, nil, driver.CompositeModeClear, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
|
||||
pix, err := dst.Pixels()
|
||||
if err != nil {
|
||||
@ -74,8 +74,8 @@ func TestReplacePixelsPartAfterDrawTriangles(t *testing.T) {
|
||||
dst := NewImage(w, h)
|
||||
vs := quadVertices(w/2, h/2)
|
||||
is := graphics.QuadIndices()
|
||||
dst.DrawTriangles([graphics.ShaderImageNum]*Image{clr}, vs, is, nil, driver.CompositeModeClear, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
dst.DrawTriangles([graphics.ShaderImageNum]*Image{src}, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
dst.DrawTriangles([graphics.ShaderImageNum]*Image{clr}, [graphics.ShaderImageNum - 1][2]float32{}, vs, is, nil, driver.CompositeModeClear, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
dst.DrawTriangles([graphics.ShaderImageNum]*Image{src}, [graphics.ShaderImageNum - 1][2]float32{}, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
dst.ReplacePixels(make([]byte, 4), 0, 0, 1, 1)
|
||||
}
|
||||
|
||||
@ -89,11 +89,11 @@ func TestShader(t *testing.T) {
|
||||
dst := NewImage(w, h)
|
||||
vs := quadVertices(w, h)
|
||||
is := graphics.QuadIndices()
|
||||
dst.DrawTriangles([graphics.ShaderImageNum]*Image{clr}, vs, is, nil, driver.CompositeModeClear, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
dst.DrawTriangles([graphics.ShaderImageNum]*Image{clr}, [graphics.ShaderImageNum - 1][2]float32{}, vs, is, nil, driver.CompositeModeClear, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
|
||||
ir := etesting.ShaderProgramFill(0xff, 0, 0, 0xff)
|
||||
s := NewShader(&ir)
|
||||
dst.DrawTriangles([graphics.ShaderImageNum]*Image{}, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, s, nil)
|
||||
dst.DrawTriangles([graphics.ShaderImageNum]*Image{}, [graphics.ShaderImageNum - 1][2]float32{}, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, s, nil)
|
||||
|
||||
pix, err := dst.Pixels()
|
||||
if err != nil {
|
||||
|
@ -802,7 +802,7 @@ func (g *Graphics) NewShader(program *shaderir.Program) (driver.Shader, error) {
|
||||
panic("metal: NewShader is not implemented")
|
||||
}
|
||||
|
||||
func (g *Graphics) DrawShader(dst driver.ImageID, srcs [graphics.ShaderImageNum]driver.ImageID, shader driver.ShaderID, indexLen int, indexOffset int, mode driver.CompositeMode, uniforms []interface{}) error {
|
||||
func (g *Graphics) DrawShader(dst driver.ImageID, srcs [graphics.ShaderImageNum]driver.ImageID, offsets [graphics.ShaderImageNum - 1][2]float32, shader driver.ShaderID, indexLen int, indexOffset int, mode driver.CompositeMode, uniforms []interface{}) error {
|
||||
panic("metal: DrawShader is not implemented")
|
||||
}
|
||||
|
||||
|
@ -287,7 +287,7 @@ func (g *Graphics) removeShader(shader *Shader) {
|
||||
delete(g.shaders, shader.id)
|
||||
}
|
||||
|
||||
func (g *Graphics) DrawShader(dst driver.ImageID, srcs [graphics.ShaderImageNum]driver.ImageID, shader driver.ShaderID, indexLen int, indexOffset int, mode driver.CompositeMode, uniforms []interface{}) error {
|
||||
func (g *Graphics) DrawShader(dst driver.ImageID, srcs [graphics.ShaderImageNum]driver.ImageID, offsets [graphics.ShaderImageNum - 1][2]float32, shader driver.ShaderID, indexLen int, indexOffset int, mode driver.CompositeMode, uniforms []interface{}) error {
|
||||
d := g.images[dst]
|
||||
s := g.shaders[shader]
|
||||
|
||||
@ -298,14 +298,22 @@ func (g *Graphics) DrawShader(dst driver.ImageID, srcs [graphics.ShaderImageNum]
|
||||
}
|
||||
g.context.blendFunc(mode)
|
||||
|
||||
us := make([]uniformVariable, 1+len(uniforms))
|
||||
us := make([]uniformVariable, graphics.PreservedUniformVariablesNum+len(uniforms))
|
||||
vw := graphics.InternalImageSize(d.width)
|
||||
vh := graphics.InternalImageSize(d.height)
|
||||
us[0].name = "U0"
|
||||
us[0].value = []float32{float32(vw), float32(vh)}
|
||||
for k, v := range uniforms {
|
||||
us[k+1].name = fmt.Sprintf("U%d", k+1)
|
||||
us[k+1].value = v
|
||||
|
||||
for i, o := range offsets {
|
||||
o := o
|
||||
us[i+1].name = fmt.Sprintf("U%d", i+1)
|
||||
us[i+1].value = o[:]
|
||||
}
|
||||
|
||||
for i, v := range uniforms {
|
||||
const offset = graphics.PreservedUniformVariablesNum
|
||||
us[i+offset].name = fmt.Sprintf("U%d", i+offset)
|
||||
us[i+offset].value = v
|
||||
}
|
||||
|
||||
var ts [graphics.ShaderImageNum]textureVariable
|
||||
|
@ -262,6 +262,8 @@ func (g *Graphics) useProgram(program program, uniforms []uniformVariable, textu
|
||||
|
||||
for _, u := range uniforms {
|
||||
switch v := u.value.(type) {
|
||||
case nil:
|
||||
// Do nothing.
|
||||
case float32:
|
||||
cached, ok := g.state.lastUniforms[u.name].(float32)
|
||||
if ok && cached == v {
|
||||
|
@ -70,6 +70,7 @@ func (p *Pixels) At(i, j int) (byte, byte, byte, byte) {
|
||||
// drawTrianglesHistoryItem is an item for history of draw-image commands.
|
||||
type drawTrianglesHistoryItem struct {
|
||||
images [graphics.ShaderImageNum]*Image
|
||||
offsets [graphics.ShaderImageNum - 1][2]float32
|
||||
vertices []float32
|
||||
indices []uint16
|
||||
colorm *affine.ColorM
|
||||
@ -259,7 +260,9 @@ func fillImage(i *graphicscommand.Image, clr color.RGBA) {
|
||||
// Add 1 pixels for paddings.
|
||||
vs := quadVertices(0, 0, float32(dw), float32(dh), 1, 1, float32(sw-1), float32(sh-1), rf, gf, bf, af)
|
||||
is := graphics.QuadIndices()
|
||||
i.DrawTriangles([graphics.ShaderImageNum]*graphicscommand.Image{emptyImage.image}, vs, is, nil, compositemode, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
srcs := [graphics.ShaderImageNum]*graphicscommand.Image{emptyImage.image}
|
||||
var offsets [graphics.ShaderImageNum - 1][2]float32
|
||||
i.DrawTriangles(srcs, offsets, vs, is, nil, compositemode, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
}
|
||||
|
||||
// BasePixelsForTesting returns the image's basePixels for testing.
|
||||
@ -351,7 +354,7 @@ func (i *Image) ReplacePixels(pixels []byte, x, y, width, height int) {
|
||||
// 5: Color G
|
||||
// 6: Color B
|
||||
// 7: Color Y
|
||||
func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []float32, indices []uint16, colorm *affine.ColorM, mode driver.CompositeMode, filter driver.Filter, address driver.Address, sourceRegion driver.Region, shader *Shader, uniforms []interface{}) {
|
||||
func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, offsets [graphics.ShaderImageNum - 1][2]float32, vertices []float32, indices []uint16, colorm *affine.ColorM, mode driver.CompositeMode, filter driver.Filter, address driver.Address, sourceRegion driver.Region, shader *Shader, uniforms []interface{}) {
|
||||
if i.priority {
|
||||
panic("restorable: DrawTriangles cannot be called on a priority image")
|
||||
}
|
||||
@ -375,7 +378,7 @@ func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []f
|
||||
if srcstale || i.screen || !needsRestoring() || i.volatile {
|
||||
i.makeStale()
|
||||
} else {
|
||||
i.appendDrawTrianglesHistory(srcs, vertices, indices, colorm, mode, filter, address, sourceRegion, shader, uniforms)
|
||||
i.appendDrawTrianglesHistory(srcs, offsets, vertices, indices, colorm, mode, filter, address, sourceRegion, shader, uniforms)
|
||||
}
|
||||
var s *graphicscommand.Shader
|
||||
if shader != nil {
|
||||
@ -389,11 +392,11 @@ func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []f
|
||||
}
|
||||
imgs[i] = src.image
|
||||
}
|
||||
i.image.DrawTriangles(imgs, vertices, indices, colorm, mode, filter, address, sourceRegion, s, uniforms)
|
||||
i.image.DrawTriangles(imgs, offsets, vertices, indices, colorm, mode, filter, address, sourceRegion, s, uniforms)
|
||||
}
|
||||
|
||||
// appendDrawTrianglesHistory appends a draw-image history item to the image.
|
||||
func (i *Image) appendDrawTrianglesHistory(srcs [graphics.ShaderImageNum]*Image, vertices []float32, indices []uint16, colorm *affine.ColorM, mode driver.CompositeMode, filter driver.Filter, address driver.Address, sourceRegion driver.Region, shader *Shader, uniforms []interface{}) {
|
||||
func (i *Image) appendDrawTrianglesHistory(srcs [graphics.ShaderImageNum]*Image, offsets [graphics.ShaderImageNum - 1][2]float32, vertices []float32, indices []uint16, colorm *affine.ColorM, mode driver.CompositeMode, filter driver.Filter, address driver.Address, sourceRegion driver.Region, shader *Shader, uniforms []interface{}) {
|
||||
if i.stale || i.volatile || i.screen {
|
||||
return
|
||||
}
|
||||
@ -413,6 +416,7 @@ func (i *Image) appendDrawTrianglesHistory(srcs [graphics.ShaderImageNum]*Image,
|
||||
|
||||
item := &drawTrianglesHistoryItem{
|
||||
images: srcs,
|
||||
offsets: offsets,
|
||||
vertices: vs,
|
||||
indices: is,
|
||||
colorm: colorm,
|
||||
@ -602,7 +606,7 @@ func (i *Image) restore() error {
|
||||
}
|
||||
imgs[i] = img.image
|
||||
}
|
||||
gimg.DrawTriangles(imgs, c.vertices, c.indices, c.colorm, c.mode, c.filter, c.address, c.sourceRegion, s, c.uniforms)
|
||||
gimg.DrawTriangles(imgs, c.offsets, c.vertices, c.indices, c.colorm, c.mode, c.filter, c.address, c.sourceRegion, s, c.uniforms)
|
||||
}
|
||||
|
||||
if len(i.drawTrianglesHistory) > 0 {
|
||||
|
@ -131,7 +131,7 @@ func TestRestoreChain(t *testing.T) {
|
||||
for i := 0; i < num-1; i++ {
|
||||
vs := quadVertices(1, 1, 0, 0)
|
||||
is := graphics.QuadIndices()
|
||||
imgs[i+1].DrawTriangles([graphics.ShaderImageNum]*Image{imgs[i]}, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
imgs[i+1].DrawTriangles([graphics.ShaderImageNum]*Image{imgs[i]}, [graphics.ShaderImageNum - 1][2]float32{}, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
}
|
||||
if err := ResolveStaleImages(); err != nil {
|
||||
t.Fatal(err)
|
||||
@ -173,10 +173,10 @@ func TestRestoreChain2(t *testing.T) {
|
||||
imgs[8].ReplacePixels([]byte{clr8.R, clr8.G, clr8.B, clr8.A}, 0, 0, w, h)
|
||||
|
||||
is := graphics.QuadIndices()
|
||||
imgs[8].DrawTriangles([graphics.ShaderImageNum]*Image{imgs[7]}, quadVertices(w, h, 0, 0), is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
imgs[9].DrawTriangles([graphics.ShaderImageNum]*Image{imgs[8]}, quadVertices(w, h, 0, 0), is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
imgs[8].DrawTriangles([graphics.ShaderImageNum]*Image{imgs[7]}, [graphics.ShaderImageNum - 1][2]float32{}, quadVertices(w, h, 0, 0), is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
imgs[9].DrawTriangles([graphics.ShaderImageNum]*Image{imgs[8]}, [graphics.ShaderImageNum - 1][2]float32{}, quadVertices(w, h, 0, 0), is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
for i := 0; i < 7; i++ {
|
||||
imgs[i+1].DrawTriangles([graphics.ShaderImageNum]*Image{imgs[i]}, quadVertices(w, h, 0, 0), is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
imgs[i+1].DrawTriangles([graphics.ShaderImageNum]*Image{imgs[i]}, [graphics.ShaderImageNum - 1][2]float32{}, quadVertices(w, h, 0, 0), is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
}
|
||||
|
||||
if err := ResolveStaleImages(); err != nil {
|
||||
@ -216,10 +216,10 @@ func TestRestoreOverrideSource(t *testing.T) {
|
||||
clr1 := color.RGBA{0x00, 0x00, 0x01, 0xff}
|
||||
img1.ReplacePixels([]byte{clr0.R, clr0.G, clr0.B, clr0.A}, 0, 0, w, h)
|
||||
is := graphics.QuadIndices()
|
||||
img2.DrawTriangles([graphics.ShaderImageNum]*Image{img1}, quadVertices(w, h, 0, 0), is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
img3.DrawTriangles([graphics.ShaderImageNum]*Image{img2}, quadVertices(w, h, 0, 0), is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
img2.DrawTriangles([graphics.ShaderImageNum]*Image{img1}, [graphics.ShaderImageNum - 1][2]float32{}, quadVertices(w, h, 0, 0), is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
img3.DrawTriangles([graphics.ShaderImageNum]*Image{img2}, [graphics.ShaderImageNum - 1][2]float32{}, quadVertices(w, h, 0, 0), is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
img0.ReplacePixels([]byte{clr1.R, clr1.G, clr1.B, clr1.A}, 0, 0, w, h)
|
||||
img1.DrawTriangles([graphics.ShaderImageNum]*Image{img0}, quadVertices(w, h, 0, 0), is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
img1.DrawTriangles([graphics.ShaderImageNum]*Image{img0}, [graphics.ShaderImageNum - 1][2]float32{}, quadVertices(w, h, 0, 0), is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
if err := ResolveStaleImages(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -298,23 +298,24 @@ func TestRestoreComplexGraph(t *testing.T) {
|
||||
}()
|
||||
vs := quadVertices(w, h, 0, 0)
|
||||
is := graphics.QuadIndices()
|
||||
img3.DrawTriangles([graphics.ShaderImageNum]*Image{img0}, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
var offsets [graphics.ShaderImageNum - 1][2]float32
|
||||
img3.DrawTriangles([graphics.ShaderImageNum]*Image{img0}, offsets, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
vs = quadVertices(w, h, 1, 0)
|
||||
img3.DrawTriangles([graphics.ShaderImageNum]*Image{img1}, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
img3.DrawTriangles([graphics.ShaderImageNum]*Image{img1}, offsets, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
vs = quadVertices(w, h, 1, 0)
|
||||
img4.DrawTriangles([graphics.ShaderImageNum]*Image{img1}, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
img4.DrawTriangles([graphics.ShaderImageNum]*Image{img1}, offsets, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
vs = quadVertices(w, h, 2, 0)
|
||||
img4.DrawTriangles([graphics.ShaderImageNum]*Image{img2}, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
img4.DrawTriangles([graphics.ShaderImageNum]*Image{img2}, offsets, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
vs = quadVertices(w, h, 0, 0)
|
||||
img5.DrawTriangles([graphics.ShaderImageNum]*Image{img3}, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
img5.DrawTriangles([graphics.ShaderImageNum]*Image{img3}, offsets, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
vs = quadVertices(w, h, 0, 0)
|
||||
img6.DrawTriangles([graphics.ShaderImageNum]*Image{img3}, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
img6.DrawTriangles([graphics.ShaderImageNum]*Image{img3}, offsets, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
vs = quadVertices(w, h, 1, 0)
|
||||
img6.DrawTriangles([graphics.ShaderImageNum]*Image{img4}, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
img6.DrawTriangles([graphics.ShaderImageNum]*Image{img4}, offsets, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
vs = quadVertices(w, h, 0, 0)
|
||||
img7.DrawTriangles([graphics.ShaderImageNum]*Image{img2}, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
img7.DrawTriangles([graphics.ShaderImageNum]*Image{img2}, offsets, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
vs = quadVertices(w, h, 2, 0)
|
||||
img7.DrawTriangles([graphics.ShaderImageNum]*Image{img3}, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
img7.DrawTriangles([graphics.ShaderImageNum]*Image{img3}, offsets, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
if err := ResolveStaleImages(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -406,8 +407,8 @@ func TestRestoreRecursive(t *testing.T) {
|
||||
img0.Dispose()
|
||||
}()
|
||||
is := graphics.QuadIndices()
|
||||
img1.DrawTriangles([graphics.ShaderImageNum]*Image{img0}, quadVertices(w, h, 1, 0), is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
img0.DrawTriangles([graphics.ShaderImageNum]*Image{img1}, quadVertices(w, h, 1, 0), is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
img1.DrawTriangles([graphics.ShaderImageNum]*Image{img0}, [graphics.ShaderImageNum - 1][2]float32{}, quadVertices(w, h, 1, 0), is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
img0.DrawTriangles([graphics.ShaderImageNum]*Image{img1}, [graphics.ShaderImageNum - 1][2]float32{}, quadVertices(w, h, 1, 0), is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
if err := ResolveStaleImages(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -501,7 +502,7 @@ func TestDrawTrianglesAndReplacePixels(t *testing.T) {
|
||||
|
||||
vs := quadVertices(1, 1, 0, 0)
|
||||
is := graphics.QuadIndices()
|
||||
img1.DrawTriangles([graphics.ShaderImageNum]*Image{img0}, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
img1.DrawTriangles([graphics.ShaderImageNum]*Image{img0}, [graphics.ShaderImageNum - 1][2]float32{}, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
img1.ReplacePixels([]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, 0, 0, 2, 1)
|
||||
|
||||
if err := ResolveStaleImages(); err != nil {
|
||||
@ -538,8 +539,8 @@ func TestDispose(t *testing.T) {
|
||||
defer img2.Dispose()
|
||||
|
||||
is := graphics.QuadIndices()
|
||||
img1.DrawTriangles([graphics.ShaderImageNum]*Image{img2}, quadVertices(1, 1, 0, 0), is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
img0.DrawTriangles([graphics.ShaderImageNum]*Image{img1}, quadVertices(1, 1, 0, 0), is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
img1.DrawTriangles([graphics.ShaderImageNum]*Image{img2}, [graphics.ShaderImageNum - 1][2]float32{}, quadVertices(1, 1, 0, 0), is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
img0.DrawTriangles([graphics.ShaderImageNum]*Image{img1}, [graphics.ShaderImageNum - 1][2]float32{}, quadVertices(1, 1, 0, 0), is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
img1.Dispose()
|
||||
|
||||
if err := ResolveStaleImages(); err != nil {
|
||||
@ -647,7 +648,7 @@ func TestReplacePixelsOnly(t *testing.T) {
|
||||
|
||||
vs := quadVertices(1, 1, 0, 0)
|
||||
is := graphics.QuadIndices()
|
||||
img1.DrawTriangles([graphics.ShaderImageNum]*Image{img0}, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
img1.DrawTriangles([graphics.ShaderImageNum]*Image{img0}, [graphics.ShaderImageNum - 1][2]float32{}, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
img0.ReplacePixels([]byte{5, 6, 7, 8}, 0, 0, 1, 1)
|
||||
|
||||
// BasePixelsForTesting is available without GPU accessing.
|
||||
@ -700,7 +701,7 @@ func TestReadPixelsFromVolatileImage(t *testing.T) {
|
||||
src.ReplacePixels(pix, 0, 0, w, h)
|
||||
vs := quadVertices(1, 1, 0, 0)
|
||||
is := graphics.QuadIndices()
|
||||
dst.DrawTriangles([graphics.ShaderImageNum]*Image{src}, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
dst.DrawTriangles([graphics.ShaderImageNum]*Image{src}, [graphics.ShaderImageNum - 1][2]float32{}, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
|
||||
// Read the pixels. If the implementation is correct, dst tries to read its pixels from GPU due to being
|
||||
// stale.
|
||||
@ -721,7 +722,7 @@ func TestAllowReplacePixelsAfterDrawTriangles(t *testing.T) {
|
||||
|
||||
vs := quadVertices(w, h, 0, 0)
|
||||
is := graphics.QuadIndices()
|
||||
dst.DrawTriangles([graphics.ShaderImageNum]*Image{src}, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
dst.DrawTriangles([graphics.ShaderImageNum]*Image{src}, [graphics.ShaderImageNum - 1][2]float32{}, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
dst.ReplacePixels(make([]byte, 4*w*h), 0, 0, w, h)
|
||||
// ReplacePixels for a whole image doesn't panic.
|
||||
}
|
||||
@ -739,7 +740,7 @@ func TestDisallowReplacePixelsForPartAfterDrawTriangles(t *testing.T) {
|
||||
|
||||
vs := quadVertices(w, h, 0, 0)
|
||||
is := graphics.QuadIndices()
|
||||
dst.DrawTriangles([graphics.ShaderImageNum]*Image{src}, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
dst.DrawTriangles([graphics.ShaderImageNum]*Image{src}, [graphics.ShaderImageNum - 1][2]float32{}, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
dst.ReplacePixels(make([]byte, 4), 0, 0, 1, 1)
|
||||
}
|
||||
|
||||
@ -828,7 +829,7 @@ func TestFill2(t *testing.T) {
|
||||
dst := NewImage(w, h, false)
|
||||
vs := quadVertices(w, h, 0, 0)
|
||||
is := graphics.QuadIndices()
|
||||
dst.DrawTriangles([graphics.ShaderImageNum]*Image{src}, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
dst.DrawTriangles([graphics.ShaderImageNum]*Image{src}, [graphics.ShaderImageNum - 1][2]float32{}, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
|
||||
// Fill src with a different color. This should not affect dst.
|
||||
src.Fill(color.RGBA{0, 0xff, 0, 0xff})
|
||||
@ -867,7 +868,7 @@ func TestMutateSlices(t *testing.T) {
|
||||
vs := quadVertices(w, h, 0, 0)
|
||||
is := make([]uint16, len(graphics.QuadIndices()))
|
||||
copy(is, graphics.QuadIndices())
|
||||
dst.DrawTriangles([graphics.ShaderImageNum]*Image{src}, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
dst.DrawTriangles([graphics.ShaderImageNum]*Image{src}, [graphics.ShaderImageNum - 1][2]float32{}, vs, is, nil, driver.CompositeModeSourceOver, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
for i := range vs {
|
||||
vs[i] = 0
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ func TestShader(t *testing.T) {
|
||||
|
||||
ir := etesting.ShaderProgramFill(0xff, 0, 0, 0xff)
|
||||
s := NewShader(&ir)
|
||||
img.DrawTriangles([graphics.ShaderImageNum]*Image{}, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, s, nil)
|
||||
img.DrawTriangles([graphics.ShaderImageNum]*Image{}, [graphics.ShaderImageNum - 1][2]float32{}, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, s, nil)
|
||||
|
||||
if err := ResolveStaleImages(); err != nil {
|
||||
t.Fatal(err)
|
||||
@ -69,7 +69,7 @@ func TestShaderChain(t *testing.T) {
|
||||
ir := etesting.ShaderProgramImages(1)
|
||||
s := NewShader(&ir)
|
||||
for i := 0; i < num-1; i++ {
|
||||
imgs[i+1].DrawTriangles([graphics.ShaderImageNum]*Image{imgs[i]}, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, s, nil)
|
||||
imgs[i+1].DrawTriangles([graphics.ShaderImageNum]*Image{imgs[i]}, [graphics.ShaderImageNum - 1][2]float32{}, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, s, nil)
|
||||
}
|
||||
|
||||
if err := ResolveStaleImages(); err != nil {
|
||||
@ -105,7 +105,48 @@ func TestShaderMultipleSources(t *testing.T) {
|
||||
|
||||
ir := etesting.ShaderProgramImages(3)
|
||||
s := NewShader(&ir)
|
||||
dst.DrawTriangles(srcs, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, s, nil)
|
||||
var offsets [graphics.ShaderImageNum - 1][2]float32
|
||||
dst.DrawTriangles(srcs, offsets, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, s, nil)
|
||||
|
||||
// Clear one of the sources after DrawTriangles. dst should not be affected.
|
||||
srcs[0].Fill(color.RGBA{})
|
||||
|
||||
if err := ResolveStaleImages(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := RestoreIfNeeded(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
want := color.RGBA{0x40, 0x80, 0xc0, 0xff}
|
||||
got := pixelsToColor(dst.BasePixelsForTesting(), 0, 0)
|
||||
if !sameColors(got, want, 1) {
|
||||
t.Errorf("got %v, want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestShaderMultipleSourcesOnOneTexture(t *testing.T) {
|
||||
if !graphicscommand.IsShaderAvailable() {
|
||||
t.Skip("shader is not available on this environment")
|
||||
}
|
||||
|
||||
var srcs [graphics.ShaderImageNum]*Image
|
||||
srcs[0] = NewImage(3, 1, false)
|
||||
srcs[0].ReplacePixels([]byte{
|
||||
0x40, 0, 0, 0xff,
|
||||
0, 0x80, 0, 0xff,
|
||||
0, 0, 0xc0, 0xff,
|
||||
}, 0, 0, 3, 1)
|
||||
|
||||
dst := NewImage(1, 1, false)
|
||||
|
||||
ir := etesting.ShaderProgramImages(3)
|
||||
s := NewShader(&ir)
|
||||
offsets := [graphics.ShaderImageNum - 1][2]float32{
|
||||
{1, 0},
|
||||
{2, 0},
|
||||
}
|
||||
dst.DrawTriangles(srcs, offsets, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, s, nil)
|
||||
|
||||
// Clear one of the sources after DrawTriangles. dst should not be affected.
|
||||
srcs[0].Fill(color.RGBA{})
|
||||
@ -134,7 +175,7 @@ func TestShaderDispose(t *testing.T) {
|
||||
|
||||
ir := etesting.ShaderProgramFill(0xff, 0, 0, 0xff)
|
||||
s := NewShader(&ir)
|
||||
img.DrawTriangles([graphics.ShaderImageNum]*Image{}, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, s, nil)
|
||||
img.DrawTriangles([graphics.ShaderImageNum]*Image{}, [graphics.ShaderImageNum - 1][2]float32{}, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, s, nil)
|
||||
|
||||
// Dispose the shader. This should invalidates all the images using this shader i.e., all the images become
|
||||
// stale.
|
||||
|
@ -181,6 +181,12 @@ func (cs *compileState) parse(f *ast.File) {
|
||||
utypes = append(utypes, cs.ir.Uniforms[i])
|
||||
}
|
||||
}
|
||||
// TODO: Check len(unames) == graphics.PreservedUniformVariablesNum. Unfortunately this is not true on tests.
|
||||
for _, t := range utypes {
|
||||
if got, want := t.Main, shaderir.Vec2; got != want {
|
||||
panic(fmt.Sprintf("shader: all the preserved uniform variables' types must be %v but %v", want, got))
|
||||
}
|
||||
}
|
||||
for i, u := range cs.uniforms {
|
||||
if !strings.HasPrefix(u, "__") {
|
||||
unames = append(unames, u)
|
||||
|
@ -220,7 +220,9 @@ func (i *Image) ensureNotShared() {
|
||||
dx1, dy1, sx1, sy1, 1, 1, 1, 1,
|
||||
}
|
||||
is := graphics.QuadIndices()
|
||||
newImg.DrawTriangles([graphics.ShaderImageNum]*restorable.Image{i.backend.restorable}, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
srcs := [graphics.ShaderImageNum]*restorable.Image{i.backend.restorable}
|
||||
var offsets [graphics.ShaderImageNum - 1][2]float32
|
||||
newImg.DrawTriangles(srcs, offsets, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil)
|
||||
|
||||
i.dispose(false)
|
||||
i.backend = &backend{
|
||||
@ -322,7 +324,6 @@ func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []f
|
||||
dy = paddingSize
|
||||
}
|
||||
|
||||
// TODO: Pass the offsets as uniform variables for second and following images.
|
||||
var oxf, oyf float32
|
||||
if srcs[0] != nil {
|
||||
ox, oy, _, _ := srcs[0].regionWithPadding()
|
||||
@ -342,6 +343,19 @@ func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []f
|
||||
}
|
||||
}
|
||||
|
||||
var offsets [graphics.ShaderImageNum - 1][2]float32
|
||||
for i := range offsets {
|
||||
src := srcs[i+1]
|
||||
if src == nil {
|
||||
continue
|
||||
}
|
||||
ox, oy, _, _ := src.regionWithPadding()
|
||||
ox += paddingSize
|
||||
oy += paddingSize
|
||||
offsets[i][0] = float32(ox) - oxf
|
||||
offsets[i][1] = float32(oy) - oyf
|
||||
}
|
||||
|
||||
var s *restorable.Shader
|
||||
if shader != nil {
|
||||
s = shader.shader
|
||||
@ -355,7 +369,7 @@ func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []f
|
||||
imgs[i] = src.backend.restorable
|
||||
}
|
||||
|
||||
i.backend.restorable.DrawTriangles(imgs, vertices, indices, colorm, mode, filter, address, sourceRegion, s, uniforms)
|
||||
i.backend.restorable.DrawTriangles(imgs, offsets, vertices, indices, colorm, mode, filter, address, sourceRegion, s, uniforms)
|
||||
|
||||
i.nonUpdatedCount = 0
|
||||
delete(imagesToMakeShared, i)
|
||||
|
@ -17,6 +17,7 @@ package testing
|
||||
import (
|
||||
"go/constant"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/internal/graphics"
|
||||
"github.com/hajimehoshi/ebiten/internal/shaderir"
|
||||
)
|
||||
|
||||
@ -210,10 +211,7 @@ var (
|
||||
)
|
||||
|
||||
func defaultProgram() shaderir.Program {
|
||||
return shaderir.Program{
|
||||
Uniforms: []shaderir.Type{
|
||||
{Main: shaderir.Vec2}, // Viewport size. This must be the first uniform variable, and the values are set at graphicscommand driver.
|
||||
},
|
||||
p := shaderir.Program{
|
||||
Attributes: []shaderir.Type{
|
||||
{Main: shaderir.Vec2}, // Local var (0) in the vertex shader
|
||||
{Main: shaderir.Vec2}, // Local var (1) in the vertex shader
|
||||
@ -225,6 +223,12 @@ func defaultProgram() shaderir.Program {
|
||||
},
|
||||
VertexFunc: defaultVertexFunc,
|
||||
}
|
||||
|
||||
p.Uniforms = make([]shaderir.Type, graphics.PreservedUniformVariablesNum)
|
||||
for i := range p.Uniforms {
|
||||
p.Uniforms[i] = shaderir.Type{Main: shaderir.Vec2}
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// ShaderProgramFill returns a shader intermediate representation to fill the frambuffer.
|
||||
@ -340,6 +344,17 @@ func ShaderProgramImages(imageNum int) shaderir.Program {
|
||||
},
|
||||
}
|
||||
} else {
|
||||
texPos2 := shaderir.Expr{
|
||||
Type: shaderir.Binary,
|
||||
Op: shaderir.Add,
|
||||
Exprs: []shaderir.Expr{
|
||||
texPos,
|
||||
{
|
||||
Type: shaderir.UniformVariable,
|
||||
Index: 1 + i - 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
rhs = shaderir.Expr{
|
||||
Type: shaderir.Binary,
|
||||
Op: shaderir.Add,
|
||||
@ -356,7 +371,7 @@ func ShaderProgramImages(imageNum int) shaderir.Program {
|
||||
Type: shaderir.TextureVariable,
|
||||
Index: i,
|
||||
},
|
||||
texPos,
|
||||
texPos2,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
34
shader.go
34
shader.go
@ -19,14 +19,16 @@ import (
|
||||
"fmt"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"strings"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/internal/buffered"
|
||||
"github.com/hajimehoshi/ebiten/internal/graphics"
|
||||
"github.com/hajimehoshi/ebiten/internal/shader"
|
||||
)
|
||||
|
||||
var shaderSuffix = `
|
||||
var shaderSuffix string
|
||||
|
||||
func init() {
|
||||
shaderSuffix = `
|
||||
var __viewportSize vec2
|
||||
|
||||
func viewportSize() vec2 {
|
||||
@ -34,18 +36,24 @@ func viewportSize() vec2 {
|
||||
}
|
||||
`
|
||||
|
||||
func init() {
|
||||
// __t%d is a special variable for a texture variable.
|
||||
// TODO: Add appropriate offsets for second and following images.
|
||||
|
||||
var fs []string
|
||||
for i := 0; i < graphics.ShaderImageNum; i++ {
|
||||
fs = append(fs, fmt.Sprintf(`func texture%[1]dAt(pos vec2) vec4 {
|
||||
return texture2D(__t%[1]d, pos)
|
||||
}
|
||||
`, i))
|
||||
for i := 1; i < graphics.ShaderImageNum; i++ {
|
||||
shaderSuffix += fmt.Sprintf(`
|
||||
var __offset%d vec2
|
||||
`, i)
|
||||
}
|
||||
|
||||
for i := 0; i < graphics.ShaderImageNum; i++ {
|
||||
var offset string
|
||||
if i >= 1 {
|
||||
offset = fmt.Sprintf(" + __offset%d", i)
|
||||
}
|
||||
// __t%d is a special variable for a texture variable.
|
||||
shaderSuffix += fmt.Sprintf(`
|
||||
func texture%[1]dAt(pos vec2) vec4 {
|
||||
return texture2D(__t%[1]d, pos%[2]s)
|
||||
}
|
||||
`, i, offset)
|
||||
}
|
||||
shaderSuffix += "\n" + strings.Join(fs, "\n")
|
||||
}
|
||||
|
||||
type Shader struct {
|
||||
|
Loading…
Reference in New Issue
Block a user