mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-06-04 20:46:29 +03:00
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:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
120
src/eepp/graphics/renderer/clippingmask.cpp
Normal file
120
src/eepp/graphics/renderer/clippingmask.cpp
Normal 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();
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -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 ) {
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -264,6 +264,11 @@ void UIWidget::onPositionChange() {
|
||||
UIControlAnim::onPositionChange();
|
||||
}
|
||||
|
||||
void UIWidget::onVisibilityChange() {
|
||||
updateAnchorsDistances();
|
||||
UIControlAnim::onVisibilityChange();
|
||||
}
|
||||
|
||||
void UIWidget::onAutoSize() {
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 );
|
||||
|
||||
Reference in New Issue
Block a user