From 4637ba2281bfba386e548f031424da2ffe86fccd Mon Sep 17 00:00:00 2001 From: cutealien Date: Wed, 5 Jul 2017 12:34:45 +0000 Subject: [PATCH] Add RTT example 13 for emscripten. git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@5498 dfc29bdd-3216-0410-991c-e03cc46cb475 --- .../13.RenderToTexture_emscripten/Makefile | 74 ++++++++ .../13.RenderToTexture_emscripten/main.cpp | 172 ++++++++++++++++++ 2 files changed, 246 insertions(+) create mode 100644 examples/13.RenderToTexture_emscripten/Makefile create mode 100644 examples/13.RenderToTexture_emscripten/main.cpp diff --git a/examples/13.RenderToTexture_emscripten/Makefile b/examples/13.RenderToTexture_emscripten/Makefile new file mode 100644 index 00000000..81dcc442 --- /dev/null +++ b/examples/13.RenderToTexture_emscripten/Makefile @@ -0,0 +1,74 @@ +# Makefile for Irrlicht Examples +# It's usually sufficient to change just the target name and source file list +# and be sure that CXX is set to a valid compiler + +# Name of the executable created (.exe will be added automatically if necessary) +Target := 13.RenderToTexture +# List of source files, separated by spaces +Sources := main.cpp +# Path to Irrlicht directory, should contain include/ and lib/ +IrrlichtHome := ../.. +# Path for the executable. Note that Irrlicht.dll should usually also be there for win32 systems +BinPath = ../../bin/$(SYSTEM) + +all_emscripten: EMSCRIPTEN=1 + +# general compiler settings (might need to be set when compiling the lib, too) +CPPFLAGS += -I$(IrrlichtHome)/include -I/usr/X11R6/include +ifndef NDEBUG + ifdef EMSCRIPTEN + LDFLAGS += -s DEMANGLE_SUPPORT=1 + endif + CXXFLAGS += -g -Wall +else + ifdef EMSCRIPTEN + LDFLAGS += -O3 + endif + CXXFLAGS += -O3 +endif + +#default target is Linux +all: all_emscripten + +# target specific settings +all_linux all_emscripten all_win32 static_win32: LDFLAGS += -L$(IrrlichtHome)/lib/$(SYSTEM) -lIrrlicht +all_linux: LDFLAGS += -L/usr/X11R6/lib$(LIBSELECT) -lGL -lEGL -lGLESv1_CM -lGLESv2 -lXxf86vm -lXext -lX11 -lXcursor +all_linux clean_linux: SYSTEM=Linux +all_emscripten clean_emscripten: SYSTEM=emscripten +all_win32 clean_win32 static_win32: SYSTEM=Win32-gcc +all_win32 clean_win32 static_win32: SUF=.exe +all_emscripten clean_emscripten: SUF=.html +all_emscripten: CXXFLAGS += -fno-exceptions -fno-rtti -fstrict-aliasing -std=gnu++11 -U__STRICT_ANSI__ +all_emscripten: LDFLAGS += -lGL -lSDL --preload-file ../../media@/media -s ALLOW_MEMORY_GROWTH=1 -s NO_EXIT_RUNTIME=1 +static_win32: CPPFLAGS += -D_IRR_STATIC_LIB_ +all_win32: LDFLAGS += -lopengl32 -lEGL -lGLESv1_CM -lGLESv2 -lm +static_win32: LDFLAGS += -lgdi32 -lwinspool -lcomdlg32 -lole32 -loleaut32 -luuid -lodbc32 -lodbccp32 -lopengl32 -lEGL -lGLESv1_CM -lGLESv2 +# name of the binary - only valid for targets which set SYSTEM +DESTPATH = $(BinPath)/$(Target)$(SUF) + +all_linux all_win32 all_emscripten static_win32: + $(warning Building...) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(Sources) -o $(DESTPATH) $(LDFLAGS) + +clean: clean_linux clean_win32 clean_emscripten + $(warning Cleaning...) + +clean_linux clean_win32: + @$(RM) $(DESTPATH) + +clean_emscripten: + @$(RM) $(BinPath)/$(Target).data + @$(RM) $(BinPath)/$(Target).html* + @$(RM) $(BinPath)/$(Target).js + + +.PHONY: all all_win32 all_emscripten static_win32 clean clean_linux clean_win32 clean_emscripten + +#multilib handling +ifeq ($(HOSTTYPE), x86_64) +LIBSELECT=64 +endif +#solaris real-time features +ifeq ($(HOSTTYPE), sun4) +LDFLAGS += -lrt +endif diff --git a/examples/13.RenderToTexture_emscripten/main.cpp b/examples/13.RenderToTexture_emscripten/main.cpp new file mode 100644 index 00000000..f9916887 --- /dev/null +++ b/examples/13.RenderToTexture_emscripten/main.cpp @@ -0,0 +1,172 @@ +/** Example 013 Render To Texture on emscripten +*/ + +#include +#include +#include "exampleHelper.h" + +using namespace irr; + +IrrlichtDevice *device = 0; +video::IVideoDriver* driver = 0; +scene::ISceneManager* smgr = 0; +gui::IGUIEnvironment* guienv = 0; +scene::ICameraSceneNode* fpsCamera = 0; +scene::ICameraSceneNode* fixedCam = 0; +video::IRenderTarget* renderTarget = 0; +scene::ISceneNode* cube = 0; + +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; + } + + driver->beginScene(video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(0)); + + if (renderTarget) + { + // draw scene into render target + + // set render target + driver->setRenderTargetEx(renderTarget, video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(0,0,0,255)); + + // make cube invisible and set fixed camera as active camera + cube->setVisible(false); + smgr->setActiveCamera(fixedCam); + + // draw whole scene into render buffer + smgr->drawAll(); + + // set back old render target + // The buffer might have been distorted, so clear it + driver->setRenderTargetEx(0, 0, video::SColor(0)); + + // make the cube visible and set the user controlled camera as active one + cube->setVisible(true); + smgr->setActiveCamera(fpsCamera); + } + + // draw scene normally + smgr->drawAll(); + guienv->drawAll(); + + driver->endScene(); +} + +int main() +{ + // create device and exit if creation failed + + device = createDevice(video::EDT_WEBGL1, core::dimension2d(640, 480), 16, false, false); + + if (device == 0) + return 1; // could not create selected driver. + + driver = device->getVideoDriver(); + smgr = device->getSceneManager(); + guienv = device->getGUIEnvironment(); + + const io::path mediaPath = getExampleMediaPath(); + + + // load and display animated fairy mesh + scene::IAnimatedMeshSceneNode* fairy = smgr->addAnimatedMeshSceneNode( + smgr->getMesh(mediaPath + "faerie.md2")); + + if (!fairy) + return 1; + + fairy->setMaterialTexture(0, driver->getTexture(mediaPath + "faerie2.bmp")); // set diffuse texture + fairy->setMaterialFlag(video::EMF_LIGHTING, true); // enable dynamic lighting + fairy->getMaterial(0).Shininess = 20.0f; // set size of specular highlights + fairy->setPosition(core::vector3df(-10,0,-100)); + fairy->setMD2Animation ( scene::EMAT_STAND ); + + // add white light + smgr->addLightSceneNode(0, core::vector3df(-15,5,-105), video::SColorf(1.0f, 1.0f, 1.0f)); + + // set ambient light + smgr->setAmbientLight(video::SColor(0,60,60,60)); + + /* + The next is just some standard stuff: Add a test cube and let it rotate + to make the scene more interesting. The user defined camera and cursor + setup is made later on, right before the render loop. + */ + + // create test cube + cube = smgr->addCubeSceneNode(60); + + // let the cube rotate and set some light settings + scene::ISceneNodeAnimator* anim = smgr->createRotationAnimator( + core::vector3df(0.3f, 0.3f,0)); + + cube->setPosition(core::vector3df(-100,0,-100)); + cube->setMaterialFlag(video::EMF_LIGHTING, false); // disable dynamic lighting + cube->addAnimator(anim); + anim->drop(); + + // set window caption + device->setWindowCaption(L"Irrlicht Engine - Render to Texture and Specular Highlights example"); + + /* + To test out the render to texture feature, we need a render target + texture. These are not like standard textures, but need to be created + first. To create one, we call IVideoDriver::addRenderTargetTexture() + and specify the size of the texture. Please don't use sizes bigger than + the frame buffer for this, because the render target shares the zbuffer + with the frame buffer. + Because we want to render the scene not from the user camera into the + texture, we add another fixed camera to the scene. But before we do all + this, we check if the current running driver is able to render to + textures. If it is not, we simply display a warning text. + */ + + // create render target + if (driver->queryFeature(video::EVDF_RENDER_TO_TARGET)) + { + video::ITexture* renderTargetTex = driver->addRenderTargetTexture(core::dimension2d(256, 256), "RTT1", video::ECF_A8R8G8B8); + video::ITexture* renderTargetDepth = driver->addRenderTargetTexture(core::dimension2d(256, 256), "DepthStencil", video::ECF_D16); + + renderTarget = driver->addRenderTarget(); + renderTarget->setTexture(renderTargetTex, renderTargetDepth); + + cube->setMaterialTexture(0, renderTargetTex); // set material of cube to render target + + // add fixed camera + fixedCam = smgr->addCameraSceneNode(0, core::vector3df(10,10,-80), + core::vector3df(-10,10,-100)); + } + else + { + return 1; + } + + // add fps camera + fpsCamera = smgr->addCameraSceneNodeFPS(); + fpsCamera->setPosition(core::vector3df(-50,50,-150)); + +/* + 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); + + return 0; +}