Commit 008a470f authored by hybrid's avatar hybrid

Fix pixel alignment and draw2DLine inconsistent offset problems. New test...

Fix pixel alignment and draw2DLine inconsistent offset problems. New test added to make sure that drawPixel and draw2DLine use the same alignment.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@4138 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 1c43d27c
...@@ -254,7 +254,7 @@ static void RenderLine32_Decal(video::IImage *t, ...@@ -254,7 +254,7 @@ static void RenderLine32_Decal(video::IImage *t,
m = dy << 1; m = dy << 1;
run = dx; run = dx;
while ( run ) do
{ {
*dst = argb; *dst = argb;
...@@ -266,7 +266,7 @@ static void RenderLine32_Decal(video::IImage *t, ...@@ -266,7 +266,7 @@ static void RenderLine32_Decal(video::IImage *t,
d -= c; d -= c;
} }
run -= 1; run -= 1;
} } while (run>=0);
t->unlock(); t->unlock();
} }
...@@ -321,7 +321,7 @@ static void RenderLine32_Blend(video::IImage *t, ...@@ -321,7 +321,7 @@ static void RenderLine32_Blend(video::IImage *t,
run = dx; run = dx;
const u32 packA = packAlpha ( alpha ); const u32 packA = packAlpha ( alpha );
while ( run ) do
{ {
*dst = packA | PixelBlend32( *dst, argb, alpha ); *dst = packA | PixelBlend32( *dst, argb, alpha );
...@@ -333,7 +333,7 @@ static void RenderLine32_Blend(video::IImage *t, ...@@ -333,7 +333,7 @@ static void RenderLine32_Blend(video::IImage *t,
d -= c; d -= c;
} }
run -= 1; run -= 1;
} } while (run>=0);
t->unlock(); t->unlock();
} }
...@@ -386,7 +386,7 @@ static void RenderLine16_Decal(video::IImage *t, ...@@ -386,7 +386,7 @@ static void RenderLine16_Decal(video::IImage *t,
m = dy << 1; m = dy << 1;
run = dx; run = dx;
while ( run ) do
{ {
*dst = (u16)argb; *dst = (u16)argb;
...@@ -398,7 +398,7 @@ static void RenderLine16_Decal(video::IImage *t, ...@@ -398,7 +398,7 @@ static void RenderLine16_Decal(video::IImage *t,
d -= c; d -= c;
} }
run -= 1; run -= 1;
} } while (run>=0);
t->unlock(); t->unlock();
} }
...@@ -453,7 +453,7 @@ static void RenderLine16_Blend(video::IImage *t, ...@@ -453,7 +453,7 @@ static void RenderLine16_Blend(video::IImage *t,
run = dx; run = dx;
const u16 packA = alpha ? 0x8000 : 0; const u16 packA = alpha ? 0x8000 : 0;
while ( run ) do
{ {
*dst = packA | PixelBlend16( *dst, argb, alpha ); *dst = packA | PixelBlend16( *dst, argb, alpha );
...@@ -465,7 +465,7 @@ static void RenderLine16_Blend(video::IImage *t, ...@@ -465,7 +465,7 @@ static void RenderLine16_Blend(video::IImage *t,
d -= c; d -= c;
} }
run -= 1; run -= 1;
} } while (run>=0);
t->unlock(); t->unlock();
} }
......
...@@ -1259,22 +1259,27 @@ void CD3D8Driver::draw2DLine(const core::position2d<s32>& start, ...@@ -1259,22 +1259,27 @@ void CD3D8Driver::draw2DLine(const core::position2d<s32>& start,
const core::position2d<s32>& end, const core::position2d<s32>& end,
SColor color) SColor color)
{ {
// thanks to Vash TheStampede who sent in his implementation if (start==end)
S3DVertex vtx[2]; drawPixel(start.X, start.Y, color);
vtx[0] = S3DVertex((f32)start.X, (f32)start.Y, 0.0f, else
0.0f, 0.0f, 0.0f, // normal {
color, 0.0f, 0.0f); // texture // thanks to Vash TheStampede who sent in his implementation
S3DVertex vtx[2];
vtx[0] = S3DVertex((f32)start.X+0.375f, (f32)start.Y+0.375f, 0.0f,
0.0f, 0.0f, 0.0f, // normal
color, 0.0f, 0.0f); // texture
vtx[1] = S3DVertex((f32)end.X, (f32)end.Y, 0.0f, vtx[1] = S3DVertex((f32)end.X+0.375f, (f32)end.Y+0.375f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
color, 0.0f, 0.0f); color, 0.0f, 0.0f);
setRenderStates2DMode(color.getAlpha() < 255, false, false); setRenderStates2DMode(color.getAlpha() < 255, false, false);
setActiveTexture(0,0); setActiveTexture(0,0);
setVertexShader(EVT_STANDARD); setVertexShader(EVT_STANDARD);
pID3DDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, &vtx[0], sizeof(S3DVertex)); pID3DDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, &vtx[0], sizeof(S3DVertex));
}
} }
...@@ -1290,7 +1295,7 @@ void CD3D8Driver::drawPixel(u32 x, u32 y, const SColor & color) ...@@ -1290,7 +1295,7 @@ void CD3D8Driver::drawPixel(u32 x, u32 y, const SColor & color)
setVertexShader(EVT_STANDARD); setVertexShader(EVT_STANDARD);
S3DVertex vertex((f32)x, (f32)y, 0.f, 0.f, 0.f, 0.f, color, 0.f, 0.f); S3DVertex vertex((f32)x+0.375f, (f32)y+0.375f, 0.f, 0.f, 0.f, 0.f, color, 0.f, 0.f);
pID3DDevice->DrawPrimitiveUP(D3DPT_POINTLIST, 1, &vertex, sizeof(vertex)); pID3DDevice->DrawPrimitiveUP(D3DPT_POINTLIST, 1, &vertex, sizeof(vertex));
} }
......
...@@ -1962,23 +1962,28 @@ void CD3D9Driver::draw2DLine(const core::position2d<s32>& start, ...@@ -1962,23 +1962,28 @@ void CD3D9Driver::draw2DLine(const core::position2d<s32>& start,
const core::position2d<s32>& end, const core::position2d<s32>& end,
SColor color) SColor color)
{ {
// thanks to Vash TheStampede who sent in his implementation if (start==end)
S3DVertex vtx[2]; drawPixel(start.X, start.Y, color);
vtx[0] = S3DVertex((f32)start.X, (f32)start.Y, 0.0f, else
0.0f, 0.0f, 0.0f, // normal {
color, 0.0f, 0.0f); // texture // thanks to Vash TheStampede who sent in his implementation
S3DVertex vtx[2];
vtx[0] = S3DVertex((f32)start.X+0.375f, (f32)start.Y+0.375f, 0.0f,
0.0f, 0.0f, 0.0f, // normal
color, 0.0f, 0.0f); // texture
vtx[1] = S3DVertex((f32)end.X, (f32)end.Y, 0.0f, vtx[1] = S3DVertex((f32)end.X+0.375f, (f32)end.Y+0.375f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
color, 0.0f, 0.0f); color, 0.0f, 0.0f);
setRenderStates2DMode(color.getAlpha() < 255, false, false); setRenderStates2DMode(color.getAlpha() < 255, false, false);
setActiveTexture(0,0); setActiveTexture(0,0);
setVertexShader(EVT_STANDARD); setVertexShader(EVT_STANDARD);
pID3DDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, pID3DDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1,
&vtx[0], sizeof(S3DVertex) ); &vtx[0], sizeof(S3DVertex) );
}
} }
...@@ -1994,7 +1999,7 @@ void CD3D9Driver::drawPixel(u32 x, u32 y, const SColor & color) ...@@ -1994,7 +1999,7 @@ void CD3D9Driver::drawPixel(u32 x, u32 y, const SColor & color)
setVertexShader(EVT_STANDARD); setVertexShader(EVT_STANDARD);
S3DVertex vertex((f32)x, (f32)y, 0.f, 0.f, 0.f, 0.f, color, 0.f, 0.f); S3DVertex vertex((f32)x+0.375f, (f32)y+0.375f, 0.f, 0.f, 0.f, 0.f, color, 0.f, 0.f);
pID3DDevice->DrawPrimitiveUP(D3DPT_POINTLIST, 1, &vertex, sizeof(vertex)); pID3DDevice->DrawPrimitiveUP(D3DPT_POINTLIST, 1, &vertex, sizeof(vertex));
} }
......
...@@ -2377,17 +2377,33 @@ void COpenGLDriver::draw2DRectangle(const core::rect<s32>& position, ...@@ -2377,17 +2377,33 @@ void COpenGLDriver::draw2DRectangle(const core::rect<s32>& position,
//! Draws a 2d line. //! Draws a 2d line.
void COpenGLDriver::draw2DLine(const core::position2d<s32>& start, void COpenGLDriver::draw2DLine(const core::position2d<s32>& start,
const core::position2d<s32>& end, const core::position2d<s32>& end, SColor color)
SColor color)
{ {
disableTextures(); if (start==end)
setRenderStates2DMode(color.getAlpha() < 255, false, false); drawPixel(start.X, start.Y, color);
else
glBegin(GL_LINES); {
glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); disableTextures();
glVertex2f(GLfloat(start.X), GLfloat(start.Y)); setRenderStates2DMode(color.getAlpha() < 255, false, false);
glVertex2f(GLfloat(end.X), GLfloat(end.Y));
glEnd(); glBegin(GL_LINES);
glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
GLfloat x=(GLfloat)start.X;
GLfloat y=(GLfloat)start.Y;
if (x>end.X)
x += 0.5f;
if (y>end.Y)
y += 0.5f;
glVertex2f(GLfloat(x), GLfloat(y));
x=(GLfloat)end.X;
y=(GLfloat)end.Y;
if (x>start.X)
x += 0.5f;
if (y>start.Y)
y += 0.5f;
glVertex2f(GLfloat(x), GLfloat(y));
glEnd();
}
} }
//! Draws a pixel //! Draws a pixel
......
...@@ -110,12 +110,76 @@ static bool pixelAccuracy(E_DRIVER_TYPE driverType) ...@@ -110,12 +110,76 @@ static bool pixelAccuracy(E_DRIVER_TYPE driverType)
return result; return result;
} }
// this test draws lines of different lengths and compares
// them with pixel placement
// grey pixels denote start and end of the white drawn lines
// black pixels only make those grey points better visible
// yellow and magenta lines should start and end next toa black pixel,
// yellow one right to the last black pixel down, magenta below the last
// black pixel to the right
// white lines are always double drawn, lines back and forth.
static bool drawLine(E_DRIVER_TYPE driverType)
{
IrrlichtDevice *device = createDevice( driverType, dimension2d<u32>(160, 120), 32);
if (!device)
return true; // Treat a failure to create a driver as benign; this saves a lot of #ifdefs
IVideoDriver* driver = device->getVideoDriver();
logTestString("Testing driver %ls\n", driver->getName());
device->getSceneManager()->addCameraSceneNode();
driver->beginScene(true, true, SColor(255,100,101,140));
// horizontal lines
for (u32 i=0; i<20; ++i)
{
driver->draw2DLine(core::vector2di(10,10+3*i), core::vector2di(10+2*i,10+3*i));
// mark start point
driver->drawPixel(9,10+3*i+1, video::SColor(0xff000000));
driver->drawPixel(10,10+3*i+1, video::SColor(0xff888888));
driver->drawPixel(11,10+3*i+1, video::SColor(0xff000000));
// mark end point
driver->drawPixel(9+2*i,10+3*i+1, video::SColor(0xff000000));
driver->drawPixel(10+2*i,10+3*i+1, video::SColor(0xff888888));
driver->drawPixel(11+2*i,10+3*i+1, video::SColor(0xff000000));
driver->draw2DLine(core::vector2di(10+2*i,10+3*i+2), core::vector2di(10,10+3*i+2));
}
// vertical lines
for (u32 i=0; i<20; ++i)
{
driver->draw2DLine(core::vector2di(11+3*i,10), core::vector2di(11+3*i,10+2*i));
// mark start point
driver->drawPixel(11+3*i+1,9, video::SColor(0xff000000));
driver->drawPixel(11+3*i+1,10, video::SColor(0xff888888));
driver->drawPixel(11+3*i+1,11, video::SColor(0xff000000));
// mark end point
driver->drawPixel(11+3*i+1,9+2*i, video::SColor(0xff000000));
driver->drawPixel(11+3*i+1,10+2*i, video::SColor(0xff888888));
driver->drawPixel(11+3*i+1,11+2*i, video::SColor(0xff000000));
driver->draw2DLine(core::vector2di(11+3*i+2,10+2*i), core::vector2di(11+3*i+2, 10));
}
// diagonal lines
driver->draw2DLine(core::vector2di(14,14),core::vector2di(50,68), video::SColor(0xffffff00));
driver->draw2DLine(core::vector2di(15,14),core::vector2di(69,50), video::SColor(0xffff00ff));
driver->endScene();
bool result = takeScreenshotAndCompareAgainstReference(driver, "-drawLine.png");
device->closeDevice();
device->run();
device->drop();
return result;
}
bool drawPixel(void) bool drawPixel(void)
{ {
bool result = true; bool result = true;
TestWithAllDrivers(lineRender); TestWithAllDrivers(lineRender);
TestWithAllDrivers(pixelAccuracy); TestWithAllDrivers(pixelAccuracy);
TestWithAllDrivers(drawLine);
return result; return result;
} }
tests/media/Direct3D 9.0-drawPixel.png

