#include "SampleViewportFilter.h"
#include <QtCore/QDir>
#define _USE_MATH_DEFINES
#include <cmath>
using namespace mudbox;
IMPLEMENT_VCLASS( SampleViewPortFilter, ViewPortFilter, "Sample Viewport Filter", 1 );
MB_PLUGIN( "Sample Filter", "Sample Viewport Filter", "Autodesk", "http://www.mudbox3d.com", 0 );
static void drawFullScreenQuad() {
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glBegin( GL_QUADS );
glTexCoord2f( 0, 0 );
glVertex2f( -1, -1 );
glTexCoord2f( 1, 0 );
glVertex2f( 1, -1 );
glTexCoord2f( 1, 1 );
glVertex2f( 1, 1 );
glTexCoord2f( 0, 1 );
glVertex2f( -1, 1 );
glEnd();
}
static void gpuTransform(Texture* const outputTexture) {
outputTexture->SetAsRenderTarget();
drawFullScreenQuad();
outputTexture->RestoreRenderTarget();
}
void SampleViewPortFilter::OnNodeEvent( const Attribute &cAttribute, NodeEventType eType ) {
if(eType == etValueChanged) {
{
Kernel()->Redraw();
}
}
}
SampleViewPortFilter::SampleViewPortFilter() :
m_aGaussianBlur(this, "Gaussian"),
m_aBlurWidth(this, "Blur Width")
{
m_CGContext = cgCreateContext();
cgGLSetDebugMode( CG_FALSE );
cgGLSetManageTextureParameters(m_CGContext, CG_TRUE);
cgSetParameterSettingMode(m_CGContext, CG_DEFERRED_PARAMETER_SETTING);
m_FragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
cgGLSetOptimalOptions(m_FragmentProfile);
QDir pluginDir( Kernel()->PluginDirectory("Sample Filter") );
QFileInfo cgPath( pluginDir, QString("Blur.cg") );
QByteArray qbaPath = QFile::encodeName(cgPath.filePath());
m_BlurProgram =
cgCreateProgramFromFile(
m_CGContext,
CG_SOURCE,
qbaPath.constData(),
m_FragmentProfile,
"main",
NULL);
if ( m_BlurProgram == NULL ) Kernel()->HUDMessageShow("Failed to load Blur.cg", Kernel::HUDmsgFade );
cgGLLoadProgram(m_BlurProgram);
m_BlurColorTextureParam = cgGetNamedParameter(m_BlurProgram, "colorTexture");
m_BlurWidthParam = cgGetNamedParameter(m_BlurProgram, "BlurWidth");
m_GaussianBlurParam = cgGetNamedParameter(m_BlurProgram, "GaussianBlur");
m_aGaussianBlur = true;
m_aBlurWidth.SetMax(.0050f);
m_aBlurWidth.SetMin(.0001f);
m_aBlurWidth = 0.0012f;
m_pResultTexture = CreateInstance<Texture>();
}
SampleViewPortFilter::~SampleViewPortFilter()
{
if( m_pResultTexture )
delete m_pResultTexture;
if (m_CGContext)
cgDestroyContext(m_CGContext);
};
void SampleViewPortFilter::Process( ViewPortState &s )
{
enum Image::Format eFormat = s.m_bHDRNeeded ? Image::e16float : Image::e8integer;
const float cameraNear = Kernel()->Scene()->ActiveCamera()->Near();
const float cameraFar = Kernel()->Scene()->ActiveCamera()->Far();
const float cameraFOV = Kernel()->Scene()->ActiveCamera()->FOV();
const float cameraAspectRatio = Kernel()->Scene()->ActiveCamera()->AspectRatio();
const float cameraHeight = tanf(cameraFOV / 2.0f) * cameraNear;
const float cameraWidth = cameraHeight * cameraAspectRatio;
const float cameraTop = -cameraHeight;
const float cameraBottom = cameraHeight;
const float cameraLeft = -cameraWidth;
const float cameraRight = cameraWidth;
const int width = s.m_pColor->Width();
const int height = s.m_pColor->Height();
const int extendMin = width < height ? width : height;
const int levelCountMax = (int)floorf(logf(float(extendMin)) / float(M_LN2));
if( m_pResultTexture->Width() != s.m_pColor->Width() ||
m_pResultTexture->Height() != s.m_pColor->Height())
{
m_pResultTexture->Create(s.m_pColor->Width(), s.m_pColor->Height(), 4, eFormat);
};
m_pResultTexture->SetLocation( TexturePool::locationGPU );
cgGLEnableProfile(m_FragmentProfile);
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glDisable(GL_CULL_FACE);
cgGLBindProgram(m_BlurProgram);
cgGLSetTextureParameter(m_BlurColorTextureParam, s.m_pColor->OpenGLName());
cgSetParameter1f(m_BlurWidthParam, m_aBlurWidth);
cgSetParameter1i(m_GaussianBlurParam, m_aGaussianBlur);
cgUpdateProgramParameters(m_BlurProgram);
gpuTransform(m_pResultTexture);
cgGLDisableProfile(m_FragmentProfile);
s.m_pColor = m_pResultTexture;
};
void SampleViewPortFilter::SetVisible( bool bVisible )
{
ViewPortFilter::SetVisible( bVisible );
if( bVisible )
{
if( !m_pResultTexture )
m_pResultTexture = CreateInstance<Texture>();
}
else
{
delete m_pResultTexture;
m_pResultTexture = 0;
};
};