Shining a spotlight onto a surface. EPT_SPOT?

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
pandoragami
Posts: 226
Joined: Wed Jan 26, 2011 5:37 pm
Contact:

Shining a spotlight onto a surface. EPT_SPOT?

Post by pandoragami »

Here's the code.

Code: Select all

 
#include "irrlicht.h"
#include <cstdlib>
#include <iostream>
 
using namespace irr;
 
class EventReceiver : public irr::IEventReceiver
{
    public:
 
    virtual bool OnEvent(const irr::SEvent& event);
    virtual bool IsKeyDown( irr::EKEY_CODE keyCode) const;
    EventReceiver();
 
private:
 
    bool KeyIsDown[ irr::KEY_KEY_CODES_COUNT];
};
bool EventReceiver::OnEvent(const irr::SEvent& event)
{
 
    if (event.EventType == irr::EET_KEY_INPUT_EVENT)
        KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
 
    return false;
}
bool EventReceiver::IsKeyDown( irr::EKEY_CODE keyCode) const
{
    return KeyIsDown[keyCode];
}
 
EventReceiver::EventReceiver()
{
    for ( irr::u32 i = 0; i < irr::KEY_KEY_CODES_COUNT; ++i)
        KeyIsDown[i] = false;
}
 
scene::SMeshBuffer Buffer;
video::IVideoDriver* driver;
void init_indices()//this is supposed to create a triangle polygon. The indices represent the points of the vertices and the point zero is the beginning and endpoint.
{
    int index = Buffer.Indices.size();
 
     Buffer.Indices.push_back(     index/3);
     Buffer.Indices.push_back( 2+index/3);
     Buffer.Indices.push_back( 3+index/3);
 
     Buffer.Indices.push_back( 2+index/3);
     Buffer.Indices.push_back( 1+index/3);
     Buffer.Indices.push_back( 3+index/3);
 
     Buffer.Indices.push_back( 1+index/3);
     Buffer.Indices.push_back(     index/3);
     Buffer.Indices.push_back( 3+index/3);
 
     Buffer.Indices.push_back( 2+index/3);
     Buffer.Indices.push_back(     index/3);
     Buffer.Indices.push_back( 1+index/3);
 
    std::cout<<"Buffer.getVertices(). "<<Buffer.getVertices();
    std::cout<<", Buffer.getVertexCount(). "<<Buffer.getVertexCount();
    std::cout<<", Buffer.getIndices(). "<<Buffer.getIndices();
    std::cout<<", Buffer.Indices.size()/3. "<<Buffer.Indices.size()/3<<std::endl;
}
void init_points( int x, int y, int z)
{
    video::SColor color( 0, 255, 0, 0);
 
    Buffer.Vertices.push_back( video::S3DVertex(     x,     y,   10+z, 1,1,0,   video::SColor(255,0,255,255), 0, 1));
    Buffer.Vertices.push_back( video::S3DVertex(  10+x,    y,      z, 1,0,0,video::SColor(255,255,0,255), 1, 1));
    Buffer.Vertices.push_back( video::S3DVertex(     x, y+10,     z, 0,1,1, video::SColor(255,255,255,0), 1, 0));
    Buffer.Vertices.push_back(video::S3DVertex(       x,    y,      z, 0,0,1,   video::SColor(255,0,255,0)  , 0, 0));
 
    init_indices();
}
 
