Public feed
#600200
// --------------------------------------------------------------------------
// Irrlicht Toon (Cel) Shader Demo
// sio2 'at' users.sourceforge.net
// --------------------------------------------------------------------------
#include <irrlicht.h>
// --------------------------------------------------------------------------
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
// --------------------------------------------------------------------------
#pragma comment(lib, "Irrlicht.lib")
// --------------------------------------------------------------------------
IrrlichtDevice *device;
class MyShaderCallBack : public video::IShaderConstantSetCallBack
{
public:
virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
{
video::IVideoDriver* driver = services->getVideoDriver();
// set inverted world matrix
// if we are using highlevel shaders (the user can select this when
// starting the program), we must set the constants by name.
core::vector3df pos = device->getSceneManager()->
getActiveCamera()->getAbsolutePosition();
services->setVertexShaderConstant("cameraVector", reinterpret_cast<f32*>(&pos), 3);
vector3df lightPosOS;
lightPosOS=vector3df(-50,50,-50);
//invWorld.transformVect(light1->getPosition(),lightPosOS);
services->setVertexShaderConstant("mLightPos", reinterpret_cast<f32*>(&lightPosOS), 3);
//services->setVertexShaderConstant("mLightPos", reinterpret_cast<f32*>(&pos), 3);
// set light color
}
};
// OpenGL Vertex Program 1.1
// OpenGL Vertex Program 1.1
const stringc vertToonShader =
"uniform vec3 cameraVector;"
"varying vec3 normal;"
"varying vec2 tcoords;"
"varying vec3 edge;"
"void main()"
"{"
" normal = gl_NormalMatrix * gl_Normal;"
" gl_Position = gl_ModelViewMatrix * gl_Vertex;;"
"tcoords = gl_MultiTexCoord0.xy;"
"vec3 cameraVector = normalize (cpos - gl_Position.xyz);"
"edge = max(dot(cameraVector,n),0);"
"}";
// --------------------------------------------------------------------------
// OpenGL Fragment Program 1.1
const stringc fragToonShader =
"varying vec3 normal;"
"varying vec2 tcoords;"
"varying vec3 edge;"
"uniform sampler2D texture;"
"void main()"
"{"
" float intensity;"
" vec4 color;"
" vec3 n = normalize(normal);"
""
" intensity = dot(vec3(gl_LightSource[0].position),n);"
""
" if (intensity > 0.95)"
" color = vec4(1.0,1.0,1.0,1.0);"
" else if (intensity > 0.5)"
" color = vec4(0.8,0.8,0.8,1.0);"
" else if (intensity > 0.25)"
" color = vec4(0.6,0.6,0.6,1.0);"
" else"
" color = vec4(0.4,0.4,0.4,1.0);"
""
" gl_FragColor = color * texture2D(texture,tcoords)*max(edge,0.2);"
"}";
//
// --------------------------------------------------------------------------
int main()
{
// Create device
video::E_DRIVER_TYPE driverType = video::EDT_OPENGL;
device = createDevice(driverType, dimension2di(800, 600), 32, false, false, false, 0);
if (!device) {
printf("Error creating Irrlicht device\n");
return 0;
}
MyShaderCallBack* mc = new MyShaderCallBack();
// Obtain device internals
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
gui::IGUIEnvironment* gui = device->getGUIEnvironment();
// Set a window caption
device->setWindowCaption(L"ToonShader - Irrlicht Engine Demo");
// Create GLSL shaders
video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
s32 mtlToonShader = video::EMT_SOLID; // Fallback material type
bool bCanDoGLSL_1_1 = false;
if (gpu && (driverType == video::EDT_OPENGL)) {
bCanDoGLSL_1_1 = true; // provisionally accept
if (!driver->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1)) {
printf("queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1) failed\n");
bCanDoGLSL_1_1 = false;
}
if (!driver->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1)) {
printf("queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1) failed\n");
bCanDoGLSL_1_1 = false;
}
}
if (bCanDoGLSL_1_1) {
// Shader uses built-in OpenGL GLSL uniforms, hence needs no explicit constants.
// Therefore a callback function is not needed and is NULL.
mtlToonShader = gpu->addHighLevelShaderMaterial(
vertToonShader.c_str(), "main", video::EVST_VS_1_1,
fragToonShader.c_str(), "main", video::EPST_PS_1_1,
mc, video::EMT_SOLID);
} else {
// This demo is for OpenGL!
printf("This demo requires OpenGL with GLSL High-Level shaders\n");
mtlToonShader = video::EMT_SOLID;
}
// setting up light ( i need ambient white light ( it is ordinal ) )
ILightSceneNode* light = smgr->addLightSceneNode( 0, vector3df(-50.0f,50.0f,-50.0f), SColorf(1.0f,1.0f,1.0f,1.0f), 500.0f );
// Add an animated mesh
//IAnimatedMesh* mesh = smgr->getMesh("./media/chr.ms3d");
IAnimatedMesh* mesh = smgr->getMesh("./media/mesh1.x");
IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh );
if (node)
{
node->setMaterialFlag(EMF_LIGHTING, false);
//node->setMD2Animation ( scene::EMAT_STAND );
//node->setMaterialTexture(0, driver->getTexture("./media/0161.bmp") );
node->setScale (vector3df(10,10,10));
node->setMaterialType((video::E_MATERIAL_TYPE)mtlToonShader); // Override material type
smgr->addTextSceneNode(gui->getBuiltInFont(),
L"Toon Shading",
video::SColor(255,255,255,255), node);
}
IAnimatedMesh* mesh3 = smgr->getMesh("./media/mesh1.x");
IAnimatedMeshSceneNode* node3 = smgr->addAnimatedMeshSceneNode( mesh3 );
if (node3)
{
node3->setScale (vector3df(10,10,10));
node3->setMaterialFlag(EMF_LIGHTING, false);
node3->setPosition (core::vector3df(60,0,0));
smgr->addTextSceneNode(gui->getBuiltInFont(),
L"None and No Light",
video::SColor(255,255,255,255), node3);
}
// Add a viewing camera
//smgr->addCameraSceneNode(0, vector3df(0,50,-80), vector3df(0,5,0));
scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS(0, 100.0f, 100.0f);
// Main rendering loop
while(device->run())
{
driver->beginScene(true, true, SColor(255,100,101,140));
smgr->drawAll();
driver->endScene();
}
device->drop();
// Done
return 0;
}
// --------------------------------------------------------------------------