首页 > 代码库 > HiCelShading

HiCelShading

  • Media

cel_shading_diffuse.png,cel_shading_edge.png,cel_shading_specular.png,

HiCelShading.material,HiCelShading.cg,ogrehead.mesh

  • HiCelShading.material
  • // -------------------------------// Cel Shading Section// -------------------------------vertex_program Ogre/CelShadingVPCg cg{    source HiCelShading.cg    entry_point main_vp    profiles vs_4_0 vs_1_1 arbvp1    default_params    {        param_named_auto lightPosition light_position_object_space 0        param_named_auto eyePosition camera_position_object_space        param_named_auto worldViewProj worldviewproj_matrix        param_named shininess float 10     }}fragment_program Ogre/CelShadingFPCg cg{    source HiCelShading.cg    entry_point main_fp    profiles ps_4_0 ps_1_1 arbfp1 fp20}material Examples/CelShading{    technique    {        pass        {            vertex_program_ref Ogre/CelShadingVPCg            {                // map shininess from custom renderable param 1                param_named_auto shininess custom 1            }            fragment_program_ref Ogre/CelShadingFPCg            {                // map diffuse from custom renderable param 2                param_named_auto diffuse custom 2                // map specular from custom renderable param 3                param_named_auto specular custom 3            }            texture_unit            {                texture cel_shading_diffuse.png 1d                tex_address_mode clamp                filtering none            }            texture_unit            {                texture cel_shading_specular.png 1d                tex_address_mode clamp                filtering none            }            texture_unit            {                texture cel_shading_edge.png 1d                tex_address_mode clamp                filtering none            }        }    }}

     

  • HiCelShading.cg
  • /* Cel shading vertex program for single-pass rendering   In this program, we want to calculate the diffuse and specular   ramp components, and the edge factor (for doing simple outlining)   For the outlining to look good, we need a pretty well curved model.*/void main_vp(float4 position    : POSITION,             float3 normal        : NORMAL,             // outputs             out float4 oPosition : POSITION,             out float  diffuse         : TEXCOORD0,             out float  specular     : TEXCOORD1,             out float  edge         : TEXCOORD2,             // parameters             uniform float3 lightPosition, // object space             uniform float3 eyePosition,   // object space             uniform float4  shininess,             uniform float4x4 worldViewProj){    // calculate output position    oPosition = mul(worldViewProj, position);    // calculate light vector    float3 N = normalize(normal);    float3 L = normalize(lightPosition - position.xyz);        // Calculate diffuse component    diffuse = max(dot(N, L) , 0);    // Calculate specular component    float3 E = normalize(eyePosition - position.xyz);    float3 H = normalize(L + E);    specular = pow(max(dot(N, H), 0), shininess);    // Mask off specular if diffuse is 0    if (diffuse == 0) specular = 0;    // Edge detection, dot eye and normal vectors    edge = max(dot(N, E), 0);}void main_fp( float4 position    : POSITION,       float diffuseIn     : TEXCOORD0,             float specularIn    : TEXCOORD1,             float edge        : TEXCOORD2,                          out float4 colour    : COLOR,                          uniform float4 diffuse,             uniform float4 specular,                          uniform sampler1D diffuseRamp,             uniform sampler1D specularRamp,             uniform sampler1D edgeRamp){    // Step functions from textures    diffuseIn = tex1D(diffuseRamp, diffuseIn).x;    specularIn = tex1D(specularRamp, specularIn).x;    edge = tex1D(edgeRamp, edge).x;    colour = edge * ((diffuse * diffuseIn) +                     (specular * specularIn));}

     

  • Graphics.h
  • /***************************************************    ©2014 Pf_D. All rights reserved.***************************************************/#pragma once#include "OGRE\Ogre.h"#include "OIS\OIS.h"      enum CameraStyle{    CS_FREELOOK,    CS_ORBIT,    CS_MANUAL};      class cCameraManager{private:    Ogre::Camera *mCamera;    CameraStyle mStyle;    Ogre::SceneNode *mTarget;    bool mOrbiting;    bool mZooming;    Ogre::Real mTopSpeed;    Ogre::Vector3 mVelocity;    bool mGoingForward;    bool mGoingBack;    bool mGoingLeft;    bool mGoingRight;    bool mGoingUp;    bool mGoingDown;    bool mFastMove;      public:    cCameraManager(Ogre::Camera *cam);          void setCamera(Ogre::Camera *cam);    Ogre::Camera *getCamera();          void manualStop();          void setStyle(CameraStyle style);    CameraStyle getStyle();          void setYawPitchDist(Ogre::Radian yaw, Ogre::Radian pitch, Ogre::Real dist);          void setTarget(Ogre::SceneNode *target);    Ogre::SceneNode *getTarget();          void setTopSpeed(Ogre::Real topSpeed);    Ogre::Real getTopSpeed();          bool frameRenderingQueued(const Ogre::FrameEvent& evt);          // Processes key press for free-look style movement.    void injectKeyDown(const OIS::KeyEvent &evt);    void injectKeyUp(const OIS::KeyEvent &evt);          // Processes mouse movement differently for each style.    void injectMouseMove(const OIS::MouseEvent &evt);          // Processes mouse presses. Only applies for orbit style.    // Left button is for orbiting, and right button is for zooming.    void injectMouseDown(const OIS::MouseEvent &evt, OIS::MouseButtonID id);    void injectMouseUp(const OIS::MouseEvent &evt, OIS::MouseButtonID id);};

      

  • Graphics.cpp
  • /***************************************************    ©2014 Pf_D. All rights reserved.***************************************************/#include "Graphics.h"      cCameraManager::cCameraManager(Ogre::Camera *cam)    :mCamera(0),    mStyle(CameraStyle::CS_FREELOOK),    mTarget(0),    mOrbiting(false),    mZooming(false),    mTopSpeed(150),    mVelocity(Ogre::Vector3::ZERO),    mGoingForward(false),    mGoingBack(false),    mGoingLeft(false),    mGoingRight(false),    mGoingUp(false),    mGoingDown(false),    mFastMove(false){    setCamera(cam);    setStyle(CS_FREELOOK);}      void cCameraManager::setCamera(Ogre::Camera *cam){    mCamera = cam;}      Ogre::Camera *cCameraManager::getCamera(){    return mCamera;}      void cCameraManager::setYawPitchDist(Ogre::Radian yaw, Ogre::Radian pitch, Ogre::Real dist){    mCamera->setPosition(mTarget->_getDerivedPosition());    mCamera->setOrientation(mTarget->_getDerivedOrientation());    mCamera->yaw(yaw);    mCamera->pitch(pitch);    mCamera->moveRelative(Ogre::Vector3(0, 0, dist));}      void cCameraManager::setTarget(Ogre::SceneNode *target){    if(target != mTarget)    {        mTarget = target;        if(target)        {            setYawPitchDist(Ogre::Degree(0), Ogre::Degree(15), 150);            mCamera->setAutoTracking(true, mTarget);        }        else            mCamera->setAutoTracking(false);    }}          Ogre::SceneNode *cCameraManager::getTarget(){    return mTarget;}      void cCameraManager::manualStop(){    if(mStyle == CS_FREELOOK)    {        mVelocity = Ogre::Vector3::ZERO;        mGoingForward = false;        mGoingBack = false;        mGoingLeft = false;        mGoingRight = false;        mGoingUp = false;        mGoingDown = false;    }}      void cCameraManager::setStyle(CameraStyle style){    if(mStyle != CS_ORBIT && style == CS_ORBIT)    {        setTarget(mTarget ? mTarget : mCamera->getSceneManager()->getRootSceneNode());        mCamera->setFixedYawAxis(true);        manualStop();        setYawPitchDist(Ogre::Degree(0), Ogre::Degree(15), 150);    }    else if(mStyle != CS_FREELOOK && style == CS_FREELOOK)    {        mCamera->setAutoTracking(false);        mCamera->setFixedYawAxis(true);    }    else if(mStyle != CS_MANUAL && style == CS_MANUAL)    {        mCamera->setAutoTracking(false);        manualStop();    }    mStyle = style;}      CameraStyle cCameraManager::getStyle(){    return mStyle;}      void cCameraManager::setTopSpeed(Ogre::Real topSpeed){    mTopSpeed = topSpeed;}      Ogre::Real cCameraManager::getTopSpeed(){    return mTopSpeed;}      bool cCameraManager::frameRenderingQueued(const Ogre::FrameEvent& evt){    if (mStyle == CS_FREELOOK)    {        // build our acceleration vector based on keyboard input composite        Ogre::Vector3 accel = Ogre::Vector3::ZERO;        if (mGoingForward) accel += mCamera->getDirection();        if (mGoingBack) accel -= mCamera->getDirection();        if (mGoingRight) accel += mCamera->getRight();        if (mGoingLeft) accel -= mCamera->getRight();        if (mGoingUp) accel += mCamera->getUp();        if (mGoingDown) accel -= mCamera->getUp();              // if accelerating, try to reach top speed in a certain time        Ogre::Real topSpeed = mFastMove ? mTopSpeed * 20 : mTopSpeed;        if (accel.squaredLength() != 0)        {            accel.normalise();            mVelocity += accel * topSpeed * evt.timeSinceLastFrame * 10;        }        // if not accelerating, try to stop in a certain time        else mVelocity -= mVelocity * evt.timeSinceLastFrame * 10;              Ogre::Real tooSmall = std::numeric_limits<Ogre::Real>::epsilon();              // keep camera velocity below top speed and above epsilon        if (mVelocity.squaredLength() > topSpeed * topSpeed)        {            mVelocity.normalise();            mVelocity *= topSpeed;        }        else if (mVelocity.squaredLength() < tooSmall * tooSmall)            mVelocity = Ogre::Vector3::ZERO;              if (mVelocity != Ogre::Vector3::ZERO) mCamera->move(mVelocity * evt.timeSinceLastFrame);    }          return true;}      void cCameraManager::injectKeyDown(const OIS::KeyEvent &evt){    if(mStyle != CS_FREELOOK)        return;    if (evt.key == OIS::KC_W || evt.key == OIS::KC_UP) mGoingForward = true;    else if (evt.key == OIS::KC_S || evt.key == OIS::KC_DOWN) mGoingBack = true;    else if (evt.key == OIS::KC_A || evt.key == OIS::KC_LEFT) mGoingLeft = true;    else if (evt.key == OIS::KC_D || evt.key == OIS::KC_RIGHT) mGoingRight = true;    else if (evt.key == OIS::KC_PGUP) mGoingUp = true;    else if (evt.key == OIS::KC_PGDOWN) mGoingDown = true;    else if (evt.key == OIS::KC_LSHIFT) mFastMove = true;}      void cCameraManager::injectKeyUp(const OIS::KeyEvent &evt){    if(mStyle != CS_FREELOOK)        return;    if (evt.key == OIS::KC_W || evt.key == OIS::KC_UP) mGoingForward = false;    else if (evt.key == OIS::KC_S || evt.key == OIS::KC_DOWN) mGoingBack = false;    else if (evt.key == OIS::KC_A || evt.key == OIS::KC_LEFT) mGoingLeft = false;    else if (evt.key == OIS::KC_D || evt.key == OIS::KC_RIGHT) mGoingRight = false;    else if (evt.key == OIS::KC_PGUP) mGoingUp = false;    else if (evt.key == OIS::KC_PGDOWN) mGoingDown = false;    else if (evt.key == OIS::KC_LSHIFT) mFastMove = false;}      void cCameraManager::injectMouseMove(const OIS::MouseEvent &evt){    if (mStyle == CS_ORBIT)    {        Ogre::Real dist = (mCamera->getPosition() - mTarget->_getDerivedPosition()).length();              if (mOrbiting)   // yaw around the target, and pitch locally        {            mCamera->setPosition(mTarget->_getDerivedPosition());                  mCamera->yaw(Ogre::Degree(-evt.state.X.rel * 0.25f));            mCamera->pitch(Ogre::Degree(-evt.state.Y.rel * 0.25f));                  mCamera->moveRelative(Ogre::Vector3(0, 0, dist));                  // don‘t let the camera go over the top or around the bottom of the target        }        else if (mZooming)  // move the camera toward or away from the target        {            // the further the camera is, the faster it moves            mCamera->moveRelative(Ogre::Vector3(0, 0, evt.state.Y.rel * 0.004f * dist));        }        else if (evt.state.Z.rel != 0)  // move the camera toward or away from the target        {            // the further the camera is, the faster it moves            mCamera->moveRelative(Ogre::Vector3(0, 0, -evt.state.Z.rel * 0.0008f * dist));        }    }    else if (mStyle == CS_FREELOOK)    {        mCamera->yaw(Ogre::Degree(-evt.state.X.rel * 0.15f));        mCamera->pitch(Ogre::Degree(-evt.state.Y.rel * 0.15f));    }}      void cCameraManager::injectMouseDown(const OIS::MouseEvent &evt, OIS::MouseButtonID id){    if (mStyle == CS_ORBIT)    {        if (id == OIS::MB_Left) mOrbiting = true;        else if (id == OIS::MB_Right) mZooming = true;    }}      void cCameraManager::injectMouseUp(const OIS::MouseEvent &evt, OIS::MouseButtonID id){    if (mStyle == CS_ORBIT)    {        if (id == OIS::MB_Left) mOrbiting = false;        else if (id == OIS::MB_Right) mZooming = false;    }}

      

  • System.h
  • /***************************************************    ©2014 Pf_D. All rights reserved.***************************************************/#pragma once#include "Graphics.h"#include "OGRE\Ogre.h"#include "OIS\OIS.h"#include "MyGUI.h"#include "MyGUI_OgrePlatform.h"    class cApplication : public Ogre::FrameListener, public OIS::KeyListener, public OIS::MouseListener{protected:    MyGUI::Gui          *mGUI;    MyGUI::OgrePlatform *mPlatform;           Ogre::Root          *mRoot;    Ogre::RenderWindow  *mWindow;    Ogre::SceneManager  *mSceneMgr;    Ogre::Camera        *mCamera;	Ogre::Viewport		*mVp;        cCameraManager      *mCameraMgr;    OIS::InputManager   *mInputMgr;    OIS::Keyboard       *mKeyboard;    OIS::Mouse          *mMouse;    bool mDragLook;   public:    cApplication()        :mDragLook(false)    {    }      virtual bool frameStarted(const Ogre::FrameEvent &evt);    virtual bool frameRenderingQueued(const Ogre::FrameEvent &evt);    virtual bool frameEnded(const Ogre::FrameEvent &evt);          virtual bool keyPressed(const OIS::KeyEvent &arg);    virtual bool keyReleased(const OIS::KeyEvent &arg);           virtual bool mouseMoved(const OIS::MouseEvent &arg);    virtual bool mousePressed(const OIS::MouseEvent &arg, OIS::MouseButtonID id);    virtual bool mouseReleased(const OIS::MouseEvent &arg, OIS::MouseButtonID id);        virtual void setupResources();    virtual void createInput();    virtual void chooseSceneMgr();    virtual void setupView();    virtual void loadResources();    virtual void createScene() {}          bool setup();    void go();        void setDragLook(bool enabled);};

      

  • System.cpp
  • /***************************************************    ©2014 Pf_D. All rights reserved.***************************************************/#include "System.h"    bool cApplication::frameStarted(const Ogre::FrameEvent &evt){    mKeyboard->capture();    mMouse->capture();    return true;}      bool cApplication::frameRenderingQueued(const Ogre::FrameEvent &evt){    mCameraMgr->frameRenderingQueued(evt);    return true;}      bool cApplication::frameEnded(const Ogre::FrameEvent &evt){    return true;}     bool cApplication::keyPressed(const OIS::KeyEvent &arg){    if(arg.key == OIS::KC_ESCAPE)        exit(0);    MyGUI::InputManager::getInstance().injectKeyPress(        MyGUI::KeyCode::Enum(arg.key), arg.text);    mCameraMgr->injectKeyDown(arg);    // ...    return true;}      bool cApplication::keyReleased(const OIS::KeyEvent &arg){    MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(arg.key));    mCameraMgr->injectKeyUp(arg);    // ...    return true;}      bool cApplication::mouseMoved( const OIS::MouseEvent &arg ){    bool ret = MyGUI::InputManager::getInstance().injectMouseMove(        arg.state.X.abs, arg.state.Y.abs, arg.state.Z.abs);    if(!ret)        mCameraMgr->injectMouseMove(arg);    // ...    return true;}      bool cApplication::mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id ){    bool ret = MyGUI::InputManager::getInstance().injectMousePress(        arg.state.X.abs, arg.state.Y.abs, MyGUI::MouseButton::Enum(id));    if(!ret)        mCameraMgr->injectMouseDown(arg, id);    if(mDragLook && id == OIS::MB_Left)     {        mCameraMgr->setStyle(CS_FREELOOK);        MyGUI::Gui::getInstance().hidePointer();    }    // ...    return true;}      bool cApplication::mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id ){    bool ret = MyGUI::InputManager::getInstance().injectMouseRelease(        arg.state.X.abs, arg.state.Y.abs, MyGUI::MouseButton::Enum(id));    if(!ret)        mCameraMgr->injectMouseUp(arg, id);    if(mDragLook && id == OIS::MB_Left)     {        mCameraMgr->setStyle(CS_MANUAL);        MyGUI::Gui::getInstance().showPointer();    }    // ...    return true;}     void cApplication::setupResources(){    Ogre::ConfigFile cf;#if OGRE_DEBUG_MODE    cf.load("resources_d.cfg");#else    cf.load("resources.cfg");#endif    Ogre::ConfigFile::SectionIterator secIter = cf.getSectionIterator();    Ogre::String secName, typeName, archName;    while(secIter.hasMoreElements())    {        secName = secIter.peekNextKey();        Ogre::ConfigFile::SettingsMultiMap *settings = secIter.getNext();        Ogre::ConfigFile::SettingsMultiMap::iterator i;        for(i=settings->begin(); i!=settings->end(); i++)        {            typeName = i->first;            archName = i->second;            Ogre::ResourceGroupManager::getSingleton().addResourceLocation(                archName, typeName, secName);        }    }}     void cApplication::createInput(){    OIS::ParamList parameters;    unsigned int windowHandle = 0;    std::ostringstream windowHandleString;    mWindow->getCustomAttribute("WINDOW", &windowHandle);    windowHandleString << windowHandle;    parameters.insert(std::make_pair("WINDOW", windowHandleString.str()));    parameters.insert(std::make_pair("w32_mouse", std::string("DISCL_FOREGROUND")));    parameters.insert(std::make_pair("w32_mouse", std::string("DISCL_NONEXCLUSIVE")));    mInputMgr = OIS::InputManager::createInputSystem(parameters);    mKeyboard = static_cast<OIS::Keyboard*>(mInputMgr->createInputObject(OIS::OISKeyboard, true));    mKeyboard->setEventCallback(this);    mMouse = static_cast<OIS::Mouse*>(mInputMgr->createInputObject(OIS::OISMouse, true));    const OIS::MouseState &mouseState = mMouse->getMouseState();    mouseState.width = mWindow->getWidth();    mouseState.height = mWindow->getHeight();    mMouse->setEventCallback(this);}    void cApplication::chooseSceneMgr(){    mSceneMgr = mRoot->createSceneManager(Ogre::ST_GENERIC);}     void cApplication::setupView(){    // Create camera    mCamera = mSceneMgr->createCamera("Camera");    mCamera->setPosition(Ogre::Vector3(0, 0, 50));    mCamera->lookAt(Ogre::Vector3(0, 0, -300));    mCamera->setNearClipDistance(5);    mCameraMgr = new cCameraManager(mCamera);    // Create viewports    mVp = mWindow->addViewport(mCamera);    mVp->setBackgroundColour(Ogre::ColourValue(0, 0, 0));    mCamera->setAspectRatio(Ogre::Real(mVp->getActualWidth())/Ogre::Real(mVp->getActualHeight()));}     void cApplication::loadResources(){    Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();}     bool cApplication::setup(){#ifndef OGRE_STATIC_LIB#if OGRE_DEBUG_MODE    mRoot = OGRE_NEW Ogre::Root("plugins_d.cfg");#else    mRoot = OGRE_NEW Ogre::Root("plugins.cfg");#endif#endif    setupResources();    if(!mRoot->showConfigDialog())        return false;    mWindow = mRoot->initialise(true);    createInput();    ShowCursor(false);    chooseSceneMgr();    setupView();    loadResources();    createScene();    mRoot->addFrameListener(this);    return true;}      void cApplication::go(){    if(!setup())        return;    mRoot->startRendering();}    void cApplication::setDragLook(bool enabled){    if(enabled)    {        mCameraMgr->setStyle(CS_MANUAL);        mDragLook = true;    }    else    {        mCameraMgr->setStyle(CS_FREELOOK);        mDragLook = false;    }}

      

  • Main.cpp
  • /***************************************************    ©2014 Pf_D. All rights reserved.***************************************************/#include "System.h"class cMyApplication : public cApplication{private:	MyGUI::ButtonPtr mMoveLight;	Ogre::SceneNode *mLightPivot;public:	enum ShaderParam { SP_SHININESS = 1, SP_DIFFUSE, SP_SPECULAR };	bool frameRenderingQueued(const Ogre::FrameEvent &evt)	{		if(mMoveLight->getStateSelected())			mLightPivot->yaw(Ogre::Degree(evt.timeSinceLastFrame*30));		return cApplication::frameRenderingQueued(evt);	}	void notifyMoveLightClick(MyGUI::WidgetPtr sender)	{		MyGUI::ButtonPtr moveLight = 			sender->castType<MyGUI::Button>(false);		bool isSelected = moveLight->getStateSelected();		moveLight->setStateSelected(!isSelected);	}    void createScene()    {        // MyGUI        mPlatform = new MyGUI::OgrePlatform();        mPlatform->initialise(mWindow, mSceneMgr);        mGUI = new MyGUI::Gui();        mGUI->initialise();		mMoveLight = MyGUI::Gui::getInstance().createWidget<MyGUI::Button>(			"CheckBox", MyGUI::IntCoord(15, 15, 100, 20), MyGUI::Align::Default, "Main", "MoveLight");		mMoveLight->setStateSelected(true);		mMoveLight->setCaption("MoveLight");		mMoveLight->setTextColour(MyGUI::Colour(1.0f, 1.0f, 1.0f));		mMoveLight->eventMouseButtonClick += MyGUI::newDelegate(this, &cMyApplication::notifyMoveLightClick);        // mSceneMgr->setAmbientLight(Ogre::ColourValue::White);		setDragLook(true);		Ogre::Light *light = mSceneMgr->createLight();		light->setPosition(20, 40, 50);		mLightPivot = mSceneMgr->getRootSceneNode()->createChildSceneNode();		mLightPivot->attachObject(light);		Ogre::Entity *ent = mSceneMgr->createEntity("Head", "ogrehead.mesh");		ent->setMaterialName("Examples/CelShading");		mSceneMgr->getRootSceneNode()->attachObject(ent);		Ogre::SubEntity *sub;		sub = ent->getSubEntity(0); // eyes		sub->setCustomParameter(SP_SHININESS, Ogre::Vector4(35, 0, 0, 0));		sub->setCustomParameter(SP_DIFFUSE, Ogre::Vector4(1, 0.3, 0.3, 1));		sub->setCustomParameter(SP_SPECULAR, Ogre::Vector4(1, 0.6, 0.6, 1));		sub = ent->getSubEntity(1); // skin		sub->setCustomParameter(SP_SHININESS, Ogre::Vector4(10, 0, 0, 0));		sub->setCustomParameter(SP_DIFFUSE, Ogre::Vector4(0, 0.5, 0, 1));		sub->setCustomParameter(SP_SPECULAR, Ogre::Vector4(0.3, 0.5, 0.3, 1));		sub = ent->getSubEntity(2); // earring		sub->setCustomParameter(SP_SHININESS, Ogre::Vector4(25, 0, 0, 0));		sub->setCustomParameter(SP_DIFFUSE, Ogre::Vector4(1, 1, 0, 1));		sub->setCustomParameter(SP_SPECULAR, Ogre::Vector4(1, 1, 0.7, 1));		sub = ent->getSubEntity(3); // teeth		sub->setCustomParameter(SP_SHININESS, Ogre::Vector4(20, 0, 0, 0));		sub->setCustomParameter(SP_DIFFUSE, Ogre::Vector4(1, 1, 0.7, 1));		sub->setCustomParameter(SP_SPECULAR, Ogre::Vector4(1, 1, 1, 1));    }};     int main(){    cMyApplication App;    App.go();    return 0;}

      

HiCelShading