void render()
{
   video::SMaterial material;
   material.Wireframe = false;
   material.Lighting = true;
   material.BackfaceCulling = true;
   material.DiffuseColor = irr::video::SColor( 255, 0, 0, 255);
   material.SpecularColor = irr::video::SColor( 255, 0, 0, 255);
   material.setTexture( 0, driver->getTexture("ice2.jpg") );
   driver->setMaterial( material);
 
   driver->drawVertexPrimitiveList
                                        (
                                        Buffer.getVertices(),
                                        Buffer.getVertexCount(),
                                        Buffer.getIndices(),
                                        Buffer.Indices.size()/3,
                                        video::EVT_STANDARD,
                                        irr::scene::EPT_TRIANGLES,
                                        video::EIT_16BIT
                                        );
}
int main()
{
    EventReceiver receiver;
    IrrlichtDevice *device = createDevice( irr::video::EDT_OPENGL,
                                       irr::core::dimension2d< irr::u32>( 1024, 768),
                                       16,
                                       false,
                                       false,
                                       false,
                                       &receiver);
 
    if (device == 0)
        return 1;
 
    device->setWindowCaption(L"IRRLICHT");
    driver = device->getVideoDriver();
    scene::ISceneManager* smgr = device->getSceneManager();
    driver->setTextureCreationFlag( irr::video::ETCF_CREATE_MIP_MAPS, true);
    irr::scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS( 0, 60.0f, 0.001f, -1, 0, 0, false, 0.0f, false, true);
    cam->setTarget( core::vector3df(0,0,0));
    cam->setPosition( core::vector3df(0,0,-15));
 
    device->getCursorControl()->setVisible( false);
 
    init_points( 0, 0, 0);
 
    irr::scene::ILightSceneNode* light1 =
    smgr->addLightSceneNode(0, irr::core::vector3df(0,0,-5),
    irr::video::SColorf(0.0f, 0.0f, 1.0f, 1.0f), 100.0f);
 
    irr::video::SLight light1_data;
    light1_data.Direction = irr::core::vector3df(0,0,0);
    light1_data.Type = irr::video::ELT_SPOT;
    light1_data.AmbientColor = irr::video::SColorf(0.0f,1.0f,0.0f,1);
    light1_data.SpecularColor = irr::video::SColorf(1.0f,0.0f,0.0f,1);//this doesn't work
    light1_data.DiffuseColor = irr::video::SColorf(0.0f,0.0f,1.0f,1);//this doesn't work
    light1_data.InnerCone = 0.0f;
    light1_data.OuterCone = 10.0f;
    light1_data.Falloff = 10.0f;
    light1_data.Attenuation =  irr::core::vector3df( 0.0f, 0.5f, 0.0f);
    light1_data.CastShadows = false;
    light1->setLightData( light1_data);
 
    u32 frames=0;
    while(device->run())
    {
        driver->beginScene( true, true, video::SColor( 0, 0, 0, 0));
        render();
        smgr->drawAll();
 
        driver->endScene();
        if (++frames==100)
        {
            core::stringw str = L"Irrlicht Engine [";
            str += driver->getName();
            str += L"] FPS: ";
            str += (s32)driver->getFPS();
 
            device->setWindowCaption(str.c_str());
            frames=0;
        }
    }
 
    device->drop();
 
    return 0;
}
 
 
The problem I'm having is trying to set the SLight settings on lines 129 to 139 in order to get a spotlight on the surface of a polygon. The best that I could do is what has been coded; it creates a light at -5 on the z axis and the camera at -15 (same axis). Both the camera and the light points towards the polygon at the origin, but it seems the light shines slightly below and to the left at a 45 degree angle. Any suggestions on setting it up.

I also wanted to ask about the two lines

Code: Select all

 
    light1_data.SpecularColor = irr::video::SColorf(1.0f,0.0f,0.0f,1);//this doesn't work
    light1_data.DiffuseColor = irr::video::SColorf(0.0f,0.0f,1.0f,1);//this doesn't work
 
I tried changing the variables and they don't seem to do much, is there something maybe missing with the Smaterial settings that I didn't code?

I set them on line 83-84.

Code: Select all

material.DiffuseColor = irr::video::SColor( 255, 0, 0, 255);
   material.SpecularColor = irr::video::SColor( 255, 0, 0, 255);
Mel
Competition winner
Posts: 2292
Joined: Wed May 07, 2008 11:40 am
Location: Granada, Spain

Re: Shining a spotlight onto a surface. EPT_SPOT?

Post by Mel »

Irrlicht lights work per vertex, try creating a surface with many vertices, and check again.
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
pandoragami
Posts: 226
Joined: Wed Jan 26, 2011 5:37 pm
Contact:

