mirror of
https://github.com/wesnoth/wesnoth
synced 2025-04-14 20:34:02 +00:00
Enable multi-pass rendering.
An extra rendering pass can be requested during render or expose by calling draw_manager::request_extra_render_pass(). This is used for blur effects.
This commit is contained in:
parent
8d4deeef02
commit
7695ee7159
|
@ -48,6 +48,7 @@ std::vector<rect> invalidated_regions_;
|
|||
bool drawing_ = false;
|
||||
bool tlds_need_tidying_ = false;
|
||||
uint32_t last_sparkle_ = 0;
|
||||
bool extra_pass_requested_ = false;
|
||||
} // namespace
|
||||
|
||||
namespace draw_manager {
|
||||
|
@ -123,6 +124,11 @@ void invalidate_all()
|
|||
invalidate_region(video::game_canvas());
|
||||
}
|
||||
|
||||
void request_extra_render_pass()
|
||||
{
|
||||
extra_pass_requested_ = true;
|
||||
}
|
||||
|
||||
void sparkle()
|
||||
{
|
||||
if (drawing_) {
|
||||
|
@ -153,7 +159,16 @@ void sparkle()
|
|||
draw_manager::render();
|
||||
|
||||
// Draw to the screen.
|
||||
if (draw_manager::expose()) {
|
||||
bool drew_something = draw_manager::expose();
|
||||
|
||||
// If extra render passes are requested, render and draw again.
|
||||
while (extra_pass_requested_) {
|
||||
extra_pass_requested_ = false;
|
||||
draw_manager::render();
|
||||
drew_something |= draw_manager::expose();
|
||||
}
|
||||
|
||||
if (drew_something) {
|
||||
// We only need to flip the screen if something was drawn.
|
||||
video::render_screen();
|
||||
} else {
|
||||
|
|
|
@ -92,6 +92,17 @@ void invalidate_region(const rect& region);
|
|||
/** Mark the entire screen as requiring redraw. */
|
||||
void invalidate_all();
|
||||
|
||||
/**
|
||||
* Request an extra render pass.
|
||||
*
|
||||
* This is used for blur effects, which need to first render what's
|
||||
* underneath so that it can be blurred.
|
||||
*
|
||||
* There is not currently any limit to the number of extra render passes,
|
||||
* but do try to keep it finite.
|
||||
*/
|
||||
void request_extra_render_pass();
|
||||
|
||||
/**
|
||||
* Ensure that everything which needs to be drawn is drawn.
|
||||
*
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "gui/core/canvas_private.hpp"
|
||||
|
||||
#include "draw.hpp"
|
||||
#include "draw_manager.hpp"
|
||||
#include "font/text.hpp"
|
||||
#include "formatter.hpp"
|
||||
#include "gettext.hpp"
|
||||
|
@ -526,23 +527,19 @@ bool canvas::update_blur(const rect& screen_region, bool force)
|
|||
// We could use the previous render frame, but there could well have been
|
||||
// another element there last frame such as a popup window which we
|
||||
// don't want to be part of the blur.
|
||||
// The only stable solution is to render in multiple passes.
|
||||
// For now, we defer rendering of translucent elements to the next frame,
|
||||
// so one frame is rendered without the element, then the element captures
|
||||
// the result from that frame and renders itself on the next frame.
|
||||
// Ultimately even with hardware acceleration of the blur effect
|
||||
// a similar solution will need to be retained. The difference with a
|
||||
// better future implementation would be that the multiple rendering
|
||||
// passes can be managed at a higher level, and that they can be done
|
||||
// within a single frame.
|
||||
// The stable solution is to render in multiple passes,
|
||||
// so that is what we shall do.
|
||||
|
||||
// For the first pass, this element and its children are not rendered.
|
||||
if(!deferred_) {
|
||||
DBG_GUI_D << "Deferring blur at " << screen_region;
|
||||
deferred_ = true;
|
||||
draw_manager::request_extra_render_pass();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read and blur pixels from the previous render frame.
|
||||
// For the second pass we read the result of the first pass at
|
||||
// this widget's location, and blur it.
|
||||
DBG_GUI_D << "Blurring " << screen_region << " depth " << blur_depth_;
|
||||
rect read_region = screen_region;
|
||||
auto setter = draw::set_render_target({});
|
||||
|
|
Loading…
Reference in New Issue
Block a user