IVideoDriver->draw2DRectangleOutline is offset by 1
IVideoDriver->draw2DRectangleOutline is offset by 1
I haven't checked if this has already been fixed in svn but I have noticed that this function draws the rectangle with x and y offset by -1 in the GLES2 driver.
Re: IVideoDriver->draw2DRectangleOutline is offset by 1
Hm, basically it draws 4 lines with the diamond exit rule (you might have to google that one).
I don't have GLES2 set up on the system I'm on right now, so have to do that test later. But I did some quick test-code and at least in other drivers it should includes all pixels in the rect, so rect(0,0,0,0) is one pixel and (0,0,1,1) is 2 pixels.
edit: Which means rect.getWidth() and .getHeight() are indeed wrong in this case. Probably drawing should _not_ include the LowerRightCorner. Is that what you meant?
Gives me:
(blue are the windows borders and you may have to zoom a bit to see how it looks unless your screen is big or your eye-sight is better than mine)
I don't have GLES2 set up on the system I'm on right now, so have to do that test later. But I did some quick test-code and at least in other drivers it should includes all pixels in the rect, so rect(0,0,0,0) is one pixel and (0,0,1,1) is 2 pixels.
edit: Which means rect.getWidth() and .getHeight() are indeed wrong in this case. Probably drawing should _not_ include the LowerRightCorner. Is that what you meant?
Code: Select all
#include <irrlicht.h>
using namespace irr;
#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif
int main(int argc, char *argv[])
{
IrrlichtDevice * Device = createDevice(video::EDT_OPENGL, core::dimension2d<u32>(640,480) );
if (!Device)
return false;
video::IVideoDriver* videoDriver = Device->getVideoDriver();
while ( Device->run() )
{
if ( Device->isWindowActive() )
{
videoDriver->beginScene(true, true);
for ( int i=0; i<10; i+=2)
{
videoDriver->draw2DRectangleOutline( core::recti(i,0,i,9), video::SColor(255, 255, 0, 0));
videoDriver->draw2DRectangleOutline( core::recti(i+1,0,i+1,9), video::SColor(255, 0, 255, 0));
videoDriver->draw2DRectangleOutline( core::recti(0,10+i,9,10+i), video::SColor(255, 255, 0, 0));
videoDriver->draw2DRectangleOutline( core::recti(0,10+i+1,9,10+i+1), video::SColor(255, 0, 255, 0));
}
videoDriver->endScene();
}
Device->yield();
}
Device->closeDevice();
Device->drop();
return 0;
}

IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Re: IVideoDriver->draw2DRectangleOutline is offset by 1
If I want to draw a rect at (0, 0) then I have to draw it at (1,1) in the GLES2 driver. It works correctly for me in the OpenGL driver.
Re: IVideoDriver->draw2DRectangleOutline is offset by 1
Hm, I guess then maybe draw2DLine is also wrong (no driver implements draw2DRectangleOutline, it's just implemented with 4 calls to draw2DLine). I'll have to do some test for that.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Re: IVideoDriver->draw2DRectangleOutline is offset by 1
I can reproduce. Sadly it's not that easy to fix as one might assume. For a start - I only need the X offset here, the Y offset would mess it up on my card.
But even more tricky - sometimes the same values can be fine or broken - depending a bit on what the compiler does (like adding +1 inside the draw2DLine function mostly fails... for whatever reason - but not always).
I guess this is all related to how OpenGL renders fragments. In theory the pixel center is off by 0.5. So this one ends up just on the border right now (which should explain the random results in theory - or so I thought at first). So adding 0.5 instead should be right (to the floats, not to the int obviously). Right? But nope - also messes up. I think because we use GL_LINES which also has the diamond exit rule. Which ends up sometimes with really strange results with first and last pixel in a line being one off in the rectangle. So a rectangle sometimes ends up looking like a bracket.
There is some common trick with offsetting values only by 0.375 (which all other drivers use), but sadly I can't get that to work either so far.
And well - now I'm runnning out of time because x-mas stress already starting and I already spend a whole afternoon which I reallly didn't have *sigh*
So very sorry - no solution so far. Anyone who wants to give it a shot, here's a nice example which easily breaks for any changes:
Some notes: The difference to the other drivers is that they do use 2 matrices here. A model-view which does the 0.375 offsets. And then an orthographic projection which brings it into the -1 to 1 range and flips the Y for OpenGL. While ES2 uses a shader without matrices (way faster...) but expects the values already in the -1 to 1 range then (I think, but maybe that's where I go wrong?). In theory just adding 0.375 should end up with the same calculation as the matrices, but well... I can't get it working so far.
I'll be back on this another time. Sadly I already have 2 other half-finished changes for Irrlicht hanging around and not getting to them currently. So probably earliest when I have some time off after x-mas.
But even more tricky - sometimes the same values can be fine or broken - depending a bit on what the compiler does (like adding +1 inside the draw2DLine function mostly fails... for whatever reason - but not always).
I guess this is all related to how OpenGL renders fragments. In theory the pixel center is off by 0.5. So this one ends up just on the border right now (which should explain the random results in theory - or so I thought at first). So adding 0.5 instead should be right (to the floats, not to the int obviously). Right? But nope - also messes up. I think because we use GL_LINES which also has the diamond exit rule. Which ends up sometimes with really strange results with first and last pixel in a line being one off in the rectangle. So a rectangle sometimes ends up looking like a bracket.
There is some common trick with offsetting values only by 0.375 (which all other drivers use), but sadly I can't get that to work either so far.
And well - now I'm runnning out of time because x-mas stress already starting and I already spend a whole afternoon which I reallly didn't have *sigh*
So very sorry - no solution so far. Anyone who wants to give it a shot, here's a nice example which easily breaks for any changes:
Code: Select all
#include <irrlicht.h>
using namespace irr;
#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif
int main(int argc, char *argv[])
{
core::dimension2d<u32> dim(320,200);
IrrlichtDevice * Device = createDevice(video::EDT_OGLES2, dim);
if (!Device)
return false;
video::IVideoDriver* videoDriver = Device->getVideoDriver();
int offsetX = 0; // just for experimenting
int offsetY = 0;
while ( Device->run() )
{
if ( Device->isWindowActive() )
{
videoDriver->beginScene(true, true);
for ( int i=0; i<dim.Width; i+=4)
{
videoDriver->draw2DRectangleOutline( core::recti(offsetX+i,offsetY+0,offsetX+i,offsetY+9), video::SColor(255, 255, 0, 0));
videoDriver->draw2DRectangleOutline( core::recti(offsetX+i+2,offsetY+0,offsetX+i+2,offsetY+9), video::SColor(255, 0, 255, 0));
}
#if 1
for ( int i=0; i<dim.Height; i+=4)
{
videoDriver->draw2DRectangleOutline( core::recti(offsetX+50,offsetY+i,offsetX+59,offsetY+i), video::SColor(255, 255, 0, 0));
videoDriver->draw2DRectangleOutline( core::recti(offsetX+50,offsetY+i+2,offsetX+59,offsetY+i+2), video::SColor(255, 0, 255, 0));
}
#endif
videoDriver->endScene();
}
Device->yield();
}
Device->closeDevice();
Device->drop();
return 0;
}
I'll be back on this another time. Sadly I already have 2 other half-finished changes for Irrlicht hanging around and not getting to them currently. So probably earliest when I have some time off after x-mas.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm