Skip to content

Commit

Permalink
Replace render interface functions PushTransform and PopTransform wit…
Browse files Browse the repository at this point in the history
…h SetTransform
  • Loading branch information
mikke89 committed Aug 25, 2019
1 parent 27f5076 commit b6739b4
Show file tree
Hide file tree
Showing 15 changed files with 70 additions and 81 deletions.
1 change: 1 addition & 0 deletions Include/RmlUi/Core/ElementInstancer.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "Traits.h"
#include "XMLParser.h"
#include "Header.h"
#include "Element.h"

namespace Rml {
namespace Core {
Expand Down
12 changes: 4 additions & 8 deletions Include/RmlUi/Core/ElementUtilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,15 +132,11 @@ class RMLUICORE_API ElementUtilities
/// @param anchor[in] Defines which corner or edge the border is to be positioned relative to.
static bool PositionElement(Element* element, const Vector2f& offset, PositionAnchor anchor);

/// Applies an element's `perspective' and `transform' properties.
/// Applies an element's accumulated transform matrix, determined from its and ancestor's `perspective' and `transform' properties.
/// Note: All calls to RenderInterface::SetTransform must go through here.
/// @param[in] element The element whose transform to apply.
/// @param[in] apply Whether to apply (true) or unapply (false) the transform.
/// @return true if the element has a transform and it could be applied.
static bool ApplyTransform(Element &element, bool apply = true);
/// Unapplies an element's `perspective' and `transform' properties.
/// @param[in] element The element whose transform to unapply.
/// @return true if the element has a transform and it could be unapplied.
static bool UnapplyTransform(Element &element);
/// @return true if a render interface is available to set the transform.
static bool ApplyTransform(Element &element);
};

}
Expand Down
11 changes: 4 additions & 7 deletions Include/RmlUi/Core/RenderInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,10 @@ class RMLUICORE_API RenderInterface : public NonCopyMoveable
/// @param texture The texture handle to release.
virtual void ReleaseTexture(TextureHandle texture);

/// Called by RmlUi when it wants to set the current transform matrix to a new matrix.
/// @param[in] transform The new transform to apply.
virtual void PushTransform(const Matrix4f& transform);
/// Called by RmlUi when it wants to revert the latest transform change.
/// @param[in] transform This is the transform to unapply.
/// It always equals the argument of the latest call to PushTransform().
virtual void PopTransform(const Matrix4f& transform);
/// Called by RmlUi when it wants the renderer to use a new transform matrix.
/// If no transform applies to the current element, nullptr is submitted. Then it expects the renderer to use an identity matrix or otherwise omit the multiplication with the transform.
/// @param[in] transform The new transform to apply, or nullptr if no transform applies to the current element.
virtual void SetTransform(const Matrix4f* transform);

/// Get the context currently being rendered. This is only valid during RenderGeometry,
/// CompileGeometry, RenderCompiledGeometry, EnableScissorRegion and SetScissorRegion.
Expand Down
4 changes: 2 additions & 2 deletions Include/RmlUi/Core/TransformState.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,13 @@ class RMLUICORE_API TransformState
mutable bool have_inverse_transform = false;
mutable bool dirty_inverse_transform = false;

// The transform combines all local transform and perspective properties of the owning element and all ancestors.
// The accumulated transform matrix combines all transform and perspective properties of the owning element and all ancestors.
Matrix4f transform;

// Local perspective which applies to children of the owning element.
Matrix4f local_perspective;

// The inverse of the transform mainly for projecting points from screen-space to 2d-space, such as used for picking elements.
// The inverse of the transform matrix for projecting points from screen space to the current element's space, such as used for picking elements.
mutable Matrix4f inverse_transform;
};

Expand Down
4 changes: 1 addition & 3 deletions Samples/basic/transform/data/transform.rml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ scrollbarvertical sliderbar:hover,scrollbarvertical sliderbar:active
width: 200px;
height: 200px;
margin: 75px auto;
border: none;
background-color: #a003;
}

