3D-Viewer: improve edge texture clamping of end segments

Fixes https://gitlab.com/kicad/code/kicad/issues/8245
This commit is contained in:
Mario Luzeiro 2021-04-20 22:19:11 +01:00 committed by jean-pierre charras
parent c973a447df
commit cdc8fd3804
4 changed files with 81 additions and 7 deletions

View File

@ -524,6 +524,64 @@ void IMAGE::EfxFilter( IMAGE* aInImg, IMAGE_FILTER aFilterType )
}
void IMAGE::EfxFilter_SkipCenter( IMAGE* aInImg, IMAGE_FILTER aFilterType, unsigned int aRadius )
{
if( ( !aInImg ) || ( m_width != aInImg->m_width ) || ( m_height != aInImg->m_height ) )
return;
S_FILTER filter = FILTERS[static_cast<int>( aFilterType )];
aInImg->m_wraping = IMAGE_WRAP::ZERO;
const unsigned int radiusSquared = aRadius * aRadius;
const unsigned int xCenter = m_width / 2;
const unsigned int yCenter = m_height / 2;
for( size_t iy = 0; iy < m_height; iy++ )
{
int yc = iy - yCenter;
yc = yc * yc;
for( size_t ix = 0; ix < m_width; ix++ )
{
int xc = ix - xCenter;
xc = xc * xc;
if( ( xc + yc ) < radiusSquared )
{
const unsigned int offset = ix + iy * m_width;
m_pixels[offset] = aInImg->m_pixels[offset];
continue;
}
int v = 0;
for( size_t sy = 0; sy < 5; sy++ )
{
for( size_t sx = 0; sx < 5; sx++ )
{
int factor = filter.kernel[sx][sy];
unsigned char pixelv = aInImg->Getpixel( ix + sx - 2, iy + sy - 2 );
v += pixelv * factor;
}
}
v /= filter.div;
v += filter.offset;
CLAMP(v, 0, 255);
m_pixels[ix + iy * m_width] = v;
}
}
}
void IMAGE::SetPixelsFromNormalizedFloat( const float* aNormalizedFloatArray )
{
for( unsigned int i = 0; i < m_wxh; i++ )

View File

@ -175,6 +175,16 @@ public:
*/
void EfxFilter( IMAGE* aInImg, IMAGE_FILTER aFilterType );
/**
* Apply a filter to the input image and store it in the image class.
* skip the circle center defined by radius
*
* @param aInImg input image
* @param aFilterType filter type to apply
* @param aRadius center circle that the effect will not be applied
*/
void EfxFilter_SkipCenter( IMAGE* aInImg, IMAGE_FILTER aFilterType, unsigned int aRadius );
/**
* Save image buffer to a PNG file into the working folder.
*

View File

@ -650,7 +650,7 @@ GLuint OPENGL_RENDER_LIST::generate_top_or_bot_seg_ends(
setBlendfunction();
glAlphaFunc( GL_GREATER, 0.2f );
glAlphaFunc( GL_GREATER, 0.98f );
glEnable( GL_ALPHA_TEST );
glNormal3f( 0.0f, 0.0f, aIsNormalUp?1.0f:-1.0f );

View File

@ -982,19 +982,25 @@ bool RENDER_3D_LEGACY::initializeOpenGL()
if( !circleImage )
return false;
unsigned int circleRadius = ( SIZE_OF_CIRCLE_TEXTURE / 2 ) - 0;
circleImage->CircleFilled( ( SIZE_OF_CIRCLE_TEXTURE / 2 ) - 0,
( SIZE_OF_CIRCLE_TEXTURE / 2 ) - 0,
( SIZE_OF_CIRCLE_TEXTURE / 2 ) - 4,
circleRadius,
0xFF );
IMAGE* circleImage_Copy = new IMAGE( *circleImage );
IMAGE* circleImageBlured = new IMAGE( circleImage->GetWidth(), circleImage->GetHeight() );
circleImage->EfxFilter( circleImage_Copy, IMAGE_FILTER::BLUR_3X3 );
circleImageBlured->EfxFilter_SkipCenter( circleImage, IMAGE_FILTER::GAUSSIAN_BLUR, circleRadius - 8 );
m_circleTexture = OglLoadTexture( *circleImage );
circleImage->EfxFilter_SkipCenter( circleImageBlured, IMAGE_FILTER::GAUSSIAN_BLUR, circleRadius - 8 );
delete circleImage_Copy;
circleImage_Copy = 0;
circleImageBlured->EfxFilter_SkipCenter( circleImage, IMAGE_FILTER::GAUSSIAN_BLUR, circleRadius - 8 );
m_circleTexture = OglLoadTexture( *circleImageBlured );
delete circleImageBlured;
circleImageBlured = 0;
delete circleImage;
circleImage = 0;