Re: Shining a spotlight onto a surface. EPT_SPOT?

Post by pandoragami »

Mel wrote:Irrlicht lights work per vertex, try creating a surface with many vertices, and check again.
I added hundreds of individual pyramids as a single wall and now it looks better but I still can seem to get an effect from the Specular and Diffuse color. Not sure if that's setup properly. The code below changes the rotation of the light node( line 168) by a small increment in the x degree.

Code: Select all

 
#include "irrlicht.h"
#include <cstdlib>
#include <iostream>
#include <cmath>
 
using namespace irr;
 
class EventReceiver : public irr::IEventReceiver
{
    public:
 
    virtual bool OnEvent(const irr::SEvent& event);
    virtual bool IsKeyDown( irr::EKEY_CODE keyCode) const;
    EventReceiver();
 
private:
 
    bool KeyIsDown[ irr::KEY_KEY_CODES_COUNT];
};
bool EventReceiver::OnEvent(const irr::SEvent& event)
{
 
    if (event.EventType == irr::EET_KEY_INPUT_EVENT)
        KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
 
    return false;
}
bool EventReceiver::IsKeyDown( irr::EKEY_CODE keyCode) const
{
    return KeyIsDown[keyCode];
}
 
EventReceiver::EventReceiver()
{
    for ( irr::u32 i = 0; i < irr::KEY_KEY_CODES_COUNT; ++i)
        KeyIsDown[i] = false;
}
 
scene::SMeshBuffer Buffer;
video::IVideoDriver* driver;
void init_indices()//this is supposed to create a triangle polygon. The indices represent the points of the vertices and the point zero is the beginning and endpoint.
{
    int index = Buffer.Indices.size();
 
     Buffer.Indices.push_back(     index/3);
     Buffer.Indices.push_back( 2+index/3);
     Buffer.Indices.push_back( 3+index/3);
 
     Buffer.Indices.push_back( 2+index/3);
     Buffer.Indices.push_back( 1+index/3);
     Buffer.Indices.push_back( 3+index/3);
 
     Buffer.Indices.push_back( 1+index/3);
     Buffer.Indices.push_back(     index/3);
     Buffer.Indices.push_back( 3+index/3);
 
     Buffer.Indices.push_back( 2+index/3);
     Buffer.Indices.push_back(     index/3);
     Buffer.Indices.push_back( 1+index/3);
 
 
}
void init_points( float x, float y, float z)
{
    video::SColor color( 0, 255, 0, 0);
 
    Buffer.Vertices.push_back( video::S3DVertex(     x,     y,   .1+z, 1,1,0,   video::SColor(255,0,255,255), 0, 1));
    Buffer.Vertices.push_back( video::S3DVertex(  .1+x,    y,      z, 1,0,0,video::SColor(255,255,0,255), 1, 1));
    Buffer.Vertices.push_back( video::S3DVertex(     x, y+.1,     z, 0,1,1, video::SColor(255,255,255,0), 1, 0));
    Buffer.Vertices.push_back(video::S3DVertex(       x,    y,      z, 0,0,1,   video::SColor(255,0,255,0)  , 0, 0));
 
    init_indices();
}
 
void render()
{
   video::SMaterial material;
   material.Wireframe = false;
   material.Lighting = true;
   material.BackfaceCulling = true;
   material.DiffuseColor = irr::video::SColor( 255, 0, 0, 255);
   material.SpecularColor = irr::video::SColor( 255, 0, 0, 255);
   material.setTexture( 0, driver->getTexture("ice2.jpg") );
   driver->setMaterial( material);
 
   driver->drawVertexPrimitiveList
                                        (
                                            Buffer.getVertices(),
                                            Buffer.getVertexCount(),
                                            Buffer.getIndices(),
                                            Buffer.Indices.size()/3,
                                            video::EVT_STANDARD,
                                            irr::scene::EPT_TRIANGLES,
                                            video::EIT_16BIT
                                        );
}
 
