OpenGL antialising code clean up & formatting

This commit is contained in:
Maciej Suminski 2017-01-11 16:19:58 +01:00
parent 32a125a767
commit da00d64877
15 changed files with 642 additions and 600 deletions

View File

@ -3,10 +3,6 @@
*
* Copyright (C) 2016 Kicad Developers, see change_log.txt for contributors.
*
* Graphics Abstraction Layer (GAL) for OpenGL
*
* Shader class
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
@ -28,32 +24,33 @@
#include <gal/gal_display_options.h>
#include <wx/config.h>
namespace KIGFX {
using namespace KIGFX;
static const wxString GalGLAntialiasingKeyword( wxT( "OpenGLAntialiasingMode" ) );
static const wxString GalGLAntialiasingKeyword( wxT( "OpenGLAntialiasingMode" ) );
GAL_DISPLAY_OPTIONS::GAL_DISPLAY_OPTIONS()
: gl_antialiasing_mode( OPENGL_ANTIALIASING_MODE::NONE )
{}
GAL_DISPLAY_OPTIONS::GAL_DISPLAY_OPTIONS()
: gl_antialiasing_mode( OPENGL_ANTIALIASING_MODE::NONE )
{}
void GAL_DISPLAY_OPTIONS::ReadConfig( wxConfigBase* aCfg, wxString aBaseName )
{
aCfg->Read( aBaseName + GalGLAntialiasingKeyword,
reinterpret_cast<long*>(&gl_antialiasing_mode),
(long)KIGFX::OPENGL_ANTIALIASING_MODE::NONE );
NotifyChanged();
}
void GAL_DISPLAY_OPTIONS::WriteConfig( wxConfigBase* aCfg, wxString aBaseName )
{
aCfg->Write( aBaseName + GalGLAntialiasingKeyword,
static_cast<long>(gl_antialiasing_mode) );
}
void GAL_DISPLAY_OPTIONS::NotifyChanged()
{
Notify( &GAL_DISPLAY_OPTIONS_OBSERVER::OnGalDisplayOptionsChanged, *this );
}
void GAL_DISPLAY_OPTIONS::ReadConfig( wxConfigBase* aCfg, wxString aBaseName )
{
aCfg->Read( aBaseName + GalGLAntialiasingKeyword,
reinterpret_cast<long*>(&gl_antialiasing_mode),
(long)KIGFX::OPENGL_ANTIALIASING_MODE::NONE );
NotifyChanged();
}
void GAL_DISPLAY_OPTIONS::WriteConfig( wxConfigBase* aCfg, wxString aBaseName )
{
aCfg->Write( aBaseName + GalGLAntialiasingKeyword,
static_cast<long>(gl_antialiasing_mode) );
}
void GAL_DISPLAY_OPTIONS::NotifyChanged()
{
Notify( &GAL_DISPLAY_OPTIONS_OBSERVER::OnGalDisplayOptionsChanged, *this );
}

View File

@ -3,10 +3,6 @@
*
* Copyright (C) 2016 Kicad Developers, see change_log.txt for contributors.
*
* Graphics Abstraction Layer (GAL) for OpenGL
*
* Shader class
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
@ -35,233 +31,256 @@
#include "SmaaAreaTex.h"
#include "SmaaSearchTex.h"
namespace KIGFX {
using namespace KIGFX;
// =========================
// ANTIALIASING_NONE
// =========================
// =========================
// ANTIALIASING_NONE
// =========================
ANTIALIASING_NONE::ANTIALIASING_NONE( OPENGL_COMPOSITOR* aCompositor )
: compositor( aCompositor )
ANTIALIASING_NONE::ANTIALIASING_NONE( OPENGL_COMPOSITOR* aCompositor )
: compositor( aCompositor )
{
}
bool ANTIALIASING_NONE::Init()
{
// Nothing to initialize
return true;
}
VECTOR2U ANTIALIASING_NONE::GetInternalBufferSize()
{
return compositor->GetScreenSize();
}
void ANTIALIASING_NONE::DrawBuffer( GLuint buffer )
{
compositor->DrawBuffer( buffer, OPENGL_COMPOSITOR::DIRECT_RENDERING );
}
void ANTIALIASING_NONE::Present()
{
// Nothing to present, draw_buffer already drew to the screen
}
void ANTIALIASING_NONE::OnLostBuffers()
{
// Nothing to do
}
void ANTIALIASING_NONE::Begin()
{
// Nothing to do
}
unsigned int ANTIALIASING_NONE::CreateBuffer()
{
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();
}
bool ANTIALIASING_NONE::Init()
}
// =========================
// 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 )
{
// Nothing to initialize
return true;
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;
}
VECTOR2U ANTIALIASING_NONE::GetInternalBufferSize()
if( areShadersCreated && mode != SUPERSAMPLING_MODE::X4 )
{
return compositor->GetScreenSize();
x4_shader.reset();
areShadersCreated = false;
}
void ANTIALIASING_NONE::DrawBuffer( GLuint buffer )
if( !areBuffersCreated )
{
compositor->DrawBuffer( buffer, OPENGL_COMPOSITOR::DIRECT_RENDERING );
}
void ANTIALIASING_NONE::Present()
{
// Nothing to present, draw_buffer already drew to the screen
}
void ANTIALIASING_NONE::OnLostBuffers()
{
// Nothing to do
}
void ANTIALIASING_NONE::Begin()
{
// Nothing to do
}
unsigned int ANTIALIASING_NONE::CreateBuffer()
{
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() );
}
// ===============================
// ANTIALIASING_SMAA
// ===============================
ANTIALIASING_SMAA::ANTIALIASING_SMAA( OPENGL_COMPOSITOR* aCompositor, SMAA_QUALITY aQuality )
: compositor( aCompositor ), shadersLoaded( false ), areBuffersInitialized( false ),
quality( aQuality )
{
}
VECTOR2U ANTIALIASING_SMAA::GetInternalBufferSize()
{
return compositor->GetScreenSize();
}
void ANTIALIASING_SMAA::loadShaders()
{
// Load constant textures
glEnable( GL_TEXTURE_2D );
glActiveTexture( GL_TEXTURE0 );
glGenTextures( 1, &smaaAreaTex );
glBindTexture( GL_TEXTURE_2D, smaaAreaTex );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
ssaaMainBuffer = compositor->CreateBuffer();
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RG8, AREATEX_WIDTH, AREATEX_HEIGHT, 0, GL_RG, GL_UNSIGNED_BYTE, areaTexBytes );
checkGlError( "loading smaa area tex" );
glGenTextures( 1, &smaaSearchTex );
glBindTexture( GL_TEXTURE_2D, smaaSearchTex );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexImage2D( GL_TEXTURE_2D, 0, GL_R8, SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT, 0, GL_RED, GL_UNSIGNED_BYTE, searchTexBytes );
checkGlError( "loading smaa search tex" );
std::string quality_string;
areBuffersCreated = true;
}
if(quality == SMAA_QUALITY::HIGH) {
quality_string = "#define SMAA_PRESET_HIGH\n";
}
else {
quality_string = "#define SMAA_PRESET_ULTRA\n";
}
return true;
}
// set up shaders
std::string vert_preamble( R"SHADER(
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() );
}
// ===============================
// ANTIALIASING_SMAA
// ===============================
ANTIALIASING_SMAA::ANTIALIASING_SMAA( OPENGL_COMPOSITOR* aCompositor, SMAA_QUALITY aQuality )
: areBuffersInitialized( false ), shadersLoaded( false ),
quality( aQuality ), compositor( aCompositor )
{
}
VECTOR2U ANTIALIASING_SMAA::GetInternalBufferSize()
{
return compositor->GetScreenSize();
}
void ANTIALIASING_SMAA::loadShaders()
{
// Load constant textures
glEnable( GL_TEXTURE_2D );
glActiveTexture( GL_TEXTURE0 );
glGenTextures( 1, &smaaAreaTex );
glBindTexture( GL_TEXTURE_2D, smaaAreaTex );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RG8, AREATEX_WIDTH, AREATEX_HEIGHT, 0, GL_RG, GL_UNSIGNED_BYTE, areaTexBytes );
checkGlError( "loading smaa area tex" );
glGenTextures( 1, &smaaSearchTex );
glBindTexture( GL_TEXTURE_2D, smaaSearchTex );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexImage2D( GL_TEXTURE_2D, 0, GL_R8, SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT, 0, GL_RED, GL_UNSIGNED_BYTE, searchTexBytes );
checkGlError( "loading smaa search tex" );
std::string quality_string;
if( quality == SMAA_QUALITY::HIGH )
{
quality_string = "#define SMAA_PRESET_HIGH\n";
}
else
{
quality_string = "#define SMAA_PRESET_ULTRA\n";
}
// set up shaders
std::string vert_preamble( R"SHADER(
#version 120
#define SMAA_GLSL_2_1
#define SMAA_INCLUDE_VS 1
@ -269,7 +288,7 @@ namespace KIGFX {
uniform vec4 SMAA_RT_METRICS;
)SHADER" );
std::string frag_preamble( R"SHADER(
std::string frag_preamble( R"SHADER(
#version 120
#define SMAA_GLSL_2_1
#define SMAA_INCLUDE_VS 0
@ -277,222 +296,228 @@ uniform vec4 SMAA_RT_METRICS;
uniform vec4 SMAA_RT_METRICS;
)SHADER" );
std::string smaa_source =
std::string( BUILTIN_SHADERS::smaa_base_shader_p1 )
+ std::string( BUILTIN_SHADERS::smaa_base_shader_p2 )
+ std::string( BUILTIN_SHADERS::smaa_base_shader_p3 )
+ std::string( BUILTIN_SHADERS::smaa_base_shader_p4 );
std::string smaa_source =
std::string( BUILTIN_SHADERS::smaa_base_shader_p1 )
+ std::string( BUILTIN_SHADERS::smaa_base_shader_p2 )
+ std::string( BUILTIN_SHADERS::smaa_base_shader_p3 )
+ std::string( BUILTIN_SHADERS::smaa_base_shader_p4 );
//
// Set up pass 1 Shader
//
pass_1_shader.reset( new SHADER() );
pass_1_shader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_VERTEX, vert_preamble,
quality_string, smaa_source, BUILTIN_SHADERS::smaa_pass_1_vertex_shader );
pass_1_shader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_FRAGMENT, frag_preamble,
quality_string, smaa_source, BUILTIN_SHADERS::smaa_pass_1_fragment_shader );
pass_1_shader->Link();
checkGlError( "linking pass 1 shader" );
//
// Set up pass 1 Shader
//
pass_1_shader.reset( new SHADER() );
pass_1_shader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_VERTEX, vert_preamble,
quality_string, smaa_source, BUILTIN_SHADERS::smaa_pass_1_vertex_shader );
pass_1_shader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_FRAGMENT, frag_preamble,
quality_string, smaa_source, BUILTIN_SHADERS::smaa_pass_1_fragment_shader );
pass_1_shader->Link();
checkGlError( "linking pass 1 shader" );
GLint smaaColorTexParameter = pass_1_shader->AddParameter( "colorTex" ); checkGlError( "pass1: getting colorTex uniform" );
pass_1_metrics = pass_1_shader->AddParameter( "SMAA_RT_METRICS" ); checkGlError( "pass1: getting metrics uniform" );
GLint smaaColorTexParameter = pass_1_shader->AddParameter( "colorTex" ); checkGlError( "pass1: getting colorTex uniform" );
pass_1_metrics = pass_1_shader->AddParameter( "SMAA_RT_METRICS" ); checkGlError( "pass1: getting metrics uniform" );
pass_1_shader->Use(); checkGlError( "pass1: using shader" );
pass_1_shader->SetParameter( smaaColorTexParameter, 0 ); checkGlError( "pass1: setting colorTex uniform" );
pass_1_shader->Deactivate(); checkGlError( "pass1: deactivating shader" );
pass_1_shader->Use(); checkGlError( "pass1: using shader" );
pass_1_shader->SetParameter( smaaColorTexParameter, 0 ); checkGlError( "pass1: setting colorTex uniform" );
pass_1_shader->Deactivate(); checkGlError( "pass1: deactivating shader" );
//
// set up pass 2 shader
//
pass_2_shader.reset( new SHADER() );
pass_2_shader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_VERTEX, vert_preamble,
quality_string, smaa_source, BUILTIN_SHADERS::smaa_pass_2_vertex_shader );
pass_2_shader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_FRAGMENT, frag_preamble,
quality_string, smaa_source, BUILTIN_SHADERS::smaa_pass_2_fragment_shader );
pass_2_shader->Link();
checkGlError( "linking pass 2 shader" );
//
// set up pass 2 shader
//
pass_2_shader.reset( new SHADER() );
pass_2_shader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_VERTEX, vert_preamble,
quality_string, smaa_source, BUILTIN_SHADERS::smaa_pass_2_vertex_shader );
pass_2_shader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_FRAGMENT, frag_preamble,
quality_string, smaa_source, BUILTIN_SHADERS::smaa_pass_2_fragment_shader );
pass_2_shader->Link();
checkGlError( "linking pass 2 shader" );
GLint smaaEdgesTexParameter = pass_2_shader->AddParameter( "edgesTex" ); checkGlError( "pass2: getting colorTex uniform" );
GLint smaaAreaTexParameter = pass_2_shader->AddParameter( "areaTex" ); checkGlError( "pass2: getting areaTex uniform" );
GLint smaaSearchTexParameter = pass_2_shader->AddParameter( "searchTex" ); checkGlError( "pass2: getting searchTex uniform" );
pass_2_metrics = pass_2_shader->AddParameter( "SMAA_RT_METRICS" ); checkGlError( "pass2: getting metrics uniform" );
GLint smaaEdgesTexParameter = pass_2_shader->AddParameter( "edgesTex" ); checkGlError( "pass2: getting colorTex uniform" );
GLint smaaAreaTexParameter = pass_2_shader->AddParameter( "areaTex" ); checkGlError( "pass2: getting areaTex uniform" );
GLint smaaSearchTexParameter = pass_2_shader->AddParameter( "searchTex" ); checkGlError( "pass2: getting searchTex uniform" );
pass_2_metrics = pass_2_shader->AddParameter( "SMAA_RT_METRICS" ); checkGlError( "pass2: getting metrics uniform" );
pass_2_shader->Use(); checkGlError( "pass2: using shader" );
pass_2_shader->SetParameter( smaaEdgesTexParameter, 0 ); checkGlError( "pass2: setting colorTex uniform" );
pass_2_shader->SetParameter( smaaAreaTexParameter, 1 ); checkGlError( "pass2: setting areaTex uniform" );
pass_2_shader->SetParameter( smaaSearchTexParameter, 3 ); checkGlError( "pass2: setting searchTex uniform" );
pass_2_shader->Deactivate(); checkGlError( "pass2: deactivating shader" );
pass_2_shader->Use(); checkGlError( "pass2: using shader" );
pass_2_shader->SetParameter( smaaEdgesTexParameter, 0 ); checkGlError( "pass2: setting colorTex uniform" );
pass_2_shader->SetParameter( smaaAreaTexParameter, 1 ); checkGlError( "pass2: setting areaTex uniform" );
pass_2_shader->SetParameter( smaaSearchTexParameter, 3 ); checkGlError( "pass2: setting searchTex uniform" );
pass_2_shader->Deactivate(); checkGlError( "pass2: deactivating shader" );
//
// set up pass 3 shader
//
pass_3_shader.reset( new SHADER() );
pass_3_shader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_VERTEX, vert_preamble,
quality_string, smaa_source, BUILTIN_SHADERS::smaa_pass_3_vertex_shader );
pass_3_shader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_FRAGMENT, frag_preamble,
quality_string, smaa_source, BUILTIN_SHADERS::smaa_pass_3_fragment_shader );
pass_3_shader->Link();
//
// set up pass 3 shader
//
pass_3_shader.reset( new SHADER() );
pass_3_shader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_VERTEX, vert_preamble,
quality_string, smaa_source, BUILTIN_SHADERS::smaa_pass_3_vertex_shader );
pass_3_shader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_FRAGMENT, frag_preamble,
quality_string, smaa_source, BUILTIN_SHADERS::smaa_pass_3_fragment_shader );
pass_3_shader->Link();
GLint smaaP3ColorTexParameter = pass_3_shader->AddParameter( "colorTex" ); checkGlError( "pass3: getting colorTex uniform" );
GLint smaaBlendTexParameter = pass_3_shader->AddParameter( "blendTex" ); checkGlError( "pass3: getting blendTex uniform" );
pass_3_metrics = pass_3_shader->AddParameter( "SMAA_RT_METRICS" ); checkGlError( "pass3: getting metrics uniform" );
GLint smaaP3ColorTexParameter = pass_3_shader->AddParameter( "colorTex" ); checkGlError( "pass3: getting colorTex uniform" );
GLint smaaBlendTexParameter = pass_3_shader->AddParameter( "blendTex" ); checkGlError( "pass3: getting blendTex uniform" );
pass_3_metrics = pass_3_shader->AddParameter( "SMAA_RT_METRICS" ); checkGlError( "pass3: getting metrics uniform" );
pass_3_shader->Use(); checkGlError( "pass3: using shader" );
pass_3_shader->SetParameter( smaaP3ColorTexParameter, 0 ); checkGlError( "pass3: setting colorTex uniform" );
pass_3_shader->SetParameter( smaaBlendTexParameter, 1 ); checkGlError( "pass3: setting blendTex uniform" );
pass_3_shader->Deactivate(); checkGlError( "pass3: deactivating shader" );
shadersLoaded = true;
}
void ANTIALIASING_SMAA::updateUniforms()
{
auto dims = compositor->GetScreenSize();
pass_1_shader->Use(); checkGlError( "pass1: using shader" );
pass_1_shader->SetParameter( pass_1_metrics,
1.f / float( dims.x ), 1.f / float( dims.y ), float( dims.x ), float( dims.y ) ); checkGlError( "pass1: setting metrics uniform" );
pass_1_shader->Deactivate(); checkGlError( "pass1: deactivating shader" );
pass_2_shader->Use(); checkGlError( "pass2: using shader" );
pass_2_shader->SetParameter( pass_2_metrics,
1.f / float( dims.x ), 1.f / float( dims.y ), float( dims.x ), float( dims.y ) ); checkGlError( "pass2: setting metrics uniform" );
pass_2_shader->Deactivate(); checkGlError( "pass2: deactivating shader" );
pass_3_shader->Use(); checkGlError( "pass3: using shader" );
pass_3_shader->SetParameter( pass_3_metrics,
1.f / float( dims.x ), 1.f / float( dims.y ), float( dims.x ), float( dims.y ) ); checkGlError( "pass3: setting metrics uniform" );
pass_3_shader->Deactivate(); checkGlError( "pass3: deactivating shader" );
}
bool ANTIALIASING_SMAA::Init()
{
if(!shadersLoaded) {
loadShaders();
}
if(!areBuffersInitialized) {
smaaBaseBuffer = compositor->CreateBuffer();
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
smaaEdgesBuffer = compositor->CreateBuffer();
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
smaaBlendBuffer = compositor->CreateBuffer();
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
updateUniforms();
areBuffersInitialized = true;
}
// Nothing to initialize
return true;
}
void ANTIALIASING_SMAA::OnLostBuffers()
{
areBuffersInitialized = false;
}
unsigned int ANTIALIASING_SMAA::CreateBuffer()
{
return compositor->CreateBuffer( compositor->GetScreenSize() );
}
void ANTIALIASING_SMAA::DrawBuffer( GLuint buffer )
{
// draw to internal buffer
compositor->DrawBuffer( buffer, smaaBaseBuffer );
}
void ANTIALIASING_SMAA::Begin()
{
compositor->SetBuffer( smaaBaseBuffer );
compositor->ClearBuffer();
}
namespace {
void draw_fullscreen_triangle()
{
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, -1.0f );
glVertex2f( -1.0f, -3.0f );
glTexCoord2f( 2.0f, 1.0f );
glVertex2f( 3.0f, 1.0f );
glEnd();
glPopMatrix();
glMatrixMode( GL_MODELVIEW );
glPopMatrix();
}
}
void ANTIALIASING_SMAA::Present()
{
auto sourceTexture = compositor->GetBufferTexture( smaaBaseBuffer );
glDisable( GL_BLEND );
glDisable( GL_DEPTH_TEST );
glEnable( GL_TEXTURE_2D );
//
// pass 1: main-buffer -> smaaEdgesBuffer
//
compositor->SetBuffer( smaaEdgesBuffer );
compositor->ClearBuffer();
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, sourceTexture ); checkGlError( "binding colorTex" );
pass_1_shader->Use(); checkGlError( "using smaa pass 1 shader" );
draw_fullscreen_triangle();
pass_1_shader->Deactivate();
//
// pass 2: smaaEdgesBuffer -> smaaBlendBuffer
//
compositor->SetBuffer( smaaBlendBuffer );
compositor->ClearBuffer();
auto edgesTex = compositor->GetBufferTexture( smaaEdgesBuffer );
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, edgesTex );
glActiveTexture( GL_TEXTURE1 );
glBindTexture( GL_TEXTURE_2D, smaaAreaTex );
glActiveTexture( GL_TEXTURE3 );
glBindTexture( GL_TEXTURE_2D, smaaSearchTex );
pass_2_shader->Use();
draw_fullscreen_triangle();
pass_2_shader->Deactivate();
//
// pass 3: colorTex + BlendBuffer -> output
//
compositor->SetBuffer( OPENGL_COMPOSITOR::DIRECT_RENDERING );
compositor->ClearBuffer();
auto blendTex = compositor->GetBufferTexture( smaaBlendBuffer );
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, sourceTexture );
glActiveTexture( GL_TEXTURE1 );
glBindTexture( GL_TEXTURE_2D, blendTex );
pass_3_shader->Use();
draw_fullscreen_triangle();
pass_3_shader->Deactivate();
}
pass_3_shader->Use(); checkGlError( "pass3: using shader" );
pass_3_shader->SetParameter( smaaP3ColorTexParameter, 0 ); checkGlError( "pass3: setting colorTex uniform" );
pass_3_shader->SetParameter( smaaBlendTexParameter, 1 ); checkGlError( "pass3: setting blendTex uniform" );
pass_3_shader->Deactivate(); checkGlError( "pass3: deactivating shader" );
shadersLoaded = true;
}
void ANTIALIASING_SMAA::updateUniforms()
{
auto dims = compositor->GetScreenSize();
pass_1_shader->Use(); checkGlError( "pass1: using shader" );
pass_1_shader->SetParameter( pass_1_metrics,
1.f / float( dims.x ), 1.f / float( dims.y ), float( dims.x ), float( dims.y ) ); checkGlError( "pass1: setting metrics uniform" );
pass_1_shader->Deactivate(); checkGlError( "pass1: deactivating shader" );
pass_2_shader->Use(); checkGlError( "pass2: using shader" );
pass_2_shader->SetParameter( pass_2_metrics,
1.f / float( dims.x ), 1.f / float( dims.y ), float( dims.x ), float( dims.y ) ); checkGlError( "pass2: setting metrics uniform" );
pass_2_shader->Deactivate(); checkGlError( "pass2: deactivating shader" );
pass_3_shader->Use(); checkGlError( "pass3: using shader" );
pass_3_shader->SetParameter( pass_3_metrics,
1.f / float( dims.x ), 1.f / float( dims.y ), float( dims.x ), float( dims.y ) ); checkGlError( "pass3: setting metrics uniform" );
pass_3_shader->Deactivate(); checkGlError( "pass3: deactivating shader" );
}
bool ANTIALIASING_SMAA::Init()
{
if( !shadersLoaded )
loadShaders();
if( !areBuffersInitialized )
{
smaaBaseBuffer = compositor->CreateBuffer();
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
smaaEdgesBuffer = compositor->CreateBuffer();
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
smaaBlendBuffer = compositor->CreateBuffer();
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
updateUniforms();
areBuffersInitialized = true;
}
// Nothing to initialize
return true;
}
void ANTIALIASING_SMAA::OnLostBuffers()
{
areBuffersInitialized = false;
}
unsigned int ANTIALIASING_SMAA::CreateBuffer()
{
return compositor->CreateBuffer( compositor->GetScreenSize() );
}
void ANTIALIASING_SMAA::DrawBuffer( GLuint buffer )
{
// draw to internal buffer
compositor->DrawBuffer( buffer, smaaBaseBuffer );
}
void ANTIALIASING_SMAA::Begin()
{
compositor->SetBuffer( smaaBaseBuffer );
compositor->ClearBuffer();
}
namespace {
void draw_fullscreen_triangle()
{
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, -1.0f );
glVertex2f( -1.0f, -3.0f );
glTexCoord2f( 2.0f, 1.0f );
glVertex2f( 3.0f, 1.0f );
glEnd();
glPopMatrix();
glMatrixMode( GL_MODELVIEW );
glPopMatrix();
}
}
void ANTIALIASING_SMAA::Present()
{
auto sourceTexture = compositor->GetBufferTexture( smaaBaseBuffer );
glDisable( GL_BLEND );
glDisable( GL_DEPTH_TEST );
glEnable( GL_TEXTURE_2D );
//
// pass 1: main-buffer -> smaaEdgesBuffer
//
compositor->SetBuffer( smaaEdgesBuffer );
compositor->ClearBuffer();
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, sourceTexture ); checkGlError( "binding colorTex" );
pass_1_shader->Use(); checkGlError( "using smaa pass 1 shader" );
draw_fullscreen_triangle();
pass_1_shader->Deactivate();
//
// pass 2: smaaEdgesBuffer -> smaaBlendBuffer
//
compositor->SetBuffer( smaaBlendBuffer );
compositor->ClearBuffer();
auto edgesTex = compositor->GetBufferTexture( smaaEdgesBuffer );
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, edgesTex );
glActiveTexture( GL_TEXTURE1 );
glBindTexture( GL_TEXTURE_2D, smaaAreaTex );
glActiveTexture( GL_TEXTURE3 );
glBindTexture( GL_TEXTURE_2D, smaaSearchTex );
pass_2_shader->Use();
draw_fullscreen_triangle();
pass_2_shader->Deactivate();
//
// pass 3: colorTex + BlendBuffer -> output
//
compositor->SetBuffer( OPENGL_COMPOSITOR::DIRECT_RENDERING );
compositor->ClearBuffer();
auto blendTex = compositor->GetBufferTexture( smaaBlendBuffer );
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, sourceTexture );
glActiveTexture( GL_TEXTURE1 );
glBindTexture( GL_TEXTURE_2D, blendTex );
pass_3_shader->Use();
draw_fullscreen_triangle();
pass_3_shader->Deactivate();
}

