Environment Mapping with Irrlicht

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.

Re: Environment Mapping with Irrlicht

Postby Mel » Wed Jan 13, 2016 4:42 pm

Here you are!, i hope you don't mind me posting the code directly here :) This works with the latest SVN (and hopefully, so on) and you can find everything needed in the media directory of irrlicht, thus, the example aims to it as if it was any other example of the engine.

Source...
cpp Code: Select all
 
#include <irrlicht.h>
#include <iostream>
 
/*This example illustrates the usage of cubemaps. Given there are no predefined materials that use the cubemaps, we
have to provide our own, so this also illustrates the creation of shaders*/

 
/*This is our constants set callback for the cubemapped materials*/
class cubemapConstants : public irr::video::IShaderConstantSetCallBack
{
    int matWorldViewProjection;//Identifiers, much faster than string matching...
    int matViewInverse;
    int matWorld;
    int baseMap;
    int reflectionMap;
 
    bool firstRun;
    bool IsOpenGL;//Our constants set callback isn't limited to D3D9
 
    irr::video::IVideoDriver* driver; //Here so we can save a call during the execution
 
public:
    cubemapConstants(bool isGL)
    {
        IsOpenGL = isGL;
        firstRun = true;
    }
 
    void OnSetConstants(irr::video::IMaterialRendererServices* services, irr::s32 userData)
    {
        if(firstRun)
        {
            firstRun = false;
 
            driver = services->getVideoDriver();
            //Looking for our constants IDs...
            matViewInverse = services->getVertexShaderConstantID("matViewInverse");
 
            if(IsOpenGL)
            {
                baseMap = services->getPixelShaderConstantID("baseMap");
                reflectionMap = services->getPixelShaderConstantID("reflectionMap");
            }
            else
            {
                matWorldViewProjection=services->getVertexShaderConstantID("matWorldViewProjection");
                matWorld = services->getVertexShaderConstantID("matWorld");
            }
        }
 
        //Setting up our constants...
        irr::core::matrix4 mat;
 
        mat = driver->getTransform(irr::video::ETS_VIEW);
        mat.makeInverse();
        services->setVertexShaderConstant(matViewInverse,mat.pointer(),16);
 
        if(IsOpenGL)
        {
            int sampler=0;
            services->setPixelShaderConstant(baseMap,&sampler,1);
            sampler=1;
            services->setPixelShaderConstant(reflectionMap,&sampler,1);    
        }
        else
        {
            mat = driver->getTransform(irr::video::ETS_PROJECTION);
            mat *= driver->getTransform(irr::video::ETS_VIEW);
            mat *= driver->getTransform(irr::video::ETS_WORLD);
            services->setVertexShaderConstant(matWorldViewProjection,mat.pointer(),16);
 
            mat = driver->getTransform(irr::video::ETS_WORLD);
            services->setVertexShaderConstant(matWorld,mat.pointer(),16);
        }
    }
};
 
/*And our main*/
 
