|
|
|
@ -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(); |
|
|
|
} |
|
|
|
bool ANTIALIASING_NONE::Init() |
|
|
|
{ |
|
|
|
// Nothing to initialize
|
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
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
|
|
|
|
} |
|
|
|
VECTOR2U ANTIALIASING_NONE::GetInternalBufferSize() |
|
|
|
{ |
|
|
|
return compositor->GetScreenSize(); |
|
|
|
} |
|
|
|
|
|
|
|
void ANTIALIASING_NONE::OnLostBuffers() |
|
|
|
{ |
|
|
|
// Nothing to do
|
|
|
|
} |
|
|
|
|
|
|
|
void ANTIALIASING_NONE::Begin() |
|
|
|
{ |
|
|
|
// Nothing to do
|
|
|
|
} |
|
|
|
void ANTIALIASING_NONE::DrawBuffer( GLuint buffer ) |
|
|
|
{ |
|
|
|
compositor->DrawBuffer( buffer, OPENGL_COMPOSITOR::DIRECT_RENDERING ); |
|
|
|
} |
|
|
|
|
|
|
|
unsigned int ANTIALIASING_NONE::CreateBuffer() |
|
|
|
{ |
|
|
|
return compositor->CreateBuffer( compositor->GetScreenSize() ); |
|
|
|
} |
|
|
|
|
|
|
|
namespace { |
|
|
|
void ANTIALIASING_NONE::Present() |
|
|
|
{ |
|
|
|
// Nothing to present, draw_buffer already drew to the screen
|
|
|
|
} |
|
|
|
|
|
|
|
void draw_fullscreen_primitive() |
|
|
|
{ |
|
|
|
glMatrixMode( GL_MODELVIEW ); |
|
|
|
glPushMatrix(); |
|
|
|
glLoadIdentity(); |
|
|
|
glMatrixMode( GL_PROJECTION ); |
|
|
|
glPushMatrix(); |
|
|
|
glLoadIdentity(); |
|
|
|
|
|
|
|
void ANTIALIASING_NONE::OnLostBuffers() |
|
|
|
{ |
|
|
|
// Nothing to do
|
|
|
|
} |
|
|
|
|
|
|
|
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(); |
|
|
|
void ANTIALIASING_NONE::Begin() |
|
|
|
{ |
|
|
|
// Nothing to do
|
|
|
|
} |
|
|
|
|
|
|
|
glPopMatrix(); |
|
|
|
glMatrixMode( GL_MODELVIEW ); |
|
|
|
glPopMatrix(); |
|
|
|
} |
|
|
|
|
|
|
|
unsigned int ANTIALIASING_NONE::CreateBuffer() |
|
|
|
{ |
|
|
|
return compositor->CreateBuffer( compositor->GetScreenSize() ); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// =========================
|
|
|
|
// ANTIALIASING_SUPERSAMPLING
|
|
|
|
// =========================
|
|
|
|
namespace { |
|
|
|
|
|
|
|
ANTIALIASING_SUPERSAMPLING::ANTIALIASING_SUPERSAMPLING( OPENGL_COMPOSITOR* aCompositor, |
|
|
|
SUPERSAMPLING_MODE aMode ) |
|
|
|
: compositor( aCompositor ), mode( aMode ), areBuffersCreated( false ), |
|
|
|
areShadersCreated( false ) |
|
|
|
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_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" ); |
|
|
|
// =========================
|
|
|
|
// ANTIALIASING_SUPERSAMPLING
|
|
|
|
// =========================
|
|
|
|
|
|
|
|
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" ); |
|
|
|
ANTIALIASING_SUPERSAMPLING::ANTIALIASING_SUPERSAMPLING( OPENGL_COMPOSITOR* aCompositor, |
|
|
|
SUPERSAMPLING_MODE aMode ) |
|
|
|
: compositor( aCompositor ), mode( aMode ), areBuffersCreated( false ), |
|
|
|
areShadersCreated( false ) |
|
|
|
{ |
|
|
|
} |
|
|
|
|
|
|
|
areShadersCreated = true; |
|
|
|
} |
|
|
|
|
|
|
|
if(areShadersCreated && mode != SUPERSAMPLING_MODE::X4) { |
|
|
|
x4_shader.reset(); |
|
|
|
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" ); |
|
|
|
|
|
|
|
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 ); |
|
|
|
GLint source_parameter = x4_shader->AddParameter( "source" ); checkGlError( "getting pass 1 colorTex" ); |
|
|
|
|
|
|
|
areBuffersCreated = true; |
|
|
|
} |
|
|
|
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" ); |
|
|
|
|
|
|
|
return true; |
|
|
|
areShadersCreated = true; |
|
|
|
} |
|
|
|
|
|
|
|
VECTOR2U ANTIALIASING_SUPERSAMPLING::GetInternalBufferSize() |
|
|
|
if( areShadersCreated && mode != SUPERSAMPLING_MODE::X4 ) |
|
|
|
{ |
|
|
|
unsigned int factor = (mode == SUPERSAMPLING_MODE::X2) ? 2 : 4; |
|
|
|
return compositor->GetScreenSize() * factor; |
|
|
|
x4_shader.reset(); |
|
|
|
areShadersCreated = false; |
|
|
|
} |
|
|
|
|
|
|
|
void ANTIALIASING_SUPERSAMPLING::Begin() |
|
|
|
if( !areBuffersCreated ) |
|
|
|
{ |
|
|
|
compositor->SetBuffer( ssaaMainBuffer ); |
|
|
|
compositor->ClearBuffer(); |
|
|
|
} |
|
|
|
ssaaMainBuffer = compositor->CreateBuffer(); |
|
|
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); |
|
|
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); |
|
|
|
|
|
|
|
void ANTIALIASING_SUPERSAMPLING::DrawBuffer( GLuint aBuffer ) |
|
|
|
{ |
|
|
|
compositor->DrawBuffer( aBuffer, ssaaMainBuffer ); |
|
|
|
areBuffersCreated = true; |
|
|
|
} |
|
|
|
|
|
|
|
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" ); |
|
|
|
} |
|
|
|
} |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
void ANTIALIASING_SUPERSAMPLING::OnLostBuffers() |
|
|
|
{ |
|
|
|
areBuffersCreated = false; |
|
|
|
} |
|
|
|
|
|
|
|
unsigned int ANTIALIASING_SUPERSAMPLING::CreateBuffer() |
|
|
|
{ |
|
|
|
return compositor->CreateBuffer( GetInternalBufferSize() ); |
|
|
|
} |
|
|
|
VECTOR2U ANTIALIASING_SUPERSAMPLING::GetInternalBufferSize() |
|
|
|
{ |
|
|
|
unsigned int factor = ( mode == SUPERSAMPLING_MODE::X2 ) ? 2 : 4; |
|
|
|
return compositor->GetScreenSize() * factor; |
|
|
|
} |
|
|
|
|
|
|
|
// ===============================
|
|
|
|
// ANTIALIASING_SMAA
|
|
|
|
// ===============================
|
|
|
|
|
|
|
|
ANTIALIASING_SMAA::ANTIALIASING_SMAA( OPENGL_COMPOSITOR* aCompositor, SMAA_QUALITY aQuality ) |
|
|
|
: compositor( aCompositor ), shadersLoaded( false ), areBuffersInitialized( false ), |
|
|
|
quality( aQuality ) |
|
|
|
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" ); |
|
|
|
} |
|
|
|
|
|
|
|
VECTOR2U ANTIALIASING_SMAA::GetInternalBufferSize() |
|
|
|
draw_fullscreen_primitive(); |
|
|
|
|
|
|
|
if( mode == SUPERSAMPLING_MODE::X4 ) |
|
|
|
{ |
|
|
|
return compositor->GetScreenSize(); |
|
|
|
x4_shader->Deactivate(); |
|
|
|
checkGlError( "deactivating supersampling x4 shader" ); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
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" ); |
|
|
|
void ANTIALIASING_SUPERSAMPLING::OnLostBuffers() |
|
|
|
{ |
|
|
|
areBuffersCreated = false; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
unsigned int ANTIALIASING_SUPERSAMPLING::CreateBuffer() |
|
|
|
{ |
|
|
|
return compositor->CreateBuffer( GetInternalBufferSize() ); |
|
|
|
} |
|
|
|
|
|
|
|
std::string quality_string; |
|
|
|
// ===============================
|
|
|
|
// ANTIALIASING_SMAA
|
|
|
|
// ===============================
|
|
|
|
|
|
|
|
if(quality == SMAA_QUALITY::HIGH) { |
|
|
|
quality_string = "#define SMAA_PRESET_HIGH\n"; |
|
|
|
} |
|
|
|
else { |
|
|
|
quality_string = "#define SMAA_PRESET_ULTRA\n"; |
|
|
|
} |
|
|
|
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(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// set up shaders
|
|
|
|
std::string vert_preamble( R"SHADER( |
|
|
|
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 ); |
|
|
|
|
|
|
|
//
|
|
|
|
// 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" ); |
|
|
|
|
|
|
|
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" ); |
|
|
|
|
|
|
|
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" ); |
|
|
|
|
|
|
|
//
|
|
|
|
// 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" ); |
|
|
|
|
|
|
|
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; |
|
|
|
} |
|
|
|
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" ); |
|
|
|
|
|
|
|
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" ); |
|
|
|
|
|
|
|
//
|
|
|
|
// 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" ); |
|
|
|
|
|
|
|
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(); |
|
|
|
|
|
|
|
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(); |
|
|
|
} |
|
|
|
void ANTIALIASING_SMAA::updateUniforms() |
|
|
|
{ |
|
|
|
auto dims = compositor->GetScreenSize(); |
|
|
|
|
|
|
|
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 ); |
|
|
|
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" ); |
|
|
|
|
|
|
|
smaaEdgesBuffer = compositor->CreateBuffer(); |
|
|
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); |
|
|
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); |
|
|
|
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" ); |
|
|
|
|
|
|
|
smaaBlendBuffer = compositor->CreateBuffer(); |
|
|
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); |
|
|
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); |
|
|
|
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" ); |
|
|
|
} |
|
|
|
|
|
|
|
updateUniforms(); |
|
|
|
areBuffersInitialized = true; |
|
|
|
} |
|
|
|
|
|
|
|
// Nothing to initialize
|
|
|
|
return true; |
|
|
|
} |
|
|
|
bool ANTIALIASING_SMAA::Init() |
|
|
|
{ |
|
|
|
if( !shadersLoaded ) |
|
|
|
loadShaders(); |
|
|
|
|
|
|
|
void ANTIALIASING_SMAA::OnLostBuffers() |
|
|
|
if( !areBuffersInitialized ) |
|
|
|
{ |
|
|
|
areBuffersInitialized = false; |
|
|
|
} |
|
|
|
smaaBaseBuffer = compositor->CreateBuffer(); |
|
|
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); |
|
|
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); |
|
|
|
|
|
|
|
unsigned int ANTIALIASING_SMAA::CreateBuffer() |
|
|
|
{ |
|
|
|
return compositor->CreateBuffer( compositor->GetScreenSize() ); |
|
|
|
} |
|
|
|
smaaEdgesBuffer = compositor->CreateBuffer(); |
|
|
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); |
|
|
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); |
|
|
|
|
|
|
|
void ANTIALIASING_SMAA::DrawBuffer( GLuint buffer ) |
|
|
|
{ |
|
|
|
// draw to internal buffer
|
|
|
|
compositor->DrawBuffer( buffer, smaaBaseBuffer ); |
|
|
|
} |
|
|
|
smaaBlendBuffer = compositor->CreateBuffer(); |
|
|
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); |
|
|
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); |
|
|
|
|
|
|
|
void ANTIALIASING_SMAA::Begin() |
|
|
|
{ |
|
|
|
compositor->SetBuffer( smaaBaseBuffer ); |
|
|
|
compositor->ClearBuffer(); |
|
|
|
updateUniforms(); |
|
|
|
areBuffersInitialized = true; |
|
|
|
} |
|
|
|
|
|
|
|
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(); |
|
|
|
} |
|
|
|
} |
|
|
|
// 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::Present() |
|
|
|
|
|
|
|
void ANTIALIASING_SMAA::Begin() |
|
|
|
{ |
|
|
|
compositor->SetBuffer( smaaBaseBuffer ); |
|
|
|
compositor->ClearBuffer(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
namespace { |
|
|
|
void draw_fullscreen_triangle() |
|
|
|
{ |
|
|
|
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(); |
|
|
|
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(); |
|
|
|
} |