PDA

View Full Version : fxsubtract possible?



Zimond
13-03-2014, 12:09 AM
In an older version of asphyre was a blendingeffect called fxsubtract. I used this effect to render holes into rendertargets by subtracting the color $ff000000 which made the alphachannel on the rendertarget go back to $00 (completly transparent)

With this trick i could create mirrors in my game engine which were defined by a rectangle and everything outside was subtracted.

I could re-enable the blending bug i mentioned in the unofficial release thread which actually exactly did that but that wouldn't work with DX11.

Zimond
17-03-2014, 11:04 PM
I cannot say I really understood how all this Source/Dest Blending stuff really works (all these values confuse me) but I was able to McGyver a solution that works in OpenGL, DX9 and DX11.

I added another Blendingeffect to Aspyhre.Canvas called beEraser.

In OpenGL.Canvas i added :


beEraser:
glBlendFuncSeparate(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);

In DirectX9.canvas :


beEraser:
with D3D9Device do
begin
SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ZERO);
SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA);

SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
end;

In DirectX11.Types i had to duplicate the function DX11CreateBasicBlendState so that alpha blend values can be changed :


function DX11CreateBasicBlendStateAlpha(SrcBlend, DestBlend,SrcAlpha,DestAlpha: D3D11_BLEND;
out BlendState: ID3D11BlendState): Boolean;
var
Desc: D3D11_BLEND_DESC;
begin
if (not Assigned(D3D11Device)) then
begin
BlendState:= nil;
Result:= False;
Exit;
end;

FillChar(Desc, SizeOf(D3D11_BLEND_DESC), 0);

Desc.RenderTarget[0].BlendEnable:= True;

Desc.RenderTarget[0].SrcBlend := SrcBlend;
Desc.RenderTarget[0].DestBlend:= DestBlend;
Desc.RenderTarget[0].BlendOp := D3D11_BLEND_OP_ADD;

Desc.RenderTarget[0].SrcBlendAlpha := SrcAlpha; //These 2 were predefined and could not be changed in the original function
Desc.RenderTarget[0].DestBlendAlpha:= DestAlpha;
Desc.RenderTarget[0].BlendOpAlpha := D3D11_BLEND_OP_ADD;

Desc.RenderTarget[0].RenderTargetWriteMask:= Ord(D3D11_COLOR_WRITE_ENABLE_ALL);

PushClearFPUState();
try
Result:= Succeeded(D3D11Device.CreateBlendState(Desc, BlendState));
finally
PopFPUState();
end;

if (not Result) then BlendState:= nil;
end;

and finally in directx11.canvas :


// "Eraser"
DX11CreateBasicBlendStateAlpha(D3D11_BLEND_ZERO, D3D11_BLEND_INV_SRC_ALPHA,D3D11_BLEND_ZERO,D3D11_B LEND_INV_SRC_ALPHA,
BlendingStates[beEraser]);

And now i can rip holes into my rendertargets again ^^