I had observed this in such cases:
1. Node is using S3DVertex2TCoords, EMT_DETAIL_MAP material, second texture is loaded (detail map) and main texture is updated.
2. Node is using S3DVertex2TCoords, EMT_DETAIL_MAP material, no detail map texture is loaded and main lexture is updated.
3. Node is using S3DVertex2TCoords, standard material, second texture is loaded (in to material second texture layer like detail map) and main lexture is updated.
At firsth I tought that its problem of EMT_DETAIL_MAP with OpenGL but problem happen also with standard material when second texture is loaded. So only common thing is S3DVertex2TCoords used.
Everything works fine with DirectX.
Here is example code which shows problem. Program should change color of texture of node from red to blue and back.
Code is slightly modified 03.CustomSceneNode Example.
Works fine with DirectX, doesnt on OpenGL.
I dont know if it is realy bug in Irrlicht or it have something to do with OpenGL itself but in all cases code like this should work.
Code: Select all
// this code should change texture of node from red to blue and back
// works fine with DirectX but OpenGl fails
#include <irrlicht.h>
using namespace irr;
// custom scene node
// taken from Irrlicht 03.CustomSceneNode Example
// with exeption of vertices changed from S3DVertex to S3DVertex2TCoords type
// and color set to plain white for all vertices
class CSampleSceneNode : public scene::ISceneNode
{
core::aabbox3d<f32> Box;
video::S3DVertex2TCoords Vertices[4];
video::SMaterial Material;
public:
CSampleSceneNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id)
: scene::ISceneNode(parent, mgr, id)
{
Material.Wireframe = false;
Material.Lighting = false;
Vertices[0] = video::S3DVertex2TCoords(0,0,10, 1,1,0, video::SColor(255,255,255,255), 0, 1);
Vertices[1] = video::S3DVertex2TCoords(10,0,-10, 1,0,0, video::SColor(255,255,255,255), 1, 1);
Vertices[2] = video::S3DVertex2TCoords(0,20,0, 0,1,1, video::SColor(255,255,255,255), 1, 0);
Vertices[3] = video::S3DVertex2TCoords(-10,0,-10, 0,0,1, video::SColor(255,255,255,255), 0, 0);
Box.reset(Vertices[0].Pos);
for (s32 i=1; i<4; ++i)
Box.addInternalPoint(Vertices[i].Pos);
}
virtual void OnRegisterSceneNode()
{
if (IsVisible)
SceneManager->registerNodeForRendering(this);
ISceneNode::OnRegisterSceneNode();
}
virtual void render()
{
u16 indices[] = { 0,2,3, 2,1,3, 1,0,3, 2,0,1 };
video::IVideoDriver* driver = SceneManager->getVideoDriver();
driver->setMaterial(Material);
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->drawIndexedTriangleList(&Vertices[0], 4, &indices[0], 4);
}
virtual const core::aabbox3d<f32>& getBoundingBox() const
{
return Box;
}
virtual u32 getMaterialCount()
{
return 1;
}
virtual video::SMaterial& getMaterial(u32 i)
{
return Material;
}
};
int main()
{
IrrlichtDevice *device =
createDevice(
video::EDT_OPENGL,
//video::EDT_DIRECT3D9,
core::dimension2d<s32>(800, 600), 32, false, false, false);
if (device == 0) return 1;
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
// camera
smgr->addCameraSceneNode(0, core::vector3df(0,-40,0), core::vector3df(0,0,0));
// create node
CSampleSceneNode *myNode =
new CSampleSceneNode(smgr->getRootSceneNode(), smgr, 666);
myNode->drop();
// create texture for node
// turn off mip maps so we dont have to update them each time texture is updated
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
video::ITexture* texture = driver->addTexture(core::dimension2d<s32>(64, 64), "cubetexture", video::ECF_A8R8G8B8);
myNode->setMaterialTexture(0, texture);
// load detail map texture
// detailmap3.jpg is from Irrlicht-1.3/media folder
// change path to your own
myNode->setMaterialTexture(1, driver->getTexture("your path/detailmap3.jpg"));
// change material to detail map
myNode->setMaterialType(video::EMT_DETAIL_MAP);
// set color for texture
video::SColor color(255,255,0,0);
// update texture with color
s32* p = (s32*)texture->lock();
for(s32 i=0; i<64*64; i++)
p[i] = color.color;
texture->unlock();
// animate
scene::ISceneNodeAnimator* anim =
smgr->createRotationAnimator(core::vector3df(0.8f, 0, 0.8f));
myNode->addAnimator(anim);
anim->drop();
// set some color variables
f32 r = 255.0f; // red
f32 rs = -0.001f; // how fast to change red
f32 b = 0.0f; // blue
f32 bs = 0.001f; // how fast to change blue
while(device->run())
{
driver->beginScene(true, true, video::SColor(255,100,101,140));
// change texture color from red to blue and back
if(r >= 255.0f) rs = -0.1f;
if(r <= 0.0f) rs = 0.1f;
if(b >= 255.0f) bs = -0.1f;
if(b <= 0.0f) bs = 0.1f;
r += rs;
b += bs;
color.setRed((u32)r);
color.setBlue((u32)b);
// update rexture with new color
s32* p = (s32*)texture->lock();
for(s32 i=0; i<64*64; i++)
p[i] = color.color;
texture->unlock();
smgr->drawAll();
driver->endScene();
}
device->drop();
return 0;
}