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

@@ -45,11 +45,11 @@ Entropia Engine++
* Backend based module, this means that you can easily create a backend for the window/input handling.
* Currently supports SDL 1.2, SDL 2 and SFML as backends.
* Currently supports SDL 2 and SFML as backends.
* Clipboard support ( SDL 2 backend and partial support with SDL 1.2 ).
* Clipboard support ( SDL 2 backend ).
* Color hardware cursors ( SDL 2 fully supported, partial support with SDL 1.2 and SFML ).
* Color hardware cursors ( SDL 2 fully supported, partial support with SFML ).
* Multiple windows
@@ -74,7 +74,7 @@ Entropia Engine++
* Provides all the basics stuffs for the full multi-threading support of the engine, file formats support for packing, clocks, resource manager, and much more.
*Core Module:*
**Core Module:**
--------------
* Customizable Memory Manager. Used by default in debug mode to track memory leaks.

View File

@@ -6,7 +6,7 @@
namespace EE { namespace Graphics {
class ArcDrawable : public PrimitiveDrawable {
class EE_API ArcDrawable : public PrimitiveDrawable {
public:
ArcDrawable();

View File

@@ -5,7 +5,7 @@
namespace EE { namespace Graphics {
class CircleDrawable : public ArcDrawable {
class EE_API CircleDrawable : public ArcDrawable {
public:
CircleDrawable();

View File

@@ -7,7 +7,7 @@ namespace EE { namespace Graphics {
class VertexBuffer;
class PrimitiveDrawable : public Drawable {
class EE_API PrimitiveDrawable : public Drawable {
public:
PrimitiveDrawable( EE_DRAWABLE_TYPE drawableType );
@@ -36,7 +36,6 @@ class PrimitiveDrawable : public Drawable {
EE_FILL_MODE mFillMode;
EE_BLEND_MODE mBlendMode;
Float mLineWidth;
Vector2f mPosition;
bool mNeedsUpdate;
bool mRecreateVertexBuffer;
VertexBuffer * mVertexBuffer;

View File

@@ -6,7 +6,7 @@
namespace EE { namespace Graphics {
class RectangleDrawable : public PrimitiveDrawable {
class EE_API RectangleDrawable : public PrimitiveDrawable {
public:
RectangleDrawable();

View File

@@ -0,0 +1,65 @@
#ifndef EE_GRAPHICS_CLIPPINGMASK_HPP
#define EE_GRAPHICS_CLIPPINGMASK_HPP
#include <eepp/core.hpp>
#include <eepp/graphics/drawable.hpp>
#include <eepp/math/rect.hpp>
#include <list>
namespace EE { namespace Graphics {
class EE_API ClippingMask {
public:
enum Mode {
Inclusive,
Exclusive
};
/** Set the current Clipping area ( default the entire window, SCISSOR TEST ). */
void clipEnable( const Int32& x, const Int32& y, const Uint32& Width, const Uint32& Height );
/** Disable the Clipping area */
void clipDisable();
/** Clip the area with a plane. */
void clipPlaneEnable( const Int32& x, const Int32& y, const Int32& Width, const Int32& Height );
/** Disable the clip plane area. */
void clipPlaneDisable();
std::size_t getMaskCount() const;
const Drawable*& operator [](std::size_t index);
const Drawable* const& operator [](std::size_t index) const;
void clearMasks();
void appendMask(const Drawable& drawable);
void removeMask(const Drawable& drawable);
Mode getMaskMode() const;
void setMaskMode(Mode theMode);
void stencilMaskEnable();
void stencilMaskDisable( bool clearMasks = false );
protected:
std::list<Rectf> mScissorsClipped;
bool mPushScissorClip;
std::vector<const Drawable*> mDrawables;
Mode mMode;
void drawMask();
private:
friend class Renderer;
ClippingMask();
};
}}
#endif

View File

@@ -4,6 +4,7 @@
#include <eepp/graphics/renderer/base.hpp>
#include <eepp/graphics/shaderprogram.hpp>
#include <eepp/graphics/renderer/rendererhelper.hpp>
#include <eepp/graphics/renderer/clippingmask.hpp>
namespace EE { namespace Graphics {
@@ -210,6 +211,8 @@ class EE_API Renderer {
const bool& quadsSupported() const;
const int& quadVertexs() const;
ClippingMask * getClippingMask() const;
protected:
static Renderer * sSingleton;
@@ -228,6 +231,7 @@ class EE_API Renderer {
unsigned int mCurVAO;
std::list<Rectf> mPlanesClipped;
ClippingMask * mClippingMask;
private:
void writeExtension( Uint8 Pos, Uint32 BitWrite );
};

View File

@@ -301,7 +301,7 @@ class EE_API UIControl {
virtual Uint32 onValueChange();
virtual void onVisibleChange();
virtual void onVisibilityChange();
virtual void onEnabledChange();

View File

@@ -100,6 +100,8 @@ class EE_API UIWidget : public UIControlAnim {
virtual void onPositionChange();
virtual void onVisibilityChange();
virtual void onAutoSize();
void notifyLayoutAttrChange();

View File

@@ -318,18 +318,6 @@ class EE_API Window {
/** Get a frame per second limit. */
Uint32 getFrameRateLimit();
/** Set the current Clipping area ( default the entire window, SCISSOR TEST ). */
void clipEnable( const Int32& x, const Int32& y, const Uint32& Width, const Uint32& Height );
/** Disable the Clipping area */
void clipDisable();
/** Clip the area with a plane. */
void clipPlaneEnable( const Int32& x, const Int32& y, const Int32& Width, const Int32& Height );
/** Disable the clip plane area. */
void clipPlaneDisable();
/** @return The clipboard manager */
Clipboard * getClipboard() const;
@@ -492,8 +480,6 @@ class EE_API Window {
};
FrameData mFrameData;
std::list<Rectf> mScissorsClipped;
bool mPushScissorClip;
/** Set the flag state to be the current window */
virtual void setCurrent();

View File

@@ -10,6 +10,7 @@
../../include/eepp/graphics/primitivedrawable.hpp
../../include/eepp/graphics/rectangledrawable.hpp
../../include/eepp/graphics/renderer/base.hpp
../../include/eepp/graphics/renderer/clippingmask.hpp
../../include/eepp/graphics/renderer/opengl.hpp
../../include/eepp/graphics/renderer/renderer.hpp
../../include/eepp/graphics/renderer/renderer.hpp
@@ -48,6 +49,7 @@
../../src/eepp/graphics/pixelperfect.cpp
../../src/eepp/graphics/primitivedrawable.cpp
../../src/eepp/graphics/rectangledrawable.cpp
../../src/eepp/graphics/renderer/clippingmask.cpp
../../src/eepp/graphics/renderer/openglext.hpp
../../src/eepp/graphics/renderer/renderer.cpp
../../src/eepp/graphics/renderer/renderer.cpp

View File

@@ -1,13 +1,15 @@
#define EE_BACKEND_SDL_ACTIVE
#define EE_BACKEND_ALLEGRO_ACTIVE
#define EE_BACKEND_SFML_ACTIVE
#define EE_SDL_VERSION_2
#define EE_SDL_VERSION_1_2
#define EE_BACKEND_SDL2
#define EE_BACKEND_SDL_1_2
#define EE_X11_PLATFORM
#define EE_DEBUG
#define EE_LIBSNDFILE_ENABLED
#define EE_MEMORY_MANAGER
#define EE_GL3_ENABLED 1
#define EE_SHADERS_SUPPORTED
#define EE_GLEW_AVAILABLE
#define EE_SSL_SUPPORT
#define EE_OPENSSL
#define EE_BACKEND_SFML_ACTIVE
#define EE_BACKEND_SDL2
#define EE_GL3_ENABLED
#define EE_SHADERS_SUPPORTED
#define EE_BACKEND_SDL_ACTIVE

File diff suppressed because it is too large Load Diff

View File

@@ -1,2 +1,14 @@
../../src/
../../include/
../../src/examples/strobe
../../../eeiv/src
.
../../include/eepp/graphics
../../src/eepp/graphics
../../include/eepp/ui
../../src/eepp/ui
../../src/eepp/helper/freetype2/include/
../../include/eepp/system
../../src/eepp/system
../../src/eepp/graphics/renderer
../../include/eepp/graphics/renderer

View File

@@ -1,3 +1,5 @@
../../include/eepp/graphics/arcdrawable.hpp
../../include/eepp/graphics/circledrawable.hpp
../../include/eepp/graphics/drawable.hpp
../../include/eepp/graphics/drawablesearcher.hpp
../../include/eepp/graphics/font.hpp
@@ -5,7 +7,10 @@
../../include/eepp/graphics/fonttruetype.hpp
../../include/eepp/graphics/fonttruetypeloader.hpp
../../include/eepp/graphics/graphicshelper.hpp
../../include/eepp/graphics/primitivedrawable.hpp
../../include/eepp/graphics/rectangledrawable.hpp
../../include/eepp/graphics/renderer/base.hpp
../../include/eepp/graphics/renderer/clippingmask.hpp
../../include/eepp/graphics/renderer/opengl.hpp
../../include/eepp/graphics/renderer/renderer.hpp
../../include/eepp/graphics/renderer/renderer.hpp
@@ -33,6 +38,8 @@
../../include/eepp/ui/uithemedefault.hpp
../../include/eepp/ui/uiwidget.hpp
../../src/eepp/gaming/mapobjectlayer.cpp
../../src/eepp/graphics/arcdrawable.cpp
../../src/eepp/graphics/circledrawable.cpp
../../src/eepp/graphics/drawable.cpp
../../src/eepp/graphics/drawablesearcher.cpp
../../src/eepp/graphics/fonttruetype.cpp
@@ -40,6 +47,9 @@
../../src/eepp/graphics/globalbatchrenderer.cpp
../../src/eepp/graphics/pixeldensity.cpp
../../src/eepp/graphics/pixelperfect.cpp
../../src/eepp/graphics/primitivedrawable.cpp
../../src/eepp/graphics/rectangledrawable.cpp
../../src/eepp/graphics/renderer/clippingmask.cpp
../../src/eepp/graphics/renderer/openglext.hpp
../../src/eepp/graphics/renderer/renderer.cpp
../../src/eepp/graphics/renderer/renderer.cpp

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 );