23.4 KB | W: | H:

tests/media/Direct3D 9.0-drawPixel.png

23.8 KB | W: | H:

tests/media/Direct3D 9.0-drawPixel.png
tests/media/Direct3D 9.0-drawPixel.png
tests/media/Direct3D 9.0-drawPixel.png
tests/media/Direct3D 9.0-drawPixel.png
  • 2-up
  • Swipe
  • Onion skin
tests/media/Direct3D 9.0-drawRectOutline.png

545 Bytes | W: | H:

tests/media/Direct3D 9.0-drawRectOutline.png

561 Bytes | W: | H:

tests/media/Direct3D 9.0-drawRectOutline.png
tests/media/Direct3D 9.0-drawRectOutline.png
tests/media/Direct3D 9.0-drawRectOutline.png
tests/media/Direct3D 9.0-drawRectOutline.png
  • 2-up
  • Swipe
  • Onion skin
tests/media/OpenGL-drawRectOutline.png

594 Bytes | W: | H:

tests/media/OpenGL-drawRectOutline.png

622 Bytes | W: | H:

tests/media/OpenGL-drawRectOutline.png
tests/media/OpenGL-drawRectOutline.png
tests/media/OpenGL-drawRectOutline.png
tests/media/OpenGL-drawRectOutline.png
  • 2-up
  • Swipe
  • Onion skin
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment