SampleViewportFilter/SampleViewportFilter.cpp

SampleViewportFilter/SampleViewportFilter.cpp
//**************************************************************************/
// Copyright (c) 2008 Autodesk, Inc.
// All rights reserved.
//
// Use of this software is subject to the terms of the Autodesk license
// agreement provided at the time of installation or download, or which
// otherwise accompanies this software in either electronic or hard copy form.
//
//**************************************************************************/
// DESCRIPTION:
// CREATED: October 2008
//**************************************************************************/
#define _USE_MATH_DEFINES
#include <cmath>
#include "SampleViewportFilter.h"
#include <QtCore/QDir>
using namespace mudbox;
// Filter plugin macros
IMPLEMENT_VCLASS( SampleViewPortFilter, ViewPortFilter, "Sample Viewport Filter", 1 );
MB_PLUGIN( "Sample Filter", "Sample Viewport Filter", "Autodesk", "http://www.mudbox3d.com", 0 );
// Render texture to screen to activate shaders.
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();
}
// Renders full screens quad to texture specified
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")
{
// Cg context
m_CGContext = cgCreateContext();
/* Compile and load the vertex program. */
m_FragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
cgGLSetOptimalOptions(m_FragmentProfile);
// Get the path to where the plug-in was loaded from
QDir pluginDir( Kernel()->PluginDirectory("Sample Filter") );
QFileInfo cgPath( pluginDir, QString("Blur.cg") );
/* Compile and load the fragment program. */
QByteArray qbaPath = QFile::encodeName(cgPath.filePath());
m_BlurProgram =
m_CGContext, /* Cg runtime context */
CG_SOURCE, /* Program in human-readable form */
qbaPath.constData(), /* Name of file containing program */
m_FragmentProfile,/* Profile: OpenGL ARB vertex program */
"main", /* Entry function name */
NULL); /* No extra compiler options */
if ( m_BlurProgram == NULL ) Kernel()->Interface()->HUDMessageShow("Failed to load Blur.cg", mudbox::Interface::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;
// Create the output texture
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;
// Set of variables not actually used for anything other than to show
// how to access the values.
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;
// Ensure our output texture is same size & type as the incoming color buffer.
// Get width and height of the viewport
const int width = s.m_pColor->Width();
const int height = s.m_pColor->Height();
// Smallest of width and height
const int extendMin = width < height ? width : height;
// Logarithm of the SMALLER extend, in order to be at least 1 pixel in size in any dimension
const int levelCountMax = (int)floorf(logf(float(extendMin)) / float(M_LN2));
// See if the input size or format changed. If so, re-create the texture.
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 );
// Enable Cg fragment profile
cgGLEnableProfile(m_FragmentProfile);
// Set up some gl states
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glDisable(GL_CULL_FACE);
cgGLBindProgram(m_BlurProgram);
// Set the incoming color buffer on the shader
cgGLSetTextureParameter(m_BlurColorTextureParam, s.m_pColor->OpenGLName());
// Set blur width value
cgSetParameter1f(m_BlurWidthParam, m_aBlurWidth);
// Set Gaussian usage value
cgSetParameter1i(m_GaussianBlurParam, m_aGaussianBlur);
cgUpdateProgramParameters(m_BlurProgram);
// Render to the resulting texture. This activates the shader pass.
gpuTransform(m_pResultTexture);
cgGLDisableProfile(m_FragmentProfile);
// Assign the resulting texture to the color buffer
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;
};
};