renderObjectFiltered method
Implementation
@override
void renderObjectFiltered(
RenderState renderState, RenderObject renderObject) {
final bounds = renderObject.bounds;
var filters = renderObject.filters;
final pixelRatio = math.sqrt(renderState.globalMatrix.det.abs());
var boundsLeft = bounds.left.floor();
var boundsTop = bounds.top.floor();
var boundsRight = bounds.right.ceil();
var boundsBottom = bounds.bottom.ceil();
for (var i = 0; i < filters.length; i++) {
final overlap = filters[i].overlap;
boundsLeft += overlap.left;
boundsTop += overlap.top;
boundsRight += overlap.right;
boundsBottom += overlap.bottom;
}
boundsLeft = (boundsLeft * pixelRatio).floor();
boundsTop = (boundsTop * pixelRatio).floor();
boundsRight = (boundsRight * pixelRatio).ceil();
boundsBottom = (boundsBottom * pixelRatio).ceil();
final boundsWidth = boundsRight - boundsLeft;
final boundsHeight = boundsBottom - boundsTop;
final initialRenderFrameBuffer = activeRenderFrameBuffer;
final initialProjectionMatrix = activeProjectionMatrix.clone();
RenderFrameBuffer? filterRenderFrameBuffer =
getRenderFrameBuffer(boundsWidth, boundsHeight);
final filterProjectionMatrix = Matrix3D.fromIdentity();
filterProjectionMatrix.scale(2.0 / boundsWidth, 2.0 / boundsHeight, 1.0);
filterProjectionMatrix.translate(-1.0, -1.0, 0.0);
var filterRenderState = RenderState(this);
filterRenderState.globalMatrix.scale(pixelRatio, pixelRatio);
filterRenderState.globalMatrix.translate(-boundsLeft, -boundsTop);
final renderFrameBufferMap = <int, RenderFrameBuffer?>{};
renderFrameBufferMap[0] = filterRenderFrameBuffer;
//----------------------------------------------
activateRenderFrameBuffer(filterRenderFrameBuffer);
activateProjectionMatrix(filterProjectionMatrix);
activateBlendMode(BlendMode.NORMAL);
clear(0);
if (filters.isEmpty) {
// Don't render anything
} else if (filters[0].isSimple &&
renderObject is _RenderTextureQuadObject) {
final renderTextureQuad = renderObject.renderTextureQuad;
renderTextureQuadFiltered(
filterRenderState, renderTextureQuad, [filters[0]]);
filters = filters.sublist(1);
} else {
renderObject.render(filterRenderState);
}
//----------------------------------------------
for (var i = 0; i < filters.length; i++) {
RenderTextureQuad sourceRenderTextureQuad;
final filter = filters[i];
final renderPassSources = filter.renderPassSources;
final renderPassTargets = filter.renderPassTargets;
for (var pass = 0; pass < renderPassSources.length; pass++) {
final renderPassSource = renderPassSources[pass];
final renderPassTarget = renderPassTargets[pass];
final RenderFrameBuffer sourceRenderFrameBuffer;
// get sourceRenderTextureQuad
if (renderFrameBufferMap.containsKey(renderPassSource)) {
sourceRenderFrameBuffer = renderFrameBufferMap[renderPassSource]!;
if (sourceRenderFrameBuffer.renderTexture == null) {
throw StateError('Invalid renderPassSource!');
}
sourceRenderTextureQuad = RenderTextureQuad(
sourceRenderFrameBuffer.renderTexture!,
Rectangle<int>(0, 0, boundsWidth, boundsHeight),
Rectangle<int>(
-boundsLeft, -boundsTop, boundsWidth, boundsHeight),
0,
pixelRatio);
} else {
throw StateError('Invalid renderPassSource!');
}
// get targetRenderFrameBuffer
if (i == filters.length - 1 &&
renderPassTarget == renderPassTargets.last) {
filterRenderFrameBuffer = null;
filterRenderState = renderState;
activateRenderFrameBuffer(initialRenderFrameBuffer);
activateProjectionMatrix(initialProjectionMatrix);
activateBlendMode(filterRenderState.globalBlendMode);
} else if (renderFrameBufferMap.containsKey(renderPassTarget)) {
filterRenderFrameBuffer = renderFrameBufferMap[renderPassTarget];
activateRenderFrameBuffer(filterRenderFrameBuffer);
activateBlendMode(BlendMode.NORMAL);
} else {
filterRenderFrameBuffer =
getRenderFrameBuffer(boundsWidth, boundsHeight);
renderFrameBufferMap[renderPassTarget] = filterRenderFrameBuffer;
activateRenderFrameBuffer(filterRenderFrameBuffer);
activateBlendMode(BlendMode.NORMAL);
clear(0);
}
// render filter
filter.renderFilter(filterRenderState, sourceRenderTextureQuad, pass);
// release obsolete source RenderFrameBuffer
if (renderPassSources
.skip(pass + 1)
.every((rps) => rps != renderPassSource)) {
renderFrameBufferMap.remove(renderPassSource);
releaseRenderFrameBuffer(sourceRenderFrameBuffer);
}
}
renderFrameBufferMap.clear();
renderFrameBufferMap[0] = filterRenderFrameBuffer;
}
}