Source

ogre-npr / ogre-npr / NPRDemoApp.cpp

Full commit
/* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details. */

#include "precompiled.h"

#include "NPRDemoApp.h"

#include <sstream>
#include <boost/foreach.hpp>
#include <boost/format.hpp>

//#define ANIMATE_LIGHT

//-----------------------------------------------------------------------------
NPRDemoApp::NPRDemoApp()
    :OgreApplication("NPR Sandbox")
    ,mBBset(NULL)
    ,mLightFlare(NULL)
    ,mLight(NULL)
    ,mLightNode(NULL)
    ,mDebugText(NULL)
    ,mAnimState(NULL)
    ,mEdgesVisible(true)
{
}
//-----------------------------------------------------------------------------
void NPRDemoApp::createScene()
{
    mLog  = LogManager::getSingleton().createLog("NPR.log");

    const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities();
    if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !(caps->hasCapability(RSC_FRAGMENT_PROGRAM)))
    {
        OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your card does not support vertex and fragment programs, so cannot "
            "run this application. Sorry!", 
            "createScene");
    }


    mSceneMgr->setNormaliseNormalsOnScale(true);
    _createGrid(500);
    _createLight();
    _populate();

    _createDebugOverlay();


    mLightNode->detachObject(mLight);
    //mCameraNode->attachObject(mLight);

    mLightNode->setVisible(true);


}
//-----------------------------------------------------------------------------
bool NPRDemoApp::frameStarted(const FrameEvent& evt)
{
    _updateDebugOverlay();

#ifdef ANIMATE_LIGHT
        mAnimState->addTime(evt.timeSinceLastFrame);
#endif

    return OgreApplication::frameStarted(evt);
}
//-----------------------------------------------------------------------------
bool NPRDemoApp::keyReleased( const OIS::KeyEvent &e )
{
    if(mKeyboard->isKeyDown(OIS::KC_H))
    {
        //BOOST_FOREACH(EdgeGeometryItem item, mEdges)
        //{
        //    mEdgesVisible = !mEdgesVisible;
        //    _setEdgesVisible(item, mEdgesVisible);
        //}
    }
    return OgreApplication::keyReleased(e);
}
//-----------------------------------------------------------------------------
void NPRDemoApp::_createDebugOverlay()
{
    new TextRenderer();

    mDebugText = TextRenderer::getSingletonPtr();

    int x_offset=100, y_offset=18, w=100, h=18;

    mDebugText->addTextBox("Batches_", "#Batches : "
                            , 10, 10, w, h
                            , ColourValue(0.7,0.7,0.7));
    mDebugText->addTextBox("Batches", "0"
                            , x_offset, 10, w, h
                            , ColourValue(1.0,1.0,1.0));
    mDebugText->addTextBox("FPS_", "#FPS : "
                            , 10, 10+y_offset, w, h
                            , ColourValue(0.7,0.7,0.7));
    mDebugText->addTextBox("FPS", "0"
                            , x_offset, 10+y_offset, w, h
                            , ColourValue(1.0,1.0,1.0));

    mDebugText->addTextBox("Triangles_", "#tris : "
                            , 10, 10+y_offset*2, w, h
                            , ColourValue(0.7,0.7,0.7));
    mDebugText->addTextBox("Triangles", "0"
                            , x_offset, 10+y_offset*2, w, h
                            , ColourValue(1.0,1.0,1.0));



}
//-----------------------------------------------------------------------------
void NPRDemoApp::_updateDebugOverlay()
{
    mDebugText->setText("Batches", StringConverter::toString(mWindow->getBatchCount()));
    mDebugText->setText("FPS", StringConverter::toString(mWindow->getLastFPS()));
    mDebugText->setText("Triangles", StringConverter::toString(mWindow->getTriangleCount()));
}