int main()
{
    EventReceiver receiver;
    IrrlichtDevice *device = createDevice( irr::video::EDT_OPENGL,
                                       irr::core::dimension2d< irr::u32>( 1024, 768),
                                       16,
                                       false,
                                       false,
                                       false,
                                       &receiver);
 
    if (device == 0)
        return 1;
 
    device->setWindowCaption(L"IRRLICHT");
    driver = device->getVideoDriver();
    scene::ISceneManager* smgr = device->getSceneManager();
    driver->setTextureCreationFlag( irr::video::ETCF_CREATE_MIP_MAPS, true);
    irr::scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS( 0, 60.0f, 0.001f, -1, 0, 0, false, 0.0f, false, true);
    cam->setTarget( core::vector3df(0,0,0));
    cam->setPosition( core::vector3df(0,0,-5));
 
    device->getCursorControl()->setVisible( false);
 
    for( float x = -5; x < 5; x+= .1)
        for( float y = -5; y < 5; y+= .1)
            init_points( x, y, 0);
 
    std::cout<<"Buffer.getVertices(). "<<Buffer.getVertices();
    std::cout<<", Buffer.getVertexCount(). "<<Buffer.getVertexCount();
    std::cout<<", Buffer.getIndices(). "<<Buffer.getIndices();
    std::cout<<", Buffer.Indices.size()/3. "<<Buffer.Indices.size()/3<<std::endl;
 
    irr::scene::ILightSceneNode* light1 =
    smgr->addLightSceneNode(0, irr::core::vector3df(0,0,-2),
    irr::video::SColorf( 0.0f, 0.0f, 1.0f, 1.0f), 100.0f);
 
    light1->setVisible( true);
    light1->enableCastShadow( true);
 
    irr::video::SLight light1_data;
    light1_data.Direction = irr::core::vector3df(0,0,0);
    light1_data.Type = irr::video::ELT_SPOT;
    light1_data.AmbientColor = irr::video::SColorf(0.0f,1.0f,0.0f,1);
    light1_data.SpecularColor = irr::video::SColorf(1.0f,0.0f,0.0f,1);//this doesn't work
    light1_data.DiffuseColor = irr::video::SColorf(0.0f,0.0f,1.0f,1);//this doesn't work
    light1_data.InnerCone = 0.0f;
    light1_data.OuterCone = 40.0f;
    light1_data.Falloff = 10.0f;
    light1_data.Attenuation =  irr::core::vector3df( 0.0f, 0.5f, 0.0f);
    light1_data.CastShadows = false;
    light1->setLightData( light1_data);
 
    float x_rot = 0.0f;
 
    u32 frames=0;
    while(device->run())
    {
        driver->beginScene( true, true, video::SColor( 0, 0, 0, 0));
        render();
        smgr->drawAll();
 
        driver->endScene();
        if (++frames==100)
        {
            core::stringw str = L"Irrlicht Engine [";
            str += driver->getName();
            str += L"] FPS: ";
            str += (s32)driver->getFPS();
 
            light1->setRotation( irr::core::vector3df( x_rot, 0, 0));
 
            device->setWindowCaption(str.c_str());
            frames=0;
        }
 
        x_rot += 0.01f;
    }
 
    device->drop();
 
    return 0;
}
 
 
Seven
Posts: 1034
Joined: Mon Nov 14, 2005 2:03 pm

Re: Shining a spotlight onto a surface. EPT_SPOT?

Post by Seven »

the attenuation value seems very high.
in the ILight code, the attenuation gets set automagially when setRadius is used.
pandoragami
Posts: 226
Joined: Wed Jan 26, 2011 5:37 pm
Contact:

Re: Shining a spotlight onto a surface. EPT_SPOT?

Post by pandoragami »

Seven wrote:the attenuation value seems very high.
in the ILight code, the attenuation gets set automagially when setRadius is used.

I changed it to lower value and moved the source back from the surfaces. Also changed lines 145-146

