-
Notifications
You must be signed in to change notification settings - Fork 326
/
Copy pathRmlUi_Renderer_GL3.h
241 lines (183 loc) · 8.51 KB
/
RmlUi_Renderer_GL3.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
/*
* This source file is part of RmlUi, the HTML/CSS Interface Middleware
*
* For the latest information, see http://github.com/mikke89/RmlUi
*
* Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
* Copyright (c) 2019-2023 The RmlUi Team, and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
#ifndef RMLUI_BACKENDS_RENDERER_GL3_H
#define RMLUI_BACKENDS_RENDERER_GL3_H
#include <RmlUi/Core/RenderInterface.h>
#include <RmlUi/Core/Types.h>
#include <bitset>
enum class ProgramId;
enum class UniformId;
class RenderLayerStack;
namespace Gfx {
struct ProgramData;
struct FramebufferData;
} // namespace Gfx
class RenderInterface_GL3 : public Rml::RenderInterface {
public:
RenderInterface_GL3();
~RenderInterface_GL3();
// Returns true if the renderer was successfully constructed.
explicit operator bool() const { return static_cast<bool>(program_data); }
// The viewport should be updated whenever the window size changes.
void SetViewport(int viewport_width, int viewport_height, int viewport_offset_x = 0, int viewport_offset_y = 0);
// Sets up OpenGL states for taking rendering commands from RmlUi.
void BeginFrame();
// Draws the result to the backbuffer and restores OpenGL state.
void EndFrame();
// Optional, can be used to clear the active framebuffer.
void Clear();
// -- Inherited from Rml::RenderInterface --
Rml::CompiledGeometryHandle CompileGeometry(Rml::Span<const Rml::Vertex> vertices, Rml::Span<const int> indices) override;
void RenderGeometry(Rml::CompiledGeometryHandle handle, Rml::Vector2f translation, Rml::TextureHandle texture) override;
void ReleaseGeometry(Rml::CompiledGeometryHandle handle) override;
Rml::TextureHandle LoadTexture(Rml::Vector2i& texture_dimensions, const Rml::String& source) override;
Rml::TextureHandle GenerateTexture(Rml::Span<const Rml::byte> source_data, Rml::Vector2i source_dimensions) override;
void ReleaseTexture(Rml::TextureHandle texture_handle) override;
void EnableScissorRegion(bool enable) override;
void SetScissorRegion(Rml::Rectanglei region) override;
void EnableClipMask(bool enable) override;
void RenderToClipMask(Rml::ClipMaskOperation mask_operation, Rml::CompiledGeometryHandle geometry, Rml::Vector2f translation) override;
void SetTransform(const Rml::Matrix4f* transform) override;
Rml::LayerHandle PushLayer() override;
void CompositeLayers(Rml::LayerHandle source, Rml::LayerHandle destination, Rml::BlendMode blend_mode,
Rml::Span<const Rml::CompiledFilterHandle> filters) override;
void PopLayer() override;
Rml::TextureHandle SaveLayerAsTexture() override;
Rml::CompiledFilterHandle SaveLayerAsMaskImage() override;
Rml::CompiledFilterHandle CompileFilter(const Rml::String& name, const Rml::Dictionary& parameters) override;
void ReleaseFilter(Rml::CompiledFilterHandle filter) override;
Rml::CompiledShaderHandle CompileShader(const Rml::String& name, const Rml::Dictionary& parameters) override;
void RenderShader(Rml::CompiledShaderHandle shader_handle, Rml::CompiledGeometryHandle geometry_handle, Rml::Vector2f translation,
Rml::TextureHandle texture) override;
void ReleaseShader(Rml::CompiledShaderHandle effect_handle) override;
// Can be passed to RenderGeometry() to enable texture rendering without changing the bound texture.
static constexpr Rml::TextureHandle TextureEnableWithoutBinding = Rml::TextureHandle(-1);
// Can be passed to RenderGeometry() to leave the bound texture and used program unchanged.
static constexpr Rml::TextureHandle TexturePostprocess = Rml::TextureHandle(-2);
// -- Utility functions for clients --
const Rml::Matrix4f& GetTransform() const;
void ResetProgram();
private:
void UseProgram(ProgramId program_id);
int GetUniformLocation(UniformId uniform_id) const;
void SubmitTransformUniform(Rml::Vector2f translation);
void BlitLayerToPostprocessPrimary(Rml::LayerHandle layer_handle);
void RenderFilters(Rml::Span<const Rml::CompiledFilterHandle> filter_handles);
void SetScissor(Rml::Rectanglei region, bool vertically_flip = false);
void DrawFullscreenQuad();
void DrawFullscreenQuad(Rml::Vector2f uv_offset, Rml::Vector2f uv_scaling = Rml::Vector2f(1.f));
void RenderBlur(float sigma, const Gfx::FramebufferData& source_destination, const Gfx::FramebufferData& temp, Rml::Rectanglei window_flipped);
static constexpr size_t MaxNumPrograms = 32;
std::bitset<MaxNumPrograms> program_transform_dirty;
Rml::Matrix4f transform;
Rml::Matrix4f projection;
ProgramId active_program = {};
Rml::Rectanglei scissor_state;
int viewport_width = 0;
int viewport_height = 0;
int viewport_offset_x = 0;
int viewport_offset_y = 0;
Rml::CompiledGeometryHandle fullscreen_quad_geometry = {};
Rml::UniquePtr<const Gfx::ProgramData> program_data;
/*
Manages render targets, including the layer stack and postprocessing framebuffers.
Layers can be pushed and popped, creating new framebuffers as needed. Typically, geometry is rendered to the top
layer. The layer framebuffers may have MSAA enabled.
Postprocessing framebuffers are separate from the layers, and are commonly used to apply texture-wide effects
such as filters. They are used both as input and output during rendering, and do not use MSAA.
*/
class RenderLayerStack {
public:
RenderLayerStack();
~RenderLayerStack();
// Push a new layer. All references to previously retrieved layers are invalidated.
Rml::LayerHandle PushLayer();
// Pop the top layer. All references to previously retrieved layers are invalidated.
void PopLayer();
const Gfx::FramebufferData& GetLayer(Rml::LayerHandle layer) const;
const Gfx::FramebufferData& GetTopLayer() const;
Rml::LayerHandle GetTopLayerHandle() const;
const Gfx::FramebufferData& GetPostprocessPrimary() { return EnsureFramebufferPostprocess(0); }
const Gfx::FramebufferData& GetPostprocessSecondary() { return EnsureFramebufferPostprocess(1); }
const Gfx::FramebufferData& GetPostprocessTertiary() { return EnsureFramebufferPostprocess(2); }
const Gfx::FramebufferData& GetBlendMask() { return EnsureFramebufferPostprocess(3); }
void SwapPostprocessPrimarySecondary();
void BeginFrame(int new_width, int new_height);
void EndFrame();
private:
void DestroyFramebuffers();
const Gfx::FramebufferData& EnsureFramebufferPostprocess(int index);
int width = 0, height = 0;
// The number of active layers is manually tracked since we re-use the framebuffers stored in the fb_layers stack.
int layers_size = 0;
Rml::Vector<Gfx::FramebufferData> fb_layers;
Rml::Vector<Gfx::FramebufferData> fb_postprocess;
};
RenderLayerStack render_layers;
struct GLStateBackup {
bool enable_cull_face;
bool enable_blend;
bool enable_stencil_test;
bool enable_scissor_test;
bool enable_depth_test;
int viewport[4];
int scissor[4];
int active_texture;
int stencil_clear_value;
float color_clear_value[4];
unsigned char color_writemask[4];
int blend_equation_rgb;
int blend_equation_alpha;
int blend_src_rgb;
int blend_dst_rgb;
int blend_src_alpha;
int blend_dst_alpha;
struct Stencil {
int func;
int ref;
int value_mask;
int writemask;
int fail;
int pass_depth_fail;
int pass_depth_pass;
};
Stencil stencil_front;
Stencil stencil_back;
};
GLStateBackup glstate_backup = {};
};
/**
Helper functions for the OpenGL 3 renderer.
*/
namespace RmlGL3 {
// Loads OpenGL functions. Optionally, the out message describes the loaded GL version or an error message on failure.
bool Initialize(Rml::String* out_message = nullptr);
// Unloads OpenGL functions.
void Shutdown();
} // namespace RmlGL3
#endif