From 2ae2a551a6290f46734307bbfdafea4b1a2cf2ba Mon Sep 17 00:00:00 2001 From: cutealien Date: Fri, 3 Jan 2020 19:05:16 +0000 Subject: Merging r5975 through r6036 from trunk to ogl-es branch. GLES drivers adapted, but only did make compile-tests. git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@6038 dfc29bdd-3216-0410-991c-e03cc46cb475 --- examples/01.HelloWorld_emscripten/main.cpp | 240 +++++++++++++++++++++++++++++ 1 file changed, 240 insertions(+) create mode 100644 examples/01.HelloWorld_emscripten/main.cpp (limited to 'examples/01.HelloWorld_emscripten/main.cpp') diff --git a/examples/01.HelloWorld_emscripten/main.cpp b/examples/01.HelloWorld_emscripten/main.cpp new file mode 100644 index 0000000..86b960d --- /dev/null +++ b/examples/01.HelloWorld_emscripten/main.cpp @@ -0,0 +1,240 @@ +/** Example 001 HelloWorld adapted to emscripten + +This Tutorial shows how to run code with emscripten. +Emscripten compiles c++ to asm.js to allow it running inside a webbrowser. +You have to setup the emscripten environment on your system first to use this. +*/ +#include +#include "exampleHelper.h" +#include +#include + +/* +The code in here is mostly similar to the usual HelloWorld. +You can find more information about it there. Here we mainly document the +differences needed for emscripten. +*/ + +using namespace irr; +using namespace core; +using namespace scene; +using namespace video; +using namespace io; +using namespace gui; + +/* +This part not necessary for emscripten, only useful to keep it in +in case you want to run the same code on Windows with VS as well. +*/ +#ifdef _MSC_VER +#pragma comment(lib, "Irrlicht.lib") +#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup") +#endif + + +/* +Variables on the stack will stay intact between runs of one_iter() +*/ +IrrlichtDevice *device = 0; +IVideoDriver* driver = 0; +ISceneManager* smgr = 0; +IGUIEnvironment* guienv = 0; + +ICameraSceneNode* camera = 0; +dimension2d screenSize(640, 480); + +#ifdef __EMSCRIPTEN__ +/* + Handle changes in canvas size which are done with html/js. + Note that it's only OK for windowed so far, + the switch to fullscreen not yet working. + Also the emscripten_get_canvas_size might cause a slow-down + (but haven't found yet a way to avoid it with SDL1). + */ +void checkCanvasResize() +{ + int w, h, fs; + emscripten_get_canvas_size(&w, &h, &fs); + const core::dimension2d canvasDim(w,h); + if ( canvasDim != screenSize ) + { + screenSize = canvasDim; + driver->OnResize(canvasDim); + driver->setViewPort(irr::core::rect(0,0,w,h)); + + irr::f32 aspect = (irr::f32)w / (irr::f32)h; + camera->setAspectRatio(aspect); + } +} + + +/* + emscripten can't run things in an endless-loop or otherwise the browse will consider + the script to hang. +*/ +void one_iter() +{ + if(!device->run()) + { + // Could clean up here in theory, but not sure if it makes a difference + + /* + This tells emscripten to not run any further code. + */ + emscripten_cancel_main_loop(); + return; + } + + // In case you have a resizeable canvas (resized from html) + //checkCanvasResize(); + + driver->beginScene(ECBF_COLOR | ECBF_DEPTH, SColor(255,100,101,140)); + + smgr->drawAll(); + guienv->drawAll(); + + driver->endScene(); +} +#endif //__EMSCRIPTEN__ + + +/* + The main method is also run on emscripten. +*/ +int main() +{ + /* + Printing out the build date/time is very useful to find troubles with unexpected browser-caches. + */ + printf("Build-date: %s %s\n", __DATE__, __TIME__); + + SIrrlichtCreationParameters parameters; + /* + Create device flags for emscripten are still experimental + and might not all work. + + - deviceType: You can to use EDT_OGLES2 or EDT_WEBGL1 on emscripten. + EDT_WEBGL1 is better optimized but does not yet support all options. + EDT_OGLES2 needs -s FULL_ES2=1 as linker flag in the Makefile. + */ +#ifndef __EMSCRIPTEN__ + parameters.DriverType = EDT_OGLES2; +#else //__EMSCRIPTEN__ + parameters.DriverType = EDT_WEBGL1; +#endif //__EMSCRIPTEN__ + + parameters.LoggingLevel = ELL_DEBUG; + parameters.WindowSize = screenSize; + parameters.Stencilbuffer = false; + parameters.AntiAlias = 4; + + device = createDeviceEx(parameters); + + if (!device) + return 1; + + /* + Window caption will set the title-text in the browser. + */ + device->setWindowCaption(L"Hello World! - Irrlicht Engine Demo"); + + /* + Get a pointer to the VideoDriver, the SceneManager and the graphical + user interface environment, so that we do not always have to write + device->getVideoDriver(), device->getSceneManager(), or + device->getGUIEnvironment(). + */ + driver = device->getVideoDriver(); + smgr = device->getSceneManager(); + guienv = device->getGUIEnvironment(); + + /* + We add a hello world label to the window, using the GUI environment. + The text is placed at the position (10,10) as top left corner and + (260,22) as lower right corner. + */ + guienv->addStaticText(L"Hello World! This is Irrlicht on emscripten!", + rect(10,10,260,22), true); + + /* + Get a media path dedicated for your platform. + We tell emscripten to copy the media folder in the Makefile with: + "--preload-file ../../media@/media" + That copies our ../../media folder in a .data + file which is loaded by the browser. It can then be accessed there + by "/media" name (that's the parameter after the '@'). + Note that usually you would try to copy only as many files + as absolutely necessary to reduce start-up times. + */ + const io::path mediaPath = getExampleMediaPath(); + + /* + Make a model called Sydney show up. + */ + IAnimatedMesh* mesh = smgr->getMesh(mediaPath + "sydney.md2"); + if (!mesh) + { + device->drop(); + return 1; + } + IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh ); + + /* + Disable lighting because we do not have a dynamic light in here, and + the mesh would be totally black otherwise. + Set the frame loop such that the predefined STAND animation is used. + Add a texture to the model. + */ + if (node) + { + node->setMaterialFlag(EMF_LIGHTING, false); + node->setMD2Animation(scene::EMAT_STAND); + node->setMaterialTexture( 0, driver->getTexture(mediaPath + "sydney.bmp") ); + } + + /* + To look at the mesh, we place a camera into 3d space at the position + (0, 30, -40). The camera looks from there to (0,5,0), which is + approximately the place where our md2 model is. + */ + camera = smgr->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0)); + +#ifndef __EMSCRIPTEN__ // this part only so you can run the same code on desktop + /* + On desktop we run and endless loop until the user closes the window or + presses ALT+F4 (or whatever keycode closes a window). + */ + while(device->run()) + { + driver->beginScene(ECBF_COLOR | ECBF_DEPTH, SColor(255,100,101,140)); + + smgr->drawAll(); + guienv->drawAll(); + + driver->endScene(); + } + device->drop(); + +#else // __EMSCRIPTEN__ + + /* + Setting fps to 0 or a negative value will use the browser’s + requestAnimationFrame mechanism to call the main loop function. + Emscripten documentation recommends to do that, but you can also set + another fps value and the browser will try to call the main-loop + fps times per second. + The simulate_infinite_loop tells emscripten that this is an application + which will simulate an infinite loop. There is also a flag in the + Makefile about that: -s NO_EXIT_RUNTIME=1 + */ + int fps = 0; + int simulate_infinite_loop = 1; + emscripten_set_main_loop(one_iter, fps, simulate_infinite_loop); +#endif //__EMSCRIPTEN__ + + return 0; +} + +/* +That's it. Compile and run. +**/ -- cgit v1.2.3