TerminalDisplay: Rendering performance improvements.

VertexBuffer: Added some helper functions to add and set quads.
GlyphDrawable: Added a function to draw the glyph into a VertexBuffer.
This commit is contained in:
Martín Lucas Golini
2022-08-25 02:59:20 -03:00
parent 0924b715ee
commit eec04b3a0b
8 changed files with 442 additions and 96 deletions

View File

@@ -70,7 +70,7 @@ class ITerminalDisplay {
virtual const char* getClipboard() const;
virtual bool drawBegin( int columns, int rows ) = 0;
virtual bool drawBegin( Uint32 columns, Uint32 rows ) = 0;
virtual void drawLine( Line line, int x1, int y, int x2 ) = 0;

View File

@@ -4,6 +4,7 @@
#include <eepp/config.hpp>
#include <eepp/graphics/font.hpp>
#include <eepp/graphics/framebuffer.hpp>
#include <eepp/graphics/primitives.hpp>
#include <eepp/system/clock.hpp>
#include <eepp/window/inputevent.hpp>
#include <eepp/window/keycodes.hpp>
@@ -24,6 +25,10 @@ using namespace EE::System;
using namespace eterm::System;
using namespace eterm::Terminal;
namespace EE { namespace Graphics {
class VertexBuffer;
}} // namespace EE::Graphics
namespace eterm { namespace Terminal {
enum class TerminalShortcutAction {
@@ -163,7 +168,7 @@ class TerminalDisplay : public ITerminalDisplay {
virtual void setClipboard( const char* text );
virtual const char* getClipboard() const;
virtual bool drawBegin( int columns, int rows );
virtual bool drawBegin( Uint32 columns, Uint32 rows );
virtual void drawLine( Line line, int x1, int y, int x2 );
virtual void drawCursor( int cx, int cy, TerminalGlyph g, int ox, int oy, TerminalGlyph og );
virtual void drawEnd();
@@ -285,11 +290,17 @@ class TerminalDisplay : public ITerminalDisplay {
bool mKeepAlive{ true };
Clock mClock;
Clock mLastDoubleClick;
int mColumns{ 0 };
int mRows{ 0 };
Uint32 mColumns{ 0 };
Uint32 mRows{ 0 };
Uint32 mClickStep{ 5 };
FrameBuffer* mFrameBuffer{ nullptr };
VertexBuffer* mVBBackground{ nullptr };
VertexBuffer* mVBForeground{ nullptr };
std::vector<VertexBuffer*> mVBStyles;
TerminalColorScheme mColorScheme;
Uint32 mQuadVertexs{ 6 };
Primitives mPrimitives;
Vector2u mCurGridPos;
std::string mProgram;
std::vector<std::string> mArgs;
@@ -315,6 +326,22 @@ class TerminalDisplay : public ITerminalDisplay {
void createFrameBuffer();
void drawFrameBuffer();
void createVBO( VertexBuffer** vbo, bool usesTexCoords );
VertexBuffer* createRowVBO( bool usesTexCoords );
void initVBOs();
void drawbox( float x, float y, float w, float h, Color fg, Color bg, ushort bd );
void drawrect( const Color& col, const float& x, const float& y, const float& w,
const float& h );
void drawpoint( const Color& col, const float& x, const float& y, const float& w,
const float& h );
void drawboxlines( float x, float y, float w, float h, Color fg, ushort bd );
};
}} // namespace eterm::Terminal

View File

@@ -1,7 +1,8 @@
#include <eepp/graphics/fontmanager.hpp>
#include <eepp/graphics/fonttruetype.hpp>
#include <eepp/graphics/primitives.hpp>
#include <eepp/graphics/renderer/renderer.hpp>
#include <eepp/graphics/text.hpp>
#include <eepp/graphics/vertexbuffer.hpp>
#include <eepp/math/math.hpp>
#include <eepp/system/color.hpp>
#include <eepp/window.hpp>
@@ -446,6 +447,10 @@ TerminalDisplay::create( EE::Window::Window* window, Font* font, const Float& fo
}
TerminalDisplay::~TerminalDisplay() {
eeSAFE_DELETE( mVBBackground );
eeSAFE_DELETE( mVBForeground );
for ( VertexBuffer* vb : mVBStyles )
eeSAFE_DELETE( vb );
eeSAFE_DELETE( mFrameBuffer );
}
@@ -468,8 +473,12 @@ TerminalDisplay::TerminalDisplay( EE::Window::Window* window, Font* font, const
Sizei gridSize( gridSizeFromTermDimensions( mFont, mFontSize, mSize - mPadding * 2.f ) );
mDirtyLines.resize( gridSize.getHeight(), 1 );
mQuadVertexs = GLi->quadVertexs();
if ( mUseFrameBuffer )
createFrameBuffer();
else
initVBOs();
}
void TerminalDisplay::resetColors() {
@@ -702,12 +711,16 @@ const char* TerminalDisplay::getClipboard() const {
return mClipboardUtf8.c_str();
}
bool TerminalDisplay::drawBegin( int columns, int rows ) {
bool TerminalDisplay::drawBegin( Uint32 columns, Uint32 rows ) {
if ( columns != mColumns || rows != mRows ) {
TerminalGlyph defaultGlyph{};
mBuffer.resize( columns * rows, defaultGlyph );
mColumns = columns;
mRows = rows;
if ( !mUseFrameBuffer )
initVBOs();
invalidateLines();
invalidateCursor();
}
@@ -853,20 +866,31 @@ static inline Color termColor( unsigned int terminalColor, const std::vector<Col
terminalColor & 0xFF, ( ~( ( terminalColor >> 25 ) & 0xFF ) ) & 0xFF );
}
inline static void drawrect( const Color& col, const float& x, const float& y, const float& w,
const float& h, Primitives& p ) {
p.setColor( col );
p.drawRectangle( { { eefloor( x ), eefloor( y ) }, { eeceil( w ), eeceil( h ) } } );
void TerminalDisplay::drawrect( const Color& col, const float& x, const float& y, const float& w,
const float& h ) {
if ( mVBStyles.empty() ) {
mPrimitives.setColor( col );
mPrimitives.drawRectangle(
{ { eefloor( x ), eefloor( y ) }, { eeceil( w ), eeceil( h ) } } );
} else {
mVBStyles[mCurGridPos.y]->addQuad( { eefloor( x ), eefloor( y ) },
{ eeceil( w ), eeceil( h ) }, col );
}
}
inline static void drawpoint( const Color& col, const float& x, const float& y, const float& w,
const float& h, Primitives& p ) {
p.setColor( col );
p.drawPoint( { eefloor( x ), eefloor( y ) }, eemin( w / 2.f, h / 2.f ) );
void TerminalDisplay::drawpoint( const Color& col, const float& x, const float& y, const float& w,
const float& h ) {
if ( mVBStyles.empty() ) {
mPrimitives.setColor( col );
mPrimitives.drawPoint( { eefloor( x ), eefloor( y ) }, eemin( w / 2.f, h / 2.f ) );
} else {
Float s = eemin( w / 2.f, h / 2.f );
mVBStyles[mCurGridPos.y]->addQuad( { eefloor( x ), eefloor( y ) },
{ eefloor( s ), eefloor( s ) }, col );
}
}
inline static void drawboxlines( float x, float y, float w, float h, Color fg, ushort bd,
Primitives& pr ) {
void TerminalDisplay::drawboxlines( float x, float y, float w, float h, Color fg, ushort bd ) {
/* s: stem thickness. width/8 roughly matches underscore thickness. */
/* We draw bold as 1.5 * normal-stem and at least 1px thicker. */
/* doubles draw at least 3px, even when w or h < 3. bold needs 6px. */
@@ -891,13 +915,13 @@ inline static void drawboxlines( float x, float y, float w, float h, Color fg, u
float d = arc || ( multi_double && !multi_light ) ? -s : 0.0f;
if ( bd & LL )
drawrect( fg, x, y + h2, w2 + s + d, s, pr );
drawrect( fg, x, y + h2, w2 + s + d, s );
if ( bd & LU )
drawrect( fg, x + w2, y, s, h2 + s + d, pr );
drawrect( fg, x + w2, y, s, h2 + s + d );
if ( bd & LR )
drawrect( fg, x + w2 - d, y + h2, w - w2 + d, s, pr );
drawrect( fg, x + w2 - d, y + h2, w - w2 + d, s );
if ( bd & LD )
drawrect( fg, x + w2, y + h2 - d, s, h - h2 + d, pr );
drawrect( fg, x + w2, y + h2 - d, s, h - h2 + d );
}
/* double lines - also align with light to form heavy when combined */
@@ -912,58 +936,57 @@ inline static void drawboxlines( float x, float y, float w, float h, Color fg, u
int dl = bd & DL, du = bd & DU, dr = bd & DR, dd = bd & DD;
if ( dl ) {
float p = dd ? -s : 0.0f, n = du ? -s : dd ? s : 0.0f;
drawrect( fg, x, y + h2 + s, w2 + s + p, s, pr );
drawrect( fg, x, y + h2 - s, w2 + s + n, s, pr );
drawrect( fg, x, y + h2 + s, w2 + s + p, s );
drawrect( fg, x, y + h2 - s, w2 + s + n, s );
}
if ( du ) {
float p = dl ? -s : 0.0f, n = dr ? -s : dl ? s : 0.0f;
drawrect( fg, x + w2 - s, y, s, h2 + s + p, pr );
drawrect( fg, x + w2 + s, y, s, h2 + s + n, pr );
drawrect( fg, x + w2 - s, y, s, h2 + s + p );
drawrect( fg, x + w2 + s, y, s, h2 + s + n );
}
if ( dr ) {
float p = du ? -s : 0.0f, n = dd ? -s : du ? s : 0.0f;
drawrect( fg, x + w2 - p, y + h2 - s, w - w2 + p, s, pr );
drawrect( fg, x + w2 - n, y + h2 + s, w - w2 + n, s, pr );
drawrect( fg, x + w2 - p, y + h2 - s, w - w2 + p, s );
drawrect( fg, x + w2 - n, y + h2 + s, w - w2 + n, s );
}
if ( dd ) {
float p = dr ? -s : 0.0f, n = dl ? -s : dr ? s : 0.0f;
drawrect( fg, x + w2 + s, y + h2 - p, s, h - h2 + p, pr );
drawrect( fg, x + w2 - s, y + h2 - n, s, h - h2 + n, pr );
drawrect( fg, x + w2 + s, y + h2 - p, s, h - h2 + p );
drawrect( fg, x + w2 - s, y + h2 - n, s, h - h2 + n );
}
}
}
inline static void drawbox( float x, float y, float w, float h, Color fg, Color bg, ushort bd,
Primitives& p ) {
void TerminalDisplay::drawbox( float x, float y, float w, float h, Color fg, Color bg, ushort bd ) {
ushort cat = bd & ~( BDB | 0xff ); /* mask out bold and data */
if ( bd & ( BDL | BDA ) ) {
/* lines (light/double/heavy/arcs) */
drawboxlines( x, y, w, h, fg, bd, p );
drawboxlines( x, y, w, h, fg, bd );
} else if ( cat == BBD ) {
/* lower (8-X)/8 block */
float d = DIV( ( bd & 0xFF ) * h, 8.0f );
drawrect( fg, x, y + d, w, h - d, p );
drawrect( fg, x, y + d, w, h - d );
} else if ( cat == BBU ) {
/* upper X/8 block */
drawrect( fg, x, y, w, DIV( ( bd & 0xFF ) * h, 8 ), p );
drawrect( fg, x, y, w, DIV( ( bd & 0xFF ) * h, 8 ) );
} else if ( cat == BBL ) {
/* left X/8 block */
drawrect( fg, x, y, DIV( ( bd & 0xFF ) * w, 8 ), h, p );
drawrect( fg, x, y, DIV( ( bd & 0xFF ) * w, 8 ), h );
} else if ( cat == BBR ) {
/* right (8-X)/8 block */
float d = DIV( ( bd & 0xFF ) * w, 8.0f );
drawrect( fg, x + d, y, w - d, h, p );
drawrect( fg, x + d, y, w - d, h );
} else if ( cat == BBQ ) {
/* Quadrants */
float w2 = DIV( w, 2.0f ), h2 = DIV( h, 2.0f );
if ( bd & TL )
drawrect( fg, x, y, w2, h2, p );
drawrect( fg, x, y, w2, h2 );
if ( bd & TR )
drawrect( fg, x + w2, y, w - w2, h2, p );
drawrect( fg, x + w2, y, w - w2, h2 );
if ( bd & BL )
drawrect( fg, x, y + h2, w2, h - h2, p );
drawrect( fg, x, y + h2, w2, h - h2 );
if ( bd & BR )
drawrect( fg, x + w2, y + h2, w - w2, h - h2, p );
drawrect( fg, x + w2, y + h2, w - w2, h - h2 );
} else if ( bd & BBS ) {
/* Shades - data is 1/2/3 for 25%/50%/75% alpha, respectively */
int d = ( bd & 0xFF );
@@ -979,28 +1002,28 @@ inline static void drawbox( float x, float y, float w, float h, Color fg, Color
4 );
Color drawcol = Color( red, green, blue, 0xFF );
drawrect( drawcol, x, y, w, h, p );
drawrect( drawcol, x, y, w, h );
} else if ( cat == BRL ) {
/* braille, each data bit corresponds to one dot at 2x4 grid */
float w1 = DIV( w, 2.0f );
float h1 = DIV( h, 4.0f ), h2 = DIV( h, 2.0f ), h3 = DIV( 3.0f * h, 4.0f );
if ( bd & 1 )
drawpoint( fg, x, y, w1, h1, p );
drawpoint( fg, x, y, w1, h1 );
if ( bd & 2 )
drawpoint( fg, x, y + h1, w1, h2 - h1, p );
drawpoint( fg, x, y + h1, w1, h2 - h1 );
if ( bd & 4 )
drawpoint( fg, x, y + h2, w1, h3 - h2, p );
drawpoint( fg, x, y + h2, w1, h3 - h2 );
if ( bd & 8 )
drawpoint( fg, x + w1, y, w - w1, h1, p );
drawpoint( fg, x + w1, y, w - w1, h1 );
if ( bd & 16 )
drawpoint( fg, x + w1, y + h1, w - w1, h2 - h1, p );
drawpoint( fg, x + w1, y + h1, w - w1, h2 - h1 );
if ( bd & 32 )
drawpoint( fg, x + w1, y + h2, w - w1, h3 - h2, p );
drawpoint( fg, x + w1, y + h2, w - w1, h3 - h2 );
if ( bd & 64 )
drawpoint( fg, x, y + h3, w1, h - h3, p );
drawpoint( fg, x, y + h3, w1, h - h3 );
if ( bd & 128 )
drawpoint( fg, x + w1, y + h3, w - w1, h - h3, p );
drawpoint( fg, x + w1, y + h3, w - w1, h - h3 );
}
}
@@ -1020,21 +1043,25 @@ void TerminalDisplay::drawGrid( const Vector2f& pos ) {
Rectf xBounds = mFont->getGlyph( L'x', mFontSize, false ).bounds;
Float strikeThroughOffset = lineHeight + xBounds.Top + cursorThickness;
Primitives p;
p.setForceDraw( false );
mPrimitives.setForceDraw( false );
for ( int j = 0; j < mRows; j++ ) {
bool dirtyBG = false;
if ( mVBBackground )
mVBBackground->bind();
for ( Uint32 j = 0; j < mRows; j++ ) {
x = std::floor( pos.x );
if ( pos.y + lineHeight * j > pos.y + mSize.getHeight() )
break;
if ( mFrameBuffer && !mDirtyLines[j] ) {
if ( !mDirtyLines[j] ) {
y += lineHeight;
continue;
}
for ( int i = 0; i < mColumns; i++ ) {
for ( Uint32 i = 0; i < mColumns; i++ ) {
mCurGridPos = { i, j };
auto& glyph = mBuffer[j * mColumns + i];
auto fg = termColor( glyph.fg, mColors );
auto bg = termColor( glyph.bg, mColors );
@@ -1054,12 +1081,16 @@ void TerminalDisplay::drawGrid( const Vector2f& pos ) {
auto advanceX = spaceCharAdvanceX * ( isWide ? 2.0f : 1.0f );
if ( glyph.mode & ATTR_WDUMMY ) {
if ( glyph.mode & ATTR_WDUMMY )
continue;
}
p.setColor( bg );
p.drawRectangle( Rectf( { x, y }, { advanceX, lineHeight } ) );
if ( mVBBackground ) {
mVBBackground->setQuad( mCurGridPos, { x, y }, { advanceX, lineHeight }, bg );
dirtyBG = true;
} else {
mPrimitives.setColor( bg );
mPrimitives.drawRectangle( Rectf( { x, y }, { advanceX, lineHeight } ) );
}
x += advanceX;
}
@@ -1067,22 +1098,37 @@ void TerminalDisplay::drawGrid( const Vector2f& pos ) {
y += lineHeight;
}
if ( mVBBackground ) {
if ( dirtyBG )
mVBBackground->update( VERTEX_FLAGS_PRIMITIVE, false );
mVBBackground->draw();
mVBBackground->unbind();
}
y = std::floor( pos.y );
for ( int j = 0; j < mRows; j++ ) {
bool dirtyFG = false;
for ( Uint32 j = 0; j < mRows; j++ ) {
x = std::floor( pos.x );
if ( pos.y + lineHeight * j > pos.y + mSize.getHeight() )
break;
if ( mFrameBuffer && !mDirtyLines[j] ) {
if ( ( mFrameBuffer || mVBForeground ) && !mDirtyLines[j] ) {
y += lineHeight;
continue;
}
mDirtyLines[j] = false;
for ( int i = 0; i < mColumns; i++ ) {
if ( !mVBStyles.empty() ) {
eeSAFE_DELETE( mVBStyles[j] );
mVBStyles[j] = createRowVBO( false );
}
for ( Uint32 i = 0; i < mColumns; i++ ) {
mCurGridPos = { i, j };
auto& glyph = mBuffer[j * mColumns + i];
auto fg = termColor( glyph.fg, mColors );
auto bg = termColor( glyph.bg, mColors );
@@ -1118,9 +1164,18 @@ void TerminalDisplay::drawGrid( const Vector2f& pos ) {
if ( glyph.mode & ATTR_WDUMMY )
continue;
if ( glyph.u == 32 ) {
x += advanceX;
if ( mVBForeground )
mVBForeground->setQuadColor( mCurGridPos, Color::Transparent );
continue;
}
if ( glyph.mode & ATTR_BOXDRAW ) {
auto bd = TerminalEmulator::boxdrawindex( &glyph );
drawbox( x, y, advanceX, lineHeight, fg, bg, bd, p );
drawbox( x, y, advanceX, lineHeight, fg, bg, bd );
if ( mVBForeground )
mVBForeground->setQuadColor( mCurGridPos, Color::Transparent );
} else {
auto* gd = mFont->getGlyphDrawable( glyph.u, mFontSize, glyph.mode & ATTR_BOLD );
@@ -1141,18 +1196,31 @@ void TerminalDisplay::drawGrid( const Vector2f& pos ) {
gd->setColor( fg );
}
gd->draw( { x, y } );
if ( glyph.mode & ATTR_UNDERLINE ) {
p.setColor( fg );
p.drawRectangle( Rectf( { x, y + lineHeight - cursorThickness },
{ advanceX, cursorThickness } ) );
if ( mVBForeground ) {
gd->drawIntoVertexBuffer( mVBForeground, mCurGridPos, { x, y } );
} else {
gd->draw( { x, y } );
}
dirtyFG = true;
if ( glyph.mode & ATTR_STRUCK ) {
p.setColor( fg );
p.drawRectangle(
Rectf( { x, y + strikeThroughOffset }, { advanceX, cursorThickness } ) );
if ( mVBStyles.empty() ) {
if ( glyph.mode & ATTR_UNDERLINE ) {
mPrimitives.setColor( fg );
mPrimitives.drawRectangle( Rectf( { x, y + lineHeight - cursorThickness },
{ advanceX, cursorThickness } ) );
} else if ( glyph.mode & ATTR_STRUCK ) {
mPrimitives.setColor( fg );
mPrimitives.drawRectangle( Rectf( { x, y + strikeThroughOffset },
{ advanceX, cursorThickness } ) );
}
} else {
if ( glyph.mode & ATTR_UNDERLINE ) {
mVBStyles[j]->addQuad( { x, y + lineHeight - cursorThickness },
{ advanceX, cursorThickness }, fg );
} else if ( glyph.mode & ATTR_STRUCK ) {
mVBStyles[j]->addQuad( { x, y + strikeThroughOffset },
{ advanceX, cursorThickness }, fg );
}
}
}
@@ -1162,6 +1230,27 @@ void TerminalDisplay::drawGrid( const Vector2f& pos ) {
y += lineHeight;
}
if ( mVBForeground ) {
mFont->getTexture( mFontSize )->bind();
if ( dirtyFG )
mVBForeground->update( VERTEX_FLAGS_DEFAULT, false );
mVBForeground->bind();
mVBForeground->draw();
mVBForeground->unbind();
}
if ( !mVBStyles.empty() ) {
if ( dirtyFG ) {
for ( auto& vbo : mVBStyles )
vbo->update( VERTEX_FLAGS_PRIMITIVE, false );
}
for ( auto& vbo : mVBStyles ) {
vbo->bind();
vbo->draw();
vbo->unbind();
}
}
if ( !mEmulator->isScrolling() && !IS_SET( MODE_HIDE ) &&
( !mUseFrameBuffer || mDirtyCursor ) ) {
mDirtyCursor = false;
@@ -1177,56 +1266,55 @@ void TerminalDisplay::drawGrid( const Vector2f& pos ) {
: mColorScheme.getCursor();
}
Vector2f a{}, b{}, c{}, d{};
p.setColor( drawcol );
mPrimitives.setColor( drawcol );
/* draw the new one */
if ( IS_SET( MODE_FOCUSED ) ) {
switch ( mCursorMode ) {
case 7: /* st extension */
mCursorGlyph.u = 0x2603; /* snowman (U+2603) */
/* FALLTHROUGH */
case 0: /* Blinking Block */
case 1: { /* Blinking Block (Default) */
if ( !( mMode & MODE_BLINK ) )
break;
}
case 2: { /* Steady Block */
auto* gd = mFont->getGlyphDrawable( mCursorGlyph.u, mFontSize );
case StExtension:
case SteadyBlock: {
auto* gd = mFont->getGlyphDrawable(
mCursorMode == StExtension ? 0xFB04 /* TUX */ : mCursorGlyph.u, mFontSize );
gd->setColor( termColor( mCursorGlyph.fg, mColors ) );
gd->setDrawMode( GlyphDrawable::DrawMode::Text );
gd->draw(
{ pos.x + mCursor.x * spaceCharAdvanceX, pos.y + mCursor.y * lineHeight } );
break;
}
case 3: { /* Blinking Underline */
case BlinkUnderline: {
if ( !( mMode & MODE_BLINK ) )
break;
}
case 4: /* Steady Underline */
p.drawRectangle(
case SteadyUnderline:
mPrimitives.drawRectangle(
Rectf( { pos.x + mCursor.x * spaceCharAdvanceX,
pos.y + ( mCursor.y + 1 ) * lineHeight - cursorThickness },
{ spaceCharAdvanceX, cursorThickness } ) );
break;
case 5: { /* Blinking bar */
case BlinkingBlock:
case BlinkingBlockDefault:
case BlinkBar: {
if ( !( mMode & MODE_BLINK ) )
break;
}
case 6: /* Steady bar */
case SteadyBar:
case TerminalCursorMode::MAX_CURSOR:
p.drawRectangle( Rectf(
mPrimitives.drawRectangle( Rectf(
{ pos.x + mCursor.x * spaceCharAdvanceX, pos.y + mCursor.y * lineHeight },
{ spaceCharAdvanceX, lineHeight } ) );
break;
}
} else {
Vector2f cpos{ pos.x + mCursor.x * spaceCharAdvanceX, pos.y + mCursor.y * lineHeight };
drawrect( drawcol, cpos.x, cpos.y, spaceCharAdvanceX, cursorThickness, p );
drawrect( drawcol, cpos.x, cpos.y, cursorThickness, lineHeight, p );
drawrect( drawcol, cpos.x + spaceCharAdvanceX, cpos.y, cursorThickness, lineHeight, p );
drawrect( drawcol, cpos.x, cpos.y + lineHeight - cursorThickness, spaceCharAdvanceX,
cursorThickness, p );
mPrimitives.setColor( drawcol );
mPrimitives.drawRectangle(
Rectf( Vector2f( cpos.x, cpos.y ), { spaceCharAdvanceX, cursorThickness } ) );
mPrimitives.drawRectangle(
Rectf( Vector2f( cpos.x, cpos.y ), { cursorThickness, lineHeight } ) );
mPrimitives.drawRectangle( Rectf( Vector2f( cpos.x + spaceCharAdvanceX, cpos.y ),
{ cursorThickness, lineHeight } ) );
mPrimitives.drawRectangle(
Rectf( Vector2f( cpos.x, cpos.y + lineHeight - cursorThickness ),
{ spaceCharAdvanceX, cursorThickness } ) );
}
}
@@ -1545,4 +1633,36 @@ void TerminalDisplay::drawFrameBuffer() {
}
}
VertexBuffer* TerminalDisplay::createRowVBO( bool usesTexCoords ) {
auto* VBO = VertexBuffer::New(
usesTexCoords ? VERTEX_FLAGS_DEFAULT : VERTEX_FLAGS_PRIMITIVE,
mQuadVertexs == 6 ? EE::Graphics::PRIMITIVE_TRIANGLES : EE::Graphics::PRIMITIVE_QUADS,
mRows * mColumns * mQuadVertexs, 0, VertexBufferUsageType::Stream );
VBO->setGridSize( Sizei( mColumns, 1 ) );
return VBO;
}
void TerminalDisplay::createVBO( VertexBuffer** vbo, bool usesTexCoords ) {
eeSAFE_DELETE( ( *vbo ) );
( *vbo ) = VertexBuffer::New(
usesTexCoords ? VERTEX_FLAGS_DEFAULT : VERTEX_FLAGS_PRIMITIVE,
mQuadVertexs == 6 ? EE::Graphics::PRIMITIVE_TRIANGLES : EE::Graphics::PRIMITIVE_QUADS,
mRows * mColumns * mQuadVertexs, 0, VertexBufferUsageType::Stream );
( *vbo )->resizeArray( VERTEX_FLAG_POSITION, mRows * mColumns * mQuadVertexs );
( *vbo )->resizeArray( VERTEX_FLAG_COLOR, mRows * mColumns * mQuadVertexs );
( *vbo )->setGridSize( Sizei( mColumns, mRows ) );
if ( usesTexCoords )
( *vbo )->resizeArray( VERTEX_FLAG_TEXTURE0, mRows * mColumns * mQuadVertexs );
}
void TerminalDisplay::initVBOs() {
createVBO( &mVBBackground, false );
createVBO( &mVBForeground, true );
for ( VertexBuffer* vb : mVBStyles )
eeSAFE_DELETE( vb );
mVBStyles.clear();
for ( Uint32 i = 0; i < mRows; ++i )
mVBStyles.emplace_back( createRowVBO( false ) );
}
}} // namespace eterm::Terminal