Improve accelerated supersampling 2x antialiasing
Avoid fractional pixel offsets by forcing integer division of m_screenSize. Shift rounded lookAtPoint onto OpenGL pixel center to ensure consistent rounding to int. The pixel 0..1 @ 1x needs to fill the area 0..2 @ 2x so its center moves by 0.5 * (pixel size @ 1x).
This commit is contained in:
parent
53a75a4961
commit
937f502158
|
@ -189,7 +189,8 @@ void GAL::ComputeWorldScreenMatrix()
|
|||
|
||||
MATRIX3x3D translation;
|
||||
translation.SetIdentity();
|
||||
translation.SetTranslation( 0.5 * VECTOR2D( m_screenSize ) );
|
||||
// We're deliberately dividing integers to avoid fractional pixel offsets.
|
||||
translation.SetTranslation( VECTOR2D( m_screenSize.x/2, m_screenSize.y/2 ) );
|
||||
|
||||
MATRIX3x3D rotate;
|
||||
rotate.SetIdentity();
|
||||
|
|
|
@ -83,6 +83,7 @@ uniform float worldPixelSize;
|
|||
uniform vec2 screenPixelSize;
|
||||
uniform float pixelSizeMultiplier;
|
||||
uniform float minLinePixelWidth;
|
||||
uniform vec2 antialiasingOffset;
|
||||
|
||||
|
||||
float roundr( float f, float r )
|
||||
|
@ -239,6 +240,7 @@ void main()
|
|||
|
||||
}
|
||||
|
||||
gl_Position.xy += antialiasingOffset;
|
||||
}
|
||||
|
||||
)SHADER_SOURCE";
|
||||
|
|
|
@ -439,3 +439,13 @@ int OPENGL_COMPOSITOR::GetAntialiasSupersamplingFactor() const
|
|||
default: return 1;
|
||||
}
|
||||
}
|
||||
|
||||
VECTOR2D OPENGL_COMPOSITOR::GetAntialiasRenderingOffset() const
|
||||
{
|
||||
switch( m_currentAntialiasingMode )
|
||||
{
|
||||
case OPENGL_ANTIALIASING_MODE::SUPERSAMPLING_X2: return VECTOR2D( 0.5, -0.5 );
|
||||
case OPENGL_ANTIALIASING_MODE::SUPERSAMPLING_X4: return VECTOR2D( 0.25, -0.25 );
|
||||
default: return VECTOR2D( 0, 0 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -281,6 +281,7 @@ OPENGL_GAL::OPENGL_GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions, wxWindow* aParent,
|
|||
ufm_worldPixelSize = 1;
|
||||
ufm_screenPixelSize = 1;
|
||||
ufm_pixelSizeMultiplier = 1;
|
||||
ufm_antialiasingOffset = 1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -528,6 +529,7 @@ void OPENGL_GAL::beginDrawing()
|
|||
ufm_worldPixelSize = m_shader->AddParameter( "worldPixelSize" );
|
||||
ufm_screenPixelSize = m_shader->AddParameter( "screenPixelSize" );
|
||||
ufm_pixelSizeMultiplier = m_shader->AddParameter( "pixelSizeMultiplier" );
|
||||
ufm_antialiasingOffset = m_shader->AddParameter( "antialiasingOffset" );
|
||||
|
||||
m_shader->Use();
|
||||
m_shader->SetParameter( ufm_fontTexture, (int) FONT_TEXTURE_UNIT );
|
||||
|
@ -541,9 +543,14 @@ void OPENGL_GAL::beginDrawing()
|
|||
m_shader->Use();
|
||||
m_shader->SetParameter( ufm_worldPixelSize,
|
||||
(float) ( getWorldPixelSize() / GetScaleFactor() ) );
|
||||
m_shader->SetParameter( ufm_screenPixelSize, getScreenPixelSize() );
|
||||
const VECTOR2D& screenPixelSize = getScreenPixelSize();
|
||||
m_shader->SetParameter( ufm_screenPixelSize, screenPixelSize );
|
||||
double pixelSizeMultiplier = m_compositor->GetAntialiasSupersamplingFactor();
|
||||
m_shader->SetParameter( ufm_pixelSizeMultiplier, (float) pixelSizeMultiplier );
|
||||
VECTOR2D renderingOffset = m_compositor->GetAntialiasRenderingOffset();
|
||||
renderingOffset.x *= screenPixelSize.x;
|
||||
renderingOffset.y *= screenPixelSize.y;
|
||||
m_shader->SetParameter( ufm_antialiasingOffset, renderingOffset );
|
||||
m_shader->Deactivate();
|
||||
|
||||
// Something betreen BeginDrawing and EndDrawing seems to depend on
|
||||
|
@ -2321,18 +2328,20 @@ void OPENGL_GAL::EnableDepthTest( bool aEnabled )
|
|||
}
|
||||
|
||||
|
||||
static double roundr( double f, double r )
|
||||
inline double round_to_half_pixel( double f, double r )
|
||||
{
|
||||
return floor( f / r + 0.5 ) * r;
|
||||
return ( ceil( f / r ) - 0.5 ) * r;
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::ComputeWorldScreenMatrix()
|
||||
{
|
||||
computeWorldScale();
|
||||
auto pixelSize = m_worldScale;
|
||||
|
||||
m_lookAtPoint.x = roundr( m_lookAtPoint.x, pixelSize );
|
||||
m_lookAtPoint.y = roundr( m_lookAtPoint.y, pixelSize );
|
||||
// we need -m_lookAtPoint == -k * pixelSize + 0.5 * pixelSize for OpenGL
|
||||
// meaning m_lookAtPoint = (k-0.5)*pixelSize with integer k
|
||||
m_lookAtPoint.x = round_to_half_pixel( m_lookAtPoint.x, pixelSize );
|
||||
m_lookAtPoint.y = round_to_half_pixel( m_lookAtPoint.y, pixelSize );
|
||||
|
||||
GAL::ComputeWorldScreenMatrix();
|
||||
}
|
||||
|
|
|
@ -94,6 +94,7 @@ public:
|
|||
OPENGL_ANTIALIASING_MODE GetAntialiasingMode() const;
|
||||
|
||||
int GetAntialiasSupersamplingFactor() const;
|
||||
VECTOR2D GetAntialiasRenderingOffset() const;
|
||||
|
||||
protected:
|
||||
/// Binds a specific Framebuffer Object.
|
||||
|
|
|
@ -336,6 +336,7 @@ private:
|
|||
GLint ufm_worldPixelSize;
|
||||
GLint ufm_screenPixelSize;
|
||||
GLint ufm_pixelSizeMultiplier;
|
||||
GLint ufm_antialiasingOffset;
|
||||
|
||||
wxCursor m_currentwxCursor; ///< wxCursor showing the current native cursor
|
||||
|
||||
|
|
Loading…
Reference in New Issue