Expand All @@ -74,7 +73,6 @@ scrollbarvertical sliderbar:hover,scrollbarvertical sliderbar:active
position: absolute;
width: 100px;
height: 100px;
border: none;
line-height: 100px;
font-size: 60px;
color: white;
Expand Down Expand Up @@ -147,7 +145,7 @@ augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet,
consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut
laoreet dolore magna aliquam erat volutpat.</p>

<button style="width: 220px;">A wild button appears!</button>
<button style="width: 220px; transform: translateZ(-30px);">A wild button appears!</button>

<p>Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit
lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure
Expand Down
7 changes: 7 additions & 0 deletions Samples/basic/transform/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ class DemoWindow : public Rml::Core::EventListener
void SetPerspective(float distance)
{
perspective = distance;

if (document && perspective > 0)
{
std::stringstream s;
s << "perspective(" << perspective << "px) ";
document->SetProperty("transform", s.str().c_str());
}
}

void SetRotation(float degrees)
Expand Down
7 changes: 2 additions & 5 deletions Samples/shell/include/ShellRenderInterfaceOpenGL.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,7 @@ class ShellRenderInterfaceOpenGL : public Rml::Core::RenderInterface, public Sh
void ReleaseTexture(Rml::Core::TextureHandle texture_handle) override;

/// Called by RmlUi when it wants to set the current transform matrix to a new matrix.
void PushTransform(const Rml::Core::Matrix4f& transform) override;

/// Called by RmlUi when it wants to revert the latest transform change.
void PopTransform(const Rml::Core::Matrix4f& transform) override;
void SetTransform(const Rml::Core::Matrix4f* transform) override;

// ShellRenderInterfaceExtensions
void SetViewport(int width, int height) override;
Expand All @@ -82,7 +79,7 @@ class ShellRenderInterfaceOpenGL : public Rml::Core::RenderInterface, public Sh
protected:
int m_width;
int m_height;
int m_transforms;
bool m_transform_enabled;
void *m_rmlui_context;

#if defined(RMLUI_PLATFORM_MACOSX)
Expand Down
31 changes: 14 additions & 17 deletions Samples/shell/src/ShellRenderInterfaceOpenGL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

#define GL_CLAMP_TO_EDGE 0x812F

