Merging r5975 through r6036 from trunk to ogl-es branch.
GLES drivers adapted, but only did make compile-tests. git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@6038 dfc29bdd-3216-0410-991c-e03cc46cb475master
parent
f2600bfd99
commit
b42fbc5ab1
29
changes.txt
29
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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<s32> 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<s32> 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<IGUITabControl*>(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
|
||||
|
|
|
@ -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.
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<MATERIAL_MAX_TEXTURES_USED) && !different; ++i)
|
||||
{
|
||||
|
@ -772,14 +786,9 @@ namespace video
|
|||
inline bool operator==(const SMaterial& b) const
|
||||
{ return !(b!=*this); }
|
||||
|
||||
bool isTransparent() const
|
||||
//! Check if material needs alpha blending
|
||||
bool isAlphaBlendOperation() const
|
||||
{
|
||||
if ( MaterialType==EMT_TRANSPARENT_ADD_COLOR ||
|
||||
MaterialType==EMT_TRANSPARENT_ALPHA_CHANNEL ||
|
||||
MaterialType==EMT_TRANSPARENT_VERTEX_ALPHA ||
|
||||
MaterialType==EMT_TRANSPARENT_REFLECTION_2_LAYER )
|
||||
return true;
|
||||
|
||||
if (BlendOperation != EBO_NONE && BlendFactor != 0.f)
|
||||
{
|
||||
E_BLEND_FACTOR srcRGBFact = EBF_ZERO;
|
||||
|
@ -797,6 +806,19 @@ namespace video
|
|||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//! Check for some fixed-function transparent types. Still used internally, but might be deprecated soon.
|
||||
//! You probably should not use this anymore, IVideoDriver::needsTransparentRenderPass is more useful in most situations
|
||||
//! as it asks the material renders directly what they do with the material.
|
||||
bool isTransparent() const
|
||||
{
|
||||
if ( MaterialType==EMT_TRANSPARENT_ADD_COLOR ||
|
||||
MaterialType==EMT_TRANSPARENT_ALPHA_CHANNEL ||
|
||||
MaterialType==EMT_TRANSPARENT_VERTEX_ALPHA ||
|
||||
MaterialType==EMT_TRANSPARENT_REFLECTION_2_LAYER )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -262,6 +262,20 @@ namespace scene
|
|||
core::matrix4 Transformation;
|
||||
};
|
||||
|
||||
//! Vertex manipulator which transforms the normal of the vertex
|
||||
class SVertexNormalTransformManipulator : public IVertexManipulator
|
||||
{
|
||||
public:
|
||||
SVertexNormalTransformManipulator(const core::matrix4& m) : Transformation(m) {}
|
||||
template <typename VType>
|
||||
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
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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<T,TAlloc>(&array[tokenStartIdx], i - tokenStartIdx));
|
||||
else if ( !ignoreEmptyTokens )
|
||||
ret.push_back(string<T,TAlloc>());
|
||||
if ( keepSeparators )
|
||||
{
|
||||
ret.push_back(string<T,TAlloc>(&array[tokenStartIdx], i+1 - tokenStartIdx));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i - tokenStartIdx > 0)
|
||||
ret.push_back(string<T,TAlloc>(&array[tokenStartIdx], i - tokenStartIdx));
|
||||
else if ( !ignoreEmptyTokens )
|
||||
ret.push_back(string<T,TAlloc>());
|
||||
ret.push_back(string<T,TAlloc>(&array[i], 1));
|
||||
}
|
||||
|
||||
tokenStartIdx = i+1;
|
||||
break;
|
||||
}
|
||||
|
@ -1418,6 +1417,8 @@ public:
|
|||
}
|
||||
if ((used - 1) > tokenStartIdx)
|
||||
ret.push_back(string<T,TAlloc>(&array[tokenStartIdx], (used - 1) - tokenStartIdx));
|
||||
else if ( !ignoreEmptyTokens )
|
||||
ret.push_back(string<T,TAlloc>());
|
||||
|
||||
return ret.size()-oldSize;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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; i<Materials.size(); ++i)
|
||||
const u32 numMaterials = ReadOnlyMaterials ? Mesh->getMeshBufferCount() : Materials.size();
|
||||
for (u32 i=0; i<numMaterials; ++i)
|
||||
{
|
||||
video::IMaterialRenderer* rnd =
|
||||
driver->getMaterialRenderer(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; i<m->getMeshBufferCount(); ++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<f32>& 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())
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -818,8 +818,10 @@ void CColorConverter::convert_viaFormat(const void* sP, ECOLOR_FORMAT sF, s32 sN
|
|||
break;
|
||||
}
|
||||
break;
|
||||
#ifndef _DEBUG
|
||||
default:
|
||||
break;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -1331,7 +1331,7 @@ IGUITabControl* CGUIEnvironment::addTabControl(const core::rect<s32>& rectangle,
|
|||
IGUITab* CGUIEnvironment::addTab(const core::rect<s32>& 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;
|
||||
|
|
|
@ -81,7 +81,7 @@ void CGUIImage::draw()
|
|||
core::rect<s32> sourceRect(SourceRect);
|
||||
if (sourceRect.getWidth() == 0 || sourceRect.getHeight() == 0)
|
||||
{
|
||||
sourceRect = core::rect<s32>(core::dimension2di(Texture->getSize()));
|
||||
sourceRect = core::rect<s32>(core::dimension2di(Texture->getOriginalSize()));
|
||||
}
|
||||
|
||||
if (ScaleImage)
|
||||
|
|
|
@ -23,10 +23,10 @@ namespace gui
|
|||
// ------------------------------------------------------------------
|
||||
|
||||
//! constructor
|
||||
CGUITab::CGUITab(s32 number, IGUIEnvironment* environment,
|
||||
CGUITab::CGUITab(IGUIEnvironment* environment,
|
||||
IGUIElement* parent, const core::rect<s32>& 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<IGUITabControl*>(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<IGUITabControl*>(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<s32>& 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; i<Tabs.size(); ++i)
|
||||
{
|
||||
if (Tabs[i])
|
||||
{
|
||||
IGUIElement::removeChild(Tabs[i]);
|
||||
Tabs[i]->drop();
|
||||
}
|
||||
}
|
||||
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(); ++i)
|
||||
|
@ -625,7 +673,7 @@ void CGUITabControl::draw()
|
|||
|
||||
pos += len;
|
||||
|
||||
if ((s32)i == ActiveTab)
|
||||
if ((s32)i == ActiveTabIndex)
|
||||
{
|
||||
// for active button just remember values
|
||||
left = frameRect.UpperLeftCorner.X;
|
||||
|
@ -913,7 +961,7 @@ s32 CGUITabControl::getTabAt(s32 xpos, s32 ypos) const
|
|||
//! Returns which tab is currently active
|
||||
s32 CGUITabControl::getActiveTab() const
|
||||
{
|
||||
return ActiveTab;
|
||||
return ActiveTabIndex;
|
||||
}
|
||||
|
||||
|
||||
|
@ -923,15 +971,13 @@ bool CGUITabControl::setActiveTab(s32 idx)
|
|||
if ((u32)idx >= 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; i<Tabs.size(); ++i)
|
||||
if (Tabs[i])
|
||||
Tabs[i]->setVisible( (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; i<Tabs.size(); ++i)
|
||||
if (Tabs[i] == tab)
|
||||
return (s32)i;
|
||||
|
||||
u32 i=0;
|
||||
// check if it is a tab
|
||||
while (i<Tabs.size())
|
||||
{
|
||||
if (Tabs[i] == child)
|
||||
{
|
||||
Tabs[i]->drop();
|
||||
Tabs.erase(i);
|
||||
isTab = true;
|
||||
}
|
||||
else
|
||||
++i;
|
||||
}
|
||||
|
||||
// reassign numbers
|
||||
if (isTab)
|
||||
{
|
||||
for (i=0; i<Tabs.size(); ++i)
|
||||
if (Tabs[i])
|
||||
Tabs[i]->setNumber(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<EGUI_ALIGNMENT>(in->getAttributeAsEnumeration("TabVerticalAlignment" , GUIAlignmentNames)) );
|
||||
}
|
||||
|
||||
|
|
|
@ -25,20 +25,10 @@ namespace gui
|
|||
public:
|
||||
|
||||
//! constructor
|
||||
CGUITab(s32 number, IGUIEnvironment* environment,
|
||||
CGUITab(IGUIEnvironment* environment,
|
||||
IGUIElement* parent, const core::rect<s32>& 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<s32> calcTabPos();
|
||||
void setVisibleTab(s32 idx);
|
||||
void removeTabButNotChild(s32 idx);
|
||||
|
||||
void recalculateScrollButtonPlacement();
|
||||
void recalculateScrollBar();
|
||||
void refreshSprites();
|
||||
|
||||
core::array<CGUITab*> Tabs; // CGUITab* because we need setNumber (which is certainly not nice)
|
||||
s32 ActiveTab;
|
||||
core::array<IGUITab*> Tabs;
|
||||
s32 ActiveTabIndex;
|
||||
bool Border;
|
||||
bool FillBackground;
|
||||
bool ScrollControl;
|
||||
|
|
|
@ -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<IGUIElement*>& children = parent->getChildren();
|
||||
core::list<IGUIElement*>::ConstIterator it = children.begin();
|
||||
for (; it != children.end(); ++it)
|
||||
{
|
||||
core::rect<s32> 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<s32> 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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<height; ++y)
|
||||
{
|
||||
f32 sx = 0.0f;
|
||||
f32 sx = 0.5f; // nearest pixel (used in float-int conversion below)
|
||||
for (u32 x=0; x<width; ++x)
|
||||
{
|
||||
CColorConverter::convert_viaFormat(Data+ syval + ((s32)sx)*BytesPerPixel, Format, 1, ((u8*)target)+ yval + (x*bpp), format);
|
||||
sx+=sourceXStep;
|
||||
}
|
||||
sy+=sourceYStep;
|
||||
syval=((s32)sy)*Pitch;
|
||||
syval=(s32)(sy)*Pitch;
|
||||
yval+=pitch;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -826,6 +826,8 @@ IImage* CImageLoaderDDS::loadImage(io::IReadFile* file) const
|
|||
format = ECF_DXT5;
|
||||
break;
|
||||
}
|
||||
default: // either not compressed or unknown
|
||||
break;
|
||||
}
|
||||
|
||||
if( format != ECF_UNKNOWN )
|
||||
|
|
|
@ -92,7 +92,6 @@ IImage* CImageLoaderPng::loadImage(io::IReadFile* file) const
|
|||
if (!file)
|
||||
return 0;
|
||||
|
||||
video::IImage* image = 0;
|
||||
//Used to point to image rows
|
||||
u8** RowPointers = 0;
|
||||
|
||||
|
@ -222,6 +221,7 @@ IImage* CImageLoaderPng::loadImage(io::IReadFile* file) const
|
|||
}
|
||||
|
||||
// Create the image structure to be filled by png data
|
||||
video::IImage* image = 0;
|
||||
if (ColorType==PNG_COLOR_TYPE_RGB_ALPHA)
|
||||
image = new CImage(ECF_A8R8G8B8, core::dimension2d<u32>(Width, Height));
|
||||
else
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -695,29 +695,22 @@ namespace
|
|||
HWND hWnd;
|
||||
irr::CIrrDeviceWin32* irrDev;
|
||||
};
|
||||
irr::core::list<SEnvMapper> EnvMap;
|
||||
// NOTE: This is global. We can have more than one Irrlicht Device at same time.
|
||||
irr::core::array<SEnvMapper> EnvMap;
|
||||
|
||||
HKL KEYBOARD_INPUT_HKL=0;
|
||||
unsigned int KEYBOARD_INPUT_CODEPAGE = 1252;
|
||||
}
|
||||
|
||||
SEnvMapper* getEnvMapperFromHWnd(HWND hWnd)
|
||||
{
|
||||
irr::core::list<SEnvMapper>::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<SEnvMapper>::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<SEnvMapper>::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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------
|
||||
|
|
|
@ -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; i<numMaterials; ++i)
|
||||
{
|
||||
// count mesh materials
|
||||
const video::SMaterial& material = ReadOnlyMaterials ? Mesh->getMeshBuffer(i)->getMaterial() : Materials[i];
|
||||
|
||||
for (u32 i=0; i<Mesh->getMeshBufferCount(); ++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; i<Materials.size(); ++i)
|
||||
{
|
||||
video::IMaterialRenderer* rnd =
|
||||
driver->getMaterialRenderer(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
|
||||
|
|
|
@ -196,7 +196,7 @@ CNullDriver::CNullDriver(io::IFileSystem* io, const core::dimension2d<u32>& 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<video::MATERIAL_MAX_TEXTURES; ++i)
|
||||
|
@ -319,7 +319,6 @@ void CNullDriver::deleteAllTextures()
|
|||
|
||||
bool CNullDriver::beginScene(u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil, const SExposedVideoData& videoData, core::rect<s32>* 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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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; i<Materials.size(); ++i)
|
||||
{
|
||||
const video::IMaterialRenderer* const rnd =
|
||||
driver->getMaterialRenderer(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
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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")
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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<u32>& size)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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; i<count; ++i)
|
||||
{
|
||||
video::IMaterialRenderer* rnd =
|
||||
Driver->getMaterialRenderer(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)
|
||||
|
|
|
@ -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_;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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<s32> rctDest(core::position2d<s32>(-1,0),
|
||||
core::dimension2di(driver->getCurrentRenderTargetSize()));
|
||||
core::rect<s32> rctSrc(core::position2d<s32>(0,0),
|
||||
core::dimension2di(tex->getSize()));
|
||||
core::dimension2di(tex->getOriginalSize()));
|
||||
|
||||
driver->draw2DImage(tex, rctDest, rctSrc);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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::array<core::vector
|
|||
|
||||
Material.org.MaterialType = video::EMT_SOLID;
|
||||
Material.org.Lighting = false;
|
||||
Material.org.ZWriteEnable = false;
|
||||
Material.org.ZWriteEnable = video::EZW_OFF;
|
||||
Material.org.ZBuffer = ECFN_LESSEQUAL;
|
||||
LightSpace.Flags &= ~VERTEXTRANSFORM;
|
||||
|
||||
|
@ -2382,6 +2382,11 @@ bool CBurningVideoDriver::queryTextureFormat(ECOLOR_FORMAT format) const
|
|||
return format == BURNINGSHADER_COLOR_FORMAT;
|
||||
}
|
||||
|
||||
bool CBurningVideoDriver::needsTransparentRenderPass(const irr::video::SMaterial& material) const
|
||||
{
|
||||
return CNullDriver::needsTransparentRenderPass(material) || material.isTransparent();
|
||||
}
|
||||
|
||||
|
||||
} // end namespace video
|
||||
} // end namespace irr
|
||||
|
|
|
@ -164,6 +164,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_;
|
||||
|
||||
IDepthBuffer * getDepthBuffer () { return DepthBuffer; }
|
||||
IStencilBuffer * getStencilBuffer () { return StencilBuffer; }
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@ CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 fl
|
|||
BURNINGSHADER_COLOR_FORMAT
|
||||
);
|
||||
|
||||
OriginalSize = optSize;
|
||||
os::Printer::log ( buf, ELL_WARNING );
|
||||
MipMap[0] = new CImage(BURNINGSHADER_COLOR_FORMAT, optSize);
|
||||
|
||||
|
|
|
@ -136,8 +136,8 @@ void CTRGouraud2::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;
|
||||
|
||||
|
@ -351,8 +351,8 @@ void CTRGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4D
|
|||
#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;
|
||||
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -59,6 +59,7 @@ void CTriangleBBSelector::fillTriangles() const
|
|||
{
|
||||
// construct triangles
|
||||
const core::aabbox3d<f32>& box = SceneNode->getBoundingBox();
|
||||
BoundingBox = box;
|
||||
core::vector3df edges[8];
|
||||
box.getEdges(edges);
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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<T>
|
||||
{
|
||||
SMeshChunk ()
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "SoftwareDriver2_compile_config.h"
|
||||
#include "irrMath.h"
|
||||
#include "irrMathFastCompat.h"
|
||||
#include "CSoftwareTexture2.h"
|
||||
#include "SMaterial.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__
|
|
@ -20,9 +20,9 @@ static bool testSplit()
|
|||
core::stringw teststring(L"[b]this [/b] is a [color=0xff000000]test[/color].");
|
||||
core::list<core::stringw> parts1;
|
||||
teststring.split<core::list<core::stringw> >(parts1, L"[");
|
||||
core::list<core::stringw> parts2;
|
||||
teststring.split<core::list<core::stringw> >(parts2, L"[", 1, false, true);
|
||||
return (parts1.getSize()==4) && (parts2.getSize()==5);
|
||||
core::array<core::stringw> parts2;
|
||||
teststring.split<core::array<core::stringw> >(parts2, L"[", 1, false, true);
|
||||
return (parts1.size()==4) && (parts2.size()==9);
|
||||
}
|
||||
|
||||
static bool testFastAlloc()
|
||||
|
|
|
@ -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.
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 3.0 KiB |
Binary file not shown.
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 7.4 KiB |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue