Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Advanced rendering effects - filters, masks, box-shadows, gradients, and shaders #594

Merged
merged 80 commits into from
Mar 30, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
78db66c
Add effect sample
mikke89 Apr 29, 2023
05ec09b
Refactor: Move DecoratorInstancer into the Decorator files
mikke89 Apr 29, 2023
b6f70ff
Refactor: Style sheet type names
mikke89 Apr 29, 2023
607a8ce
Rectangle: Add getters for all corners and math rounding procedure
mikke89 Apr 30, 2023
679c615
Add number_percent parser and combined unit
mikke89 Apr 30, 2023
76b8556
ElementUtilities: Add procedure for determining element bounding box …
mikke89 Apr 30, 2023
1be3e86
Add render interface commands for layers and filters
mikke89 Apr 30, 2023
a5e3c7f
Add Filter class, to be used with the new 'filter' and 'backdrop-filt…
mikke89 Apr 29, 2023
bafca42
Add basic filters
mikke89 Apr 30, 2023
faae241
Take texture out of the compiled geometry
mikke89 Apr 30, 2023
f6230b2
Make elements with 'filter' and 'backdrop-filter' properties create a…
mikke89 Apr 30, 2023
a5ddc1a
Elements with 'filter' and 'backdrop-filter' properties now act as co…
mikke89 May 1, 2023
cb64ba4
Add a new visual test for stacking context paint order
mikke89 May 1, 2023
ebc8b65
Add filters to effect sample
mikke89 May 1, 2023
1d7b183
Add render layer and filter support to GL3 renderer
mikke89 May 1, 2023
edcb854
Improve visual tests automated test result output
mikke89 May 1, 2023
156d2bd
Fix backdrop-filter
mikke89 May 11, 2023
17246f5
Add blur filter, implement in GL3 renderer
mikke89 May 11, 2023
19281fd
Implement drop-shadow filter, integrate filter in GL3 renderer, and a…
mikke89 May 28, 2023
a30d3d5
Clarify Context::GetElementAtPoint
mikke89 Jun 1, 2023
3429285
Add geometry utility for creating background geometry on any target a…
mikke89 Jun 1, 2023
69ea397
Add clip mask to render interface, introduce render manager to keep t…
mikke89 Jun 2, 2023
4bfc80f
Debugger: Display the bounding box of the selected element
mikke89 Jun 3, 2023
655cd9a
Add support for the 'box-shadow' property
mikke89 Jun 3, 2023
72c816f
GL3 renderer: Fix assertion errors when minimizing the window
mikke89 Jun 4, 2023
2dba53e
GL3 renderer: Avoid sampling outside target region
mikke89 Jun 4, 2023
2338f2d
Add visual tests for drop shadow filter, and bounding box with ink ov…
mikke89 Jun 4, 2023
556607d
Replace gradient decorator syntax 'gradient(horizontal|vertical ...)'…
mikke89 Jun 6, 2023
17f1d95
Math: Normalize angle to positive values only
mikke89 Jun 6, 2023
0507e48
Improve PropertySpecification::ParsePropertyValues
mikke89 Jun 6, 2023
1525fd7
Add support for rendering geometry with shaders through the render in…
mikke89 Jun 7, 2023
b6efab1
Add 'linear-gradient' and 'repeating-linear-gradient' decorators
mikke89 Jun 7, 2023
c3622e6
Allow decorators to specify paint area [breaking change]
mikke89 Jun 7, 2023
81ae0c8
Visual tests: Highlight differences when comparing to previous captur…
mikke89 Jun 7, 2023
2f146f4
Add support for conic-gradient and radial-gradient, as well as their …
mikke89 Jun 8, 2023
5888497
Add interpolation support for angle values, support conic gradient an…
mikke89 Jun 8, 2023
5d52f71
Add shader decorator
mikke89 Jun 10, 2023
0471ce7
Add support for 'mask-image' property
mikke89 Jun 10, 2023
c6f550d
Add animation support for filters
mikke89 Jun 14, 2023
ecaaefa
Add 'mask-image' and 'backdrop-filter' animation tests
mikke89 Jun 15, 2023
aec3f2a
Fix backdrop-filter clipping to border background, add visual test
mikke89 Jun 30, 2023
ae8f2a4
Refactor: Move the box shadow generation into a separate file
mikke89 Jul 2, 2023
bdf5608
Use move semantics for texture callbacks
mikke89 Jul 2, 2023
9a00f2c
Unit tests: Make doctest string conversion functions inline
mikke89 Jul 15, 2023
59146e9
Update clang-format
mikke89 Jul 22, 2023
70bcdc7
Update SVG plugin for LunaSVG v2.3.2 and newer
mikke89 Jul 22, 2023
a064612
Avoid setting computed 'has_decorator' and similar when their pointer…
mikke89 Jul 22, 2023
641f8b5
Visual tests: Add alpha blending tests for renderer
mikke89 Jul 22, 2023
7ae3bb3
Use premultiplied alpha for textures submitted through the render int…
mikke89 Jul 22, 2023
c802aeb
Use premultiplied alpha for vertex colors
mikke89 Jul 22, 2023
2f80bdd
Backends: Handle premultiplied alpha for textures and vertices
mikke89 Jul 22, 2023
cfd963c
Fix minor GCC warning on Win32 backends
mikke89 Jul 23, 2023
f4414b8
Render interface: Mark optional functions for advanced effects
mikke89 Jul 23, 2023
a076be2
Postpone instancing named decorators until other decorators are insta…
mikke89 Aug 5, 2023
a452f26
Refactor Geometry and Texture, introduce unique render resources
mikke89 Sep 10, 2023
ba35525
Implement clip masks for the GL2 renderer
mikke89 Oct 8, 2023
90d2ef2
Introduce a basic implementation of a Span type
mikke89 Dec 25, 2023
3176c85
In demo sample, fix form submit animation not playing smoothly on pow…
mikke89 Dec 25, 2023
5faedc4
Refactor render interface: Require compiled geometry, use modern and …
mikke89 Dec 25, 2023
8b292e1
Add a render interface adapter from the old interface to the newly re…
mikke89 Dec 25, 2023
94fda35
GL3 renderer: Fix shader compilation on GLES, add GLSL line numbers
mikke89 Dec 26, 2023
cbeea43
Remove unused Log procedures for initialise and shutdown
mikke89 Dec 30, 2023
ac8e1f2
Use default log output also when there is no system interface installed
mikke89 Dec 30, 2023
5a27590
Redirect all print-like calls to our built-in logger
mikke89 Dec 30, 2023
6e1d487
Fix some situations where units were not shown in properties
mikke89 Feb 3, 2024
ff65107
Fix string conversion of ColorStopList and BoxShadowList, fixes #590
mikke89 Feb 3, 2024
7335eed
Ensure all invoked types define a string converter
mikke89 Feb 3, 2024
7b359d5
Use RCSS syntax for color-string conversion, format colors using hexa…
mikke89 Feb 3, 2024
144212b
Fix defender decorator from being rendered in invader samples
mikke89 Feb 3, 2024
b301702
Update CMake minimum to 3.5
mikke89 Feb 4, 2024
13b60d1
UnitTests: Add filter support to tests interface, test filter generat…
mikke89 Feb 5, 2024
7b9d865
Log warning if filter could not be compiled
mikke89 Feb 4, 2024
8dfba05
GL3 renderer: Add color write mask to OpenGL state backup
mikke89 Feb 4, 2024
742bbba
Add mask-image to absolute positioning containing block
mikke89 Feb 5, 2024
c42d729
Render interface naming: Remove compiled from release functions
mikke89 Feb 5, 2024
011b3c1
Fix file textures not being reloaded after release
mikke89 Mar 4, 2024
b470b2b
Make backdrop-filter be affected by any filter and mask-image applied…
mikke89 Mar 24, 2024
e96b950
Render interface: Make layer compositing a separate function instead …
mikke89 Mar 25, 2024
c93dbc0
Fix bad rendering in Emscripten, add sample assets as link dependencies
mikke89 Mar 26, 2024
37cf4d3
Refactor ElementDecoration to ElementEffects
mikke89 Mar 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
ElementUtilities: Add procedure for determining element bounding box …
…with projection
  • Loading branch information
