Merging r5975 through r6036 from trunk to ogl-es branch.

GLES drivers adapted, but only did make compile-tests.


git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@6038 dfc29bdd-3216-0410-991c-e03cc46cb475
master
cutealien 2020-01-03 19:05:16 +00:00 committed by MoNTE48
parent f2600bfd99
commit b42fbc5ab1
110 changed files with 1040 additions and 721 deletions

View File

@ -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.

View File

@ -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

View File

@ -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 )

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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.
/**

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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
{

View File

@ -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)

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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())

View File

@ -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;

View File

@ -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 );
}
}

View File

@ -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;

View File

@ -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);

View File

@ -818,8 +818,10 @@ void CColorConverter::convert_viaFormat(const void* sP, ECOLOR_FORMAT sF, s32 sN
break;
}
break;
#ifndef _DEBUG
default:
break;
break;
#endif
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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)

View File

@ -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)) );
}

View File

@ -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;

View File

@ -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();
}
}
}

View File

@ -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);

View File

@ -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,

View File

@ -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;
}
}

View File

@ -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 )

View File

@ -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

View File

@ -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
}

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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;
}
}
//---------------------------------------------------

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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_;

View File

@ -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")
{

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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 );

View File

@ -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

View File

@ -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)

View File

@ -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_;

View File

@ -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;

View File

@ -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);
}

View File

@ -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);

View File

@ -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
{

View File

@ -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

View File

@ -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; }

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)
{

View File

@ -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);

View File

@ -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"

View File

@ -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 ()

View File

@ -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 );
}

View File

@ -12,6 +12,7 @@
#include "SoftwareDriver2_compile_config.h"
#include "irrMath.h"
#include "irrMathFastCompat.h"
#include "CSoftwareTexture2.h"
#include "SMaterial.h"

View File

@ -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__

View File

@ -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()

View File

@ -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