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
This commit is contained in:
240
examples/01.HelloWorld_emscripten/main.cpp
Normal file
240
examples/01.HelloWorld_emscripten/main.cpp
Normal file
@@ -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.
|
||||
**/
|
Reference in New Issue
Block a user