Ogre Tutorial 1: Creating a sample application
In this page you will be presented with the required tasks to create a simple application based on the Reference Application Layer. It is a simplified version of the BSPCollision example that ships with Ogre.
IMPORTANT NOTE: It is assumed that you have been through the Ogre 3D Introduction and know about Ogre's Example Reference Application Layer. You should also look into Setting up Ogre3D (Windows) and make sure you have ogre correctly installed and configured, and that you are able to compile and run the Demos.
The following steps are described here:
- Preparing the project
- Create the GameApplication class: where the engine is setup and the scene is described
- Create the GameFrameListener class: the class that will handle user input and scene update
- Create the main entry point: the standard code that instantiates a GameApplication and starts its main loop
Preparing the project
Assuming that you have tried to compile and run at least one of the demos shipped with Ogre and succeeded, your new project will be placed at a similar level of the demos, for the sake of simplicity.
- Navigate to the “samples” folder in the OgreSDK home folder
- Extract the OgreGameSlnTemplate.zip file in that folder. You should end up with a “Game” folder contain a .sln file, a .vcproj file and a .user file.
- Go inside the “Game” folder and open the .sln file in MSVC
- At this point you have the project set up, now you must add the files with the code, as described in the following sections.
Game Application Class: Lights, camera, scenario (world and objects)
- Create a GameApplication class extending ExampleRefAppApplication, and overriding the createScene method to:
- setup lights and shadows
- setup the physics world parameters (gravity)
- setup the camera
- create a collidable Ball to be thrown
- create four walls using collidable FinitePlane's
- create a shelf using a collidable Box
- create a set of collidable Box's
- GameApplication.h
#pragma once #include "GameFrameListener.h" #include "OgreReferenceAppLayer.h" #include "ExampleRefAppApplication.h" #include "OgreStringConverter.h" class GameApplication : public ExampleRefAppApplication { public: GameApplication() { } ~GameApplication() { } protected: ApplicationObject *ball; void createScene(void) { mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE); // Set ambient light mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2)); // Create a point light Light* l = mSceneMgr->createLight("MainLight"); l->setPosition(-100,50,100); l->setAttenuation(8000,1,0,0); // Setup World mWorld->setGravity(Vector3(0, 0, -60)); // modify camera for close work mCamera->setNearClipDistance(10); mCamera->setFarClipDistance(20000); // Also change position, and set Quake-type orientation // Get random player start point ViewPoint vp = mSceneMgr->getSuggestedViewpoint(true); mCamera->setPosition(vp.position); mCamera->pitch(Degree(90)); // Quake uses X/Y horizon, Z up mCamera->rotate(vp.orientation); // Don't yaw along variable axis, causes leaning mCamera->setFixedYawAxis(true, Vector3::UNIT_Z); // Look at the boxes mCamera->lookAt(-150,40,30); // create ball ball = mWorld->createBall("ball", 7, vp.position + Vector3(0,0,80)); ball->setDynamicsEnabled(true); ball->getEntity()->setMaterialName("Ogre/Eyes"); // Create walls OgreRefApp::FinitePlane* walls[4]; //Right walls[0] = mWorld->createPlane("Wall0",100,100,Vector3(-150,+100,0),Quaternion(Radian(Degree(90)),Vector3(1,0,0))); walls[0]->getEntity()->setMaterialName("Examples/Rocky"); //Left walls[1] = mWorld->createPlane("Wall1",100,100,Vector3(-150,-100,0),Quaternion(Radian(Degree(-90)),Vector3(1,0,0))); walls[1]->getEntity()->setMaterialName("Examples/Rocky"); //Back walls[2] = mWorld->createPlane("Wall2",100,100,Vector3(-250,0,0),Quaternion(Radian(Degree(90)),Vector3(0,1,0))); walls[2]->getEntity()->setMaterialName("Examples/Rocky"); //bottom walls[3] = mWorld->createPlane("Wall3",100,100,Vector3(-150,0,-100),Quaternion(Radian(Degree(0)),Vector3(1,0,0))); walls[3]->getEntity()->setMaterialName("Examples/Rocky"); // Shelf OgreRefApp::Box* box = mWorld->createBox("shelf", 75, 125, 5, Vector3(-150, 40, 30)); box->getEntity()->setMaterialName("Examples/Rocky"); // Cubes static const Real BOX_SIZE = 15.0f; static const int num_rows = 3; for (int row = 0; row < num_rows; ++row) { for (int i = 0; i < (num_rows-row); ++i) { Real row_size = (num_rows - row) * BOX_SIZE * 1.25; String name = "box"; name += StringConverter::toString((row*num_rows) + i); box = mWorld->createBox(name, BOX_SIZE,BOX_SIZE,BOX_SIZE , Vector3(-150, 40 - (row_size * 0.5) + (i * BOX_SIZE * 1.25) , 32.5 + (BOX_SIZE / 2) + (row * BOX_SIZE))); box->setDynamicsEnabled(false, true); box->getEntity()->setMaterialName("Examples/10PointBlock"); } } mCamera->setCollisionEnabled(false); } // Create new frame listener void createFrameListener(void) { mFrameListener= new GameFrameListener(mWindow, mCamera, ball); mRoot->addFrameListener(mFrameListener); } };
Game Frame Listener: action (input handling and scene update)
- Create a GameFrameListener class extending ExampleRefAppFrameListener and overriding the frameEnded method so that it:
- calls the base class's method (to process general input)
- if the space key is pressed, throw the ball i.e., set it in the viewer's position and set a velocity vector with a direction equal to the looking direction
- GameFrameListener.h
#pragma once #include "OgreReferenceAppLayer.h" #include "ExampleRefAppFrameListener.h" class GameFrameListener : public ExampleRefAppFrameListener { protected: ApplicationObject *ball; public: GameFrameListener(RenderWindow* win, CollideCamera* cam, ApplicationObject *pball) : ExampleRefAppFrameListener(win, cam), ball(pball) { } bool frameEnded(const FrameEvent& evt) { // Call superclass bool ret = ExampleRefAppFrameListener::frameEnded(evt); // Respond to keyboard: SPACE FIRES if (mKeyboard->isKeyDown(OIS::KC_SPACE)) { ball->setPosition(mCamera->getPosition() + mCamera->getDirection() * mCamera->getNearClipDistance() * 2); ball->setLinearVelocity(mCamera->getDirection() * 200); ball->setAngularVelocity(Vector3::ZERO); } return ret; } };
Main Application Entry Point
- The application's main entry point consists solely of the creation of a GameApplication object and invoking its go method (plus some minor platform handling code):
- GameMain.cpp
#include "GameApplication.h" #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 #define WIN32_LEAN_AND_MEAN #include "windows.h" INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT ) #else int main(int argc, char **argv) #endif { // Create application object GameApplication 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; }