OPENGL_GAL: optimized JP's bitmap drawing function to use textures
This commit is contained in:
parent
fefc7b8172
commit
516cf47946
|
@ -64,6 +64,94 @@ GLuint OPENGL_GAL::fontTexture = 0;
|
||||||
bool OPENGL_GAL::isBitmapFontLoaded = false;
|
bool OPENGL_GAL::isBitmapFontLoaded = false;
|
||||||
SHADER* OPENGL_GAL::shader = NULL;
|
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,
|
OPENGL_GAL::OPENGL_GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions, wxWindow* aParent,
|
||||||
wxEvtHandler* aMouseListener, wxEvtHandler* aPaintListener,
|
wxEvtHandler* aMouseListener, wxEvtHandler* aPaintListener,
|
||||||
|
@ -103,6 +191,8 @@ OPENGL_GAL::OPENGL_GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions, wxWindow* aParent,
|
||||||
|
|
||||||
++instanceCounter;
|
++instanceCounter;
|
||||||
|
|
||||||
|
bitmapCache.reset( new GL_BITMAP_CACHE );
|
||||||
|
|
||||||
compositor = new OPENGL_COMPOSITOR;
|
compositor = new OPENGL_COMPOSITOR;
|
||||||
compositor->SetAntialiasingMode( options.gl_antialiasing_mode );
|
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 )
|
void OPENGL_GAL::DrawBitmap( const BITMAP_BASE& aBitmap )
|
||||||
{
|
{
|
||||||
int ppi = aBitmap.GetPPI();
|
int ppi = aBitmap.GetPPI();
|
||||||
double worldIU_per_mm = 1/(worldUnitLength/2.54)/1000;
|
double worldIU_per_mm = 1.0 / ( worldUnitLength / 2.54 )/ 1000;
|
||||||
double pix_size_iu = worldIU_per_mm * ( 25.4 / ppi );
|
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:
|
glm::vec4 v0 = xform * glm::vec4( -w/2, -h/2, 0.0, 0.0 );
|
||||||
currentManager->Scale( pix_size_iu, pix_size_iu, 0 );
|
glm::vec4 v1 = xform * glm::vec4( w/2, h/2, 0.0, 0.0 );
|
||||||
// The position of the bitmap is the bitmap center.
|
glm::vec4 trans = xform[3];
|
||||||
// move the draw origin to the top left bitmap corner:
|
|
||||||
currentManager->Translate( -aBitmap.GetSizePixels().x/2, -aBitmap.GetSizePixels().y/2, 0 );
|
|
||||||
|
|
||||||
isFillEnabled = true;
|
auto id = bitmapCache->RequestBitmap( &aBitmap );
|
||||||
isStrokeEnabled = false;
|
|
||||||
|
|
||||||
// The pixel buffer of the initial bitmap:
|
auto oldTarget = GetTarget();
|
||||||
auto bm_pix_buffer = (( BITMAP_BASE&)aBitmap).GetImageData();
|
|
||||||
|
|
||||||
for( int row = 0; row < aBitmap.GetSizePixels().y; row++ )
|
glPushMatrix();
|
||||||
{
|
glTranslated( trans.x, trans.y, trans.z );
|
||||||
VECTOR2D pos( 0, row );
|
|
||||||
|
|
||||||
for( int col = 0; col < aBitmap.GetSizePixels().x; col++ )
|
SetTarget( TARGET_NONCACHED );
|
||||||
{
|
glEnable(GL_TEXTURE_2D);
|
||||||
pos.x = col;
|
glActiveTexture( GL_TEXTURE0 );
|
||||||
SetFillColor( COLOR4D( bm_pix_buffer->GetRed( col, row )/255.0,
|
glBindTexture( GL_TEXTURE_2D, id );
|
||||||
bm_pix_buffer->GetGreen( col, row )/255.0,
|
|
||||||
bm_pix_buffer->GetBlue( col, row )/255.0,
|
glBegin( GL_QUADS );
|
||||||
1.0 ) );
|
glColor4f(1.0, 1.0, 1.0, 1.0);
|
||||||
VECTOR2D end = pos + 1.0; // Size of the rectangle = 1 pixel
|
glTexCoord2f(0.0, 0.0);
|
||||||
DrawRectangle( pos, end );
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1354,6 +1453,8 @@ void OPENGL_GAL::DeleteGroup( int aGroupNumber )
|
||||||
|
|
||||||
void OPENGL_GAL::ClearCache()
|
void OPENGL_GAL::ClearCache()
|
||||||
{
|
{
|
||||||
|
bitmapCache.reset( new GL_BITMAP_CACHE );
|
||||||
|
|
||||||
groups.clear();
|
groups.clear();
|
||||||
|
|
||||||
if( isInitialized )
|
if( isInitialized )
|
||||||
|
|
|
@ -53,6 +53,7 @@ struct bitmap_glyph;
|
||||||
namespace KIGFX
|
namespace KIGFX
|
||||||
{
|
{
|
||||||
class SHADER;
|
class SHADER;
|
||||||
|
class GL_BITMAP_CACHE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Class OpenGL_GAL is the OpenGL implementation of the Graphics Abstraction Layer.
|
* @brief Class OpenGL_GAL is the OpenGL implementation of the Graphics Abstraction Layer.
|
||||||
|
@ -326,6 +327,8 @@ private:
|
||||||
///< when the window is visible
|
///< when the window is visible
|
||||||
bool isGrouping; ///< Was a group started?
|
bool isGrouping; ///< Was a group started?
|
||||||
|
|
||||||
|
std::unique_ptr<GL_BITMAP_CACHE> bitmapCache;
|
||||||
|
|
||||||
///< Update handler for OpenGL settings
|
///< Update handler for OpenGL settings
|
||||||
bool updatedGalDisplayOptions( const GAL_DISPLAY_OPTIONS& aOptions ) override;
|
bool updatedGalDisplayOptions( const GAL_DISPLAY_OPTIONS& aOptions ) override;
|
||||||
|
|
||||||
|
|
|
@ -459,6 +459,7 @@ void PCB_DRAW_PANEL_GAL::setDefaultLayerDeps()
|
||||||
m_view->SetLayerTarget( LAYER_RATSNEST, KIGFX::TARGET_OVERLAY );
|
m_view->SetLayerTarget( LAYER_RATSNEST, KIGFX::TARGET_OVERLAY );
|
||||||
m_view->SetLayerDisplayOnly( LAYER_RATSNEST );
|
m_view->SetLayerDisplayOnly( LAYER_RATSNEST );
|
||||||
|
|
||||||
|
m_view->SetLayerTarget( LAYER_WORKSHEET, KIGFX::TARGET_NONCACHED );
|
||||||
m_view->SetLayerDisplayOnly( LAYER_WORKSHEET ) ;
|
m_view->SetLayerDisplayOnly( LAYER_WORKSHEET ) ;
|
||||||
m_view->SetLayerDisplayOnly( LAYER_GRID );
|
m_view->SetLayerDisplayOnly( LAYER_GRID );
|
||||||
m_view->SetLayerDisplayOnly( LAYER_DRC );
|
m_view->SetLayerDisplayOnly( LAYER_DRC );
|
||||||
|
|
Loading…
Reference in New Issue