aboutsummaryrefslogtreecommitdiff
path: root/examples/01.HelloWorld_emscripten/main.cpp
diff options
context:
space:
mode:
authorcutealien <cutealien@dfc29bdd-3216-0410-991c-e03cc46cb475>2020-01-03 19:05:16 +0000
committercutealien <cutealien@dfc29bdd-3216-0410-991c-e03cc46cb475>2020-01-03 19:05:16 +0000
commit2ae2a551a6290f46734307bbfdafea4b1a2cf2ba (patch)
treeba2f0b468640e44899fed3df2d4cc58795f4a003 /examples/01.HelloWorld_emscripten/main.cpp
downloadirrlicht-2ae2a551a6290f46734307bbfdafea4b1a2cf2ba.tar.xz
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
Diffstat (limited to 'examples/01.HelloWorld_emscripten/main.cpp')
-rw-r--r--examples/01.HelloWorld_emscripten/main.cpp240
1 files changed, 240 insertions, 0 deletions
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 <irrlicht.h>
+#include "exampleHelper.h"
+#include <emscripten.h>
+#include <stdio.h>
+
+/*
+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<u32> 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<u32> canvasDim(w,h);
+ if ( canvasDim != screenSize )
+ {
+ screenSize = canvasDim;
+ driver->OnResize(canvasDim);
+ driver->setViewPort(irr::core::rect<irr::s32>(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<s32>(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.
+**/