I have a problem with light and irrlicht, it's probably a basic problem with normals.
But i didn't solve the problem by myself. I wrote a short source code to illustrate my problem :
Code: Select all
// to compile : g++ norm.cpp -lIrrlicht -o norm
#include <irrlicht/irrlicht.h>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
// build a basic surface oriented Y
void build_surface(core::array<S3DVertex> &vertices, const vector3df &pos, const vector3df &size)
{
vector3df up[4] = { irr::core::vector3df(-.5, .5, .5),
irr::core::vector3df(.5, .5, .5),
irr::core::vector3df(.5, .5, -.5),
irr::core::vector3df(-.5, .5, -.5)};
for(char i=0;i<4;i++)
{
vector3df p = up[i] * size + pos;
vertices.push_back(S3DVertex(p,
vector3df(0, 1, 0),
SColor(255, 0, 255, 255),
vector2df(0,0)));
}
}
// build a mesh, enable light and normals debug
void build_mesh(ISceneManager* smgr, const vector3df &pos, const vector3df &size)
{
core::array<S3DVertex> vertices;
array<u16> indices;
build_surface(vertices, pos, size);
indices.push_back( 0 );
indices.push_back( 1 );
indices.push_back( 2 );
indices.push_back( 2 );
indices.push_back( 3 );
indices.push_back( 0 );
scene::SMeshBuffer *buf = new scene::SMeshBuffer();
SMesh *mesh = new SMesh();
buf->append(vertices.pointer(), vertices.size(), indices.pointer(), indices.size() );
mesh->addMeshBuffer(buf);
buf->Material.setFlag(video::EMF_LIGHTING, true);
buf->drop();
irr::scene::ISceneNode *node = smgr->addMeshSceneNode(mesh);
node->setDebugDataVisible(irr::scene::EDS_NORMALS);
}
// manage to close this app with the escape key
class EventReceiver_close : public IEventReceiver
{
private:
IrrlichtDevice *Device;
public:
EventReceiver_close ( IrrlichtDevice *device ): Device ( device ) {}
virtual bool OnEvent(const SEvent& event)
{
if (event.EventType == irr::EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown)
{
if(event.KeyInput.Key == irr::KEY_ESCAPE)
{
Device->closeDevice();
return true;
}
}
return false;
}
};
int main()
{
IrrlichtDevice *device =
createDevice( video::EDT_OPENGL, dimension2d<u32>(640, 480), 16,
false, false, false, 0);
if (!device)
return 0;
EventReceiver_close receiver(device);
device->setEventReceiver(&receiver);
device->setWindowCaption(L"Hello World! - Irrlicht Engine Demo");
device->getCursorControl()->setVisible(false);
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
IGUIEnvironment* guienv = device->getGUIEnvironment();
smgr->setAmbientLight(irr::video::SColorf(0.2f, 0.2f, 0.f, 1.0f));
ICameraSceneNode * camera = smgr->addCameraSceneNodeFPS(0, 50, 0.2);
camera->setPosition(vector3df(0, 20, 0));
camera->setTarget(vector3df(0,0,0));
// create two mesh with different size,
// one just nearest other one
build_mesh(smgr, vector3df(0, 0, 0), vector3df(10, 10, 10));
build_mesh(smgr, vector3df(0, 0, 10), vector3df(30, 10, 10));
// add a light just top of the surfaces
smgr->addLightSceneNode( 0, irr::core::vector3df(0, 10, 10), irr::video::SColorf(1.0f, 1.0f, 1.0f), 3.0f, 1 );
// add a small block in same position of the light to undestand what happen
smgr->addCubeSceneNode(1, 0, -1, vector3df(0, 10, 10));
while(device->run())
{
driver->beginScene(true, true, SColor(255,0,0,0));
smgr->drawAll();
guienv->drawAll();
driver->endScene();
}
device->drop();
return 0;
}
So where I am wrong ?
Thanks in advance,
Jérôme