Adjust scissor test to current FBO coordinates. Fixes some clipping bugs when using FBOs withing UI components.

This commit is contained in:
Martín Lucas Golini
2025-06-01 01:35:05 -03:00
parent f580998b55
commit 9a8ece04d6
6 changed files with 67 additions and 13 deletions

View File

@@ -107,20 +107,32 @@ class EE_API FrameBuffer {
/** @return If the frame buffer was created */
virtual bool created() const = 0;
void setPosition( Vector2f position ) { mPosition = position; }
const Vector2f& getPosition() const { return mPosition; }
void setAdjustCurrentClipping( bool enabled ) { mAdjustCurrentClipping = enabled; }
bool adjustCurrentClipping() const { return mAdjustCurrentClipping; }
protected:
EE::Window::Window* mWindow;
Vector2f mPosition;
Sizei mSize;
Uint32 mChannels;
Uint32 mChannels{ 4 };
std::string mName;
String::HashType mId;
bool mHasColorBuffer;
bool mHasDepthBuffer;
bool mHasStencilBuffer;
Texture* mTexture;
String::HashType mId{ 0 };
bool mHasColorBuffer{ false };
bool mHasDepthBuffer{ false };
bool mHasStencilBuffer{ false };
bool mAdjustCurrentClipping{ true };
bool mNeedsToRestoreScissorsClipping{ false };
Texture* mTexture{ nullptr };
ColorAf mClearColor;
View mView;
float mProjMat[16];
float mModelViewMat[16];
std::vector<Rectf> mOldScissorsRect;
FrameBuffer( EE::Window::Window* window );

View File

@@ -17,6 +17,8 @@ class EE_API ClippingMask {
/** Disable the Clipping area */
void clipDisable();
bool isScissorsClipEnabled() const;
/** Clip the area with a plane. */
void clipPlaneEnable( const Int32& x, const Int32& y, const Int32& Width, const Int32& Height );

View File

@@ -51,7 +51,7 @@ Texture* FrameBuffer::getTexture() const {
}
void FrameBuffer::setClearColor( const ColorAf& color ) {
mClearColor = color;
mClearColor.assign( color );
}
ColorAf FrameBuffer::getClearColor() const {
@@ -78,6 +78,17 @@ void FrameBuffer::setBufferView() {
GLi->ortho( 0.0f, mSize.getWidth(), 0.f, mSize.getHeight(), -1000.0f, 1000.0f );
GLi->matrixMode( GL_MODELVIEW );
GLi->loadIdentity();
auto cm = GLi->getClippingMask();
if ( mAdjustCurrentClipping && cm->isScissorsClipEnabled() ) {
mNeedsToRestoreScissorsClipping = true;
mOldScissorsRect = cm->getScissorsClipped();
Rectf currentClip = mOldScissorsRect.back();
Rectf fboScreenRect( mPosition.floor(), mSize.asFloat() );
Rectf newClipRect( fboScreenRect.getPosition() - currentClip.getPosition(),
currentClip.getSize() );
cm->setScissorsClipped( { newClipRect } );
}
}
void FrameBuffer::recoverView() {
@@ -101,6 +112,11 @@ void FrameBuffer::recoverView() {
GLi->matrixMode( GL_MODELVIEW );
GLi->loadIdentity();
GLi->loadMatrixf( mModelViewMat );
if ( mNeedsToRestoreScissorsClipping ) {
GLi->getClippingMask()->setScissorsClipped( mOldScissorsRect );
mNeedsToRestoreScissorsClipping = false;
}
}
const Int32& FrameBuffer::getWidth() const {

View File

@@ -47,6 +47,10 @@ void ClippingMask::clipDisable() {
}
}
bool ClippingMask::isScissorsClipEnabled() const {
return !mScissorsClipped.empty();
}
void ClippingMask::clipPlaneEnable( const Int32& x, const Int32& y, const Int32& Width,
const Int32& Height ) {
GlobalBatchRenderer::instance()->draw();

View File

@@ -283,6 +283,7 @@ class TerminalDisplay : public ITerminalDisplay {
bool mDirty{ true };
bool mDirtyCursor{ true };
bool mDrawing{ false };
bool mFullDirty{ false };
Vector2i mCursor;
TerminalGlyph mCursorGlyph;
bool mUseColorEmoji{ true };
@@ -349,6 +350,8 @@ class TerminalDisplay : public ITerminalDisplay {
void drawboxlines( float x, float y, float w, float h, Color fg, ushort bd );
Rectf updateIMELocation();
void drawBg( bool toFBO = false );
};
}} // namespace eterm::Terminal

View File

@@ -1081,9 +1081,14 @@ void TerminalDisplay::drawbox( float x, float y, float w, float h, Color fg, Col
}
void TerminalDisplay::drawGrid( const Vector2f& pos ) {
if ( mFrameBuffer )
if ( mFrameBuffer ) {
mFrameBuffer->setPosition( mPosition.floor() + Vector2f( mPadding.Left, mPadding.Top ) );
mFrameBuffer->bind();
if ( mFullDirty )
drawBg( true );
}
auto fontSize = mFont->getFontHeight( mFontSize );
auto spaceCharAdvanceX = mFont->getGlyph( 'A', mFontSize, false, false ).advance;
@@ -1388,17 +1393,26 @@ void TerminalDisplay::drawGrid( const Vector2f& pos ) {
mFrameBuffer->unbind();
}
void TerminalDisplay::drawBg( bool toFBO ) {
auto defaultBg = termColor( mEmulator->getDefaultBackground(), mColors );
Primitives p;
p.setForceDraw( toFBO );
p.setColor( defaultBg );
if ( toFBO ) {
p.drawRectangle( Rectf( Vector2f::Zero, mFrameBuffer->getSize().asFloat() ) );
} else {
p.drawRectangle( Rectf( mPosition.floor().asFloat(), mSize.asFloat() ) );
}
}
void TerminalDisplay::draw( const Vector2f& pos ) {
if ( !mEmulator || !mTerminal )
return;
mDrawing = true;
auto defaultBg = termColor( mEmulator->getDefaultBackground(), mColors );
Primitives p;
p.setForceDraw( false );
p.setColor( defaultBg );
p.drawRectangle( Rectf( mPosition.floor().asFloat(), mSize.asFloat() ) );
drawBg();
if ( !mFrameBuffer || mDirty )
drawGrid( pos );
@@ -1418,6 +1432,7 @@ void TerminalDisplay::draw( const Vector2f& pos ) {
mDrawing = false;
mDirty = false;
mFullDirty = false;
}
Vector2i TerminalDisplay::positionToGrid( const Vector2i& pos ) {
@@ -1455,6 +1470,7 @@ void TerminalDisplay::onSizeChange() {
Sizei gridSize( gridSizeFromTermDimensions(
mFont, mFontSize,
mSize - Vector2f( mPadding.Left + mPadding.Right, mPadding.Top + mPadding.Bottom ) ) );
if ( mTerminal ) {
if ( gridSize.getWidth() != mTerminal->getNumColumns() ||
gridSize.getHeight() != mTerminal->getNumRows() ) {
@@ -1682,6 +1698,7 @@ void TerminalDisplay::invalidateLine( const int& line ) {
void TerminalDisplay::invalidateLines() {
mDirtyLines.assign( mDirtyLines.size(), 1 );
mDirty = true;
mFullDirty = true;
}
void TerminalDisplay::setFocus( bool focus ) {
if ( focus )