Add supersampling (2x/4x) antialiasing
This commit is contained in:
parent
02bb410cdb
commit
afacee5d96
|
@ -53,4 +53,133 @@ namespace KIGFX {
|
|||
return compositor->CreateBuffer( compositor->GetScreenSize() );
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void draw_fullscreen_primitive()
|
||||
{
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
|
||||
glBegin(GL_TRIANGLES);
|
||||
glTexCoord2f(0.0f, 1.0f);
|
||||
glVertex2f(-1.0f, 1.0f);
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
glVertex2f(-1.0f, -1.0f);
|
||||
glTexCoord2f(1.0f, 1.0f);
|
||||
glVertex2f(1.0f, 1.0f);
|
||||
|
||||
glTexCoord2f(1.0f, 1.0f);
|
||||
glVertex2f(1.0f, 1.0f);
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
glVertex2f(-1.0f, -1.0f);
|
||||
glTexCoord2f(1.0f, 0.0f);
|
||||
glVertex2f(1.0f, -1.0f);
|
||||
glEnd();
|
||||
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// =========================
|
||||
// ANTIALIASING_SUPERSAMPLING
|
||||
// =========================
|
||||
|
||||
ANTIALIASING_SUPERSAMPLING::ANTIALIASING_SUPERSAMPLING( OPENGL_COMPOSITOR* aCompositor,
|
||||
SUPERSAMPLING_MODE aMode )
|
||||
: compositor( aCompositor ), mode( aMode ), areBuffersCreated( false ),
|
||||
areShadersCreated( false )
|
||||
{
|
||||
}
|
||||
|
||||
bool ANTIALIASING_SUPERSAMPLING::Init()
|
||||
{
|
||||
if( mode == SUPERSAMPLING_MODE::X4 && !areShadersCreated ) {
|
||||
x4_shader.reset(new SHADER());
|
||||
x4_shader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_VERTEX, BUILTIN_SHADERS::ssaa_x4_vertex_shader );
|
||||
x4_shader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_FRAGMENT, BUILTIN_SHADERS::ssaa_x4_fragment_shader );
|
||||
x4_shader->Link();
|
||||
checkGlError( "linking supersampling x4 shader" );
|
||||
|
||||
GLint source_parameter = x4_shader->AddParameter( "source" ); checkGlError("getting pass 1 colorTex");
|
||||
|
||||
x4_shader->Use(); checkGlError("using pass 1 shader");
|
||||
x4_shader->SetParameter( source_parameter, 0 ); checkGlError("setting colorTex uniform");
|
||||
x4_shader->Deactivate(); checkGlError("deactivating pass 2 shader");
|
||||
|
||||
areShadersCreated = true;
|
||||
}
|
||||
|
||||
if( areShadersCreated && mode != SUPERSAMPLING_MODE::X4 ) {
|
||||
x4_shader.reset();
|
||||
areShadersCreated = false;
|
||||
}
|
||||
|
||||
if( !areBuffersCreated ) {
|
||||
ssaaMainBuffer = compositor->CreateBuffer();
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
||||
|
||||
areBuffersCreated = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
VECTOR2U ANTIALIASING_SUPERSAMPLING::GetInternalBufferSize()
|
||||
{
|
||||
unsigned int factor = (mode == SUPERSAMPLING_MODE::X2) ? 2 : 4;
|
||||
return compositor->GetScreenSize() * factor;
|
||||
}
|
||||
|
||||
void ANTIALIASING_SUPERSAMPLING::Begin()
|
||||
{
|
||||
compositor->SetBuffer( ssaaMainBuffer );
|
||||
compositor->ClearBuffer();
|
||||
}
|
||||
|
||||
void ANTIALIASING_SUPERSAMPLING::DrawBuffer( GLuint aBuffer )
|
||||
{
|
||||
compositor->DrawBuffer( aBuffer, ssaaMainBuffer );
|
||||
}
|
||||
|
||||
void ANTIALIASING_SUPERSAMPLING::Present()
|
||||
{
|
||||
glDisable( GL_BLEND );
|
||||
glDisable( GL_DEPTH_TEST );
|
||||
glActiveTexture( GL_TEXTURE0 );
|
||||
glBindTexture( GL_TEXTURE_2D, compositor->GetBufferTexture( ssaaMainBuffer ) );
|
||||
compositor->SetBuffer( OPENGL_COMPOSITOR::DIRECT_RENDERING );
|
||||
|
||||
if( mode == SUPERSAMPLING_MODE::X4 ) {
|
||||
x4_shader->Use();
|
||||
checkGlError ( "activating supersampling x4 shader" );
|
||||
}
|
||||
|
||||
draw_fullscreen_primitive();
|
||||
|
||||
if( mode == SUPERSAMPLING_MODE::X4 ) {
|
||||
x4_shader->Deactivate();
|
||||
checkGlError ( "deactivating supersampling x4 shader" );
|
||||
}
|
||||
}
|
||||
|
||||
void ANTIALIASING_SUPERSAMPLING::OnLostBuffers()
|
||||
{
|
||||
areBuffersCreated = false;
|
||||
}
|
||||
|
||||
unsigned int ANTIALIASING_SUPERSAMPLING::CreateBuffer()
|
||||
{
|
||||
return compositor->CreateBuffer( GetInternalBufferSize() );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -41,6 +41,36 @@ namespace KIGFX {
|
|||
OPENGL_COMPOSITOR* compositor;
|
||||
};
|
||||
|
||||
enum class SUPERSAMPLING_MODE {
|
||||
X2,
|
||||
X4
|
||||
};
|
||||
|
||||
class ANTIALIASING_SUPERSAMPLING : public OPENGL_PRESENTOR {
|
||||
public:
|
||||
ANTIALIASING_SUPERSAMPLING(OPENGL_COMPOSITOR* compositor, SUPERSAMPLING_MODE aMode);
|
||||
|
||||
bool Init() override;
|
||||
unsigned int CreateBuffer() override;
|
||||
|
||||
VECTOR2U GetInternalBufferSize() override;
|
||||
void OnLostBuffers() override;
|
||||
|
||||
void Begin() override;
|
||||
void DrawBuffer(GLuint) override;
|
||||
void Present() override;
|
||||
|
||||
private:
|
||||
OPENGL_COMPOSITOR* compositor;
|
||||
SUPERSAMPLING_MODE mode;
|
||||
|
||||
unsigned int ssaaMainBuffer;
|
||||
bool areBuffersCreated;
|
||||
|
||||
bool areShadersCreated;
|
||||
std::unique_ptr< SHADER > x4_shader;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -224,6 +224,38 @@ void main()
|
|||
|
||||
)SHADER_SOURCE";
|
||||
|
||||
const char ssaa_x4_vertex_shader[] = R"SHADER_SOURCE(
|
||||
|
||||
#version 120
|
||||
varying vec2 texcoord;
|
||||
void main()
|
||||
{
|
||||
texcoord = gl_MultiTexCoord0.st;
|
||||
gl_Position = ftransform();
|
||||
}
|
||||
|
||||
)SHADER_SOURCE";
|
||||
|
||||
const char ssaa_x4_fragment_shader[] = R"SHADER_SOURCE(
|
||||
|
||||
#version 120
|
||||
varying vec2 texcoord;
|
||||
uniform sampler2D source;
|
||||
void main()
|
||||
{
|
||||
float step_x = dFdx(texcoord.x)/4.;
|
||||
float step_y = dFdy(texcoord.y)/4.;
|
||||
|
||||
vec4 q00 = texture2D( source, texcoord + vec2(-step_x, -step_y) );
|
||||
vec4 q01 = texture2D( source, texcoord + vec2( step_x, -step_y) );
|
||||
vec4 q10 = texture2D( source, texcoord + vec2(-step_x, step_y) );
|
||||
vec4 q11 = texture2D( source, texcoord + vec2( step_x, step_y) );
|
||||
|
||||
gl_FragColor = (q00+q01+q10+q11)/4;
|
||||
}
|
||||
|
||||
)SHADER_SOURCE";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,9 @@ namespace KIGFX {
|
|||
extern const char kicad_vertex_shader[];
|
||||
extern const char kicad_fragment_shader[];
|
||||
|
||||
extern const char ssaa_x4_vertex_shader[];
|
||||
extern const char ssaa_x4_fragment_shader[];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ OPENGL_COMPOSITOR::OPENGL_COMPOSITOR() :
|
|||
m_initialized( false ), m_curBuffer( 0 ),
|
||||
m_mainFbo( 0 ), m_depthBuffer( 0 ), m_curFbo( DIRECT_RENDERING )
|
||||
{
|
||||
m_antialiasing.reset( new ANTIALIASING_NONE( this ) );
|
||||
m_antialiasing.reset( new ANTIALIASING_SUPERSAMPLING( this, SUPERSAMPLING_MODE::X4 ) );
|
||||
}
|
||||
|
||||
|
||||
|
@ -81,6 +81,8 @@ void OPENGL_COMPOSITOR::Initialize()
|
|||
bindFb( DIRECT_RENDERING );
|
||||
|
||||
m_initialized = true;
|
||||
|
||||
m_antialiasing->Init();
|
||||
}
|
||||
|
||||
|
||||
|
@ -236,7 +238,6 @@ void OPENGL_COMPOSITOR::SetBuffer( unsigned int aBufferHandle )
|
|||
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_COMPOSITOR::ClearBuffer()
|
||||
{
|
||||
assert( m_initialized );
|
||||
|
@ -266,8 +267,8 @@ void OPENGL_COMPOSITOR::DrawBuffer(unsigned int aSourceHandle, unsigned int aDes
|
|||
assert( aSourceHandle != 0 && aSourceHandle <= usedBuffers() );
|
||||
assert (aDestHandle <= usedBuffers() );
|
||||
|
||||
// Switch to the main framebuffer and blit the scene
|
||||
bindFb( aDestHandle );
|
||||
// Switch to the destination buffer and blit the scene
|
||||
SetBuffer ( aDestHandle );
|
||||
|
||||
// Depth test has to be disabled to make transparency working
|
||||
glDisable( GL_DEPTH_TEST );
|
||||
|
|
|
@ -299,6 +299,10 @@ void OPENGL_GAL::BeginDrawing()
|
|||
isBitmapFontInitialized = true;
|
||||
}
|
||||
|
||||
// Something betreen BeginDrawing and EndDrawing seems to depend on
|
||||
// this texture unit being active, but it does not assure it itself.
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
// Unbind buffers - set compositor for direct drawing
|
||||
compositor->SetBuffer( OPENGL_COMPOSITOR::DIRECT_RENDERING );
|
||||
|
||||
|
@ -332,7 +336,7 @@ void OPENGL_GAL::EndDrawing()
|
|||
compositor->DrawBuffer( mainBuffer );
|
||||
compositor->DrawBuffer( overlayBuffer );
|
||||
compositor->Present();
|
||||
blitCursor();
|
||||
//blitCursor();
|
||||
|
||||
SwapBuffers();
|
||||
GL_CONTEXT_MANAGER::Get().UnlockCtx( glPrivContext );
|
||||
|
|
Loading…
Reference in New Issue