It looks like this can be done with some use of shaders to preprocess the iRenderImage so that it has the right background color before the sprite is drawn to it. The problem is when the first sprite is drawn it is taking the clear color of iRenderImage and blending it into itself, so when you then take iRenderImage and blend it with something else the clear color of iRenderImage is influencing the final result. So one solution would to make sure the color under the sprite matches itself if it is the first sprite to draw at that location, then it won't be affected be the clear color of iRenderImage. We can do this by keeping a separate image the same size as iRenderImage which is white where sprites have drawn and black where nothing has yet been drawn, as a sort of mask. We can then use a shader with the brush sprite that checks the mask image, if the mask image tells the shader that the brush sprite is drawing to a new (black) area of iRenderImage then it first draws its color to iRenderImage without alpha blending, then draws itself normally so it blends with its own color instead of the clear color of iRenderImage. Subsequent sprites will then blend normally with other sprites, and skip the non-blending step if a sprite has already drawn at that location in iRenderImage.
Here's the new code I came up with
SetWindowTitle( "RenderToImage" )
SetWindowSize( 1024, 768, 0 )
SetVirtualResolution( 1024, 768 )
SetClearColor(100,100,100)
SetPrintSize(20)
SetPrintColor(0,0,0)
// Load a brush sprite
global BG
BG = CreateSprite(0)
SetSpriteSize(bg,1024,768)
SetSpriteColor(bg,120,220,220,255)
global brush
Brush = CreateSprite(0)
//SetSpriteTransparency(brush,0) // if I uncomment that, I lost the transparency shades
SetSpriteSize(brush,80,80)
SetSpriteColorAlpha(brush,60)
LoadShader( 1, "painter.vs", "painter.ps" )
LoadShader( 2, "mask.vs", "mask.ps" )
// Create the image to render onto
global iRenderImage
global iRenderMask
iRenderImage = CreateRenderImage(1024,768,0,0)
iRenderMask = CreateRenderImage(1024,768,0,0) // mask image will be white where sprites have drawn and black otherwise
// Set RenderToImage
SetClearColor(0,0,0)
SetRenderToImage(iRenderImage,0)
ClearScreen()
SetRenderToImage(iRenderMask,0)
ClearScreen()
SetRenderToScreen()
// Create the final sprite which will use the iRenderImage.
global LAyer
Layer = CreateSprite(iRenderImage)
SetSpritePosition(Layer,0,0)
SetSpriteTransparency(Layer,1)
SetSpritePosition(brush,-100000,0)
global R,g,b,A as integer
R = 255
G = 255
B = 255
A = 60
do
if GetPointerState()
paint(getpointerx(),getpointerY())
endif
if GetRawKeyPressed(65)
SaveImage(iRenderImage,"test.png")
endif
if GetRawKeyState(66 ) = 1 // B
inc B
if b>255
B= 0
endif
SetSpriteColorBlue(brush,B)
endif
if GetRawKeyState(67 ) = 1 // C
inc G
if G>255
G= 0
endif
SetSpriteColorGreen(brush,G)
endif
if GetRawKeyState(68 ) = 1 // D
inc R
if R>255
R= 0
endif
SetSpriteColorRed(brush,R)
endif
if GetRawKeyState(69 ) = 1 // E
inc A
if A>255
A= 0
endif
SetSpriteColorAlpha(brush,A)
endif
print("R : "+str(R)+" / G : "+str(G)+" / B : "+str(B)+" / A : "+str(A))
Sync()
loop
function Paint(x,y)
SetRenderToImage(iRenderImage,0)
SetSpritePositionByOffset(brush,x,y)
SetSpriteAngle(brush,random(0,360))
// set iRenderImage color to equal current sprite if no other sprites have drawn here
SetSpriteTransparency( brush, 0 ) // we want to overwrite the current color, not blend it
SetSpriteImage( brush, iRenderMask ) // image to tell the shader where other sprites have drawn
SetSpriteShader( brush, 1 )
DrawSprite(brush)
// draw sprite normally
SetSpriteTransparency( brush, 1 )
SetSpriteImage( brush, 0 )
SetSpriteShader( brush, 0 )
DrawSprite(brush)
// draw to mask so other sprites know that something has drawn here
SetRenderToImage(iRenderMask,0)
SetSpriteTransparency( brush, 0 )
SetSpriteImage( brush, 0 )
SetSpriteShader( brush, 2 )
DrawSprite(brush)
SetRenderToScreen()
deletesprite(layer)
// Create the final sprite which will use the iRenderImage.
Layer = CreateSprite(iRenderImage)
SetSpritePosition(Layer,0,0)
SetSpriteTransparency(Layer,1)
SetSpritePosition(brush,-100000,0) // hide the brush
EndFunction
You will need the attached shaders in your media folder