View File

@ -3,10 +3,6 @@
*
* Copyright (C) 2016 Kicad Developers, see change_log.txt for contributors.
*
* Graphics Abstraction Layer (GAL) for OpenGL
*
* Shader class
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
@ -46,11 +42,13 @@ namespace KIGFX {
virtual void OnLostBuffers() = 0;
virtual void Begin() = 0;
virtual void DrawBuffer(GLuint buffer) = 0;
virtual void DrawBuffer( GLuint aBuffer ) = 0;
virtual void Present() = 0;
};
class ANTIALIASING_NONE : public OPENGL_PRESENTOR {
class ANTIALIASING_NONE : public OPENGL_PRESENTOR
{
public:
ANTIALIASING_NONE( OPENGL_COMPOSITOR* aCompositor );
@ -61,7 +59,7 @@ namespace KIGFX {
void OnLostBuffers() override;
void Begin() override;
void DrawBuffer( GLuint buffer ) override;
void DrawBuffer( GLuint aBuffer ) override;
void Present() override;
private:
@ -73,9 +71,11 @@ namespace KIGFX {
X4
};
class ANTIALIASING_SUPERSAMPLING : public OPENGL_PRESENTOR {
class ANTIALIASING_SUPERSAMPLING : public OPENGL_PRESENTOR
{
public:
ANTIALIASING_SUPERSAMPLING(OPENGL_COMPOSITOR* compositor, SUPERSAMPLING_MODE aMode);
ANTIALIASING_SUPERSAMPLING( OPENGL_COMPOSITOR* aCompositor, SUPERSAMPLING_MODE aMode );
bool Init() override;
unsigned int CreateBuffer() override;
@ -84,7 +84,7 @@ namespace KIGFX {
void OnLostBuffers() override;
void Begin() override;
void DrawBuffer(GLuint) override;
void DrawBuffer( GLuint ) override;
void Present() override;
private:
@ -95,7 +95,7 @@ namespace KIGFX {
bool areBuffersCreated;
bool areShadersCreated;
std::unique_ptr< SHADER > x4_shader;
std::unique_ptr<SHADER> x4_shader;
};
enum class SMAA_QUALITY {
@ -103,44 +103,45 @@ namespace KIGFX {
ULTRA
};
class ANTIALIASING_SMAA : public OPENGL_PRESENTOR {
class ANTIALIASING_SMAA : public OPENGL_PRESENTOR
{
public:
ANTIALIASING_SMAA ( OPENGL_COMPOSITOR* aCompositor, SMAA_QUALITY aQuality );
ANTIALIASING_SMAA( OPENGL_COMPOSITOR* aCompositor, SMAA_QUALITY aQuality );
bool Init() override;
unsigned int CreateBuffer () override;
VECTOR2U GetInternalBufferSize() override;
void OnLostBuffers () override;
void OnLostBuffers() override;
void Begin() override;
void DrawBuffer( GLuint buffer ) override;
void Present () override;
void Present() override;
private:
void loadShaders ();
void updateUniforms ();
void loadShaders();
void updateUniforms();
bool areBuffersInitialized; //
bool isInitialized; // shaders linked
unsigned int smaaBaseBuffer; // base + overlay temporary
unsigned int smaaEdgesBuffer;
unsigned int smaaBlendBuffer;
unsigned int smaaBaseBuffer; // base + overlay temporary
unsigned int smaaEdgesBuffer;
unsigned int smaaBlendBuffer;
// smaa shader lookup textures
unsigned int smaaAreaTex;
unsigned int smaaSearchTex;
unsigned int smaaAreaTex;
unsigned int smaaSearchTex;
bool shadersLoaded;
std::unique_ptr< SHADER > pass_1_shader;
std::unique_ptr<SHADER> pass_1_shader;
GLint pass_1_metrics;
std::unique_ptr< SHADER > pass_2_shader;
std::unique_ptr<SHADER> pass_2_shader;
GLint pass_2_metrics;
std::unique_ptr< SHADER > pass_3_shader;
std::unique_ptr<SHADER> pass_3_shader;
GLint pass_3_metrics;
SMAA_QUALITY quality;

View File

@ -3,10 +3,6 @@
*
* Copyright (C) 2016 Kicad Developers, see change_log.txt for contributors.
*
* Graphics Abstraction Layer (GAL) for OpenGL
*
* Shader class
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2

View File

@ -3,10 +3,6 @@
*
* Copyright (C) 2016 Kicad Developers, see change_log.txt for contributors.
*
* Graphics Abstraction Layer (GAL) for OpenGL
*
* Shader class
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2

View File

@ -3,10 +3,6 @@
*
* Copyright (C) 2016 Kicad Developers, see change_log.txt for contributors.
*
* Graphics Abstraction Layer (GAL) for OpenGL
*
* Shader class
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2

View File

@ -3,10 +3,6 @@
*
* Copyright (C) 2016 Kicad Developers, see change_log.txt for contributors.
*
* Graphics Abstraction Layer (GAL) for OpenGL
*
* Shader class
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
@ -34,26 +30,30 @@ namespace KIGFX {
namespace BUILTIN_FONT {
struct FONT_IMAGE_TYPE {
struct FONT_IMAGE_TYPE
{
unsigned int width, height;
unsigned int char_border;
unsigned int spacing;
unsigned char pixels[1024 * 1024 * 3];
};
struct FONT_INFO_TYPE {
struct FONT_INFO_TYPE
{
unsigned int smooth_pixels;
float min_y;
float max_y;
};
struct FONT_SPAN_TYPE {
struct FONT_SPAN_TYPE
{
unsigned int start;
unsigned int end;
unsigned int cumulative;
};
struct FONT_GLYPH_TYPE {
struct FONT_GLYPH_TYPE
{
unsigned int atlas_x, atlas_y;
unsigned int atlas_w, atlas_h;
float minx, maxx;

View File

@ -67,9 +67,7 @@ OPENGL_GAL::OPENGL_GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions, wxWindow* aParent,
const wxString& aName ) :
wxGLCanvas( aParent, wxID_ANY, (int*) glAttributes, wxDefaultPosition, wxDefaultSize,
wxEXPAND, aName ),
mouseListener( aMouseListener ),
paintListener( aPaintListener ),
options( aDisplayOptions )
options( aDisplayOptions ), mouseListener( aMouseListener ), paintListener( aPaintListener )
{
if( glMainContext == NULL )
{

View File

@ -204,7 +204,7 @@ void SHADER::shaderInfo( GLuint aShader )
}
std::string SHADER::ReadSource( std::string aShaderSourceName )
std::string SHADER::ReadSource( const std::string& aShaderSourceName )
{
// Open the shader source for reading
std::ifstream inputFile( aShaderSourceName.c_str(), std::ifstream::in );
@ -226,8 +226,8 @@ std::string SHADER::ReadSource( std::string aShaderSourceName )
}
bool SHADER::loadShaderFromStringArray( SHADER_TYPE aShaderType, const char* const * aArray,
size_t aSize )
bool SHADER::loadShaderFromStringArray( SHADER_TYPE aShaderType, const char* const* aArray,
size_t aSize )
{
assert( !isShaderLinked );

View File

@ -3,10 +3,6 @@
*
* Copyright (C) 2016 Kicad Developers, see change_log.txt for contributors.
*
* Graphics Abstraction Layer (GAL) for OpenGL
*
* Shader class
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
@ -36,7 +32,8 @@ namespace UTIL {
struct equals {
equals( const T& val ) : val_( val ) {}
bool operator()( const T& val ) {
bool operator()( const T& val )
{
return val == val_;
}
@ -44,60 +41,68 @@ namespace UTIL {
const T& val_;
};
OBSERVABLE_BASE::IMPL::IMPL( OBSERVABLE_BASE* owned_by )
: owned_by_( owned_by ), iteration_count_( 0 )
: iteration_count_( 0 ), owned_by_( owned_by )
{}
bool OBSERVABLE_BASE::IMPL::is_shared() const
{
return owned_by_ == nullptr;
}
void OBSERVABLE_BASE::IMPL::set_shared()
{
owned_by_ = nullptr;
}
OBSERVABLE_BASE::IMPL::~IMPL()
{
}
void OBSERVABLE_BASE::IMPL::enter_iteration()
{
++iteration_count_;
}
void OBSERVABLE_BASE::IMPL::leave_iteration()
{
--iteration_count_;
if(iteration_count_ == 0) {
if( iteration_count_ == 0 )
collect();
}
}
bool OBSERVABLE_BASE::IMPL::is_iterating() const
{
return iteration_count_ != 0;
}
void OBSERVABLE_BASE::IMPL::add_observer( void* observer )
{
assert( !is_iterating() );
observers_.push_back( observer );
}
void OBSERVABLE_BASE::IMPL::remove_observer( void* observer )
{
auto it = std::find( observers_.begin(), observers_.end(), observer );
if(is_iterating()) {
if( is_iterating() )
*it = nullptr;
}
else {
else
observers_.erase( it );
}
}
void OBSERVABLE_BASE::IMPL::collect()
{
auto it = std::remove_if( observers_.begin(), observers_.end(), DETAIL::equals<void*>( nullptr ) );
@ -105,21 +110,25 @@ namespace UTIL {
}
}
LINK::LINK()
{
}
LINK::LINK( std::shared_ptr<DETAIL::OBSERVABLE_BASE::IMPL> token, void* observer )
: token_( std::move( token ) ), observer_( observer )
{
}
LINK::LINK( LINK&& other )
: token_( std::move( other.token_ ) ), observer_( other.observer_ )
{
other.token_.reset();
}
LINK& LINK::operator=( LINK&& other )
{
token_ = std::move( other.token_ );
@ -128,100 +137,117 @@ namespace UTIL {
return *this;
}
LINK::operator bool() const {
LINK::operator bool() const
{
return token_ ? true : false;
}
LINK::~LINK()
{
reset();
}
void LINK::reset()
{
if(token_) {
if(token_)
{
token_->remove_observer( observer_ );
token_.reset();
}
}
namespace DETAIL {
OBSERVABLE_BASE::OBSERVABLE_BASE()
{
}
OBSERVABLE_BASE::OBSERVABLE_BASE( OBSERVABLE_BASE& other )
: impl_( other.get_shared_impl() )
{
}
OBSERVABLE_BASE::~OBSERVABLE_BASE()
{
}
void OBSERVABLE_BASE::allocate_impl() {
if(!impl_) {
void OBSERVABLE_BASE::allocate_impl()
{
if(!impl_)
impl_ = std::make_shared<IMPL>( this );
}
}
void OBSERVABLE_BASE::allocate_shared_impl()
{
if(!impl_) {
if(!impl_)
impl_ = std::make_shared<IMPL>();
}
else {
else
impl_->set_shared();
}
}
void OBSERVABLE_BASE::deallocate_impl() {
impl_.reset();
}
std::shared_ptr<OBSERVABLE_BASE::IMPL> OBSERVABLE_BASE::get_shared_impl()
{
allocate_shared_impl();
return impl_;
}
void OBSERVABLE_BASE::add_observer( void* observer ) {
void OBSERVABLE_BASE::add_observer( void* observer )
{
allocate_impl();
impl_->add_observer( observer );
}
void OBSERVABLE_BASE::remove_observer( void* observer ) {
void OBSERVABLE_BASE::remove_observer( void* observer )
{
assert( impl_ );
impl_->remove_observer( observer );
}
void OBSERVABLE_BASE::enter_iteration() {
if(impl_) {
void OBSERVABLE_BASE::enter_iteration()
{
if( impl_ )
impl_->enter_iteration();
}
}
void OBSERVABLE_BASE::leave_iteration() {
if(impl_) {
void OBSERVABLE_BASE::leave_iteration()
{
if( impl_)
{
impl_->leave_iteration();
if( !impl_->is_iterating() && !impl_->is_shared() && impl_.use_count() == 1 ) {
if( !impl_->is_iterating() && !impl_->is_shared() && impl_.use_count() == 1 )
impl_.reset();
}
}
}
size_t OBSERVABLE_BASE::size() const {
if(impl_) {
size_t OBSERVABLE_BASE::size() const
{
if( impl_ )
return impl_->observers_.size();
}
else {
else
return 0;
}
}
void OBSERVABLE_BASE::on_observers_empty()
{
// called by an impl that is owned by this, ie. it is a non-shared impl
@ -229,8 +255,6 @@ namespace UTIL {
deallocate_impl();
}
}
}

View File

@ -3,10 +3,6 @@
*
* Copyright (C) 2016 Kicad Developers, see change_log.txt for contributors.
*
* Graphics Abstraction Layer (GAL) for OpenGL
*
* Shader class
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
@ -37,7 +33,8 @@ namespace KIGFX {
class GAL_DISPLAY_OPTIONS;
enum class OPENGL_ANTIALIASING_MODE : long {
enum class OPENGL_ANTIALIASING_MODE : long
{
NONE = 0,
SUBSAMPLE_HIGH = 1,
SUBSAMPLE_ULTRA = 2,
@ -48,11 +45,10 @@ namespace KIGFX {
class GAL_DISPLAY_OPTIONS_OBSERVER
{
public:
virtual void OnGalDisplayOptionsChanged(const GAL_DISPLAY_OPTIONS&) = 0;
virtual void OnGalDisplayOptionsChanged( const GAL_DISPLAY_OPTIONS& ) = 0;
};
class GAL_DISPLAY_OPTIONS
: public UTIL::OBSERVABLE< GAL_DISPLAY_OPTIONS_OBSERVER >
class GAL_DISPLAY_OPTIONS : public UTIL::OBSERVABLE<GAL_DISPLAY_OPTIONS_OBSERVER>
{
public:
GAL_DISPLAY_OPTIONS();

View File

@ -113,7 +113,7 @@ protected:
GLuint m_curFbo;
OPENGL_ANTIALIASING_MODE m_currentAntialiasingMode;
std::unique_ptr< OPENGL_PRESENTOR > m_antialiasing;
std::unique_ptr<OPENGL_PRESENTOR> m_antialiasing;
/// Binds a specific Framebuffer Object.
void bindFb( unsigned int aFb );

View File

@ -198,14 +198,14 @@ public:
* @param aShaderSourceName is the shader source file name.
* @return the source as string
*/
static std::string ReadSource( std::string aShaderSourceName );
static std::string ReadSource( const std::string& aShaderSourceName );
private:
/**
* @brief Compile vertex of fragment shader source code into the program.
*/
bool loadShaderFromStringArray( SHADER_TYPE aShaderType, const char * const * aArray,
bool loadShaderFromStringArray( SHADER_TYPE aShaderType, const char* const* aArray,
size_t aSize );
/**

View File

@ -4,10 +4,6 @@
*
* Copyright (C) 2016 Kicad Developers, see change_log.txt for contributors.
*
* Graphics Abstraction Layer (GAL) for OpenGL
*
* Shader class
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
@ -58,7 +54,8 @@ namespace UTIL {
private:
friend class UTIL::LINK;
struct IMPL {
struct IMPL
{
IMPL( OBSERVABLE_BASE* owned_by = nullptr );
bool is_shared() const;
void set_shared();
@ -126,7 +123,7 @@ namespace UTIL {
//
//
//
template< typename ObserverInterface >
template<typename ObserverInterface>
class OBSERVABLE :
public DETAIL::OBSERVABLE_BASE
{
@ -188,17 +185,21 @@ namespace UTIL {
{
static_assert(sizeof...(Args1) == sizeof...(Args2), "argument counts don't match");
if(impl_) {
if( impl_ )
{
enter_iteration();
try {
for(auto* void_ptr : impl_->observers_) {
if(void_ptr) {
for( auto* void_ptr : impl_->observers_ )
{
if( void_ptr )
{
auto* typed_ptr = static_cast<ObserverInterface*>(void_ptr);
(typed_ptr->*Ptr)(std::forward<Args2>( aArgs )...);
}
}
}
catch(...) {
catch(...)
{
leave_iteration();
throw;
}
@ -220,20 +221,27 @@ namespace UTIL {
{
static_assert(sizeof...(Args1) == sizeof...(Args2), "argument counts don't match");
if(impl_) {
if( impl_ )
{
enter_iteration();
try {
for(auto* void_ptr : impl_->observers_) {
if(void_ptr && void_ptr != aIgnore) {
try
{
for(auto* void_ptr : impl_->observers_)
{
if( void_ptr && void_ptr != aIgnore )
{
auto* typed_ptr = static_cast<ObserverInterface*>(void_ptr);
(typed_ptr->*Ptr)(std::forward<Args2>( aArgs )...);
}
}
}
catch(...) {
catch(...)
{
leave_iteration();
throw;
}
leave_iteration();
}
}

View File

@ -109,22 +109,27 @@ void DIALOG_DISPLAY_OPTIONS::init()
m_OptDisplayDrawings->SetValue( displ_opts->m_DisplayDrawItemsFill == SKETCH );
m_ShowNetNamesOption->SetSelection( displ_opts->m_DisplayNetNamesMode );
switch(gal_opts.gl_antialiasing_mode) {
case KIGFX::OPENGL_ANTIALIASING_MODE::NONE:
m_choiceAntialiasing->Select( 0 );
break;
case KIGFX::OPENGL_ANTIALIASING_MODE::SUBSAMPLE_HIGH:
m_choiceAntialiasing->Select( 1 );
break;
case KIGFX::OPENGL_ANTIALIASING_MODE::SUBSAMPLE_ULTRA:
m_choiceAntialiasing->Select( 2 );
break;
case KIGFX::OPENGL_ANTIALIASING_MODE::SUPERSAMPLING_X2:
m_choiceAntialiasing->Select( 3 );
break;
case KIGFX::OPENGL_ANTIALIASING_MODE::SUPERSAMPLING_X4:
m_choiceAntialiasing->Select( 4 );
break;
switch( gal_opts.gl_antialiasing_mode )
{
case KIGFX::OPENGL_ANTIALIASING_MODE::NONE:
m_choiceAntialiasing->Select( 0 );
break;
case KIGFX::OPENGL_ANTIALIASING_MODE::SUBSAMPLE_HIGH:
m_choiceAntialiasing->Select( 1 );
break;
case KIGFX::OPENGL_ANTIALIASING_MODE::SUBSAMPLE_ULTRA:
m_choiceAntialiasing->Select( 2 );
break;
case KIGFX::OPENGL_ANTIALIASING_MODE::SUPERSAMPLING_X2:
m_choiceAntialiasing->Select( 3 );
break;
case KIGFX::OPENGL_ANTIALIASING_MODE::SUPERSAMPLING_X4:
m_choiceAntialiasing->Select( 4 );
break;
}
}
@ -186,27 +191,27 @@ void DIALOG_DISPLAY_OPTIONS::OnOkClick(wxCommandEvent& event)
displ_opts->m_DisplayDrawItemsFill = not m_OptDisplayDrawings->GetValue();
displ_opts->m_DisplayNetNamesMode = m_ShowNetNamesOption->GetSelection();
switch(m_choiceAntialiasing->GetSelection()) {
case 0:
gal_opts.gl_antialiasing_mode =
KIGFX::OPENGL_ANTIALIASING_MODE::NONE;
break;
case 1:
gal_opts.gl_antialiasing_mode =
KIGFX::OPENGL_ANTIALIASING_MODE::SUBSAMPLE_HIGH;
break;
case 2:
gal_opts.gl_antialiasing_mode =
KIGFX::OPENGL_ANTIALIASING_MODE::SUBSAMPLE_ULTRA;
break;
case 3:
gal_opts.gl_antialiasing_mode =
KIGFX::OPENGL_ANTIALIASING_MODE::SUPERSAMPLING_X2;
break;
case 4:
gal_opts.gl_antialiasing_mode =
KIGFX::OPENGL_ANTIALIASING_MODE::SUPERSAMPLING_X4;
break;
switch( m_choiceAntialiasing->GetSelection() )
{
case 0:
gal_opts.gl_antialiasing_mode = KIGFX::OPENGL_ANTIALIASING_MODE::NONE;
break;
case 1:
gal_opts.gl_antialiasing_mode = KIGFX::OPENGL_ANTIALIASING_MODE::SUBSAMPLE_HIGH;
break;
case 2:
gal_opts.gl_antialiasing_mode = KIGFX::OPENGL_ANTIALIASING_MODE::SUBSAMPLE_ULTRA;
break;
case 3:
gal_opts.gl_antialiasing_mode = KIGFX::OPENGL_ANTIALIASING_MODE::SUPERSAMPLING_X2;
break;
case 4:
gal_opts.gl_antialiasing_mode = KIGFX::OPENGL_ANTIALIASING_MODE::SUPERSAMPLING_X4;
break;
}
gal_opts.NotifyChanged();