ShellRenderInterfaceOpenGL::ShellRenderInterfaceOpenGL() : m_width(0), m_height(0), m_transforms(0), m_rmlui_context(nullptr)
ShellRenderInterfaceOpenGL::ShellRenderInterfaceOpenGL() : m_width(0), m_height(0), m_transform_enabled(false), m_rmlui_context(nullptr)
{

}
Expand Down Expand Up @@ -97,7 +97,7 @@ void ShellRenderInterfaceOpenGL::ReleaseCompiledGeometry(Rml::Core::CompiledGeom
void ShellRenderInterfaceOpenGL::EnableScissorRegion(bool enable)
{
if (enable) {
if (m_transforms <= 0) {
if (!m_transform_enabled) {
glEnable(GL_SCISSOR_TEST);
glDisable(GL_STENCIL_TEST);
} else {
Expand All @@ -113,7 +113,7 @@ void ShellRenderInterfaceOpenGL::EnableScissorRegion(bool enable)
// Called by RmlUi when it wants to change the scissor region.
void ShellRenderInterfaceOpenGL::SetScissorRegion(int x, int y, int width, int height)
{
if (m_transforms <= 0) {
if (!m_transform_enabled) {
glScissor(x, m_height - (y + height), width, height);
} else {
// clear the stencil buffer
Expand Down Expand Up @@ -282,21 +282,18 @@ void ShellRenderInterfaceOpenGL::ReleaseTexture(Rml::Core::TextureHandle texture
}

// Called by RmlUi when it wants to set the current transform matrix to a new matrix.
void ShellRenderInterfaceOpenGL::PushTransform(const Rml::Core::Matrix4f& transform)
void ShellRenderInterfaceOpenGL::SetTransform(const Rml::Core::Matrix4f* transform)
{
glPushMatrix();

if(std::is_same<Rml::Core::Matrix4f, Rml::Core::ColumnMajorMatrix4f>::value)
glLoadMatrixf(transform.data());
else if (std::is_same<Rml::Core::Matrix4f, Rml::Core::RowMajorMatrix4f>::value)
glLoadMatrixf(transform.Transpose().data());
m_transform_enabled = (bool)transform;

++m_transforms;
if (transform)
{
if (std::is_same<Rml::Core::Matrix4f, Rml::Core::ColumnMajorMatrix4f>::value)
glLoadMatrixf(transform->data());
else if (std::is_same<Rml::Core::Matrix4f, Rml::Core::RowMajorMatrix4f>::value)
glLoadMatrixf(transform->Transpose().data());
}
else
glLoadIdentity();
}

// Called by RmlUi when it wants to revert the latest transform change.
void ShellRenderInterfaceOpenGL::PopTransform(const Rml::Core::Matrix4f& transform)
{
glPopMatrix();
--m_transforms;
}
5 changes: 1 addition & 4 deletions Source/Core/Element.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,9 +271,6 @@ void Element::Render()
// Render the rest of the elements in the stacking context.
for (; i < stacking_context.size(); ++i)
stacking_context[i]->Render();

// Unapply our transform
ElementUtilities::UnapplyTransform(*this);
}

// Clones this element, returning a new, unparented element.
Expand Down Expand Up @@ -2451,7 +2448,7 @@ void Element::UpdateTransformState()

if (dirty_transform)
{
// We want to find the combined transform of all our ancestors. It is assumed here that the parent transform is already updated,
// We want to find the accumulated transform given all our ancestors. It is assumed here that the parent transform is already updated,
// so that we only need to consider our local transform and combine it with our parent's transform and perspective matrices.
bool had_transform = (transform_state && transform_state->GetTransform());

Expand Down
29 changes: 13 additions & 16 deletions Source/Core/ElementUtilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -347,32 +347,29 @@ bool ElementUtilities::PositionElement(Element* element, const Vector2f& offset,
return true;
}

// Applies an element's `perspective' and `transform' properties.
bool ElementUtilities::ApplyTransform(Element &element, bool apply)
bool ElementUtilities::ApplyTransform(Element &element)
{
RenderInterface *render_interface = element.GetRenderInterface();
if (!render_interface)
return false;

if(auto state = element.GetTransformState())
static SmallUnorderedMap<RenderInterface*, const Matrix4f*> previous_matrix;

const Matrix4f*& old_transform = previous_matrix.emplace(render_interface, nullptr).first->second;
const Matrix4f* new_transform = nullptr;

if (auto state = element.GetTransformState())
new_transform = state->GetTransform();

// Only changed transforms are submitted.
if (old_transform != new_transform)
{
if(auto transform = state->GetTransform())
{
if (apply)
render_interface->PushTransform(*transform);
else
render_interface->PopTransform(*transform);
}
render_interface->SetTransform(new_transform);
old_transform = new_transform;
}

return true;
}

// Unapplies an element's `perspective' and `transform' properties.
bool ElementUtilities::UnapplyTransform(Element &element)
{
return ApplyTransform(element, false);
}

}
}
7 changes: 1 addition & 6 deletions Source/Core/RenderInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,7 @@ void RenderInterface::ReleaseTexture(TextureHandle RMLUI_UNUSED_PARAMETER(textur
}

// Called by RmlUi when it wants to change the current transform matrix to a new matrix.
void RenderInterface::PushTransform(const Matrix4f& transform)
{
}

// Called by RmlUi when it wants to revert the latest transform change.
void RenderInterface::PopTransform(const Matrix4f& transform)
void RenderInterface::SetTransform(const Matrix4f* transform)
{
}

Expand Down
24 changes: 17 additions & 7 deletions Source/Core/TransformPrimitive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -741,28 +741,38 @@ bool Primitive::InterpolateWith(const Primitive & other, float alpha) noexcept


template<size_t N>
inline String ToString(const Transforms::ResolvedPrimitive<N>& p, String unit, bool rad_to_deg = false, bool only_unit_on_last_value = false) noexcept {
static inline String ToString(const Transforms::ResolvedPrimitive<N>& p, String unit, bool rad_to_deg = false, bool only_unit_on_last_value = false) noexcept {
float multiplier = 1.0f;
if (rad_to_deg) multiplier = 180.f / Math::RMLUI_PI;
String tmp;
String result = "(";
for (size_t i = 0; i < N; i++) {
for (size_t i = 0; i < N; i++)
{
if (only_unit_on_last_value && i < N - 1)
multiplier = 1.0f;
else if (rad_to_deg)
multiplier = 180.f / Math::RMLUI_PI;

if (TypeConverter<float, String>::Convert(p.values[i] * multiplier, tmp))
result += tmp;

if (!unit.empty() && (!only_unit_on_last_value || (i == N - 1)))
result += unit;
if (i != N - 1) result += ", ";

if (i < N - 1)
result += ", ";
}
result += ")";
return result;
}

template<size_t N>
inline String ToString(const Transforms::UnresolvedPrimitive<N> & p) noexcept {
static inline String ToString(const Transforms::UnresolvedPrimitive<N> & p) noexcept {
String result = "(";
for (size_t i = 0; i < N; i++) {
for (size_t i = 0; i < N; i++)
{
result += p.values[i].ToString();
if (i != N - 1) result += ", ";
if (i != N - 1)
result += ", ";
}
result += ")";
return result;
Expand Down
3 changes: 0 additions & 3 deletions Source/Debugger/ElementInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,6 @@ void ElementInfo::RenderHoverElement()
1
);
}
Core::ElementUtilities::UnapplyTransform(*hover_element);
}
}

Expand All @@ -244,8 +243,6 @@ void ElementInfo::RenderSourceElement()
// Border area:
Geometry::RenderBox(source_element->GetAbsoluteOffset(Core::Box::BORDER) + element_box.GetPosition(Core::Box::MARGIN), element_box.GetSize(Core::Box::MARGIN), source_element->GetAbsoluteOffset(Core::Box::BORDER) + element_box.GetPosition(Core::Box::BORDER), element_box.GetSize(Core::Box::BORDER), Core::Colourb(240, 255, 131, 128));
}

Core::ElementUtilities::UnapplyTransform(*source_element);
}
}

Expand Down
2 changes: 0 additions & 2 deletions Source/Debugger/Plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,6 @@ void Plugin::Render()

for (int j = 0; j < element->GetNumChildren(); ++j)
element_stack.push(element->GetChild(j));

Core::ElementUtilities::UnapplyTransform(*element);
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,10 @@ The inner workings of transforms have been completely revised, resulting in incr

Some relevant changes for users:
- Removed the need for users to set the view and projection matrices they use outside the library.
- Replaced the `PushTransform()` and `PopTransform()` render interface functions with `SetTransform()`, which is only called when the transform matrix needs to change and never called if there are no `transform` properties present.
- The `perspective` property now applies to the element's children, as in CSS.
- The transform function `perspective()` behaves like in CSS. It applies a perspective projection to the current element.
- Chaining transforms and perspectives now provides more expected results. As opposed to CSS, we don't flatten transforms.
- Chaining transforms and perspectives now provides more expected results. However, as opposed to CSS we don't flatten transforms.
- Have a look at the updated transforms sample for some fun with 3d boxes.


Expand All @@ -256,6 +257,7 @@ Breaking changes since RmlUi v2.0.
- Removed RenderInterface::GetPixelsPerInch, instead the pixels per inch value has been fixed to 96 PPI, as per CSS specs. To achieve a scalable user interface, instead use the 'dp' unit.
- Removed 'top' and 'bottom' from z-index property.
- See changes to the declaration of decorators and font-effects above.
- See changes to the render interface regarding transforms above.
- Also, see removal of manual reference counting above.


Expand Down

0 comments on commit b6739b4

Please sign in to comment.