OPENGL_GAL: optimized JP's bitmap drawing function to use textures
(cherry picked from commit 516cf47946
)
This commit is contained in:
parent
7b596f0365
commit
a43ec3e3f0
|
@ -64,6 +64,94 @@ GLuint OPENGL_GAL::fontTexture = 0;
|
|||
bool OPENGL_GAL::isBitmapFontLoaded = false;
|
||||
SHADER* OPENGL_GAL::shader = NULL;
|
||||
|
||||
namespace KIGFX {
|
||||
class GL_BITMAP_CACHE
|
||||
{
|
||||
public:
|
||||
GL_BITMAP_CACHE()
|
||||
{
|
||||
}
|
||||
|
||||
~GL_BITMAP_CACHE();
|
||||
|
||||
GLuint RequestBitmap( const BITMAP_BASE* aBitmap );
|
||||
|
||||
private:
|
||||
|
||||
struct CACHED_BITMAP
|
||||
{
|
||||
GLuint id;
|
||||
int w, h;
|
||||
};
|
||||
|
||||
GLuint cacheBitmap( const BITMAP_BASE* aBitmap );
|
||||
|
||||
std::map<const BITMAP_BASE*, CACHED_BITMAP> m_bitmaps;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
GL_BITMAP_CACHE::~GL_BITMAP_CACHE()
|
||||
{
|
||||
for ( auto b = m_bitmaps.begin(); b != m_bitmaps.end(); ++b )
|
||||
{
|
||||
glDeleteTextures( 1, &b->second.id );
|
||||
}
|
||||
}
|
||||
|
||||
GLuint GL_BITMAP_CACHE::RequestBitmap( const BITMAP_BASE* aBitmap )
|
||||
{
|
||||
auto it = m_bitmaps.find( aBitmap) ;
|
||||
|
||||
if ( it != m_bitmaps.end() )
|
||||
{
|
||||
return it->second.id;
|
||||
}
|
||||
else
|
||||
{
|
||||
return cacheBitmap( aBitmap );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GLuint GL_BITMAP_CACHE::cacheBitmap( const BITMAP_BASE* aBitmap )
|
||||
{
|
||||
CACHED_BITMAP bmp;
|
||||
|
||||
bmp.w = aBitmap->GetSizePixels().x;
|
||||
bmp.h = aBitmap->GetSizePixels().y;
|
||||
|
||||
GLuint textureID;
|
||||
glGenTextures(1, &textureID);
|
||||
|
||||
uint8_t *buf = new uint8_t [ bmp.w * bmp.h * 3];
|
||||
auto imgData = const_cast<BITMAP_BASE*>( aBitmap )->GetImageData();
|
||||
|
||||
for( int y=0; y < bmp.h; y++ )
|
||||
for( int x = 0; x < bmp.w;x++)
|
||||
{
|
||||
auto *p = buf + ( bmp.w * y + x ) * 3;
|
||||
|
||||
p[0] = imgData->GetRed( x, y );
|
||||
p[1] = imgData->GetGreen( x, y );
|
||||
p[2] = imgData->GetBlue( x, y );
|
||||
}
|
||||
|
||||
glBindTexture( GL_TEXTURE_2D, textureID );
|
||||
|
||||
glTexImage2D( GL_TEXTURE_2D, 0,GL_RGB, bmp.w, bmp.h, 0, GL_RGB, GL_UNSIGNED_BYTE, buf );
|
||||
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
|
||||
|
||||
delete [] buf;
|
||||
|
||||
bmp.id = textureID;
|
||||
|
||||
m_bitmaps[ aBitmap ] = bmp;
|
||||
|
||||
return textureID;
|
||||
}
|
||||
|
||||
OPENGL_GAL::OPENGL_GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions, wxWindow* aParent,
|
||||
wxEvtHandler* aMouseListener, wxEvtHandler* aPaintListener,
|
||||
|
@ -103,6 +191,8 @@ OPENGL_GAL::OPENGL_GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions, wxWindow* aParent,
|
|||
|
||||
++instanceCounter;
|
||||
|
||||
bitmapCache.reset( new GL_BITMAP_CACHE );
|
||||
|
||||
compositor = new OPENGL_COMPOSITOR;
|
||||
compositor->SetAntialiasingMode( options.gl_antialiasing_mode );
|
||||
|
||||
|
@ -903,40 +993,49 @@ void OPENGL_GAL::DrawCurve( const VECTOR2D& aStartPoint, const VECTOR2D& aContro
|
|||
void OPENGL_GAL::DrawBitmap( const BITMAP_BASE& aBitmap )
|
||||
{
|
||||
int ppi = aBitmap.GetPPI();
|
||||
double worldIU_per_mm = 1/(worldUnitLength/2.54)/1000;
|
||||
double pix_size_iu = worldIU_per_mm * ( 25.4 / ppi );
|
||||
double worldIU_per_mm = 1.0 / ( worldUnitLength / 2.54 )/ 1000;
|
||||
double pix_size_iu = worldIU_per_mm * ( 25.4 / ppi );
|
||||
|
||||
Save();
|
||||
double w = aBitmap.GetSizePixels().x * pix_size_iu;
|
||||
double h = aBitmap.GetSizePixels().y * pix_size_iu;
|
||||
|
||||
auto xform = currentManager->GetTransformation();
|
||||
|
||||
// Set the pixel scaling factor:
|
||||
currentManager->Scale( pix_size_iu, pix_size_iu, 0 );
|
||||
// The position of the bitmap is the bitmap center.
|
||||
// move the draw origin to the top left bitmap corner:
|
||||
currentManager->Translate( -aBitmap.GetSizePixels().x/2, -aBitmap.GetSizePixels().y/2, 0 );
|
||||
glm::vec4 v0 = xform * glm::vec4( -w/2, -h/2, 0.0, 0.0 );
|
||||
glm::vec4 v1 = xform * glm::vec4( w/2, h/2, 0.0, 0.0 );
|
||||
glm::vec4 trans = xform[3];
|
||||
|
||||
isFillEnabled = true;
|
||||
isStrokeEnabled = false;
|
||||
auto id = bitmapCache->RequestBitmap( &aBitmap );
|
||||
|
||||
// The pixel buffer of the initial bitmap:
|
||||
auto bm_pix_buffer = (( BITMAP_BASE&)aBitmap).GetImageData();
|
||||
auto oldTarget = GetTarget();
|
||||
|
||||
for( int row = 0; row < aBitmap.GetSizePixels().y; row++ )
|
||||
{
|
||||
VECTOR2D pos( 0, row );
|
||||
glPushMatrix();
|
||||
glTranslated( trans.x, trans.y, trans.z );
|
||||
|
||||
for( int col = 0; col < aBitmap.GetSizePixels().x; col++ )
|
||||
{
|
||||
pos.x = col;
|
||||
SetFillColor( COLOR4D( bm_pix_buffer->GetRed( col, row )/255.0,
|
||||
bm_pix_buffer->GetGreen( col, row )/255.0,
|
||||
bm_pix_buffer->GetBlue( col, row )/255.0,
|
||||
1.0 ) );
|
||||
VECTOR2D end = pos + 1.0; // Size of the rectangle = 1 pixel
|
||||
DrawRectangle( pos, end );
|
||||
}
|
||||
}
|
||||
SetTarget( TARGET_NONCACHED );
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glActiveTexture( GL_TEXTURE0 );
|
||||
glBindTexture( GL_TEXTURE_2D, id );
|
||||
|
||||
glBegin( GL_QUADS );
|
||||
glColor4f(1.0, 1.0, 1.0, 1.0);
|
||||
glTexCoord2f(0.0, 0.0);
|
||||
glVertex3f( v0.x, v0.y, layerDepth );
|
||||
glColor4f(1.0, 1.0, 1.0, 1.0);
|
||||
glTexCoord2f(1.0, 0.0);
|
||||
glVertex3f( v1.x, v0.y, layerDepth );
|
||||
glColor4f(1.0, 1.0, 1.0, 1.0);
|
||||
glTexCoord2f(1.0, 1.0);
|
||||
glVertex3f( v1.x, v1.y, layerDepth );
|
||||
glColor4f(1.0, 1.0, 1.0, 1.0);
|
||||
glTexCoord2f(0.0, 1.0);
|
||||
glVertex3f( v0.x, v1.y, layerDepth );
|
||||
glEnd();
|
||||
|
||||
Restore();
|
||||
SetTarget( oldTarget );
|
||||
glBindTexture( GL_TEXTURE_2D, 0 );
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1357,6 +1456,8 @@ void OPENGL_GAL::DeleteGroup( int aGroupNumber )
|
|||
|
||||
void OPENGL_GAL::ClearCache()
|
||||
{
|
||||
bitmapCache.reset( new GL_BITMAP_CACHE );
|
||||
|
||||
groups.clear();
|
||||
|
||||
if( isInitialized )
|
||||
|
|
|
@ -53,6 +53,7 @@ struct bitmap_glyph;
|
|||
namespace KIGFX
|
||||
{
|
||||
class SHADER;
|
||||
class GL_BITMAP_CACHE;
|
||||
|
||||
/**
|
||||
* @brief Class OpenGL_GAL is the OpenGL implementation of the Graphics Abstraction Layer.
|
||||
|
@ -326,6 +327,8 @@ private:
|
|||
///< when the window is visible
|
||||
bool isGrouping; ///< Was a group started?
|
||||
|
||||
std::unique_ptr<GL_BITMAP_CACHE> bitmapCache;
|
||||
|
||||
///< Update handler for OpenGL settings
|
||||
bool updatedGalDisplayOptions( const GAL_DISPLAY_OPTIONS& aOptions ) override;
|
||||
|
||||
|
|
|
@ -482,6 +482,7 @@ void PCB_DRAW_PANEL_GAL::setDefaultLayerDeps()
|
|||
m_view->SetLayerTarget( LAYER_RATSNEST, KIGFX::TARGET_OVERLAY );
|
||||
m_view->SetLayerDisplayOnly( LAYER_RATSNEST );
|
||||
|
||||
m_view->SetLayerTarget( LAYER_WORKSHEET, KIGFX::TARGET_NONCACHED );
|
||||
m_view->SetLayerDisplayOnly( LAYER_WORKSHEET ) ;
|
||||
m_view->SetLayerDisplayOnly( LAYER_GRID );
|
||||
m_view->SetLayerDisplayOnly( LAYER_DRC );
|
||||
|
|
Loading…
Reference in New Issue