void main(void)
{
    irr::IrrlichtDevice* device;
    irr::video::IVideoDriver* driver;
    irr::scene::ISceneManager* manager;
    irr::video::ITexture* cubemap;
    irr::video::IImage* cubemapImages[6];
 
    //create the engine
    int value;
    std::cout<<"Pick driver 1:OpenGL 2:Direct3D9"<<std::endl;
    std::cin>>value;
 
    irr::SIrrlichtCreationParameters prm;
    prm.DriverType = value==1?irr::video::EDT_OPENGL:irr::video::EDT_DIRECT3D9;
    prm.WindowSize = irr::core::dimension2du(1024,768);
    device = createDeviceEx(prm);
 
    if( device != NULL )
    {
        cubemapConstants* cns = new cubemapConstants(prm.DriverType==irr::video::EDT_OPENGL);
        driver = device->getVideoDriver();
        manager = device->getSceneManager();
 
        //So far there are no materials ready to use a cubemap, so we provide our own.
        irr::s32 shader;
 
        if(prm.DriverType==irr::video::EDT_DIRECT3D9)
            shader = driver->getGPUProgrammingServices()->addHighLevelShaderMaterialFromFiles(
                "../media/shader.hlsl",
                "vs_main",
                irr::video::EVST_VS_2_0,
                "../media/shader.hlsl",
                "ps_main",
                irr::video::EPST_PS_2_0,
                cns,
                irr::video::EMT_SOLID
                );
        else //OpenGL
            shader = driver->getGPUProgrammingServices()->addHighLevelShaderMaterialFromFiles(
                "../media/shaderV.glsl",
                "main",
                irr::video::EVST_VS_2_0,
                "../media/shaderP.glsl",
                "main",
                irr::video::EPST_PS_2_0,
                cns,
                irr::video::EMT_SOLID
                );
 
        shader = shader==-1?0:shader; //Just in case something goes horribly wrong...
 
        //creating the cubemap... For now, Irrlicht's cubemaps need to be created on the fly out of images.
        //Loading the images
        cubemapImages[0] = driver->createImageFromFile("../media/irrlicht2_ft.jpg");
        cubemapImages[1] = driver->createImageFromFile("../media/irrlicht2_bk.jpg");
        cubemapImages[2] = driver->createImageFromFile("../media/irrlicht2_up.jpg");
        cubemapImages[3] = driver->createImageFromFile("../media/irrlicht2_dn.jpg");
        cubemapImages[4] = driver->createImageFromFile("../media/irrlicht2_lf.jpg");
        cubemapImages[5] = driver->createImageFromFile("../media/irrlicht2_rt.jpg");
 
        //creating the cubemap itself
        cubemap = driver->addTextureCubemap(
            "irrlicht2.cubemap",
            cubemapImages[0],
            cubemapImages[1],
            cubemapImages[2],
            cubemapImages[3],
            cubemapImages[4],
            cubemapImages[5]
        );
 
        //We're done with the images, so we're releasing them. Unlike the Textures, the Images can be dropped.
        for(int i=0;i<6;i++)
            cubemapImages[i]->drop();
 
        //creating the scene
        manager->addCameraSceneNodeFPS();
 
        //Adding a skybox...
        irr::scene::ISceneNode* node = manager->addSkyBoxSceneNode(
            driver->getTexture("../media/irrlicht2_up.jpg"),
            driver->getTexture("../media/irrlicht2_dn.jpg"),
            driver->getTexture("../media/irrlicht2_lf.jpg"),
            driver->getTexture("../media/irrlicht2_rt.jpg"),
            driver->getTexture("../media/irrlicht2_ft.jpg"),
            driver->getTexture("../media/irrlicht2_bk.jpg")
        );
 
        node->setRotation(irr::core::vector3df(0,-90.0f,0));//This way, the skybox matches the cubemap ;)
 
        //Add some rotating spheres and cubes...
        irr::scene::ISceneNode* root = manager->addEmptySceneNode();
        irr::scene::ISceneNodeAnimator* anim = manager->createRotationAnimator(irr::core::vector3df(0,0.1f,0));
        root->addAnimator(anim);
        anim->drop();
 
        for(int i=0;i<12;i++)
        {
            irr::scene::ISceneNode* sphere = manager->addSphereSceneNode(50.0f);
            sphere->setPosition(irr::core::vector3df(sin(2*i*irr::core::PI/12.0f)*350,0.0f,cos(2*i*irr::core::PI/12.0f)*350.0f));
            sphere->getMaterial(0).setTexture(0,driver->getTexture("../media/water.jpg"));
            sphere->getMaterial(0).setTexture(1,cubemap);
            sphere->getMaterial(0).MaterialType = (irr::video::E_MATERIAL_TYPE)shader;
            sphere->setParent(root);
        }
 
        irr::scene::ISceneNode* root2 = manager->addEmptySceneNode();
        irr::scene::ISceneNodeAnimator* anim2 = manager->createRotationAnimator(irr::core::vector3df(0.1f,0,0));
        root2->addAnimator(anim2);
        anim2->drop();
 
        for(int i=0;i<18;i++)
        {
            irr::scene::ISceneNode* sphere = manager->addCubeSceneNode(20.0f);
            sphere->setPosition(irr::core::vector3df(sin(2*i*irr::core::PI/12.0f)*260,0.0f,cos(2*i*irr::core::PI/12.0f)*260.0f));
            sphere->getMaterial(0).setTexture(0,driver->getTexture("../media/rockwall_height.bmp"));
            sphere->getMaterial(0).setTexture(1,cubemap);
            sphere->getMaterial(0).MaterialType = (irr::video::E_MATERIAL_TYPE)shader;
            sphere->setParent(root2);
        }
 
        irr::scene::ISceneNode* root3 = manager->addEmptySceneNode();
        irr::scene::ISceneNodeAnimator* anim3 = manager->createRotationAnimator(irr::core::vector3df(0,0,0.1f));
        root3->addAnimator(anim3);
        anim3->drop();
 
        for(int i=0;i<24;i++)
        {
            irr::scene::ISceneNode* sphere = manager->addSphereSceneNode(10.0f);
            sphere->setPosition(irr::core::vector3df(sin(2*i*irr::core::PI/12.0f)*80,0.0f,cos(2*i*irr::core::PI/12.0f)*80.0f));
            sphere->getMaterial(0).setTexture(0,driver->getTexture("../media/water.jpg"));
            sphere->getMaterial(0).setTexture(1,cubemap);
            sphere->getMaterial(0).MaterialType = (irr::video::E_MATERIAL_TYPE)shader;
            sphere->setParent(root3);
        }
 
        root2->setParent(root);
        root3->setParent(root2);
 
        //Add a dwarf...
        irr::scene::IAnimatedMesh* dwarf = manager->getMesh("../media/dwarf.x");
        irr::scene::ISceneNode* dwarfNode = manager->addAnimatedMeshSceneNode(dwarf);
        for(unsigned int i=0;i<dwarfNode->getMaterialCount();i++)
        {
            dwarfNode->getMaterial(i).setTexture(1,cubemap);
            dwarfNode->getMaterial(i).MaterialType = (irr::video::E_MATERIAL_TYPE)shader;
        }
       
        irr::s32 lastFPS = -1;
 
        while(device->run())
        {
            const irr::s32 fps = driver->getFPS();
            driver->beginScene();
            manager->drawAll();
            irr::core::stringw str = L"Irrlicht Engine - Cubemaps Example [";
            str += driver->getName();
            str += "] FPS:";
            str += fps;
 
            device->setWindowCaption(str.c_str());
            lastFPS = fps;
            driver->endScene();
        }
 
    }
}
 


