Here is example code of automatic blending of two textures. Its done on single tile just for demonstration. Replace "dirth.bmp" and "grass.bmp" with your own textures. Change vertex color to blend textures in diferent order:
Code: Select all
#include <irrlicht.h>
using namespace irr;
class TestSceneNode : public scene::ISceneNode
{
video::S3DVertex VertexA[4];
video::S3DVertex VertexB[4];
u16 IndexA[6];
u16 IndexB[6];
core::aabbox3d<f32> BoundingBox;
video::SMaterial Material[2];
public:
TestSceneNode(scene::ISceneNode* parent, scene::ISceneManager* smgr, s32 id, f32 width, f32 height)
: scene::ISceneNode(parent, smgr, id)
{
VertexA[0].Pos = core::vector3df(0,0,0);
VertexA[1].Pos = core::vector3df(0,0,height);
VertexA[2].Pos = core::vector3df(width,0,height);
VertexA[3].Pos = core::vector3df(width,0,0);
VertexA[0].Normal = core::vector3df(0,1,0);
VertexA[1].Normal = core::vector3df(0,1,0);
VertexA[2].Normal = core::vector3df(0,1,0);
VertexA[3].Normal = core::vector3df(0,1,0);
VertexA[0].Color = video::SColor(0,0,0,0);
VertexA[1].Color = video::SColor(0,0,0,0);
VertexA[2].Color = video::SColor(255,255,255,255);
VertexA[3].Color = video::SColor(255,255,255,255);
VertexA[0].TCoords = core::vector2df(0,1);
VertexA[1].TCoords = core::vector2df(0,0);
VertexA[2].TCoords = core::vector2df(1,0);
VertexA[3].TCoords = core::vector2df(1,1);
IndexA[0] = 0;
IndexA[1] = 1;
IndexA[2] = 2;
IndexA[3] = 0;
IndexA[4] = 2;
IndexA[5] = 3;
VertexB[0].Pos = core::vector3df(0,0,0);
VertexB[1].Pos = core::vector3df(0,0,height);
VertexB[2].Pos = core::vector3df(width,0,height);
VertexB[3].Pos = core::vector3df(width,0,0);
VertexB[0].Normal = core::vector3df(0,1,0);
VertexB[1].Normal = core::vector3df(0,1,0);
VertexB[2].Normal = core::vector3df(0,1,0);
VertexB[3].Normal = core::vector3df(0,1,0);
VertexB[0].Color = video::SColor(255,255,255,255);
VertexB[1].Color = video::SColor(255,255,255,255);
VertexB[2].Color = video::SColor(0,0,0,0);
VertexB[3].Color = video::SColor(0,0,0,0);
VertexB[0].TCoords = core::vector2df(0,1);
VertexB[1].TCoords = core::vector2df(0,0);
VertexB[2].TCoords = core::vector2df(1,0);
VertexB[3].TCoords = core::vector2df(1,1);
IndexB[0] = 0;
IndexB[1] = 1;
IndexB[2] = 2;
IndexB[3] = 0;
IndexB[4] = 2;
IndexB[5] = 3;
BoundingBox.reset(VertexA[0].Pos);
for (s32 i=1; i<4; ++i)
BoundingBox.addInternalPoint(VertexA[i].Pos);
video::IVideoDriver* driver = SceneManager->getVideoDriver();
Material[0].MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
Material[0].Textures[0] = driver->getTexture("grass.bmp");
Material[1].MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
Material[1].Textures[0] = driver->getTexture("dirth.bmp");
}
virtual void OnRegisterSceneNode()
{
if (IsVisible)
SceneManager->registerNodeForRendering(this);
ISceneNode::OnRegisterSceneNode();
}
virtual void render()
{
video::IVideoDriver* driver = SceneManager->getVideoDriver();
if (!driver) return;
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->setMaterial(Material[0]);
driver->drawIndexedTriangleList(&VertexA[0], 4, &IndexA[0], 2);
driver->setMaterial(Material[1]);
driver->drawIndexedTriangleList(&VertexB[0], 4, &IndexB[0], 2);
}
virtual const core::aabbox3d<f32>& getBoundingBox() const
{
return BoundingBox;
}
virtual u32 getMaterialCount()
{
return 2;
}
virtual video::SMaterial& getMaterial(u32 i)
{
return Material[i];
}
};
int main()
{
IrrlichtDevice *device = createDevice(
video::EDT_DIRECT3D9,
//video::EDT_OPENGL,
core::dimension2d<s32>(640, 480), 32, false, false, false, 0);
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
TestSceneNode *tile = new TestSceneNode(smgr->getRootSceneNode(), smgr, -1, 10.0f, 10.0f);
tile->drop();
tile->setMaterialFlag(video::EMF_LIGHTING, true);
smgr->addCameraSceneNode(0, core::vector3df(5, 5, -5), core::vector3df(5, 0, 5));
scene::ILightSceneNode* light = smgr->addLightSceneNode(0, core::vector3df(0,10,0),
video::SColorf(255, 255, 255, 255), 1000.0f);
while(device->run())
{
driver->beginScene(true, true, video::SColor(255,100,101,140));
smgr->drawAll();
driver->endScene();
}
device->drop();
return 0;
}
Like this user would not need to create texture sets. Also you are not limited in nubmer of textures. You can blend 4 textures on one tile easyly.
Problem is that EMT_TRANSPARENT_VERTEX_ALPHA material type is not working under OpenGL when lighting is on.
Also there is no detail map wersion of EMT_TRANSPARENT_VERTEX_ALPHA.
There are EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA and EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA materials awailable so normal maps and parallax maps would be possible.
If somebody can fix EMT_TRANSPARENT_VERTEX_ALPHA with OpenGL that would be great.
[EDIT] I forget to note that I was testing this with Irrlicht 1.3. If somebody have 1.31 instaled, please let me know howe ots working.