IntermediateTutorial6Source         Intermediate Tutorial 6 - source

This is the source for Intermediate Tutorial 6.


IntermediateTutorial6.h

#ifndef __IntermediateTutorial6_h_
#define __IntermediateTutorial6_h_

#include "BaseApplication.h"

class IntermediateTutorial6 : public BaseApplication
{
public:
    IntermediateTutorial6(void);
    virtual ~IntermediateTutorial6(void);

protected:
    virtual void createScene(void);
	virtual bool frameRenderingQueued(const Ogre::FrameEvent& evt);
	virtual void createProjector();
	virtual void makeMaterialReceiveDecal(const Ogre::String& matName);

	Ogre::SceneNode* mProjectorNode;
	Ogre::Frustum* mDecalFrustum;
	Ogre::Frustum* mFilterFrustum;
	float mAnim;
};

#endif // #ifndef __IntermediateTutorial6_h_




IntermediateTutorial6.cpp

#include "IntermediateTutorial6.h"

//-------------------------------------------------------------------------------------
IntermediateTutorial6::IntermediateTutorial6(void)
{
}
//-------------------------------------------------------------------------------------
IntermediateTutorial6::~IntermediateTutorial6(void)
{
}

//-------------------------------------------------------------------------------------
void IntermediateTutorial6::createScene(void)
{
	mSceneMgr->setAmbientLight(Ogre::ColourValue(0.2f, 0.2f, 0.2f));

	Ogre::Light* light = mSceneMgr->createLight("MainLight");
	light->setPosition(20, 80, 50);

	mCamera->setPosition(60, 200, 70);
	mCamera->lookAt(0,0,0);

	//set up the ogre heads
	Ogre::Entity* ent;
	for (int i = 0; i < 6; i++)
	{
		Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
		ent = mSceneMgr->createEntity("head" + Ogre::StringConverter::toString(i), "ogrehead.mesh");
		headNode->attachObject(ent);

		Ogre::Radian angle(i + Ogre::Math::TWO_PI / 6);
		headNode->setPosition(75 * Ogre::Math::Cos(angle), 0, 75 * Ogre::Math::Sin(angle));
	}

	//create the projector and turn it on
	createProjector();
	for(unsigned int i = 0; i < ent->getNumSubEntities(); i++)
	{
		makeMaterialReceiveDecal(ent->getSubEntity(i)->getMaterialName());
	}
}

bool IntermediateTutorial6::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
	//make the projector rotate around
	mProjectorNode->rotate(Ogre::Vector3::UNIT_Y, Ogre::Degree(evt.timeSinceLastFrame * 10));
	return BaseApplication::frameRenderingQueued(evt);
}

void IntermediateTutorial6::createProjector()
{
	//set up the first frustum to be projected
	mDecalFrustum = new Ogre::Frustum();
	mProjectorNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("DecalProjectorNode");
	mProjectorNode->attachObject(mDecalFrustum);
	mProjectorNode->setPosition(0, 5, 0);

	//create the filter for the projector
	mFilterFrustum = new Ogre::Frustum();
	mFilterFrustum->setProjectionType(Ogre::PT_ORTHOGRAPHIC);
	Ogre::SceneNode* filterNode = mProjectorNode->createChildSceneNode("DecalFilterNode");
	filterNode->attachObject(mFilterFrustum);
	filterNode->setOrientation(Ogre::Quaternion(Ogre::Degree(90), Ogre::Vector3::UNIT_Y));
}

void IntermediateTutorial6::makeMaterialReceiveDecal(const Ogre::String& matName)
{
	//get the material information so that we can modify it
	Ogre::MaterialPtr mat = (Ogre::MaterialPtr)Ogre::MaterialManager::getSingleton().getByName(matName);
	Ogre::Pass* pass = mat->getTechnique(0)->createPass();

	//set the scene blending so that we don't get smears at the edge of our texture
	pass->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
	pass->setDepthBias(1);
	pass->setLightingEnabled(false);

	Ogre::TextureUnitState* texState = pass->createTextureUnitState("decal.png");
	texState->setProjectiveTexturing(true, mDecalFrustum);
	texState->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
	texState->setTextureFiltering(Ogre::FO_POINT, Ogre::FO_LINEAR, Ogre::FO_NONE);

	texState = pass->createTextureUnitState("decal_filter.png");
	texState->setProjectiveTexturing(true, mFilterFrustum);
	texState->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
	texState->setTextureFiltering(Ogre::TFO_NONE);
}



#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
        IntermediateTutorial6 app;

        try {
            app.go();
        } catch( Ogre::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().c_str() << std::endl;
#endif
        }

        return 0;
    }

#ifdef __cplusplus
}
#endif