- The models in this test got scaled to 0 in one direction. Which is always a bit tricky as front and back-side polygons end up being drawn at the same depth. So that can cause models going black. Better to use some minimal scaling like 0.001 or so.
- We have no pixel-lighting, but polygon lighting, so yeah - that shows.
- Behavior on GL and D3D different because GL doesn't have a fixed range at which it cuts of light (just something I noticed because it was a nice test, but not going to get changed)
Aside from that I found no bug - things look lighted correctly. Thought because of the scaling to 0 they can pop-in/out very abruptly. And certainly due to angles between light/camera mattering you can see half the objects in the test then sometimes and other half is black.
Test I used in the end was a simplified version of the test send to me (needs some models to run)
Code: Select all
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
#include <irrlicht.h>
using namespace irr;
#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif
float randf(float min, float max)
{
return (max - min) * ((((float) rand()) / (float) RAND_MAX)) + min ;
}
int main()
{
srand ((unsigned int)time(0));
video::E_DRIVER_TYPE driverType = video::EDT_OPENGL;
IrrlichtDevice* device = createDevice(driverType,
core::dimension2d<u32>(1280, 720), 32,
false, true, false, 0);
if (!device)
return 1; // could not create selected driver.
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
const f32 lightRadius = 150.0f;
scene::ILightSceneNode* l = smgr->addLightSceneNode(0, core::vector3df(100.f,11.f,100.f),
video::SColorf(1.f, 1.f, 1.f, 1.0f), lightRadius);
l->setLightType(video::ELT_POINT);
l->setDebugDataVisible(scene::EDS_BBOX); // not showing up?
video::SLight& lightData = l->getLightData();
irr::core::vector3df at = lightData.Attenuation;
l->setRadius(sqrt(FLT_MAX));
lightData.Attenuation = at;
smgr->setAmbientLight(video::SColorf(0.f, 0.f, 0.f, 1.0f));
scene::IAnimatedMesh* tmesh = smgr->getMesh("media_camacho/terrain.obj");
scene::ISceneNode *node = smgr->addMeshSceneNode(tmesh);
if ( node )
{
node->setMaterialFlag(video::EMF_LIGHTING, true);
node->getMaterial(0).Shininess = 0.0f;
}
// Can use createCylinderMesh and rotated mesh 90 degrees for similar mesh
scene::IMesh* cylinderMesh = smgr->getMesh("media_camacho/drum.obj");
for (int i=0; i<200; i++)
{
scene::ISceneNode * boxNode = smgr->addCubeSceneNode(1.f,0,-1,
core::vector3df(randf(-40.f,40.f), randf(10.5f,15.f), randf(-40.f,40.f)),
core::vector3df(0.f, 0.f, 0.f),
core::vector3df(randf(0.5f,1.f), randf(0.5f,1.f), randf(0.5f,1.f)));
boxNode->setMaterialTexture(0, driver->getTexture("../../media/t351sml.jpg"));
boxNode->setMaterialFlag(video::EMF_LIGHTING, true);
boxNode->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
scene::ISceneNode * cylinderNode = smgr->addMeshSceneNode(cylinderMesh, 0, -1,
core::vector3df(randf(-40.f,40.f), randf(0.5f,15.f), randf(-40.f,40.f)),
core::vector3df(0, 0, 0),
core::vector3df(randf(0.5f,1.f), randf(4.f,8.f), 0.1f));
//core::vector3df(4.f, 4.f, 4.f));
cylinderNode->setMaterialFlag(video::EMF_LIGHTING, true);
cylinderNode->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
//cylinderNode->setDebugDataVisible(scene::EDS_NORMALS);
}
scene::ISceneNode* floor = smgr->addCubeSceneNode(1.f,0,-1,
core::vector3df(0.f, 0.f, 0.f),core::vector3df(0.f, 0.f, 0.f),
core::vector3df(200.f,0.1f,200.f));
if (floor)
{
floor->setMaterialTexture(0, driver->getTexture("../../media/wall.jpg"));
floor->setMaterialFlag(video::EMF_LIGHTING, true);
floor->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
floor->getMaterial(0).getTextureMatrix(0).setTextureScale(20,20);
}
scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS(0, 20.f, 0.05f);
cam->setPosition(core::vector3df(0.f, 16.f, 12.f));
cam->setTarget (core::vector3df(0.f,0.f,0.f));
device->getCursorControl()->setVisible(false);
while(device->run())
{
driver->beginScene(true, true, video::SColor(255,0,0,127));
smgr->drawAll(); // draw the 3d scene
// some debug-lines for light
video::SMaterial matDbg;
matDbg.Lighting = false;
driver->setMaterial(matDbg);
driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
core::vector3df sx(lightRadius,0,0);
core::vector3df sy(0,lightRadius,0);
core::vector3df sz(0,0,lightRadius);
driver->draw3DLine( l->getPosition(), l->getPosition() - sx, video::SColor(255, 255, 255, 255) );
driver->draw3DLine( l->getPosition(), l->getPosition() + sx, video::SColor(255, 255, 255, 255) );
driver->draw3DLine( l->getPosition(), l->getPosition() - sy, video::SColor(255, 255, 255, 255) );
driver->draw3DLine( l->getPosition(), l->getPosition() + sy, video::SColor(255, 255, 255, 255) );
driver->draw3DLine( l->getPosition(), l->getPosition() - sz, video::SColor(255, 255, 255, 255) );
driver->draw3DLine( l->getPosition(), l->getPosition() + sz, video::SColor(255, 255, 255, 255) );
driver->endScene();
}
device->drop();
return 0;
}