Clip masks complete
This commit is contained in:
@@ -10,6 +10,7 @@ endif()
|
|||||||
|
|
||||||
find_package(raylib REQUIRED)
|
find_package(raylib REQUIRED)
|
||||||
find_package(RmlUi REQUIRED)
|
find_package(RmlUi REQUIRED)
|
||||||
|
find_package(OpenGL REQUIRED)
|
||||||
|
|
||||||
add_library(rmlui_backend STATIC
|
add_library(rmlui_backend STATIC
|
||||||
src/backend/RaylibSystemInterface.cpp
|
src/backend/RaylibSystemInterface.cpp
|
||||||
@@ -23,6 +24,7 @@ add_executable(${PROJECT_NAME}
|
|||||||
|
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||||
raylib
|
raylib
|
||||||
|
OpenGL::GL
|
||||||
rmlui_backend
|
rmlui_backend
|
||||||
RmlUi::Core
|
RmlUi::Core
|
||||||
RmlUi::Debugger
|
RmlUi::Debugger
|
||||||
|
|||||||
@@ -5,7 +5,8 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Hello from RmlUi</h1>
|
<h1>Hello from RmlUi</h1>
|
||||||
<div style="position:absolute; top: 0; left: 0; width: 200px; height: 100px; background-color: rgba(255, 0, 0, 128); transform: rotate(15deg) translate(50px,0) scale(0.8)">
|
<div style="position: relative; width: 300px; height: 200px; overflow: hidden; border-radius: 40px; background-color: #0000ff">
|
||||||
|
<div style="position: absolute; top: -20px; left: -20px; width: 150px; height: 150px; background-color: #ff0000; transform: rotate(15deg);"></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</rml>
|
</rml>
|
||||||
|
|||||||
6
flake.lock
generated
6
flake.lock
generated
@@ -2,11 +2,11 @@
|
|||||||
"nodes": {
|
"nodes": {
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1788039129,
|
"lastModified": 1788179007,
|
||||||
"narHash": "sha256-pa4Q0qErvCvzCaaUph7Sm37RhR4xvPrYI8Lgz6k85+A=",
|
"narHash": "sha256-hn1oU2rue2SYK8dAr8+WNZWtbsz1S2W5mnHlSEuh3bo=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "d2f67949798825fe853f7c5d0492b8bf016d3f88",
|
"rev": "34ab99075ac4f7e40cf037eef32cb1c360bb85e9",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
20
flake.nix
20
flake.nix
@@ -14,8 +14,8 @@
|
|||||||
rmluiSrc = pkgs.fetchFromGitHub {
|
rmluiSrc = pkgs.fetchFromGitHub {
|
||||||
owner = "mikke89";
|
owner = "mikke89";
|
||||||
repo = "RmlUi";
|
repo = "RmlUi";
|
||||||
rev = "9c74c4fadc2ad7f1496239e560bab19ca2fe5072";
|
tag = "6.3";
|
||||||
hash = "sha256-YZz41ViE3+a0VPypnbJ1Orlf5Hyxd65se5yzyHIY7ZI=";
|
hash = "sha256-ZoK6H3ldrgHjCoMgDg+6XAD+ZaCwLuUgPq0fK+GdlCs=";
|
||||||
};
|
};
|
||||||
|
|
||||||
rmluiCmakeFlags = [
|
rmluiCmakeFlags = [
|
||||||
@@ -27,13 +27,23 @@
|
|||||||
|
|
||||||
rmlui = pkgs.stdenv.mkDerivation {
|
rmlui = pkgs.stdenv.mkDerivation {
|
||||||
pname = "rmlui";
|
pname = "rmlui";
|
||||||
version = "master";
|
version = "6.3";
|
||||||
src = rmluiSrc;
|
src = rmluiSrc;
|
||||||
nativeBuildInputs = [ pkgs.cmake pkgs.pkg-config ];
|
nativeBuildInputs = [ pkgs.cmake pkgs.pkg-config ];
|
||||||
buildInputs = [ pkgs.freetype ];
|
buildInputs = [ pkgs.freetype ];
|
||||||
cmakeFlags = rmluiCmakeFlags ++ [ "-DBUILD_SHARED_LIBS=ON" ];
|
cmakeFlags = rmluiCmakeFlags ++ [ "-DBUILD_SHARED_LIBS=ON" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
raylibPatched = pkgs.raylib.overrideAttrs (old: {
|
||||||
|
postPatch = (old.postPatch or "") + ''
|
||||||
|
substituteInPlace src/platforms/rcore_desktop_glfw.c \
|
||||||
|
--replace-fail \
|
||||||
|
'glfwSetJoystickCallback(NULL);' \
|
||||||
|
'glfwWindowHint(GLFW_STENCIL_BITS, 8);
|
||||||
|
glfwSetJoystickCallback(NULL);'
|
||||||
|
'';
|
||||||
|
});
|
||||||
|
|
||||||
nativeBuildTools = with pkgs; [
|
nativeBuildTools = with pkgs; [
|
||||||
cmake
|
cmake
|
||||||
pkg-config
|
pkg-config
|
||||||
@@ -41,7 +51,7 @@
|
|||||||
];
|
];
|
||||||
|
|
||||||
nativeRuntimeDeps = with pkgs; [
|
nativeRuntimeDeps = with pkgs; [
|
||||||
raylib
|
raylibPatched
|
||||||
libGL
|
libGL
|
||||||
libX11
|
libX11
|
||||||
libXcursor
|
libXcursor
|
||||||
@@ -79,6 +89,8 @@
|
|||||||
--prefix LD_LIBRARY_PATH : "${pkgs.lib.makeLibraryPath nativeRuntimeDeps}"
|
--prefix LD_LIBRARY_PATH : "${pkgs.lib.makeLibraryPath nativeRuntimeDeps}"
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
packages.raylibPatched = raylibPatched;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ I originally began creating this for a Game Jam project where I got the basic re
|
|||||||
## Roadmap
|
## Roadmap
|
||||||
*Rendering features (from the RmlUi render interfface documentation https://mikke89.github.io/RmlUiDoc/pages/cpp_manual/interfaces/render.html#feature-table):*
|
*Rendering features (from the RmlUi render interfface documentation https://mikke89.github.io/RmlUiDoc/pages/cpp_manual/interfaces/render.html#feature-table):*
|
||||||
- [x] Basic rendering
|
- [x] Basic rendering
|
||||||
- [ ] Clip Mask
|
- [x] Clip Mask
|
||||||
- [x] Transforms
|
- [x] Transforms
|
||||||
- [ ] Layers
|
- [ ] Layers
|
||||||
- [ ] Render textures
|
- [ ] Render textures
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
#include <raylib.h>
|
#include <raylib.h>
|
||||||
#include <rlgl.h>
|
#include <rlgl.h>
|
||||||
|
|
||||||
|
#include <GL/gl.h>
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -127,3 +129,77 @@ void RaylibRenderInterface::SetTransform(const Rml::Matrix4f *transform) {
|
|||||||
has_transform = false;
|
has_transform = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RaylibRenderInterface::DrawGeometryTriangles(Rml::CompiledGeometryHandle handle,
|
||||||
|
Rml::Vector2f translation) {
|
||||||
|
auto *geo = reinterpret_cast<GeometryData *>(handle);
|
||||||
|
|
||||||
|
rlPushMatrix();
|
||||||
|
rlTranslatef(translation.x, translation.y, 0.0f);
|
||||||
|
if (has_transform) {
|
||||||
|
rlMultMatrixf(current_transform.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
rlBegin(RL_TRIANGLES);
|
||||||
|
for (size_t i = 0; i + 2 < geo->indices.size(); i += 3) {
|
||||||
|
for (int j = 0; j < 3; ++j) {
|
||||||
|
const Rml::Vertex &v = geo->vertices[geo->indices[i + j]];
|
||||||
|
rlVertex2f(v.position.x, v.position.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rlEnd();
|
||||||
|
|
||||||
|
rlPopMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RaylibRenderInterface::EnableClipMask(bool enable) {
|
||||||
|
rlDrawRenderBatchActive();
|
||||||
|
clip_mask_enabled = enable;
|
||||||
|
|
||||||
|
if (enable) {
|
||||||
|
glEnable(GL_STENCIL_TEST);
|
||||||
|
glStencilFunc(GL_EQUAL, static_cast<GLint>(clip_mask_level), 0xFF);
|
||||||
|
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_STENCIL_TEST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RaylibRenderInterface::RenderToClipMask(Rml::ClipMaskOperation operation,
|
||||||
|
Rml::CompiledGeometryHandle geometry,
|
||||||
|
Rml::Vector2f translation) {
|
||||||
|
rlDrawRenderBatchActive();
|
||||||
|
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||||
|
|
||||||
|
switch (operation) {
|
||||||
|
case Rml::ClipMaskOperation::Set:
|
||||||
|
glClearStencil(0);
|
||||||
|
glClear(GL_STENCIL_BUFFER_BIT);
|
||||||
|
glStencilFunc(GL_ALWAYS, 1, 0xFF);
|
||||||
|
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||||
|
clip_mask_level = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Rml::ClipMaskOperation::SetInverse:
|
||||||
|
glClearStencil(1);
|
||||||
|
glClear(GL_STENCIL_BUFFER_BIT);
|
||||||
|
glStencilFunc(GL_ALWAYS, 0, 0xFF);
|
||||||
|
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||||
|
clip_mask_level = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Rml::ClipMaskOperation::Intersect:
|
||||||
|
glStencilFunc(GL_EQUAL, static_cast<GLint>(clip_mask_level), 0xFF);
|
||||||
|
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
|
||||||
|
clip_mask_level += 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawGeometryTriangles(geometry, translation);
|
||||||
|
rlDrawRenderBatchActive();
|
||||||
|
|
||||||
|
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||||
|
|
||||||
|
glStencilFunc(GL_EQUAL, static_cast<GLint>(clip_mask_level), 0xFF);
|
||||||
|
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||||
|
}
|
||||||
|
|||||||
@@ -32,6 +32,11 @@ public:
|
|||||||
|
|
||||||
void SetTransform(const Rml::Matrix4f *transform) override;
|
void SetTransform(const Rml::Matrix4f *transform) override;
|
||||||
|
|
||||||
|
void EnableClipMask(bool enable) override;
|
||||||
|
void RenderToClipMask(Rml::ClipMaskOperation operation,
|
||||||
|
Rml::CompiledGeometryHandle geometry,
|
||||||
|
Rml::Vector2f translation) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ApplyScissor();
|
void ApplyScissor();
|
||||||
|
|
||||||
@@ -40,4 +45,8 @@ private:
|
|||||||
|
|
||||||
bool has_transform = false;
|
bool has_transform = false;
|
||||||
Rml::Matrix4f current_transform;
|
Rml::Matrix4f current_transform;
|
||||||
|
|
||||||
|
bool clip_mask_enabled = false;
|
||||||
|
unsigned int clip_mask_level = 0;
|
||||||
|
void DrawGeometryTriangles(Rml::CompiledGeometryHandle geometry, Rml::Vector2f translation);
|
||||||
};
|
};
|
||||||
|
|||||||
28
src/main.cpp
28
src/main.cpp
@@ -10,6 +10,8 @@
|
|||||||
#include "backend/RaylibSystemInterface.h"
|
#include "backend/RaylibSystemInterface.h"
|
||||||
#include "backend/RaylibInput.h"
|
#include "backend/RaylibInput.h"
|
||||||
|
|
||||||
|
#include <GL/gl.h>
|
||||||
|
|
||||||
static RaylibSystemInterface system_interface;
|
static RaylibSystemInterface system_interface;
|
||||||
static RaylibRenderInterface render_interface;
|
static RaylibRenderInterface render_interface;
|
||||||
static Rml::Context *ctx;
|
static Rml::Context *ctx;
|
||||||
@@ -24,12 +26,24 @@ int main() {
|
|||||||
Rml::SetSystemInterface(&system_interface);
|
Rml::SetSystemInterface(&system_interface);
|
||||||
Rml::SetRenderInterface(&render_interface);
|
Rml::SetRenderInterface(&render_interface);
|
||||||
Rml::Initialise();
|
Rml::Initialise();
|
||||||
|
TraceLog(LOG_INFO, "RmlUi version: %s", Rml::GetVersion().c_str());
|
||||||
|
|
||||||
ctx = Rml::CreateContext("main", Rml::Vector2i(600, 800));
|
ctx = Rml::CreateContext("main", Rml::Vector2i(600, 800));
|
||||||
Rml::Debugger::Initialise(ctx);
|
Rml::Debugger::Initialise(ctx);
|
||||||
|
|
||||||
auto doc = ctx->LoadDocument("assets/main.rml");
|
auto doc = ctx->LoadDocument("assets/main.rml");
|
||||||
doc->Show();
|
doc->Show();
|
||||||
|
|
||||||
|
Camera3D cam3;
|
||||||
|
cam3.position = Vector3 {0.0f, 10.0f, 10.0f};
|
||||||
|
cam3.target = Vector3 {0.0f, 0.0f, 0.0f};
|
||||||
|
cam3.up = Vector3 {0, 1.0f, 0.0f};
|
||||||
|
cam3.fovy = 45.0f;
|
||||||
|
cam3.projection = CAMERA_PERSPECTIVE;
|
||||||
|
|
||||||
|
Vector3 cubePos = Vector3 {0.0f, 0.0f, 0.0f};
|
||||||
|
|
||||||
|
// DisableCursor();
|
||||||
|
|
||||||
while (!WindowShouldClose()) {
|
while (!WindowShouldClose()) {
|
||||||
|
|
||||||
@@ -37,14 +51,24 @@ int main() {
|
|||||||
ctx->SetDimensions(Rml::Vector2i(GetScreenWidth(), GetScreenHeight()));
|
ctx->SetDimensions(Rml::Vector2i(GetScreenWidth(), GetScreenHeight()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateCamera(&cam3, CAMERA_FREE);
|
||||||
|
|
||||||
ForwardInputToRml(ctx);
|
ForwardInputToRml(ctx);
|
||||||
ctx->Update();
|
ctx->Update();
|
||||||
|
|
||||||
|
if (IsKeyPressed(KEY_Z)) cam3.target = Vector3 {0.0f, 0.0f, 0.0f};
|
||||||
|
|
||||||
BeginDrawing();
|
BeginDrawing();
|
||||||
ClearBackground(BLACK);
|
ClearBackground(BLACK);
|
||||||
DrawFPS(10, 10);
|
DrawFPS(10, 10);
|
||||||
DrawText("Hello!", GetScreenWidth()/2, GetScreenHeight()/2, 10, RAYWHITE);
|
// DrawText("Hello!", GetScreenWidth()/2, GetScreenHeight()/2, 10, RAYWHITE);
|
||||||
|
|
||||||
|
BeginMode3D(cam3);
|
||||||
|
DrawCube(cubePos, 2.0f, 2.0f, 2.0f, RED);
|
||||||
|
DrawCubeWires(cubePos, 2.0f, 2.0f, 2.0f, BLUE);
|
||||||
|
DrawGrid(10, 1.0f);
|
||||||
|
EndMode3D();
|
||||||
|
|
||||||
ctx->Render();
|
ctx->Render();
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user