diff --git a/changes.txt b/changes.txt index 490dc90c..39e604ea 100644 --- a/changes.txt +++ b/changes.txt @@ -9,9 +9,20 @@ Changes in ogl-es (not yet released - will be merged with trunk at some point) -------------------------- Changes in 1.9 (not yet released) +- Add example 28.CubeMapping. + Based originally on EnvCubeMap example from irrSpintz engine. + Including a cubemap texture from Emil Persson, aka Humus from http://www.humus.name +- IGeometryCreator::createCubeMesh has a new parameter to allow creating different types of cube meshes. + Added a new cube-mesh with meshbuffers per side. + Also single buffer cube-mesh now normalizes it's normals. +- Bugfix: CBillboardTextSceneNode no longer disregards IsVisible flag +- FPS-camera movement now smoother (it would sometimes skip back because it worked with wrong values for the screen-center position). +- Fix ms3d loader to work on big endian systems which need floats to be aligned in memory. Thanks @ kas1e, Corto and Salas for the patch (http://irrlicht.sourceforge.net/forum/viewtopic.php?f=7&t=52538). +- Bugfix: COBJMeshFileLoder no longer overwrites transparency value with 1.0 when it's set before the diffuse color value in the mtl file. Thanks @Boshen for bugreport (#445). - Bugfix: OpenGL no longer antialiasing stencil buffer when driver has antialiasing disabled. - Add IShadowVolumeSceneNode::setOptimization to allow disabling optimizations for meshes were contour shadows fail. - Stencil shadows work now also with directional light +- Add example 27.PostProcessing written by Boshen Guan - Drivers can now try to create textures from images in more exotic color formats (like floating point formats). It depends on the driver how much that works (so far mainly OpenGL can handle it somewhat). - Fix OpenGL to no longer switch colors red and blue in 24-bit RGB format. But warnings added to documentation to avoid 24-bit textures as they are generally just trouble. - No longer try to convert ECF_R5G6B5 to ECF_A1R5G5B5 on OpenGL (just made texture-loading seem to fail). @@ -80,12 +91,12 @@ Changes in 1.9 (not yet released) - ISceneManager::getMesh can now creates meshes with alternative cache-names. - Lets the BSP loader find textures inserted with relative paths. Thx@ curaga for patch - Slightly simplified ALLOC_STRATEGY_DOUBLE in arrays -- Add alternavive BoundingBox calculation for BillboardSceneNode which can take in a camera node. Thx @Seven and @JacKDuRdEn for bugreports. +- Add alternative BoundingBox calculation for BillboardSceneNode which can take in a camera node. Thx @Seven and @JacKDuRdEn for bugreports. - FPS camera now supports keyboard rotation. - Base FPS-camera movement on last position of mouse instead of always center (works better on platforms where cursor-placement is not allowed) - Octrees with other vertex types than EVT_2TCOORDS can now also use VBO's. - Add IOctreeSceneNode interface to control parameters like VBO usage and polygon clipping checks for octree scene nodes. -- Add support for different geometric primitivs to meshbuffers. Thanks @gerdb for patch proposal (http://irrlicht.sourceforge.net/forum/viewtopic.php?f=7&t=45999) +- Add support for different geometric primitives to meshbuffers. Thanks @gerdb for patch proposal (http://irrlicht.sourceforge.net/forum/viewtopic.php?f=7&t=45999) - change SEvent::SUserEvent.UserData1 and SEvent::SUserEvent.UserData1 from s32 to size_t to avoid cutting numbers on some 64-bit platforms (SDL and Windows) - Improve speed of draw3DBox (OpenGL and D3D9). Thanks @zerochen for patch (https://sourceforge.net/p/irrlicht/patches/256) - Support more keys on OSX "[]\". Thanks @neoascetic for patch (#313). @@ -112,7 +123,7 @@ Changes in 1.9 (not yet released) Several examples got adapted for new ranges. - Pausing timer now pauses animator. Also doesn't reset values anymore with pauses. - Clones no longer have 1000 times the gravity of original animator. -should now be fps independentn + - Should now be fps independent - Speedup CTriangleSelector (mainly for animated meshes) - CTriangleSelector now supports 32-bit meshbuffers. Thanks @Wol101 for reporting and patch-proposal. - Fix: CTriangleSelector no longer resets it's boundingbox to 0,0,0 (was wrong when a meshbuffer was not around 0) @@ -139,7 +150,7 @@ should now be fps independentn - Fix skinned meshes not playing their last frame. Also clarified animation documentation to describe current behavior more exactly. - Add IWriteFile::flush interface (thx @ JLouisB for the patch). - CLightSceneNode::updateAbsolutePosition does now light recalculations. This is to fix using animators with lights. -- Fix collada export for objects with rotations around more than 1 axis. +- Fix Collada export for objects with rotations around more than 1 axis. - Add ISceneNodeAnimatorCameraMaya::setTargetMinDistance and getTargetMinDistance. - Add override font to IGUITreeView - CGUIComboBox now updates selection-list when font changes while it's open (thx @ rubixcuber for bugreport) @@ -168,7 +179,7 @@ should now be fps independentn - mtl (obj) format reader and write now regards texture scaling and translation. (thx @thanhle for noticing and patch proposal). - Added Visual Studio 2013 project files. - Added new color formats: ECF_R8, ECF_R8G8, ECF_D16, ECF_D32, ECF_D24S8. -- Can now enable/disable backround drawing for IGUITable. +- Can now enable/disable background drawing for IGUITable. - Bugfix: Cloning CBillboardSceneNode now copies colors and sizes. - EditBox works now with numpad on X11 - Added helper functions for converting between wchar and utf-8. Patch provided by Hendu. @@ -228,7 +239,7 @@ should now be fps independentn - Add IGUIElement::isTrulyVisible which works like ISceneNode::isTrulyVisible and checks for parent visibility as well. - Improved DDS loader and added support for DXTn (DXT1-5) compressed textures in OpenGL and Direct3D9 drivers. - Add function ISceneNode::getTransformedBoundingBoxEdges. -- Improve automatic compiling under solaris (proposed by curaga) +- Improve automatic compiling under Solaris (proposed by curaga) - Add in IGUICheckBox: setDrawBackground, isDrawBackgroundEnabled, setDrawBorder, isDrawBorderEnabled - IGUISpinBox now passes on the EGET_BUTTON_CLICKED, EGET_EDITBOX_CHANGED and EGET_EDITBOX_ENTER events from it's sub-elements. - IGUISpinBox no longer validates values after each character type but only on KEY_ENTER and when losing focus. New behavior can be set with IGUISpinBox::setValidateOn diff --git a/examples/27.PostProcessing/PostProcessing.cbp b/examples/27.PostProcessing/PostProcessing.cbp index b9fc0873..8c7f68e6 100644 --- a/examples/27.PostProcessing/PostProcessing.cbp +++ b/examples/27.PostProcessing/PostProcessing.cbp @@ -1,56 +1,56 @@ - - - - - - + + + + + + diff --git a/examples/27.PostProcessing/PostProcessing_vc10.vcxproj.user b/examples/27.PostProcessing/PostProcessing_vc10.vcxproj.user deleted file mode 100644 index 695b5c78..00000000 --- a/examples/27.PostProcessing/PostProcessing_vc10.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/examples/27.PostProcessing/PostProcessing_vc11.vcxproj.user b/examples/27.PostProcessing/PostProcessing_vc11.vcxproj.user deleted file mode 100644 index 695b5c78..00000000 --- a/examples/27.PostProcessing/PostProcessing_vc11.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/examples/27.PostProcessing/PostProcessing_vc12.vcxproj.user b/examples/27.PostProcessing/PostProcessing_vc12.vcxproj.user deleted file mode 100644 index 695b5c78..00000000 --- a/examples/27.PostProcessing/PostProcessing_vc12.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/examples/27.PostProcessing/PostProcessing_vc14.vcxproj.user b/examples/27.PostProcessing/PostProcessing_vc14.vcxproj.user deleted file mode 100644 index 695b5c78..00000000 --- a/examples/27.PostProcessing/PostProcessing_vc14.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/examples/27.PostProcessing/main.cpp b/examples/27.PostProcessing/main.cpp index e60b7b69..2f49ccfc 100644 --- a/examples/27.PostProcessing/main.cpp +++ b/examples/27.PostProcessing/main.cpp @@ -1,7 +1,5 @@ /** Example 027 Post Processing -@author Boshen Guan - This tutorial shows how to implement post processing for D3D9 and OpenGL with the engine. In order to do post processing, scene objects are firstly rendered to render target. With the help of screen quad, the render target texture @@ -15,6 +13,8 @@ texture attached to it. A simple color inverse example is presented in this tutorial. The effect is written in HLSL and GLSL. +@author Boshen Guan + We include all headers and define necessary variables as we have done before. */ #include "driverChoice.h" diff --git a/examples/28.CubeMapping/CubeMapping.cbp b/examples/28.CubeMapping/CubeMapping.cbp new file mode 100644 index 00000000..f8025e49 --- /dev/null +++ b/examples/28.CubeMapping/CubeMapping.cbp @@ -0,0 +1,56 @@ + + + + + + diff --git a/examples/28.CubeMapping/CubeMapping_vc10.vcxproj b/examples/28.CubeMapping/CubeMapping_vc10.vcxproj new file mode 100644 index 00000000..403cd970 --- /dev/null +++ b/examples/28.CubeMapping/CubeMapping_vc10.vcxproj @@ -0,0 +1,231 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + 28.CubeMapping + {9A2CE404-75E2-4195-837D-BED5B0FF3FA7} + CubeMapping + + + + Application + false + MultiByte + + + Application + false + MultiByte + + + Application + false + MultiByte + + + Application + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ..\..\bin\Win32-VisualStudio\ + ..\..\bin\Win64-VisualStudio\ + + + ..\..\bin\Win32-VisualStudio\ + ..\..\bin\Win64-VisualStudio\ + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + + + + .\Debug/CubeMapping.tlb + + + + + Disabled + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + + Level3 + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + ..\..\bin\Win32-VisualStudio\28.CubeMapping.exe + ..\..\lib\Win32-visualstudio;%(AdditionalLibraryDirectories) + true + Console + + + + + + + .\Debug/CubeMapping.tlb + + + + + Disabled + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + + Level3 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + ..\..\bin\Win64-VisualStudio\28.CubeMapping.exe + ..\..\lib\Win64-visualstudio;%(AdditionalLibraryDirectories) + true + Console + + + + + + + .\Release/CubeMapping.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + true + + + Level3 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + ..\..\bin\Win32-VisualStudio\28.CubeMapping.exe + ..\..\lib\Win32-visualstudio;%(AdditionalLibraryDirectories) + Console + + + + + + + .\Release/CubeMapping.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + true + + + Level3 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + ..\..\bin\Win64-VisualStudio\28.CubeMapping.exe + ..\..\lib\Win64-visualstudio;%(AdditionalLibraryDirectories) + Console + + + + + + + Disabled + Disabled + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + EnableFastChecks + EnableFastChecks + MaxSpeed + MaxSpeed + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + + \ No newline at end of file diff --git a/examples/28.CubeMapping/CubeMapping_vc11.vcxproj b/examples/28.CubeMapping/CubeMapping_vc11.vcxproj new file mode 100644 index 00000000..bd8bbb92 --- /dev/null +++ b/examples/28.CubeMapping/CubeMapping_vc11.vcxproj @@ -0,0 +1,235 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + 28.CubeMapping + {3DAD16DC-3D80-46EA-ADD8-C4418CEDE553} + CubeMapping + + + + Application + false + MultiByte + v110 + + + Application + false + MultiByte + v110 + + + Application + false + MultiByte + v110 + + + Application + false + MultiByte + v110 + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ..\..\bin\Win32-VisualStudio\ + ..\..\bin\Win64-VisualStudio\ + + + ..\..\bin\Win32-VisualStudio\ + ..\..\bin\Win64-VisualStudio\ + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + + + + .\Debug/CubeMapping.tlb + + + + + Disabled + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + + Level3 + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + ..\..\bin\Win32-VisualStudio\28.CubeMapping.exe + ..\..\lib\Win32-visualstudio;%(AdditionalLibraryDirectories) + true + Console + + + + + + + .\Debug/CubeMapping.tlb + + + + + Disabled + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + + Level3 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + ..\..\bin\Win64-VisualStudio\28.CubeMapping.exe + ..\..\lib\Win64-visualstudio;%(AdditionalLibraryDirectories) + true + Console + + + + + + + .\Release/CubeMapping.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + true + + + Level3 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + ..\..\bin\Win32-VisualStudio\28.CubeMapping.exe + ..\..\lib\Win32-visualstudio;%(AdditionalLibraryDirectories) + Console + + + + + + + .\Release/CubeMapping.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + true + + + Level3 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + ..\..\bin\Win64-VisualStudio\28.CubeMapping.exe + ..\..\lib\Win64-visualstudio;%(AdditionalLibraryDirectories) + Console + + + + + + + Disabled + Disabled + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + EnableFastChecks + EnableFastChecks + MaxSpeed + MaxSpeed + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + + \ No newline at end of file diff --git a/examples/28.CubeMapping/CubeMapping_vc12.vcxproj b/examples/28.CubeMapping/CubeMapping_vc12.vcxproj new file mode 100644 index 00000000..1c7f9201 --- /dev/null +++ b/examples/28.CubeMapping/CubeMapping_vc12.vcxproj @@ -0,0 +1,235 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + 28.CubeMapping + {1FDD5E75-9EB3-4467-B672-0BFC105B84A5} + CubeMapping + + + + Application + false + MultiByte + v110 + + + Application + false + MultiByte + v110 + + + Application + false + MultiByte + v110 + + + Application + false + MultiByte + v110 + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ..\..\bin\Win32-VisualStudio\ + ..\..\bin\Win64-VisualStudio\ + + + ..\..\bin\Win32-VisualStudio\ + ..\..\bin\Win64-VisualStudio\ + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + + + + .\Debug/CubeMapping.tlb + + + + + Disabled + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + + Level3 + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + ..\..\bin\Win32-VisualStudio\28.CubeMapping.exe + ..\..\lib\Win32-visualstudio;%(AdditionalLibraryDirectories) + true + Console + + + + + + + .\Debug/CubeMapping.tlb + + + + + Disabled + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + + Level3 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + ..\..\bin\Win64-VisualStudio\28.CubeMapping.exe + ..\..\lib\Win64-visualstudio;%(AdditionalLibraryDirectories) + true + Console + + + + + + + .\Release/CubeMapping.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + true + + + Level3 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + ..\..\bin\Win32-VisualStudio\28.CubeMapping.exe + ..\..\lib\Win32-visualstudio;%(AdditionalLibraryDirectories) + Console + + + + + + + .\Release/CubeMapping.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + true + + + Level3 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + ..\..\bin\Win64-VisualStudio\28.CubeMapping.exe + ..\..\lib\Win64-visualstudio;%(AdditionalLibraryDirectories) + Console + + + + + + + Disabled + Disabled + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + EnableFastChecks + EnableFastChecks + MaxSpeed + MaxSpeed + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + + \ No newline at end of file diff --git a/examples/28.CubeMapping/CubeMapping_vc14.vcxproj b/examples/28.CubeMapping/CubeMapping_vc14.vcxproj new file mode 100644 index 00000000..55e11efc --- /dev/null +++ b/examples/28.CubeMapping/CubeMapping_vc14.vcxproj @@ -0,0 +1,235 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + 28.CubeMapping + {DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A} + CubeMapping + + + + Application + false + MultiByte + v140 + + + Application + false + MultiByte + v140 + + + Application + false + MultiByte + v140 + + + Application + false + MultiByte + v140 + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ..\..\bin\Win32-VisualStudio\ + ..\..\bin\Win64-VisualStudio\ + + + ..\..\bin\Win32-VisualStudio\ + ..\..\bin\Win64-VisualStudio\ + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + + + + .\Debug/CubeMapping.tlb + + + + + Disabled + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + + Level3 + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + ..\..\bin\Win32-VisualStudio\28.CubeMapping.exe + ..\..\lib\Win32-visualstudio;%(AdditionalLibraryDirectories) + true + Console + + + + + + + .\Debug/CubeMapping.tlb + + + + + Disabled + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + + Level3 + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + ..\..\bin\Win64-VisualStudio\28.CubeMapping.exe + ..\..\lib\Win64-visualstudio;%(AdditionalLibraryDirectories) + true + Console + + + + + + + .\Release/CubeMapping.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + true + + + Level3 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + ..\..\bin\Win32-VisualStudio\28.CubeMapping.exe + ..\..\lib\Win32-visualstudio;%(AdditionalLibraryDirectories) + Console + + + + + + + .\Release/CubeMapping.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\include;%(AdditionalIncludeDirectories) + WIN32;WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + true + + + Level3 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c07 + + + ..\..\bin\Win64-VisualStudio\28.CubeMapping.exe + ..\..\lib\Win64-visualstudio;%(AdditionalLibraryDirectories) + Console + + + + + + + Disabled + Disabled + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + EnableFastChecks + EnableFastChecks + MaxSpeed + MaxSpeed + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + + \ No newline at end of file diff --git a/examples/28.CubeMapping/Makefile b/examples/28.CubeMapping/Makefile new file mode 100644 index 00000000..22514c2c --- /dev/null +++ b/examples/28.CubeMapping/Makefile @@ -0,0 +1,38 @@ +# 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 +Target = 28.CubeMapping +Sources = main.cpp + +# general compiler settings +CPPFLAGS = -I../../include -I/usr/X11R6/include +CXXFLAGS = -O3 -ffast-math +#CXXFLAGS = -g -Wall + +#default target is Linux +all: all_linux + +ifeq ($(HOSTTYPE), x86_64) +LIBSELECT=64 +endif + +# target specific settings +all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor +all_linux clean_linux: SYSTEM=Linux +all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm +all_win32 clean_win32: SYSTEM=Win32-gcc +all_win32 clean_win32: SUF=.exe +# name of the binary - only valid for targets which set SYSTEM +DESTPATH = ../../bin/$(SYSTEM)/$(Target)$(SUF) + +all_linux all_win32: + $(warning Building...) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(Sources) -o $(DESTPATH) $(LDFLAGS) + +clean: clean_linux clean_win32 + $(warning Cleaning...) + +clean_linux clean_win32: + @$(RM) $(DESTPATH) + +.PHONY: all all_win32 clean clean_linux clean_win32 diff --git a/examples/28.CubeMapping/main.cpp b/examples/28.CubeMapping/main.cpp new file mode 100644 index 00000000..b831d318 --- /dev/null +++ b/examples/28.CubeMapping/main.cpp @@ -0,0 +1,770 @@ +/** Example 028 CubeMapping + +Shows usage of cubemap textures and how to do some simple environment mapping. +Cubemap textures have images for all 6 directions of a cube in a single texture. +Environment is used to reflect the environment around an object onto the object. +Cubemaps only work with shader materials which are written to support cube mapping. + +@author Michael Zeilfelder, based on EnvCubeMap example from irrSpintz engine. + +Start with the usual includes. +*/ + +#ifdef _MSC_VER +#pragma comment(lib, "Irrlicht.lib") +#endif + +#include +#include "driverChoice.h" +#include "exampleHelper.h" + +using namespace irr; + + +/* + A callback class for our cubemap shader. + We need a shader material which maps the cubemap texture to + the polygon vertices of objects. +*/ +class CubeMapReflectionCallback : public video::IShaderConstantSetCallBack +{ +public: + CubeMapReflectionCallback(scene::ISceneManager* smgr, int styleUVW) + : SceneMgr(smgr) + , StyleUVW(styleUVW), Roughness(0.f) + , styleUvwID(-1) , worldViewProjID(-1), worldID(-1), cameraPosID(-1) + {} + + /* + Setting the style to map vertex UV-coordinates to the cubemap textures. + - Specular style is typically used for mirrors and highlight reflections. + - Diffuse style is commonly used in image based lighting calculations and + often in combination with a higher roughness. Think of it as the sum of all + light which reaches a point on your object. + - Using model vertices directly for UV's is just nice for testing sometimes. + Maybe has more uses? Experiment around :-) + */ + void SetStyleUVW(int style) + { + StyleUVW = style; + } + + int GetStyleUVW() const + { + return StyleUVW; + } + + /* + We could also call this sharpness as the rougher a material the less + sharp the reflections of a cubemap are (light for rough materials + spreads out more while smooth materials reflect it more like a mirror). + Roughness is calculated using the mipmaps of the cubemap texture. + Note that rendertarget cubemap textures won't have mipmaps, so unfortunately + it won't work for those. + Also currently only OpenGL is able to interpolate seamless over cubemap borders. + On Direct3D9 you will only smooth per side, but not over side-borders. + */ + void SetRoughness(float roughness) + { + Roughness = roughness; + } + + float getRoughness() const + { + return Roughness; + } + + /* + Typical code which passes a few values from c++ to shader. + */ + virtual void OnSetMaterial(const video::SMaterial& material) + {} + + virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData) + { + video::IVideoDriver* driver = services->getVideoDriver(); + + if ( worldViewProjID < 0 ) // first update + { + styleUvwID = services->getVertexShaderConstantID("StyleUVW"); + if( driver->getDriverType() == video::EDT_DIRECT3D9 ) + { + worldViewProjID = services->getVertexShaderConstantID("WorldViewProj"); + } + worldID = services->getVertexShaderConstantID("World"); + cameraPosID = services->getVertexShaderConstantID("CameraPos"); + roughnessID = services->getPixelShaderConstantID("Roughness"); + } + + services->setVertexShaderConstant(styleUvwID, &StyleUVW, 1 ); + + irr::core::matrix4 world = driver->getTransform(irr::video::ETS_WORLD); + services->setVertexShaderConstant(worldID, world.pointer(), 16); + + if( driver->getDriverType() == video::EDT_DIRECT3D9 ) + { + irr::core::matrix4 worldViewProj; + worldViewProj = driver->getTransform(irr::video::ETS_PROJECTION); + worldViewProj *= driver->getTransform(irr::video::ETS_VIEW); + worldViewProj *= world; + services->setVertexShaderConstant(worldViewProjID, worldViewProj.pointer(), 16); + } + + core::vector3df cameraPos = SceneMgr->getActiveCamera()->getAbsolutePosition(); + services->setVertexShaderConstant(cameraPosID, &cameraPos.X, 3 ); + services->setPixelShaderConstant(roughnessID, &Roughness, 1 ); + } + +private: + scene::ISceneManager* SceneMgr; + + int StyleUVW; // 0 = specular, 1=diffuse, 2 = use model vertex coordinates for uvw. + float Roughness; // cubemap 0 = specular ... highest value depends on number of mipmaps in the texture + + irr::s32 styleUvwID; + irr::s32 worldViewProjID; + irr::s32 worldID; + irr::s32 cameraPosID; + irr::s32 roughnessID; +}; + +/* + To keep the example compact our event-receiver acts also like a main + application class. So it handles user input, updates the dynamic parts of + the UI and it keeps some 3d nodes around. +*/ +class MyEventReceiver : public IEventReceiver +{ +public: + MyEventReceiver() : Driver(0), Shader(0) + ,BackgroundSkybox(0), BackgroundCube(0) + , CubemapUpdates(2) + , CurrentStyleUVW(0), CurrentRoughness(0) + , NeedCubemapUpdate(true) + { + StyleNamesUVW.push_back( L"specular" ); + StyleNamesUVW.push_back( L"diffuse" ); + StyleNamesUVW.push_back( L"model coordinates" ); + } + + // Handle the key input + virtual bool OnEvent(const SEvent& event) + { + if (event.EventType == EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown == false) + { + switch(event.KeyInput.Key ) + { + case KEY_SPACE: + // Switch between different texture mapping styles + if ( Shader ) + { + Shader->SetStyleUVW((Shader->GetStyleUVW()+1)%StyleNamesUVW.size()); + updateStyleUVW(); + } + break; + case KEY_KEY_B: + // Switch between our 2 different backgrounds + if ( BackgroundSkybox && BackgroundCube ) + { + if ( BackgroundSkybox->isVisible() ) + { + BackgroundSkybox->setVisible(false); + BackgroundCube->setVisible(true); + } + else + { + BackgroundSkybox->setVisible(true); + BackgroundCube->setVisible(false); + } + NeedCubemapUpdate = true; + } + break; + case KEY_KEY_I: + // Show/hide the info text nodes + for (u32 i=0; isetVisible(!InfoTextNodes[i]->isVisible()); + break; + case KEY_KEY_S: + // Enable/disable seamless smoothing of mipmaps over cube borders + if ( Driver ) + { + Driver->disableFeature(video::EVDF_TEXTURE_CUBEMAP_SEAMLESS, Driver->queryFeature(video::EVDF_TEXTURE_CUBEMAP_SEAMLESS) ); + updateSeamless(); + } + break; + case KEY_KEY_U: + // Switch dynamic cubemap updates on/off. + CubemapUpdates = (CubemapUpdates+1) % 3; + updateCubemapUpdates(); + break; + case KEY_PLUS: + case KEY_ADD: + // Make material rougher + if ( Shader ) + { + Shader->SetRoughness( Shader->getRoughness() + 0.5f ); + updateRoughness(); + } + break; + case KEY_MINUS: + case KEY_SUBTRACT: + { + // Make material smoother + if ( Shader ) + { + float roughness = Shader->getRoughness() - 0.5f; + if ( roughness >= 0.f ) + { + Shader->SetRoughness(roughness); + updateRoughness(); + } + } + break; + } + default: + break; + } + } + + return false; + } + + // Some helper functions to update the UI + void updateStyleUVW() + { + if ( CurrentStyleUVW && Shader) + CurrentStyleUVW->setText(StyleNamesUVW[Shader->GetStyleUVW()].c_str()); + } + + void updateRoughness() + { + if ( CurrentRoughness && Shader ) + { + CurrentRoughness->setText( irr::core::stringw(Shader->getRoughness()).c_str() ); + } + } + + void updateSeamless() + { + if ( CurrentSeamlessCubemap && Driver ) + { + CurrentSeamlessCubemap->setText( Driver->queryFeature(video::EVDF_TEXTURE_CUBEMAP_SEAMLESS) ? L"ON" : L"OFF" ); + } + } + + void updateCubemapUpdates() + { + if ( CurrentCubemapUpdates ) + { + switch ( CubemapUpdates ) + { + case 0: CurrentCubemapUpdates->setText( L"static"); break; + case 1: CurrentCubemapUpdates->setText( L"dynamic" ); break; + case 2: CurrentCubemapUpdates->setText( L"dynamic+mips" ); break; + } + } + } + + // Check if the cubemap textures should be updated with new screenshots + // return 0 for no update, 1 for update, 2 for update and fix mip-maps + int checkCubemapUpdate() + { + if ( NeedCubemapUpdate || CubemapUpdates == 2) + { + NeedCubemapUpdate = false; + return 2; + } + + return CubemapUpdates; + } + + // Add some text-node floating above it's parent node. + void addInfoTextNode(irr::gui::IGUIFont* font, const wchar_t* text, irr::scene::ISceneNode* parent) + { + if ( parent ) + { + const video::SColor infoTextCol(250, 70, 90, 90); + core::dimension2du dim(font->getDimension(text)); + core::dimension2df dimf((f32)dim.Width, (f32)dim.Height); + scene::IBillboardTextSceneNode* infoNode = parent->getSceneManager()->addBillboardTextSceneNode( font, text, parent, dimf, core::vector3df(0, 120, 0), -1, infoTextCol, infoTextCol); + InfoTextNodes.push_back(infoNode); + } + } + + irr::video::IVideoDriver* Driver; + CubeMapReflectionCallback* Shader; + + scene::ISceneNode* BackgroundSkybox; + scene::ISceneNode* BackgroundCube; + irr::core::array InfoTextNodes; + + int CubemapUpdates; // 0 = static, 1 = dynamic, 2 = dynamic with rtt + + irr::core::array StyleNamesUVW; + + irr::gui::IGUIStaticText* CurrentStyleUVW; + irr::gui::IGUIStaticText* CurrentRoughness; + irr::gui::IGUIStaticText* CurrentSeamlessCubemap; + irr::gui::IGUIStaticText* CurrentCubemapUpdates; + +private: + bool NeedCubemapUpdate; +}; + +/* Workaround for OpenGL's upside-down images. + Texture origins (0,0) in OpenGL are usually at the left-bottom instead of the more common left-top image formats. + Irrlicht internally uses textures with left-top origin and then corrects the texture-matrices in the fixed-function pipeline. + For shader materials it's left to the users to handle those UV-flips for the texture-matrix. + Render target textures (RTT's) in OpenGL are rendered with left-bottom origin and Irrlicht can't change that, so all RTT textures + in memory are upside-down (unlike all other Irrlicht textures). + In the fixed function pipeline Irrlicht handles this by flipping the RTT's texture matrix once more and for shaders it's again + left to the users to handle it. + Cubemap textures are different from other textures in OpenGL. Each cube side has left-top as the origin. So not flipping Irrlicht textures for those would be fine. + Except - OpenGL RTT's still render left-bottom - even when the target is a cubemap RTT. + I found no good way around this so far - it just seems messed up as we get a left-handed/right handed coordinate system change that way. + + So... the following 2 defines are two different workarounds I found. Both are ugly, which one is better in reality depends probably on the scene. + Only use one of those: + CUBEMAP_UPSIDE_DOWN_GL_PROJECTION is relatively fast as it just changes the project matrix. The problem is that changing the projection matrix + means changing front/backside culling. So every node rendered has to flip the material flags for those. + + CUBEMAP_USPIDE_DOWN_RTT will change the texture memory itself and flip the image upside-down. + While easier to do, this involves texture-locking and is very slow. +*/ +#define CUBEMAP_UPSIDE_DOWN_GL_PROJECTION +//#define CUBEMAP_USPIDE_DOWN_RTT + + +// Flip frontface/backface culling for all nodes +#ifdef CUBEMAP_UPSIDE_DOWN_GL_PROJECTION +void flipCullingFlags(const core::array& nodes) +{ + for ( irr::u32 n=0; n < nodes.size(); ++n ) + { + scene::ISceneNode* node = nodes[n]; + const irr::u32 matCount = node->getMaterialCount(); + for ( irr::u32 m=0; m < matCount; ++m) + { + video::SMaterial& mat = node->getMaterial(m); + mat.BackfaceCulling = !mat.BackfaceCulling; + mat.FrontfaceCulling = !mat.FrontfaceCulling; + } + } +} +#endif + + +/* + Render the environment around a node into a cubemap texture. +*/ +void renderEnvironmentCubeMap(irr::video::IVideoDriver* driver, irr::scene::ICameraSceneNode* cubeMapCamera, irr::scene::ISceneNode* cubeCenterNode, video::IRenderTarget* cubeMapRT, video::ITexture* dynamicCubeMapRTT, video::ITexture* depthStencilRTT) +{ + // Change to the cubemap camera which has a few specific render-settings + scene::ISceneManager* smgr = cubeMapCamera->getSceneManager(); + scene::ICameraSceneNode * oldCam = smgr->getActiveCamera(); + smgr->setActiveCamera( cubeMapCamera ); + + /* + We want to see everything around the center node, so hide the node + itself, otherwise it would be in the way. + Then set the camera to that node's position. + */ + cubeCenterNode->setVisible( false ); + const core::vector3df center( cubeCenterNode->getAbsolutePosition() ); + cubeMapCamera->setPosition( center ); + + /* + Render all 6 directions. Which means simple setting the camera target/up + vector to all 6 directions and then render the full scene each time. + So yeah - updating an environment cube-map means 6 full renders for each + object which needs an environment map. In other words - you generally only + want to do that in pre-processing, not in realtime. + */ + const core::vector3df targetVecs[6] = { + core::vector3df(1.f, 0.f, 0.f), + core::vector3df(-1.f, 0.f, 0.f), + core::vector3df(0.f, 1.f, 0.f), + core::vector3df(0.f, -1.f, 0.f), + core::vector3df(0.f, 0.f, 1.f), + core::vector3df(0.f, 0.f, -1.f) + }; + + const core::vector3df upVecs[6] = { + core::vector3df( 0,1,0 ), + core::vector3df( 0,1,0 ), + core::vector3df( 0,0,-1 ), + core::vector3df( 0,0,1 ), + core::vector3df( 0,1,0 ), + core::vector3df( 0,1,0 ) + }; + for ( int s=0; s<6; ++s ) + { + cubeMapCamera->setUpVector( upVecs[s] ); + cubeMapCamera->setTarget( center + targetVecs[s] ); + // Here we tell into which side of the cubemap texture we want to write + cubeMapRT->setTexture(dynamicCubeMapRTT, depthStencilRTT, (video::E_CUBE_SURFACE)(video::ECS_POSX + s)); + driver->setRenderTargetEx(cubeMapRT, video::ECBF_ALL); + smgr->drawAll(); + +#ifdef CUBEMAP_USPIDE_DOWN_RTT + // This works because the lock for rtt's always flips in Irrlicht. + // So in this case lock() unlock will result in a flipped texture + // But be warned - it's very, very slow! + driver->setRenderTarget(0); // to avoid accessing active rt + dynamicCubeMapRTT->lock(video::ETLM_READ_WRITE, 0, s, video::ETLF_FLIP_Y_UP_RTT); + dynamicCubeMapRTT->unlock(); +#endif + } + + //dynamicCubeMapRTT->regenerateMipMapLevels(); // Unfortunately we can't seem to have mipmaps for rtt's + + driver->setRenderTarget(0); + cubeCenterNode->setVisible( true ); + smgr->setActiveCamera( oldCam ); +} + +/* + Typical setup at the main start. +*/ +int main() +{ + // Ask user for driver + video::E_DRIVER_TYPE driverType = driverChoiceConsole(); + if (driverType==video::EDT_COUNT) + return 1; + + // Create device + MyEventReceiver eventReceiver; + const core::dimension2d dimDevice(1024, 768); + IrrlichtDevice* device = createDevice( driverType, dimDevice, 32, false, false, false, &eventReceiver ); + if (!device) + return 1; + + const io::path mediaPath = getExampleMediaPath(); + video::IVideoDriver* driver = device->getVideoDriver(); + scene::ISceneManager* smgr = device->getSceneManager(); + gui::IGUIEnvironment* env = device->getGUIEnvironment(); + eventReceiver.Driver = driver; + + // Set window title + core::stringw strCaption(L"Cubemap example - Irrlicht Engine ["); + strCaption += driver->getName(); + strCaption += L"]"; + device->setWindowCaption(strCaption.c_str()); + + // set a nicer font + gui::IGUISkin* skin = env->getSkin(); + gui::IGUIFont* font = env->getFont(mediaPath + "fonthaettenschweiler.bmp"); + if (font) + skin->setFont(font); + + /* + Create a shader material for cube mapping + */ + video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices(); + s32 cubeMapReflectionMaterial = 0; + if( gpu ) + { + // Decide on shader to use based on active driver + irr::io::path vsFileName; + irr::io::path psFileName; + switch( driverType ) + { + case video::EDT_DIRECT3D9: + vsFileName = mediaPath + "cubeMapReflectionVS.hlsl"; + psFileName = mediaPath + "cubeMapReflectionPS.hlsl"; + break; + + case video::EDT_OPENGL: + vsFileName = mediaPath + "cubeMapReflection.vert"; + psFileName = mediaPath + "cubeMapReflection.frag"; + break; + } + + CubeMapReflectionCallback* cubeMapCB = new CubeMapReflectionCallback(smgr, 2); + cubeMapReflectionMaterial = gpu->addHighLevelShaderMaterialFromFiles( + vsFileName, "VS", video::EVST_VS_1_1, + psFileName, "PS", video::EPST_PS_3_0, + cubeMapCB, video::EMT_SOLID ); + if ( cubeMapReflectionMaterial >= 0 ) + eventReceiver.Shader = cubeMapCB; + cubeMapCB->drop(); + } + + // add fps camera + scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS(0, 100.f, 1.f); + camera->setPosition( core::vector3df( 0,10,-200 ) ); + device->getCursorControl()->setVisible(false); + + /* + Get 6 images forming a cubemap. The coordinate system used in those images + seemed to be different than the one in Irrlicht. I decided to leave it like + that because it's pretty common that way. If you get cubemap textures which + seem to have x/y/z axis named different you'll just have to experiment until + you figured out the correct order. + */ + core::array cubeMapImages; + cubeMapImages.push_back(driver->createImageFromFile( mediaPath + "cubemap_posx.jpg" )); + cubeMapImages.push_back(driver->createImageFromFile( mediaPath + "cubemap_negx.jpg" )); + cubeMapImages.push_back(driver->createImageFromFile( mediaPath + "cubemap_posy.jpg" )); + cubeMapImages.push_back(driver->createImageFromFile( mediaPath + "cubemap_negy.jpg" )); + cubeMapImages.push_back(driver->createImageFromFile( mediaPath + "cubemap_posz.jpg" )); + cubeMapImages.push_back(driver->createImageFromFile( mediaPath + "cubemap_negz.jpg" )); + + /* Create a cubemap texture from those images. Note that 6 images become a single texture now. */ + video::ITexture* cubeMapStaticTex = 0; + cubeMapStaticTex = driver->addTextureCubemap("cm", cubeMapImages[0], cubeMapImages[1], cubeMapImages[2], cubeMapImages[3], cubeMapImages[4], cubeMapImages[5]); + for ( u32 i=0; idrop(); + cubeMapImages.clear(); + + /* Create a render target, cubemap render-target-textures and a camera with settings for cube mapping */ + video::IRenderTarget* cubeMapRT = driver->addRenderTarget(); + video::ITexture* dynamicCubeMapRTT = 0; + video::ITexture* depthStencilRTT = 0; + video::ITexture* dynamicCubeMapRTT_intermediate = 0; // just for rendering, but not used in material + video::ITexture* dynamicCubeMapTex = 0; // dynamic and with mipmaps + scene::ICameraSceneNode* cubeMapCamera = 0; + if( driver->queryFeature( video::EVDF_RENDER_TO_TARGET ) ) + { + // Create cube map textures and render target cubemap textures. + const u32 dynamicCubeMapSize = 512; + dynamicCubeMapRTT = driver->addRenderTargetTextureCubemap(dynamicCubeMapSize, "cube_rtr"); + depthStencilRTT = driver->addRenderTargetTexture(irr::core::dimension2du(dynamicCubeMapSize, dynamicCubeMapSize), "cubemap_ds", irr::video::ECF_D24S8); + + dynamicCubeMapRTT_intermediate = driver->addRenderTargetTextureCubemap(dynamicCubeMapSize, "cube_rtr"); + dynamicCubeMapTex = driver->addTextureCubemap(dynamicCubeMapSize, "cube_tex"); + + // Camera for creating an environment cubemap + cubeMapCamera = smgr->addCameraSceneNode(); + cubeMapCamera->setFOV(core::PI* 0.5f); // 90° view angle + cubeMapCamera->setAspectRatio(1.f); // it's a cube... all sides have the same length + smgr->setActiveCamera( camera ); + } + + /* + Add sphere-nodes which will be using the cubemaps as materials. + You may also want to experiment with other node-types here! + */ + + scene::ISceneNode* sphereNode = 0; + scene::ISceneNode* sphereNode2 = 0; + scene::ISceneNode* sphereNode3 = 0; + scene::IMesh* sphereMesh = smgr->getGeometryCreator()->createSphereMesh(100.f); + if( sphereMesh ) + { + // Nothing really special here except they need the shader material to display cubemaps. + sphereNode = smgr->addMeshSceneNode( sphereMesh ); + sphereNode->setPosition( core::vector3df(-250,0,0) ); + sphereNode->updateAbsolutePosition(); + sphereNode->setMaterialFlag( video::EMF_LIGHTING, false ); + sphereNode->setMaterialTexture( 0, dynamicCubeMapRTT ); + sphereNode->setMaterialType( (video::E_MATERIAL_TYPE)cubeMapReflectionMaterial ); + eventReceiver.addInfoTextNode(font, L"Cubemap dynamic rtt, no mip-maps", sphereNode); + + if ( dynamicCubeMapTex ) + { + sphereNode3 = smgr->addMeshSceneNode( sphereMesh ); + sphereNode3->setPosition( core::vector3df(0,0,250) ); + sphereNode3->updateAbsolutePosition(); + sphereNode3->setMaterialFlag( video::EMF_LIGHTING, false ); + sphereNode3->setMaterialTexture( 0, dynamicCubeMapTex ); + sphereNode3->getMaterial(0).TextureLayer[0].TrilinearFilter = false; // this is default anyway. It would be faster - but you can only access integer mip-levels - no filtering between mip-levels. + sphereNode3->setMaterialType( (video::E_MATERIAL_TYPE)cubeMapReflectionMaterial ); + eventReceiver.addInfoTextNode(font, L"Cubemap dynamic with mip-maps", sphereNode3); + } + + if ( cubeMapStaticTex ) + { + sphereNode2 = smgr->addMeshSceneNode( sphereMesh ); + sphereNode2->setPosition( core::vector3df(250,0,0) ); + sphereNode2->updateAbsolutePosition(); + sphereNode2->setMaterialFlag( video::EMF_LIGHTING, false ); + sphereNode2->setMaterialTexture( 0, cubeMapStaticTex ); + sphereNode2->getMaterial(0).TextureLayer[0].TrilinearFilter = true; // this way smoothing happens between different mip-levels. + sphereNode2->setMaterialType( (video::E_MATERIAL_TYPE)cubeMapReflectionMaterial ); + eventReceiver.addInfoTextNode(font, L"Cubemap fixed images", sphereNode2); + } + + sphereMesh->drop(); + } + + /* Add some background which will show up in the environment maps. + For first one we use the same textures as used in the spheres. + Note the difference between a skybox and a cubemap is that the skybox really uses 6 different + textures. While the cubemap uses a single texture created from 6 images. */ + eventReceiver.BackgroundSkybox = smgr->addSkyBoxSceneNode( + driver->getTexture(mediaPath + "cubemap_posy.jpg"), // top + driver->getTexture(mediaPath + "cubemap_negy.jpg"), // bottom + driver->getTexture(mediaPath + "cubemap_posz.jpg"), // left + driver->getTexture(mediaPath + "cubemap_negz.jpg"), // right + driver->getTexture(mediaPath + "cubemap_posx.jpg"), // front + driver->getTexture(mediaPath + "cubemap_negx.jpg")); // back + + + + /* Another background for comparison and to make it more obvious + when the spheres reflect the environment and when they use static cubemaps. */ + scene::IMesh * cubeMesh = smgr->getGeometryCreator()->createCubeMesh( core::vector3df(10.f, 10.f, 10.f), scene::ECMT_6BUF_4VTX_NP); + smgr->getMeshManipulator()->scale(cubeMesh, core::vector3df(-1, 1, 1)); + if( cubeMesh ) + { + smgr->getMeshManipulator()->setVertexColors( cubeMesh->getMeshBuffer(0), video::SColor(255, 240, 10, 10) ); + smgr->getMeshManipulator()->setVertexColors( cubeMesh->getMeshBuffer(1), video::SColor(255, 240, 130, 10) ); + smgr->getMeshManipulator()->setVertexColors( cubeMesh->getMeshBuffer(2), video::SColor(255, 50, 250, 10) ); + smgr->getMeshManipulator()->setVertexColors( cubeMesh->getMeshBuffer(3), video::SColor(255, 70, 10, 250) ); + smgr->getMeshManipulator()->setVertexColors( cubeMesh->getMeshBuffer(4), video::SColor(255, 240, 250, 10) ); + smgr->getMeshManipulator()->setVertexColors( cubeMesh->getMeshBuffer(5), video::SColor(255, 85, 250, 250) ); + + eventReceiver.BackgroundCube = smgr->addMeshSceneNode( cubeMesh ); + cubeMesh->drop(); + + eventReceiver.BackgroundCube->setScale( core::vector3df( 200, 200, 200 ) ); + eventReceiver.BackgroundCube->setMaterialFlag( video::EMF_LIGHTING, false ); + eventReceiver.BackgroundCube->setVisible(false); + } + +#ifdef CUBEMAP_UPSIDE_DOWN_GL_PROJECTION + if ( driverType == video::EDT_OPENGL ) + { + // Flip projection matrix (note this also flips front/backface culling) + core::matrix4 matProj = cubeMapCamera->getProjectionMatrix(); + matProj[4] = -matProj[4]; + matProj[5] = -matProj[5]; + matProj[6] = -matProj[6]; + matProj[7] = -matProj[7]; + cubeMapCamera->setProjectionMatrix(matProj); + } +#endif + + /* + Add some moving node to show the difference between static/dynamic environment maps + */ + scene::IMeshSceneNode * movingNode = smgr->addCubeSceneNode(30.f); + movingNode->getMaterial(0).Lighting = false; + smgr->getMeshManipulator()->setVertexColors( movingNode->getMesh()->getMeshBuffer(0), video::SColor(255, 230, 200, 150)); + scene::ISceneNodeAnimator* circleAnimator = smgr->createFlyCircleAnimator(core::vector3df(-125, -50.f, 125), 300.f, 0.0005f); + movingNode->addAnimator(circleAnimator); + circleAnimator->drop(); + + /* Add some UI */ + if ( eventReceiver.Shader ) + { + skin->setColor(gui::EGDC_3D_FACE, video::SColor(50, 160, 120, 120)); + + u32 top = dimDevice.Height - 200; + const u32 left = dimDevice.Width - 350; + const u32 right = dimDevice.Width - 10; + irr::gui::IGUIStaticText * stextUVW = env->addStaticText(L" Style of generating texture coordinates:\n Change with (space)", core::recti(left, top, right, top+35), false, true, 0, -1, true); + top += 40; + stextUVW->setTextAlignment(gui::EGUIA_UPPERLEFT, gui::EGUIA_UPPERLEFT); + eventReceiver.CurrentStyleUVW = env->addStaticText(L"", core::recti(240,0, 400, 20), false, false, stextUVW); + eventReceiver.updateStyleUVW(); + + irr::gui::IGUIStaticText * stextRoughness = env->addStaticText(L" Roughness:\n Change with (+) and (-)", core::recti(left, top, right, top+35), false, true, 0, -1, true); + top += 40; + eventReceiver.CurrentRoughness = env->addStaticText( L"", core::recti(240,0, 400, 20), false, false, stextRoughness); + eventReceiver.updateRoughness(); + + irr::gui::IGUIStaticText * stextSeamlessCupemap = env->addStaticText(L" Seamless cubemap (with roughness):\n Change with (s)", core::recti(left, top, right, top+35), false, true, 0, -1, true); + top += 40; + eventReceiver.CurrentSeamlessCubemap = env->addStaticText( L"", core::recti(240,0, 400, 20), false, false, stextSeamlessCupemap); + eventReceiver.updateSeamless(); + + irr::gui::IGUIStaticText * stextUpdates = env->addStaticText(L" Cubemap updates:\n Change with (u)", core::recti(left, top, right, top+35), false, true, 0, -1, true); + top += 40; + eventReceiver.CurrentCubemapUpdates = env->addStaticText( L"", core::recti(240,0, 400, 20), false, false, stextUpdates); + eventReceiver.updateCubemapUpdates(); + + env->addStaticText(L" Change background with (b)", core::recti(left, top, right, top+15), false, true, 0, -1, true); + top += 20; + + env->addStaticText(L" Show/hide info nodes with (i)", core::recti(left, top, right, top+15), false, true, 0, -1, true); + } + + + /* Main loop */ + while(device->run()) + { + if (device->isWindowActive()) + { + driver->beginScene(true, true, video::SColor(255, 127, 127, 255)); + + /* Check if we want to update the environment maps. + Usually not something you'll do every frame, but either once at the star + or maybe updating an environment map once in a while. + */ + int updateCubemaps = eventReceiver.checkCubemapUpdate(); + if( dynamicCubeMapRTT && sphereNode && updateCubemaps > 0 ) + { +#ifdef CUBEMAP_UPSIDE_DOWN_GL_PROJECTION + core::array allNodes; + if ( driverType == video::EDT_OPENGL ) + { + /* + Flipping projection matrix flips front/backface culling. + We only have a skybox so in this case this still would be fast, with more objects it's getting more ugly. + */ + smgr->getSceneNodesFromType(scene::ESNT_ANY, allNodes); + flipCullingFlags(allNodes); + } +#endif + /* + If rendered just once then this node has still a white (or even undefined) texture at this point + Just hiding it and render the background when rendering the cubemap for the other node is less noticable + than having a big white dot in the environment texture. + Render order can matter if you want several environment maps in your scene. + */ + if (sphereNode3) + sphereNode3->setVisible(false); + + renderEnvironmentCubeMap(driver, cubeMapCamera, sphereNode, cubeMapRT, dynamicCubeMapRTT, depthStencilRTT); + + if ( sphereNode3) + { + if ( updateCubemaps == 2 ) + { + /* + Our rtt's unfortunately don't have mipmaps (sorry, not sure if we can get that somehow...) + So if we want mipmaps in the dynamic cubemap we have to copy it to a non-rtt texture. + Warning: Very, very slow. Far slower than just creating an environment map as this + will copy the texture from GPU to main memory - copy it to a new texture, create mip-maps and + upload the result back to the GPU. + */ + renderEnvironmentCubeMap(driver, cubeMapCamera, sphereNode3, cubeMapRT, dynamicCubeMapRTT_intermediate, depthStencilRTT); + for ( int i=0; i<6; ++i) + { + void * rtData = dynamicCubeMapRTT_intermediate->lock(video::ETLM_READ_ONLY, 0, i, video::ETLF_NONE); + void * tData = dynamicCubeMapTex->lock(video::ETLM_READ_WRITE, 0, i); + memcpy(tData, rtData, dynamicCubeMapTex->getPitch()*dynamicCubeMapTex->getSize().Width); + dynamicCubeMapRTT_intermediate->unlock(); + dynamicCubeMapTex->unlock(); + dynamicCubeMapTex->regenerateMipMapLevels(); + } + } + sphereNode3->setVisible(true); + } + +#ifdef CUBEMAP_UPSIDE_DOWN_GL_PROJECTION + if ( driverType == video::EDT_OPENGL ) + { + flipCullingFlags(allNodes); + } +#endif + } + + smgr->drawAll(); + env->drawAll(); + + driver->endScene(); + } + } + + device->drop(); + + return 0; +} + +/* +**/ diff --git a/examples/BuildAllExamples.workspace b/examples/BuildAllExamples.workspace index 906ce1a2..d5cb5827 100644 --- a/examples/BuildAllExamples.workspace +++ b/examples/BuildAllExamples.workspace @@ -1,8 +1,8 @@ + - @@ -27,6 +27,8 @@ + + diff --git a/examples/BuildAllExamples_vc10.sln b/examples/BuildAllExamples_vc10.sln index 52f85843..27618b7c 100644 --- a/examples/BuildAllExamples_vc10.sln +++ b/examples/BuildAllExamples_vc10.sln @@ -148,6 +148,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "30.Profiling", "30.Profilin EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "27.PostProcessing", "27.PostProcessing\PostProcessing_vc10.vcxproj", "{2B885150-210F-4CA7-957E-2C3D75974308}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "28.CubeMapping", "28.CubeMapping\CubeMapping_vc10.vcxproj", "{9A2CE404-75E2-4195-837D-BED5B0FF3FA7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -420,6 +422,14 @@ Global {2B885150-210F-4CA7-957E-2C3D75974308}.Release|Win32.Build.0 = Release|Win32 {2B885150-210F-4CA7-957E-2C3D75974308}.Release|x64.ActiveCfg = Release|x64 {2B885150-210F-4CA7-957E-2C3D75974308}.Release|x64.Build.0 = Release|x64 + {9A2CE404-75E2-4195-837D-BED5B0FF3FA7}.Debug|Win32.ActiveCfg = Debug|Win32 + {9A2CE404-75E2-4195-837D-BED5B0FF3FA7}.Debug|Win32.Build.0 = Debug|Win32 + {9A2CE404-75E2-4195-837D-BED5B0FF3FA7}.Debug|x64.ActiveCfg = Debug|x64 + {9A2CE404-75E2-4195-837D-BED5B0FF3FA7}.Debug|x64.Build.0 = Debug|x64 + {9A2CE404-75E2-4195-837D-BED5B0FF3FA7}.Release|Win32.ActiveCfg = Release|Win32 + {9A2CE404-75E2-4195-837D-BED5B0FF3FA7}.Release|Win32.Build.0 = Release|Win32 + {9A2CE404-75E2-4195-837D-BED5B0FF3FA7}.Release|x64.ActiveCfg = Release|x64 + {9A2CE404-75E2-4195-837D-BED5B0FF3FA7}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/examples/BuildAllExamples_vc11.sln b/examples/BuildAllExamples_vc11.sln index 25bfd7f5..6b5b06e2 100644 --- a/examples/BuildAllExamples_vc11.sln +++ b/examples/BuildAllExamples_vc11.sln @@ -151,6 +151,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "30.Profiling", "30.Profilin EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "27.PostProcessing", "27.PostProcessing\PostProcessing_vc11.vcxproj", "{F864F96D-F6AE-43E2-9A12-218B1A081255}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "28.CubeMapping", "28.CubeMapping\CubeMapping_vc11.vcxproj", "{3DAD16DC-3D80-46EA-ADD8-C4418CEDE553}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -423,6 +425,14 @@ Global {F864F96D-F6AE-43E2-9A12-218B1A081255}.Release|Win32.Build.0 = Release|Win32 {F864F96D-F6AE-43E2-9A12-218B1A081255}.Release|x64.ActiveCfg = Release|x64 {F864F96D-F6AE-43E2-9A12-218B1A081255}.Release|x64.Build.0 = Release|x64 + {3DAD16DC-3D80-46EA-ADD8-C4418CEDE553}.Debug|Win32.ActiveCfg = Debug|Win32 + {3DAD16DC-3D80-46EA-ADD8-C4418CEDE553}.Debug|Win32.Build.0 = Debug|Win32 + {3DAD16DC-3D80-46EA-ADD8-C4418CEDE553}.Debug|x64.ActiveCfg = Debug|x64 + {3DAD16DC-3D80-46EA-ADD8-C4418CEDE553}.Debug|x64.Build.0 = Debug|x64 + {3DAD16DC-3D80-46EA-ADD8-C4418CEDE553}.Release|Win32.ActiveCfg = Release|Win32 + {3DAD16DC-3D80-46EA-ADD8-C4418CEDE553}.Release|Win32.Build.0 = Release|Win32 + {3DAD16DC-3D80-46EA-ADD8-C4418CEDE553}.Release|x64.ActiveCfg = Release|x64 + {3DAD16DC-3D80-46EA-ADD8-C4418CEDE553}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/examples/BuildAllExamples_vc12.sln b/examples/BuildAllExamples_vc12.sln index b5a77416..a6786e25 100644 --- a/examples/BuildAllExamples_vc12.sln +++ b/examples/BuildAllExamples_vc12.sln @@ -153,6 +153,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Irrlicht", "..\source\Irrli EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "27.PostProcessing", "27.PostProcessing\PostProcessing_vc12.vcxproj", "{17E74625-568E-4008-897E-CAD12A332B0C}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "28.CubeMapping", "28.CubeMapping\CubeMapping_vc12.vcxproj", "{1FDD5E75-9EB3-4467-B672-0BFC105B84A5}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -1095,6 +1097,34 @@ Global {17E74625-568E-4008-897E-CAD12A332B0C}.Static lib - Release|Win32.Build.0 = Release|Win32 {17E74625-568E-4008-897E-CAD12A332B0C}.Static lib - Release|x64.ActiveCfg = Release|x64 {17E74625-568E-4008-897E-CAD12A332B0C}.Static lib - Release|x64.Build.0 = Release|x64 + {1FDD5E75-9EB3-4467-B672-0BFC105B84A5}.Debug|Win32.ActiveCfg = Debug|Win32 + {1FDD5E75-9EB3-4467-B672-0BFC105B84A5}.Debug|Win32.Build.0 = Debug|Win32 + {1FDD5E75-9EB3-4467-B672-0BFC105B84A5}.Debug|x64.ActiveCfg = Debug|x64 + {1FDD5E75-9EB3-4467-B672-0BFC105B84A5}.Debug|x64.Build.0 = Debug|x64 + {1FDD5E75-9EB3-4467-B672-0BFC105B84A5}.Release - Fast FPU|Win32.ActiveCfg = Release|Win32 + {1FDD5E75-9EB3-4467-B672-0BFC105B84A5}.Release - Fast FPU|Win32.Build.0 = Release|Win32 + {1FDD5E75-9EB3-4467-B672-0BFC105B84A5}.Release - Fast FPU|x64.ActiveCfg = Release|x64 + {1FDD5E75-9EB3-4467-B672-0BFC105B84A5}.Release - Fast FPU|x64.Build.0 = Release|x64 + {1FDD5E75-9EB3-4467-B672-0BFC105B84A5}.Release|Win32.ActiveCfg = Release|Win32 + {1FDD5E75-9EB3-4467-B672-0BFC105B84A5}.Release|Win32.Build.0 = Release|Win32 + {1FDD5E75-9EB3-4467-B672-0BFC105B84A5}.Release|x64.ActiveCfg = Release|x64 + {1FDD5E75-9EB3-4467-B672-0BFC105B84A5}.Release|x64.Build.0 = Release|x64 + {1FDD5E75-9EB3-4467-B672-0BFC105B84A5}.SDL-Debug|Win32.ActiveCfg = Debug|Win32 + {1FDD5E75-9EB3-4467-B672-0BFC105B84A5}.SDL-Debug|Win32.Build.0 = Debug|Win32 + {1FDD5E75-9EB3-4467-B672-0BFC105B84A5}.SDL-Debug|x64.ActiveCfg = Debug|x64 + {1FDD5E75-9EB3-4467-B672-0BFC105B84A5}.SDL-Debug|x64.Build.0 = Debug|x64 + {1FDD5E75-9EB3-4467-B672-0BFC105B84A5}.Static lib - Debug|Win32.ActiveCfg = Debug|Win32 + {1FDD5E75-9EB3-4467-B672-0BFC105B84A5}.Static lib - Debug|Win32.Build.0 = Debug|Win32 + {1FDD5E75-9EB3-4467-B672-0BFC105B84A5}.Static lib - Debug|x64.ActiveCfg = Debug|x64 + {1FDD5E75-9EB3-4467-B672-0BFC105B84A5}.Static lib - Debug|x64.Build.0 = Debug|x64 + {1FDD5E75-9EB3-4467-B672-0BFC105B84A5}.Static lib - Release - Fast FPU|Win32.ActiveCfg = Release|Win32 + {1FDD5E75-9EB3-4467-B672-0BFC105B84A5}.Static lib - Release - Fast FPU|Win32.Build.0 = Release|Win32 + {1FDD5E75-9EB3-4467-B672-0BFC105B84A5}.Static lib - Release - Fast FPU|x64.ActiveCfg = Release|x64 + {1FDD5E75-9EB3-4467-B672-0BFC105B84A5}.Static lib - Release - Fast FPU|x64.Build.0 = Release|x64 + {1FDD5E75-9EB3-4467-B672-0BFC105B84A5}.Static lib - Release|Win32.ActiveCfg = Release|Win32 + {1FDD5E75-9EB3-4467-B672-0BFC105B84A5}.Static lib - Release|Win32.Build.0 = Release|Win32 + {1FDD5E75-9EB3-4467-B672-0BFC105B84A5}.Static lib - Release|x64.ActiveCfg = Release|x64 + {1FDD5E75-9EB3-4467-B672-0BFC105B84A5}.Static lib - Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/examples/BuildAllExamples_vc14.sln b/examples/BuildAllExamples_vc14.sln index 9529fd64..4766c3b5 100644 --- a/examples/BuildAllExamples_vc14.sln +++ b/examples/BuildAllExamples_vc14.sln @@ -148,6 +148,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Irrlicht", "..\source\Irrli EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "27.PostProcessing", "27.PostProcessing\PostProcessing_vc14.vcxproj", "{F25F2AC4-AEDA-4A95-9769-01A2652B54A2}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "28.CubeMapping", "28.CubeMapping\CubeMapping_vc14.vcxproj", "{DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -1062,6 +1064,34 @@ Global {F25F2AC4-AEDA-4A95-9769-01A2652B54A2}.Static lib - Release|Win32.Build.0 = Release|Win32 {F25F2AC4-AEDA-4A95-9769-01A2652B54A2}.Static lib - Release|x64.ActiveCfg = Release|x64 {F25F2AC4-AEDA-4A95-9769-01A2652B54A2}.Static lib - Release|x64.Build.0 = Release|x64 + {DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}.Debug|Win32.ActiveCfg = Debug|Win32 + {DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}.Debug|Win32.Build.0 = Debug|Win32 + {DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}.Debug|x64.ActiveCfg = Debug|x64 + {DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}.Debug|x64.Build.0 = Debug|x64 + {DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}.Release - Fast FPU|Win32.ActiveCfg = Release|Win32 + {DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}.Release - Fast FPU|Win32.Build.0 = Release|Win32 + {DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}.Release - Fast FPU|x64.ActiveCfg = Release|x64 + {DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}.Release - Fast FPU|x64.Build.0 = Release|x64 + {DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}.Release|Win32.ActiveCfg = Release|Win32 + {DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}.Release|Win32.Build.0 = Release|Win32 + {DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}.Release|x64.ActiveCfg = Release|x64 + {DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}.Release|x64.Build.0 = Release|x64 + {DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}.SDL-Debug|Win32.ActiveCfg = Debug|Win32 + {DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}.SDL-Debug|Win32.Build.0 = Debug|Win32 + {DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}.SDL-Debug|x64.ActiveCfg = Debug|x64 + {DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}.SDL-Debug|x64.Build.0 = Debug|x64 + {DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}.Static lib - Debug|Win32.ActiveCfg = Debug|Win32 + {DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}.Static lib - Debug|Win32.Build.0 = Debug|Win32 + {DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}.Static lib - Debug|x64.ActiveCfg = Debug|x64 + {DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}.Static lib - Debug|x64.Build.0 = Debug|x64 + {DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}.Static lib - Release - Fast FPU|Win32.ActiveCfg = Release|Win32 + {DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}.Static lib - Release - Fast FPU|Win32.Build.0 = Release|Win32 + {DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}.Static lib - Release - Fast FPU|x64.ActiveCfg = Release|x64 + {DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}.Static lib - Release - Fast FPU|x64.Build.0 = Release|x64 + {DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}.Static lib - Release|Win32.ActiveCfg = Release|Win32 + {DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}.Static lib - Release|Win32.Build.0 = Release|Win32 + {DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}.Static lib - Release|x64.ActiveCfg = Release|x64 + {DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}.Static lib - Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/include/ICursorControl.h b/include/ICursorControl.h index 1deff662..4597bf37 100644 --- a/include/ICursorControl.h +++ b/include/ICursorControl.h @@ -134,16 +134,23 @@ namespace gui virtual void setPosition(s32 x, s32 y) = 0; //! Returns the current position of the mouse cursor. - /** \return Returns the current position of the cursor. The returned position + /** \param updateCursor When true ask system/OS for current cursor position. + When false return the last known (buffered) position ( this is useful to + check what has become of a setPosition call with float numbers). + \return Returns the current position of the cursor. The returned position is the position of the mouse cursor in pixel units. */ - virtual const core::position2d& getPosition() = 0; + virtual const core::position2d& getPosition(bool updateCursor=true) = 0; //! Returns the current position of the mouse cursor. - /** \return Returns the current position of the cursor. The returned position + /** \param updateCursor When true ask system/OS for current cursor position. + When false return the last known (buffered) position (this is + useful to check what has become of a setPosition call with float numbers + and is often different from the values you passed in setPosition). + \return Returns the current position of the cursor. The returned position is a value between (0.0f, 0.0f) and (1.0f, 1.0f), where (0.0f, 0.0f) is the top left corner and (1.0f, 1.0f) is the bottom right corner of the render window. */ - virtual core::position2d getRelativePosition() = 0; + virtual core::position2d getRelativePosition(bool updateCursor=true) = 0; //! Sets an absolute reference rect for setting and retrieving the cursor position. /** If this rect is set, the cursor position is not being calculated relative to diff --git a/include/IGeometryCreator.h b/include/IGeometryCreator.h index 08b1bc75..fbc76a93 100644 --- a/include/IGeometryCreator.h +++ b/include/IGeometryCreator.h @@ -20,6 +20,19 @@ namespace video namespace scene { + enum ECUBE_MESH_TYPE + { + //! Single buffer with 12 different vertices, normals are average of adjacent planes + //! Order for outgoing (front-face) normals of planes would be: NEG_Z, POS_X, POS_Z, NEG_X, POS_Y, NEG_Y + ECMT_1BUF_12VTX_NA, + + //! One buffer per side, each with 4 vertices, normals are perpendicular to sides + //! Note: You probably will have to scale down your texture uv's to avoid white lines at borders + // as this mesh sets them to 0,1 values. We can't do that when creating the mesh as it + // depends on texture resolution which we don't know at that point. + ECMT_6BUF_4VTX_NP + }; + //! Helper class for creating geometry on the fly. /** You can get an instance of this class through ISceneManager::getGeometryCreator() */ class IGeometryCreator : public IReferenceCounted @@ -29,9 +42,10 @@ public: //! Creates a simple cube mesh. /** \param size Dimensions of the cube. + \param type One of ECUBE_MESH_TYPE. So you can chose between cubes with single material or independent materials per side. \return Generated mesh. */ - virtual IMesh* createCubeMesh(const core::vector3df& size=core::vector3df(5.f,5.f,5.f)) const =0; + virtual IMesh* createCubeMesh(const core::vector3df& size=core::vector3df(5.f,5.f,5.f), ECUBE_MESH_TYPE type = ECMT_1BUF_12VTX_NA) const =0; //! Create a pseudo-random mesh representing a hilly terrain. /** diff --git a/include/IrrCompileConfig.h b/include/IrrCompileConfig.h index e14f79df..e27156d2 100644 --- a/include/IrrCompileConfig.h +++ b/include/IrrCompileConfig.h @@ -373,7 +373,9 @@ the engine will no longer read .jpeg images. */ //! Define _IRR_USE_NON_SYSTEM_JPEG_LIB_ to let irrlicht use the jpeglib which comes with irrlicht. /** If this is commented out, Irrlicht will try to compile using the jpeg lib installed in the system. - This is only used when _IRR_COMPILE_WITH_LIBJPEG_ is defined. */ + This is only used when _IRR_COMPILE_WITH_LIBJPEG_ is defined. + NOTE: You will also have to modify the Makefile or project files when changing this default. + */ #define _IRR_USE_NON_SYSTEM_JPEG_LIB_ #ifdef NO_IRR_USE_NON_SYSTEM_JPEG_LIB_ #undef _IRR_USE_NON_SYSTEM_JPEG_LIB_ @@ -389,7 +391,9 @@ the engine will no longer read .png images. */ //! Define _IRR_USE_NON_SYSTEM_LIBPNG_ to let irrlicht use the libpng which comes with irrlicht. /** If this is commented out, Irrlicht will try to compile using the libpng installed in the system. - This is only used when _IRR_COMPILE_WITH_LIBPNG_ is defined. */ + This is only used when _IRR_COMPILE_WITH_LIBPNG_ is defined. + NOTE: You will also have to modify the Makefile or project files when changing this default. + */ #define _IRR_USE_NON_SYSTEM_LIB_PNG_ #ifdef NO_IRR_USE_NON_SYSTEM_LIB_PNG_ #undef _IRR_USE_NON_SYSTEM_LIB_PNG_ @@ -784,8 +788,10 @@ ones. */ #endif //! Define _IRR_USE_NON_SYSTEM_ZLIB_ to let irrlicht use the zlib which comes with irrlicht. /** If this is commented out, Irrlicht will try to compile using the zlib -installed on the system. This is only used when _IRR_COMPILE_WITH_ZLIB_ is -defined. */ + installed on the system. This is only used when _IRR_COMPILE_WITH_ZLIB_ is + defined. + NOTE: You will also have to modify the Makefile or project files when changing this default. + */ #define _IRR_USE_NON_SYSTEM_ZLIB_ #ifdef NO_IRR_USE_NON_SYSTEM_ZLIB_ #undef _IRR_USE_NON_SYSTEM_ZLIB_ @@ -806,7 +812,9 @@ library. */ //! Define _IRR_USE_NON_SYSTEM_BZLIB_ to let irrlicht use the bzlib which comes with irrlicht. /** If this is commented out, Irrlicht will try to compile using the bzlib installed on the system. This is only used when _IRR_COMPILE_WITH_BZLIB_ is -defined. */ +defined. +NOTE: You will also have to modify the Makefile or project files when changing this default. +*/ #define _IRR_USE_NON_SYSTEM_BZLIB_ #ifdef NO_IRR_USE_NON_SYSTEM_BZLIB_ #undef _IRR_USE_NON_SYSTEM_BZLIB_ @@ -918,9 +926,8 @@ precision will be lower but speed higher. currently X86 only #if defined(__BORLANDC__) #include - // Borland 5.5.1 does not have _strcmpi defined + // Borland 5.5.1 #if __BORLANDC__ == 0x551 - // #define _strcmpi strcmpi #undef _tfinddata_t #undef _tfindfirst #undef _tfindnext diff --git a/include/irrTypes.h b/include/irrTypes.h index cadb157f..aa99b50e 100644 --- a/include/irrTypes.h +++ b/include/irrTypes.h @@ -244,9 +244,4 @@ code like 'code', but some generate warnings so we use this macro here */ ((irr::u32)(irr::u8)(c0) | ((irr::u32)(irr::u8)(c1) << 8) | \ ((irr::u32)(irr::u8)(c2) << 16) | ((irr::u32)(irr::u8)(c3) << 24 )) -#if defined(__BORLANDC__) || defined (__BCPLUSPLUS__) -#define _strcmpi(a,b) strcmpi(a,b) -#endif - #endif // __IRR_TYPES_H_INCLUDED__ - diff --git a/media/cubeMapReflection.frag b/media/cubeMapReflection.frag new file mode 100644 index 00000000..f1a4a1fc --- /dev/null +++ b/media/cubeMapReflection.frag @@ -0,0 +1,12 @@ +uniform samplerCube cubeTex; +uniform float Roughness; + +void main( void ) +{ +// gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); + vec3 uvw = vec3(gl_TexCoord[0]); + //gl_FragColor = textureCube( cubeTex, uvw ); + gl_FragColor = textureLod( cubeTex, uvw, Roughness ); + //gl_FragColor = textureCube( cubeTex, uvw, Roughness ); +} + diff --git a/media/cubeMapReflection.vert b/media/cubeMapReflection.vert new file mode 100644 index 00000000..97f9ac5b --- /dev/null +++ b/media/cubeMapReflection.vert @@ -0,0 +1,27 @@ +uniform int StyleUVW ; // 0 = specular reflection, 1 = diffuse reflection, 2 = use model vertex coordinates for uvw. +uniform vec3 CameraPos; +uniform mat4 World; + +void main(void) +{ + gl_Position = ftransform(); // same as gl_ModelViewProjectionMatrix * gl_Vertex; + + // compute the reflection vector, and assign it to texcoord 0 + if ( StyleUVW == 0 ) + { + vec4 worldPos = World*gl_Vertex; + vec3 viewNormal = normalize(worldPos.xyz - CameraPos); // view vector + + gl_TexCoord[0] = vec4( reflect( viewNormal, normalize(gl_Normal) ), 1.0 ); + } + else if ( StyleUVW == 1 ) + { + // just use the normal for the reflection vector + gl_TexCoord[0] = vec4(normalize(gl_Normal), 1.0); + } + else if ( StyleUVW == 2 ) + { + // use vertex-coordinates for texture coordinates + gl_TexCoord[0] = normalize(gl_Vertex); + } +} diff --git a/media/cubeMapReflectionPS.hlsl b/media/cubeMapReflectionPS.hlsl new file mode 100644 index 00000000..179979dc --- /dev/null +++ b/media/cubeMapReflectionPS.hlsl @@ -0,0 +1,10 @@ +sampler cubeTex: register(s0); +float Roughness; + +float4 PS( float4 uvwTex : TEXCOORD0 ) : COLOR +{ + uvwTex.w = Roughness; + //return texCUBEbias( cubeTex, uvwTex); + return texCUBElod( cubeTex, uvwTex); + //return texCUBE( cubeTex, uvwTex); +} diff --git a/media/cubeMapReflectionVS.hlsl b/media/cubeMapReflectionVS.hlsl new file mode 100644 index 00000000..64033060 --- /dev/null +++ b/media/cubeMapReflectionVS.hlsl @@ -0,0 +1,38 @@ +int StyleUVW ; // 0 = specular reflection, 1 = diffuse reflection, 2 = use model vertex coordinates for uvw. +float4x4 WorldViewProj; +float4x4 World; +float3 CameraPos; + +// Vertex Shader +void VS( + in float4 VPos : POSITION, + in float3 VNorm : NORMAL, + in float3 VTex : TEXCOORD0, + out float4 outPos : POSITION, + out float4 outTex : TEXCOORD0 ) +{ + // vertex position from model-space to view-space + outPos = mul( VPos, WorldViewProj ); + + if ( StyleUVW == 0 ) + { + // create ray from camera position to the vertex, in world space + float4 worldPos = mul(float4(VPos.x, VPos.y, VPos.z, 1.0), World); + float3 view = CameraPos - worldPos.xyz; + + float4 normWorld = normalize(mul(float4(VNorm.x, VNorm.y, VNorm.z, 0.0), World)); // TODO: when objects are scaled non-uniform we need to multiply by WorldInverseTranspose instead + + // compute the reflection vector, and assign it to texcoord 0 + outTex.xyz = reflect( -normalize(view), normWorld.xyz ); + } + else if ( StyleUVW == 1 ) + { + // just use the normal for the reflection vector + outTex.xyz = normalize(VNorm); + } + else if ( StyleUVW == 2 ) + { + // use vertex-coordinates for texture coordinates + outTex.xyz = VPos.xyz; + } +} diff --git a/media/cubemap_license.txt b/media/cubemap_license.txt new file mode 100644 index 00000000..2bfb4a5a --- /dev/null +++ b/media/cubemap_license.txt @@ -0,0 +1,18 @@ +License for the cubemap_*.jpg files in this folder. + +Author +====== + +This is the work of Emil Persson, aka Humus. +http://www.humus.name + +License +======= + +This work is licensed under a Creative Commons Attribution 3.0 Unported License. +http://creativecommons.org/licenses/by/3.0/ + + +Changes +======= +For the Irrlicht engine we downscaled the images to 512x512. Get the full 2048x2048 resolution at http://www.humus.name diff --git a/media/cubemap_negx.jpg b/media/cubemap_negx.jpg new file mode 100644 index 00000000..abb77ce1 Binary files /dev/null and b/media/cubemap_negx.jpg differ diff --git a/media/cubemap_negy.jpg b/media/cubemap_negy.jpg new file mode 100644 index 00000000..740c536d Binary files /dev/null and b/media/cubemap_negy.jpg differ diff --git a/media/cubemap_negz.jpg b/media/cubemap_negz.jpg new file mode 100644 index 00000000..057d3f1e Binary files /dev/null and b/media/cubemap_negz.jpg differ diff --git a/media/cubemap_posx.jpg b/media/cubemap_posx.jpg new file mode 100644 index 00000000..6c32969b Binary files /dev/null and b/media/cubemap_posx.jpg differ diff --git a/media/cubemap_posy.jpg b/media/cubemap_posy.jpg new file mode 100644 index 00000000..e343c3fa Binary files /dev/null and b/media/cubemap_posy.jpg differ diff --git a/media/cubemap_posz.jpg b/media/cubemap_posz.jpg new file mode 100644 index 00000000..2d28e44e Binary files /dev/null and b/media/cubemap_posz.jpg differ diff --git a/media/001shot.jpg b/media/example_screenshots/001shot.jpg similarity index 100% rename from media/001shot.jpg rename to media/example_screenshots/001shot.jpg diff --git a/media/002shot.jpg b/media/example_screenshots/002shot.jpg similarity index 100% rename from media/002shot.jpg rename to media/example_screenshots/002shot.jpg diff --git a/media/003shot.jpg b/media/example_screenshots/003shot.jpg similarity index 100% rename from media/003shot.jpg rename to media/example_screenshots/003shot.jpg diff --git a/media/004shot.jpg b/media/example_screenshots/004shot.jpg similarity index 100% rename from media/004shot.jpg rename to media/example_screenshots/004shot.jpg diff --git a/media/005shot.jpg b/media/example_screenshots/005shot.jpg similarity index 100% rename from media/005shot.jpg rename to media/example_screenshots/005shot.jpg diff --git a/media/006shot.jpg b/media/example_screenshots/006shot.jpg similarity index 100% rename from media/006shot.jpg rename to media/example_screenshots/006shot.jpg diff --git a/media/007shot.jpg b/media/example_screenshots/007shot.jpg similarity index 100% rename from media/007shot.jpg rename to media/example_screenshots/007shot.jpg diff --git a/media/008shot.jpg b/media/example_screenshots/008shot.jpg similarity index 100% rename from media/008shot.jpg rename to media/example_screenshots/008shot.jpg diff --git a/media/009shot.jpg b/media/example_screenshots/009shot.jpg similarity index 100% rename from media/009shot.jpg rename to media/example_screenshots/009shot.jpg diff --git a/media/010shot.jpg b/media/example_screenshots/010shot.jpg similarity index 100% rename from media/010shot.jpg rename to media/example_screenshots/010shot.jpg diff --git a/media/011shot.jpg b/media/example_screenshots/011shot.jpg similarity index 100% rename from media/011shot.jpg rename to media/example_screenshots/011shot.jpg diff --git a/media/012shot.jpg b/media/example_screenshots/012shot.jpg similarity index 100% rename from media/012shot.jpg rename to media/example_screenshots/012shot.jpg diff --git a/media/013shot.jpg b/media/example_screenshots/013shot.jpg similarity index 100% rename from media/013shot.jpg rename to media/example_screenshots/013shot.jpg diff --git a/media/014shot.jpg b/media/example_screenshots/014shot.jpg similarity index 100% rename from media/014shot.jpg rename to media/example_screenshots/014shot.jpg diff --git a/media/015shot.jpg b/media/example_screenshots/015shot.jpg similarity index 100% rename from media/015shot.jpg rename to media/example_screenshots/015shot.jpg diff --git a/media/016shot.jpg b/media/example_screenshots/016shot.jpg similarity index 100% rename from media/016shot.jpg rename to media/example_screenshots/016shot.jpg diff --git a/media/017shot.jpg b/media/example_screenshots/017shot.jpg similarity index 100% rename from media/017shot.jpg rename to media/example_screenshots/017shot.jpg diff --git a/media/018shot.jpg b/media/example_screenshots/018shot.jpg similarity index 100% rename from media/018shot.jpg rename to media/example_screenshots/018shot.jpg diff --git a/media/019shot.jpg b/media/example_screenshots/019shot.jpg similarity index 100% rename from media/019shot.jpg rename to media/example_screenshots/019shot.jpg diff --git a/media/020shot.jpg b/media/example_screenshots/020shot.jpg similarity index 100% rename from media/020shot.jpg rename to media/example_screenshots/020shot.jpg diff --git a/media/021shot.jpg b/media/example_screenshots/021shot.jpg similarity index 100% rename from media/021shot.jpg rename to media/example_screenshots/021shot.jpg diff --git a/media/022shot.jpg b/media/example_screenshots/022shot.jpg similarity index 100% rename from media/022shot.jpg rename to media/example_screenshots/022shot.jpg diff --git a/media/023shot.jpg b/media/example_screenshots/023shot.jpg similarity index 100% rename from media/023shot.jpg rename to media/example_screenshots/023shot.jpg diff --git a/media/024shot.jpg b/media/example_screenshots/024shot.jpg similarity index 100% rename from media/024shot.jpg rename to media/example_screenshots/024shot.jpg diff --git a/media/025shot.jpg b/media/example_screenshots/025shot.jpg similarity index 100% rename from media/025shot.jpg rename to media/example_screenshots/025shot.jpg diff --git a/media/026shot.jpg b/media/example_screenshots/026shot.jpg similarity index 100% rename from media/026shot.jpg rename to media/example_screenshots/026shot.jpg diff --git a/media/027shot.jpg b/media/example_screenshots/027shot.jpg similarity index 100% rename from media/027shot.jpg rename to media/example_screenshots/027shot.jpg diff --git a/media/example_screenshots/028shot.jpg b/media/example_screenshots/028shot.jpg new file mode 100644 index 00000000..84ee7f31 Binary files /dev/null and b/media/example_screenshots/028shot.jpg differ diff --git a/media/fonthaettenschweiler.bmp b/media/fonthaettenschweiler.bmp index ca301da4..d2786d8e 100644 Binary files a/media/fonthaettenschweiler.bmp and b/media/fonthaettenschweiler.bmp differ diff --git a/scripts/doc/irrlicht/doxygen-pdf.cfg b/scripts/doc/irrlicht/doxygen-pdf.cfg index 66402cfa..8175b558 100644 --- a/scripts/doc/irrlicht/doxygen-pdf.cfg +++ b/scripts/doc/irrlicht/doxygen-pdf.cfg @@ -711,6 +711,7 @@ EXAMPLE_RECURSIVE = NO # the \image command). IMAGE_PATH = ../../../media +IMAGE_PATH += ../../../media/example_screenshots # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program diff --git a/scripts/doc/irrlicht/doxygen.cfg b/scripts/doc/irrlicht/doxygen.cfg index e04973aa..2e80f8cb 100644 --- a/scripts/doc/irrlicht/doxygen.cfg +++ b/scripts/doc/irrlicht/doxygen.cfg @@ -711,6 +711,7 @@ EXAMPLE_RECURSIVE = NO # the \image command). IMAGE_PATH = ../../../media +IMAGE_PATH += ../../../media/example_screenshots # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program diff --git a/scripts/doc/irrlicht/footer.html b/scripts/doc/irrlicht/footer.html index fa50f6a1..f1ad5d3d 100644 --- a/scripts/doc/irrlicht/footer.html +++ b/scripts/doc/irrlicht/footer.html @@ -1,7 +1,7 @@ @@ -9,7 +9,7 @@ Engine Documentation © 2003-2012 by Nikolaus Gebhardt. $generatedby diff --git a/scripts/doc/irrlicht/makedocumentation.bat b/scripts/doc/irrlicht/makedocumentation.bat index e3d4c110..80793a98 100644 --- a/scripts/doc/irrlicht/makedocumentation.bat +++ b/scripts/doc/irrlicht/makedocumentation.bat @@ -34,6 +34,8 @@ rem for /F %%i in ('dir ..\..\..\examples\[01]*\main.cpp') DO ..\sed.exe -f tuto ..\sed.exe -f tutorials.sed ..\..\..\examples\24.CursorControl\main.cpp >>tut.txt ..\sed.exe -f tutorials.sed ..\..\..\examples\25.XmlHandling\main.cpp >>tut.txt ..\sed.exe -f tutorials.sed ..\..\..\examples\26.OcclusionQuery\main.cpp >>tut.txt +..\sed.exe -f tutorials.sed ..\..\..\examples\27.PostProcessing\main.cpp >>tut.txt +..\sed.exe -f tutorials.sed ..\..\..\examples\28.CubeMapping\main.cpp >>tut.txt :SKIP_TUTS diff --git a/source/Irrlicht/CGeometryCreator.cpp b/source/Irrlicht/CGeometryCreator.cpp index b13a9163..5c926ee7 100644 --- a/source/Irrlicht/CGeometryCreator.cpp +++ b/source/Irrlicht/CGeometryCreator.cpp @@ -15,51 +15,131 @@ namespace irr namespace scene { -IMesh* CGeometryCreator::createCubeMesh(const core::vector3df& size) const +IMesh* CGeometryCreator::createCubeMesh(const core::vector3df& size, ECUBE_MESH_TYPE type) const { - SMeshBuffer* buffer = new SMeshBuffer(); - - // Create indices - const u16 u[36] = { 0,2,1, 0,3,2, 1,5,4, 1,2,5, 4,6,7, 4,5,6, - 7,3,0, 7,6,3, 9,5,2, 9,8,5, 0,11,10, 0,10,7}; - - buffer->Indices.set_used(36); - - for (u32 i=0; i<36; ++i) - buffer->Indices[i] = u[i]; - - - // Create vertices - video::SColor clr(255,255,255,255); - - buffer->Vertices.reallocate(12); - - buffer->Vertices.push_back(video::S3DVertex(0,0,0, -1,-1,-1, clr, 0, 1)); - buffer->Vertices.push_back(video::S3DVertex(1,0,0, 1,-1,-1, clr, 1, 1)); - buffer->Vertices.push_back(video::S3DVertex(1,1,0, 1, 1,-1, clr, 1, 0)); - buffer->Vertices.push_back(video::S3DVertex(0,1,0, -1, 1,-1, clr, 0, 0)); - buffer->Vertices.push_back(video::S3DVertex(1,0,1, 1,-1, 1, clr, 0, 1)); - buffer->Vertices.push_back(video::S3DVertex(1,1,1, 1, 1, 1, clr, 0, 0)); - buffer->Vertices.push_back(video::S3DVertex(0,1,1, -1, 1, 1, clr, 1, 0)); - buffer->Vertices.push_back(video::S3DVertex(0,0,1, -1,-1, 1, clr, 1, 1)); - buffer->Vertices.push_back(video::S3DVertex(0,1,1, -1, 1, 1, clr, 0, 1)); - buffer->Vertices.push_back(video::S3DVertex(0,1,0, -1, 1,-1, clr, 1, 1)); - buffer->Vertices.push_back(video::S3DVertex(1,0,1, 1,-1, 1, clr, 1, 0)); - buffer->Vertices.push_back(video::S3DVertex(1,0,0, 1,-1,-1, clr, 0, 0)); - - // Recalculate bounding box - buffer->BoundingBox.reset(0,0,0); - - for (u32 i=0; i<12; ++i) - { - buffer->Vertices[i].Pos -= core::vector3df(0.5f, 0.5f, 0.5f); - buffer->Vertices[i].Pos *= size; - buffer->BoundingBox.addInternalPoint(buffer->Vertices[i].Pos); - } - SMesh* mesh = new SMesh; - mesh->addMeshBuffer(buffer); - buffer->drop(); + + const video::SColor clr(255,255,255,255); + + if ( type == ECMT_1BUF_12VTX_NA ) + { + SMeshBuffer* buffer = new SMeshBuffer(); + + // Create indices (pos, neg describes normal direction of front-face) + const u16 u[36] = { 0,2,1, 0,3,2, // NEG_Z + 1,5,4, 1,2,5, // POS_X + 4,6,7, 4,5,6, // POS_Z + 7,3,0, 7,6,3, // NEG_X + 9,5,2, 9,8,5, // POS_Y + 0,11,10, 0,10,7}; // NEG_Y + + buffer->Indices.set_used(36); + + for (u32 i=0; i<36; ++i) + buffer->Indices[i] = u[i]; + + // Create vertices + buffer->Vertices.reallocate(12); + + buffer->Vertices.push_back(video::S3DVertex(0,0,0, -1,-1,-1, clr, 0, 1)); // 0 + buffer->Vertices.push_back(video::S3DVertex(1,0,0, 1,-1,-1, clr, 1, 1)); // 1 + buffer->Vertices.push_back(video::S3DVertex(1,1,0, 1, 1,-1, clr, 1, 0)); // 2 + buffer->Vertices.push_back(video::S3DVertex(0,1,0, -1, 1,-1, clr, 0, 0)); // 3 + buffer->Vertices.push_back(video::S3DVertex(1,0,1, 1,-1, 1, clr, 0, 1)); // 4 + buffer->Vertices.push_back(video::S3DVertex(1,1,1, 1, 1, 1, clr, 0, 0)); // 5 + buffer->Vertices.push_back(video::S3DVertex(0,1,1, -1, 1, 1, clr, 1, 0)); // 6 + buffer->Vertices.push_back(video::S3DVertex(0,0,1, -1,-1, 1, clr, 1, 1)); // 7 + buffer->Vertices.push_back(video::S3DVertex(0,1,1, -1, 1, 1, clr, 0, 1)); // 8 + buffer->Vertices.push_back(video::S3DVertex(0,1,0, -1, 1,-1, clr, 1, 1)); // 9 + buffer->Vertices.push_back(video::S3DVertex(1,0,1, 1,-1, 1, clr, 1, 0)); // 10 + buffer->Vertices.push_back(video::S3DVertex(1,0,0, 1,-1,-1, clr, 0, 0)); // 11 + + // Recalculate bounding box and set cube size + buffer->BoundingBox.reset(0,0,0); + + for (u32 i=0; i<12; ++i) + { + buffer->Vertices[i].Pos -= core::vector3df(0.5f, 0.5f, 0.5f); + buffer->Vertices[i].Pos *= size; + buffer->Vertices[i].Normal.normalize(); + buffer->BoundingBox.addInternalPoint(buffer->Vertices[i].Pos); + } + + mesh->addMeshBuffer(buffer); + buffer->drop(); + } + else if ( type == ECMT_6BUF_4VTX_NP ) + { + for ( int b=0; b<6; ++b ) + { + SMeshBuffer* buffer = new SMeshBuffer(); + + // Create indices + const u16 u[6] = { 0,2,1,0,3,2}; + + buffer->Indices.set_used(6); + + for ( int i=0; i<6; ++i ) + buffer->Indices[i] = u[i]; + + // Create vertices + buffer->Vertices.reallocate(4); + + switch ( b ) + { + case 0: + buffer->Vertices.push_back(video::S3DVertex(0,0,0, 0, 0,-1, clr, 0, 1)); + buffer->Vertices.push_back(video::S3DVertex(1,0,0, 0, 0,-1, clr, 1, 1)); + buffer->Vertices.push_back(video::S3DVertex(1,1,0, 0, 0,-1, clr, 1, 0)); + buffer->Vertices.push_back(video::S3DVertex(0,1,0, 0, 0,-1, clr, 0, 0)); + break; + case 1: + buffer->Vertices.push_back(video::S3DVertex(1,0,0, 1, 0, 0, clr, 0, 1)); + buffer->Vertices.push_back(video::S3DVertex(1,0,1, 1, 0, 0, clr, 1, 1)); + buffer->Vertices.push_back(video::S3DVertex(1,1,1, 1, 0, 0, clr, 1, 0)); + buffer->Vertices.push_back(video::S3DVertex(1,1,0, 1, 0, 0, clr, 0, 0)); + break; + case 2: + buffer->Vertices.push_back(video::S3DVertex(1,0,1, 0, 0, 1, clr, 0, 1)); + buffer->Vertices.push_back(video::S3DVertex(0,0,1, 0, 0, 1, clr, 1, 1)); + buffer->Vertices.push_back(video::S3DVertex(0,1,1, 0, 0, 1, clr, 1, 0)); + buffer->Vertices.push_back(video::S3DVertex(1,1,1, 0, 0, 1, clr, 0, 0)); + break; + case 3: + buffer->Vertices.push_back(video::S3DVertex(0,0,1, -1, 0, 0, clr, 0, 1)); + buffer->Vertices.push_back(video::S3DVertex(0,0,0, -1, 0, 0, clr, 1, 1)); + buffer->Vertices.push_back(video::S3DVertex(0,1,0, -1, 0, 0, clr, 1, 0)); + buffer->Vertices.push_back(video::S3DVertex(0,1,1, -1, 0, 0, clr, 0, 0)); + break; + case 4: + buffer->Vertices.push_back(video::S3DVertex(0,1,0, 0, 1, 0, clr, 0, 1)); + buffer->Vertices.push_back(video::S3DVertex(1,1,0, 0, 1, 0, clr, 1, 1)); + buffer->Vertices.push_back(video::S3DVertex(1,1,1, 0, 1, 0, clr, 1, 0)); + buffer->Vertices.push_back(video::S3DVertex(0,1,1, 0, 1, 0, clr, 0, 0)); + break; + case 5: + buffer->Vertices.push_back(video::S3DVertex(0,0,1, 0, -1, 0, clr, 0, 1)); + buffer->Vertices.push_back(video::S3DVertex(1,0,1, 0, -1, 0, clr, 1, 1)); + buffer->Vertices.push_back(video::S3DVertex(1,0,0, 0, -1, 0, clr, 1, 0)); + buffer->Vertices.push_back(video::S3DVertex(0,0,0, 0, -1, 0, clr, 0, 0)); + break; + } + + // Recalculate bounding box and set cube size + for (u32 i=0; i<4; ++i) + { + buffer->Vertices[i].Pos -= core::vector3df(0.5f, 0.5f, 0.5f); + buffer->Vertices[i].Pos *= size; + if ( i == 0 ) + buffer->BoundingBox.reset(buffer->Vertices[i].Pos); + else + buffer->BoundingBox.addInternalPoint(buffer->Vertices[i].Pos); + } + + mesh->addMeshBuffer(buffer); + buffer->drop(); + } + } mesh->recalculateBoundingBox(); return mesh; diff --git a/source/Irrlicht/CGeometryCreator.h b/source/Irrlicht/CGeometryCreator.h index f87f9814..ad2c6c7e 100644 --- a/source/Irrlicht/CGeometryCreator.h +++ b/source/Irrlicht/CGeometryCreator.h @@ -19,7 +19,7 @@ class CGeometryCreator : public IGeometryCreator { void addToBuffer(const video::S3DVertex& v, SMeshBuffer* Buffer) const; public: - virtual IMesh* createCubeMesh(const core::vector3df& size) const _IRR_OVERRIDE_; + virtual IMesh* createCubeMesh(const core::vector3df& size, ECUBE_MESH_TYPE type) const _IRR_OVERRIDE_; virtual IMesh* createHillPlaneMesh( const core::dimension2d& tileSize, const core::dimension2d& tileCount, diff --git a/source/Irrlicht/CIrrDeviceConsole.h b/source/Irrlicht/CIrrDeviceConsole.h index 06eaf119..43d34591 100644 --- a/source/Irrlicht/CIrrDeviceConsole.h +++ b/source/Irrlicht/CIrrDeviceConsole.h @@ -159,13 +159,13 @@ namespace irr } //! Returns the current position of the mouse cursor. - virtual const core::position2d& getPosition() _IRR_OVERRIDE_ + virtual const core::position2d& getPosition(bool updateCursor) _IRR_OVERRIDE_ { return CursorPos; } //! Returns the current position of the mouse cursor. - virtual core::position2d getRelativePosition() _IRR_OVERRIDE_ + virtual core::position2d getRelativePosition(bool updateCursor) _IRR_OVERRIDE_ { if (!UseReferenceRect) { diff --git a/source/Irrlicht/CIrrDeviceFB.h b/source/Irrlicht/CIrrDeviceFB.h index 3a6b0081..62286583 100644 --- a/source/Irrlicht/CIrrDeviceFB.h +++ b/source/Irrlicht/CIrrDeviceFB.h @@ -140,16 +140,18 @@ namespace irr } //! Returns the current position of the mouse cursor. - virtual const core::position2d& getPosition() _IRR_OVERRIDE_ + virtual const core::position2d& getPosition(bool updateCursor) _IRR_OVERRIDE_ { - updateCursorPos(); + if ( updateCursor ) + updateCursorPos(); return CursorPos; } //! Returns the current position of the mouse cursor. - virtual core::position2d getRelativePosition() _IRR_OVERRIDE_ + virtual core::position2d getRelativePosition(bool updateCursor) _IRR_OVERRIDE_ { - updateCursorPos(); + if ( updateCursor) + updateCursorPos(); return core::position2d(CursorPos.X / (f32)Device->CreationParams.WindowSize.Width, CursorPos.Y / (f32)Device->CreationParams.WindowSize.Height); } diff --git a/source/Irrlicht/CIrrDeviceLinux.h b/source/Irrlicht/CIrrDeviceLinux.h index 17993e44..344149e1 100644 --- a/source/Irrlicht/CIrrDeviceLinux.h +++ b/source/Irrlicht/CIrrDeviceLinux.h @@ -238,16 +238,18 @@ namespace irr } //! Returns the current position of the mouse cursor. - virtual const core::position2d& getPosition() _IRR_OVERRIDE_ + virtual const core::position2d& getPosition(bool updateCursor) _IRR_OVERRIDE_ { - updateCursorPos(); + if ( updateCursor ) + updateCursorPos(); return CursorPos; } //! Returns the current position of the mouse cursor. - virtual core::position2d getRelativePosition() _IRR_OVERRIDE_ + virtual core::position2d getRelativePosition(bool updateCursor) _IRR_OVERRIDE_ { - updateCursorPos(); + if ( updateCursor ) + updateCursorPos(); if (!UseReferenceRect) { diff --git a/source/Irrlicht/CIrrDeviceSDL.h b/source/Irrlicht/CIrrDeviceSDL.h index fab011c2..9047f526 100644 --- a/source/Irrlicht/CIrrDeviceSDL.h +++ b/source/Irrlicht/CIrrDeviceSDL.h @@ -156,16 +156,18 @@ namespace irr } //! Returns the current position of the mouse cursor. - virtual const core::position2d& getPosition() _IRR_OVERRIDE_ + virtual const core::position2d& getPosition(bool updateCursor) _IRR_OVERRIDE_ { - updateCursorPos(); + if ( updateCursor ) + updateCursorPos(); return CursorPos; } //! Returns the current position of the mouse cursor. - virtual core::position2d getRelativePosition() _IRR_OVERRIDE_ + virtual core::position2d getRelativePosition(bool updateCursor) _IRR_OVERRIDE_ { - updateCursorPos(); + if ( updateCursor ) + updateCursorPos(); return core::position2d(CursorPos.X / (f32)Device->Width, CursorPos.Y / (f32)Device->Height); } diff --git a/source/Irrlicht/CIrrDeviceWin32.cpp b/source/Irrlicht/CIrrDeviceWin32.cpp index bd9d2f88..5ebc5713 100644 --- a/source/Irrlicht/CIrrDeviceWin32.cpp +++ b/source/Irrlicht/CIrrDeviceWin32.cpp @@ -1717,11 +1717,12 @@ void CIrrDeviceWin32::getWindowsVersion(core::stringc& out) (LPBYTE) szProductType, &dwBufLen); RegCloseKey( hKey ); - if (_strcmpi( "WINNT", szProductType) == 0 ) + + if (irr::core::stringc("WINNT").equals_ignore_case(szProductType)) out.append("Professional "); - if (_strcmpi( "LANMANNT", szProductType) == 0) + if (irr::core::stringc("LANMANNT").equals_ignore_case(szProductType)) out.append("Server "); - if (_strcmpi( "SERVERNT", szProductType) == 0) + if (irr::core::stringc("SERVERNT").equals_ignore_case(szProductType)) out.append("Advanced Server "); } diff --git a/source/Irrlicht/CIrrDeviceWin32.h b/source/Irrlicht/CIrrDeviceWin32.h index 456d346b..b32da282 100644 --- a/source/Irrlicht/CIrrDeviceWin32.h +++ b/source/Irrlicht/CIrrDeviceWin32.h @@ -224,16 +224,18 @@ namespace irr } //! Returns the current position of the mouse cursor. - virtual const core::position2d& getPosition() _IRR_OVERRIDE_ + virtual const core::position2d& getPosition(bool updateCursor) _IRR_OVERRIDE_ { - updateInternalCursorPosition(); + if ( updateCursor ) + updateInternalCursorPosition(); return CursorPos; } //! Returns the current position of the mouse cursor. - virtual core::position2d getRelativePosition() _IRR_OVERRIDE_ + virtual core::position2d getRelativePosition(bool updateCursor) _IRR_OVERRIDE_ { - updateInternalCursorPosition(); + if ( updateCursor ) + updateInternalCursorPosition(); if (!UseReferenceRect) { diff --git a/source/Irrlicht/CMS3DMeshFileLoader.cpp b/source/Irrlicht/CMS3DMeshFileLoader.cpp index ed7d9cec..33c4957f 100644 --- a/source/Irrlicht/CMS3DMeshFileLoader.cpp +++ b/source/Irrlicht/CMS3DMeshFileLoader.cpp @@ -1,4 +1,5 @@ // Copyright (C) 2002-2012 Nikolaus Gebhardt +// 2019 additional alignment and big_endian fixes by Corto and Salas00 // This file is part of the "Irrlicht Engine". // For conditions of distribution and use, see copyright notice in irrlicht.h @@ -34,12 +35,16 @@ struct MS3DHeader // Vertex information struct MS3DVertex { + u8 pad1[3]; u8 Flags; float Vertex[3]; char BoneID; u8 RefCount; + u8 pad2[2]; } PACK_STRUCT; +#define MS3DVERTEX_NUM_PAD_BYTES 5 + // Triangle information struct MS3DTriangle { @@ -49,8 +54,11 @@ struct MS3DTriangle float S[3], T[3]; u8 SmoothingGroup; u8 GroupIndex; + u8 pad1[2]; } PACK_STRUCT; +#define MS3DTRIANGLE_NUM_PAD_BYTES 2 + // Material information struct MS3DMaterial { @@ -64,11 +72,15 @@ struct MS3DMaterial u8 Mode; // 0, 1, 2 is unused now char Texture[128]; char Alphamap[128]; + u8 pad1[3]; } PACK_STRUCT; +#define MS3DMATERIAL_NUM_PAD_BYTES 3 + // Joint information struct MS3DJoint { + u8 pad[3]; u8 Flags; char Name[32]; char ParentName[32]; @@ -78,6 +90,8 @@ struct MS3DJoint u16 NumTranslationKeyframes; } PACK_STRUCT; +#define MS3DJOINT_NUM_PAD_BYTES 3 + // Keyframe data struct MS3DKeyframe { @@ -97,6 +111,25 @@ struct MS3DVertexWeights // Default alignment #include "irrunpack.h" +// Get float encoded in little endian in way not causing troubles when floats have to be memory aligned. +static inline float get_unaligned_le_float(const u8 *ptr) +{ + union { + u8 u[4]; + float f; + } tmp; +#ifdef __BIG_ENDIAN__ + tmp.u[0] = ptr[3]; + tmp.u[1] = ptr[2]; + tmp.u[2] = ptr[1]; + tmp.u[3] = ptr[0]; +#else + tmp.f = *(float*)ptr; +#endif + return tmp.f; +} + + struct SGroup { core::stringc Name; @@ -159,7 +192,7 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file) // read whole file u8* buffer = new u8[fileSize]; - long read = (long)file->read(buffer, fileSize); + s32 read = file->read(buffer, fileSize); if (read != fileSize) { delete [] buffer; @@ -203,10 +236,10 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file) #ifdef _IRR_DEBUG_MS3D_LOADER_ os::Printer::log("Load vertices", core::stringc(numVertices).c_str()); #endif + pPtr += sizeof(u16); - MS3DVertex *vertices = (MS3DVertex*)pPtr; - pPtr += sizeof(MS3DVertex) * numVertices; - if (pPtr > buffer+fileSize) + MS3DVertex *vertices = new MS3DVertex[numVertices]; + if (pPtr + ((sizeof(MS3DVertex) - MS3DVERTEX_NUM_PAD_BYTES) * numVertices) > buffer+fileSize) { delete [] buffer; os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); @@ -214,6 +247,8 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file) } for (u16 tmp=0; tmp buffer+fileSize) + MS3DTriangle *triangles = new MS3DTriangle[numTriangles]; + if (pPtr + ((sizeof(MS3DTriangle) - MS3DTRIANGLE_NUM_PAD_BYTES) * numTriangles) > buffer+fileSize) { delete [] buffer; os::Printer::log("Loading failed. Corrupted data found.", file->getFileName(), ELL_ERROR); @@ -242,6 +278,7 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file) } for (u16 tmp=0; tmpaddMeshBuffer(); } + MS3DMaterial *material = new MS3DMaterial; for (i=0; iAmbient[j] = os::Byteswap::byteswap(material->Ambient[j]); @@ -346,7 +386,7 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file) material->Shininess = os::Byteswap::byteswap(material->Shininess); material->Transparency = os::Byteswap::byteswap(material->Transparency); #endif - pPtr += sizeof(MS3DMaterial); + pPtr += (sizeof(MS3DMaterial) - MS3DMATERIAL_NUM_PAD_BYTES); if (pPtr > buffer+fileSize) { delete [] buffer; @@ -378,12 +418,13 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file) tmpBuffer->Material.setTexture(2, Driver->getTexture(AlphamapPath)); } } + delete material; // animation time - f32 framesPerSecond = *(float*)pPtr; -#ifdef __BIG_ENDIAN__ - framesPerSecond = os::Byteswap::byteswap(framesPerSecond); -#endif + + + f32 framesPerSecond = get_unaligned_le_float(pPtr); + #ifdef _IRR_DEBUG_MS3D_LOADER_ os::Printer::log("FPS", core::stringc(framesPerSecond).c_str()); #endif @@ -422,7 +463,10 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file) for (i=0; iRotation[0] = %p (%d)\n", &pJoint->Rotation[0], (int)((long long)(&pJoint->Rotation[0]) % 4)); + memcpy(&pJoint->Flags, pPtr, sizeof(MS3DJoint) - MS3DJOINT_NUM_PAD_BYTES); + #ifdef __BIG_ENDIAN__ for (j=0; j<3; ++j) pJoint->Rotation[j] = os::Byteswap::byteswap(pJoint->Rotation[j]); @@ -431,7 +475,7 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file) pJoint->NumRotationKeyframes= os::Byteswap::byteswap(pJoint->NumRotationKeyframes); pJoint->NumTranslationKeyframes = os::Byteswap::byteswap(pJoint->NumTranslationKeyframes); #endif - pPtr += sizeof(MS3DJoint); + pPtr = pPtr + sizeof(MS3DJoint) - MS3DJOINT_NUM_PAD_BYTES; if (pPtr > buffer+fileSize) { delete [] buffer; @@ -468,11 +512,14 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file) HasAnimation = true; */ + MS3DKeyframe* kf = new MS3DKeyframe; + // get rotation keyframes const u16 numRotationKeyframes = pJoint->NumRotationKeyframes; for (j=0; j < numRotationKeyframes; ++j) { - MS3DKeyframe* kf = (MS3DKeyframe*)pPtr; + memcpy(kf, pPtr, sizeof(MS3DKeyframe)); + //printf("rotation kf = %p (%d)\n", kf, (int)((long long)kf % 4)); #ifdef __BIG_ENDIAN__ kf->Time = os::Byteswap::byteswap(kf->Time); for (u32 l=0; l<3; ++l) @@ -510,7 +557,9 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file) const u16 numTranslationKeyframes = pJoint->NumTranslationKeyframes; for (j=0; jTime = os::Byteswap::byteswap(kf->Time); for (u32 l=0; l<3; ++l) @@ -532,6 +581,9 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file) kf->Parameter[1]+pJoint->Translation[1], -kf->Parameter[2]-pJoint->Translation[2]); } + + delete kf; + delete pJoint; } core::array vertexWeights; @@ -785,6 +837,8 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file) } delete [] buffer; + delete [] triangles; + delete [] vertices; return true; } diff --git a/source/Irrlicht/COBJMeshFileLoader.cpp b/source/Irrlicht/COBJMeshFileLoader.cpp index 61663f67..d4ce82ed 100644 --- a/source/Irrlicht/COBJMeshFileLoader.cpp +++ b/source/Irrlicht/COBJMeshFileLoader.cpp @@ -635,6 +635,7 @@ void COBJMeshFileLoader::readMTL(const c8* fileName, const io::path& relPath) break; case 'e': // Ke = emissive { + currMaterial->Meshbuffer->Material.EmissiveColor.setAlpha(255); bufPtr=readColor(bufPtr, currMaterial->Meshbuffer->Material.EmissiveColor, bufEnd); } break; @@ -707,7 +708,6 @@ const c8* COBJMeshFileLoader::readColor(const c8* bufPtr, video::SColor& color, const u32 COLOR_BUFFER_LENGTH = 16; c8 colStr[COLOR_BUFFER_LENGTH]; - color.setAlpha(255); bufPtr = goAndCopyNextWord(colStr, bufPtr, COLOR_BUFFER_LENGTH, bufEnd); color.setRed((s32)(core::fast_atof(colStr) * 255.0f)); bufPtr = goAndCopyNextWord(colStr, bufPtr, COLOR_BUFFER_LENGTH, bufEnd); diff --git a/source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp b/source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp index 49453923..a06a23da 100644 --- a/source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp +++ b/source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp @@ -9,6 +9,7 @@ #include "ICursorControl.h" #include "ICameraSceneNode.h" #include "ISceneNodeAnimatorCollisionResponse.h" +#include "os.h" namespace irr { @@ -81,16 +82,11 @@ bool CSceneNodeAnimatorCameraFPS::OnEvent(const SEvent& evt) break; case EET_MOUSE_INPUT_EVENT: - if (evt.MouseInput.Event == EMIE_MOUSE_MOVED) + if ( evt.MouseInput.Event == EMIE_MOUSE_ENTER_CANVAS && CursorControl) { - if ( CursorControl ) - CursorPos = CursorControl->getRelativePosition(); - return true; - } - if ( evt.MouseInput.Event == EMIE_MOUSE_ENTER_CANVAS) - { - resetCursorPos(); - return false; + CursorControl->setPosition(0.5f, 0.5f); + CenterCursor = CursorControl->getRelativePosition(false); + CursorPos = CenterCursor; } break; @@ -107,6 +103,8 @@ void CSceneNodeAnimatorCameraFPS::animateNode(ISceneNode* node, u32 timeMs) if (!node || node->getType() != ESNT_CAMERA) return; + timeMs = os::Timer::getRealTime(); // User input is always in real-time + ICameraSceneNode* camera = static_cast(node); if (firstUpdate) @@ -115,7 +113,7 @@ void CSceneNodeAnimatorCameraFPS::animateNode(ISceneNode* node, u32 timeMs) if (CursorControl ) { CursorControl->setPosition(0.5f, 0.5f); - CursorPos = CenterCursor = CursorControl->getRelativePosition(); + CursorPos = CenterCursor = CursorControl->getRelativePosition(false); } LastAnimationTime = timeMs; @@ -140,46 +138,48 @@ void CSceneNodeAnimatorCameraFPS::animateNode(ISceneNode* node, u32 timeMs) if(smgr && smgr->getActiveCamera() != camera) return; + if ( CursorControl ) + CursorPos = CursorControl->getRelativePosition(); + // get time f32 timeDiff = (f32) ( timeMs - LastAnimationTime ); LastAnimationTime = timeMs; - // update position - core::vector3df pos = camera->getPosition(); - // Update rotation core::vector3df target = (camera->getTarget() - camera->getAbsolutePosition()); core::vector3df relativeRotation = target.getHorizontalAngle(); if (CursorControl) { + bool reset = false; + if (CursorPos != CenterCursor) { relativeRotation.Y -= (CenterCursor.X - CursorPos.X) * RotateSpeed; relativeRotation.X -= (CenterCursor.Y - CursorPos.Y) * RotateSpeed * MouseYDirection; - // Do the fix as normal, special case below - // reset cursor position to the centre of the window. - CursorControl->setPosition(0.5f, 0.5f); - CenterCursor = CursorControl->getRelativePosition(); - - // needed to avoid problems when the event receiver is disabled - CursorPos = CenterCursor; + reset = true; } - // Special case, mouse is whipped outside of window before it can update. - video::IVideoDriver* driver = smgr->getVideoDriver(); - core::vector2d mousepos(u32(CursorControl->getPosition().X), u32(CursorControl->getPosition().Y)); - core::rect screenRect(0, 0, driver->getScreenSize().Width, driver->getScreenSize().Height); + if ( !reset ) + { + // TODO: not sure if this case is still needed. Might be it was only something + // that was necessary when someone tried to use mouse-events in the past. + // But not too expensive, test on all platforms before removing. - // Only if we are moving outside quickly. - bool reset = !screenRect.isPointInside(mousepos); + // Special case, mouse is whipped outside of window before it can update. + video::IVideoDriver* driver = smgr->getVideoDriver(); + core::vector2d mousepos(u32(CursorPos.X), u32(CursorPos.Y)); + core::rect screenRect(0, 0, driver->getScreenSize().Width, driver->getScreenSize().Height); + + // Only if we are moving outside quickly. + reset = !screenRect.isPointInside(mousepos); + } if(reset) { - // Force a reset. CursorControl->setPosition(0.5f, 0.5f); - CenterCursor = CursorControl->getRelativePosition(); + CenterCursor = CursorControl->getRelativePosition(false); // often no longer 0.5 due to int/float conversions CursorPos = CenterCursor; } } @@ -205,11 +205,9 @@ void CSceneNodeAnimatorCameraFPS::animateNode(ISceneNode* node, u32 timeMs) relativeRotation.X = MaxVerticalAngle; } - // set target - - target.set(0,0, core::max_(1.f, pos.getLength())); - core::vector3df movedir = target; + target.set(0,0,1); + core::vector3df movedir(target); core::matrix4 mat; mat.setRotationDegrees(core::vector3df(relativeRotation.X, relativeRotation.Y, 0)); @@ -227,6 +225,7 @@ void CSceneNodeAnimatorCameraFPS::animateNode(ISceneNode* node, u32 timeMs) movedir.normalize(); + core::vector3df pos = camera->getPosition(); if (CursorKeys[EKA_MOVE_FORWARD]) pos += movedir * timeDiff * MoveSpeed; @@ -235,7 +234,7 @@ void CSceneNodeAnimatorCameraFPS::animateNode(ISceneNode* node, u32 timeMs) // strafing - core::vector3df strafevect = target; + core::vector3df strafevect(target); strafevect = strafevect.crossProduct(camera->getUpVector()); if (NoVerticalMovement) @@ -278,14 +277,6 @@ void CSceneNodeAnimatorCameraFPS::animateNode(ISceneNode* node, u32 timeMs) camera->setTarget(target); } -void CSceneNodeAnimatorCameraFPS::resetCursorPos() -{ - CursorControl->setPosition(0.5f, 0.5f); - CenterCursor = CursorControl->getRelativePosition(); - CursorPos = CenterCursor; -} - - void CSceneNodeAnimatorCameraFPS::allKeysUp() { for (u32 i=0; i& image) +{ + return 0; +} + bool CSoftwareDriver::setRenderTargetEx(IRenderTarget* target, u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil) { if (target && target->getDriverType() != EDT_SOFTWARE) diff --git a/source/Irrlicht/CSoftwareDriver.h b/source/Irrlicht/CSoftwareDriver.h index ab9b1af4..c816142e 100644 --- a/source/Irrlicht/CSoftwareDriver.h +++ b/source/Irrlicht/CSoftwareDriver.h @@ -99,6 +99,7 @@ namespace video virtual const core::matrix4& getTransform(E_TRANSFORMATION_STATE state) const _IRR_OVERRIDE_; virtual ITexture* createDeviceDependentTexture(const io::path& name, IImage* image) _IRR_OVERRIDE_; + virtual ITexture* createDeviceDependentTextureCubemap(const io::path& name, const core::array& image) _IRR_OVERRIDE_; //! Creates a render target texture. virtual ITexture* addRenderTargetTexture(const core::dimension2d& size, diff --git a/source/Irrlicht/CSoftwareDriver2.cpp b/source/Irrlicht/CSoftwareDriver2.cpp index fd67b053..5cbfaaca 100644 --- a/source/Irrlicht/CSoftwareDriver2.cpp +++ b/source/Irrlicht/CSoftwareDriver2.cpp @@ -2265,6 +2265,10 @@ ITexture* CBurningVideoDriver::createDeviceDependentTexture(const io::path& name return texture; } +ITexture* CBurningVideoDriver::createDeviceDependentTextureCubemap(const io::path& name, const core::array& image) +{ + return 0; +} //! Returns the maximum amount of primitives (mostly vertices) which //! the device is able to render with one drawIndexedTriangleList diff --git a/source/Irrlicht/CSoftwareDriver2.h b/source/Irrlicht/CSoftwareDriver2.h index 84760ec6..c9017306 100644 --- a/source/Irrlicht/CSoftwareDriver2.h +++ b/source/Irrlicht/CSoftwareDriver2.h @@ -176,6 +176,7 @@ namespace video //bool setTexture(u32 stage, video::ITexture* texture); virtual ITexture* createDeviceDependentTexture(const io::path& name, IImage* image) _IRR_OVERRIDE_; + virtual ITexture* createDeviceDependentTextureCubemap(const io::path& name, const core::array& image) _IRR_OVERRIDE_; video::CImage* BackBuffer; video::IImagePresenter* Presenter; diff --git a/source/Irrlicht/CTextSceneNode.cpp b/source/Irrlicht/CTextSceneNode.cpp index bd994321..5f17418b 100644 --- a/source/Irrlicht/CTextSceneNode.cpp +++ b/source/Irrlicht/CTextSceneNode.cpp @@ -373,8 +373,11 @@ void CBillboardTextSceneNode::updateMesh(const irr::scene::ICameraSceneNode* cam void CBillboardTextSceneNode::OnRegisterSceneNode() { - SceneManager->registerNodeForRendering(this, ESNRP_TRANSPARENT); - ISceneNode::OnRegisterSceneNode(); + if (IsVisible && Font && Mesh) + { + SceneManager->registerNodeForRendering(this, ESNRP_TRANSPARENT); + ISceneNode::OnRegisterSceneNode(); + } } diff --git a/tests/mrt.cpp b/tests/mrt.cpp index 78db98fc..84c8c4d3 100644 --- a/tests/mrt.cpp +++ b/tests/mrt.cpp @@ -21,8 +21,34 @@ static bool testWithDriver(video::E_DRIVER_TYPE driverType) logTestString("Testing driver %ls\n", driver->getName()); - const char* const ps1="struct PS_INPUT\n {\n float4 Position : POSITION0;\n };\n\n struct PS_OUTPUT\n {\n float4 Color : COLOR0;\n float4 Normal : COLOR1;\n float4 Depth : COLOR2;\n };\n PS_OUTPUT pixelMain( PS_INPUT Input )\n {\n PS_OUTPUT Output;\n Output.Color = float4(1.0,1.0,1.0,1.0);\n Output.Normal = float4(0.0,1.0,0.0,1.0);\n Output.Depth = float4(0.0,0.0,1.0,1.0);\n return Output;\n }"; - const char* const ps2="void main(void)\n {\n gl_FragData[0] = vec4(1.0,1.0,1.0,1.0);\n gl_FragData[1] = vec4(0.0,1.0,0.0,1.0);\n gl_FragData[2] = vec4(0.0,0.0,1.0,1.0);\n }"; + // write white to first render-texture, green to second, blue to third + const char* const psHLSL = + "struct PS_INPUT\n"\ + "{\n"\ + " float4 Position : POSITION0;\n"\ + "};\n"\ + "struct PS_OUTPUT\n"\ + "{\n "\ + " float4 Color : COLOR0;\n"\ + " float4 Normal : COLOR1;\n"\ + " float4 Depth : COLOR2;\n"\ + "};\n"\ + "PS_OUTPUT pixelMain( PS_INPUT Input )\n"\ + "{\n"\ + " PS_OUTPUT Output;\n"\ + " Output.Color = float4(1.0,1.0,1.0,1.0);\n"\ + " Output.Normal = float4(0.0,1.0,0.0,1.0);\n"\ + " Output.Depth = float4(0.0,0.0,1.0,1.0);\n"\ + " return Output;\n"\ + "}"; + + const char* const psGLSL = + "void main(void)\n"\ + "{\n"\ + " gl_FragData[0] = vec4(1.0,1.0,1.0,1.0);\n"\ + " gl_FragData[1] = vec4(0.0,1.0,0.0,1.0);\n"\ + " gl_FragData[2] = vec4(0.0,0.0,1.0,1.0);\n"\ + "}"; // variable video::IRenderTarget* renderTarget = 0; @@ -51,7 +77,7 @@ static bool testWithDriver(video::E_DRIVER_TYPE driverType) { newMaterialType = gpu->addHighLevelShaderMaterial( 0, "vertexMain", video::EVST_VS_1_1, - driverType==video::EDT_DIRECT3D9?ps1:ps2, "pixelMain", video::EPST_PS_1_1); + driverType==video::EDT_DIRECT3D9?psHLSL:psGLSL, "pixelMain", video::EPST_PS_1_1); } } diff --git a/tests/tests-last-passed-at.txt b/tests/tests-last-passed-at.txt index eb9e250c..4755cf20 100644 --- a/tests/tests-last-passed-at.txt +++ b/tests/tests-last-passed-at.txt @@ -1,4 +1,4 @@ -Tests finished. 72 tests of 72 passed. -Compiled as DEBUG -Test suite pass at GMT Fri Nov 22 15:52:21 2019 - +Tests finished. 72 tests of 72 passed. +Compiled as DEBUG +Test suite pass at GMT Tue Nov 26 13:57:09 2019 +