mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-13 22:47:26 +01:00
Compare commits
7 Commits
a666f485b8
...
142f503456
Author | SHA1 | Date | |
---|---|---|---|
|
142f503456 | ||
|
5b54a1d8b7 | ||
|
483059184f | ||
|
dc6074bec9 | ||
|
dbe06ec468 | ||
|
d706d38ada | ||
|
0b53525808 |
9
image.go
9
image.go
@ -711,10 +711,8 @@ func (i *Image) DrawTrianglesShader(vertices []Vertex, indices []uint16, shader
|
||||
//
|
||||
// When the image i is disposed, DrawTrianglesShader does nothing.
|
||||
func DrawTrianglesShaderMRT(dsts [graphics.ShaderDstImageCount]*Image, vertices []Vertex, indices []uint16, shader *Shader, options *DrawTrianglesShaderOptions) {
|
||||
if dsts[0] == nil || dsts[0].isDisposed() {
|
||||
panic("ebiten: the first destination image given to DrawTrianglesShaderMRT must not be nil or disposed")
|
||||
}
|
||||
var dstImgs [graphics.ShaderDstImageCount]*ui.Image
|
||||
var firstDst *Image
|
||||
for i, dst := range dsts {
|
||||
if dst == nil {
|
||||
continue
|
||||
@ -723,6 +721,9 @@ func DrawTrianglesShaderMRT(dsts [graphics.ShaderDstImageCount]*Image, vertices
|
||||
if dst.isDisposed() {
|
||||
panic("ebiten: the destination images given to DrawTrianglesShaderMRT must not be disposed")
|
||||
}
|
||||
if firstDst == nil {
|
||||
firstDst = dst
|
||||
}
|
||||
dstImgs[i] = dst.image
|
||||
}
|
||||
|
||||
@ -754,7 +755,7 @@ func DrawTrianglesShaderMRT(dsts [graphics.ShaderDstImageCount]*Image, vertices
|
||||
blend = options.CompositeMode.blend().internalBlend()
|
||||
}
|
||||
|
||||
dst := dsts[0]
|
||||
dst := firstDst
|
||||
vs := dst.ensureTmpVertices(len(vertices) * graphics.VertexFloatCount)
|
||||
src := options.Images[0]
|
||||
for i, v := range vertices {
|
||||
|
@ -576,12 +576,14 @@ func drawTrianglesMRT(dsts [graphics.ShaderDstImageCount]*Image, srcs [graphics.
|
||||
src.backend.sourceInThisFrame = true
|
||||
}
|
||||
|
||||
var firstDst *Image
|
||||
var dstImgs [graphics.ShaderDstImageCount]*graphicscommand.Image
|
||||
for i, dst := range dsts {
|
||||
if dst == nil {
|
||||
continue
|
||||
}
|
||||
dst.ensureIsolatedFromSource(backends)
|
||||
firstDst = dst
|
||||
dstImgs[i] = dst.backend.image
|
||||
}
|
||||
|
||||
@ -595,7 +597,7 @@ func drawTrianglesMRT(dsts [graphics.ShaderDstImageCount]*Image, srcs [graphics.
|
||||
}
|
||||
}
|
||||
|
||||
r := dsts[0].regionWithPadding()
|
||||
r := firstDst.regionWithPadding()
|
||||
// TODO: Check if dstRegion does not to violate the region.
|
||||
dstRegion = dstRegion.Add(r.Min)
|
||||
|
||||
|
@ -330,7 +330,14 @@ func (q *commandQueue) prependPreservedUniforms(uniforms []uint32, shader *Shade
|
||||
copy(uniforms[graphics.PreservedUniformUint32Count:], origUniforms)
|
||||
|
||||
// Set the destination texture size.
|
||||
dw, dh := dsts[0].InternalSize()
|
||||
var firstDst *Image
|
||||
for _, dst := range dsts {
|
||||
if dst != nil {
|
||||
firstDst = dst
|
||||
break
|
||||
}
|
||||
}
|
||||
dw, dh := firstDst.InternalSize()
|
||||
uniforms[0] = math.Float32bits(float32(dw))
|
||||
uniforms[1] = math.Float32bits(float32(dh))
|
||||
uniformIndex := 2
|
||||
|
@ -517,30 +517,31 @@ func (g *graphics11) removeShader(s *shader11) {
|
||||
|
||||
func (g *graphics11) setAsRenderTargets(dsts []*image11, useStencil bool) error {
|
||||
var rtvs []*_ID3D11RenderTargetView
|
||||
for _, i := range dsts {
|
||||
var dsv *_ID3D11DepthStencilView
|
||||
for _, dst := range dsts {
|
||||
// Ignore a nil image in case of MRT
|
||||
if i == nil {
|
||||
if dst == nil {
|
||||
rtvs = append(rtvs, nil)
|
||||
continue
|
||||
}
|
||||
if i.renderTargetView == nil {
|
||||
rtv, err := g.device.CreateRenderTargetView(unsafe.Pointer(i.texture), nil)
|
||||
if dst.renderTargetView == nil {
|
||||
rtv, err := g.device.CreateRenderTargetView(unsafe.Pointer(dst.texture), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i.renderTargetView = rtv
|
||||
dst.renderTargetView = rtv
|
||||
}
|
||||
rtvs = append(rtvs, i.renderTargetView)
|
||||
rtvs = append(rtvs, dst.renderTargetView)
|
||||
|
||||
if !useStencil {
|
||||
if !useStencil || dsv != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if i.screen {
|
||||
if dst.screen {
|
||||
return fmt.Errorf("directx: a stencil buffer is not available for a screen image")
|
||||
}
|
||||
if i.stencil == nil {
|
||||
w, h := i.internalSize()
|
||||
if dst.stencil == nil {
|
||||
w, h := dst.internalSize()
|
||||
s, err := g.device.CreateTexture2D(&_D3D11_TEXTURE2D_DESC{
|
||||
Width: uint32(w),
|
||||
Height: uint32(h),
|
||||
@ -559,20 +560,21 @@ func (g *graphics11) setAsRenderTargets(dsts []*image11, useStencil bool) error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i.stencil = s
|
||||
dst.stencil = s
|
||||
}
|
||||
if i.stencilView == nil {
|
||||
sv, err := g.device.CreateDepthStencilView(unsafe.Pointer(i.stencil), nil)
|
||||
if dst.stencilView == nil {
|
||||
sv, err := g.device.CreateDepthStencilView(unsafe.Pointer(dst.stencil), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i.stencilView = sv
|
||||
dst.stencilView = sv
|
||||
}
|
||||
dsv = dst.stencilView
|
||||
}
|
||||
|
||||
g.deviceContext.OMSetRenderTargets(rtvs, dsts[0].stencilView)
|
||||
g.deviceContext.OMSetRenderTargets(rtvs, dsv)
|
||||
if useStencil {
|
||||
g.deviceContext.ClearDepthStencilView(dsts[0].stencilView, uint8(_D3D11_CLEAR_STENCIL), 0, 0)
|
||||
g.deviceContext.ClearDepthStencilView(dsv, uint8(_D3D11_CLEAR_STENCIL), 0, 0)
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -585,7 +587,7 @@ func (g *graphics11) DrawTriangles(dstIDs [graphics.ShaderDstImageCount]graphics
|
||||
g.deviceContext.PSSetShaderResources(0, srvs[:])
|
||||
|
||||
var dsts [graphics.ShaderDstImageCount]*image11
|
||||
var viewports [graphics.ShaderDstImageCount]_D3D11_VIEWPORT
|
||||
var vp _D3D11_VIEWPORT
|
||||
var targetCount int
|
||||
firstTarget := -1
|
||||
for i, id := range dstIDs {
|
||||
@ -598,7 +600,7 @@ func (g *graphics11) DrawTriangles(dstIDs [graphics.ShaderDstImageCount]graphics
|
||||
}
|
||||
dsts[i] = img
|
||||
w, h := img.internalSize()
|
||||
viewports[i] = _D3D11_VIEWPORT{
|
||||
vp = _D3D11_VIEWPORT{
|
||||
TopLeftX: 0,
|
||||
TopLeftY: 0,
|
||||
Width: float32(w),
|
||||
@ -621,13 +623,12 @@ func (g *graphics11) DrawTriangles(dstIDs [graphics.ShaderDstImageCount]graphics
|
||||
// If the number of targets is more than one, or if the only target is the first one, then
|
||||
// it is safe to assume that MRT is used.
|
||||
// Also, it only matters in order to specify empty targets/viewports when not all slots are
|
||||
// being filled.
|
||||
// being filled, even though it's not a MRT scenario.
|
||||
if targetCount > 1 || firstTarget > 0 {
|
||||
targetCount = graphics.ShaderDstImageCount
|
||||
}
|
||||
|
||||
g.deviceContext.RSSetViewports(viewports[:targetCount])
|
||||
|
||||
g.deviceContext.RSSetViewports([]_D3D11_VIEWPORT{vp})
|
||||
if err := g.setAsRenderTargets(dsts[:targetCount], fillRule != graphicsdriver.FillAll); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -1084,7 +1084,7 @@ func (g *graphics12) NewShader(program *shaderir.Program) (graphicsdriver.Shader
|
||||
|
||||
func (g *graphics12) setAsRenderTargets(dsts []*image12, useStencil bool) error {
|
||||
var rtvs []_D3D12_CPU_DESCRIPTOR_HANDLE
|
||||
var dsvPtr *_D3D12_CPU_DESCRIPTOR_HANDLE
|
||||
var dsv *_D3D12_CPU_DESCRIPTOR_HANDLE
|
||||
|
||||
for i, img := range dsts {
|
||||
// Ignore a nil image in case of MRT
|
||||
@ -1127,18 +1127,18 @@ func (g *graphics12) setAsRenderTargets(dsts []*image12, useStencil bool) error
|
||||
rtv := rtvBase
|
||||
rtvs = append(rtvs, rtv)
|
||||
|
||||
if !useStencil || dsvPtr != nil {
|
||||
if !useStencil || dsv != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := img.ensureDepthStencilView(g.device); err != nil {
|
||||
return err
|
||||
}
|
||||
dsv, err := img.dsvDescriptorHeap.GetCPUDescriptorHandleForHeapStart()
|
||||
sv, err := img.dsvDescriptorHeap.GetCPUDescriptorHandleForHeapStart()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dsvPtr = &dsv
|
||||
dsv = &sv
|
||||
}
|
||||
|
||||
if !useStencil {
|
||||
@ -1147,8 +1147,8 @@ func (g *graphics12) setAsRenderTargets(dsts []*image12, useStencil bool) error
|
||||
}
|
||||
|
||||
g.drawCommandList.OMSetStencilRef(0)
|
||||
g.drawCommandList.OMSetRenderTargets(rtvs, false, dsvPtr)
|
||||
g.drawCommandList.ClearDepthStencilView(*dsvPtr, _D3D12_CLEAR_FLAG_STENCIL, 0, 0, nil)
|
||||
g.drawCommandList.OMSetRenderTargets(rtvs, false, dsv)
|
||||
g.drawCommandList.ClearDepthStencilView(*dsv, _D3D12_CLEAR_FLAG_STENCIL, 0, 0, nil)
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -1177,7 +1177,7 @@ func (g *graphics12) DrawTriangles(dstIDs [graphics.ShaderDstImageCount]graphics
|
||||
var resourceBarriers []_D3D12_RESOURCE_BARRIER_Transition
|
||||
|
||||
var dsts [graphics.ShaderDstImageCount]*image12
|
||||
var viewports [graphics.ShaderDstImageCount]_D3D12_VIEWPORT
|
||||
var vp _D3D12_VIEWPORT
|
||||
var targetCount int
|
||||
firstTarget := -1
|
||||
for i, id := range dstIDs {
|
||||
@ -1190,7 +1190,7 @@ func (g *graphics12) DrawTriangles(dstIDs [graphics.ShaderDstImageCount]graphics
|
||||
}
|
||||
dsts[i] = img
|
||||
w, h := img.internalSize()
|
||||
viewports[i] = _D3D12_VIEWPORT{
|
||||
vp = _D3D12_VIEWPORT{
|
||||
TopLeftX: 0,
|
||||
TopLeftY: 0,
|
||||
Width: float32(w),
|
||||
@ -1225,14 +1225,12 @@ func (g *graphics12) DrawTriangles(dstIDs [graphics.ShaderDstImageCount]graphics
|
||||
// If the number of targets is more than one, or if the only target is the first one, then
|
||||
// it is safe to assume that MRT is used.
|
||||
// Also, it only matters in order to specify empty targets/viewports when not all slots are
|
||||
// being filled.
|
||||
// being filled, even though it's not a MRT scenario.
|
||||
usesMRT := targetCount > 1 || firstTarget > 0
|
||||
if usesMRT {
|
||||
targetCount = graphics.ShaderDstImageCount
|
||||
}
|
||||
|
||||
g.drawCommandList.RSSetViewports(viewports[:targetCount])
|
||||
|
||||
if err := g.setAsRenderTargets(dsts[:targetCount], fillRule != graphicsdriver.FillAll); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1242,6 +1240,8 @@ func (g *graphics12) DrawTriangles(dstIDs [graphics.ShaderDstImageCount]graphics
|
||||
|
||||
g.needFlushDrawCommandList = true
|
||||
|
||||
g.drawCommandList.RSSetViewports([]_D3D12_VIEWPORT{vp})
|
||||
|
||||
g.drawCommandList.IASetPrimitiveTopology(_D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST)
|
||||
g.drawCommandList.IASetVertexBuffers(0, []_D3D12_VERTEX_BUFFER_VIEW{
|
||||
{
|
||||
|
@ -70,7 +70,7 @@ func (i *image12) disposeImpl() {
|
||||
|
||||
func (i *image12) ReadPixels(args []graphicsdriver.PixelsArgs) error {
|
||||
if i.screen {
|
||||
return errors.New("directx: Pixels cannot be called on the screen")
|
||||
return errors.New("directx: ReadPixels cannot be called on the screen")
|
||||
}
|
||||
|
||||
if err := i.graphics.flushCommandList(i.graphics.drawCommandList); err != nil {
|
||||
|
@ -484,6 +484,18 @@ func (p *pipelineStates) newPipelineState(device *_ID3D12Device, vsh, psh *_ID3D
|
||||
}
|
||||
|
||||
// Create a pipeline state.
|
||||
rtBlendDesc := _D3D12_RENDER_TARGET_BLEND_DESC{
|
||||
BlendEnable: 1,
|
||||
LogicOpEnable: 0,
|
||||
SrcBlend: blendFactorToBlend12(blend.BlendFactorSourceRGB, false),
|
||||
DestBlend: blendFactorToBlend12(blend.BlendFactorDestinationRGB, false),
|
||||
BlendOp: blendOperationToBlendOp12(blend.BlendOperationRGB),
|
||||
SrcBlendAlpha: blendFactorToBlend12(blend.BlendFactorSourceAlpha, true),
|
||||
DestBlendAlpha: blendFactorToBlend12(blend.BlendFactorDestinationAlpha, true),
|
||||
BlendOpAlpha: blendOperationToBlendOp12(blend.BlendOperationAlpha),
|
||||
LogicOp: _D3D12_LOGIC_OP_NOOP,
|
||||
RenderTargetWriteMask: writeMask,
|
||||
}
|
||||
psoDesc := _D3D12_GRAPHICS_PIPELINE_STATE_DESC{
|
||||
pRootSignature: rootSignature,
|
||||
VS: _D3D12_SHADER_BYTECODE{
|
||||
@ -498,102 +510,7 @@ func (p *pipelineStates) newPipelineState(device *_ID3D12Device, vsh, psh *_ID3D
|
||||
AlphaToCoverageEnable: 0,
|
||||
IndependentBlendEnable: 0,
|
||||
RenderTarget: [8]_D3D12_RENDER_TARGET_BLEND_DESC{
|
||||
{
|
||||
BlendEnable: 1,
|
||||
LogicOpEnable: 0,
|
||||
SrcBlend: blendFactorToBlend12(blend.BlendFactorSourceRGB, false),
|
||||
DestBlend: blendFactorToBlend12(blend.BlendFactorDestinationRGB, false),
|
||||
BlendOp: blendOperationToBlendOp12(blend.BlendOperationRGB),
|
||||
SrcBlendAlpha: blendFactorToBlend12(blend.BlendFactorSourceAlpha, true),
|
||||
DestBlendAlpha: blendFactorToBlend12(blend.BlendFactorDestinationAlpha, true),
|
||||
BlendOpAlpha: blendOperationToBlendOp12(blend.BlendOperationAlpha),
|
||||
LogicOp: _D3D12_LOGIC_OP_NOOP,
|
||||
RenderTargetWriteMask: writeMask,
|
||||
},
|
||||
{
|
||||
BlendEnable: 1,
|
||||
LogicOpEnable: 0,
|
||||
SrcBlend: blendFactorToBlend12(blend.BlendFactorSourceRGB, false),
|
||||
DestBlend: blendFactorToBlend12(blend.BlendFactorDestinationRGB, false),
|
||||
BlendOp: blendOperationToBlendOp12(blend.BlendOperationRGB),
|
||||
SrcBlendAlpha: blendFactorToBlend12(blend.BlendFactorSourceAlpha, true),
|
||||
DestBlendAlpha: blendFactorToBlend12(blend.BlendFactorDestinationAlpha, true),
|
||||
BlendOpAlpha: blendOperationToBlendOp12(blend.BlendOperationAlpha),
|
||||
LogicOp: _D3D12_LOGIC_OP_NOOP,
|
||||
RenderTargetWriteMask: writeMask,
|
||||
},
|
||||
{
|
||||
BlendEnable: 1,
|
||||
LogicOpEnable: 0,
|
||||
SrcBlend: blendFactorToBlend12(blend.BlendFactorSourceRGB, false),
|
||||
DestBlend: blendFactorToBlend12(blend.BlendFactorDestinationRGB, false),
|
||||
BlendOp: blendOperationToBlendOp12(blend.BlendOperationRGB),
|
||||
SrcBlendAlpha: blendFactorToBlend12(blend.BlendFactorSourceAlpha, true),
|
||||
DestBlendAlpha: blendFactorToBlend12(blend.BlendFactorDestinationAlpha, true),
|
||||
BlendOpAlpha: blendOperationToBlendOp12(blend.BlendOperationAlpha),
|
||||
LogicOp: _D3D12_LOGIC_OP_NOOP,
|
||||
RenderTargetWriteMask: writeMask,
|
||||
},
|
||||
{
|
||||
BlendEnable: 1,
|
||||
LogicOpEnable: 0,
|
||||
SrcBlend: blendFactorToBlend12(blend.BlendFactorSourceRGB, false),
|
||||
DestBlend: blendFactorToBlend12(blend.BlendFactorDestinationRGB, false),
|
||||
BlendOp: blendOperationToBlendOp12(blend.BlendOperationRGB),
|
||||
SrcBlendAlpha: blendFactorToBlend12(blend.BlendFactorSourceAlpha, true),
|
||||
DestBlendAlpha: blendFactorToBlend12(blend.BlendFactorDestinationAlpha, true),
|
||||
BlendOpAlpha: blendOperationToBlendOp12(blend.BlendOperationAlpha),
|
||||
LogicOp: _D3D12_LOGIC_OP_NOOP,
|
||||
RenderTargetWriteMask: writeMask,
|
||||
},
|
||||
{
|
||||
BlendEnable: 1,
|
||||
LogicOpEnable: 0,
|
||||
SrcBlend: blendFactorToBlend12(blend.BlendFactorSourceRGB, false),
|
||||
DestBlend: blendFactorToBlend12(blend.BlendFactorDestinationRGB, false),
|
||||
BlendOp: blendOperationToBlendOp12(blend.BlendOperationRGB),
|
||||
SrcBlendAlpha: blendFactorToBlend12(blend.BlendFactorSourceAlpha, true),
|
||||
DestBlendAlpha: blendFactorToBlend12(blend.BlendFactorDestinationAlpha, true),
|
||||
BlendOpAlpha: blendOperationToBlendOp12(blend.BlendOperationAlpha),
|
||||
LogicOp: _D3D12_LOGIC_OP_NOOP,
|
||||
RenderTargetWriteMask: writeMask,
|
||||
},
|
||||
{
|
||||
BlendEnable: 1,
|
||||
LogicOpEnable: 0,
|
||||
SrcBlend: blendFactorToBlend12(blend.BlendFactorSourceRGB, false),
|
||||
DestBlend: blendFactorToBlend12(blend.BlendFactorDestinationRGB, false),
|
||||
BlendOp: blendOperationToBlendOp12(blend.BlendOperationRGB),
|
||||
SrcBlendAlpha: blendFactorToBlend12(blend.BlendFactorSourceAlpha, true),
|
||||
DestBlendAlpha: blendFactorToBlend12(blend.BlendFactorDestinationAlpha, true),
|
||||
BlendOpAlpha: blendOperationToBlendOp12(blend.BlendOperationAlpha),
|
||||
LogicOp: _D3D12_LOGIC_OP_NOOP,
|
||||
RenderTargetWriteMask: writeMask,
|
||||
},
|
||||
{
|
||||
BlendEnable: 1,
|
||||
LogicOpEnable: 0,
|
||||
SrcBlend: blendFactorToBlend12(blend.BlendFactorSourceRGB, false),
|
||||
DestBlend: blendFactorToBlend12(blend.BlendFactorDestinationRGB, false),
|
||||
BlendOp: blendOperationToBlendOp12(blend.BlendOperationRGB),
|
||||
SrcBlendAlpha: blendFactorToBlend12(blend.BlendFactorSourceAlpha, true),
|
||||
DestBlendAlpha: blendFactorToBlend12(blend.BlendFactorDestinationAlpha, true),
|
||||
BlendOpAlpha: blendOperationToBlendOp12(blend.BlendOperationAlpha),
|
||||
LogicOp: _D3D12_LOGIC_OP_NOOP,
|
||||
RenderTargetWriteMask: writeMask,
|
||||
},
|
||||
{
|
||||
BlendEnable: 1,
|
||||
LogicOpEnable: 0,
|
||||
SrcBlend: blendFactorToBlend12(blend.BlendFactorSourceRGB, false),
|
||||
DestBlend: blendFactorToBlend12(blend.BlendFactorDestinationRGB, false),
|
||||
BlendOp: blendOperationToBlendOp12(blend.BlendOperationRGB),
|
||||
SrcBlendAlpha: blendFactorToBlend12(blend.BlendFactorSourceAlpha, true),
|
||||
DestBlendAlpha: blendFactorToBlend12(blend.BlendFactorDestinationAlpha, true),
|
||||
BlendOpAlpha: blendOperationToBlendOp12(blend.BlendOperationAlpha),
|
||||
LogicOp: _D3D12_LOGIC_OP_NOOP,
|
||||
RenderTargetWriteMask: writeMask,
|
||||
},
|
||||
rtBlendDesc, // TODO: need to fill them all?
|
||||
},
|
||||
},
|
||||
SampleMask: math.MaxUint32,
|
||||
|
152
shader_test.go
152
shader_test.go
@ -2595,3 +2595,155 @@ func Fragment(dstPos vec4, srcPos vec2, color vec4) vec4 {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Issue #2930
|
||||
func TestShaderMRT(t *testing.T) {
|
||||
const w, h = 16, 16
|
||||
|
||||
s, err := ebiten.NewShader([]byte(`//kage:unit pixels
|
||||
|
||||
package main
|
||||
|
||||
func Fragment(dstPos vec4, srcPos vec2, color vec4) (vec4, vec4, vec4, vec4, vec4, vec4, vec4, vec4) {
|
||||
return vec4(1, 0, 0, 1),
|
||||
vec4(0, 1, 0, 1),
|
||||
vec4(0, 0, 1, 1),
|
||||
vec4(1, 0, 1, 1),
|
||||
vec4(1, 1, 0, 1),
|
||||
vec4(0, 1, 1, 1),
|
||||
vec4(1, 1, 1, 1),
|
||||
vec4(1, 1, 1, 0)
|
||||
}
|
||||
`))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
bounds := image.Rect(0, 0, w, h)
|
||||
opts := &ebiten.NewImageOptions{
|
||||
Unmanaged: true,
|
||||
}
|
||||
vertices := []ebiten.Vertex{
|
||||
{
|
||||
DstX: 0,
|
||||
DstY: 0,
|
||||
},
|
||||
{
|
||||
DstX: w,
|
||||
DstY: 0,
|
||||
},
|
||||
{
|
||||
DstX: 0,
|
||||
DstY: h,
|
||||
},
|
||||
{
|
||||
DstX: w,
|
||||
DstY: h,
|
||||
},
|
||||
}
|
||||
indices := []uint16{0, 1, 2, 1, 2, 3}
|
||||
t.Run("8 locations", func(t *testing.T) {
|
||||
imgs := [8]*ebiten.Image{
|
||||
ebiten.NewImageWithOptions(bounds, opts),
|
||||
ebiten.NewImageWithOptions(bounds, opts),
|
||||
ebiten.NewImageWithOptions(bounds, opts),
|
||||
ebiten.NewImageWithOptions(bounds, opts),
|
||||
ebiten.NewImageWithOptions(bounds, opts),
|
||||
ebiten.NewImageWithOptions(bounds, opts),
|
||||
ebiten.NewImageWithOptions(bounds, opts),
|
||||
ebiten.NewImageWithOptions(bounds, opts),
|
||||
}
|
||||
wantColors := [8]color.RGBA{
|
||||
{R: 0xff, G: 0, B: 0, A: 0xff},
|
||||
{R: 0, G: 0xff, B: 0, A: 0xff},
|
||||
{R: 0, G: 0, B: 0xff, A: 0xff},
|
||||
{R: 0xff, G: 0, B: 0xff, A: 0xff},
|
||||
{R: 0xff, G: 0xff, B: 0, A: 0xff},
|
||||
{R: 0, G: 0xff, B: 0xff, A: 0xff},
|
||||
{R: 0xff, G: 0xff, B: 0xff, A: 0xff},
|
||||
{R: 0xff, G: 0xff, B: 0xff, A: 0},
|
||||
}
|
||||
ebiten.DrawTrianglesShaderMRT(imgs, vertices, indices, s, nil)
|
||||
for k, dst := range imgs {
|
||||
for j := 0; j < h; j++ {
|
||||
for i := 0; i < w; i++ {
|
||||
got := dst.At(i, j).(color.RGBA)
|
||||
want := wantColors[k]
|
||||
if !sameColors(got, want, 1) {
|
||||
t.Errorf("dst.At(%d, %d): got: %v, want: %v", i, j, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
/*t.Run("Empty locations", func(t *testing.T) {
|
||||
imgs := [8]*ebiten.Image{
|
||||
ebiten.NewImageWithOptions(bounds, opts),
|
||||
ebiten.NewImageWithOptions(bounds, opts),
|
||||
ebiten.NewImageWithOptions(bounds, opts),
|
||||
ebiten.NewImageWithOptions(bounds, opts),
|
||||
ebiten.NewImageWithOptions(bounds, opts),
|
||||
ebiten.NewImageWithOptions(bounds, opts),
|
||||
ebiten.NewImageWithOptions(bounds, opts),
|
||||
ebiten.NewImageWithOptions(bounds, opts),
|
||||
}
|
||||
wantColors := [8]color.RGBA{
|
||||
{},
|
||||
{R: 0, G: 0xff, B: 0, A: 0xff},
|
||||
{},
|
||||
{R: 0xff, G: 0, B: 0xff, A: 0xff},
|
||||
{},
|
||||
{R: 0, G: 0xff, B: 0xff, A: 0xff},
|
||||
{},
|
||||
{R: 0xff, G: 0xff, B: 0xff, A: 0},
|
||||
}
|
||||
dsts := [8]*ebiten.Image{
|
||||
nil, imgs[1], nil, imgs[3], nil, imgs[5], nil, imgs[7],
|
||||
}
|
||||
ebiten.DrawTrianglesShaderMRT(dsts, vertices, indices, s, nil)
|
||||
for k, dst := range imgs {
|
||||
for j := 0; j < h; j++ {
|
||||
for i := 0; i < w; i++ {
|
||||
got := dst.At(i, j).(color.RGBA)
|
||||
want := wantColors[k]
|
||||
if !sameColors(got, want, 1) {
|
||||
t.Errorf("%d dst.At(%d, %d): got: %v, want: %v", k, i, j, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})*/
|
||||
|
||||
t.Run("1 location (first slot)", func(t *testing.T) {
|
||||
imgs := [8]*ebiten.Image{
|
||||
ebiten.NewImageWithOptions(bounds, opts),
|
||||
ebiten.NewImageWithOptions(bounds, opts),
|
||||
ebiten.NewImageWithOptions(bounds, opts),
|
||||
ebiten.NewImageWithOptions(bounds, opts),
|
||||
ebiten.NewImageWithOptions(bounds, opts),
|
||||
ebiten.NewImageWithOptions(bounds, opts),
|
||||
ebiten.NewImageWithOptions(bounds, opts),
|
||||
ebiten.NewImageWithOptions(bounds, opts),
|
||||
}
|
||||
wantColors := [8]color.RGBA{
|
||||
{R: 0xff, G: 0, B: 0, A: 0xff},
|
||||
{}, {}, {}, {}, {}, {}, {},
|
||||
}
|
||||
dsts := [8]*ebiten.Image{
|
||||
imgs[0], nil, nil, nil, nil, nil, nil, nil,
|
||||
}
|
||||
ebiten.DrawTrianglesShaderMRT(dsts, vertices, indices, s, nil)
|
||||
for k, dst := range imgs {
|
||||
for j := 0; j < h; j++ {
|
||||
for i := 0; i < w; i++ {
|
||||
got := dst.At(i, j).(color.RGBA)
|
||||
want := wantColors[k]
|
||||
if !sameColors(got, want, 1) {
|
||||
t.Errorf("dst.At(%d, %d): got: %v, want: %v", i, j, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user