Code: Select all

 
  light1_data.SpecularColor = irr::video::SColorf(1.0f,1.0f,1.0f,0.0f);
    light1_data.DiffuseColor = irr::video::SColorf(1.0f,1.0f,1.0f,0.0f);
 
and now the surface has a different color on the left half compared to the right. I think it was the diffuse color that changed it, the specular color still
does nothing.

Code: Select all

 
#include "irrlicht.h"
#include <cstdlib>
#include <iostream>
#include <cmath>
 
using namespace irr;
 
class EventReceiver : public irr::IEventReceiver
{
    public:
 
    virtual bool OnEvent(const irr::SEvent& event);
    virtual bool IsKeyDown( irr::EKEY_CODE keyCode) const;
    EventReceiver();
 
private:
 
    bool KeyIsDown[ irr::KEY_KEY_CODES_COUNT];
};
bool EventReceiver::OnEvent(const irr::SEvent& event)
{
 
    if (event.EventType == irr::EET_KEY_INPUT_EVENT)
        KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
 
    return false;
}
bool EventReceiver::IsKeyDown( irr::EKEY_CODE keyCode) const
{
    return KeyIsDown[keyCode];
}
 
EventReceiver::EventReceiver()
{
    for ( irr::u32 i = 0; i < irr::KEY_KEY_CODES_COUNT; ++i)
        KeyIsDown[i] = false;
}
 
scene::SMeshBuffer Buffer;
video::IVideoDriver* driver;
void init_indices()//this is supposed to create a triangle polygon. The indices represent the points of the vertices and the point zero is the beginning and endpoint.
{
    int index = Buffer.Indices.size();
 
     Buffer.Indices.push_back(     index/3);
     Buffer.Indices.push_back( 2+index/3);
     Buffer.Indices.push_back( 3+index/3);
 
     Buffer.Indices.push_back( 2+index/3);
     Buffer.Indices.push_back( 1+index/3);
     Buffer.Indices.push_back( 3+index/3);
 
     Buffer.Indices.push_back( 1+index/3);
     Buffer.Indices.push_back(     index/3);
     Buffer.Indices.push_back( 3+index/3);
 
     Buffer.Indices.push_back( 2+index/3);
     Buffer.Indices.push_back(     index/3);
     Buffer.Indices.push_back( 1+index/3);
 
 
}
void init_points( float x, float y, float z)
{
    video::SColor color( 0, 255, 0, 0);
 
    Buffer.Vertices.push_back( video::S3DVertex(     x,     y,   .1+z, 1,1,0,   video::SColor(255,0,255,255), 0, 1));
    Buffer.Vertices.push_back( video::S3DVertex(  .1+x,    y,      z, 1,0,0,video::SColor(255,255,0,255), 1, 1));
    Buffer.Vertices.push_back( video::S3DVertex(     x, y+.1,     z, 0,1,1, video::SColor(255,255,255,0), 1, 0));
    Buffer.Vertices.push_back(video::S3DVertex(       x,    y,      z, 0,0,1,   video::SColor(255,0,255,0)  , 0, 0));
 
    init_indices();
}
 
void render()
{
   video::SMaterial material;
   material.Wireframe = false;
   material.Lighting = true;
   material.BackfaceCulling = true;
   material.DiffuseColor = irr::video::SColor( 255, 0, 0, 255);
   material.SpecularColor = irr::video::SColor( 255, 0, 0, 255);
   material.setTexture( 0, driver->getTexture("ice2.jpg") );
   material.setFlag( irr::video::EMF_FOG_ENABLE, true);
   driver->setMaterial( material);
 
   driver->drawVertexPrimitiveList
                                        (
                                            Buffer.getVertices(),
                                            Buffer.getVertexCount(),
                                            Buffer.getIndices(),
                                            Buffer.Indices.size()/3,
                                            video::EVT_STANDARD,
                                            irr::scene::EPT_TRIANGLES,
                                            video::EIT_16BIT
                                        );
}
 
