Public feed #600216

Mine

public text v1 · immutable
Raw Edit
·published 2007-07-02 18:12 UTC
rendered paste body
// --------------------------------------------------------------------------
// 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 float edge;"
"void main()"
"{"
"   normal = gl_NormalMatrix * gl_Normal;"
"   gl_Position = gl_ModelViewMatrix * gl_Vertex;"
"tcoords = gl_MultiTexCoord0.xy;"
"vec3 cameraVectorf = normalize (cameraVector - gl_Position.xyz);"
"edge = max(dot(cameraVectorf, normal ),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)*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;
}

// --------------------------------------------------------------------------