Added ClippingMask class, for clipping with scissor test, clip planes and stencil test.

Fixed some minor problems.

--HG--
branch : dev
This commit is contained in:
Martí­n Lucas Golini
2017-03-30 01:17:11 -03:00
parent 12c74347ac
commit e09b07ecc0
24 changed files with 835 additions and 643 deletions

View File

@@ -214,7 +214,7 @@ void TileMap::draw() {
GlobalBatchRenderer::instance()->draw();
if ( getClipedArea() ) {
mWindow->clipEnable( mScreenPos.x, mScreenPos.y, mViewSize.x, mViewSize.y );
GLi->getClippingMask()->clipEnable( mScreenPos.x, mScreenPos.y, mViewSize.x, mViewSize.y );
}
if ( getDrawBackground() ) {
@@ -252,7 +252,7 @@ void TileMap::draw() {
GLi->loadMatrixf( oldM );
if ( getClipedArea() ) {
mWindow->clipDisable();
GLi->getClippingMask()->clipDisable();
}
}

View File

@@ -0,0 +1,120 @@
#include <eepp/graphics/renderer/clippingmask.hpp>
#include <eepp/graphics/renderer/renderer.hpp>
#include <eepp/graphics/globalbatchrenderer.hpp>
#include <eepp/graphics/renderer/openglext.hpp>
#include <eepp/graphics/drawable.hpp>
#include <eepp/window/engine.hpp>
#include <algorithm>
using namespace EE::Window;
namespace EE { namespace Graphics {
void ClippingMask::clipEnable( const Int32& x, const Int32& y, const Uint32& Width, const Uint32& Height ) {
EE::Window::Window * window = Engine::instance()->getCurrentWindow();
GlobalBatchRenderer::instance()->draw();
Rectf r( x, y, x + Width, y + Height );
if ( !mScissorsClipped.empty() ) {
Rectf r2 = mScissorsClipped.back();
r.shrink( r2 );
}
GLi->scissor( r.Left, window->getHeight() - r.Bottom, r.getWidth(), r.getHeight() );
GLi->enable( GL_SCISSOR_TEST );
if ( mPushScissorClip ) {
mScissorsClipped.push_back( r );
}
}
void ClippingMask::clipDisable() {
GlobalBatchRenderer::instance()->draw();
if ( ! mScissorsClipped.empty() ) { // This should always be true
mScissorsClipped.pop_back();
}
if ( mScissorsClipped.empty() ) {
GLi->disable( GL_SCISSOR_TEST );
} else {
Rectf R( mScissorsClipped.back() );
mPushScissorClip = false;
clipEnable( R.Left, R.Top, R.getWidth(), R.getHeight() );
mPushScissorClip = true;
}
}
void ClippingMask::clipPlaneEnable( const Int32& x, const Int32& y, const Int32& Width, const Int32& Height ) {
GlobalBatchRenderer::instance()->draw();
GLi->clip2DPlaneEnable( x, y, Width, Height );
}
void ClippingMask::clipPlaneDisable() {
GlobalBatchRenderer::instance()->draw();
GLi->clip2DPlaneDisable();
}
ClippingMask::ClippingMask() :
mPushScissorClip( true ),
mMode( Inclusive )
{
}
std::size_t ClippingMask::getMaskCount() const {
return mDrawables.size();
}
const Drawable*& ClippingMask::operator [](std::size_t index) {
return mDrawables[index];
}
const Drawable* const& ClippingMask::operator [](std::size_t index) const {
return mDrawables[index];
}
void ClippingMask::clearMasks() {
mDrawables.clear();
}
void ClippingMask::appendMask(const Drawable& drawable) {
mDrawables.push_back(&drawable);
}
void ClippingMask::removeMask(const Drawable& drawable) {
mDrawables.erase(std::remove(mDrawables.begin(), mDrawables.end(), &drawable), mDrawables.end());
}
ClippingMask::Mode ClippingMask::getMaskMode() const {
return mMode;
}
void ClippingMask::setMaskMode(Mode theMode) {
mMode = theMode;
}
void ClippingMask::stencilMaskEnable() {
GLi->enable(GL_STENCIL_TEST);
GLi->stencilMask(0xFF);
GLi->stencilFunc(GL_NEVER, 1, 0xFF);
GLi->stencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);
drawMask();
GLi->stencilFunc(GL_EQUAL, getMaskMode() == Inclusive ? 1 : 0, 0xFF);
}
void ClippingMask::stencilMaskDisable( bool clearMasks ) {
GLi->disable(GL_STENCIL_TEST);
if ( clearMasks )
this->clearMasks();
}
void ClippingMask::drawMask() {
for ( std::size_t i = 0; i < getMaskCount(); i++ )
const_cast<Drawable*>(mDrawables[i])->draw();
}
}}

View File

@@ -115,12 +115,14 @@ Renderer::Renderer() :
mBlendEnabled( false ),
mQuadVertexs( 4 ),
mLineWidth( 1 ),
mCurVAO( 0 )
mCurVAO( 0 ),
mClippingMask( eeNew( ClippingMask , () ) )
{
GLi = this;
}
Renderer::~Renderer() {
eeSAFE_DELETE( mClippingMask );
GLi = NULL;
}
@@ -623,6 +625,10 @@ const int& Renderer::quadVertexs() const {
return mQuadVertexs;
}
ClippingMask * Renderer::getClippingMask() const {
return mClippingMask;
}
void Renderer::bindVertexArray ( unsigned int array ) {
#if !defined( EE_GLES )
if ( mCurVAO != array ) {

View File

@@ -225,7 +225,7 @@ const Sizei& UIControl::getRealSize() {
UIControl * UIControl::setVisible( const bool& visible ) {
mVisible = visible;
onVisibleChange();
onVisibilityChange();
return this;
}
@@ -663,7 +663,7 @@ void UIControl::toPosition( const Uint32& Pos ) {
}
}
void UIControl::onVisibleChange() {
void UIControl::onVisibilityChange() {
sendCommonEvent( UIEvent::EventOnVisibleChange );
}

View File

@@ -2,6 +2,7 @@
#include <eepp/window/engine.hpp>
#include <eepp/window/cursormanager.hpp>
#include <eepp/graphics/globalbatchrenderer.hpp>
#include <eepp/graphics/renderer/renderer.hpp>
#include <eepp/helper/pugixml/pugixml.hpp>
#include <algorithm>
@@ -286,19 +287,19 @@ const Uint32& UIManager::getLastPressTrigger() const {
}
void UIManager::clipPlaneEnable( const Int32& x, const Int32& y, const Uint32& Width, const Uint32& Height ) {
mWindow->clipPlaneEnable( x, y, Width, Height );
GLi->getClippingMask()->clipPlaneEnable( x, y, Width, Height );
}
void UIManager::clipPlaneDisable() {
mWindow->clipPlaneDisable();
GLi->getClippingMask()->clipPlaneDisable();
}
void UIManager::clipEnable( const Int32& x, const Int32& y, const Uint32& Width, const Uint32& Height ) {
mWindow->clipEnable( x, y, Width, Height );
GLi->getClippingMask()->clipEnable( x, y, Width, Height );
}
void UIManager::clipDisable() {
mWindow->clipDisable();
GLi->getClippingMask()->clipDisable();
}
void UIManager::clipSmartEnable(UIControl * ctrl, const Int32 & x, const Int32 & y, const Uint32 & Width, const Uint32 & Height) {

View File

@@ -264,6 +264,11 @@ void UIWidget::onPositionChange() {
UIControlAnim::onPositionChange();
}
void UIWidget::onVisibilityChange() {
updateAnchorsDistances();
UIControlAnim::onVisibilityChange();
}
void UIWidget::onAutoSize() {
}

View File

@@ -49,8 +49,7 @@ Window::Window( WindowSettings Settings, ContextSettings Context, Clipboard * Cl
mInput( Input ),
mCursorManager( CursorManager ),
mPlatform( NULL ),
mNumCallBacks( 0 ),
mPushScissorClip( true )
mNumCallBacks( 0 )
{
mWindow.WindowConfig = Settings;
mWindow.ContextConfig = Context;
@@ -327,51 +326,6 @@ void Window::display( bool clear ) {
limitFps();
}
void Window::clipEnable( const Int32& x, const Int32& y, const Uint32& Width, const Uint32& Height ) {
GlobalBatchRenderer::instance()->draw();
Rectf r( x, y, x + Width, y + Height );
if ( !mScissorsClipped.empty() ) {
Rectf r2 = mScissorsClipped.back();
r.shrink( r2 );
}
GLi->scissor( r.Left, getHeight() - r.Bottom, r.getWidth(), r.getHeight() );
GLi->enable( GL_SCISSOR_TEST );
if ( mPushScissorClip ) {
mScissorsClipped.push_back( r );
}
}
void Window::clipDisable() {
GlobalBatchRenderer::instance()->draw();
if ( ! mScissorsClipped.empty() ) { // This should always be true
mScissorsClipped.pop_back();
}
if ( mScissorsClipped.empty() ) {
GLi->disable( GL_SCISSOR_TEST );
} else {
Rectf R( mScissorsClipped.back() );
mPushScissorClip = false;
clipEnable( R.Left, R.Top, R.getWidth(), R.getHeight() );
mPushScissorClip = true;
}
}
void Window::clipPlaneEnable( const Int32& x, const Int32& y, const Int32& Width, const Int32& Height ) {
GlobalBatchRenderer::instance()->draw();
GLi->clip2DPlaneEnable( x, y, Width, Height );
}
void Window::clipPlaneDisable() {
GlobalBatchRenderer::instance()->draw();
GLi->clip2DPlaneDisable();
}
Clipboard * Window::getClipboard() const {
return mClipboard;
}

View File

@@ -1,16 +1,10 @@
#include <eepp/ee.hpp>
#define GL_STENCIL_TEST 0x0B90
#define GL_EQUAL 0x0202
#define GL_NEVER 0x0200
#define GL_KEEP 0x1E00
#define GL_REPLACE 0x1E01
EE::Window::Window * win = NULL;
float circ = 0, circ2 = 0;
int op = 1;
ArcDrawable arcDrawable( 100, 64 );
RectangleDrawable rectDrawable( Vector2f(0,0), Sizef(250,250) );
ArcDrawable arcDrawable( 200, 64 );
CircleDrawable circleDrawableMask( 150, 64 );
void mainLoop()
{
@@ -46,46 +40,20 @@ void mainLoop()
Vector2f winCenter( win->getWidth() * 0.5f, win->getHeight() * 0.5f );
/*
GLi->enable(GL_STENCIL_TEST);
GLi->stencilMask(0xFF);
GLi->stencilFunc(GL_NEVER, 1, 0xFF);
GLi->stencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);
ClippingMask * clippingMask = Renderer::instance()->getClippingMask();
p.drawCircle( winCenter, 150, 64 );
circleDrawableMask.setPosition( winCenter );
GLi->stencilFunc(GL_EQUAL, 0, 0xFF);
clippingMask->setMaskMode( ClippingMask::Exclusive );
clippingMask->clearMasks();
clippingMask->appendMask( circleDrawableMask );
clippingMask->stencilMaskEnable();
// Draw a circle
p.drawArc( winCenter, 200, 64, circ, circ2 );
GLi->disable(GL_STENCIL_TEST);
*/
/*
GLi->Enable(GL_STENCIL_TEST);
GLi->StencilFunc(GL_ALWAYS, 1, 1);
GLi->ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
GLi->StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
p.SetColor( ColorA( 255, 255, 255, 255 ) );
p.DrawCircle( winCenter, 150, 40 );
GLi->StencilFunc(GL_NOTEQUAL, 1, 1);
GLi->StencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
GLi->ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
// Draw a circle
p.SetColor( ColorA( 0, 255, 0, 150 ) );
p.DrawArc( winCenter, 200, 40, circ, circ2 );
GLi->Disable(GL_STENCIL_TEST);
*/
arcDrawable.setArcAngle( circ );
arcDrawable.setArcStartAngle( circ2 );
arcDrawable.draw( winCenter );
rectDrawable.draw();
clippingMask->stencilMaskDisable();
// Draw frame
win->display();
@@ -102,12 +70,11 @@ EE_MAIN_FUNC int main (int argc, char * argv [])
// Set window background color
win->setClearColor( Color( 50, 50, 50 ) );
arcDrawable.setColorFilter( ColorA( 0, 255, 0, 150 ) );
arcDrawable.setColor( ColorA( 0, 255, 0, 150 ) );
arcDrawable.setFillMode( DRAW_FILL );
rectDrawable.setColorFilter( ColorA( 255, 0, 0, 150 ) );
rectDrawable.setFillMode( DRAW_FILL );
rectDrawable.setCorners( 64 );
circleDrawableMask.setColor( ColorA( 0, 255, 0, 150 ) );
circleDrawableMask.setFillMode( DRAW_FILL );
// Set the MainLoop function and run it
// This is the application loop, it will loop until the window is closed.

View File

@@ -1427,9 +1427,9 @@ void EETest::render() {
screen1();
mWindow->setView( mWindow->getDefaultView() );
mWindow->clipEnable( (Int32)HWidth - 320, (Int32)HHeight - 240, 640, 480 );
GLi->getClippingMask()->clipEnable( (Int32)HWidth - 320, (Int32)HHeight - 240, 640, 480 );
screen3();
mWindow->clipDisable();
GLi->getClippingMask()->clipDisable();
}
ColorA ColRR1( 150, 150, 150, 220 );