Skip to content

Commit

Permalink
Merge branch 'effects' (#594)
Browse files Browse the repository at this point in the history
  • Loading branch information
mikke89 committed Mar 28, 2024
2 parents 1ac79c3 + 37cf4d3 commit 8559aaf
Show file tree
Hide file tree
Showing 293 changed files with 14,826 additions and 4,887 deletions.
1 change: 1 addition & 0 deletions .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,4 @@ StatementMacros:
- RMLUI_RTTI_DefineWithParent
TabWidth: 4
UseTab: AlignWithSpaces
WhitespaceSensitiveMacros: ['RMLUI_STRINGIFY']
8 changes: 1 addition & 7 deletions Backends/RmlUi_Backend_GLFW_GL3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,6 @@ bool Backend::Initialize(const char* name, int width, int height, bool allow_res
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_DOUBLEBUFFER, GLFW_TRUE);

// Request stencil buffer of at least 8-bit size to supporting clipping on transformed elements.
glfwWindowHint(GLFW_STENCIL_BITS, 8);

// Enable MSAA for better-looking visuals, especially when transforms are applied.
glfwWindowHint(GLFW_SAMPLES, 2);

// Apply window properties and create it.
glfwWindowHint(GLFW_RESIZABLE, allow_resize ? GLFW_TRUE : GLFW_FALSE);
glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE);
Expand Down Expand Up @@ -184,8 +178,8 @@ void Backend::RequestExit()
void Backend::BeginFrame()
{
RMLUI_ASSERT(data);
data->render_interface.BeginFrame();
data->render_interface.Clear();
data->render_interface.BeginFrame();
}

void Backend::PresentFrame()
Expand Down
9 changes: 5 additions & 4 deletions Backends/RmlUi_Backend_GLFW_VK.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,15 @@
*
*/

