From: <tj...@us...> - 2010-02-28 13:12:16
|
Revision: 12988 http://alleg.svn.sourceforge.net/alleg/?rev=12988&view=rev Author: tjaden Date: 2010-02-28 13:12:09 +0000 (Sun, 28 Feb 2010) Log Message: ----------- Add an example demonstrating use of Ogre graphics rendering alongside Allegro. This currently only works on Linux/GLX and is not properly added to the build system (it is commented out). Modified Paths: -------------- allegro/branches/4.9/examples/CMakeLists.txt Added Paths: ----------- allegro/branches/4.9/examples/ex_ogre3d.cpp Modified: allegro/branches/4.9/examples/CMakeLists.txt =================================================================== --- allegro/branches/4.9/examples/CMakeLists.txt 2010-02-28 02:26:30 UTC (rev 12987) +++ allegro/branches/4.9/examples/CMakeLists.txt 2010-02-28 13:12:09 UTC (rev 12988) @@ -177,6 +177,10 @@ # ex_gp2x # ex_iphone +# example(ex_ogre3d ex_ogre3d.cpp) +# include_directories(/usr/include/OGRE) +# target_link_libraries(ex_ogre3d OgreMain) + copy_data_dir_to_build(copy_example_data data) #-----------------------------------------------------------------------------# Added: allegro/branches/4.9/examples/ex_ogre3d.cpp =================================================================== --- allegro/branches/4.9/examples/ex_ogre3d.cpp (rev 0) +++ allegro/branches/4.9/examples/ex_ogre3d.cpp 2010-02-28 13:12:09 UTC (rev 12988) @@ -0,0 +1,435 @@ +/* + * Example program for the Allegro library, by Peter Wang. + * + * This is a test program to see if Allegro can be used alongside the OGRE + * graphics library. It currently only works on Linux/GLX. To run, you + * will need to have OGRE plugins.cfg and resources.cfg files in the + * current directory. + * + * Inputs: W A S D, mouse + * + * This code is based on the samples in the OGRE distribution. + */ + +#include <Ogre.h> +#undef stricmp +#include <allegro5/allegro.h> +#include <allegro5/allegro_opengl.h> + +/* + * Ogre 1.7 (and, optionally, earlier versions) uses the FreeImage library to + * handle image loading. FreeImage bundles its own copies of common libraries + * like libjpeg and libpng, which can conflict with the system copies of those + * libraries that allegro_image uses. That means we can't use allegro_image + * safely, nor any of the addons which depend on it. + * + * One solution would be to write a codec for Ogre that avoids FreeImage, or + * write allegro_image handlers using FreeImage. The latter would probably be + * easier and useful for other reasons. + */ + +using namespace Ogre; + +const int WIDTH = 640; +const int HEIGHT = 480; +const float MOVE_SPEED = 1500.0; + +class Application +{ +protected: + Root *mRoot; + RenderWindow *mWindow; + SceneManager *mSceneMgr; + Camera *mCamera; + +public: + void setup() + { + createRoot(); + defineResources(); + setupRenderSystem(); + createRenderWindow(); + initializeResourceGroups(); + chooseSceneManager(); + createCamera(); + createViewports(); + createScene(); + } + + ~Application() + { + delete mRoot; + } + +private: + void createRoot() + { + mRoot = new Root(); + } + + void defineResources() + { + String secName, typeName, archName; + ConfigFile cf; + cf.load("resources.cfg"); + ConfigFile::SectionIterator seci = cf.getSectionIterator(); + while (seci.hasMoreElements()) { + secName = seci.peekNextKey(); + ConfigFile::SettingsMultiMap *settings = seci.getNext(); + ConfigFile::SettingsMultiMap::iterator i; + for (i = settings->begin(); i != settings->end(); ++i) { + typeName = i->first; + archName = i->second; + ResourceGroupManager::getSingleton().addResourceLocation(archName, + typeName, secName); + } + } + } + + void setupRenderSystem() + { + if (!mRoot->restoreConfig() && !mRoot->showConfigDialog()) { + throw Exception(52, "User canceled the config dialog!", + "Application::setupRenderSystem()"); + } + } + + void createRenderWindow() + { + // Initialise Ogre without creating a window. + mRoot->initialise(false); + + Ogre::NameValuePairList misc; + // Tell Ogre to use the current GL context. This works on Linux/GLX but + // you *will* need something different on Windows or Mac. + misc["currentGLContext"] = String("True"); + + int w = al_get_display_width(); + int h = al_get_display_height(); + mWindow = mRoot->createRenderWindow("MainRenderWindow", w, h, false, + &misc); + mWindow->setVisible(true); + } + + void initializeResourceGroups() + { + TextureManager::getSingleton().setDefaultNumMipmaps(5); + ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); + } + + virtual void chooseSceneManager() + { + mSceneMgr = mRoot->createSceneManager(ST_GENERIC, "Default SceneManager"); + } + + virtual void createCamera() + { + mCamera = mSceneMgr->createCamera("PlayerCam"); + mCamera->setPosition(Vector3(-300, 300, -300)); + mCamera->lookAt(Vector3(0, 0, 0)); + mCamera->setNearClipDistance(5); + } + + virtual void createViewports() + { + // Create one viewport, entire window. + Viewport *vp = mWindow->addViewport(mCamera); + vp->setBackgroundColour(ColourValue(0, 0.25, 0.5)); + + // Alter the camera aspect ratio to match the viewport. + mCamera->setAspectRatio( + Real(vp->getActualWidth()) / Real(vp->getActualHeight())); + } + + virtual void createScene() = 0; + +public: + + void render() + { + const bool swap_buffers = false; + mWindow->update(swap_buffers); + mRoot->renderOneFrame(); + al_flip_display(); + } +}; + +class Example : public Application +{ +private: + ALLEGRO_EVENT_QUEUE *queue; + ALLEGRO_TIMER *timer; + + double startTime; + double lastRenderTime; + double lastMoveTime; + bool lmb; + bool rmb; + bool forward; + bool back; + bool left; + bool right; + float current_speed; + Vector3 last_translate; + +public: + Example(); + ~Example(); + void setup(); + void mainLoop(); + +private: + void createScene(); + void moveCamera(double timestamp, Radian rot_x, Radian rot_y, + Vector3 & translate); + void animate(double now); + void nextFrame(); +}; + +Example::Example() : + queue(NULL), + timer(NULL), + startTime(0.0), + lastRenderTime(0.0), + lastMoveTime(0.0), + lmb(false), + rmb(false), + forward(false), + back(false), + left(false), + right(false), + current_speed(0), + last_translate(Vector3::ZERO) +{ +} + +Example::~Example() +{ + al_uninstall_timer(timer); + al_destroy_event_queue(queue); +} + +void Example::createScene() +{ + // Enable shadows. + mSceneMgr->setAmbientLight(ColourValue(0.5, 0.25, 0.0)); + //mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE); // slower + mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE); // faster + + // Create the character. + Entity *ent1 = mSceneMgr->createEntity("Ninja", "ninja.mesh"); + ent1->setCastShadows(true); + mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent1); + + AnimationState *anim1 = ent1->getAnimationState("Walk"); + anim1->setLoop(true); + anim1->setEnabled(true); + + // Create the ground. + Plane plane(Vector3::UNIT_Y, 0); + MeshManager::getSingleton().createPlane("ground", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, + 1500, 1500, 20, 20, true, 1, 5, 5, Vector3::UNIT_Z); + + Entity *ent2 = mSceneMgr->createEntity("GroundEntity", "ground"); + ent2->setMaterialName("Examples/Rockwall"); + ent2->setCastShadows(false); + mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent2); + + // Create a light. + Light *light = mSceneMgr->createLight("Light1"); + light->setType(Light::LT_POINT); + light->setPosition(Vector3(0, 150, 250)); + light->setDiffuseColour(1.0, 1.0, 1.0); + light->setSpecularColour(1.0, 0.0, 0.0); +} + +void Example::setup() +{ + Application::setup(); + + const double BPS = 60.0; + timer = al_install_timer(1.0 / BPS); + + queue = al_create_event_queue(); + al_register_event_source(queue, al_get_keyboard_event_source()); + al_register_event_source(queue, al_get_mouse_event_source()); + al_register_event_source(queue, al_get_timer_event_source(timer)); +} + +void Example::mainLoop() +{ + bool redraw = true; + + startTime = lastMoveTime = al_current_time(); + al_start_timer(timer); + + for (;;) { + ALLEGRO_EVENT event; + + if (al_event_queue_is_empty(queue) && redraw) { + nextFrame(); + redraw = false; + } + + al_wait_for_event(queue, &event); + if (event.type == ALLEGRO_EVENT_KEY_DOWN && + event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { + break; + } + + Radian rot_x(0); + Radian rot_y(0); + Vector3 translate(Vector3::ZERO); + + switch (event.type) { + case ALLEGRO_EVENT_TIMER: + redraw = true; + break; + + case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: + if (event.mouse.button == 1) + lmb = true; + if (event.mouse.button == 2) + rmb = true; + break; + + case ALLEGRO_EVENT_MOUSE_BUTTON_UP: + if (event.mouse.button == 1) + lmb = false; + if (event.mouse.button == 2) + rmb = false; + if (!lmb && !rmb) + al_show_mouse_cursor(); + break; + + case ALLEGRO_EVENT_MOUSE_AXES: + if (lmb) { + rot_x = Degree(-event.mouse.dx * 0.13); + rot_y = Degree(-event.mouse.dy * 0.13); + } + if (rmb) { + translate.x = event.mouse.dx * 0.5; + translate.y = event.mouse.dy * -0.5; + } + if (lmb || rmb) { + al_hide_mouse_cursor(); + al_set_mouse_xy(al_get_display_width()/2, + al_get_display_height()/2); + } + break; + + case ALLEGRO_EVENT_KEY_DOWN: + case ALLEGRO_EVENT_KEY_UP: { + const bool is_down = (event.type == ALLEGRO_EVENT_KEY_DOWN); + if (event.keyboard.keycode == ALLEGRO_KEY_W) + forward = is_down; + if (event.keyboard.keycode == ALLEGRO_KEY_S) + back = is_down; + if (event.keyboard.keycode == ALLEGRO_KEY_A) + left = is_down; + if (event.keyboard.keycode == ALLEGRO_KEY_D) + right = is_down; + break; + } + } + + moveCamera(event.any.timestamp, rot_x, rot_y, translate); + } +} + +void Example::moveCamera(double timestamp, Radian rot_x, Radian rot_y, + Vector3 & translate) +{ + const double time_since_move = timestamp - lastMoveTime; + const float move_scale = MOVE_SPEED * time_since_move; + + if (forward) { + translate.z = -move_scale; + } + if (back) { + translate.z = move_scale; + } + if (left) { + translate.x = -move_scale; + } + if (right) { + translate.x = move_scale; + } + + if (translate == Vector3::ZERO) { + // Continue previous motion but dampen. + translate = last_translate; + current_speed -= time_since_move * 0.3; + } + else { + // Ramp up. + current_speed += time_since_move; + } + if (current_speed > 1.0) + current_speed = 1.0; + if (current_speed < 0.0) + current_speed = 0.0; + + translate *= current_speed; + + mCamera->yaw(rot_x); + mCamera->pitch(rot_y); + mCamera->moveRelative(translate); + + last_translate = translate; + lastMoveTime = timestamp; +} + +void Example::animate(double now) +{ + const double dt0 = now - startTime; + const double dt = now - lastRenderTime; + + // Animate the character. + Entity *ent = mSceneMgr->getEntity("Ninja"); + AnimationState *anim = ent->getAnimationState("Walk"); + anim->addTime(dt); + + // Move the light around. + Light *light = mSceneMgr->getLight("Light1"); + light->setPosition(Vector3(300 * cos(dt0), 300, 300 * sin(dt0))); +} + +void Example::nextFrame() +{ + const double now = al_current_time(); + animate(now); + render(); + lastRenderTime = now; +} + +int main(int argc, char *argv[]) +{ + (void)argc; + (void)argv; + + if (!al_init()) { + return 1; + } + al_install_keyboard(); + al_install_mouse(); + + al_set_new_display_flags(ALLEGRO_OPENGL); + if (!al_create_display(WIDTH, HEIGHT)) { + return 1; + } + al_set_window_title("My window"); + + { + Example app; + app.setup(); + app.mainLoop(); + } + + al_uninstall_system(); + + return 0; +} + +/* vim: set sts=3 sw=3 et: */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |