// -------------------------------------------------------------------------- // Irrlicht Toon (Cel) Shader Demo // sio2 'at' users.sourceforge.net // -------------------------------------------------------------------------- #include // -------------------------------------------------------------------------- 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(&pos), 3); vector3df lightPosOS; lightPosOS=vector3df(-50,50,-50); //invWorld.transformVect(light1->getPosition(),lightPosOS); services->setVertexShaderConstant("mLightPos", reinterpret_cast(&lightPosOS), 3); //services->setVertexShaderConstant("mLightPos", reinterpret_cast(&pos), 3); // set light color // set clip matrix core::matrix4 worldViewProj; worldViewProj = driver->getTransform(video::ETS_VIEW); services->setVertexShaderConstant("viewm", &worldViewProj.M[0], 16); } }; // OpenGL Vertex Program 1.1 // OpenGL Vertex Program 1.1 const stringc vertToonShader = "uniform vec3 cameraVector;" "uniform mat4x4 viewm;;" "varying vec3 normal;" "varying vec2 tcoords;" "varying float edge;" "void main()" "{" " normal = gl_NormalMatrix * gl_Normal;" " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;" "tcoords = gl_MultiTexCoord0.xy;" "vec3 cameraVectorf = normalize (cameraVector - (gl_ModelViewMatrix * gl_Vertex).xyz);" "edge = max(dot(cameraVectorf, normalize(matm*vec4(gl_Normal,0)) ),0);" "}"; // -------------------------------------------------------------------------- // OpenGL Fragment Program 1.1 const stringc fragToonShader = "varying vec3 normal;" "varying vec2 tcoords;" "varying float 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)*edge;" "}"; // // -------------------------------------------------------------------------- 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; } // --------------------------------------------------------------------------