diff --git a/changes.txt b/changes.txt index 39e604ea..e86cc1a5 100644 --- a/changes.txt +++ b/changes.txt @@ -9,6 +9,26 @@ Changes in ogl-es (not yet released - will be merged with trunk at some point) -------------------------- Changes in 1.9 (not yet released) +- Fix bug that AnimatedMeshSceneNode ignored ReadOnlyMaterials flag when checking materials for transparent render passes. +- Unify checks if materials should use transparent render pass with new IVideoDriver::needsTransparentRenderPass function. +- Material.ZWriteEnable is now of type E_ZWRITE instead of bool. This allows now setting materials to always "on" independent of material type and transparency. + This breaks compiling. To have old values replace false with EZW_OFF and true with EWZ_AUTO. +- Materials EMT_REFLECTION_2_LAYER and EMT_TRANSPARENT_REFLECTION_2_LAYER on OpenGL are now same as in D3D9. Before GL used a sphere-map for those instead of reflection. +- Bugfix: CGUIToolBar automatic placement no longer outside of screen when there are modals screens when creating it. + Or when there are other window elements going over full window-size. + Thanks to Stephen Lynx for the bugreport and to Sérgio Augusto Vianna for writing a test case with a bug example. + Changes: a) Never move the toolbar below it's parents lower border. b) No longer check all element-types, but only try to be below other toolbars or menues. +- Add a normalType parameter to IGeometryCreator::createCylinderMesh +- Add a normalsUpdate parameter to IMeshManipulator::transform to allow updating the normals with the inverse-transpose of the transformation matrix. +- Bugfix: quaternion::slerp now uses lerpN instead of lerp to keep result normalized. +- Add function quaternion::lerpN which is like lerp but normalizes the result. +- Add function ISceneManager::createShadowVolumeSceneNode to allow custom ISceneNode's to use shadows. +- CGUITabControl serialization changed to allow using custom tabs (before only CGUITab could be serialized). + There was a lot of rewriting involved, including some minor interface changes (IGUITab* can now be added directly for example). + See http://irrlicht.sourceforge.net/forum/viewtopic.php?f=7&t=52344 for a thread about this. + Thanks @chronologicaldot for bringing this up, writing a patch proposal and even writing test. +- CGUITabControl no longer eats EMIE_LMOUSE_PRESSED_DOWN (doesn't seem to need it, was just done for a planned feature which is not implemented yet). +- Removing a tab in CGUITabControl will now also remove the tab-element. Fixes problems like tabs still being around & visible when you removed the active tab. - 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 @@ -16,7 +36,10 @@ Changes in 1.9 (not yet released) 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). +- FPS-camera rotation now smoother. + First bug was that it would sometimes skip back because it worked with wrong values for the screen-center position. + Second (and bigger) bug was that it ignored all cursor-movement which happened between device->run() and the point where + the animator did run. Tiny side-effect your camera will now rotate generally faster. - 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. @@ -95,7 +118,7 @@ Changes in 1.9 (not yet released) - 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 IOctreeSceneNode interface to control polygon clipping checks for octree scene nodes. - 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) @@ -145,8 +168,6 @@ Changes in 1.9 (not yet released) - Fix bug with ignored opening brace in .X files with DeclData section. Thx @Alin for bugreport and patch. - Fix problem with OpenGL textures cache. - Add clear buffer flags and marked some methods used for clear buffers as deprecated. -- Fix: CGUIImage no longer scales wrong when working with textures which don't have the original image size. -- Fix CSoftwareTexture2 calculation for OriginalSize of ITexture. It was returning the changed texture size instead of the original one before. - 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. diff --git a/doc/release_checklist.txt b/doc/release_checklist.txt index c228c921..840e7728 100644 --- a/doc/release_checklist.txt +++ b/doc/release_checklist.txt @@ -25,6 +25,7 @@ compiler, otherwise oldest you have still installed) - - create a target directory, like irrlicht-1.8.1 for example - - svn export to the target directory - - copy the subfolders of doctemp into the doc folder of the target directory + careful, this should only be one(!) subfolder (we ended up with copies before, maybe Windows/Linux builds use different names?) - - copy all .exe files (except test.exe) from bin\Win32-VisualStudio (.pdb's are not necessary) - - copy Irrlicht.dll from bin\Win32-visualstudio - - copy the files in lib\Win32-visualstudio diff --git a/examples/22.MaterialViewer/main.cpp b/examples/22.MaterialViewer/main.cpp index 6f9c766e..83309260 100755 --- a/examples/22.MaterialViewer/main.cpp +++ b/examples/22.MaterialViewer/main.cpp @@ -778,7 +778,7 @@ bool CApp::update() // Figure out delta time since last frame ITimer * timer = Device->getTimer(); u32 newTick = timer->getRealTime(); - f32 deltaTime = RealTimeTick > 0 ? f32(newTick-RealTimeTick)/1000.0 : 0.f; // in seconds + f32 deltaTime = RealTimeTick > 0 ? f32(newTick-RealTimeTick)/1000.f : 0.f; // in seconds RealTimeTick = newTick; if ( Device->isWindowActive() || Config.RenderInBackground ) diff --git a/include/EMaterialTypes.h b/include/EMaterialTypes.h index 3dac0690..cdbd4997 100644 --- a/include/EMaterialTypes.h +++ b/include/EMaterialTypes.h @@ -118,9 +118,7 @@ namespace video //! A transparent reflecting material with an optional additional non reflecting texture layer. /** The reflection map should be set as first texture. The transparency depends on the alpha value in the vertex colors. A - texture which will not reflect can be set as second texture. - Please note that this material type is currently not 100% - implemented in OpenGL. */ + texture which will not reflect can be set as second texture.*/ EMT_TRANSPARENT_REFLECTION_2_LAYER, //! A solid normal map renderer. @@ -189,7 +187,9 @@ namespace video EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA, //! BlendFunc = source * sourceFactor + dest * destFactor ( E_BLEND_FUNC ) - /** Using only first texture. Generic blending method. */ + /** Using only first texture. Generic blending method. + The blend function is set to SMaterial::MaterialTypeParam with + pack_textureBlendFunc (for 2D) or pack_textureBlendFuncSeparate (for 3D). */ EMT_ONETEXTURE_BLEND, //! This value is not used. It only forces this enumeration to compile to 32 bit. diff --git a/include/IGUIEnvironment.h b/include/IGUIEnvironment.h index f58b80a3..695b41b8 100644 --- a/include/IGUIEnvironment.h +++ b/include/IGUIEnvironment.h @@ -250,8 +250,13 @@ public: const wchar_t* text=0, IGUIElement* parent=0, s32 id=-1) = 0; //! Adds a modal screen. - /** This control stops its parent's members from being able to receive - input until its last child is removed, it then deletes itself. + /** Input focus stays with children of the modal screen. + If you have some window x which should keep the input focus you + do something like: addModalScreen()->addChild(x). And x will then get the focus + and not lose it anymore. + The modal screen removes itself when it no longer has any children. + Note that it usually works badly to pass the modal screen already as parent when creating + a new element. It's better to add that new element later to the modal screen with addChild. \param parent Parent gui element of the modal. \return Pointer to the created modal. Returns 0 if an error occurred. This pointer should not be dropped. See IReferenceCounted::drop() for diff --git a/include/IGUITabControl.h b/include/IGUITabControl.h index 9f7ace36..8301238d 100644 --- a/include/IGUITabControl.h +++ b/include/IGUITabControl.h @@ -13,40 +13,7 @@ namespace irr { namespace gui { - //! A tab-page, onto which other gui elements could be added. - /** IGUITab refers mostly to the page itself, but also carries some data about the tab in the tabbar of an IGUITabControl. */ - class IGUITab : public IGUIElement - { - public: - - //! constructor - IGUITab(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) - : IGUIElement(EGUIET_TAB, environment, parent, id, rectangle) {} - - //! Returns zero based index of tab if in tabcontrol. - /** Can be accessed later IGUITabControl::getTab() by this number. - Note that this number can change when other tabs are inserted or removed . - */ - virtual s32 getNumber() const = 0; - - //! sets if the tab should draw its background - virtual void setDrawBackground(bool draw=true) = 0; - - //! sets the color of the background, if it should be drawn. - virtual void setBackgroundColor(video::SColor c) = 0; - - //! returns true if the tab is drawing its background, false if not - virtual bool isDrawingBackground() const = 0; - - //! returns the color of the background - virtual video::SColor getBackgroundColor() const = 0; - - //! sets the color of it's text in the tab-bar - virtual void setTextColor(video::SColor c) = 0; - - //! gets the color of the text - virtual video::SColor getTextColor() const = 0; - }; + class IGUITab; //! A standard tab control /** \par This element can create the following events of type EGUI_EVENT_TYPE: @@ -63,10 +30,27 @@ namespace gui //! Adds a tab virtual IGUITab* addTab(const wchar_t* caption, s32 id=-1) = 0; + //! Adds an existing tab + /** Note that it will also add the tab as a child of this TabControl. + \return Index of added tab or -1 for failure*/ + virtual s32 addTab(IGUITab* tab) = 0; + //! Insert the tab at the given index /** \return The tab on success or NULL on failure. */ virtual IGUITab* insertTab(s32 idx, const wchar_t* caption, s32 id=-1) = 0; + //! Insert an existing tab + /** Note that it will also add the tab as a child of this TabControl. + \param idx Index at which tab will be inserted. Later tabs will be moved. + Previous active tab will stay active unless this is the first + element to be inserted in which case it becomes active. + \param tab New tab to insert. + \param serializationMode Internally used for serialization. You should not need this. + When true it reserves space for the index, doesn't move but replaces tabs + and it doesn't change the active tab. + \return Index of added tab (should be same as the one passed) or -1 for failure*/ + virtual s32 insertTab(s32 idx, IGUITab* tab, bool serializationMode=false) = 0; + //! Removes a tab from the tabcontrol virtual void removeTab(s32 idx) = 0; @@ -82,6 +66,13 @@ namespace gui is corresponding to this tab. */ virtual IGUITab* getTab(s32 idx) const = 0; + //! For given element find if it's a tab and return it's zero-based index (or -1 for not found) + /** \param tab Tab for which we are looking (usually you will look for an IGUITab* type as only + those can be tabs, but we allow looking for any kind of IGUIElement* as there are some + use-cases for that even if it just returns 0. For example this way you can check for + all children of this gui-element if they are tabs or some non-tab children.*/ + virtual s32 getTabIndex(const IGUIElement *tab) const = 0; + //! Brings a tab to front. /** \param idx: number of the tab. \return Returns true if successful. */ @@ -128,6 +119,43 @@ namespace gui virtual s32 getTabExtraWidth() const = 0; }; + //! A tab-page, onto which other gui elements could be added. + /** IGUITab refers mostly to the page itself, but also carries some data about the tab in the tabbar of an IGUITabControl. */ + class IGUITab : public IGUIElement + { + public: + + //! constructor + IGUITab(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect rectangle) + : IGUIElement(EGUIET_TAB, environment, parent, id, rectangle) {} + + //! Returns zero based index of tab if in tabcontrol. + /** \deprecated Deprecated in 1.9, use IGUITabControl::getTabIndex instead*/ + _IRR_DEPRECATED_ virtual s32 getNumber() const + { + if (Parent && Parent->getType() == EGUIET_TAB_CONTROL) + return static_cast(Parent)->getTabIndex(this); + return -1; + } + + //! sets if the tab should draw its background + virtual void setDrawBackground(bool draw=true) = 0; + + //! sets the color of the background, if it should be drawn. + virtual void setBackgroundColor(video::SColor c) = 0; + + //! returns true if the tab is drawing its background, false if not + virtual bool isDrawingBackground() const = 0; + + //! returns the color of the background + virtual video::SColor getBackgroundColor() const = 0; + + //! sets the color of it's text in the tab-bar + virtual void setTextColor(video::SColor c) = 0; + + //! gets the color of the text + virtual video::SColor getTextColor() const = 0; + }; } // end namespace gui } // end namespace irr diff --git a/include/IGeometryCreator.h b/include/IGeometryCreator.h index fbc76a93..6083f5b4 100644 --- a/include/IGeometryCreator.h +++ b/include/IGeometryCreator.h @@ -152,13 +152,21 @@ public: \param tesselation Number of quads around the circumference of the cylinder. \param color The color of the cylinder. \param closeTop If true, close the ends of the cylinder, otherwise leave them open. - \param oblique (to be documented) + \param oblique X-offset (shear) of top compared to bottom. + \param normalType When 0 side normals are radial from origin. Note that origin is at the bottom. + When 1 side normals are flat along top/bottom polygons. + NOTE: To get normals which are perpendicular to the side of an oblique + cylinder, don't use the oblique parameter. Instead set normalType to 1 + and create a cylinder with oblique set to 0. Then use + IMeshManipulator::transform with a shear matrix on the returned mesh. + You get a shear matrix for an identical effect of this oblique parameter when you + set the 4th element of an identity matrix to (oblique/length). \return Generated mesh. */ virtual IMesh* createCylinderMesh(f32 radius, f32 length, u32 tesselation, const video::SColor& color=video::SColor(0xffffffff), - bool closeTop=true, f32 oblique=0.f) const =0; + bool closeTop=true, f32 oblique=0.f, u32 normalType=0) const =0; //! Create a cone mesh. /** diff --git a/include/ILightSceneNode.h b/include/ILightSceneNode.h index 445ee2dd..62533a0d 100644 --- a/include/ILightSceneNode.h +++ b/include/ILightSceneNode.h @@ -51,6 +51,7 @@ public: shadows. Setting the radius will also influence the attenuation, setting it to (0,1/radius,0). If you want to override this behavior, set the attenuation after the radius. + NOTE: On OpenGL only the attenuation is set, there's no hard range. \param radius The new radius. */ virtual void setRadius(f32 radius) = 0; diff --git a/include/IMeshManipulator.h b/include/IMeshManipulator.h index 3dbbccc4..8ff59564 100644 --- a/include/IMeshManipulator.h +++ b/include/IMeshManipulator.h @@ -144,18 +144,44 @@ namespace scene //! Applies a transformation to a mesh /** \param mesh Mesh on which the operation is performed. - \param m transformation matrix. */ - void transform(IMesh* mesh, const core::matrix4& m) const + \param m transformation matrix. + \param normalsUpdate When 0 - don't update normals. + When 1 - update normals with inverse transposed of the transformation matrix + */ + void transform(IMesh* mesh, const core::matrix4& m, u32 normalsUpdate = 0) const { apply(SVertexPositionTransformManipulator(m), mesh, true); + + if ( normalsUpdate == 1 ) + { + core::matrix4 invT; + if ( m.getInverse(invT) ) + { + invT = invT.getTransposed(); + apply(SVertexNormalTransformManipulator(invT), mesh, false); + } + } } //! Applies a transformation to a meshbuffer /** \param buffer Meshbuffer on which the operation is performed. - \param m transformation matrix. */ - void transform(IMeshBuffer* buffer, const core::matrix4& m) const + \param m transformation matrix. + \param normalsUpdate When 0 - don't update normals. + When 1 - update normals with inverse transposed of the transformation matrix + */ + void transform(IMeshBuffer* buffer, const core::matrix4& m, u32 normalsUpdate = 0) const { apply(SVertexPositionTransformManipulator(m), buffer, true); + + if ( normalsUpdate == 1 ) + { + core::matrix4 invT; + if ( m.getInverse(invT) ) + { + invT = invT.getTransposed(); + apply(SVertexNormalTransformManipulator(invT), buffer, false); + } + } } //! Applies a transformation to a mesh diff --git a/include/IOctreeSceneNode.h b/include/IOctreeSceneNode.h index 4e2b08fd..352a274a 100644 --- a/include/IOctreeSceneNode.h +++ b/include/IOctreeSceneNode.h @@ -63,12 +63,9 @@ public: const core::vector3df& scale = core::vector3df(1,1,1)) : IMeshSceneNode(parent, mgr, id, position, rotation, scale) {} - //! Set if/how vertex buffer object are used for the meshbuffers - /** NOTE: When there is already a mesh in the node this will rebuild - the octree. */ - virtual void setUseVBO(EOCTREENODE_VBO useVBO) = 0; - //! Get if/how vertex buffer object are used for the meshbuffers + // NOTE: Will currently _always_ return EOV_NO_VBO. + // Octree's with VBO's don't work yet correctly. virtual EOCTREENODE_VBO getUseVBO() const = 0; //! Set the kind of tests polygons do for visibility against the camera diff --git a/include/ISceneManager.h b/include/ISceneManager.h index 27be3451..29b4b878 100644 --- a/include/ISceneManager.h +++ b/include/ISceneManager.h @@ -121,6 +121,7 @@ namespace scene class ISceneNodeAnimatorFactory; class ISceneNodeFactory; class ISceneUserDataSerializer; + class IShadowVolumeSceneNode; class ITerrainSceneNode; class ITextSceneNode; class ITriangleSelector; @@ -1108,6 +1109,11 @@ namespace scene //! Get the current color of shadows. virtual video::SColor getShadowColor() const = 0; + //! Create a shadow volume scene node to be used with custom nodes + /** Use this if you implement your own SceneNodes and need shadow volumes in them. + Otherwise you should generally use addShadowVolumeSceneNode functions from IMeshSceneNode or IAnimatedMeshSceneNode.*/ + virtual IShadowVolumeSceneNode* createShadowVolumeSceneNode(const IMesh* shadowMesh, ISceneNode* parent, s32 id, bool zfailmethod, f32 infinity) = 0; + //! Registers a node for rendering it at a specific time. /** This method should only be used by SceneNodes when they get a ISceneNode::OnRegisterSceneNode() call. diff --git a/include/IVideoDriver.h b/include/IVideoDriver.h index add3ba63..a8031afc 100644 --- a/include/IVideoDriver.h +++ b/include/IVideoDriver.h @@ -1317,7 +1317,7 @@ namespace video the E_MATERIAL_TYPE enum or a value which was returned by addMaterialRenderer(). \return Pointer to material renderer or null if not existing. */ - virtual IMaterialRenderer* getMaterialRenderer(u32 idx) =0; + virtual IMaterialRenderer* getMaterialRenderer(u32 idx) const = 0; //! Get amount of currently available material renderers. /** \return Amount of currently available material renderers. */ @@ -1526,6 +1526,9 @@ namespace video //! Check if the driver supports creating textures with the given color format /** \return True if the format is available, false if not. */ virtual bool queryTextureFormat(ECOLOR_FORMAT format) const = 0; + + //! Used by some SceneNodes to check if a material should be rendered in the transparent render pass + virtual bool needsTransparentRenderPass(const irr::video::SMaterial& material) const = 0; }; } // end namespace video diff --git a/include/SLight.h b/include/SLight.h index f809d2ee..60df5f6b 100644 --- a/include/SLight.h +++ b/include/SLight.h @@ -70,7 +70,7 @@ struct SLight //! The angle of the spot's inner cone. Ignored for other lights. f32 InnerCone; - //! The light strength's decrease between Outer and Inner cone. + //! The light strength's decrease between Outer and Inner cone. Only for spot lights f32 Falloff; //! Read-ONLY! Position of the light. @@ -82,6 +82,9 @@ struct SLight core::vector3df Direction; //! Read-ONLY! Radius of light. Everything within this radius will be lighted. + /** On OpenGL light doesn't stop at radius. To get same light as in OpenGL in other drivers + do set the radius to a large value like sqrt(FLT_MAX) and then set the Attenuation afterwards. + */ f32 Radius; //! Read-ONLY! Type of the light. Default: ELT_POINT diff --git a/include/SMaterial.h b/include/SMaterial.h index a5f310af..7604ef46 100644 --- a/include/SMaterial.h +++ b/include/SMaterial.h @@ -19,7 +19,8 @@ namespace video { class ITexture; - //! Flag for EMT_ONETEXTURE_BLEND, ( BlendFactor ) BlendFunc = source * sourceFactor + dest * destFactor + //! Flag for MaterialTypeParam (in combination with EMT_ONETEXTURE_BLEND) or for BlendFactor + //! BlendFunc = source * sourceFactor + dest * destFactor enum E_BLEND_FACTOR { EBF_ZERO = 0, //!< src & dest (0, 0, 0, 0) @@ -247,16 +248,33 @@ namespace video 0 }; - //! Fine-tuning for SMaterial.ZWriteFineControl - enum E_ZWRITE_FINE_CONTROL + //! For SMaterial.ZWriteEnable + enum E_ZWRITE { - //! Default. Only write zbuffer when SMaterial::ZBuffer is true and SMaterial::isTransparent() returns false. - EZI_ONLY_NON_TRANSPARENT, - //! Writing will just be based on SMaterial::ZBuffer value, transparency is ignored. - //! Needed mostly for certain shader materials as SMaterial::isTransparent will always return false for those. - EZI_ZBUFFER_FLAG + //! zwrite always disabled for this material + EZW_OFF = 0, + + //! This is the default setting for SMaterial and tries to handle things automatically. + //! This is also the value which is set when SMaterial::setFlag(EMF_ZWRITE_ENABLE) is enabled. + //! Usually zwriting is enabled non-transparent materials - as far as Irrlicht can recognize those. + //! Basically Irrlicht tries to handle the zwriting for you and assumes transparent materials don't need it. + //! This is addionally affected by IVideoDriver::setAllowZWriteOnTransparent + EZW_AUTO, + + //! zwrite always enabled for this material + EZW_ON }; + //! Names for E_ZWRITE + const c8* const ZWriteNames[] = + { + "Off", + "Auto", + "On", + 0 + }; + + //! Maximum number of texture an SMaterial can have. /** SMaterial might ignore some textures in most function, like assignment and comparison, @@ -296,9 +314,8 @@ namespace video PolygonOffsetFactor(0), PolygonOffsetDirection(EPO_FRONT), PolygonOffsetDepthBias(0.f), PolygonOffsetSlopeScale(0.f), Wireframe(false), PointCloud(false), GouraudShading(true), - Lighting(true), ZWriteEnable(true), BackfaceCulling(true), FrontfaceCulling(false), - FogEnable(false), NormalizeNormals(false), UseMipMaps(true), - ZWriteFineControl(EZI_ONLY_NON_TRANSPARENT) + Lighting(true), ZWriteEnable(EZW_AUTO), BackfaceCulling(true), FrontfaceCulling(false), + FogEnable(false), NormalizeNormals(false), UseMipMaps(true) { } //! Copy constructor @@ -354,7 +371,6 @@ namespace video PolygonOffsetDepthBias = other.PolygonOffsetDepthBias; PolygonOffsetSlopeScale = other.PolygonOffsetSlopeScale; UseMipMaps = other.UseMipMaps; - ZWriteFineControl = other.ZWriteFineControl; return *this; } @@ -416,8 +432,8 @@ namespace video f32 Shininess; //! Free parameter, dependent on the material type. - /** Mostly ignored, used for example in EMT_PARALLAX_MAP_SOLID - and EMT_TRANSPARENT_ALPHA_CHANNEL. */ + /** Mostly ignored, used for example in EMT_PARALLAX_MAP_SOLID, + EMT_TRANSPARENT_ALPHA_CHANNEL and EMT_ONETEXTURE_BLEND. */ f32 MaterialTypeParam; //! Second free parameter, dependent on the material type. @@ -459,8 +475,14 @@ namespace video //! Store the blend factors /** textureBlendFunc/textureBlendFuncSeparate functions should be used to write - properly blending factors to this parameter. If you use EMT_ONETEXTURE_BLEND - type for this material, this field should be equal to MaterialTypeParam. */ + properly blending factors to this parameter. + Due to historical reasons this parameter is not used for material type + EMT_ONETEXTURE_BLEND which uses MaterialTypeParam instead for the blend factor. + It's generally used only for materials without any blending otherwise (like EMT_SOLID). + It's main use is to allow having shader materials which can enable/disable + blending after they have been created. + When you set this you usually also have to set BlendOperation to a value != EBO_NONE + (setting it to EBO_ADD is probably the most common one value). */ f32 BlendFactor; //! DEPRECATED. Will be removed after Irrlicht 1.9. Please use PolygonOffsetDepthBias instead. @@ -508,12 +530,10 @@ namespace video //! Will this material be lighted? Default: true bool Lighting:1; - //! Is the zbuffer writable or is it read-only. Default: true. - /** This flag is forced to false if the MaterialType is a - transparent type and the scene parameter - ALLOW_ZWRITE_ON_TRANSPARENT is not set. If you set this parameter - to true, make sure that ZBuffer value is other than ECFN_DISABLED */ - bool ZWriteEnable:1; + //! Is the zbuffer writable or is it read-only. Default: EZW_AUTO. + /** If this parameter is not EZW_OFF, you probably also want to set ZBuffer + to values other than ECFN_DISABLED */ + E_ZWRITE ZWriteEnable:2; //! Is backface culling enabled? Default: true bool BackfaceCulling:1; @@ -532,11 +552,6 @@ namespace video /** Sometimes, disabling mipmap usage can be useful. Default: true */ bool UseMipMaps:1; - //! Give more control how the ZWriteEnable flag is interpreted - /** Note that there is also the global flag AllowZWriteOnTransparent - which when set acts like all materials have set EZI_ALLOW_ON_TRANSPARENT. */ - E_ZWRITE_FINE_CONTROL ZWriteFineControl:1; - //! Gets the texture transformation matrix for level i /** \param i The desired level. Must not be larger than MATERIAL_MAX_TEXTURES \return Texture matrix for texture level i. */ @@ -603,7 +618,7 @@ namespace video case EMF_ZBUFFER: ZBuffer = value; break; case EMF_ZWRITE_ENABLE: - ZWriteEnable = value; break; + ZWriteEnable = value ? EZW_AUTO : EZW_OFF; break; case EMF_BACK_FACE_CULLING: BackfaceCulling = value; break; case EMF_FRONT_FACE_CULLING: @@ -684,7 +699,7 @@ namespace video case EMF_ZBUFFER: return ZBuffer!=ECFN_DISABLED; case EMF_ZWRITE_ENABLE: - return ZWriteEnable; + return ZWriteEnable != EZW_OFF; case EMF_BACK_FACE_CULLING: return BackfaceCulling; case EMF_FRONT_FACE_CULLING: @@ -756,8 +771,7 @@ namespace video PolygonOffsetDirection != b.PolygonOffsetDirection || PolygonOffsetDepthBias != b.PolygonOffsetDepthBias || PolygonOffsetSlopeScale != b.PolygonOffsetSlopeScale || - UseMipMaps != b.UseMipMaps || - ZWriteFineControl != b.ZWriteFineControl; + UseMipMaps != b.UseMipMaps ; for (u32 i=0; (i + void operator()(VType& vertex) const + { + Transformation.transformVect(vertex.Normal); + } + private: + core::matrix4 Transformation; + }; + //! Vertex manipulator which scales the TCoords of the vertex class SVertexTCoordsScaleManipulator : public IVertexManipulator { diff --git a/include/irrMath.h b/include/irrMath.h index 53e87af4..3818fc9e 100644 --- a/include/irrMath.h +++ b/include/irrMath.h @@ -483,25 +483,14 @@ namespace core state ^= ( ( -condition >> 31 ) ^ state ) & mask; } + // NOTE: This is not as exact as the c99/c++11 round function, especially at high numbers starting with 8388609 + // (only low number which seems to go wrong is 0.49999997 which is rounded to 1) + // Also negative 0.5 is rounded up not down unlike with the standard function (p.E. input -0.5 will be 0 and not -1) inline f32 round_( f32 x ) { return floorf( x + 0.5f ); } - REALINLINE void clearFPUException () - { -#ifdef IRRLICHT_FAST_MATH - return; - #ifdef feclearexcept - feclearexcept(FE_ALL_EXCEPT); - #elif defined(_MSC_VER) - __asm fnclex; - #elif defined(__GNUC__) && defined(__x86__) - __asm__ __volatile__ ("fclex \n\t"); - #endif -#endif - } - // calculate: sqrt ( x ) REALINLINE f32 squareroot(const f32 f) { @@ -538,7 +527,10 @@ namespace core REALINLINE f32 reciprocal_squareroot(const f32 f) { #if defined ( IRRLICHT_FAST_MATH ) - #if defined(_MSC_VER) + // NOTE: Unlike comment below says I found inaccuracies already at 4'th significant bit. + // p.E: Input 1, expected 1, got 0.999755859 + + #if defined(_MSC_VER) && !defined(_WIN64) // SSE reciprocal square root estimate, accurate to 12 significant // bits of the mantissa f32 recsqrt; @@ -570,12 +562,13 @@ namespace core REALINLINE f32 reciprocal( const f32 f ) { #if defined (IRRLICHT_FAST_MATH) + // NOTE: Unlike with 1.f / f the values very close to 0 return -nan instead of inf // SSE Newton-Raphson reciprocal estimate, accurate to 23 significant // bi ts of the mantissa // One Newton-Raphson Iteration: // f(i+1) = 2 * rcpss(f) - f * rcpss(f) * rcpss(f) -#if defined(_MSC_VER) +#if defined(_MSC_VER) && !defined(_WIN64) f32 rec; __asm rcpss xmm0, f // xmm0 = rcpss(f) __asm movss xmm1, f // xmm1 = f @@ -617,7 +610,7 @@ namespace core // bi ts of the mantissa // One Newton-Raphson Iteration: // f(i+1) = 2 * rcpss(f) - f * rcpss(f) * rcpss(f) -#if defined(_MSC_VER) +#if defined(_MSC_VER) && !defined(_WIN64) f32 rec; __asm rcpss xmm0, f // xmm0 = rcpss(f) __asm movss xmm1, f // xmm1 = f @@ -652,94 +645,18 @@ namespace core REALINLINE s32 floor32(f32 x) { -#ifdef IRRLICHT_FAST_MATH - const f32 h = 0.5f; - - s32 t; - -#if defined(_MSC_VER) - __asm - { - fld x - fsub h - fistp t - } -#elif defined(__GNUC__) - __asm__ __volatile__ ( - "fsub %2 \n\t" - "fistpl %0" - : "=m" (t) - : "t" (x), "f" (h) - : "st" - ); -#else return (s32) floorf ( x ); -#endif - return t; -#else // no fast math - return (s32) floorf ( x ); -#endif } - REALINLINE s32 ceil32 ( f32 x ) { -#ifdef IRRLICHT_FAST_MATH - const f32 h = 0.5f; - - s32 t; - -#if defined(_MSC_VER) - __asm - { - fld x - fadd h - fistp t - } -#elif defined(__GNUC__) - __asm__ __volatile__ ( - "fadd %2 \n\t" - "fistpl %0 \n\t" - : "=m"(t) - : "t"(x), "f"(h) - : "st" - ); -#else return (s32) ceilf ( x ); -#endif - return t; -#else // not fast math - return (s32) ceilf ( x ); -#endif } - - + // NOTE: Please check round_ documentation about some inaccuracies in this compared to standard library round function. REALINLINE s32 round32(f32 x) { -#if defined(IRRLICHT_FAST_MATH) - s32 t; - -#if defined(_MSC_VER) - __asm - { - fld x - fistp t - } -#elif defined(__GNUC__) - __asm__ __volatile__ ( - "fistpl %0 \n\t" - : "=m"(t) - : "t"(x) - : "st" - ); -#else return (s32) round_(x); -#endif - return t; -#else // no fast math - return (s32) round_(x); -#endif } inline f32 f32_max3(const f32 a, const f32 b, const f32 c) diff --git a/include/irrString.h b/include/irrString.h index 6f4812a9..0b57864a 100644 --- a/include/irrString.h +++ b/include/irrString.h @@ -1376,8 +1376,9 @@ public: \param delimiter C-style string of delimiter characters \param countDelimiters Number of delimiter characters \param ignoreEmptyTokens Flag to avoid empty substrings in the result - container. If two delimiters occur without a character in between, an - empty substring would be placed in the result. If this flag is set, + container. If two delimiters occur without a character in between or an + empty substring would be placed in the result. Or if a delimiter is the last + character an empty substring would be added at the end. If this flag is set, only non-empty strings are stored. \param keepSeparators Flag which allows to add the separator to the result string. If this flag is true, the concatenation of the @@ -1400,17 +1401,15 @@ public: { if (array[i] == delimiter[j]) { + if (i - tokenStartIdx > 0) + ret.push_back(string(&array[tokenStartIdx], i - tokenStartIdx)); + else if ( !ignoreEmptyTokens ) + ret.push_back(string()); if ( keepSeparators ) { - ret.push_back(string(&array[tokenStartIdx], i+1 - tokenStartIdx)); - } - else - { - if (i - tokenStartIdx > 0) - ret.push_back(string(&array[tokenStartIdx], i - tokenStartIdx)); - else if ( !ignoreEmptyTokens ) - ret.push_back(string()); + ret.push_back(string(&array[i], 1)); } + tokenStartIdx = i+1; break; } @@ -1418,6 +1417,8 @@ public: } if ((used - 1) > tokenStartIdx) ret.push_back(string(&array[tokenStartIdx], (used - 1) - tokenStartIdx)); + else if ( !ignoreEmptyTokens ) + ret.push_back(string()); return ret.size()-oldSize; } diff --git a/include/quaternion.h b/include/quaternion.h index 97e2581c..5fdff798 100644 --- a/include/quaternion.h +++ b/include/quaternion.h @@ -140,14 +140,27 @@ class quaternion quaternion& makeInverse(); //! Set this quaternion to the linear interpolation between two quaternions - /** \param q1 First quaternion to be interpolated. + /** NOTE: lerp result is *not* a normalized quaternion. In most cases + you will want to use lerpN instead as most other quaternion functions expect + to work with a normalized quaternion. + \param q1 First quaternion to be interpolated. \param q2 Second quaternion to be interpolated. \param time Progress of interpolation. For time=0 the result is q1, for time=1 the result is q2. Otherwise interpolation - between q1 and q2. + between q1 and q2. Result is not normalized. */ quaternion& lerp(quaternion q1, quaternion q2, f32 time); + //! Set this quaternion to the linear interpolation between two quaternions and normalize the result + /** + \param q1 First quaternion to be interpolated. + \param q2 Second quaternion to be interpolated. + \param time Progress of interpolation. For time=0 the result is + q1, for time=1 the result is q2. Otherwise interpolation + between q1 and q2. Result is normalized. + */ + quaternion& lerpN(quaternion q1, quaternion q2, f32 time); + //! Set this quaternion to the result of the spherical interpolation between two quaternions /** \param q1 First quaternion to be interpolated. \param q2 Second quaternion to be interpolated. @@ -572,16 +585,22 @@ inline quaternion& quaternion::normalize() { // removed conditional branch since it may slow down and anyway the condition was // false even after normalization in some cases. - return (*this *= reciprocal_squareroot ( X*X + Y*Y + Z*Z + W*W )); + return (*this *= (f32)reciprocal_squareroot ( (f64)(X*X + Y*Y + Z*Z + W*W) )); } -// set this quaternion to the result of the linear interpolation between two quaternions +// Set this quaternion to the result of the linear interpolation between two quaternions inline quaternion& quaternion::lerp( quaternion q1, quaternion q2, f32 time) { const f32 scale = 1.0f - time; return (*this = (q1*scale) + (q2*time)); } +// Set this quaternion to the result of the linear interpolation between two quaternions and normalize the result +inline quaternion& quaternion::lerpN( quaternion q1, quaternion q2, f32 time) +{ + const f32 scale = 1.0f - time; + return (*this = ((q1*scale) + (q2*time)).normalize() ); +} // set this quaternion to the result of the interpolation between two quaternions inline quaternion& quaternion::slerp( quaternion q1, quaternion q2, f32 time, f32 threshold) @@ -604,7 +623,7 @@ inline quaternion& quaternion::slerp( quaternion q1, quaternion q2, f32 time, f3 return (*this = (q1*scale) + (q2*invscale)); } else // linear interpolation - return lerp(q1,q2,time); + return lerpN(q1,q2,time); } diff --git a/source/Irrlicht/CAnimatedMeshSceneNode.cpp b/source/Irrlicht/CAnimatedMeshSceneNode.cpp index d8c8491d..593496a4 100644 --- a/source/Irrlicht/CAnimatedMeshSceneNode.cpp +++ b/source/Irrlicht/CAnimatedMeshSceneNode.cpp @@ -149,7 +149,7 @@ void CAnimatedMeshSceneNode::buildFrameNr(u32 timeMs) void CAnimatedMeshSceneNode::OnRegisterSceneNode() { - if (IsVisible) + if (IsVisible && Mesh) { // because this node supports rendering of mixed mode meshes consisting of // transparent and solid material at the same time, we need to go through all @@ -163,12 +163,12 @@ void CAnimatedMeshSceneNode::OnRegisterSceneNode() int solidCount = 0; // count transparent and solid materials in this scene node - for (u32 i=0; igetMeshBufferCount() : Materials.size(); + for (u32 i=0; igetMaterialRenderer(Materials[i].MaterialType); + const video::SMaterial& material = ReadOnlyMaterials ? Mesh->getMeshBuffer(i)->getMaterial() : Materials[i]; - if ((rnd && rnd->isTransparent()) || Materials[i].isTransparent()) + if ( driver->needsTransparentRenderPass(material) ) ++transparentCount; else ++solidCount; @@ -274,7 +274,7 @@ void CAnimatedMeshSceneNode::render() return; - bool isTransparentPass = + const bool isTransparentPass = SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT; ++PassCount; @@ -329,8 +329,7 @@ void CAnimatedMeshSceneNode::render() { for (u32 i=0; igetMeshBufferCount(); ++i) { - video::IMaterialRenderer* rnd = driver->getMaterialRenderer(Materials[i].MaterialType); - bool transparent = (rnd && rnd->isTransparent()); + const bool transparent = driver->needsTransparentRenderPass(Materials[i]); // only render transparent buffer if this is the transparent render pass // and solid only in solid pass @@ -533,7 +532,7 @@ const core::aabbox3d& CAnimatedMeshSceneNode::getBoundingBox() const } -//! returns the material based on the zero based index i. +//! returns the material based on the zero based index i. video::SMaterial& CAnimatedMeshSceneNode::getMaterial(u32 i) { if (i >= Materials.size()) diff --git a/source/Irrlicht/CB3DMeshFileLoader.cpp b/source/Irrlicht/CB3DMeshFileLoader.cpp index 6c68aefb..c473d529 100644 --- a/source/Irrlicht/CB3DMeshFileLoader.cpp +++ b/source/Irrlicht/CB3DMeshFileLoader.cpp @@ -962,7 +962,7 @@ bool CB3DMeshFileLoader::readChunkBRUS() else { B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; - B3dMaterial.Material.ZWriteEnable = false; + B3dMaterial.Material.ZWriteEnable = video::EZW_OFF; } } else if (B3dMaterial.Textures[0]) //One texture: @@ -971,7 +971,7 @@ bool CB3DMeshFileLoader::readChunkBRUS() if (B3dMaterial.Textures[0]->Flags & 0x2) //(Alpha mapped) { B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; - B3dMaterial.Material.ZWriteEnable = false; + B3dMaterial.Material.ZWriteEnable = video::EZW_OFF; } else if (B3dMaterial.Textures[0]->Flags & 0x4) //(Masked) B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; // TODO: create color key texture @@ -984,7 +984,7 @@ bool CB3DMeshFileLoader::readChunkBRUS() else { B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; - B3dMaterial.Material.ZWriteEnable = false; + B3dMaterial.Material.ZWriteEnable = video::EZW_OFF; } } else //No texture: @@ -994,7 +994,7 @@ bool CB3DMeshFileLoader::readChunkBRUS() else { B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; - B3dMaterial.Material.ZWriteEnable = false; + B3dMaterial.Material.ZWriteEnable = video::EZW_OFF; } } @@ -1023,7 +1023,7 @@ bool CB3DMeshFileLoader::readChunkBRUS() if (B3dMaterial.fx & 32) //force vertex alpha-blending { B3dMaterial.Material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; - B3dMaterial.Material.ZWriteEnable = false; + B3dMaterial.Material.ZWriteEnable = video::EZW_OFF; } B3dMaterial.Material.Shininess = B3dMaterial.shininess; diff --git a/source/Irrlicht/CBlit.h b/source/Irrlicht/CBlit.h index 677151a8..d67a76b0 100644 --- a/source/Irrlicht/CBlit.h +++ b/source/Irrlicht/CBlit.h @@ -988,24 +988,24 @@ static void executeBlit_TextureCombineColor_16_to_16( const SBlitJob * job ) { const u32 w = job->width * 2; const u32 h = job->height * 2; - u8* src = (u8*) job->src; - u8* dst = (u8*) job->dst; + u16* src = (u16*) job->src; + u16* dst = (u16*) job->dst; const u16 jobColor = video::A8R8G8B8toA1R5G5B5( job->argb ); /* Stretch not supported. */ - for ( u32 dy = 0; dy != h; dy+=2 ) + for ( u32 dy = 0; dy != h; dy++ ) { - for ( u32 dx = 0; dx != w; dx+=2 ) + for ( u32 dx = 0; dx != w; dx++ ) { - const u16 src_x = src[dx] << 8 | src[dx+1]; - const u16 dst_x = dst[dx] << 8 | dst[dx+1]; + const u16 src_x = src[dx]; + const u16 dst_x = dst[dx]; dst[dx] = PixelCombine16( dst_x, PixelMul16_2( src_x, jobColor ) ); } - src = (src) + job->srcPitch; - dst = (dst) + job->dstPitch; + src = (u16*) ( (u8*) (src) + job->srcPitch ); + dst = (u16*) ( (u8*) (dst) + job->dstPitch ); } } diff --git a/source/Irrlicht/CBurningShader_Raster_Reference.cpp b/source/Irrlicht/CBurningShader_Raster_Reference.cpp index 4f1a4474..c04db94b 100644 --- a/source/Irrlicht/CBurningShader_Raster_Reference.cpp +++ b/source/Irrlicht/CBurningShader_Raster_Reference.cpp @@ -655,7 +655,7 @@ void CBurningShader_Raster_Reference::setMaterial ( const SBurningShaderMaterial } // depth buffer write - ShaderParam.SetRenderState( BD3DRS_ZWRITEENABLE, m.ZWriteEnable ); + ShaderParam.SetRenderState( BD3DRS_ZWRITEENABLE, m.ZWriteEnable != video::EZW_OFF ); } /*! @@ -690,8 +690,8 @@ REALINLINE void CBurningShader_Raster_Reference::depthWrite () REALINLINE void CBurningShader_Raster_Reference::scanline2() { // apply top-left fill-convention, left - pShader.xStart = core::ceil32( line.x[0] ); - pShader.xEnd = core::ceil32( line.x[1] ) - 1; + pShader.xStart = core::ceil32_fast( line.x[0] ); + pShader.xEnd = core::ceil32_fast( line.x[1] ) - 1; pShader.dx = pShader.xEnd - pShader.xStart; if ( pShader.dx < 0 ) @@ -755,8 +755,8 @@ REALINLINE void CBurningShader_Raster_Reference::scanline () u32 i; // apply top-left fill-convention, left - pShader.xStart = core::ceil32( line.x[0] ); - pShader.xEnd = core::ceil32( line.x[1] ) - 1; + pShader.xStart = core::ceil32_fast( line.x[0] ); + pShader.xEnd = core::ceil32_fast( line.x[1] ) - 1; pShader.dx = pShader.xEnd - pShader.xStart; if ( pShader.dx < 0 ) @@ -929,8 +929,8 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4 } // apply top-left fill convention, top part - yStart = core::ceil32( a->Pos.y ); - yEnd = core::ceil32( b->Pos.y ) - 1; + yStart = core::ceil32_fast( a->Pos.y ); + yEnd = core::ceil32_fast( b->Pos.y ) - 1; subPixel = ( (f32) yStart ) - a->Pos.y; @@ -1043,8 +1043,8 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4 } // apply top-left fill convention, top part - yStart = core::ceil32( b->Pos.y ); - yEnd = core::ceil32( c->Pos.y ) - 1; + yStart = core::ceil32_fast( b->Pos.y ); + yEnd = core::ceil32_fast( c->Pos.y ) - 1; subPixel = ( (f32) yStart ) - b->Pos.y; diff --git a/source/Irrlicht/CColladaFileLoader.cpp b/source/Irrlicht/CColladaFileLoader.cpp index ab4d7fe0..7645254d 100644 --- a/source/Irrlicht/CColladaFileLoader.cpp +++ b/source/Irrlicht/CColladaFileLoader.cpp @@ -1541,7 +1541,7 @@ void CColladaFileLoader::readEffect(io::IXMLReaderUTF8* reader, SColladaEffect * if ((effect->Transparency != 0.0f) && (effect->Transparency != 1.0f)) { effect->Mat.MaterialType = irr::video::EMT_TRANSPARENT_VERTEX_ALPHA; - effect->Mat.ZWriteEnable = false; + effect->Mat.ZWriteEnable = video::EZW_OFF; } video::E_TEXTURE_CLAMP twu = video::ETC_REPEAT; @@ -1658,7 +1658,7 @@ void CColladaFileLoader::readBindMaterialSection(io::IXMLReaderUTF8* reader, con if ((material->Transparency!=0.0f) && (material->Transparency!=1.0f)) { toBind[i]->getMaterial().MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; - toBind[i]->getMaterial().ZWriteEnable = false; + toBind[i]->getMaterial().ZWriteEnable = video::EZW_OFF; } } SceneManager->getMeshManipulator()->setVertexColors(&tmpmesh,material->Mat.DiffuseColor); diff --git a/source/Irrlicht/CColorConverter.cpp b/source/Irrlicht/CColorConverter.cpp index bafa92d7..76e606fb 100644 --- a/source/Irrlicht/CColorConverter.cpp +++ b/source/Irrlicht/CColorConverter.cpp @@ -818,8 +818,10 @@ void CColorConverter::convert_viaFormat(const void* sP, ECOLOR_FORMAT sF, s32 sN break; } break; +#ifndef _DEBUG default: - break; + break; +#endif } } diff --git a/source/Irrlicht/CD3D9Driver.cpp b/source/Irrlicht/CD3D9Driver.cpp index 98501b39..7073b26d 100644 --- a/source/Irrlicht/CD3D9Driver.cpp +++ b/source/Irrlicht/CD3D9Driver.cpp @@ -2219,7 +2219,9 @@ void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMateria } // Blend Factor - if (IR(material.BlendFactor) & 0xFFFFFFFF) + if (IR(material.BlendFactor) & 0xFFFFFFFF // TODO: why the & 0xFFFFFFFF? + && material.MaterialType != EMT_ONETEXTURE_BLEND + ) { E_BLEND_FACTOR srcRGBFact = EBF_ZERO; E_BLEND_FACTOR dstRGBFact = EBF_ZERO; @@ -3581,6 +3583,11 @@ bool CD3D9Driver::queryTextureFormat(ECOLOR_FORMAT format) const return getD3DFormatFromColorFormat(format) != D3DFMT_UNKNOWN; } +bool CD3D9Driver::needsTransparentRenderPass(const irr::video::SMaterial& material) const +{ + return CNullDriver::needsTransparentRenderPass(material) || material.isAlphaBlendOperation(); +} + u32 CD3D9Driver::getD3DBlend(E_BLEND_FACTOR factor) const { u32 r = 0; diff --git a/source/Irrlicht/CD3D9Driver.h b/source/Irrlicht/CD3D9Driver.h index d066f8e5..e4d7925d 100644 --- a/source/Irrlicht/CD3D9Driver.h +++ b/source/Irrlicht/CD3D9Driver.h @@ -300,6 +300,9 @@ namespace video //! Check if the driver supports creating textures with the given color format virtual bool queryTextureFormat(ECOLOR_FORMAT format) const _IRR_OVERRIDE_; + //! Used by some SceneNodes to check if a material should be rendered in the transparent render pass + virtual bool needsTransparentRenderPass(const irr::video::SMaterial& material) const _IRR_OVERRIDE_; + //! Get the current color format of the color buffer /** \return Color format of the color buffer as D3D color value. */ D3DFORMAT getD3DColorFormat() const; diff --git a/source/Irrlicht/CD3D9HLSLMaterialRenderer.cpp b/source/Irrlicht/CD3D9HLSLMaterialRenderer.cpp index 1ca26765..3600333a 100644 --- a/source/Irrlicht/CD3D9HLSLMaterialRenderer.cpp +++ b/source/Irrlicht/CD3D9HLSLMaterialRenderer.cpp @@ -88,10 +88,15 @@ bool CD3D9HLSLMaterialRenderer::createHLSLVertexShader(const char* vertexShaderP #ifdef _IRR_D3D_NO_SHADER_DEBUGGING + size_t dataLen_t = strlen(vertexShaderProgram); + UINT dataLen = (UINT)dataLen_t; + if ( dataLen != dataLen_t ) + return false; + // compile without debug info HRESULT h = stubD3DXCompileShader( vertexShaderProgram, - strlen(vertexShaderProgram), + dataLen, 0, // macros 0, // no includes shaderEntryPointName, @@ -190,10 +195,15 @@ bool CD3D9HLSLMaterialRenderer::createHLSLPixelShader(const char* pixelShaderPro #ifdef _IRR_D3D_NO_SHADER_DEBUGGING + size_t dataLen_t = strlen(pixelShaderProgram); + UINT dataLen = (UINT)dataLen_t; + if ( dataLen != dataLen_t ) + return false; + // compile without debug info HRESULT h = stubD3DXCompileShader( pixelShaderProgram, - strlen(pixelShaderProgram), + dataLen, 0, // macros 0, // no includes shaderEntryPointName, diff --git a/source/Irrlicht/CGUIEnvironment.cpp b/source/Irrlicht/CGUIEnvironment.cpp index 934e5b8a..e29195b2 100644 --- a/source/Irrlicht/CGUIEnvironment.cpp +++ b/source/Irrlicht/CGUIEnvironment.cpp @@ -1331,7 +1331,7 @@ IGUITabControl* CGUIEnvironment::addTabControl(const core::rect& rectangle, IGUITab* CGUIEnvironment::addTab(const core::rect& rectangle, IGUIElement* parent, s32 id) { - IGUITab* t = new CGUITab(-1, this, parent ? parent : this, + IGUITab* t = new CGUITab(this, parent ? parent : this, rectangle, id); t->drop(); return t; diff --git a/source/Irrlicht/CGUIImage.cpp b/source/Irrlicht/CGUIImage.cpp index b1c25d26..87e5818d 100644 --- a/source/Irrlicht/CGUIImage.cpp +++ b/source/Irrlicht/CGUIImage.cpp @@ -81,7 +81,7 @@ void CGUIImage::draw() core::rect sourceRect(SourceRect); if (sourceRect.getWidth() == 0 || sourceRect.getHeight() == 0) { - sourceRect = core::rect(core::dimension2di(Texture->getSize())); + sourceRect = core::rect(core::dimension2di(Texture->getOriginalSize())); } if (ScaleImage) diff --git a/source/Irrlicht/CGUITabControl.cpp b/source/Irrlicht/CGUITabControl.cpp index 57b9a72a..998856b1 100644 --- a/source/Irrlicht/CGUITabControl.cpp +++ b/source/Irrlicht/CGUITabControl.cpp @@ -23,10 +23,10 @@ namespace gui // ------------------------------------------------------------------ //! constructor -CGUITab::CGUITab(s32 number, IGUIEnvironment* environment, +CGUITab::CGUITab(IGUIEnvironment* environment, IGUIElement* parent, const core::rect& rectangle, s32 id) - : IGUITab(environment, parent, id, rectangle), Number(number), + : IGUITab(environment, parent, id, rectangle), BackColor(0,0,0,0), OverrideTextColorEnabled(false), TextColor(255,0,0,0), DrawBackground(false) { @@ -39,21 +39,6 @@ CGUITab::CGUITab(s32 number, IGUIEnvironment* environment, TextColor = skin->getColor(EGDC_BUTTON_TEXT); } - -//! Returns number of tab in tabcontrol. Can be accessed -//! later IGUITabControl::getTab() by this number. -s32 CGUITab::getNumber() const -{ - return Number; -} - - -//! Sets the number -void CGUITab::setNumber(s32 n) -{ - Number = n; -} - //! draws the element and its children void CGUITab::draw() { @@ -118,7 +103,9 @@ void CGUITab::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteO { IGUITab::serializeAttributes(out,options); - out->addInt ("TabNumber", Number); + IGUITabControl* parentTabControl = Parent && Parent->getType() == EGUIET_TAB_CONTROL ? static_cast(Parent) : 0; + if ( parentTabControl ) + out->addInt ("TabNumber", parentTabControl->getTabIndex(this)); // order of children and tabs can be different, so we save tab-number out->addBool ("DrawBackground", DrawBackground); out->addColor ("BackColor", BackColor); out->addBool ("OverrideTextColorEnabled", OverrideTextColorEnabled); @@ -132,18 +119,20 @@ void CGUITab::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWrite { IGUITab::deserializeAttributes(in,options); - setNumber(in->getAttributeAsInt("TabNumber", Number)); setDrawBackground(in->getAttributeAsBool("DrawBackground", DrawBackground)); setBackgroundColor(in->getAttributeAsColor("BackColor", BackColor)); bool overrideColor = in->getAttributeAsBool("OverrideTextColorEnabled", OverrideTextColorEnabled); setTextColor(in->getAttributeAsColor("TextColor", TextColor)); OverrideTextColorEnabled = overrideColor; // because setTextColor does set OverrideTextColorEnabled always to true - if (Parent && Parent->getType() == EGUIET_TAB_CONTROL) + IGUITabControl* parentTabControl = Parent && Parent->getType() == EGUIET_TAB_CONTROL ? static_cast(Parent) : 0; + if (parentTabControl) { - ((CGUITabControl*)Parent)->addTab(this); - if (isVisible()) - ((CGUITabControl*)Parent)->setActiveTab(this); + s32 idx = in->getAttributeAsInt("TabNumber", -1); + if ( idx >= 0 ) + parentTabControl->insertTab(idx, this, true); + else + parentTabControl->addTab(this); } } @@ -156,7 +145,7 @@ void CGUITab::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWrite CGUITabControl::CGUITabControl(IGUIEnvironment* environment, IGUIElement* parent, const core::rect& rectangle, bool fillbackground, bool border, s32 id) - : IGUITabControl(environment, parent, id, rectangle), ActiveTab(-1), + : IGUITabControl(environment, parent, id, rectangle), ActiveTabIndex(-1), Border(border), FillBackground(fillbackground), ScrollControl(false), TabHeight(0), VerticalAlignment(EGUIA_UPPERLEFT), UpButton(0), DownButton(0), TabMaxWidth(0), CurrentScrollTabIndex(0), TabExtraWidth(20) { @@ -244,16 +233,16 @@ void CGUITabControl::refreshSprites() //! Adds a tab IGUITab* CGUITabControl::addTab(const wchar_t* caption, s32 id) { - CGUITab* tab = new CGUITab(Tabs.size(), Environment, this, calcTabPos(), id); + CGUITab* tab = new CGUITab(Environment, this, calcTabPos(), id); tab->setText(caption); tab->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); tab->setVisible(false); - Tabs.push_back(tab); + Tabs.push_back(tab); // no grab as new already creates a reference - if (ActiveTab == -1) + if (ActiveTabIndex == -1) { - ActiveTab = 0; + ActiveTabIndex = Tabs.size()-1; tab->setVisible(true); } @@ -264,65 +253,33 @@ IGUITab* CGUITabControl::addTab(const wchar_t* caption, s32 id) //! adds a tab which has been created elsewhere -void CGUITabControl::addTab(CGUITab* tab) +s32 CGUITabControl::addTab(IGUITab* tab) { - if (!tab) - return; - - // check if its already added - for (u32 i=0; i < Tabs.size(); ++i) - { - if (Tabs[i] == tab) - return; - } - - tab->grab(); - - if (tab->getNumber() == -1) - tab->setNumber((s32)Tabs.size()); - - while (tab->getNumber() >= (s32)Tabs.size()) - Tabs.push_back(0); - - if (Tabs[tab->getNumber()]) - { - Tabs.push_back(Tabs[tab->getNumber()]); - Tabs[Tabs.size()-1]->setNumber(Tabs.size()); - } - Tabs[tab->getNumber()] = tab; - - if (ActiveTab == -1) - ActiveTab = tab->getNumber(); - - - if (tab->getNumber() == ActiveTab) - { - setActiveTab(ActiveTab); - } + return insertTab( Tabs.size(), tab, false); } //! Insert the tab at the given index IGUITab* CGUITabControl::insertTab(s32 idx, const wchar_t* caption, s32 id) { - if ( idx < 0 || idx > (s32)Tabs.size() ) // idx == Tabs.size() is indeed ok here as core::array can handle that + if ( idx < 0 || idx > (s32)Tabs.size() ) // idx == Tabs.size() is indeed OK here as core::array can handle that return NULL; - CGUITab* tab = new CGUITab(idx, Environment, this, calcTabPos(), id); + CGUITab* tab = new CGUITab(Environment, this, calcTabPos(), id); tab->setText(caption); tab->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); tab->setVisible(false); Tabs.insert(tab, (u32)idx); - if (ActiveTab == -1) + if (ActiveTabIndex == -1) { - ActiveTab = 0; + ActiveTabIndex = (u32)idx; tab->setVisible(true); } - - for ( u32 i=(u32)idx+1; i < Tabs.size(); ++i ) + else if ( idx <= ActiveTabIndex ) { - Tabs[i]->setNumber(i); + ++ActiveTabIndex; + setVisibleTab(ActiveTabIndex); } recalculateScrollBar(); @@ -330,17 +287,102 @@ IGUITab* CGUITabControl::insertTab(s32 idx, const wchar_t* caption, s32 id) return tab; } +s32 CGUITabControl::insertTab(s32 idx, IGUITab* tab, bool serializationMode) +{ + if (!tab) + return -1; + if ( idx > (s32)Tabs.size() && !serializationMode ) // idx == Tabs.size() is indeed OK here as core::array can handle that + return -1; + // Not allowing to add same tab twice as it would make things complicated (serialization or setting active visible) + if ( getTabIndex(tab) >= 0 ) + return -1; + + if ( idx < 0 ) + idx = (s32)Tabs.size(); + + if ( tab->getParent() != this ) + this->addChildToEnd(tab); + + tab->setVisible(false); + + tab->grab(); + + if ( serializationMode) + { + while ( idx >= (s32)Tabs.size() ) + { + Tabs.push_back(0); + } + Tabs[idx] = tab; + + if ( idx == ActiveTabIndex) // in serialization that can happen for any index + { + setVisibleTab(ActiveTabIndex); + tab->setVisible(true); + } + } + else + { + Tabs.insert(tab, (u32)idx); + + if (ActiveTabIndex == -1) + { + ActiveTabIndex = idx; + setVisibleTab(ActiveTabIndex); + } + else if ( idx <= ActiveTabIndex) + { + ++ActiveTabIndex; + setVisibleTab(ActiveTabIndex); + } + } + + recalculateScrollBar(); + + return idx; +} + +//! Removes a child. +void CGUITabControl::removeChild(IGUIElement* child) +{ + s32 idx = getTabIndex(child); + if ( idx >= 0 ) + removeTabButNotChild(idx); + + // remove real element + IGUIElement::removeChild(child); + + recalculateScrollBar(); +} + + //! Removes a tab from the tabcontrol void CGUITabControl::removeTab(s32 idx) +{ + if ( idx < 0 || idx >= (s32)Tabs.size() ) + return; + + removeChild(Tabs[(u32)idx]); +} + +void CGUITabControl::removeTabButNotChild(s32 idx) { if ( idx < 0 || idx >= (s32)Tabs.size() ) return; Tabs[(u32)idx]->drop(); Tabs.erase((u32)idx); - for ( u32 i=(u32)idx; i < Tabs.size(); ++i ) + + if ( idx < ActiveTabIndex ) { - Tabs[i]->setNumber(i); + --ActiveTabIndex; + setVisibleTab(ActiveTabIndex); + } + else if ( idx == ActiveTabIndex ) + { + if ( (u32)idx == Tabs.size() ) + --ActiveTabIndex; + setVisibleTab(ActiveTabIndex); } } @@ -350,9 +392,14 @@ void CGUITabControl::clear() for (u32 i=0; idrop(); + } } Tabs.clear(); + + recalculateScrollBar(); } //! Returns amount of tabs in the tabcontrol @@ -365,7 +412,7 @@ s32 CGUITabControl::getTabCount() const //! Returns a tab based on zero based index IGUITab* CGUITabControl::getTab(s32 idx) const { - if ((u32)idx >= Tabs.size()) + if (idx < 0 || (u32)idx >= Tabs.size()) return 0; return Tabs[idx]; @@ -377,7 +424,6 @@ bool CGUITabControl::OnEvent(const SEvent& event) { if (isEnabled()) { - switch(event.EventType) { case EET_GUI_EVENT: @@ -403,9 +449,9 @@ bool CGUITabControl::OnEvent(const SEvent& event) case EET_MOUSE_INPUT_EVENT: switch(event.MouseInput.Event) { - case EMIE_LMOUSE_PRESSED_DOWN: - // todo: dragging tabs around - return true; + //case EMIE_LMOUSE_PRESSED_DOWN: + // // todo: dragging tabs around + // return true; case EMIE_LMOUSE_LEFT_UP: { s32 idx = getTabAt(event.MouseInput.X, event.MouseInput.Y); @@ -500,16 +546,18 @@ bool CGUITabControl::needScrollControl(s32 startIndex, bool withScrollControl) // get Text const wchar_t* text = 0; if (Tabs[i]) + { text = Tabs[i]->getText(); - // get text length - s32 len = calcTabWidth(pos, font, text, false); // always without withScrollControl here or len would be shortened + // get text length + s32 len = calcTabWidth(pos, font, text, false); // always without withScrollControl here or len would be shortened - frameRect.LowerRightCorner.X += len; + frameRect.LowerRightCorner.X += len; - frameRect.UpperLeftCorner.X = pos; - frameRect.LowerRightCorner.X = frameRect.UpperLeftCorner.X + len; - pos += len; + frameRect.UpperLeftCorner.X = pos; + frameRect.LowerRightCorner.X = frameRect.UpperLeftCorner.X + len; + pos += len; + } if ( withScrollControl && pos > UpButton->getAbsolutePosition().UpperLeftCorner.X - 2) return true; @@ -601,7 +649,7 @@ void CGUITabControl::draw() s32 right = 0; //const wchar_t* activetext = 0; - CGUITab *activeTab = 0; + IGUITab *activeTab = 0; // Draw all tab-buttons except the active one for (u32 i=CurrentScrollTabIndex; i= Tabs.size()) return false; - bool changed = (ActiveTab != idx); + bool changed = (ActiveTabIndex != idx); - ActiveTab = idx; + ActiveTabIndex = idx; - for (s32 i=0; i<(s32)Tabs.size(); ++i) - if (Tabs[i]) - Tabs[i]->setVisible( i == ActiveTab ); + setVisibleTab(ActiveTabIndex); - if (changed) + if (changed && Parent) { SEvent event; event.EventType = EET_GUI_EVENT; @@ -944,50 +990,28 @@ bool CGUITabControl::setActiveTab(s32 idx) return true; } +void CGUITabControl::setVisibleTab(s32 idx) +{ + for (u32 i=0; isetVisible( (s32)i == idx ); +} + bool CGUITabControl::setActiveTab(IGUITab *tab) { - for (s32 i=0; i<(s32)Tabs.size(); ++i) - if (Tabs[i] == tab) - return setActiveTab(i); - return false; + return setActiveTab(getTabIndex(tab)); } - -//! Removes a child. -void CGUITabControl::removeChild(IGUIElement* child) +s32 CGUITabControl::getTabIndex(const IGUIElement *tab) const { - bool isTab = false; + for (u32 i=0; idrop(); - Tabs.erase(i); - isTab = true; - } - else - ++i; - } - - // reassign numbers - if (isTab) - { - for (i=0; isetNumber(i); - } - - // remove real element - IGUIElement::removeChild(child); - - recalculateScrollBar(); + return -1; } - //! Update the position of the element, decides scroll button status void CGUITabControl::updateAbsolutePosition() { @@ -1001,7 +1025,7 @@ void CGUITabControl::serializeAttributes(io::IAttributes* out, io::SAttributeRea { IGUITabControl::serializeAttributes(out,options); - out->addInt ("ActiveTab", ActiveTab); + out->addInt ("ActiveTab", ActiveTabIndex); out->addBool("Border", Border); out->addBool("FillBackground", FillBackground); out->addInt ("TabHeight", TabHeight); @@ -1016,14 +1040,14 @@ void CGUITabControl::deserializeAttributes(io::IAttributes* in, io::SAttributeRe Border = in->getAttributeAsBool("Border"); FillBackground = in->getAttributeAsBool("FillBackground"); - ActiveTab = -1; + ActiveTabIndex = -1; setTabHeight(in->getAttributeAsInt("TabHeight")); TabMaxWidth = in->getAttributeAsInt("TabMaxWidth"); IGUITabControl::deserializeAttributes(in,options); - setActiveTab(in->getAttributeAsInt("ActiveTab")); + ActiveTabIndex = in->getAttributeAsInt("ActiveTab", -1); // not setActiveTab as tabs are loaded later setTabVerticalAlignment( static_cast(in->getAttributeAsEnumeration("TabVerticalAlignment" , GUIAlignmentNames)) ); } diff --git a/source/Irrlicht/CGUITabControl.h b/source/Irrlicht/CGUITabControl.h index 1e329586..3752a10f 100644 --- a/source/Irrlicht/CGUITabControl.h +++ b/source/Irrlicht/CGUITabControl.h @@ -25,20 +25,10 @@ namespace gui public: //! constructor - CGUITab(s32 number, IGUIEnvironment* environment, + CGUITab(IGUIEnvironment* environment, IGUIElement* parent, const core::rect& rectangle, s32 id); - //! destructor - //virtual ~CGUITab(); - - //! Returns number of this tab in tabcontrol. Can be accessed - //! later IGUITabControl::getTab() by this number. - virtual s32 getNumber() const _IRR_OVERRIDE_; - - //! Sets the number - virtual void setNumber(s32 n); - //! draws the element and its children virtual void draw() _IRR_OVERRIDE_; @@ -67,7 +57,6 @@ namespace gui private: - s32 Number; video::SColor BackColor; bool OverrideTextColorEnabled; video::SColor TextColor; @@ -91,12 +80,17 @@ namespace gui //! Adds a tab virtual IGUITab* addTab(const wchar_t* caption, s32 id=-1) _IRR_OVERRIDE_; - //! Adds a tab that has already been created - virtual void addTab(CGUITab* tab); + //! Adds an existing tab + virtual s32 addTab(IGUITab* tab) _IRR_OVERRIDE_; //! Insert the tab at the given index virtual IGUITab* insertTab(s32 idx, const wchar_t* caption, s32 id=-1) _IRR_OVERRIDE_; + //! Insert an existing tab + /** Note that it will also add the tab as a child of this TabControl. + \return Index of added tab (should be same as the one passed) or -1 for failure*/ + virtual s32 insertTab(s32 idx, IGUITab* tab, bool serializationMode) _IRR_OVERRIDE_; + //! Removes a tab from the tabcontrol virtual void removeTab(s32 idx) _IRR_OVERRIDE_; @@ -115,6 +109,9 @@ namespace gui //! Brings a tab to front. virtual bool setActiveTab(IGUITab *tab) _IRR_OVERRIDE_; + //! For given given tab find it's zero-based index (or -1 for not found) + virtual s32 getTabIndex(const IGUIElement *tab) const _IRR_OVERRIDE_; + //! Returns which tab is currently active virtual s32 getActiveTab() const _IRR_OVERRIDE_; @@ -170,13 +167,15 @@ namespace gui bool needScrollControl( s32 startIndex=0, bool withScrollControl=false ); s32 calcTabWidth(s32 pos, IGUIFont* font, const wchar_t* text, bool withScrollControl ) const; core::rect calcTabPos(); + void setVisibleTab(s32 idx); + void removeTabButNotChild(s32 idx); void recalculateScrollButtonPlacement(); void recalculateScrollBar(); void refreshSprites(); - core::array Tabs; // CGUITab* because we need setNumber (which is certainly not nice) - s32 ActiveTab; + core::array Tabs; + s32 ActiveTabIndex; bool Border; bool FillBackground; bool ScrollControl; diff --git a/source/Irrlicht/CGUIToolBar.cpp b/source/Irrlicht/CGUIToolBar.cpp index 9671c045..2f4bf4ec 100644 --- a/source/Irrlicht/CGUIToolBar.cpp +++ b/source/Irrlicht/CGUIToolBar.cpp @@ -32,15 +32,27 @@ CGUIToolBar::CGUIToolBar(IGUIEnvironment* environment, IGUIElement* parent, s32 if (parent) { parentwidth = Parent->getAbsolutePosition().getWidth(); + s32 parentheight = Parent->getAbsolutePosition().getHeight(); const core::list& children = parent->getChildren(); core::list::ConstIterator it = children.begin(); for (; it != children.end(); ++it) { - core::rect r = (*it)->getAbsolutePosition(); - if (r.UpperLeftCorner.X == 0 && r.UpperLeftCorner.Y <= y && - r.LowerRightCorner.X == parentwidth) - y = r.LowerRightCorner.Y; + const IGUIElement* e = *it; + if ( e->hasType(EGUIET_CONTEXT_MENU) + || e->hasType(EGUIET_MENU) + || e->hasType(EGUIET_TOOL_BAR) ) + { + core::rect r = e->getAbsolutePosition(); + if (r.UpperLeftCorner.X == 0 && r.UpperLeftCorner.Y <= y && + r.LowerRightCorner.X == parentwidth + && parentheight > r.LowerRightCorner.Y ) + y = r.LowerRightCorner.Y; + } + else + { + e->getType(); + } } } diff --git a/source/Irrlicht/CGeometryCreator.cpp b/source/Irrlicht/CGeometryCreator.cpp index 5c926ee7..22ce7170 100644 --- a/source/Irrlicht/CGeometryCreator.cpp +++ b/source/Irrlicht/CGeometryCreator.cpp @@ -683,7 +683,7 @@ IMesh* CGeometryCreator::createSphereMesh(f32 radius, u32 polyCountX, u32 polyCo /* A cylinder with proper normals and texture coords */ IMesh* CGeometryCreator::createCylinderMesh(f32 radius, f32 length, u32 tesselation, const video::SColor& color, - bool closeTop, f32 oblique) const + bool closeTop, f32 oblique, u32 normalType) const { SMeshBuffer* buffer = new SMeshBuffer(); @@ -704,7 +704,11 @@ IMesh* CGeometryCreator::createCylinderMesh(f32 radius, f32 length, v.Pos.X = radius * cosf(angle); v.Pos.Y = 0.f; v.Pos.Z = radius * sinf(angle); - v.Normal = v.Pos; + switch (normalType) + { + case 0: v.Normal = v.Pos; break; + case 1: v.Normal = v.Pos; break; + } v.Normal.normalize(); v.TCoords.X=tcx; v.TCoords.Y=0.f; @@ -712,7 +716,11 @@ IMesh* CGeometryCreator::createCylinderMesh(f32 radius, f32 length, v.Pos.X += oblique; v.Pos.Y = length; - v.Normal = v.Pos; + switch (normalType) + { + case 0: v.Normal = v.Pos; break; + case 1: v.Normal = core::vector3df(v.Pos.X-oblique, 0, v.Pos.Z); break; + } v.Normal.normalize(); v.TCoords.Y=1.f; buffer->Vertices.push_back(v); @@ -720,7 +728,11 @@ IMesh* CGeometryCreator::createCylinderMesh(f32 radius, f32 length, v.Pos.X = radius * cosf(angle + angleStepHalf); v.Pos.Y = 0.f; v.Pos.Z = radius * sinf(angle + angleStepHalf); - v.Normal = v.Pos; + switch (normalType) + { + case 0: v.Normal = v.Pos; break; + case 1: v.Normal = v.Pos; break; + } v.Normal.normalize(); v.TCoords.X=tcx+recTesselationHalf; v.TCoords.Y=0.f; @@ -728,7 +740,11 @@ IMesh* CGeometryCreator::createCylinderMesh(f32 radius, f32 length, v.Pos.X += oblique; v.Pos.Y = length; - v.Normal = v.Pos; + switch (normalType) + { + case 0: v.Normal = v.Pos; break; + case 1: v.Normal = core::vector3df(v.Pos.X-oblique, 0, v.Pos.Z); break; + } v.Normal.normalize(); v.TCoords.Y=1.f; buffer->Vertices.push_back(v); @@ -1049,7 +1065,7 @@ IMesh* CGeometryCreator::createVolumeLightMesh( Buffer->Material.MaterialTypeParam = pack_textureBlendFunc( video::EBF_SRC_COLOR, video::EBF_SRC_ALPHA, video::EMFN_MODULATE_1X ); Buffer->Material.Lighting = false; - Buffer->Material.ZWriteEnable = false; + Buffer->Material.ZWriteEnable = video::EZW_OFF; Buffer->setDirty(EBT_VERTEX_AND_INDEX); diff --git a/source/Irrlicht/CGeometryCreator.h b/source/Irrlicht/CGeometryCreator.h index ad2c6c7e..4c918bdc 100644 --- a/source/Irrlicht/CGeometryCreator.h +++ b/source/Irrlicht/CGeometryCreator.h @@ -44,7 +44,7 @@ public: virtual IMesh* createCylinderMesh(f32 radius, f32 length, u32 tesselation, const video::SColor& color=0xffffffff, - bool closeTop=true, f32 oblique=0.f) const _IRR_OVERRIDE_; + bool closeTop=true, f32 oblique=0.f, u32 normalType=0) const _IRR_OVERRIDE_; virtual IMesh* createConeMesh(f32 radius, f32 length, u32 tesselation, const video::SColor& colorTop=0xffffffff, diff --git a/source/Irrlicht/CImage.cpp b/source/Irrlicht/CImage.cpp index 95e704eb..f21b76f3 100644 --- a/source/Irrlicht/CImage.cpp +++ b/source/Irrlicht/CImage.cpp @@ -219,17 +219,17 @@ void CImage::copyToScaling(void* target, u32 width, u32 height, ECOLOR_FORMAT fo const f32 sourceXStep = (f32)Size.Width / (f32)width; const f32 sourceYStep = (f32)Size.Height / (f32)height; s32 yval=0, syval=0; - f32 sy = 0.0f; + f32 sy = 0.5f; // nearest pixel (used in float-int conversion below) for (u32 y=0; y(Width, Height)); else diff --git a/source/Irrlicht/CIrrDeviceConsole.cpp b/source/Irrlicht/CIrrDeviceConsole.cpp index d067fa01..8a2414a3 100644 --- a/source/Irrlicht/CIrrDeviceConsole.cpp +++ b/source/Irrlicht/CIrrDeviceConsole.cpp @@ -73,16 +73,16 @@ CIrrDeviceConsole::CIrrDeviceConsole(const SIrrlichtCreationParameters& params) WindowsSTDIn = GetStdHandle(STD_INPUT_HANDLE); WindowsSTDOut = GetStdHandle(STD_OUTPUT_HANDLE); - PCOORD Dimensions = 0; if (CreationParams.Fullscreen) { // Some mingw versions lack this define, so avoid it in case it does not exist #if (_WIN32_WINNT >= 0x0501) && defined(CONSOLE_FULLSCREEN_MODE) - if (SetConsoleDisplayMode(WindowsSTDOut, CONSOLE_FULLSCREEN_MODE, Dimensions)) + PCOORD dimensions = 0; + if (SetConsoleDisplayMode(WindowsSTDOut, CONSOLE_FULLSCREEN_MODE, dimensions)) { - CreationParams.WindowSize.Width = Dimensions->X; - CreationParams.WindowSize.Width = Dimensions->Y; + CreationParams.WindowSize.Width = dimensions->X; + CreationParams.WindowSize.Width = dimensions->Y; } #endif } diff --git a/source/Irrlicht/CIrrDeviceWin32.cpp b/source/Irrlicht/CIrrDeviceWin32.cpp index 5ebc5713..270be368 100644 --- a/source/Irrlicht/CIrrDeviceWin32.cpp +++ b/source/Irrlicht/CIrrDeviceWin32.cpp @@ -695,29 +695,22 @@ namespace HWND hWnd; irr::CIrrDeviceWin32* irrDev; }; - irr::core::list EnvMap; + // NOTE: This is global. We can have more than one Irrlicht Device at same time. + irr::core::array EnvMap; HKL KEYBOARD_INPUT_HKL=0; unsigned int KEYBOARD_INPUT_CODEPAGE = 1252; } -SEnvMapper* getEnvMapperFromHWnd(HWND hWnd) -{ - irr::core::list::Iterator it = EnvMap.begin(); - for (; it!= EnvMap.end(); ++it) - if ((*it).hWnd == hWnd) - return &(*it); - - return 0; -} - - irr::CIrrDeviceWin32* getDeviceFromHWnd(HWND hWnd) { - irr::core::list::Iterator it = EnvMap.begin(); - for (; it!= EnvMap.end(); ++it) - if ((*it).hWnd == hWnd) - return (*it).irrDev; + const irr::u32 end = EnvMap.size(); + for ( irr::u32 i=0; i < end; ++i ) + { + const SEnvMapper& env = EnvMap[i]; + if ( env.hWnd == hWnd ) + return env.irrDev; + } return 0; } @@ -1159,13 +1152,11 @@ CIrrDeviceWin32::~CIrrDeviceWin32() delete JoyControl; // unregister environment - - irr::core::list::Iterator it = EnvMap.begin(); - for (; it!= EnvMap.end(); ++it) + for (u32 i=0; i< EnvMap.size(); ++i) { - if ((*it).hWnd == HWnd) + if (EnvMap[i].hWnd == HWnd) { - EnvMap.erase(it); + EnvMap.erase(i); break; } } diff --git a/source/Irrlicht/CMS3DMeshFileLoader.cpp b/source/Irrlicht/CMS3DMeshFileLoader.cpp index 33c4957f..4ad18aa2 100644 --- a/source/Irrlicht/CMS3DMeshFileLoader.cpp +++ b/source/Irrlicht/CMS3DMeshFileLoader.cpp @@ -192,8 +192,8 @@ bool CMS3DMeshFileLoader::load(io::IReadFile* file) // read whole file u8* buffer = new u8[fileSize]; - s32 read = file->read(buffer, fileSize); - if (read != fileSize) + size_t read = file->read(buffer, fileSize); + if (read != (size_t)fileSize) { delete [] buffer; os::Printer::log("Could not read full file. Loading failed", file->getFileName(), ELL_ERROR); diff --git a/source/Irrlicht/CMY3DHelper.h b/source/Irrlicht/CMY3DHelper.h index 8f0906f0..c1566d11 100644 --- a/source/Irrlicht/CMY3DHelper.h +++ b/source/Irrlicht/CMY3DHelper.h @@ -188,7 +188,7 @@ int rle_encode ( { unsigned long ret_code; - unsigned char ch; + unsigned char ch=0; nCodedBytes=0; nReadedBytes=0; @@ -271,7 +271,7 @@ unsigned long process_comp( // we start out with 3 repeating bytes int len = 3; - unsigned char ch; + unsigned char ch = 0; // we're starting a repeating chunk - end the non-repeaters flush_outbuf(out_buf, out_buf_size); @@ -338,11 +338,12 @@ void flush_outbuf(unsigned char *out_buf, int out_buf_size) put_byte((unsigned char)outbuf[pos++], out_buf, out_buf_size); } //--------------------------------------------------- -void put_byte(unsigned char ch, unsigned char *out_buf, int out_buf_size) +void put_byte(unsigned char b, unsigned char *out_buf, int out_buf_size) { if (nCodedBytes<=(out_buf_size-1)) - { out_buf[nCodedBytes++]=ch; - out_buf[nCodedBytes]=0; + { + out_buf[nCodedBytes++] = b; + out_buf[nCodedBytes] = 0; } } //--------------------------------------------------- diff --git a/source/Irrlicht/CMeshSceneNode.cpp b/source/Irrlicht/CMeshSceneNode.cpp index def77d43..59d1c1cd 100644 --- a/source/Irrlicht/CMeshSceneNode.cpp +++ b/source/Irrlicht/CMeshSceneNode.cpp @@ -52,7 +52,7 @@ CMeshSceneNode::~CMeshSceneNode() //! frame void CMeshSceneNode::OnRegisterSceneNode() { - if (IsVisible) + if (IsVisible && Mesh) { // because this node supports rendering of mixed mode meshes consisting of // transparent and solid material at the same time, we need to go through all @@ -66,41 +66,18 @@ void CMeshSceneNode::OnRegisterSceneNode() int solidCount = 0; // count transparent and solid materials in this scene node - if (ReadOnlyMaterials && Mesh) + const u32 numMaterials = ReadOnlyMaterials ? Mesh->getMeshBufferCount() : Materials.size(); + for (u32 i=0; igetMeshBuffer(i)->getMaterial() : Materials[i]; - for (u32 i=0; igetMeshBufferCount(); ++i) - { - scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); - video::IMaterialRenderer* rnd = mb ? driver->getMaterialRenderer(mb->getMaterial().MaterialType) : 0; + if ( driver->needsTransparentRenderPass(material) ) + ++transparentCount; + else + ++solidCount; - if (rnd && rnd->isTransparent()) - ++transparentCount; - else - ++solidCount; - - if (solidCount && transparentCount) - break; - } - } - else - { - // count copied materials - - for (u32 i=0; igetMaterialRenderer(Materials[i].MaterialType); - - if ((rnd && rnd->isTransparent()) || Materials[i].isTransparent()) - ++transparentCount; - else - ++solidCount; - - if (solidCount && transparentCount) - break; - } + if (solidCount && transparentCount) + break; } // register according to material types counted @@ -124,7 +101,7 @@ void CMeshSceneNode::render() if (!Mesh || !driver) return; - bool isTransparentPass = + const bool isTransparentPass = SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT; ++PassCount; @@ -165,8 +142,7 @@ void CMeshSceneNode::render() { const video::SMaterial& material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i]; - video::IMaterialRenderer* rnd = driver->getMaterialRenderer(material.MaterialType); - bool transparent = (rnd && rnd->isTransparent()); + const bool transparent = driver->needsTransparentRenderPass(material); // only render transparent buffer if this is the transparent render pass // and solid only in solid pass diff --git a/source/Irrlicht/CNullDriver.cpp b/source/Irrlicht/CNullDriver.cpp index b74695f9..23110e33 100644 --- a/source/Irrlicht/CNullDriver.cpp +++ b/source/Irrlicht/CNullDriver.cpp @@ -196,7 +196,7 @@ CNullDriver::CNullDriver(io::IFileSystem* io, const core::dimension2d& scre InitMaterial2D.AntiAliasing=video::EAAM_OFF; InitMaterial2D.Lighting=false; - InitMaterial2D.ZWriteEnable=false; + InitMaterial2D.ZWriteEnable=video::EZW_OFF; InitMaterial2D.ZBuffer=video::ECFN_DISABLED; InitMaterial2D.UseMipMaps=false; for (u32 i=0; i* sourceRect) { - core::clearFPUException(); PrimitivesDrawn = 0; return true; } @@ -1949,7 +1948,7 @@ void CNullDriver::runOcclusionQuery(scene::ISceneNode* node, bool visible) mat.AntiAliasing=0; mat.ColorMask=ECP_NONE; mat.GouraudShading=false; - mat.ZWriteEnable=false; + mat.ZWriteEnable=EZW_OFF; setMaterial(mat); } setTransform(video::ETS_WORLD, node->getAbsoluteTransformation()); @@ -2154,7 +2153,7 @@ io::IAttributes* CNullDriver::createAttributesFromMaterial(const video::SMateria attr->addBool("PointCloud", material.PointCloud); attr->addBool("GouraudShading", material.GouraudShading); attr->addBool("Lighting", material.Lighting); - attr->addBool("ZWriteEnable", material.ZWriteEnable); + attr->addEnum("ZWriteEnable", (irr::s32)material.ZWriteEnable, video::ZWriteNames); attr->addInt("ZBuffer", material.ZBuffer); attr->addBool("BackfaceCulling", material.BackfaceCulling); attr->addBool("FrontfaceCulling", material.FrontfaceCulling); @@ -2170,7 +2169,6 @@ io::IAttributes* CNullDriver::createAttributesFromMaterial(const video::SMateria attr->addEnum("PolygonOffsetDirection", material.PolygonOffsetDirection, video::PolygonOffsetDirectionNames); attr->addFloat("PolygonOffsetDepthBias", material.PolygonOffsetDepthBias); attr->addFloat("PolygonOffsetSlopeScale", material.PolygonOffsetSlopeScale); - attr->addInt("ZWriteFineControl", material.ZWriteFineControl); // TODO: Would be nice to have a flag that only serializes rest of texture data when a texture pointer exists. prefix = "BilinearFilter"; @@ -2233,7 +2231,13 @@ void CNullDriver::fillMaterialStructureFromAttributes(video::SMaterial& outMater outMaterial.PointCloud = attr->getAttributeAsBool("PointCloud", outMaterial.PointCloud); outMaterial.GouraudShading = attr->getAttributeAsBool("GouraudShading", outMaterial.GouraudShading); outMaterial.Lighting = attr->getAttributeAsBool("Lighting", outMaterial.Lighting); - outMaterial.ZWriteEnable = attr->getAttributeAsBool("ZWriteEnable", outMaterial.ZWriteEnable); + + io::E_ATTRIBUTE_TYPE attType = attr->getAttributeType("ZWriteEnable"); + if (attType == io::EAT_BOOL ) // Before Irrlicht 1.9 + outMaterial.ZWriteEnable = attr->getAttributeAsBool("ZWriteEnable", outMaterial.ZWriteEnable != video::EZW_OFF ) ? video::EZW_AUTO : video::EZW_OFF; + else if (attType == io::EAT_ENUM ) + outMaterial.ZWriteEnable = (video::E_ZWRITE)attr->getAttributeAsEnumeration("ZWriteEnable", video::ZWriteNames, outMaterial.ZWriteEnable); + outMaterial.ZBuffer = (u8)attr->getAttributeAsInt("ZBuffer", outMaterial.ZBuffer); outMaterial.BackfaceCulling = attr->getAttributeAsBool("BackfaceCulling", outMaterial.BackfaceCulling); outMaterial.FrontfaceCulling = attr->getAttributeAsBool("FrontfaceCulling", outMaterial.FrontfaceCulling); @@ -2250,7 +2254,7 @@ void CNullDriver::fillMaterialStructureFromAttributes(video::SMaterial& outMater outMaterial.PolygonOffsetDirection = (video::E_POLYGON_OFFSET)attr->getAttributeAsEnumeration("PolygonOffsetDirection", video::PolygonOffsetDirectionNames, outMaterial.PolygonOffsetDirection); outMaterial.PolygonOffsetDepthBias = attr->getAttributeAsFloat("PolygonOffsetDepthBias", outMaterial.PolygonOffsetDepthBias); outMaterial.PolygonOffsetSlopeScale = attr->getAttributeAsFloat("PolygonOffsetSlopeScale", outMaterial.PolygonOffsetSlopeScale); - outMaterial.ZWriteFineControl = (video::E_ZWRITE_FINE_CONTROL)attr->getAttributeAsInt("ZWriteFineControl", outMaterial.ZWriteFineControl); + prefix = "BilinearFilter"; if (attr->existsAttribute(prefix.c_str())) // legacy outMaterial.setFlag(EMF_BILINEAR_FILTER, attr->getAttributeAsBool(prefix.c_str())); @@ -2325,7 +2329,7 @@ void CNullDriver::deleteMaterialRenders() //! Returns pointer to material renderer or null -IMaterialRenderer* CNullDriver::getMaterialRenderer(u32 idx) +IMaterialRenderer* CNullDriver::getMaterialRenderer(u32 idx) const { if ( idx < MaterialRenderers.size() ) return MaterialRenderers[idx].Renderer; @@ -2749,6 +2753,24 @@ core::dimension2du CNullDriver::getMaxTextureSize() const return core::dimension2du(0x10000,0x10000); // maybe large enough } +bool CNullDriver::needsTransparentRenderPass(const irr::video::SMaterial& material) const +{ + // TODO: I suspect it would be nice if the material had an enum for further control. + // Especially it probably makes sense to allow disabling transparent render pass as soon as material.ZWriteEnable is on. + // But then we might want an enum for the renderpass in material instead of just a transparency flag in material - and that's more work. + // Or we could at least set return false when material.ZWriteEnable is EZW_ON? Still considering that... + // Be careful - this function is deeply connected to getWriteZBuffer as transparent render passes are usually about rendering with + // zwrite disabled and getWriteZBuffer calls this function. + + video::IMaterialRenderer* rnd = getMaterialRenderer(material.MaterialType); + // TODO: I suspect IMaterialRenderer::isTransparent also often could use SMaterial as parameter + // We could for example then get rid of IsTransparent function in SMaterial and move that to the software material renderer. + if (rnd && rnd->isTransparent()) + return true; + + return false; +} + //! Color conversion convenience function /** Convert an image (as array of pixels) from source to destination diff --git a/source/Irrlicht/CNullDriver.h b/source/Irrlicht/CNullDriver.h index c246a263..ebd700de 100644 --- a/source/Irrlicht/CNullDriver.h +++ b/source/Irrlicht/CNullDriver.h @@ -536,7 +536,7 @@ namespace video s32 userData=0) _IRR_OVERRIDE_; //! Returns pointer to material renderer or null - virtual IMaterialRenderer* getMaterialRenderer(u32 idx) _IRR_OVERRIDE_; + virtual IMaterialRenderer* getMaterialRenderer(u32 idx) const _IRR_OVERRIDE_; //! Returns amount of currently available material renderers. virtual u32 getMaterialRendererCount() const _IRR_OVERRIDE_; @@ -670,6 +670,9 @@ namespace video //! Returns the maximum texture size supported. virtual core::dimension2du getMaxTextureSize() const _IRR_OVERRIDE_; + //! Used by some SceneNodes to check if a material should be rendered in the transparent render pass + virtual bool needsTransparentRenderPass(const irr::video::SMaterial& material) const _IRR_OVERRIDE_; + //! Color conversion convenience function /** Convert an image (as array of pixels) from source to destination array, thereby converting the color format. The pixel size is @@ -746,24 +749,18 @@ namespace video return (f32) getAverage ( p[(y * pitch) + x] ); } - inline bool getWriteZBuffer(const SMaterial&material) const + inline bool getWriteZBuffer(const SMaterial& material) const { - if (material.ZWriteEnable) + switch ( material.ZWriteEnable ) { - if (!AllowZWriteOnTransparent) - { - switch (material.ZWriteFineControl) - { - case EZI_ONLY_NON_TRANSPARENT: - return !material.isTransparent(); - case EZI_ZBUFFER_FLAG: - return true; - } - } - else + case video::EZW_OFF: + return false; + case video::EZW_AUTO: + return AllowZWriteOnTransparent || ! needsTransparentRenderPass(material); + case video::EZW_ON: return true; } - return false; + return true; // never should get here, but some compilers don't know and complain } struct SSurface diff --git a/source/Irrlicht/COGLES2Common.h b/source/Irrlicht/COGLES2Common.h index 2c257704..8b01c8e6 100644 --- a/source/Irrlicht/COGLES2Common.h +++ b/source/Irrlicht/COGLES2Common.h @@ -43,10 +43,6 @@ typedef char GLchar; #define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 2 #define GL_FRAMEBUFFER_INCOMPLETE_FORMATS 3 -// Irrlicht's OpenGL version. - -#define IRR_OPENGL_VERSION 20 - // to check if this header is in the current compile unit (different GL implementation used different "GLCommon" headers in Irrlicht #define IRR_COMPILE_GLES2_COMMON diff --git a/source/Irrlicht/COGLES2Driver.cpp b/source/Irrlicht/COGLES2Driver.cpp index 7ff5c3ea..5f5c6b39 100644 --- a/source/Irrlicht/COGLES2Driver.cpp +++ b/source/Irrlicht/COGLES2Driver.cpp @@ -1825,7 +1825,9 @@ COGLES2Driver::~COGLES2Driver() } // Blend Factor - if (IR(material.BlendFactor) & 0xFFFFFFFF) + if (IR(material.BlendFactor) & 0xFFFFFFFF // TODO: why the & 0xFFFFFFFF? + && material.MaterialType != EMT_ONETEXTURE_BLEND + ) { E_BLEND_FACTOR srcRGBFact = EBF_ZERO; E_BLEND_FACTOR dstRGBFact = EBF_ZERO; @@ -2029,7 +2031,7 @@ COGLES2Driver::~COGLES2Driver() if (OverrideMaterial2DEnabled) { OverrideMaterial2D.Lighting=false; - OverrideMaterial2D.ZWriteEnable=false; + OverrideMaterial2D.ZWriteEnable=EZW_OFF; OverrideMaterial2D.ZBuffer=ECFN_DISABLED; // it will be ECFN_DISABLED after merge OverrideMaterial2D.Lighting=false; @@ -2955,6 +2957,11 @@ COGLES2Driver::~COGLES2Driver() return getColorFormatParameters(format, dummyInternalFormat, dummyPixelFormat, dummyPixelType, &dummyConverter); } + bool COGLES2Driver::needsTransparentRenderPass(const irr::video::SMaterial& material) const + { + return CNullDriver::needsTransparentRenderPass(material) || material.isAlphaBlendOperation(); + } + const SMaterial& COGLES2Driver::getCurrentMaterial() const { return Material; diff --git a/source/Irrlicht/COGLES2Driver.h b/source/Irrlicht/COGLES2Driver.h index fe0857f8..e7e2ac4b 100644 --- a/source/Irrlicht/COGLES2Driver.h +++ b/source/Irrlicht/COGLES2Driver.h @@ -311,6 +311,9 @@ namespace video //! Check if the driver supports creating textures with the given color format virtual bool queryTextureFormat(ECOLOR_FORMAT format) const _IRR_OVERRIDE_; + //! Used by some SceneNodes to check if a material should be rendered in the transparent render pass + virtual bool needsTransparentRenderPass(const irr::video::SMaterial& material) const _IRR_OVERRIDE_; + //! Convert E_BLEND_FACTOR to OpenGL equivalent GLenum getGLBlend(E_BLEND_FACTOR factor) const; diff --git a/source/Irrlicht/COGLESCommon.h b/source/Irrlicht/COGLESCommon.h index b9919d4a..c7988f7a 100644 --- a/source/Irrlicht/COGLESCommon.h +++ b/source/Irrlicht/COGLESCommon.h @@ -93,10 +93,6 @@ typedef char GLchar; #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0 #endif -// Irrlicht's OpenGL version. - -#define IRR_OPENGL_VERSION 15 - // to check if this header is in the current compile unit (different GL implementation used different "GLCommon" headers in Irrlicht #define IRR_COMPILE_GLES_COMMON diff --git a/source/Irrlicht/COGLESDriver.cpp b/source/Irrlicht/COGLESDriver.cpp index a4ab4e8a..28c56878 100644 --- a/source/Irrlicht/COGLESDriver.cpp +++ b/source/Irrlicht/COGLESDriver.cpp @@ -1800,7 +1800,9 @@ void COGLES1Driver::setBasicRenderStates(const SMaterial& material, const SMater } // Blend Factor - if (IR(material.BlendFactor) & 0xFFFFFFFF) + if (IR(material.BlendFactor) & 0xFFFFFFFF // TODO: why the & 0xFFFFFFFF? + && material.MaterialType != EMT_ONETEXTURE_BLEND + ) { E_BLEND_FACTOR srcRGBFact = EBF_ZERO; E_BLEND_FACTOR dstRGBFact = EBF_ZERO; @@ -3249,6 +3251,11 @@ bool COGLES1Driver::queryTextureFormat(ECOLOR_FORMAT format) const return getColorFormatParameters(format, dummyInternalFormat, dummyPixelFormat, dummyPixelType, &dummyConverter); } +bool COGLES1Driver::needsTransparentRenderPass(const irr::video::SMaterial& material) const +{ + return CNullDriver::needsTransparentRenderPass(material) || material.isAlphaBlendOperation(); +} + COGLES1CacheHandler* COGLES1Driver::getCacheHandler() const { return CacheHandler; diff --git a/source/Irrlicht/COGLESDriver.h b/source/Irrlicht/COGLESDriver.h index 9e2b3134..12017d6b 100644 --- a/source/Irrlicht/COGLESDriver.h +++ b/source/Irrlicht/COGLESDriver.h @@ -289,6 +289,9 @@ namespace video //! Check if the driver supports creating textures with the given color format virtual bool queryTextureFormat(ECOLOR_FORMAT format) const _IRR_OVERRIDE_; + //! Used by some SceneNodes to check if a material should be rendered in the transparent render pass + virtual bool needsTransparentRenderPass(const irr::video::SMaterial& material) const _IRR_OVERRIDE_; + //! Convert E_BLEND_FACTOR to OpenGL equivalent GLenum getGLBlend(E_BLEND_FACTOR factor) const; diff --git a/source/Irrlicht/COctreeSceneNode.cpp b/source/Irrlicht/COctreeSceneNode.cpp index 63e9e43d..16df1199 100644 --- a/source/Irrlicht/COctreeSceneNode.cpp +++ b/source/Irrlicht/COctreeSceneNode.cpp @@ -34,7 +34,7 @@ COctreeSceneNode::COctreeSceneNode(ISceneNode* parent, ISceneManager* mgr, : IOctreeSceneNode(parent, mgr, id), StdOctree(0), LightMapOctree(0), TangentsOctree(0), VertexType((video::E_VERTEX_TYPE)-1), MinimalPolysPerNode(minimalPolysPerNode), Mesh(0), Shadow(0), - UseVBOs(EOV_USE_VBO_WITH_VISIBITLY), PolygonChecks(EOPC_BOX) + UseVBOs(EOV_NO_VBO), PolygonChecks(EOPC_BOX) { #ifdef _DEBUG setDebugName("COctreeSceneNode"); @@ -79,10 +79,7 @@ void COctreeSceneNode::OnRegisterSceneNode() // count transparent and solid materials in this scene node for (u32 i=0; igetMaterialRenderer(Materials[i].MaterialType); - - if ((rnd && rnd->isTransparent()) || Materials[i].isTransparent()) + if (driver->needsTransparentRenderPass(Materials[i])) ++transparentCount; else ++solidCount; @@ -145,7 +142,7 @@ void COctreeSceneNode::render() if (!camera) return; - bool isTransparentPass = + const bool isTransparentPass = SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT; ++PassCount; @@ -188,8 +185,7 @@ void COctreeSceneNode::render() if ( 0 == d[i].CurrentSize ) continue; - const video::IMaterialRenderer* const rnd = driver->getMaterialRenderer(Materials[i].MaterialType); - const bool transparent = (rnd && rnd->isTransparent()); + const bool transparent = driver->needsTransparentRenderPass(Materials[i]); // only render transparent buffer if this is the transparent render pass // and solid only in solid pass diff --git a/source/Irrlicht/COctreeSceneNode.h b/source/Irrlicht/COctreeSceneNode.h index 89de7eda..5ef28088 100644 --- a/source/Irrlicht/COctreeSceneNode.h +++ b/source/Irrlicht/COctreeSceneNode.h @@ -78,10 +78,14 @@ namespace scene //! or to remove attached child. virtual bool removeChild(ISceneNode* child) _IRR_OVERRIDE_; + // TODO: Currently using VBO's will crash when reloading the model. + // The reason is that COctreeSceneNode uses Octree::SMeshChunk + // which does use a an IReferenceCounted object on the stack. + // Which breaks VBO's which correctly use reference counting., //! Set if/how vertex buffer object are used for the meshbuffers /** NOTE: When there is already a mesh in the node this will rebuild the octree. */ - virtual void setUseVBO(EOCTREENODE_VBO useVBO) _IRR_OVERRIDE_; + virtual void setUseVBO(EOCTREENODE_VBO useVBO); //! Get if/how vertex buffer object are used for the meshbuffers virtual EOCTREENODE_VBO getUseVBO() const _IRR_OVERRIDE_; diff --git a/source/Irrlicht/COgreMeshFileLoader.cpp b/source/Irrlicht/COgreMeshFileLoader.cpp index 9daf3698..9df20871 100644 --- a/source/Irrlicht/COgreMeshFileLoader.cpp +++ b/source/Irrlicht/COgreMeshFileLoader.cpp @@ -1013,7 +1013,7 @@ void COgreMeshFileLoader::readPass(io::IReadFile* file, OgreTechnique& technique else if (token=="depth_write") { getMaterialToken(file, token); - pass.Material.ZWriteEnable=(token=="on"); + pass.Material.ZWriteEnable=(token=="on") ? video::EZW_ON : video::EZW_OFF; } else if (token=="depth_func") { diff --git a/source/Irrlicht/COpenGLCommon.h b/source/Irrlicht/COpenGLCommon.h index 0e60345f..4d38c3a0 100644 --- a/source/Irrlicht/COpenGLCommon.h +++ b/source/Irrlicht/COpenGLCommon.h @@ -169,11 +169,7 @@ typedef char GLchar; #endif #endif -// Irrlicht's OpenGL version. - -#define IRR_OPENGL_VERSION 14 - -// to check if this header is in the current compile unit (different GL implementation used different "GLCommon" headers in Irrlicht +// To check if this header is in the current compile unit (different GL driver implementations use different "GLCommon" headers in Irrlicht) #define IRR_COMPILE_GL_COMMON namespace irr diff --git a/source/Irrlicht/COpenGLCoreCacheHandler.h b/source/Irrlicht/COpenGLCoreCacheHandler.h index 13b1b5eb..5726e5f2 100644 --- a/source/Irrlicht/COpenGLCoreCacheHandler.h +++ b/source/Irrlicht/COpenGLCoreCacheHandler.h @@ -94,12 +94,12 @@ class COpenGLCoreCacheHandler { glBindTexture(prevTextureType, 0); -#if (defined(IRR_OPENGL_VERSION) && IRR_OPENGL_VERSION < 20) || (defined(IRR_OPENGL_ES_VERSION) && IRR_OPENGL_ES_VERSION < 20) +#if ( defined(IRR_COMPILE_GL_COMMON) || defined(IRR_COMPILE_GLES_COMMON) ) glDisable(prevTextureType); glEnable(curTextureType); #endif } -#if (defined(IRR_OPENGL_VERSION) && IRR_OPENGL_VERSION < 20) || (defined(IRR_OPENGL_ES_VERSION) && IRR_OPENGL_ES_VERSION < 20) +#if ( defined(IRR_COMPILE_GL_COMMON) || defined(IRR_COMPILE_GLES_COMMON) ) else if (!prevTexture) glEnable(curTextureType); #endif @@ -122,7 +122,7 @@ class COpenGLCoreCacheHandler glBindTexture(prevTextureType, 0); -#if (defined(IRR_OPENGL_VERSION) && IRR_OPENGL_VERSION < 20) || (defined(IRR_OPENGL_ES_VERSION) && IRR_OPENGL_ES_VERSION < 20) +#if ( defined(IRR_COMPILE_GL_COMMON) || defined(IRR_COMPILE_GLES_COMMON) ) glDisable(prevTextureType); #endif } @@ -241,7 +241,7 @@ public: Driver->irrGlActiveTexture(ActiveTexture); -#if (defined(IRR_OPENGL_VERSION) && IRR_OPENGL_VERSION < 20) || (defined(IRR_OPENGL_ES_VERSION) && IRR_OPENGL_ES_VERSION < 20) +#if ( defined(IRR_COMPILE_GL_COMMON) || defined(IRR_COMPILE_GLES_COMMON) ) glDisable(GL_TEXTURE_2D); #endif diff --git a/source/Irrlicht/COpenGLDriver.cpp b/source/Irrlicht/COpenGLDriver.cpp index 154261e7..1eb81686 100644 --- a/source/Irrlicht/COpenGLDriver.cpp +++ b/source/Irrlicht/COpenGLDriver.cpp @@ -2587,7 +2587,9 @@ void COpenGLDriver::setBasicRenderStates(const SMaterial& material, const SMater } // Blend Factor - if (IR(material.BlendFactor) & 0xFFFFFFFF) + if (IR(material.BlendFactor) & 0xFFFFFFFF // TODO: why the & 0xFFFFFFFF? + && material.MaterialType != EMT_ONETEXTURE_BLEND + ) { E_BLEND_FACTOR srcRGBFact = EBF_ZERO; E_BLEND_FACTOR dstRGBFact = EBF_ZERO; @@ -3620,6 +3622,11 @@ bool COpenGLDriver::queryTextureFormat(ECOLOR_FORMAT format) const return getColorFormatParameters(format, dummyInternalFormat, dummyPixelFormat, dummyPixelType, &dummyConverter); } +bool COpenGLDriver::needsTransparentRenderPass(const irr::video::SMaterial& material) const +{ + return CNullDriver::needsTransparentRenderPass(material) || material.isAlphaBlendOperation(); +} + //! Only used by the internal engine. Used to notify the driver that //! the window was resized. void COpenGLDriver::OnResize(const core::dimension2d& size) diff --git a/source/Irrlicht/COpenGLDriver.h b/source/Irrlicht/COpenGLDriver.h index 265d727c..54660cbe 100644 --- a/source/Irrlicht/COpenGLDriver.h +++ b/source/Irrlicht/COpenGLDriver.h @@ -383,6 +383,9 @@ namespace video //! Check if the driver supports creating textures with the given color format virtual bool queryTextureFormat(ECOLOR_FORMAT format) const _IRR_OVERRIDE_; + //! Used by some SceneNodes to check if a material should be rendered in the transparent render pass + virtual bool needsTransparentRenderPass(const irr::video::SMaterial& material) const _IRR_OVERRIDE_; + //! Convert E_PRIMITIVE_TYPE to OpenGL equivalent GLenum primitiveTypeToGL(scene::E_PRIMITIVE_TYPE type) const; diff --git a/source/Irrlicht/COpenGLMaterialRenderer.h b/source/Irrlicht/COpenGLMaterialRenderer.h index 115d161d..43d72190 100644 --- a/source/Irrlicht/COpenGLMaterialRenderer.h +++ b/source/Irrlicht/COpenGLMaterialRenderer.h @@ -727,8 +727,8 @@ public: glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT); #endif - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); } @@ -812,8 +812,8 @@ public: glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_ARB); #endif - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); } diff --git a/source/Irrlicht/COpenGLShaderMaterialRenderer.h b/source/Irrlicht/COpenGLShaderMaterialRenderer.h index fad2efbf..7cae915e 100644 --- a/source/Irrlicht/COpenGLShaderMaterialRenderer.h +++ b/source/Irrlicht/COpenGLShaderMaterialRenderer.h @@ -21,7 +21,7 @@ namespace video class COpenGLDriver; class IShaderConstantSetCallBack; -//! Class for using vertex and pixel shaders with OpenGL +//! Class for using vertex and pixel shaders with OpenGL (asm not glsl!) class COpenGLShaderMaterialRenderer : public IMaterialRenderer { public: @@ -69,6 +69,13 @@ protected: COpenGLDriver* Driver; IShaderConstantSetCallBack* CallBack; + // I didn't write this, but here's my understanding: + // Those flags seem to be exclusive so far (so could be an enum). + // Maybe the idea was to make them non-exclusive in future (basically having a shader-material) + // Actually currently there's not even any need to cache them (probably even slower than not doing so). + // They seem to be mostly for downward compatibility. + // I suppose the idea is to use SMaterial.BlendOperation + SMaterial.BlendFactor and a simple non-transparent type as base for more flexibility in the future. + // Note that SMaterial.BlendOperation + SMaterial.BlendFactor are in some drivers already evaluated before OnSetMaterial. bool Alpha; bool Blending; bool FixedBlending; diff --git a/source/Irrlicht/CQ3LevelMesh.cpp b/source/Irrlicht/CQ3LevelMesh.cpp index 7d7ca779..b2f9060e 100644 --- a/source/Irrlicht/CQ3LevelMesh.cpp +++ b/source/Irrlicht/CQ3LevelMesh.cpp @@ -718,7 +718,7 @@ s32 CQ3LevelMesh::setShaderFogMaterial( video::SMaterial &material, const tBSPFa material.setTexture(2, 0); material.setTexture(3, 0); material.ZBuffer = video::ECFN_LESSEQUAL; - material.ZWriteEnable = false; + material.ZWriteEnable = video::EZW_OFF; material.MaterialTypeParam = 0.f; s32 shaderState = -1; @@ -746,7 +746,7 @@ s32 CQ3LevelMesh::setShaderMaterial( video::SMaterial &material, const tBSPFace material.setTexture(2, 0); material.setTexture(3, 0); material.ZBuffer = video::ECFN_LESSEQUAL; - material.ZWriteEnable = true; + material.ZWriteEnable = video::EZW_AUTO; material.MaterialTypeParam = 0.f; s32 shaderState = -1; @@ -804,7 +804,7 @@ s32 CQ3LevelMesh::setShaderMaterial( video::SMaterial &material, const tBSPFace if ( group->isDefined( "depthwrite" ) ) { - material.ZWriteEnable = true; + material.ZWriteEnable = video::EZW_ON; } SBlendFunc blendfunc ( LoadParam.defaultModulate ); diff --git a/source/Irrlicht/CQuake3ShaderSceneNode.cpp b/source/Irrlicht/CQuake3ShaderSceneNode.cpp index 9df0f61e..972f131d 100644 --- a/source/Irrlicht/CQuake3ShaderSceneNode.cpp +++ b/source/Irrlicht/CQuake3ShaderSceneNode.cpp @@ -368,13 +368,14 @@ void CQuake3ShaderSceneNode::render() material.setTexture(0, tex ); material.ZBuffer = getDepthFunction( group->get( "depthfunc" ) ); + // TODO: maybe should be video::EZW_ON instead of EZW_AUTO now (we didn't have that before and I just kept old values here when introducing it to not break anything) if ( group->isDefined( "depthwrite" ) ) { - material.ZWriteEnable = true; + material.ZWriteEnable = video::EZW_AUTO; } else { - material.ZWriteEnable = drawCount == 0; + material.ZWriteEnable = drawCount == 0 ? video::EZW_AUTO : video::EZW_OFF; } //resolve quake3 blendfunction to irrlicht Material Type diff --git a/source/Irrlicht/CSceneManager.cpp b/source/Irrlicht/CSceneManager.cpp index 2c1af0ad..0d1f7c9d 100644 --- a/source/Irrlicht/CSceneManager.cpp +++ b/source/Irrlicht/CSceneManager.cpp @@ -159,6 +159,12 @@ #include "CSkyDomeSceneNode.h" #endif // _IRR_COMPILE_WITH_SKYDOME_SCENENODE_ +#ifdef _IRR_COMPILE_WITH_SHADOW_VOLUME_SCENENODE_ +#include "CShadowVolumeSceneNode.h" +#else +#include "IShadowVolumeSceneNode.h" +#endif // _IRR_COMPILE_WITH_SHADOW_VOLUME_SCENENODE_ + #ifdef _IRR_COMPILE_WITH_PARTICLES_ #include "CParticleSystemSceneNode.h" #endif // _IRR_COMPILE_WITH_PARTICLES_ @@ -1371,9 +1377,7 @@ u32 CSceneManager::registerNodeForRendering(ISceneNode* node, E_SCENE_NODE_RENDE taken = 0; for (u32 i=0; igetMaterialRenderer(node->getMaterial(i).MaterialType); - if ((rnd && rnd->isTransparent()) || node->getMaterial(i).isTransparent()) + if (Driver->needsTransparentRenderPass(node->getMaterial(i))) { // register as transparent node TransparentNodeEntry e(node, camWorldPos); @@ -1740,6 +1744,16 @@ video::SColor CSceneManager::getShadowColor() const return ShadowColor; } +IShadowVolumeSceneNode* CSceneManager::createShadowVolumeSceneNode(const IMesh* shadowMesh, ISceneNode* parent, s32 id, bool zfailmethod, f32 infinity) +{ +#ifdef _IRR_COMPILE_WITH_SHADOW_VOLUME_SCENENODE_ + return new CShadowVolumeSceneNode(shadowMesh, parent, this, id, zfailmethod, infinity); +#else + return 0; +#endif +} + + //! creates a rotation animator, which rotates the attached scene node around itself. ISceneNodeAnimator* CSceneManager::createRotationAnimator(const core::vector3df& rotationPerSecond) diff --git a/source/Irrlicht/CSceneManager.h b/source/Irrlicht/CSceneManager.h index 26afb921..a83ab48b 100644 --- a/source/Irrlicht/CSceneManager.h +++ b/source/Irrlicht/CSceneManager.h @@ -408,6 +408,9 @@ namespace scene //! Returns the current color of shadows. virtual video::SColor getShadowColor() const _IRR_OVERRIDE_; + //! Create a shadow volume scene node to be used with custom nodes + virtual IShadowVolumeSceneNode* createShadowVolumeSceneNode(const IMesh* shadowMesh, ISceneNode* parent, s32 id, bool zfailmethod, f32 infinity) _IRR_OVERRIDE_; + //! Adds a scene node to the deletion queue. virtual void addToDeletionQueue(ISceneNode* node) _IRR_OVERRIDE_; diff --git a/source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp b/source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp index a06a23da..89d377ab 100644 --- a/source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp +++ b/source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp @@ -206,7 +206,8 @@ void CSceneNodeAnimatorCameraFPS::animateNode(ISceneNode* node, u32 timeMs) } // set target - target.set(0,0,1); + core::vector3df pos = camera->getPosition(); + target.set(0,0, core::max_(1.f, pos.getLength())); // better float precision than (0,0,1) in target-pos calculation in camera core::vector3df movedir(target); core::matrix4 mat; @@ -225,7 +226,6 @@ void CSceneNodeAnimatorCameraFPS::animateNode(ISceneNode* node, u32 timeMs) movedir.normalize(); - core::vector3df pos = camera->getPosition(); if (CursorKeys[EKA_MOVE_FORWARD]) pos += movedir * timeDiff * MoveSpeed; diff --git a/source/Irrlicht/CSkyBoxSceneNode.cpp b/source/Irrlicht/CSkyBoxSceneNode.cpp index de41f03d..2ad3fe6e 100644 --- a/source/Irrlicht/CSkyBoxSceneNode.cpp +++ b/source/Irrlicht/CSkyBoxSceneNode.cpp @@ -39,7 +39,7 @@ CSkyBoxSceneNode::CSkyBoxSceneNode(video::ITexture* top, video::ITexture* bottom video::SMaterial mat; mat.Lighting = false; mat.ZBuffer = video::ECFN_DISABLED; - mat.ZWriteEnable = false; + mat.ZWriteEnable = video::EZW_OFF; mat.AntiAliasing=0; mat.TextureLayer[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE; mat.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE; @@ -196,7 +196,7 @@ void CSkyBoxSceneNode::render() core::rect rctDest(core::position2d(-1,0), core::dimension2di(driver->getCurrentRenderTargetSize())); core::rect rctSrc(core::position2d(0,0), - core::dimension2di(tex->getSize())); + core::dimension2di(tex->getOriginalSize())); driver->draw2DImage(tex, rctDest, rctSrc); } diff --git a/source/Irrlicht/CSkyDomeSceneNode.cpp b/source/Irrlicht/CSkyDomeSceneNode.cpp index 7b6affe0..7cf81f39 100644 --- a/source/Irrlicht/CSkyDomeSceneNode.cpp +++ b/source/Irrlicht/CSkyDomeSceneNode.cpp @@ -49,7 +49,7 @@ CSkyDomeSceneNode::CSkyDomeSceneNode(video::ITexture* sky, u32 horiRes, u32 vert Buffer = new SMeshBuffer(); Buffer->Material.Lighting = false; Buffer->Material.ZBuffer = video::ECFN_DISABLED; - Buffer->Material.ZWriteEnable = false; + Buffer->Material.ZWriteEnable = video::EZW_OFF; Buffer->Material.AntiAliasing = video::EAAM_OFF; Buffer->Material.setTexture(0, sky); Buffer->BoundingBox.MaxEdge.set(0,0,0); diff --git a/source/Irrlicht/CSoftwareDriver.cpp b/source/Irrlicht/CSoftwareDriver.cpp index 3ffebb1c..426aac29 100644 --- a/source/Irrlicht/CSoftwareDriver.cpp +++ b/source/Irrlicht/CSoftwareDriver.cpp @@ -139,7 +139,7 @@ void CSoftwareDriver::selectRightTriangleRenderer() renderer = ETR_TEXTURE_GOURAUD_ADD; } else - if ((Material.ZBuffer==ECFN_DISABLED) && !Material.ZWriteEnable) + if ((Material.ZBuffer==ECFN_DISABLED) && Material.ZWriteEnable == video::EZW_OFF) renderer = ETR_TEXTURE_GOURAUD_NOZ; else { diff --git a/source/Irrlicht/CSoftwareDriver2.cpp b/source/Irrlicht/CSoftwareDriver2.cpp index 5cbfaaca..8b514c9d 100644 --- a/source/Irrlicht/CSoftwareDriver2.cpp +++ b/source/Irrlicht/CSoftwareDriver2.cpp @@ -177,8 +177,8 @@ void CBurningVideoDriver::setCurrentShader() ITexture *texture1 = Material.org.getTexture(1); bool zMaterialTest = Material.org.ZBuffer != ECFN_DISABLED && - Material.org.ZWriteEnable && - getWriteZBuffer(Material.org); + Material.org.ZWriteEnable != video::EZW_OFF && + ( AllowZWriteOnTransparent || !Material.org.isTransparent() ); EBurningFFShader shader = zMaterialTest ? ETR_TEXTURE_GOURAUD : ETR_TEXTURE_GOURAUD_NOZ; @@ -1885,8 +1885,8 @@ void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core core::recti clip=ViewPort; if (ViewPort.getSize().Width != ScreenSize.Width) { - dest.X=ViewPort.UpperLeftCorner.X+core::round32(destPos.X*ViewPort.getWidth()/(f32)ScreenSize.Width); - dest.Y=ViewPort.UpperLeftCorner.Y+core::round32(destPos.Y*ViewPort.getHeight()/(f32)ScreenSize.Height); + dest.X=ViewPort.UpperLeftCorner.X+core::round32_fast(destPos.X*ViewPort.getWidth()/(f32)ScreenSize.Width); + dest.Y=ViewPort.UpperLeftCorner.Y+core::round32_fast(destPos.Y*ViewPort.getHeight()/(f32)ScreenSize.Height); if (clipRect) { clip.constrainTo(*clipRect); @@ -2292,7 +2292,7 @@ void CBurningVideoDriver::drawStencilShadowVolume(const core::arrayPos.y ); - yEnd = core::ceil32( b->Pos.y ) - 1; + yStart = core::ceil32_fast( a->Pos.y ); + yEnd = core::ceil32_fast( b->Pos.y ) - 1; #ifdef SUBTEXEL subPixel = ( (f32) yStart ) - a->Pos.y; @@ -510,8 +510,8 @@ void CTRGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4D #endif // apply top-left fill convention, top part - yStart = core::ceil32( b->Pos.y ); - yEnd = core::ceil32( c->Pos.y ) - 1; + yStart = core::ceil32_fast( b->Pos.y ); + yEnd = core::ceil32_fast( c->Pos.y ) - 1; #ifdef SUBTEXEL diff --git a/source/Irrlicht/CTRGouraudAlpha2.cpp b/source/Irrlicht/CTRGouraudAlpha2.cpp index 889df1d0..837ab3e4 100644 --- a/source/Irrlicht/CTRGouraudAlpha2.cpp +++ b/source/Irrlicht/CTRGouraudAlpha2.cpp @@ -142,8 +142,8 @@ void CTRGouraudAlpha2::scanline_bilinear () #endif // apply top-left fill-convention, left - xStart = core::ceil32( line.x[0] ); - xEnd = core::ceil32( line.x[1] ) - 1; + xStart = core::ceil32_fast( line.x[0] ); + xEnd = core::ceil32_fast( line.x[1] ) - 1; dx = xEnd - xStart; @@ -365,8 +365,8 @@ void CTRGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons #endif // apply top-left fill convention, top part - yStart = core::ceil32( a->Pos.y ); - yEnd = core::ceil32( b->Pos.y ) - 1; + yStart = core::ceil32_fast( a->Pos.y ); + yEnd = core::ceil32_fast( b->Pos.y ) - 1; #ifdef SUBTEXEL subPixel = ( (f32) yStart ) - a->Pos.y; @@ -524,8 +524,8 @@ void CTRGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons #endif // apply top-left fill convention, top part - yStart = core::ceil32( b->Pos.y ); - yEnd = core::ceil32( c->Pos.y ) - 1; + yStart = core::ceil32_fast( b->Pos.y ); + yEnd = core::ceil32_fast( c->Pos.y ) - 1; #ifdef SUBTEXEL diff --git a/source/Irrlicht/CTRGouraudAlphaNoZ2.cpp b/source/Irrlicht/CTRGouraudAlphaNoZ2.cpp index e03fb192..b5453df0 100644 --- a/source/Irrlicht/CTRGouraudAlphaNoZ2.cpp +++ b/source/Irrlicht/CTRGouraudAlphaNoZ2.cpp @@ -138,8 +138,8 @@ void CTRGouraudAlphaNoZ2::scanline_bilinear () #endif // apply top-left fill-convention, left - xStart = core::ceil32( line.x[0] ); - xEnd = core::ceil32( line.x[1] ) - 1; + xStart = core::ceil32_fast( line.x[0] ); + xEnd = core::ceil32_fast( line.x[1] ) - 1; dx = xEnd - xStart; @@ -363,8 +363,8 @@ void CTRGouraudAlphaNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,c #endif // apply top-left fill convention, top part - yStart = core::ceil32( a->Pos.y ); - yEnd = core::ceil32( b->Pos.y ) - 1; + yStart = core::ceil32_fast( a->Pos.y ); + yEnd = core::ceil32_fast( b->Pos.y ) - 1; #ifdef SUBTEXEL subPixel = ( (f32) yStart ) - a->Pos.y; @@ -522,8 +522,8 @@ void CTRGouraudAlphaNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,c #endif // apply top-left fill convention, top part - yStart = core::ceil32( b->Pos.y ); - yEnd = core::ceil32( c->Pos.y ) - 1; + yStart = core::ceil32_fast( b->Pos.y ); + yEnd = core::ceil32_fast( c->Pos.y ) - 1; #ifdef SUBTEXEL diff --git a/source/Irrlicht/CTRNormalMap.cpp b/source/Irrlicht/CTRNormalMap.cpp index 61fc258e..bc72b75c 100644 --- a/source/Irrlicht/CTRNormalMap.cpp +++ b/source/Irrlicht/CTRNormalMap.cpp @@ -145,8 +145,8 @@ void CTRNormalMap::scanline_bilinear () #endif // apply top-left fill-convention, left - xStart = core::ceil32( line.x[0] ); - xEnd = core::ceil32( line.x[1] ) - 1; + xStart = core::ceil32_fast( line.x[0] ); + xEnd = core::ceil32_fast( line.x[1] ) - 1; dx = xEnd - xStart; @@ -476,8 +476,8 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4 #endif // apply top-left fill convention, top part - yStart = core::ceil32( a->Pos.y ); - yEnd = core::ceil32( b->Pos.y ) - 1; + yStart = core::ceil32_fast( a->Pos.y ); + yEnd = core::ceil32_fast( b->Pos.y ) - 1; #ifdef SUBTEXEL subPixel = ( (f32) yStart ) - a->Pos.y; @@ -683,8 +683,8 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4 #endif // apply top-left fill convention, top part - yStart = core::ceil32( b->Pos.y ); - yEnd = core::ceil32( c->Pos.y ) - 1; + yStart = core::ceil32_fast( b->Pos.y ); + yEnd = core::ceil32_fast( c->Pos.y ) - 1; #ifdef SUBTEXEL diff --git a/source/Irrlicht/CTRStencilShadow.cpp b/source/Irrlicht/CTRStencilShadow.cpp index 45a4c19e..02ed525d 100644 --- a/source/Irrlicht/CTRStencilShadow.cpp +++ b/source/Irrlicht/CTRStencilShadow.cpp @@ -169,8 +169,8 @@ void CTRStencilShadow::fragment_zfail_decr () #endif // apply top-left fill-convention, left - xStart = core::ceil32( line.x[0] ); - xEnd = core::ceil32( line.x[1] ) - 1; + xStart = core::ceil32_fast( line.x[0] ); + xEnd = core::ceil32_fast( line.x[1] ) - 1; dx = xEnd - xStart; @@ -326,8 +326,8 @@ void CTRStencilShadow::fragment_zfail_incr() #endif // apply top-left fill-convention, left - xStart = core::ceil32( line.x[0] ); - xEnd = core::ceil32( line.x[1] ) - 1; + xStart = core::ceil32_fast( line.x[0] ); + xEnd = core::ceil32_fast( line.x[1] ) - 1; dx = xEnd - xStart; @@ -559,8 +559,8 @@ void CTRStencilShadow::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons #endif // apply top-left fill convention, top part - yStart = core::ceil32( a->Pos.y ); - yEnd = core::ceil32( b->Pos.y ) - 1; + yStart = core::ceil32_fast( a->Pos.y ); + yEnd = core::ceil32_fast( b->Pos.y ) - 1; #ifdef SUBTEXEL subPixel = ( (f32) yStart ) - a->Pos.y; @@ -766,8 +766,8 @@ void CTRStencilShadow::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons #endif // apply top-left fill convention, top part - yStart = core::ceil32( b->Pos.y ); - yEnd = core::ceil32( c->Pos.y ) - 1; + yStart = core::ceil32_fast( b->Pos.y ); + yEnd = core::ceil32_fast( c->Pos.y ) - 1; #ifdef SUBTEXEL diff --git a/source/Irrlicht/CTRTextureBlend.cpp b/source/Irrlicht/CTRTextureBlend.cpp index 472cd924..e3ba0791 100644 --- a/source/Irrlicht/CTRTextureBlend.cpp +++ b/source/Irrlicht/CTRTextureBlend.cpp @@ -255,8 +255,8 @@ void CTRTextureBlend::fragment_dst_color_src_alpha () #endif // apply top-left fill-convention, left - xStart = core::ceil32( line.x[0] ); - xEnd = core::ceil32( line.x[1] ) - 1; + xStart = core::ceil32_fast( line.x[0] ); + xEnd = core::ceil32_fast( line.x[1] ) - 1; dx = xEnd - xStart; @@ -439,8 +439,8 @@ void CTRTextureBlend::fragment_src_color_src_alpha () #endif // apply top-left fill-convention, left - xStart = core::ceil32( line.x[0] ); - xEnd = core::ceil32( line.x[1] ) - 1; + xStart = core::ceil32_fast( line.x[0] ); + xEnd = core::ceil32_fast( line.x[1] ) - 1; dx = xEnd - xStart; @@ -619,8 +619,8 @@ void CTRTextureBlend::fragment_one_one_minus_src_alpha() #endif // apply top-left fill-convention, left - xStart = core::ceil32( line.x[0] ); - xEnd = core::ceil32( line.x[1] ) - 1; + xStart = core::ceil32_fast( line.x[0] ); + xEnd = core::ceil32_fast( line.x[1] ) - 1; dx = xEnd - xStart; @@ -816,8 +816,8 @@ void CTRTextureBlend::fragment_one_minus_dst_alpha_one () #endif // apply top-left fill-convention, left - xStart = core::ceil32( line.x[0] ); - xEnd = core::ceil32( line.x[1] ) - 1; + xStart = core::ceil32_fast( line.x[0] ); + xEnd = core::ceil32_fast( line.x[1] ) - 1; dx = xEnd - xStart; @@ -1012,8 +1012,8 @@ void CTRTextureBlend::fragment_src_alpha_one () #endif // apply top-left fill-convention, left - xStart = core::ceil32( line.x[0] ); - xEnd = core::ceil32( line.x[1] ) - 1; + xStart = core::ceil32_fast( line.x[0] ); + xEnd = core::ceil32_fast( line.x[1] ) - 1; dx = xEnd - xStart; @@ -1239,8 +1239,8 @@ void CTRTextureBlend::fragment_dst_color_one_minus_dst_alpha () #endif // apply top-left fill-convention, left - xStart = core::ceil32( line.x[0] ); - xEnd = core::ceil32( line.x[1] ) - 1; + xStart = core::ceil32_fast( line.x[0] ); + xEnd = core::ceil32_fast( line.x[1] ) - 1; dx = xEnd - xStart; @@ -1435,8 +1435,8 @@ void CTRTextureBlend::fragment_dst_color_zero () #endif // apply top-left fill-convention, left - xStart = core::ceil32( line.x[0] ); - xEnd = core::ceil32( line.x[1] ) - 1; + xStart = core::ceil32_fast( line.x[0] ); + xEnd = core::ceil32_fast( line.x[1] ) - 1; dx = xEnd - xStart; @@ -1629,8 +1629,8 @@ void CTRTextureBlend::fragment_dst_color_one () #endif // apply top-left fill-convention, left - xStart = core::ceil32( line.x[0] ); - xEnd = core::ceil32( line.x[1] ) - 1; + xStart = core::ceil32_fast( line.x[0] ); + xEnd = core::ceil32_fast( line.x[1] ) - 1; dx = xEnd - xStart; @@ -1826,8 +1826,8 @@ void CTRTextureBlend::fragment_zero_one_minus_scr_color () #endif // apply top-left fill-convention, left - xStart = core::ceil32( line.x[0] ); - xEnd = core::ceil32( line.x[1] ) - 1; + xStart = core::ceil32_fast( line.x[0] ); + xEnd = core::ceil32_fast( line.x[1] ) - 1; dx = xEnd - xStart; @@ -2092,8 +2092,8 @@ void CTRTextureBlend::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const #endif // apply top-left fill convention, top part - yStart = core::ceil32( a->Pos.y ); - yEnd = core::ceil32( b->Pos.y ) - 1; + yStart = core::ceil32_fast( a->Pos.y ); + yEnd = core::ceil32_fast( b->Pos.y ) - 1; #ifdef SUBTEXEL subPixel = ( (f32) yStart ) - a->Pos.y; @@ -2251,8 +2251,8 @@ void CTRTextureBlend::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const #endif // apply top-left fill convention, top part - yStart = core::ceil32( b->Pos.y ); - yEnd = core::ceil32( c->Pos.y ) - 1; + yStart = core::ceil32_fast( b->Pos.y ); + yEnd = core::ceil32_fast( c->Pos.y ) - 1; #ifdef SUBTEXEL diff --git a/source/Irrlicht/CTRTextureDetailMap2.cpp b/source/Irrlicht/CTRTextureDetailMap2.cpp index 88eb4c69..f5653ab5 100644 --- a/source/Irrlicht/CTRTextureDetailMap2.cpp +++ b/source/Irrlicht/CTRTextureDetailMap2.cpp @@ -138,8 +138,8 @@ void CTRTextureDetailMap2::scanline_bilinear () #endif // apply top-left fill-convention, left - xStart = core::ceil32( line.x[0] ); - xEnd = core::ceil32( line.x[1] ) - 1; + xStart = core::ceil32_fast( line.x[0] ); + xEnd = core::ceil32_fast( line.x[1] ) - 1; dx = xEnd - xStart; @@ -360,8 +360,8 @@ void CTRTextureDetailMap2::drawTriangle ( const s4DVertex *a,const s4DVertex *b, #endif // apply top-left fill convention, top part - yStart = core::ceil32( a->Pos.y ); - yEnd = core::ceil32( b->Pos.y ) - 1; + yStart = core::ceil32_fast( a->Pos.y ); + yEnd = core::ceil32_fast( b->Pos.y ) - 1; #ifdef SUBTEXEL subPixel = ( (f32) yStart ) - a->Pos.y; @@ -519,8 +519,8 @@ void CTRTextureDetailMap2::drawTriangle ( const s4DVertex *a,const s4DVertex *b, #endif // apply top-left fill convention, top part - yStart = core::ceil32( b->Pos.y ); - yEnd = core::ceil32( c->Pos.y ) - 1; + yStart = core::ceil32_fast( b->Pos.y ); + yEnd = core::ceil32_fast( c->Pos.y ) - 1; #ifdef SUBTEXEL diff --git a/source/Irrlicht/CTRTextureGouraud2.cpp b/source/Irrlicht/CTRTextureGouraud2.cpp index e1788a99..7bcc512b 100644 --- a/source/Irrlicht/CTRTextureGouraud2.cpp +++ b/source/Irrlicht/CTRTextureGouraud2.cpp @@ -137,8 +137,8 @@ void CTRTextureGouraud2::scanline_bilinear () #endif // apply top-left fill-convention, left - xStart = core::ceil32( line.x[0] ); - xEnd = core::ceil32( line.x[1] ) - 1; + xStart = core::ceil32_fast( line.x[0] ); + xEnd = core::ceil32_fast( line.x[1] ) - 1; dx = xEnd - xStart; @@ -380,8 +380,8 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co #endif // apply top-left fill convention, top part - yStart = core::ceil32( a->Pos.y ); - yEnd = core::ceil32( b->Pos.y ) - 1; + yStart = core::ceil32_fast( a->Pos.y ); + yEnd = core::ceil32_fast( b->Pos.y ) - 1; #ifdef SUBTEXEL subPixel = ( (f32) yStart ) - a->Pos.y; @@ -539,8 +539,8 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co #endif // apply top-left fill convention, top part - yStart = core::ceil32( b->Pos.y ); - yEnd = core::ceil32( c->Pos.y ) - 1; + yStart = core::ceil32_fast( b->Pos.y ); + yEnd = core::ceil32_fast( c->Pos.y ) - 1; #ifdef SUBTEXEL diff --git a/source/Irrlicht/CTRTextureGouraudAdd2.cpp b/source/Irrlicht/CTRTextureGouraudAdd2.cpp index 1042341a..0f54928f 100644 --- a/source/Irrlicht/CTRTextureGouraudAdd2.cpp +++ b/source/Irrlicht/CTRTextureGouraudAdd2.cpp @@ -137,8 +137,8 @@ void CTRTextureGouraudAdd2::scanline_bilinear () #endif // apply top-left fill-convention, left - xStart = core::ceil32( line.x[0] ); - xEnd = core::ceil32( line.x[1] ) - 1; + xStart = core::ceil32_fast( line.x[0] ); + xEnd = core::ceil32_fast( line.x[1] ) - 1; dx = xEnd - xStart; @@ -373,8 +373,8 @@ void CTRTextureGouraudAdd2::drawTriangle ( const s4DVertex *a,const s4DVertex *b #endif // apply top-left fill convention, top part - yStart = core::ceil32( a->Pos.y ); - yEnd = core::ceil32( b->Pos.y ) - 1; + yStart = core::ceil32_fast( a->Pos.y ); + yEnd = core::ceil32_fast( b->Pos.y ) - 1; #ifdef SUBTEXEL subPixel = ( (f32) yStart ) - a->Pos.y; @@ -532,8 +532,8 @@ void CTRTextureGouraudAdd2::drawTriangle ( const s4DVertex *a,const s4DVertex *b #endif // apply top-left fill convention, top part - yStart = core::ceil32( b->Pos.y ); - yEnd = core::ceil32( c->Pos.y ) - 1; + yStart = core::ceil32_fast( b->Pos.y ); + yEnd = core::ceil32_fast( c->Pos.y ) - 1; #ifdef SUBTEXEL diff --git a/source/Irrlicht/CTRTextureGouraudAddNoZ2.cpp b/source/Irrlicht/CTRTextureGouraudAddNoZ2.cpp index e0fa1f97..1c7f586b 100644 --- a/source/Irrlicht/CTRTextureGouraudAddNoZ2.cpp +++ b/source/Irrlicht/CTRTextureGouraudAddNoZ2.cpp @@ -137,8 +137,8 @@ void CTRTextureGouraudAddNoZ2::scanline_bilinear () #endif // apply top-left fill-convention, left - xStart = core::ceil32( line.x[0] ); - xEnd = core::ceil32( line.x[1] ) - 1; + xStart = core::ceil32_fast( line.x[0] ); + xEnd = core::ceil32_fast( line.x[1] ) - 1; dx = xEnd - xStart; @@ -348,8 +348,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex #endif // apply top-left fill convention, top part - yStart = core::ceil32( a->Pos.y ); - yEnd = core::ceil32( b->Pos.y ) - 1; + yStart = core::ceil32_fast( a->Pos.y ); + yEnd = core::ceil32_fast( b->Pos.y ) - 1; #ifdef SUBTEXEL subPixel = ( (f32) yStart ) - a->Pos.y; @@ -507,8 +507,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex #endif // apply top-left fill convention, top part - yStart = core::ceil32( b->Pos.y ); - yEnd = core::ceil32( c->Pos.y ) - 1; + yStart = core::ceil32_fast( b->Pos.y ); + yEnd = core::ceil32_fast( c->Pos.y ) - 1; #ifdef SUBTEXEL diff --git a/source/Irrlicht/CTRTextureGouraudAlpha.cpp b/source/Irrlicht/CTRTextureGouraudAlpha.cpp index f83a8d1a..37bb477c 100644 --- a/source/Irrlicht/CTRTextureGouraudAlpha.cpp +++ b/source/Irrlicht/CTRTextureGouraudAlpha.cpp @@ -115,9 +115,9 @@ CTRTextureGouraudAlpha2::CTRTextureGouraudAlpha2(CBurningVideoDriver* driver) void CTRTextureGouraudAlpha2::setParam ( u32 index, f32 value) { #ifdef BURNINGVIDEO_RENDERER_FAST - AlphaRef = core::floor32 ( value * 256.f ); + AlphaRef = core::floor32_fast( value * 256.f ); #else - AlphaRef = u32_to_fixPoint ( core::floor32 ( value * 256.f ) ); + AlphaRef = u32_to_fixPoint ( core::floor32_fast( value * 256.f ) ); #endif } @@ -154,8 +154,8 @@ void CTRTextureGouraudAlpha2::scanline_bilinear () #endif // apply top-left fill-convention, left - xStart = core::ceil32( line.x[0] ); - xEnd = core::ceil32( line.x[1] ) - 1; + xStart = core::ceil32_fast( line.x[0] ); + xEnd = core::ceil32_fast( line.x[1] ) - 1; dx = xEnd - xStart; @@ -441,8 +441,8 @@ void CTRTextureGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex #endif // apply top-left fill convention, top part - yStart = core::ceil32( a->Pos.y ); - yEnd = core::ceil32( b->Pos.y ) - 1; + yStart = core::ceil32_fast( a->Pos.y ); + yEnd = core::ceil32_fast( b->Pos.y ) - 1; #ifdef SUBTEXEL subPixel = ( (f32) yStart ) - a->Pos.y; @@ -600,8 +600,8 @@ void CTRTextureGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex #endif // apply top-left fill convention, top part - yStart = core::ceil32( b->Pos.y ); - yEnd = core::ceil32( c->Pos.y ) - 1; + yStart = core::ceil32_fast( b->Pos.y ); + yEnd = core::ceil32_fast( c->Pos.y ) - 1; #ifdef SUBTEXEL diff --git a/source/Irrlicht/CTRTextureGouraudAlphaNoZ.cpp b/source/Irrlicht/CTRTextureGouraudAlphaNoZ.cpp index d2104700..2830247e 100644 --- a/source/Irrlicht/CTRTextureGouraudAlphaNoZ.cpp +++ b/source/Irrlicht/CTRTextureGouraudAlphaNoZ.cpp @@ -115,9 +115,9 @@ CTRTextureGouraudAlphaNoZ::CTRTextureGouraudAlphaNoZ(CBurningVideoDriver* driver void CTRTextureGouraudAlphaNoZ::setParam ( u32 index, f32 value) { #ifdef BURNINGVIDEO_RENDERER_FAST - AlphaRef = core::floor32 ( value * 256.f ); + AlphaRef = core::floor32_fast( value * 256.f ); #else - AlphaRef = u32_to_fixPoint ( core::floor32 ( value * 256.f ) ); + AlphaRef = u32_to_fixPoint ( core::floor32_fast( value * 256.f ) ); #endif } @@ -154,8 +154,8 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear () #endif // apply top-left fill-convention, left - xStart = core::ceil32( line.x[0] ); - xEnd = core::ceil32( line.x[1] ) - 1; + xStart = core::ceil32_fast( line.x[0] ); + xEnd = core::ceil32_fast( line.x[1] ) - 1; dx = xEnd - xStart; @@ -440,8 +440,8 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte #endif // apply top-left fill convention, top part - yStart = core::ceil32( a->Pos.y ); - yEnd = core::ceil32( b->Pos.y ) - 1; + yStart = core::ceil32_fast( a->Pos.y ); + yEnd = core::ceil32_fast( b->Pos.y ) - 1; #ifdef SUBTEXEL subPixel = ( (f32) yStart ) - a->Pos.y; @@ -599,8 +599,8 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte #endif // apply top-left fill convention, top part - yStart = core::ceil32( b->Pos.y ); - yEnd = core::ceil32( c->Pos.y ) - 1; + yStart = core::ceil32_fast( b->Pos.y ); + yEnd = core::ceil32_fast( c->Pos.y ) - 1; #ifdef SUBTEXEL diff --git a/source/Irrlicht/CTRTextureGouraudNoZ2.cpp b/source/Irrlicht/CTRTextureGouraudNoZ2.cpp index 3b10abff..6abc6e11 100644 --- a/source/Irrlicht/CTRTextureGouraudNoZ2.cpp +++ b/source/Irrlicht/CTRTextureGouraudNoZ2.cpp @@ -142,8 +142,8 @@ void CTRTextureGouraudNoZ2::scanline_bilinear ( ) #endif // apply top-left fill-convention, left - xStart = core::ceil32( line.x[0] ); - xEnd = core::ceil32( line.x[1] ) - 1; + xStart = core::ceil32_fast( line.x[0] ); + xEnd = core::ceil32_fast( line.x[1] ) - 1; dx = xEnd - xStart; @@ -348,8 +348,8 @@ void CTRTextureGouraudNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b #endif // apply top-left fill convention, top part - yStart = core::ceil32( a->Pos.y ); - yEnd = core::ceil32( b->Pos.y ) - 1; + yStart = core::ceil32_fast( a->Pos.y ); + yEnd = core::ceil32_fast( b->Pos.y ) - 1; #ifdef SUBTEXEL subPixel = ( (f32) yStart ) - a->Pos.y; @@ -507,8 +507,8 @@ void CTRTextureGouraudNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b #endif // apply top-left fill convention, top part - yStart = core::ceil32( b->Pos.y ); - yEnd = core::ceil32( c->Pos.y ) - 1; + yStart = core::ceil32_fast( b->Pos.y ); + yEnd = core::ceil32_fast( c->Pos.y ) - 1; #ifdef SUBTEXEL diff --git a/source/Irrlicht/CTRTextureGouraudVertexAlpha2.cpp b/source/Irrlicht/CTRTextureGouraudVertexAlpha2.cpp index 65e24b2a..8da8e872 100644 --- a/source/Irrlicht/CTRTextureGouraudVertexAlpha2.cpp +++ b/source/Irrlicht/CTRTextureGouraudVertexAlpha2.cpp @@ -136,8 +136,8 @@ void CTRTextureVertexAlpha2::scanline_bilinear ( ) #endif // apply top-left fill-convention, left - xStart = core::ceil32( line.x[0] ); - xEnd = core::ceil32( line.x[1] ) - 1; + xStart = core::ceil32_fast( line.x[0] ); + xEnd = core::ceil32_fast( line.x[1] ) - 1; dx = xEnd - xStart; @@ -384,8 +384,8 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex * #endif // apply top-left fill convention, top part - yStart = core::ceil32( a->Pos.y ); - yEnd = core::ceil32( b->Pos.y ) - 1; + yStart = core::ceil32_fast( a->Pos.y ); + yEnd = core::ceil32_fast( b->Pos.y ) - 1; #ifdef SUBTEXEL subPixel = ( (f32) yStart ) - a->Pos.y; @@ -543,8 +543,8 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex * #endif // apply top-left fill convention, top part - yStart = core::ceil32( b->Pos.y ); - yEnd = core::ceil32( c->Pos.y ) - 1; + yStart = core::ceil32_fast( b->Pos.y ); + yEnd = core::ceil32_fast( c->Pos.y ) - 1; #ifdef SUBTEXEL diff --git a/source/Irrlicht/CTRTextureLightMap2_Add.cpp b/source/Irrlicht/CTRTextureLightMap2_Add.cpp index 2aaa9f9b..db49d530 100644 --- a/source/Irrlicht/CTRTextureLightMap2_Add.cpp +++ b/source/Irrlicht/CTRTextureLightMap2_Add.cpp @@ -137,8 +137,8 @@ REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear () #endif // apply top-left fill-convention, left - xStart = core::ceil32( line.x[0] ); - xEnd = core::ceil32( line.x[1] ) - 1; + xStart = core::ceil32_fast( line.x[0] ); + xEnd = core::ceil32_fast( line.x[1] ) - 1; dx = xEnd - xStart; @@ -365,8 +365,8 @@ void CTRTextureLightMap2_Add::drawTriangle ( const s4DVertex *a,const s4DVertex #endif // apply top-left fill convention, top part - yStart = core::ceil32( a->Pos.y ); - yEnd = core::ceil32( b->Pos.y ) - 1; + yStart = core::ceil32_fast( a->Pos.y ); + yEnd = core::ceil32_fast( b->Pos.y ) - 1; #ifdef SUBTEXEL subPixel = ( (f32) yStart ) - a->Pos.y; @@ -524,8 +524,8 @@ void CTRTextureLightMap2_Add::drawTriangle ( const s4DVertex *a,const s4DVertex #endif // apply top-left fill convention, top part - yStart = core::ceil32( b->Pos.y ); - yEnd = core::ceil32( c->Pos.y ) - 1; + yStart = core::ceil32_fast( b->Pos.y ); + yEnd = core::ceil32_fast( c->Pos.y ) - 1; #ifdef SUBTEXEL diff --git a/source/Irrlicht/CTRTextureLightMap2_M1.cpp b/source/Irrlicht/CTRTextureLightMap2_M1.cpp index b5d741b5..71952749 100644 --- a/source/Irrlicht/CTRTextureLightMap2_M1.cpp +++ b/source/Irrlicht/CTRTextureLightMap2_M1.cpp @@ -115,8 +115,8 @@ REALINLINE void CTRTextureLightMap2_M1::scanline_bilinear2 () // apply top-left fill-convention, left - xStart = core::ceil32( line.x[0] ); - xEnd = core::ceil32( line.x[1] ) - 1; + xStart = core::ceil32_fast( line.x[0] ); + xEnd = core::ceil32_fast( line.x[1] ) - 1; dx = xEnd - xStart; if ( dx < 0 ) @@ -345,8 +345,8 @@ void CTRTextureLightMap2_M1::drawTriangle ( const s4DVertex *a,const s4DVertex * #endif // apply top-left fill convention, top part - yStart = core::ceil32( a->Pos.y ); - yEnd = core::ceil32( b->Pos.y ) - 1; + yStart = core::ceil32_fast( a->Pos.y ); + yEnd = core::ceil32_fast( b->Pos.y ) - 1; #ifdef SUBTEXEL subPixel = ( (f32) yStart ) - a->Pos.y; @@ -505,8 +505,8 @@ void CTRTextureLightMap2_M1::drawTriangle ( const s4DVertex *a,const s4DVertex * #endif // apply top-left fill convention, top part - yStart = core::ceil32( b->Pos.y ); - yEnd = core::ceil32( c->Pos.y ) - 1; + yStart = core::ceil32_fast( b->Pos.y ); + yEnd = core::ceil32_fast( c->Pos.y ) - 1; #ifdef SUBTEXEL diff --git a/source/Irrlicht/CTRTextureLightMap2_M2.cpp b/source/Irrlicht/CTRTextureLightMap2_M2.cpp index f2bc7d4e..f748990b 100644 --- a/source/Irrlicht/CTRTextureLightMap2_M2.cpp +++ b/source/Irrlicht/CTRTextureLightMap2_M2.cpp @@ -115,8 +115,8 @@ REALINLINE void CTRTextureLightMap2_M2::scanline_bilinear2 () // apply top-left fill-convention, left - xStart = core::ceil32( line.x[0] ); - xEnd = core::ceil32( line.x[1] ) - 1; + xStart = core::ceil32_fast( line.x[0] ); + xEnd = core::ceil32_fast( line.x[1] ) - 1; dx = xEnd - xStart; if ( dx < 0 ) @@ -345,8 +345,8 @@ void CTRTextureLightMap2_M2::drawTriangle ( const s4DVertex *a,const s4DVertex * #endif // apply top-left fill convention, top part - yStart = core::ceil32( a->Pos.y ); - yEnd = core::ceil32( b->Pos.y ) - 1; + yStart = core::ceil32_fast( a->Pos.y ); + yEnd = core::ceil32_fast( b->Pos.y ) - 1; #ifdef SUBTEXEL subPixel = ( (f32) yStart ) - a->Pos.y; @@ -505,8 +505,8 @@ void CTRTextureLightMap2_M2::drawTriangle ( const s4DVertex *a,const s4DVertex * #endif // apply top-left fill convention, top part - yStart = core::ceil32( b->Pos.y ); - yEnd = core::ceil32( c->Pos.y ) - 1; + yStart = core::ceil32_fast( b->Pos.y ); + yEnd = core::ceil32_fast( c->Pos.y ) - 1; #ifdef SUBTEXEL diff --git a/source/Irrlicht/CTRTextureLightMap2_M4.cpp b/source/Irrlicht/CTRTextureLightMap2_M4.cpp index c98f7cc7..3fd726cf 100644 --- a/source/Irrlicht/CTRTextureLightMap2_M4.cpp +++ b/source/Irrlicht/CTRTextureLightMap2_M4.cpp @@ -115,8 +115,8 @@ REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_mag () fp24 *z; // apply top-left fill-convention, left - const s32 xStart = irr::core::ceil32( line.x[0] ); - const s32 xEnd = irr::core::ceil32( line.x[1] ) - 1; + const s32 xStart = irr::core::ceil32_fast( line.x[0] ); + const s32 xEnd = irr::core::ceil32_fast( line.x[1] ) - 1; s32 dx; s32 i; @@ -260,8 +260,8 @@ REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_min () // apply top-left fill-convention, left - xStart = core::ceil32( line.x[0] ); - xEnd = core::ceil32( line.x[1] ) - 1; + xStart = core::ceil32_fast( line.x[0] ); + xEnd = core::ceil32_fast( line.x[1] ) - 1; dx = xEnd - xStart; if ( dx < 0 ) @@ -481,8 +481,8 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex *a,const s4DVert #endif // apply top-left fill convention, top part - yStart = core::ceil32( a->Pos.y ); - yEnd = core::ceil32( b->Pos.y ) - 1; + yStart = core::ceil32_fast( a->Pos.y ); + yEnd = core::ceil32_fast( b->Pos.y ) - 1; #ifdef SUBTEXEL subPixel = ( (f32) yStart ) - a->Pos.y; @@ -641,8 +641,8 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex *a,const s4DVert #endif // apply top-left fill convention, top part - yStart = core::ceil32( b->Pos.y ); - yEnd = core::ceil32( c->Pos.y ) - 1; + yStart = core::ceil32_fast( b->Pos.y ); + yEnd = core::ceil32_fast( c->Pos.y ) - 1; #ifdef SUBTEXEL @@ -855,8 +855,8 @@ void CTRTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex * #endif // apply top-left fill convention, top part - yStart = core::ceil32( a->Pos.y ); - yEnd = core::ceil32( b->Pos.y ) - 1; + yStart = core::ceil32_fast( a->Pos.y ); + yEnd = core::ceil32_fast( b->Pos.y ) - 1; #ifdef SUBTEXEL subPixel = ( (f32) yStart ) - a->Pos.y; @@ -1015,8 +1015,8 @@ void CTRTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex * #endif // apply top-left fill convention, top part - yStart = core::ceil32( b->Pos.y ); - yEnd = core::ceil32( c->Pos.y ) - 1; + yStart = core::ceil32_fast( b->Pos.y ); + yEnd = core::ceil32_fast( c->Pos.y ) - 1; #ifdef SUBTEXEL diff --git a/source/Irrlicht/CTRTextureLightMapGouraud2_M4.cpp b/source/Irrlicht/CTRTextureLightMapGouraud2_M4.cpp index 742de513..64a14ab4 100644 --- a/source/Irrlicht/CTRTextureLightMapGouraud2_M4.cpp +++ b/source/Irrlicht/CTRTextureLightMapGouraud2_M4.cpp @@ -137,8 +137,8 @@ void CTRGTextureLightMap2_M4::scanline_bilinear () #endif // apply top-left fill-convention, left - xStart = core::ceil32( line.x[0] ); - xEnd = core::ceil32( line.x[1] ) - 1; + xStart = core::ceil32_fast( line.x[0] ); + xEnd = core::ceil32_fast( line.x[1] ) - 1; dx = xEnd - xStart; @@ -379,8 +379,8 @@ void CTRGTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex #endif // apply top-left fill convention, top part - yStart = core::ceil32( a->Pos.y ); - yEnd = core::ceil32( b->Pos.y ) - 1; + yStart = core::ceil32_fast( a->Pos.y ); + yEnd = core::ceil32_fast( b->Pos.y ) - 1; #ifdef SUBTEXEL subPixel = ( (f32) yStart ) - a->Pos.y; @@ -540,8 +540,8 @@ void CTRGTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex #endif // apply top-left fill convention, top part - yStart = core::ceil32( b->Pos.y ); - yEnd = core::ceil32( c->Pos.y ) - 1; + yStart = core::ceil32_fast( b->Pos.y ); + yEnd = core::ceil32_fast( c->Pos.y ) - 1; #ifdef SUBTEXEL diff --git a/source/Irrlicht/CTextSceneNode.cpp b/source/Irrlicht/CTextSceneNode.cpp index 5f17418b..131c9184 100644 --- a/source/Irrlicht/CTextSceneNode.cpp +++ b/source/Irrlicht/CTextSceneNode.cpp @@ -134,7 +134,7 @@ CBillboardTextSceneNode::CBillboardTextSceneNode(ISceneNode* parent, ISceneManag Material.BackfaceCulling = false; Material.Lighting = false; Material.ZBuffer = video::ECFN_LESSEQUAL; - Material.ZWriteEnable = false; + Material.ZWriteEnable = video::EZW_OFF; if (font) { diff --git a/source/Irrlicht/CTriangleBBSelector.cpp b/source/Irrlicht/CTriangleBBSelector.cpp index d752a044..b30f04e1 100644 --- a/source/Irrlicht/CTriangleBBSelector.cpp +++ b/source/Irrlicht/CTriangleBBSelector.cpp @@ -59,6 +59,7 @@ void CTriangleBBSelector::fillTriangles() const { // construct triangles const core::aabbox3d& box = SceneNode->getBoundingBox(); + BoundingBox = box; core::vector3df edges[8]; box.getEdges(edges); diff --git a/source/Irrlicht/IBurningShader.h b/source/Irrlicht/IBurningShader.h index 8e734ac3..0fffff7c 100644 --- a/source/Irrlicht/IBurningShader.h +++ b/source/Irrlicht/IBurningShader.h @@ -8,6 +8,7 @@ #include "SoftwareDriver2_compile_config.h" #include "IReferenceCounted.h" #include "irrMath.h" +#include "irrMathFastCompat.h" #include "IImage.h" #include "S2DVertex.h" #include "rect.h" diff --git a/source/Irrlicht/Octree.h b/source/Irrlicht/Octree.h index 9746f05d..e9c092b8 100644 --- a/source/Irrlicht/Octree.h +++ b/source/Irrlicht/Octree.h @@ -28,6 +28,13 @@ class Octree { public: + // TODO: Using reference counted class on the stack. + // Reason is likely that it really costs speed here otherwise. + // But doing so prevents using VBO's with octrees. + // Also it's just a bad idea, for example this is the reason + // we can't make the copy-constructor private for IReferenceCounted. + // So would be nice to figure out how to put this on heap (and check + // if it's maybe cheap enough) or maybe stop using CMeshBuffer here. struct SMeshChunk : public scene::CMeshBuffer { SMeshChunk () diff --git a/source/Irrlicht/S4DVertex.h b/source/Irrlicht/S4DVertex.h index b0f0436a..7ad6b83d 100644 --- a/source/Irrlicht/S4DVertex.h +++ b/source/Irrlicht/S4DVertex.h @@ -88,10 +88,10 @@ struct sCompressedVec4 void setColorf ( const video::SColorf & color ) { - argb = core::floor32 ( color.a * 255.f ) << 24 | - core::floor32 ( color.r * 255.f ) << 16 | - core::floor32 ( color.g * 255.f ) << 8 | - core::floor32 ( color.b * 255.f ); + argb = core::floor32_fast( color.a * 255.f ) << 24 | + core::floor32_fast( color.r * 255.f ) << 16 | + core::floor32_fast( color.g * 255.f ) << 8 | + core::floor32_fast( color.b * 255.f ); } void setVec4 ( const sVec4 & v ); @@ -99,7 +99,7 @@ struct sCompressedVec4 // f = a * t + b * ( 1 - t ) void interpolate(const sCompressedVec4& a, const sCompressedVec4& b, const f32 t) { - argb = PixelBlend32 ( b.argb, a.argb, core::floor32 ( t * 256.f ) ); + argb = PixelBlend32 ( b.argb, a.argb, core::floor32_fast( t * 256.f ) ); } @@ -390,10 +390,10 @@ struct sVec3 inline void sCompressedVec4::setVec4 ( const sVec4 & v ) { - argb = core::floor32 ( v.x * 255.f ) << 24 | - core::floor32 ( v.y * 255.f ) << 16 | - core::floor32 ( v.z * 255.f ) << 8 | - core::floor32 ( v.w * 255.f ); + argb = core::floor32_fast( v.x * 255.f ) << 24 | + core::floor32_fast( v.y * 255.f ) << 16 | + core::floor32_fast( v.z * 255.f ) << 8 | + core::floor32_fast( v.w * 255.f ); } diff --git a/source/Irrlicht/SoftwareDriver2_helper.h b/source/Irrlicht/SoftwareDriver2_helper.h index 7a300da3..01e2f4f7 100644 --- a/source/Irrlicht/SoftwareDriver2_helper.h +++ b/source/Irrlicht/SoftwareDriver2_helper.h @@ -12,6 +12,7 @@ #include "SoftwareDriver2_compile_config.h" #include "irrMath.h" +#include "irrMathFastCompat.h" #include "CSoftwareTexture2.h" #include "SMaterial.h" diff --git a/source/Irrlicht/irrMathFastCompat.h b/source/Irrlicht/irrMathFastCompat.h new file mode 100644 index 00000000..19ce1ed6 --- /dev/null +++ b/source/Irrlicht/irrMathFastCompat.h @@ -0,0 +1,126 @@ +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef __IRR_FAST_MATH_COMPAT_H_INCLUDED__ +#define __IRR_FAST_MATH_COMPAT_H_INCLUDED__ + +#include "irrMath.h" + +namespace irr +{ +namespace core +{ + + +// IRRLICHT_FAST_MATH functions which I wanted to kick out because they return +// wrong results. But last time I proposed that I've been asked to keep them for +// Burnings software renderer. So to avoid changing that accidentally or messing up +// it's speed I'll keep them around, but only as internal header. +// They should not be used otherwise any longer. + + // Some examples for unexpected results when using this with IRRLICHT_FAST_MATH: + // Input 1, expected 1, got 0 + // Input 3, expected 3, got 2 + // Input -1.40129846e-45, expected -1, got 0 + REALINLINE s32 floor32_fast(f32 x) + { +#ifdef IRRLICHT_FAST_MATH + const f32 h = 0.5f; + + s32 t; + +#if defined(_MSC_VER) && !defined(_WIN64) + __asm + { + fld x + fsub h + fistp t + } +#elif defined(__GNUC__) + __asm__ __volatile__ ( + "fsub %2 \n\t" + "fistpl %0" + : "=m" (t) + : "t" (x), "f" (h) + : "st" + ); +#else + return (s32) floorf ( x ); +#endif + return t; +#else // no fast math + return (s32) floorf ( x ); +#endif + } + + // Some examples for unexpected results when using this with IRRLICHT_FAST_MATH: + // Input 1.40129846e-45, expected 1, got 0 + // Input -1, expected -1, got 0 + // Input -3, expected -3, got -2 + REALINLINE s32 ceil32_fast ( f32 x ) + { +#ifdef IRRLICHT_FAST_MATH + const f32 h = 0.5f; + + s32 t; + +#if defined(_MSC_VER) && !defined(_WIN64) + __asm + { + fld x + fadd h + fistp t + } +#elif defined(__GNUC__) + __asm__ __volatile__ ( + "fadd %2 \n\t" + "fistpl %0 \n\t" + : "=m"(t) + : "t"(x), "f"(h) + : "st" + ); +#else + return (s32) ceilf ( x ); +#endif + return t; +#else // not fast math + return (s32) ceilf ( x ); +#endif + } + + // Some examples for unexpected results when using this with IRRLICHT_FAST_MATH: + // Input 0.5, expected 1, got 0 + // Input 2.5, expected 3, got 2 + // Input -1.40129846e-45, expected -nan(ind), got -inf + // Input -2.80259693e-45, expected -nan(ind), got -inf + REALINLINE s32 round32_fast(f32 x) + { +#if defined(IRRLICHT_FAST_MATH) + s32 t; + +#if defined(_MSC_VER) && !defined(_WIN64) + __asm + { + fld x + fistp t + } +#elif defined(__GNUC__) + __asm__ __volatile__ ( + "fistpl %0 \n\t" + : "=m"(t) + : "t"(x) + : "st" + ); +#else + return (s32) round_(x); +#endif + return t; +#else // no fast math + return (s32) round_(x); +#endif + } + +} // end namespace core +} // end namespace irr + +#endif // __IRR_FAST_MATH_COMPAT_H_INCLUDED__ diff --git a/tests/irrString.cpp b/tests/irrString.cpp index ad35e89d..a5298ff6 100644 --- a/tests/irrString.cpp +++ b/tests/irrString.cpp @@ -20,9 +20,9 @@ static bool testSplit() core::stringw teststring(L"[b]this [/b] is a [color=0xff000000]test[/color]."); core::list parts1; teststring.split >(parts1, L"["); - core::list parts2; - teststring.split >(parts2, L"[", 1, false, true); - return (parts1.getSize()==4) && (parts2.getSize()==5); + core::array parts2; + teststring.split >(parts2, L"[", 1, false, true); + return (parts1.size()==4) && (parts2.size()==9); } static bool testFastAlloc() diff --git a/tests/main.cpp b/tests/main.cpp index 0f604a72..6becc7c3 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -49,7 +49,7 @@ int main(int argumentCount, char * arguments[]) #if 0 // To interactively debug a test, move it (temporarily) in here and enable the define to only run this test // Otherwise debugging is slightly tricky as each test runs in it's own process. - TEST(stencilShadow); + TEST(ioScene); #else TEST(disambiguateTextures); // Normally you should run this first, since it validates the working directory. diff --git a/tests/media/Burning's Video-orthoCam.png b/tests/media/Burning's Video-orthoCam.png index 15fa5b04..5e35ddde 100644 Binary files a/tests/media/Burning's Video-orthoCam.png and b/tests/media/Burning's Video-orthoCam.png differ diff --git a/tests/media/Burning's Video-testGeometryCreator.png b/tests/media/Burning's Video-testGeometryCreator.png index b5370518..5ea41667 100644 Binary files a/tests/media/Burning's Video-testGeometryCreator.png and b/tests/media/Burning's Video-testGeometryCreator.png differ diff --git a/tests/media/Direct3D 9.0-transparentReflection2Layer.png b/tests/media/Direct3D 9.0-transparentReflection2Layer.png index ed1b45d3..12baed71 100644 Binary files a/tests/media/Direct3D 9.0-transparentReflection2Layer.png and b/tests/media/Direct3D 9.0-transparentReflection2Layer.png differ diff --git a/tests/media/OpenGL-orthoCam.png b/tests/media/OpenGL-orthoCam.png index d1fa7f3a..fa7b8b04 100644 Binary files a/tests/media/OpenGL-orthoCam.png and b/tests/media/OpenGL-orthoCam.png differ diff --git a/tests/media/scene.irr b/tests/media/scene.irr index 9efe6ca6..244913b2 100644 Binary files a/tests/media/scene.irr and b/tests/media/scene.irr differ diff --git a/tests/media/scene2.irr b/tests/media/scene2.irr index 3847048a..49ff185e 100644 Binary files a/tests/media/scene2.irr and b/tests/media/scene2.irr differ diff --git a/tests/projectionMatrix.cpp b/tests/projectionMatrix.cpp index 0bdeaaf6..439d8e82 100644 --- a/tests/projectionMatrix.cpp +++ b/tests/projectionMatrix.cpp @@ -31,7 +31,7 @@ static bool runTestWithDriver(E_DRIVER_TYPE driverType) mat.MaterialType = EMT_SOLID; mat.Lighting = false; mat.ZBuffer = false; - mat.ZWriteEnable = false; + mat.ZWriteEnable = video::EZW_OFF; mat.Thickness = 1; driver->setMaterial(mat); diff --git a/tests/sceneCollisionManager.cpp b/tests/sceneCollisionManager.cpp index b75ae75e..93bccf00 100644 --- a/tests/sceneCollisionManager.cpp +++ b/tests/sceneCollisionManager.cpp @@ -154,7 +154,7 @@ static bool testGetSceneNodeFromScreenCoordinatesBB(IrrlichtDevice * device, IMeshSceneNode * cubeNode3 = smgr->addCubeSceneNode(10.f, 0, -1, vector3df(0, 0, 40)); cubeNode3->setRotation(vector3df(180.f, 180.f, 180.f)); // Just check that rotation doesn't stop us hitting it. - ICameraSceneNode * camera = smgr->addCameraSceneNode(); + smgr->addCameraSceneNode(); device->run(); smgr->drawAll(); // Get the camera in a good state diff --git a/tests/testGeometryCreator.cpp b/tests/testGeometryCreator.cpp index 9be0e33b..cbf48ddb 100644 --- a/tests/testGeometryCreator.cpp +++ b/tests/testGeometryCreator.cpp @@ -28,7 +28,7 @@ bool testGeometryCreator(void) material.Lighting = false; material.TextureLayer[0].Texture = wall; - irr::scene::IMesh * meshHill = geom->createHillPlaneMesh(dimension2df(10, 5), dimension2du(5, 5), + irr::scene::IMesh * meshHill = geom->createHillPlaneMesh(dimension2df(10, 5), dimension2du(5, 5), &material, 10, dimension2df(2, 2), dimension2df(3, 3) ); IMeshSceneNode * node = smgr->addMeshSceneNode(meshHill, 0, -1, vector3df(0, 10, 0), vector3df(-60, 0, 0)); @@ -116,7 +116,7 @@ bool testGeometryCreator(void) // This screenshot shows some mipmap problems, but this seems to be // no fault of the mesh - result = takeScreenshotAndCompareAgainstReference(driver, "-testTerrainMesh.png", 99.989f); + result &= takeScreenshotAndCompareAgainstReference(driver, "-testTerrainMesh.png", 99.989f); device->closeDevice(); device->run(); diff --git a/tests/testQuaternion.cpp b/tests/testQuaternion.cpp index dc04d305..b54f0c88 100644 --- a/tests/testQuaternion.cpp +++ b/tests/testQuaternion.cpp @@ -18,7 +18,7 @@ inline bool compareQ(const core::vector3df& v, const core::vector3df& turn=core: logTestString("Inequality before quat.toEuler(): %f,%f,%f\n", v.X,v.Y,v.Z); return false; } - + q.toEuler(v2); v2*=core::RADTODEG; v2=v2.rotationToDirection(turn); @@ -110,7 +110,7 @@ bool testQuatEulerMatrix() core::vector3df v6 = mat.getRotationDegrees()*core::DEGTORAD; // make sure comparison matrix is correct result &= v4.equals(v6); - + core::matrix4 mat2 = q1.getMatrix(); result &= mat.equals(mat2, 0.0005f); @@ -205,6 +205,7 @@ bool testInterpolation() { bool result=true; core::quaternion q(1.f,2.f,3.f,4.f); + q.normalize(); core::quaternion q2; q2.lerp(q,q,0); if (q != q2) diff --git a/tests/tests-last-passed-at.txt b/tests/tests-last-passed-at.txt index 4755cf20..1034815d 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 Tue Nov 26 13:57:09 2019 - +Tests finished. 72 tests of 72 passed. +Compiled as DEBUG +Test suite pass at GMT Fri Jan 3 17:05:41 2020 + diff --git a/tests/textureFeatures.cpp b/tests/textureFeatures.cpp index b0f12e42..9ce787df 100644 --- a/tests/textureFeatures.cpp +++ b/tests/textureFeatures.cpp @@ -29,7 +29,7 @@ bool renderMipLevels(video::E_DRIVER_TYPE driverType) driver->setTextureCreationFlag(video::ETCF_AUTO_GENERATE_MIP_MAPS, false); stabilizeScreenBackground(driver); - + logTestString("Testing driver %ls\n", driver->getName()); scene::ISceneNode* n = smgr->addCubeSceneNode(); @@ -55,7 +55,7 @@ bool renderMipLevels(video::E_DRIVER_TYPE driverType) mipdata[index++]=val; } } - + image->setMipMapsData(mipdata, false, true); video::ITexture* tex = driver->addTexture("miptest", image); if (!tex) @@ -422,9 +422,6 @@ bool lockCubemapTexture(video::E_DRIVER_TYPE driverType) result = false; break; } - u32 b0 = bits[0].color; - u32 b2 = bits[2].color; - result &= ((bits[0].color == 0xff00ff00) && (bits[2].color == 0xff0000fd)); tex->unlock(); }