//-----------------------------------------------------------------------------
void NPRDemoApp::_populate()
{
    //_loadMesh("TorusKnot01", Vector3(-50, 0, 0));
    //_loadMesh("Teapot01",    Vector3(50, 0, 0));
    //_loadMesh("Gengon01",   Vector3(-50, 0, 50));
    //_loadMesh("Cone01",     Vector3(50, 0, 50));
    //_loadMesh("Box01",      Vector3(-50, 0, -50));

	//_loadMesh("sphere2", Vector3(500, 0, 0));
	//
    //_loadMesh("Rectangle01", Vector3(0, 0, 0));

    // stanford models

 //   SceneNode *bunny = _loadMesh("bunny", Vector3::ZERO);
    
	//bunny->scale(100, 100, 100);
	//bunny->pitch(Degree(-90));
	//bunny->translate(0, 20, 0);

	//SceneNode *dragon = _loadMesh("dragon", Vector3(50, 0, 100));
    
 //   SceneNode *dragon = _loadMesh("dragon", Vector3::ZERO);

	//dragon->scale(50, 50, 50);
	//dragon->pitch(Degree(180));
	//dragon->translate(0, 15, 0);

    //_loadMesh("math_back wall", Vector3(0, 0, 0));
    //_loadMesh("math_front wall", Vector3(0, 0, 0));
    //_loadMesh("math_left wall", Vector3(0, 0, 0));
    //_loadMesh("math_right wall", Vector3(0, 0, 0));
    //_loadMesh("math_roof", Vector3(0, 0, 0));
    //_loadMesh("math_ground", Vector3(0, 0, 0));
    //_loadMesh("math_chairs", Vector3(0, 0, 0));

    // loading a .scene scene
    //SceneNode *node = mSceneMgr->getRootSceneNode()->createChildSceneNode("titanic_root");
    //_loadScene("titanic", node);




    //_loadMesh("ulb_building_BATIMENTS_EST", Vector3(-1200, 0, 0));
    //_loadMesh("ulb_building_BATIMENTS_TOUT", Vector3(-1200, 0, 0));
    _loadMesh("ulb_building_bat_C", Vector3(-1200, 0, 0));
    //_loadMesh("ulb_building_bat_C_1", Vector3(-1200, 0, 0));
    //_loadMesh("ulb_building_bat_C_2", Vector3(-1200, 0, 0));

    //_loadMesh("ulb_building_ASCENCEUR", Vector3(-1200, 0, 0));

 
    _loadMesh("ulb_building_BAT_NEXT", Vector3(-1200, 0, 0));
    _loadMesh("ulb_building_BAT_PRINCIPAL", Vector3(-1200, 0, 0));
    _loadMesh("ulb_building_bat_projet_broullion", Vector3(-1200, 0, 0));
    _loadMesh("ulb_building_bat_S_W", Vector3(-1200, 0, 0));
    _loadMesh("ulb_building_batiment_plus", Vector3(-1200, 0, 0));


    _loadMesh("ulb_building_BATIMENTS_PROJET", Vector3(-1200, 0, 0));
    _loadMesh("ulb_building_BATIMENTS_TOUT", Vector3(-1200, 0, 0));
    _loadMesh("ulb_building_Calque1", Vector3(-1200, 0, 0));
    _loadMesh("ulb_building_Calque2", Vector3(-1200, 0, 0));
    _loadMesh("ulb_building_COURBES", Vector3(-1200, 0, 0));

    _loadMesh("ulb_building_galleries", Vector3(-1200, 0, 0));
    _loadMesh("ulb_building_Layer0", Vector3(-1200, 0, 0));

    _loadMesh("ulb_building_Le_Batiment", Vector3(-1200, 0, 0));
    _loadMesh("ulb_building_route_relief", Vector3(-1200, 0, 0));

    _loadMesh("ulb_building_tour", Vector3(-1200, 0, 0));
    _loadMesh("ulb_building_Z_LAYOUT", Vector3(-1200, 0, 0));

    ////node->translate(0, 0, -1500);
    //node->scale(0.1, 0.1, 0.1);
}
//-----------------------------------------------------------------------------
void NPRDemoApp::_loadScene(const String &_name, SceneNode* _node)
{
    OgreMax::OgreMaxScene sceneLoader;

    sceneLoader.Load("../media/"+_name+"/"+_name+".scene", mWindow
        , OgreMax::OgreMaxScene::SKIP_ENVIRONMENT |
        OgreMax::OgreMaxScene::SKIP_SKY |
        OgreMax::OgreMaxScene::SKIP_TERRAIN|
        OgreMax::OgreMaxScene::SKIP_EXTERNALS
                    ,mSceneMgr,_node, this);
}
//-----------------------------------------------------------------------------
SceneNode* NPRDemoApp::_loadMesh(const Ogre::String &_name, const Ogre::Vector3 &_pos)
{
    Entity *ent = mSceneMgr->createEntity(_name, _name+".mesh");
    SceneNode *node = mSceneMgr->getRootSceneNode()->createChildSceneNode(_name+"Node", _pos);

	ent->setMaterialName("Shading/PerPixel/Gooch");
    node->attachObject(ent);

    EdgeGeometryBuilder *edges = new EdgeGeometryBuilder(mLog, mSceneMgr);
    edges->addEdgesForEntity(ent);
    edges->setVisible(true);
    edges->attachToSceneNode(node);

    return node;
}
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
void NPRDemoApp::_setCelShadingMaterial(Entity *_ent)
{
    _ent->getSubEntity(0)->setMaterialName("Examples/CelShading");

    _ent->getSubEntity(0)->setCustomParameter(0, Vector4(10.0f, 0.0f, 0.0f, 0.0f));
    _ent->getSubEntity(0)->setCustomParameter(1, Vector4(0.0f, 0.5f, 0.0f, 1.0f));
    _ent->getSubEntity(0)->setCustomParameter(2, Vector4(0.3f, 0.5f, 0.3f, 1.0f));
}
//-----------------------------------------------------------------------------
void NPRDemoApp::_createLight()
{
    mBBset = mSceneMgr->createBillboardSet("Light BB");
    mBBset->setMaterialName("Objects/Flare");
    mLightFlare = mBBset->createBillboard(Vector3::ZERO);

    mLight = mSceneMgr->createLight("main light");
    mLight->setType(Light::LT_POINT);
    mLight->setDiffuseColour(ColourValue::White);
    mLight->setSpecularColour(ColourValue::White);

    mLightNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("light node");
    mLightNode->attachObject(mLight);
    mLightNode->attachObject(mBBset);


#ifdef ANIMATE_LIGHT
    Real totalTime = 10;                
    
    Animation *anim = mSceneMgr->createAnimation("Light Track", totalTime);
    anim->setInterpolationMode(Animation::IM_SPLINE);

    NodeAnimationTrack *track = anim->createNodeTrack(0, mLightNode);
    TransformKeyFrame *key;      

    Real precision = 36, amplitude = 300;
    int keyframeIndex = 0;
    for(float phi=0.0; phi <= 2*Math::PI; phi+= Math::PI / precision)
    {
        key = track->createNodeKeyFrame(phi * (totalTime/ (2*Math::PI)));
        key->setTranslate(Vector3(amplitude*Math::Cos(phi)
                                 ,amplitude
                                 ,amplitude*Math::Sin(phi)));
    }

    mAnimState = mSceneMgr->createAnimationState("Light Track");
    mAnimState->setEnabled(true);
#else
    mLightNode->setPosition(0, 500, 500);
#endif
}
//-----------------------------------------------------------------------------

////-----------------------------------------------------------------------------
//void NPRDemoApp::CreatedEntity(const OgreMax::OgreMaxScene* scene
//                                 ,Ogre::Entity* entity)
//{
//    entity->setMaterialName("NPR/Face");
//    ManualObject *edges = _createQuadFinGeometry(entity);
//    edges->setVisible(true);
//
//    SceneNode *node = entity->getParentSceneNode();
//
//    if (node)
//    {
//        node->attachObject(edges);
//        node->setVisible(true); 
//    }
//}
////-----------------------------------------------------------------------------
//void NPRDemoApp::_setEdgesVisible(EdgeGeometryItem &_item, bool _visible)
//{
//    ManualObject *edges = _item.first;
//    SceneNode    *node  = _item.second;
//    
//    node->setVisible(_visible);
//    edges->setVisible(_visible);
//}
////-----------------------------------------------------------------------------