int main()
{
    EventReceiver receiver;
    IrrlichtDevice *device = createDevice( irr::video::EDT_OPENGL,
                                       irr::core::dimension2d< irr::u32>( 1024, 768),
                                       16,
                                       false,
                                       false,
                                       false,
                                       &receiver);
 
    if (device == 0)
        return 1;
 
    device->setWindowCaption(L"IRRLICHT");
    driver = device->getVideoDriver();
    scene::ISceneManager* smgr = device->getSceneManager();
    driver->setTextureCreationFlag( irr::video::ETCF_CREATE_MIP_MAPS, true);
    irr::scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS( 0, 60.0f, 0.001f, -1, 0, 0, false, 0.0f, false, true);
    cam->setTarget( core::vector3df(0,0,0));
    cam->setPosition( core::vector3df(0,0,-5));
 
    device->getCursorControl()->setVisible( false);
 
    for( float x = -5; x < 5; x+= .1)
        for( float y = -5; y < 5; y+= .1)
            init_points( x, y, 0);
 
    std::cout<<"Buffer.getVertices(). "<<Buffer.getVertices();
    std::cout<<", Buffer.getVertexCount(). "<<Buffer.getVertexCount();
    std::cout<<", Buffer.getIndices(). "<<Buffer.getIndices();
    std::cout<<", Buffer.Indices.size()/3. "<<Buffer.Indices.size()/3<<std::endl;
 
    driver->setFog(video::SColor( 0, 0, 100, 0), irr::video::EFT_FOG_EXP, 0, 10, 0.05f, true, false);
 
    irr::scene::ILightSceneNode* light1 =
    smgr->addLightSceneNode(0, irr::core::vector3df(0,0,-20),
    irr::video::SColorf( 0.0f, 0.0f, 1.0f, 1.0f), 21.0f);
 
    light1->setVisible( true);
    light1->enableCastShadow( true);
 
    irr::video::SLight light1_data;
    light1_data.Direction = irr::core::vector3df( 0, 0, 0);
    light1_data.Type = irr::video::ELT_SPOT;
    light1_data.AmbientColor = irr::video::SColorf(1.0f,0.0f,0.0f,0.0f);
    light1_data.SpecularColor = irr::video::SColorf(1.0f,1.0f,1.0f,0.0f);
    light1_data.DiffuseColor = irr::video::SColorf(1.0f,1.0f,1.0f,0.0f);
    light1_data.InnerCone = 0.0f;
    light1_data.OuterCone = 5.0f;
    light1_data.Falloff = 0.0f;
    light1_data.Attenuation =  irr::core::vector3df( 0.00005f, 0.00005f, 0.00005f);
    light1_data.CastShadows = true;
    light1->setLightData( light1_data);
 
    float x_rot = 0.0f;
 
    u32 frames=0;
    while(device->run())
    {
        driver->beginScene( true, true, video::SColor( 0, 0, 0, 0));
        render();
        smgr->drawAll();
 
        driver->endScene();
        if (++frames==100)
        {
            core::stringw str = L"Irrlicht Engine [";
            str += driver->getName();
            str += L"] FPS: ";
            str += (s32)driver->getFPS();
 
            light1->setRotation( irr::core::vector3df( x_rot, 0, 0));
 
            device->setWindowCaption(str.c_str());
            frames=0;
        }
 
        //x_rot += 0.05f;
    }
 
    device->drop();
 
    return 0;
}
 
 
Mel
Competition winner
Posts: 2292
Joined: Wed May 07, 2008 11:40 am
Location: Granada, Spain

Re: Shining a spotlight onto a surface. EPT_SPOT?

Post by Mel »

Also, enable the "normalize normals" flag on the materials to see if that improves the lighting
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
pandoragami
Posts: 226
Joined: Wed Jan 26, 2011 5:37 pm
Contact:

Re: Shining a spotlight onto a surface. EPT_SPOT?

Post by pandoragami »

Mel wrote:Also, enable the "normalize normals" flag on the materials to see if that improves the lighting
Tried it and didn't see any difference. I'm guessing this thread is solved though for the most part, thanks!
Post Reply