/* ----------------------------------------------------------------------------- This source file is part of OGRE (Object-oriented Graphics Rendering Engine) For the latest info, see http://www.ogre3d.org/ Copyright (c) 2000-2005 The OGRE Team Also see acknowledgements in Readme.html You may use this sample code for anything you like, it is not covered by the LGPL like the rest of the engine. ----------------------------------------------------------------------------- */ /* ----------------------------------------------------------------------------- Filename: CelShading.cpp Description: Demo of cel-shaded graphics using vertex & fragment programs ----------------------------------------------------------------------------- */ #include "ExampleApplication.h" SceneNode* rotNode; // Listener class for frame updates class CelShadingListener : public ExampleFrameListener { protected: public: CelShadingListener(RenderWindow* win, Camera* cam) : ExampleFrameListener(win, cam) { } bool frameStarted(const FrameEvent& evt) { rotNode->yaw(Degree(evt.timeSinceLastFrame * 30)); // Call superclass return ExampleFrameListener::frameStarted(evt); } }; // Custom parameter bindings #define CUSTOM_SHININESS 1 #define CUSTOM_DIFFUSE 2 #define CUSTOM_SPECULAR 3 class CelShadingApplication : public ExampleApplication { public: CelShadingApplication() { } ~CelShadingApplication() { } protected: void createFrameListener(void) { // This is where we instantiate our own frame listener mFrameListener= new CelShadingListener(mWindow, mCamera); mRoot->addFrameListener(mFrameListener); } // Just override the mandatory create scene method void createScene(void) { // Check capabilities const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities(); if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !(caps->hasCapability(RSC_FRAGMENT_PROGRAM))) { OGRE_EXCEPT(1, "Your card does not support vertex and fragment programs (or you selected D3D7), so cannot " "run this demo. Sorry!", "CelShading::createScene"); } // Create a point light Light* l = mSceneMgr->createLight("MainLight"); // Accept default settings: point light, white diffuse, just set position // Add light to the scene node rotNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); rotNode->createChildSceneNode(Vector3(20,40,50))->attachObject(l); Entity *ent = mSceneMgr->createEntity("head", "ogrehead.mesh"); mCamera->setPosition(20, 0, 100); mCamera->lookAt(0,0,0); // Set common material, but define custom parameters to change colours // See Example-Advanced.material for how these are finally bound to GPU parameters SubEntity* sub; // eyes sub = ent->getSubEntity(0); sub->setMaterialName("Examples/CelShading"); sub->setCustomParameter(CUSTOM_SHININESS, Vector4(35.0f, 0.0f, 0.0f, 0.0f)); sub->setCustomParameter(CUSTOM_DIFFUSE, Vector4(1.0f, 0.3f, 0.3f, 1.0f)); sub->setCustomParameter(CUSTOM_SPECULAR, Vector4(1.0f, 0.6f, 0.6f, 1.0f)); // skin sub = ent->getSubEntity(1); sub->setMaterialName("Examples/CelShading"); sub->setCustomParameter(CUSTOM_SHININESS, Vector4(10.0f, 0.0f, 0.0f, 0.0f)); sub->setCustomParameter(CUSTOM_DIFFUSE, Vector4(0.0f, 0.5f, 0.0f, 1.0f)); sub->setCustomParameter(CUSTOM_SPECULAR, Vector4(0.3f, 0.5f, 0.3f, 1.0f)); // earring sub = ent->getSubEntity(2); sub->setMaterialName("Examples/CelShading"); sub->setCustomParameter(CUSTOM_SHININESS, Vector4(25.0f, 0.0f, 0.0f, 0.0f)); sub->setCustomParameter(CUSTOM_DIFFUSE, Vector4(1.0f, 1.0f, 0.0f, 1.0f)); sub->setCustomParameter(CUSTOM_SPECULAR, Vector4(1.0f, 1.0f, 0.7f, 1.0f)); // teeth sub = ent->getSubEntity(3); sub->setMaterialName("Examples/CelShading"); sub->setCustomParameter(CUSTOM_SHININESS, Vector4(20.0f, 0.0f, 0.0f, 0.0f)); sub->setCustomParameter(CUSTOM_DIFFUSE, Vector4(1.0f, 1.0f, 0.7f, 1.0f)); sub->setCustomParameter(CUSTOM_SPECULAR, Vector4(1.0f, 1.0f, 1.0f, 1.0f)); // Add entity to the root scene node mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); mWindow->getViewport(0)->setBackgroundColour(ColourValue::White); } }; #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 #define WIN32_LEAN_AND_MEAN #include "windows.h" #endif #ifdef __cplusplus extern "C" { #endif #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT ) #else int main(int argc, char **argv) #endif { // Create application object CelShadingApplication app; try { app.go(); } catch( Exception& e ) { #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL); #else std::cerr << "An exception has occured: " << e.getFullDescription(); #endif } return 0; } #ifdef __cplusplus } #endif