-
Notifications
You must be signed in to change notification settings - Fork 172
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor and test clipping code (#673)
And allow using Gosu.clip_to within Gosu.render.
- Loading branch information
Showing
16 changed files
with
199 additions
and
202 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
#include "ClipRectStack.hpp" | ||
#include <stdexcept> | ||
|
||
void Gosu::ClipRectStack::clear() | ||
{ | ||
m_stack.clear(); | ||
m_effective_rect = std::nullopt; | ||
} | ||
|
||
void Gosu::ClipRectStack::push(const Rect& rect) | ||
{ | ||
m_stack.push_back(rect); | ||
if (m_effective_rect) { | ||
m_effective_rect->clip_to(rect); | ||
} | ||
else { | ||
m_effective_rect = rect; | ||
} | ||
} | ||
|
||
void Gosu::ClipRectStack::pop() | ||
{ | ||
if (m_stack.empty()) { | ||
throw std::logic_error("ClipRectStack is empty"); | ||
} | ||
m_stack.pop_back(); | ||
|
||
// The clip rect is the intersection of all active clip rects (if any). | ||
m_effective_rect = std::nullopt; | ||
for (const auto& rect : m_stack) { | ||
if (m_effective_rect) { | ||
m_effective_rect->clip_to(rect); | ||
} | ||
else { | ||
m_effective_rect = rect; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,90 +1,24 @@ | ||
#pragma once | ||
|
||
#include <Gosu/Utility.hpp> | ||
#include "GraphicsImpl.hpp" | ||
#include <cassert> | ||
#include <limits> | ||
#include <optional> | ||
#include <stdexcept> | ||
#include <vector> | ||
|
||
class Gosu::ClipRectStack | ||
namespace Gosu | ||
{ | ||
std::vector<ClipRect> stack; | ||
bool has_effective_rect; // is effective_rect valid? | ||
ClipRect effective_rect; | ||
|
||
void update_effective_rect() | ||
class ClipRectStack | ||
{ | ||
// Nothing to do, no clipping in place. | ||
if (stack.empty()) { | ||
has_effective_rect = false; | ||
return; | ||
} | ||
|
||
ClipRect result = { 0.0, 0.0, 1e10, 1e10 }; | ||
for (std::size_t i = 0, end = stack.size(); i < end; ++i) { | ||
const ClipRect& rect = stack[i]; | ||
int result_right = std::min(result.x + result.width, rect.x + rect.width); | ||
int result_bottom = std::min(result.y + result.height, rect.y + rect.height); | ||
result.x = std::max(result.x, rect.x); | ||
result.y = std::max(result.y, rect.y); | ||
|
||
if (result.x >= result_right || result.y >= result_bottom) { | ||
// We have clipped the world away! | ||
has_effective_rect = false; | ||
return; | ||
} | ||
|
||
result.width = result_right - result.x; | ||
result.height = result_bottom - result.y; | ||
} | ||
|
||
// On the iPhone, we may have to multiply everything by 2 for Retina displays. | ||
// TODO: Doesn't this affect Retina Macs as well? | ||
// TODO: This should be handled by a global transform. | ||
int fac = clip_rect_base_factor(); | ||
result.x *= fac; | ||
result.y *= fac; | ||
result.width *= fac; | ||
result.height *= fac; | ||
|
||
// Normal clipping. | ||
effective_rect = result; | ||
has_effective_rect = true; | ||
} | ||
|
||
public: | ||
ClipRectStack() | ||
: has_effective_rect(false) | ||
{ | ||
} | ||
|
||
void clear() | ||
{ | ||
stack.clear(); | ||
has_effective_rect = false; | ||
} | ||
|
||
void begin_clipping(double x, double y, double width, double height) | ||
{ | ||
ClipRect rect = { x, y, width, height }; | ||
stack.push_back(rect); | ||
update_effective_rect(); | ||
} | ||
|
||
void end_clipping() | ||
{ | ||
assert (!stack.empty()); | ||
stack.pop_back(); | ||
update_effective_rect(); | ||
} | ||
|
||
const ClipRect* maybe_effective_rect() const | ||
{ | ||
return has_effective_rect ? &effective_rect : 0; | ||
} | ||
|
||
bool clipped_world_away() const | ||
{ | ||
// When we have no effective rect but the stack is not empty, we have clipped | ||
// the whole world away and don't need to render things. | ||
return !has_effective_rect && !stack.empty(); | ||
} | ||
}; | ||
std::vector<Rect> m_stack; | ||
std::optional<Rect> m_effective_rect; | ||
|
||
public: | ||
void clear(); | ||
void push(const Rect& rect); | ||
void pop(); | ||
|
||
const std::optional<Rect>& effective_rect() const { return m_effective_rect; } | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.