mikke89 committed Jul 23, 2023
commit 76b855652edb294e6549b14774d3eecd6c5e790a
7 changes: 7 additions & 0 deletions Include/RmlUi/Core/ElementUtilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,13 @@ class RMLUICORE_API ElementUtilities {
/// @param[in] context The context to read the clip region from
static void ApplyActiveClipRegion(Context* context);

/// Returns a rectangle covering the element's area in window coordinate space.
/// @param[in] out_rectangle The resulting rectangle covering the projected element's box.
/// @param[in] element The element to find the bounding box of.
/// @param[in] area The box area to consider.
/// @return True on success, otherwise false.
static bool GetBoundingBox(Rectanglef& out_rectangle, Element* element, BoxArea area);

/// Formats the contents of an element. This does not need to be called for ordinary elements, but can be useful
/// for non-DOM elements of custom elements.
/// @param[in] element The element to lay out.
Expand Down
62 changes: 62 additions & 0 deletions Source/Core/ElementUtilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,68 @@ void ElementUtilities::ApplyActiveClipRegion(Context* context)
}
}

bool ElementUtilities::GetBoundingBox(Rectanglef& out_rectangle, Element* element, BoxArea box_area)
{
RMLUI_ASSERT(element);

if (box_area == BoxArea::Auto)
box_area = BoxArea::Border;

// Element bounds in non-transformed space.
const Rectanglef bounds = Rectanglef::FromPositionSize(element->GetAbsoluteOffset(box_area), element->GetBox().GetSize(box_area));

const TransformState* transform_state = element->GetTransformState();
const Matrix4f* transform = (transform_state ? transform_state->GetTransform() : nullptr);

// Early exit in the common case of no transform.
if (!transform)
{
out_rectangle = bounds;
return true;
}

Context* context = element->GetContext();
if (!context)
return false;

constexpr int num_corners = 4;
Vector2f corners[num_corners] = {
bounds.TopLeft(),
bounds.TopRight(),
bounds.BottomRight(),
bounds.BottomLeft(),
};

// Transform and project corners to window coordinates.
constexpr float z_clip = 10'000.f;
const Vector2f window_size = Vector2f(context->GetDimensions());
const Matrix4f project = Matrix4f::ProjectOrtho(0.f, window_size.x, 0.f, window_size.y, -z_clip, z_clip);
const Matrix4f project_transform = project * (*transform);
bool any_vertex_depth_clipped = false;

for (int i = 0; i < num_corners; i++)
{
const Vector4f pos_clip_space = project_transform * Vector4f(corners[i].x, corners[i].y, 0, 1);
const Vector2f pos_ndc = Vector2f(pos_clip_space.x, pos_clip_space.y) / pos_clip_space.w;
const Vector2f pos_viewport = 0.5f * window_size * (pos_ndc + Vector2f(1));
corners[i] = pos_viewport;
any_vertex_depth_clipped |= !(-pos_clip_space.w <= pos_clip_space.z && pos_clip_space.z <= pos_clip_space.w);
}

// If any part of the box area is outside the depth clip planes we give up finding the bounding box. In this situation a renderer would normally
// clip the underlying triangles against the clip planes. We could in principle do the same, but the added complexity does not seem worthwhile for
// our use cases.
if (any_vertex_depth_clipped)
return false;

// Find the rectangle covering the projected corners.
out_rectangle = Rectanglef::FromPosition(corners[0]);
for (int i = 1; i < num_corners; i++)
out_rectangle.Join(corners[i]);

return true;
}

void ElementUtilities::FormatElement(Element* element, Vector2f containing_block)
{
LayoutEngine::FormatElement(element, containing_block);
Expand Down