Help! Direct3D9 renderer affecting equals operator

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
wolfpack
Posts: 4
Joined: Sat Feb 10, 2007 10:11 am

Help! Direct3D9 renderer affecting equals operator

Post by wolfpack »

I'm sure there is something I'm doing wrong here, but for some reason comparing vector3dfs seems to return different results depending on whether I use the Direct3D renderer or OpenGL. I wrote a test program that isolates the problem. Can someone please tell me if this has the same behavior on their computer? Change the #if 1 to #if 0 to switch from the Direct3D renderer to OpenGL.

On my computer, OpenGL passes the test, but Direct3D fails. I'm running Windows XP SP2, with all the current updates and my graphics chipset is the mobile Intel 915GM onboard graphics accelerator, with the latest driver, although I don't understand why my graphics driver or choice of renderer would affect the result of vector3d.equals(). This behavior is consistent in both Irrlicht 1.3.1 and 1.3.

Thanks for any help/data anyone can provide!

Test code:

Code: Select all

#include <irrlicht.h>

irr::IrrlichtDevice* device = 0;

#define NULL_VECTOR irr::core::vector3df(-99999,-99999,-99999)

int main (int argc, char * const argv[]) {

#if 1
   irr::video::E_DRIVER_TYPE driverType = irr::video::EDT_DIRECT3D9;
#else
   irr::video::E_DRIVER_TYPE driverType = irr::video::EDT_OPENGL;
#endif


   device = irr::createDevice(driverType, irr::core::dimension2d<irr::s32>(640, 480),
			      16, false, false, false, NULL);
   if (device == 0)
      return -1;

   bool equal = NULL_VECTOR.equals(NULL_VECTOR);

   printf("Test\t\t[%s]\n", equal ? "PASSED" : "FAILED");

   return 0;
}
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

The D3D device will set the FPU to low precision by default [look here]. You can change this behavior if you use createDeviceEx() and set the HighPrecisionFPU flag on the SIrrlichtCreationParameters structure.

Travis
wolfpack
Posts: 4
Joined: Sat Feb 10, 2007 10:11 am

Post by wolfpack »

Thanks so much, that did it. It still makes me wonder why .equals() uses > and < comparison, instead of >= and <=, given that this tolerance issue exists, for D3D at least.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

Yup, you are right. You should be okay as long as the tolerance you provide is sufficient. If the tolerance is 0.f, the results will be wrong.

Code: Select all

//! returns if a float equals the other one, taking floating
//! point rounding errors into account
inline bool equals(const f32 a, const f32 b, const f32 tolerance = ROUNDING_ERROR_32)
{
   return (a + tolerance > b) && (a - tolerance < b);
}
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

From glancing at irrMath.h, I'm not sure why ROUNDING_ERROR_32 / ROUNDING_ERROR_64 aren't defined as FLT_EPSILON and DLB_EPSILON, nor what's "faster" about using a larger rounding tolerance. What's up with that?
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Post Reply