#include "ToonMaterial.h"
#include <QtCore/QDir>
MB_PLUGIN(
"ToonMaterial",
"Toon material",
"Autodesk",
"http://www.mudbox3d.com", 0 );
static float diffuseRamp(
float x);
static float specularRamp(
float x);
static float edgeRamp(
float x);
static void loadRamp(
GLuint texobj,
int size,
float (*func)(
float x));
ToonMaterial::ToonMaterial( void ) :
m_aKd(this, "Kd"),
m_aKs(this, "Ks"),
m_aShininess(this, "Shiny")
{
SetName( "Toon Material" );
QDir pluginDir(
Kernel()->PluginDirectory(
"ToonMaterial") );
m_VertexProgram =
m_CGContext,
m_VertexProfile,
"main",
NULL);
m_FragmentProgram =
m_CGContext,
m_FragmentProfile,
"main",
NULL);
glGenTextures(1, &m_iDiffuseRamp);
loadRamp(m_iDiffuseRamp, 255, diffuseRamp);
glGenTextures(1, &m_iSpecularRamp);
loadRamp(m_iSpecularRamp, 255, specularRamp);
glGenTextures(1, &m_iEdgeRamp);
loadRamp(m_iEdgeRamp, 255, edgeRamp);
m_aKd = Color(0.8
f, 0.6
f, 0.2
f, 1.0
f);
m_aKs = Color(0.3
f, 0.3
f, 4.0
f, 0.0
f);
m_aShininess.SetMax(25);
m_aShininess.SetMin(1);
m_aShininess = 5.2f;
};
ToonMaterial::~ToonMaterial( void )
{
glDeleteTextures(1, &m_iDiffuseRamp);
glDeleteTextures(1, &m_iSpecularRamp);
glDeleteTextures(1, &m_iEdgeRamp);
};
bool ToonMaterial::Activate( const Mesh *pMesh, const AxisAlignedBoundingBox &cUVArea, const Color &cColor )
{
if (!pMesh)
return false;
if (
Kernel()->Scene()->LightCount())
{
Light *pLight =
Kernel()->Scene()->Light(0);
if (pLight->Type() == Light::LIGHT_POINT)
{
v = pLight->Transformation()->Position();
}
else if (pLight->Type() == Light::LIGHT_DIRECTIONAL)
{
if (pLight->IsLockedToCamera())
v = pLight->LockedToCameraMatrix().Transform(
v);
else
v = pLight->Transformation()->WorldToLocalMatrix().Invert().Transform(
v);
}
}
Matrix mModelViewProj = pMesh->Geometry()->Transformation()->LocalToWorldMatrix()*
Kernel()->Scene()->ActiveCamera()->Matrix(
true);
return true;
};
void ToonMaterial::Deactivate( void )
{
};
void ToonMaterial::OnNodeEvent(
const Attribute &cAttribute,
NodeEventType cType )
{
bool bRedraw = false;
{
if (cAttribute == m_aKs ||
cAttribute == m_aKd ||
cAttribute == m_aShininess)
bRedraw = true;
}
Material::OnNodeEvent( cAttribute, cType );
if (bRedraw)
};
float diffuseRamp(
float x)
{
if (x > 0.5) {
} else {
return 0.5f;
}
}
float specularRamp(float x)
{
} else {
return 0.0f;
}
}
float edgeRamp(float x)
{
return 1.0f;
} else {
return 0.85f;
}
}
void loadRamp(
GLuint texobj,
int size,
float (*func)(
float x))
{
int bytesForRamp = size*sizeof(float);
float *ramp = (float *) malloc(bytesForRamp);
float *slot = ramp;
float dx = 1.0f / (float) size;
int i;
for (i=0, x=0.0, slot=ramp; i<
size; i++, x +=
dx, slot++) {
}
#ifndef GL_CLAMP_TO_EDGE
#define GL_CLAMP_TO_EDGE 0x812F
#endif
glBindTexture(GL_TEXTURE_1D, texobj);
}