Commit c3cfdcfa authored by hybrid's avatar hybrid

Merged revisions 2006:2016 from 1.5 branch, makeColorKeyTexture changes.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@2017 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 77216f12
...@@ -11,6 +11,10 @@ Changes in version 1.6 ...@@ -11,6 +11,10 @@ Changes in version 1.6
------------------------------------- -------------------------------------
Changes in version 1.5.1 (??.?? 2009) Changes in version 1.5.1 (??.?? 2009)
- Changed behaviour of PixelBlend16() / PixelBlend16_simd() so that they treat the 1 bit alpha of the source pixel as boolean, i.e. they draw either the source pixel, or the destination pixel, rather than "blending". (Issue revealed by the fix to IVideoDriver::makeColorKeyTexture()).
- IVideoDriver::makeColorKeyTexture() bug fixed so that only alphas, not whole texel colors, are zeroed. An optional parameter allows using the old (buggy) behaviour for backwards compatibility.
- MD2 mesh loader: Now uses much less memory, reduced number of allocations when loading meshes. - MD2 mesh loader: Now uses much less memory, reduced number of allocations when loading meshes.
----------------------------------- -----------------------------------
......
...@@ -271,30 +271,41 @@ namespace video ...@@ -271,30 +271,41 @@ namespace video
//! Remove all hardware buffers //! Remove all hardware buffers
virtual void removeAllHardwareBuffers() = 0; virtual void removeAllHardwareBuffers() = 0;
//! Creates a 1bit alpha channel of the texture based of an color key. //! Sets a boolean alpha channel on the texture based on a color key.
/** This makes the texture transparent at the regions where /** This makes the texture fully transparent at the texels where
this color key can be found when using for example draw2DImage this color key can be found when using for example draw2DImage
with useAlphachannel==true. with useAlphachannel==true. The alpha of other texels is not modified.
\param texture Texture whose alpha channel is modified. \param texture Texture whose alpha channel is modified.
\param color Color key color. Every pixel with this color will \param color Color key color. Every texel with this color will
become transparent as described above. Please note that the become fully transparent as described above. Please note that the
colors of a texture may be converted when loading it, so the colors of a texture may be converted when loading it, so the
color values may not be exactly the same in the engine and for color values may not be exactly the same in the engine and for
example in picture edit programs. To avoid this problem, you example in picture edit programs. To avoid this problem, you
could use the makeColorKeyTexture method, which takes the could use the makeColorKeyTexture method, which takes the
position of a pixel instead a color value. */ position of a pixel instead a color value.
virtual void makeColorKeyTexture(video::ITexture* texture, video::SColor color) const = 0; \param \deprecated zeroTexels If set to true, then any texels that match
the color key will have their color, as well as their alpha, set to zero
(i.e. black). This behaviour matches the legacy (buggy) behaviour prior
to release 1.5 and is provided for backwards compatibility only.*/
virtual void makeColorKeyTexture(video::ITexture* texture,
video::SColor color,
bool zeroTexels = false) const = 0;
//! Creates a 1bit alpha channel of the texture based of an color key position. //! Sets a boolean alpha channel on the texture based on the color at a position.
/** This makes the texture transparent at the regions where /** This makes the texture fully transparent at the texels where
this color key can be found when using for example draw2DImage the color key can be found when using for example draw2DImage
with useAlphachannel==true. with useAlphachannel==true. The alpha of other texels is not modified.
\param texture Texture whose alpha channel is modified. \param texture Texture whose alpha channel is modified.
\param colorKeyPixelPos Position of a pixel with the color key \param colorKeyPixelPos Position of a pixel with the color key
color. Every pixel with this color will become transparent as color. Every texel with this color will become fully transparent as
described above. */ described above.
\param \deprecated zeroTexels If set to true, then any texels that match
the color key will have their color, as well as their alpha, set to zero
(i.e. black). This behaviour matches the legacy (buggy) behaviour prior
to release 1.5 and is provided for backwards compatibility only.*/
virtual void makeColorKeyTexture(video::ITexture* texture, virtual void makeColorKeyTexture(video::ITexture* texture,
core::position2d<s32> colorKeyPixelPos) const = 0; core::position2d<s32> colorKeyPixelPos,
bool zeroTexels = false) const = 0;
//! Creates a normal map from a height map texture. //! Creates a normal map from a height map texture.
/** If the target texture has 32 bit, the height value is /** If the target texture has 32 bit, the height value is
......
...@@ -2321,6 +2321,9 @@ bool CD3D9Driver::reset() ...@@ -2321,6 +2321,9 @@ bool CD3D9Driver::reset()
if(DepthBuffers[i]->Surface) if(DepthBuffers[i]->Surface)
DepthBuffers[i]->Surface->Release(); DepthBuffers[i]->Surface->Release();
} }
// this does not require a restore in the reset method, it's updated
// automatically in the next render cycle.
removeAllHardwareBuffers();
DriverWasReset=true; DriverWasReset=true;
......
...@@ -853,8 +853,10 @@ const SLight& CNullDriver::getDynamicLight(u32 idx) const ...@@ -853,8 +853,10 @@ const SLight& CNullDriver::getDynamicLight(u32 idx) const
} }
//! Creates an 1bit alpha channel of the texture based of an color key. //! Creates a boolean alpha channel of the texture based of an color key.
void CNullDriver::makeColorKeyTexture(video::ITexture* texture, video::SColor color) const void CNullDriver::makeColorKeyTexture(video::ITexture* texture,
video::SColor color,
bool zeroTexels) const
{ {
if (!texture) if (!texture)
return; return;
...@@ -876,19 +878,27 @@ void CNullDriver::makeColorKeyTexture(video::ITexture* texture, video::SColor co ...@@ -876,19 +878,27 @@ void CNullDriver::makeColorKeyTexture(video::ITexture* texture, video::SColor co
return; return;
} }
core::dimension2d<s32> dim = texture->getSize(); const core::dimension2d<s32> dim = texture->getSize();
s32 pitch = texture->getPitch() / 2; const s32 pitch = texture->getPitch() / 2;
// color with alpha enabled (color opaque) // color with alpha disabled (i.e. fully transparent)
s16 ref = (0x1<<15) | (0x7fff & color.toA1R5G5B5()); const s16 refZeroAlpha = (0x7fff & color.toA1R5G5B5());
for (s32 y=0; y<dim.Height; ++y) const s32 pixels = pitch * dim.Height;
for (s32 pixel = 0; pixel < pixels; ++ pixel)
{ {
for (s32 x=0; x<pitch; ++x) // If the colour matches the reference colour, ignoring alphas,
// set the alpha to zero.
if(((*p) & 0x7fff) == refZeroAlpha)
{ {
s16 c = (0x1<<15) | (0x7fff & p[y*pitch + x]); if(zeroTexels)
p[y*pitch + x] = (c == ref) ? 0 : c; (*p) = 0;
else
(*p) = refZeroAlpha;
} }
++p;
} }
texture->unlock(); texture->unlock();
...@@ -906,16 +916,23 @@ void CNullDriver::makeColorKeyTexture(video::ITexture* texture, video::SColor co ...@@ -906,16 +916,23 @@ void CNullDriver::makeColorKeyTexture(video::ITexture* texture, video::SColor co
core::dimension2d<s32> dim = texture->getSize(); core::dimension2d<s32> dim = texture->getSize();
s32 pitch = texture->getPitch() / 4; s32 pitch = texture->getPitch() / 4;
// color with alpha enabled (color opaque) // color with alpha disabled (fully transparent)
s32 ref = 0xff000000 | (0x00ffffff & color.color); const s32 refZeroAlpha = 0x00ffffff & color.color;
for (s32 y=0; y<dim.Height; ++y) const s32 pixels = pitch * dim.Height;
for (s32 pixel = 0; pixel < pixels; ++ pixel)
{ {
for (s32 x=0; x<pitch; ++x) // If the colour matches the reference colour, ignoring alphas,
// set the alpha to zero.
if(((*p) & 0x00ffffff) == refZeroAlpha)
{ {
s32 c = (0xff<<24) | (0x00ffffff & p[y*pitch + x]); if(zeroTexels)
p[y*pitch + x] = (c == ref) ? 0 : c; (*p) = 0;
else
(*p) = refZeroAlpha;
} }
++p;
} }
texture->unlock(); texture->unlock();
...@@ -924,9 +941,10 @@ void CNullDriver::makeColorKeyTexture(video::ITexture* texture, video::SColor co ...@@ -924,9 +941,10 @@ void CNullDriver::makeColorKeyTexture(video::ITexture* texture, video::SColor co
//! Creates an 1bit alpha channel of the texture based of an color key position. //! Creates an boolean alpha channel of the texture based of an color key position.
void CNullDriver::makeColorKeyTexture(video::ITexture* texture, void CNullDriver::makeColorKeyTexture(video::ITexture* texture,
core::position2d<s32> colorKeyPixelPos) const core::position2d<s32> colorKeyPixelPos,
bool zeroTexels) const
{ {
if (!texture) if (!texture)
return; return;
...@@ -938,6 +956,8 @@ void CNullDriver::makeColorKeyTexture(video::ITexture* texture, ...@@ -938,6 +956,8 @@ void CNullDriver::makeColorKeyTexture(video::ITexture* texture,
return; return;
} }
SColor colorKey;
if (texture->getColorFormat() == ECF_A1R5G5B5) if (texture->getColorFormat() == ECF_A1R5G5B5)
{ {
s16 *p = (s16*)texture->lock(); s16 *p = (s16*)texture->lock();
...@@ -948,21 +968,11 @@ void CNullDriver::makeColorKeyTexture(video::ITexture* texture, ...@@ -948,21 +968,11 @@ void CNullDriver::makeColorKeyTexture(video::ITexture* texture,
return; return;
} }
core::dimension2d<s32> dim = texture->getSize();
s32 pitch = texture->getPitch() / 2; s32 pitch = texture->getPitch() / 2;
s16 ref = (0x1<<15) | (0x7fff & p[colorKeyPixelPos.Y*dim.Width + colorKeyPixelPos.X]); const s16 key16Bit = 0x7fff & p[colorKeyPixelPos.Y*pitch + colorKeyPixelPos.X];
for (s32 y=0; y<dim.Height; ++y) colorKey = video::A1R5G5B5toA8R8G8B8(key16Bit);
{
for (s32 x=0; x<pitch; ++x)
{
s16 c = (0x1<<15) | (0x7fff & p[y*pitch + x]);
p[y*pitch + x] = (c == ref) ? 0 : c;
}
}
texture->unlock();
} }
else else
{ {
...@@ -974,22 +984,12 @@ void CNullDriver::makeColorKeyTexture(video::ITexture* texture, ...@@ -974,22 +984,12 @@ void CNullDriver::makeColorKeyTexture(video::ITexture* texture,
return; return;
} }
core::dimension2d<s32> dim = texture->getSize();
s32 pitch = texture->getPitch() / 4; s32 pitch = texture->getPitch() / 4;
colorKey = 0x00ffffff & p[colorKeyPixelPos.Y*pitch + colorKeyPixelPos.X];
s32 ref = (0xff<<24) | (0x00ffffff & p[colorKeyPixelPos.Y*dim.Width + colorKeyPixelPos.X]);
for (s32 y=0; y<dim.Height; ++y)
{
for (s32 x=0; x<pitch; ++x)
{
s32 c = (0xff<<24) | (0x00ffffff & p[y*pitch + x]);
p[y*pitch + x] = (c == ref) ? 0 : c;
}
} }
texture->unlock(); texture->unlock();
} makeColorKeyTexture(texture, colorKey, zeroTexels);
} }
......
...@@ -274,10 +274,10 @@ namespace video ...@@ -274,10 +274,10 @@ namespace video
const c8* name); const c8* name);
//! Creates an 1bit alpha channel of the texture based of an color key. //! Creates an 1bit alpha channel of the texture based of an color key.
virtual void makeColorKeyTexture(video::ITexture* texture, video::SColor color) const; virtual void makeColorKeyTexture(video::ITexture* texture, video::SColor color, bool zeroTexels) const;
//! Creates an 1bit alpha channel of the texture based of an color key position. //! Creates an 1bit alpha channel of the texture based of an color key position.
virtual void makeColorKeyTexture(video::ITexture* texture, core::position2d<s32> colorKeyPixelPos) const; virtual void makeColorKeyTexture(video::ITexture* texture, core::position2d<s32> colorKeyPixelPos, bool zeroTexels) const;
//! Creates a normal map from a height map texture. //! Creates a normal map from a height map texture.
//! \param amplitude: Constant value by which the height information is multiplied. //! \param amplitude: Constant value by which the height information is multiplied.
......
...@@ -1404,12 +1404,6 @@ void CBurningVideoDriver::lightVertex ( s4DVertex *dest, const S3DVertex *source ...@@ -1404,12 +1404,6 @@ void CBurningVideoDriver::lightVertex ( s4DVertex *dest, const S3DVertex *source
return; return;
} }
if ( Lights.size () == 0 )
{
dest->Color[0] = Material.EmissiveColor;
return;
}
// eyespace // eyespace
/* /*
core::matrix4 modelview = Transformation[ETS_WORLD].m * Transformation[ETS_VIEW].m; core::matrix4 modelview = Transformation[ETS_WORLD].m * Transformation[ETS_VIEW].m;
......
...@@ -292,31 +292,31 @@ REALINLINE u32 PixelAdd32 ( const u32 c2, const u32 c1) ...@@ -292,31 +292,31 @@ REALINLINE u32 PixelAdd32 ( const u32 c2, const u32 c1)
// 1 - Bit Alpha Blending // 1 - Bit Alpha Blending
inline u16 PixelBlend16 ( const u16 c2, const u16 c1 ) inline u16 PixelBlend16 ( const u16 destination, const u16 source )
{ {
u16 c = c1 & 0x8000; if((source & 0x8000) == 0x8000)
return source; // The source is visible, so use it.
c >>= 15; else
c += 0x7fff; return destination; // The source is transparent, so use the destination.
c &= c2;
c |= c1;
return c;
} }
// 1 - Bit Alpha Blending 16Bit SIMD // 1 - Bit Alpha Blending 16Bit SIMD
inline u32 PixelBlend16_simd ( const u32 c2, const u32 c1 ) inline u32 PixelBlend16_simd ( const u32 destination, const u32 source )
{ {
u32 c = c1 & 0x80008000; switch(source & 0x80008000)
{
case 0x80008000: // Both source pixels are visible
return source;
c >>= 15; case 0x80000000: // Only the first source pixel is visible
c += 0x7fff7fff; return (source & 0xFFFF0000) | (destination & 0x0000FFFF);
c &= c2; case 0x00008000: // Only the second source pixel is visible.
c |= c1; return (destination & 0xFFFF0000) | (source & 0x0000FFFF);
return c; default: // Neither source pixel is visible.
return destination;
}
} }
......
#include "testUtils.h"
#include "irrlicht.h"
using namespace irr;
using namespace scene;
using namespace video;
/** Tests the Burning Video driver */
bool burningsVideo(void)
{
IrrlichtDevice *device = createDevice(video::EDT_BURNINGSVIDEO,
core::dimension2di(160,120), 32);
if (!device)
return false;
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
smgr->addCubeSceneNode(10.f, 0, -1, core::vector3df(0.f, 0.f, 20.f));
smgr->addCameraSceneNode();
// Test that ambient lighting works when there are no other lights in the scene
smgr->setAmbientLight(video::SColorf(.7f, .1f, .1f, 1.f));
bool result = false;
device->run();
if (driver->beginScene(true, true, video::SColor(0, 80, 80, 80)))
{
smgr->drawAll();
driver->endScene();
result = takeScreenshotAndCompareAgainstReference(driver, "-ambient-lighting.png", 100);
}
device->drop();
return result;
}
...@@ -80,6 +80,8 @@ int main(int argumentCount, char * arguments[]) ...@@ -80,6 +80,8 @@ int main(int argumentCount, char * arguments[])
TEST(textureRenderStates) TEST(textureRenderStates)
}; };
static const unsigned int numberOfTests = sizeof tests / sizeof tests[0]; static const unsigned int numberOfTests = sizeof tests / sizeof tests[0];
TEST(burningsVideo);
TEST(makeColorKeyTexture);
unsigned int testToRun = 0; unsigned int testToRun = 0;
unsigned int fails = 0; unsigned int fails = 0;
......
// Copyright (C) 2008 Colin MacDonald
// No rights reserved: this software is in the public domain.
#include "irrlicht.h"
#include "testUtils.h"
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
/** Test the behaviour of makeColorKeyTexture() using both 16 bit (software)
and 32 bit (Burning) textures, with the new behaviour and the legacy
behaviour. */
static bool doTestWith(E_DRIVER_TYPE driverType,
bool zeroTexels)
{
IrrlichtDevice *device = createDevice( driverType,
dimension2d<s32>(160, 120), 32);
if (!device)
return false;
IVideoDriver* driver = device->getVideoDriver();
ISceneManager * smgr = device->getSceneManager();
// Draw a cube background so that we can check that the keying is working.
ISceneNode * cube = smgr->addCubeSceneNode(50.f, 0, -1, vector3df(0, 0, 60));
cube->setMaterialTexture(0, driver->getTexture("../media/wall.bmp"));
cube->setMaterialFlag(video::EMF_LIGHTING, false);
ITexture * Texture = device->getVideoDriver()->getTexture("../media/portal2.bmp");
device->getVideoDriver()->makeColorKeyTexture(Texture,
position2d<s32>(64,64),
zeroTexels);
device->getVideoDriver()->makeColorKeyTexture(Texture,
position2d<s32>(64,64),
zeroTexels);
(void)smgr->addCameraSceneNode();
driver->beginScene(true, true, SColor(255,100,101,140));
smgr->drawAll();
driver->draw2DImage(Texture,
position2di(40, 40),
rect<s32>(0, 0, Texture->getSize().Width, Texture->getSize().Height),
0,
SColor(255,255,255,255),
true);
driver->endScene();
char screenshotName[256];
(void)sprintf(screenshotName, "-makeColorKeyTexture-%s.png",
zeroTexels? "old" : "new");
bool result = takeScreenshotAndCompareAgainstReference(driver, screenshotName);
device->drop();
return result;
}
bool makeColorKeyTexture(void)
{
bool result = doTestWith(EDT_SOFTWARE, false);
result &= doTestWith(EDT_BURNINGSVIDEO, false);
result &= doTestWith(EDT_SOFTWARE, true);
result &= doTestWith(EDT_BURNINGSVIDEO, true);
return result;
}
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
<Add directory="..\lib\gcc" /> <Add directory="..\lib\gcc" />
</Linker> </Linker>
<Unit filename="b3dAnimation.cpp" /> <Unit filename="b3dAnimation.cpp" />
<Unit filename="burningsVideo.cpp" />
<Unit filename="collisionResponseAnimator.cpp" /> <Unit filename="collisionResponseAnimator.cpp" />
<Unit filename="disambiguateTextures.cpp" /> <Unit filename="disambiguateTextures.cpp" />
<Unit filename="drawPixel.cpp" /> <Unit filename="drawPixel.cpp" />
...@@ -47,6 +48,7 @@ ...@@ -47,6 +48,7 @@
<Unit filename="guiDisabledMenu.cpp" /> <Unit filename="guiDisabledMenu.cpp" />
<Unit filename="line2dIntersectWith.cpp" /> <Unit filename="line2dIntersectWith.cpp" />
<Unit filename="main.cpp" /> <Unit filename="main.cpp" />
<Unit filename="makeColorKeyTexture.cpp" />
<Unit filename="md2Animation.cpp" /> <Unit filename="md2Animation.cpp" />
<Unit filename="planeMatrix.cpp" /> <Unit filename="planeMatrix.cpp" />
<Unit filename="sceneCollisionManager.cpp" /> <Unit filename="sceneCollisionManager.cpp" />
......
...@@ -173,6 +173,10 @@ ...@@ -173,6 +173,10 @@
RelativePath=".\b3dAnimation.cpp" RelativePath=".\b3dAnimation.cpp"
> >
</File> </File>
<File
RelativePath=".\burningsVideo.cpp"
>
</File>
<File <File
RelativePath=".\collisionResponseAnimator.cpp" RelativePath=".\collisionResponseAnimator.cpp"
> >
...@@ -209,6 +213,10 @@ ...@@ -209,6 +213,10 @@
RelativePath=".\main.cpp" RelativePath=".\main.cpp"
> >
</File> </File>
<File
RelativePath=".\makeColorKeyTexture.cpp"
>
</File>
<File <File
RelativePath=".\md2Animation.cpp" RelativePath=".\md2Animation.cpp"
> >
......
...@@ -171,6 +171,10 @@ ...@@ -171,6 +171,10 @@
RelativePath=".\b3dAnimation.cpp" RelativePath=".\b3dAnimation.cpp"
> >
</File> </File>
<File
RelativePath=".\burningsVideo.cpp"
>
</File>
<File <File
RelativePath=".\collisionResponseAnimator.cpp" RelativePath=".\collisionResponseAnimator.cpp"
> >
...@@ -207,6 +211,10 @@ ...@@ -207,6 +211,10 @@
RelativePath=".\main.cpp" RelativePath=".\main.cpp"
> >
</File> </File>
<File
RelativePath=".\makeColorKeyTexture.cpp"
>
</File>
<File <File
RelativePath=".\md2Animation.cpp" RelativePath=".\md2Animation.cpp"
> >
......
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