#include "RmlUi/Config/Config.h"
#include "RmlUi_Backend.h"
#include "RmlUi_Renderer_VK.h"
// This space is intentional to prevent autoformat from reordering RmlUi_Renderer_VK behind RmlUi_Platform_GLFW
#include "RmlUi_Platform_GLFW.h"
#include <RmlUi/Config/Config.h>
#include <RmlUi/Core/Context.h>
#include <RmlUi/Core/Core.h>
#include <RmlUi/Core/FileInterface.h>
#include <RmlUi/Core/Log.h>
#include <GLFW/glfw3.h>
#include <stdint.h>
#include <thread>
Expand Down Expand Up @@ -84,7 +85,7 @@ bool Backend::Initialize(const char* window_name, int width, int height, bool al

if (!window)
{
fprintf(stderr, "[GLFW] error can't create window!");
Rml::Log::Message(Rml::Log::LT_ERROR, "GLFW failed to create window");
return false;
}

Expand All @@ -93,15 +94,15 @@ bool Backend::Initialize(const char* window_name, int width, int height, bool al

uint32_t count;
const char** extensions = glfwGetRequiredInstanceExtensions(&count);
RMLUI_VK_ASSERTMSG(extensions != nullptr, "Failed to query glfw vulkan extensions");
RMLUI_VK_ASSERTMSG(extensions != nullptr, "Failed to query GLFW Vulkan extensions");
if (!data->render_interface.Initialize(Rml::Vector<const char*>(extensions, extensions + count),
[](VkInstance instance, VkSurfaceKHR* out_surface) {
return glfwCreateWindowSurface(instance, data->window, nullptr, out_surface) == VkResult::VK_SUCCESS;
;
}))
{
data.reset();
fprintf(stderr, "Could not initialize Vulkan render interface.");
Rml::Log::Message(Rml::Log::LT_ERROR, "Failed to initialize Vulkan render interface");
return false;
}

Expand Down
56 changes: 31 additions & 25 deletions Backends/RmlUi_Backend_SDL_GL2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <RmlUi/Core/Context.h>
#include <RmlUi/Core/Core.h>
#include <RmlUi/Core/FileInterface.h>
#include <RmlUi/Core/Log.h>
#include <GL/glew.h>
#include <SDL.h>
#include <SDL_image.h>
Expand All @@ -52,8 +53,7 @@ class RenderInterface_GL2_SDL : public RenderInterface_GL2 {
public:
RenderInterface_GL2_SDL(SDL_Renderer* renderer) : renderer(renderer) {}

void RenderGeometry(Rml::Vertex* vertices, int num_vertices, int* indices, int num_indices, Rml::TextureHandle texture,
const Rml::Vector2f& translation) override
void RenderGeometry(Rml::CompiledGeometryHandle handle, Rml::Vector2f translation, Rml::TextureHandle texture) override
{
SDL_Texture* sdl_texture = (SDL_Texture*)texture;
if (sdl_texture)
Expand All @@ -62,59 +62,66 @@ class RenderInterface_GL2_SDL : public RenderInterface_GL2 {
texture = RenderInterface_GL2::TextureEnableWithoutBinding;
}

RenderInterface_GL2::RenderGeometry(vertices, num_vertices, indices, num_indices, texture, translation);
RenderInterface_GL2::RenderGeometry(handle, translation, texture);

if (sdl_texture)
SDL_GL_UnbindTexture(sdl_texture);
}

bool LoadTexture(Rml::TextureHandle& texture_handle, Rml::Vector2i& texture_dimensions, const Rml::String& source) override
Rml::TextureHandle LoadTexture(Rml::Vector2i& texture_dimensions, const Rml::String& source) override
{
Rml::FileInterface* file_interface = Rml::GetFileInterface();
Rml::FileHandle file_handle = file_interface->Open(source);
if (!file_handle)
return false;
return {};

file_interface->Seek(file_handle, 0, SEEK_END);
size_t buffer_size = file_interface->Tell(file_handle);
const size_t buffer_size = file_interface->Tell(file_handle);
file_interface->Seek(file_handle, 0, SEEK_SET);

Rml::UniquePtr<char[]> buffer(new char[buffer_size]);
using Rml::byte;
Rml::UniquePtr<byte[]> buffer(new byte[buffer_size]);
file_interface->Read(buffer.get(), buffer_size, file_handle);
file_interface->Close(file_handle);

const size_t i = source.rfind('.');
Rml::String extension = (i == Rml::String::npos ? Rml::String() : source.substr(i + 1));
const size_t i_ext = source.rfind('.');
Rml::String extension = (i_ext == Rml::String::npos ? Rml::String() : source.substr(i_ext + 1));

SDL_Surface* surface = IMG_LoadTyped_RW(SDL_RWFromMem(buffer.get(), int(buffer_size)), 1, extension.c_str());
if (!surface)
return false;
return {};

texture_dimensions = {surface->w, surface->h};

if (surface->format->Amask == 0)
if (surface->format->format != SDL_PIXELFORMAT_RGBA32 && surface->format->format != SDL_PIXELFORMAT_BGRA32)
{
// Fix for rendering images with no alpha channel, see https://github.com/mikke89/RmlUi/issues/239
// Ensure correct format for premultiplied alpha conversion below. Additionally, fix rendering images with
// no alpha channel, see https://github.com/mikke89/RmlUi/issues/239
SDL_Surface* converted_surface = SDL_ConvertSurfaceFormat(surface, SDL_PixelFormatEnum::SDL_PIXELFORMAT_RGBA32, 0);
SDL_FreeSurface(surface);

if (!converted_surface)
return false;
return {};

surface = converted_surface;
}

SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
if (texture)
// Convert colors to premultiplied alpha, which is necessary for correct alpha compositing.
byte* pixels = static_cast<byte*>(surface->pixels);
for (int i = 0; i < surface->w * surface->h * 4; i += 4)
{
texture_handle = (Rml::TextureHandle)texture;
texture_dimensions = Rml::Vector2i(surface->w, surface->h);
const byte alpha = pixels[i + 3];
for (int j = 0; j < 3; ++j)
pixels[i + j] = byte(int(pixels[i + j]) * int(alpha) / 255);
}

SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_FreeSurface(surface);

return true;
return (Rml::TextureHandle)texture;
}

bool GenerateTexture(Rml::TextureHandle& texture_handle, const Rml::byte* source, const Rml::Vector2i& source_dimensions) override
Rml::TextureHandle GenerateTexture(Rml::Span<const Rml::byte> source, Rml::Vector2i source_dimensions) override
{
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
Uint32 rmask = 0xff000000;
Expand All @@ -128,13 +135,12 @@ class RenderInterface_GL2_SDL : public RenderInterface_GL2 {
Uint32 amask = 0xff000000;
#endif

SDL_Surface* surface = SDL_CreateRGBSurfaceFrom((void*)source, source_dimensions.x, source_dimensions.y, 32, source_dimensions.x * 4, rmask,
gmask, bmask, amask);
SDL_Surface* surface = SDL_CreateRGBSurfaceFrom((void*)source.data(), source_dimensions.x, source_dimensions.y, 32, source_dimensions.x * 4,
rmask, gmask, bmask, amask);
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
SDL_FreeSurface(surface);
texture_handle = (Rml::TextureHandle)texture;
return true;
return (Rml::TextureHandle)texture;
}

void ReleaseTexture(Rml::TextureHandle texture_handle) override { SDL_DestroyTexture((SDL_Texture*)texture_handle); }
Expand Down Expand Up @@ -190,7 +196,7 @@ bool Backend::Initialize(const char* window_name, int width, int height, bool al
window = SDL_CreateWindow(window_name, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, window_flags);
if (!window)
{
fprintf(stderr, "SDL error on create window: %s\n", SDL_GetError());
Rml::Log::Message(Rml::Log::LT_ERROR, "SDL error on create window: %s", SDL_GetError());
return false;
}
}
Expand All @@ -215,7 +221,7 @@ bool Backend::Initialize(const char* window_name, int width, int height, bool al
GLenum err = glewInit();
if (err != GLEW_OK)
{
fprintf(stderr, "GLEW error: %s\n", glewGetErrorString(err));
Rml::Log::Message(Rml::Log::LT_ERROR, "GLEW error: %s", glewGetErrorString(err));
return false;
}

Expand Down
76 changes: 33 additions & 43 deletions Backends/RmlUi_Backend_SDL_GL3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <RmlUi/Core/Context.h>
#include <RmlUi/Core/Core.h>
#include <RmlUi/Core/FileInterface.h>
#include <RmlUi/Core/Log.h>
#include <RmlUi/Core/Profiling.h>
#include <SDL.h>
#include <SDL_image.h>
Expand All @@ -53,12 +54,12 @@ class RenderInterface_GL3_SDL : public RenderInterface_GL3 {
public:
RenderInterface_GL3_SDL() {}

bool LoadTexture(Rml::TextureHandle& texture_handle, Rml::Vector2i& texture_dimensions, const Rml::String& source) override
Rml::TextureHandle LoadTexture(Rml::Vector2i& texture_dimensions, const Rml::String& source) override
{
Rml::FileInterface* file_interface = Rml::GetFileInterface();
Rml::FileHandle file_handle = file_interface->Open(source);
if (!file_handle)
return false;
return {};

file_interface->Seek(file_handle, 0, SEEK_END);
const size_t buffer_size = file_interface->Tell(file_handle);
Expand All @@ -69,38 +70,42 @@ class RenderInterface_GL3_SDL : public RenderInterface_GL3 {
file_interface->Read(buffer.get(), buffer_size, file_handle);
file_interface->Close(file_handle);

const size_t i = source.rfind('.');
Rml::String extension = (i == Rml::String::npos ? Rml::String() : source.substr(i + 1));
const size_t i_ext = source.rfind('.');
Rml::String extension = (i_ext == Rml::String::npos ? Rml::String() : source.substr(i_ext + 1));

SDL_Surface* surface = IMG_LoadTyped_RW(SDL_RWFromMem(buffer.get(), int(buffer_size)), 1, extension.c_str());
if (!surface)
return {};

bool success = false;
if (surface)
texture_dimensions = {surface->w, surface->h};

if (surface->format->format != SDL_PIXELFORMAT_RGBA32)
{
texture_dimensions.x = surface->w;
texture_dimensions.y = surface->h;
// Ensure correct format for premultiplied alpha conversion and GenerateTexture below.
SDL_Surface* converted_surface = SDL_ConvertSurfaceFormat(surface, SDL_PixelFormatEnum::SDL_PIXELFORMAT_RGBA32, 0);
SDL_FreeSurface(surface);

if (surface->format->format != SDL_PIXELFORMAT_RGBA32)
{
SDL_SetSurfaceAlphaMod(surface, SDL_ALPHA_OPAQUE);
SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE);
if (!converted_surface)
return {};

SDL_Surface* new_surface = SDL_CreateRGBSurfaceWithFormat(0, surface->w, surface->h, 32, SDL_PIXELFORMAT_RGBA32);
if (!new_surface)
return false;
surface = converted_surface;
}

if (SDL_BlitSurface(surface, 0, new_surface, 0) != 0)
return false;
// Convert colors to premultiplied alpha, which is necessary for correct alpha compositing.
const size_t pixels_byte_size = surface->w * surface->h * 4;
byte* pixels = static_cast<byte*>(surface->pixels);
for (size_t i = 0; i < pixels_byte_size; i += 4)
{
const byte alpha = pixels[i + 3];
for (size_t j = 0; j < 3; ++j)
pixels[i + j] = byte(int(pixels[i + j]) * int(alpha) / 255);
}

SDL_FreeSurface(surface);
surface = new_surface;
}
Rml::TextureHandle texture_handle = RenderInterface_GL3::GenerateTexture({pixels, pixels_byte_size}, texture_dimensions);

success = RenderInterface_GL3::GenerateTexture(texture_handle, (const Rml::byte*)surface->pixels, texture_dimensions);
SDL_FreeSurface(surface);
}
SDL_FreeSurface(surface);

return success;
return texture_handle;
}
};

Expand Down Expand Up @@ -144,30 +149,15 @@ bool Backend::Initialize(const char* window_name, int width, int height, bool al
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
#endif

// Request stencil buffer of at least 8-bit size to supporting clipping on transformed elements.
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

// Enable linear filtering and MSAA for better-looking visuals, especially when transforms are applied.
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 2);

const Uint32 window_flags = (SDL_WINDOW_OPENGL | (allow_resize ? SDL_WINDOW_RESIZABLE : 0));

SDL_Window* window = SDL_CreateWindow(window_name, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, window_flags);
if (!window)
{
// Try again on low-quality settings.
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest");
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
window = SDL_CreateWindow(window_name, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, window_flags);
if (!window)
{
fprintf(stderr, "SDL error on create window: %s\n", SDL_GetError());
return false;
}
Rml::Log::Message(Rml::Log::LT_ERROR, "SDL error on create window: %s", SDL_GetError());
return false;
}

SDL_GLContext glcontext = SDL_GL_CreateContext(window);
Expand All @@ -176,7 +166,7 @@ bool Backend::Initialize(const char* window_name, int width, int height, bool al

if (!RmlGL3::Initialize())
{
fprintf(stderr, "Could not initialize OpenGL");
Rml::Log::Message(Rml::Log::LT_ERROR, "Failed to initialize OpenGL renderer");
return false;
}

Expand All @@ -185,7 +175,7 @@ bool Backend::Initialize(const char* window_name, int width, int height, bool al
if (!data->render_interface)
{
data.reset();
fprintf(stderr, "Could not initialize OpenGL3 render interface.");
Rml::Log::Message(Rml::Log::LT_ERROR, "Failed to initialize OpenGL3 render interface");
return false;
}

Expand Down
9 changes: 5 additions & 4 deletions Backends/RmlUi_Backend_SDL_VK.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <RmlUi/Core/Context.h>
#include <RmlUi/Core/Core.h>
#include <RmlUi/Core/FileInterface.h>
#include <RmlUi/Core/Log.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_vulkan.h>

Expand Down Expand Up @@ -69,7 +70,7 @@ bool Backend::Initialize(const char* window_name, int width, int height, bool al
SDL_Window* window = SDL_CreateWindow(window_name, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, window_flags);
if (!window)
{
fprintf(stderr, "SDL error on create window: %s\n", SDL_GetError());
Rml::Log::Message(Rml::Log::LT_ERROR, "SDL error on create window: %s", SDL_GetError());
return false;
}

Expand All @@ -82,14 +83,14 @@ bool Backend::Initialize(const char* window_name, int width, int height, bool al
if (!SDL_Vulkan_GetInstanceExtensions(window, &count, nullptr))
{
data.reset();
fprintf(stderr, "Could not get required vulkan extensions");
Rml::Log::Message(Rml::Log::LT_ERROR, "Failed to get required vulkan extensions");
return false;
}
extensions.resize(count);
if (!SDL_Vulkan_GetInstanceExtensions(window, &count, extensions.data()))
{
data.reset();
fprintf(stderr, "Could not get required vulkan extensions");
Rml::Log::Message(Rml::Log::LT_ERROR, "Failed to get required vulkan extensions");
return false;
}
}
Expand All @@ -98,7 +99,7 @@ bool Backend::Initialize(const char* window_name, int width, int height, bool al
[](VkInstance instance, VkSurfaceKHR* out_surface) { return (bool)SDL_Vulkan_CreateSurface(data->window, instance, out_surface); }))
{
data.reset();
fprintf(stderr, "Could not initialize Vulkan render interface.");
Rml::Log::Message(Rml::Log::LT_ERROR, "Failed to initialize Vulkan render interface");
return false;
}

Expand Down
Loading

0 comments on commit 8559aaf

Please sign in to comment.