Direct3D9 shader:
cpp Code: Select all
 
/*Shader code for DirectX*/
float4x4 matWorldViewProjection;
float4x4 matViewInverse;
float4x4 matWorld;
sampler2D baseMap;
samplerCUBE reflectionMap;
 
struct vertexIN
{
   float4 Position : POSITION0;
   float2 Texcoord : TEXCOORD0;
   float3 Normal :   NORMAL0;
};
 
struct vertexOUT
{
    float4 position : POSITION0;
    float2 texcoord : TEXCOORD0;
    float3 normal : TEXCOORD1;
    float3 viewDirection: TEXCOORD2;
};
 
vertexOUT vs_main(vertexIN IN)
{
    vertexOUT OUT;
    OUT.position = mul(IN.Position,matWorldViewProjection);
    OUT.normal = mul(float4(IN.Normal,0),matWorld).xyz;
    OUT.viewDirection = mul(float4(OUT.position.xyz,0),matViewInverse).xyz;
    OUT.texcoord = IN.Texcoord;
    return OUT;
}
 
struct pixelIN
{
    float2 texcoord : TEXCOORD0;
    float3 normal : TEXCOORD1;
    float3 viewDirection: TEXCOORD2;
};
 
 
float4 ps_main(pixelIN IN):color0
{
    float4 color = tex2D(baseMap,IN.texcoord);
    float3 reflection = normalize(reflect(IN.viewDirection,IN.normal));
    float4 reflectedColor = texCUBE(reflectionMap,reflection);
    return reflectedColor*color;
}
 


OpenGL shaders:
vertex:
cpp Code: Select all
 
/*Shader for Open GL*/
 
uniform mat4 matViewInverse; //We need to move the normal into world space so the reflections are accurate
 
varying vec2 Texcoord;
varying vec3 Normal;
varying vec3 ViewDirection;
 
void main()
{
   gl_Position = ftransform();
   Texcoord    = gl_MultiTexCoord0.xy;
   Normal      = gl_NormalMatrix * gl_Normal;
   ViewDirection = normalize(gl_Position.xyz);
   Normal      = (matViewInverse*vec4(Normal,0)).xyz;
   ViewDirection = (matViewInverse*vec4(ViewDirection,0)).xyz;
}
 


fragment:
cpp Code: Select all
 
/*Shader for Open GL*/
uniform sampler2D baseMap;
uniform samplerCube reflectionMap;
 
varying vec2 Texcoord;
varying vec3 Normal;
varying vec3 ViewDirection;
 
void main()
{
    vec4 color = texture(baseMap,Texcoord);
    vec3 reflection = normalize(reflect(ViewDirection,Normal));
    vec4 refl = texture(reflectionMap,reflection);
    gl_FragColor = color*refl;
}
 
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
User avatar
Mel
Competition winner
 
Posts: 2264
Joined: Wed May 07, 2008 11:40 am
Location: Granada, Spain

Re: Environment Mapping with Irrlicht

Postby kinkreet » Mon Mar 14, 2016 10:46 am

but the SVN version is not stable isn't it?
User avatar
kinkreet
 
Posts: 64
Joined: Thu Oct 31, 2013 7:53 pm
Location: Barcelona, Spain

Re: Environment Mapping with Irrlicht

Postby CuteAlien » Mon Mar 14, 2016 11:00 am

@kinkreet: I work with svn most of the time (doing jobs for companies). Once in a while I have to go back a few versions, but doesn't happen often and generally we fix it quickly when it happens.
IRC: #irrlicht on irc.freenode.net
Code snippets, patches&stuff: http://www.michaelzeilfelder.de/irrlicht.htm
Free racer created with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
User avatar
CuteAlien
Admin
 
Posts: 8514
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany

Re: Environment Mapping with Irrlicht

Postby kinkreet » Mon Mar 14, 2016 11:32 am

Awesome, thanks. I'll try the SVN with this cool demo ;)
User avatar
kinkreet
 
Posts: 64
Joined: Thu Oct 31, 2013 7:53 pm
Location: Barcelona, Spain

Re: Environment Mapping with Irrlicht

Postby Nadro » Mon Mar 14, 2016 5:34 pm

Few revs ago I added support for load cubemaps directly from PVR textures. IMO PVR is the best file format for texture handling in Irrlicht at now (it supports standard and cubemaps textures, both compressed and uncompressed formats and custom mipmaps).
Nadro
 
Posts: 1647
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

Re: Environment Mapping with Irrlicht

Postby kinkreet » Mon Mar 14, 2016 6:25 pm

Is there any PVR editor/exporter that does not require a license?

EDIT: Thanks @Nadro :)
Last edited by kinkreet on Mon Mar 14, 2016 9:02 pm, edited 1 time in total.
User avatar
kinkreet
 
Posts: 64
Joined: Thu Oct 31, 2013 7:53 pm
Location: Barcelona, Spain

Re: Environment Mapping with Irrlicht

Postby Nadro » Mon Mar 14, 2016 8:12 pm

You can use PVRTexTool from PowerVR SDK. It's free.
Nadro
 
Posts: 1647
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

Re: Environment Mapping with Irrlicht

Postby hendu » Mon Mar 14, 2016 8:49 pm

...but is it open source and available for all common platforms?
hendu
 
Posts: 2599
Joined: Sat Dec 18, 2010 12:53 pm

Re: Environment Mapping with Irrlicht

Postby kinkreet » Mon Mar 14, 2016 9:04 pm

"Our Tools and SDK can be used freely (i.e., no fees) for any commercial or non-commercial purpose. The code provided can be modified, cut and paste as well as integrated into other projects....."

https://community.imgtec.com/developers/powervr/installers/
User avatar
kinkreet
 
Posts: 64
Joined: Thu Oct 31, 2013 7:53 pm
Location: Barcelona, Spain

Re: Environment Mapping with Irrlicht

Postby Nadro » Tue Mar 15, 2016 12:49 am

hendu wrote:...but is it open source and available for all common platforms?

PVRTextTool is available for Windows, Linux and OSX (CLI + GUI). IIRC it isn't open source, but it shouldn't be a problem in this case.
Nadro
 
Posts: 1647
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

Re: Environment Mapping with Irrlicht

Postby hendu » Tue Mar 15, 2016 10:46 am

It is a problem: they may have embedded malfeatures, and users may be on non-x86 platforms. Like the recent Power8 workstation ;)
hendu
 
Posts: 2599
Joined: Sat Dec 18, 2010 12:53 pm

Re: Environment Mapping with Irrlicht

Postby Nadro » Tue Mar 15, 2016 1:57 pm

PVR format is relative simple, so there shouldn't be a problem to write exporter yourself. Spec is available at here: http://cdn.imgtec.com/sdk-documentation ... cation.pdf

Anyway I don't think there is a lot of people without non-x86 platforms whose design textures for Irrlicht based games :P There is also an option to convert textures remotely on x86 server via PVRTexTool command-line in that cases.
Nadro
 
Posts: 1647
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

Re: Environment Mapping with Irrlicht

Postby hendu » Tue Mar 15, 2016 9:22 pm

There is also an option to convert textures remotely on x86 server via PVRTexTool command-line in that cases.


That is, if you're willing to run IMG's closed-source blob.
hendu
 
Posts: 2599
Joined: Sat Dec 18, 2010 12:53 pm

Re: Environment Mapping with Irrlicht

Postby devsh » Wed Mar 16, 2016 9:00 am

What about Cube Map arrays??? (wink?)
User avatar
devsh
Competition winner
 
Posts: 1858
Joined: Tue Dec 09, 2008 6:00 pm
Location: UK

Re: Environment Mapping with Irrlicht

Postby Nadro » Wed Mar 16, 2016 12:05 pm

Texture arrays and cubemap arrays are not supported yet. We'll add texture arrays support after v1.9 release and cubemaps arrays in further future.
Nadro
 
Posts: 1647
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

PreviousNext

Return to Code Snippets

Who is online

Users browsing this forum: No registered users and 1 guest