Grass Patch Scene Node doesn't work with Realistic Water

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
archmagus
Posts: 25
Joined: Sat May 30, 2015 4:18 am
Location: Australia

Grass Patch Scene Node doesn't work with Realistic Water

Post by archmagus »

Hi

Since I've been trying to learn to use Irrlicht's various extensions I decided to put together a little demo of a nice grassy area with some water, using the Grass Scene Node from IrrExt and Elvman's Realistic Water scene node.
When I put them together in the same scene however, the grass will not appear.

This is a modified version of the Grass example program from IrrExt, I have removed the event receiver and collision parts because they not necessary for this particular example. I also made a minor fix, TextureLayer[0].TextureWrap is now TextureLayer[0].TextureWrapU(/V).
Note there is no skybox so the Realistic Water will reflect black if you try this.

Code: Select all

 
#include <irrlicht.h>
      
using namespace irr;  
 
#include "CGrassPatchSceneNode.h"
#include "CWindGenerator.h"
#include "RealisticWater.h"
   
video::ITexture *tex1;
scene::IWindGenerator *wind;
 
#define width  10
#define height 10
#define total  width*height
 
int main()
{
    // create device
    IrrlichtDevice* device = createDevice(video::EDT_OPENGL, core::dimension2d<u32>(1360, 700));
 
    if (device == 0)
        return 1; // could not create selected driver.
  
    video::IVideoDriver* driver = device->getVideoDriver();
    scene::ISceneManager* smgr = device->getSceneManager();
   
    driver->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, true);
    
    // add camera
    scene::ICameraSceneNode* camera = 
        smgr->addCameraSceneNodeFPS(0, 100.0f, 1.20f, -1, 0, 0);//, false);
 
    camera->setPosition(core::vector3df(1000,500,1000));
    camera->setFarValue(12000.0f);
 
    // create wind...
    wind = scene::createWindGenerator( 30.0f, 3.0f );
 
    // disable mouse cursor
    device->getCursorControl()->setVisible(false);
 
    // add terrain scene node
    scene::ITerrainSceneNode* terrain = smgr->addTerrainSceneNode("media/terrain-heightmap.bmp");
    if (!terrain)
        return 1;
 
    video::IImage* heightMap  = driver->createImageFromFile ("media/terrain-heightmap.bmp");  
    video::IImage* textureMap = driver->createImageFromFile ("media/terrain-grasscol.bmp");  
    video::IImage* grassMap   = driver->createImageFromFile ("media/terrain-grassmap.png"); 
 
    terrain->setScale(core::vector3df(20, 3.0f, 20));
    terrain->setPosition( core::vector3df(0,0,0) );
 
    terrain->setMaterialFlag(video::EMF_LIGHTING, false);
 
    terrain->setMaterialTexture(0, driver->getTexture("media/terrain-texture.jpg"));
    terrain->setMaterialTexture(1, driver->getTexture("media/detailmap3.jpg")); 
 
    terrain->setMaterialType(video::EMT_DETAIL_MAP);
 
    terrain->scaleTexture(1.0f, 20.0f);
 
    scene::CGrassPatchSceneNode *grass[width*height];
 
    int lastFPS = -1;
    tex1 = driver->getTexture("media/grass.png");
  
    //now we add some grass nodes
    for (int x=0; x<width; ++x)
      for (int z=0; z<height; ++z)
      {   
        // add a grass node        
        grass[x*width + z] = new scene::CGrassPatchSceneNode(terrain, smgr, -1, core::vector3d<s32>(x,0,z), "grass", heightMap, textureMap, grassMap, wind);
        grass[x*width + z]->setMaterialFlag(video::EMF_LIGHTING, false);
        grass[x*width + z]->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL);
        grass[x*width + z]->getMaterial(0).TextureLayer[0].TextureWrapU = video::ETC_CLAMP;
        grass[x*width + z]->getMaterial(0).TextureLayer[0].TextureWrapV = video::ETC_CLAMP;
        grass[x*width + z]->getMaterial(0).MaterialTypeParam = 0.5f;
        grass[x*width + z]->setMaterialTexture(0, tex1);
        //grass[x*width + z]->setDebugDataVisible(-1);
        grass[x*width + z]->drop();
    }
 
    smgr->getParameters()->setAttribute(scene::ALLOW_ZWRITE_ON_TRANSPARENT, true);
 
    RealisticWaterSceneNode* water = new RealisticWaterSceneNode(smgr, 6000.f, 6000.f);
    water->setPosition(core::vector3df(2500,300,2500));
    
    smgr->getRootSceneNode()->addChild(water);
    
    while(device->run())
    if (device->isWindowActive())
    {
                                 
        driver->beginScene(true, true, video::SColor(0,50,50,200) );
 
        smgr->drawAll();
 
        driver->endScene();
        if (camera->getPosition().Y < -300.0f)
            camera->setPosition(core::vector3df(1000,500,1000));
             
        // display frames per second in window title
        int fps = driver->getFPS();
        if (lastFPS != fps)
        {
            core::stringw str = L"Irrlicht! [";
            str += driver->getName();
            str += "] FPS:";
            str += fps;
            str += ", Tri:";
            str += s32(driver->getPrimitiveCountDrawn());
 
            device->setWindowCaption(str.c_str());
            lastFPS = fps;
        }
    }
 
    heightMap->drop();
    textureMap->drop();
    grassMap->drop();
 
    device->drop();
    
    return 0;
}
 
 
 
This is the relevant part for adding water:

Code: Select all

 
RealisticWaterSceneNode* water = new RealisticWaterSceneNode(smgr, 6000.f, 6000.f);
water->setPosition(core::vector3df(2500,300,2500));
    
smgr->getRootSceneNode()->addChild(water);
 
If I comment this out, the Grass displays fine (but I obviously have no water then). :?
Compiling with -Wall -Wextra doesn't give me any relevant warnings, make clean had no effect.

I am using OpenGL and Irrlicht 1.8 from SVN.

Edit:
Links to the IrrExt Grass Node and Elvman's Realistic Water Scene Node.
archmagus
Posts: 25
Joined: Sat May 30, 2015 4:18 am
Location: Australia

Re: Grass Patch Scene Node doesn't work with Realistic Water

Post by archmagus »

Just tested this Irrlicht 1.9 (trunk 5107) and it has the same problem, so this is a problem in one of the custom nodes.
I really don't understand how the Realistic Water node could interfere with the Grass Patch Node... :(
kornwaretm
Competition winner
Posts: 189
Joined: Tue Oct 16, 2007 3:53 am
Location: Indonesia
Contact:

Re: Grass Patch Scene Node doesn't work with Realistic Water

Post by kornwaretm »

You need to check the near and far value. Also try to use EMT_TRANSPARENT_ALPH_CHANNEL_REF as far as i know sorting is better. Your grass material parameter need adjustment for a different texture. Try to change it or use the default value
archmagus
Posts: 25
Joined: Sat May 30, 2015 4:18 am
Location: Australia

Re: Grass Patch Scene Node doesn't work with Realistic Water

Post by archmagus »

Adjusting the camera's near and far had no effect, i don't think this is a problem with Irrlicht either, rather with the custom nodes.

Pictures:
With Water Node and Grass Node at the same time:
Image

Water Disabled (water->setVisble(false)):
Image
Grass works fine waves in the wind, more grass appears as I move.

Water Re-enabled:
Image
When the water has been re enabled, the grass doesn't wave in the wind and no new grass appears when I move the Camera.

(White boxes are the debug outlines)
Essentially no new grass appears when the water is visible, but it acts fine when the water is not visible.
archmagus
Posts: 25
Joined: Sat May 30, 2015 4:18 am
Location: Australia

Re: Grass Patch Scene Node doesn't work with Realistic Water

Post by archmagus »

Ok it's kind of fixed, this line of code in CGrassPatchSceneNode.cpp:271

Code: Select all

 
    redrawnextloop = false;
 
can be changed to redrawnextloop = true. Grass and Water will now work together, at the expense of performance.
I am unsure what this bit of code does exactly but it seems to me that it is responsible for an optimization regarding redrawing the grass.
FPS drops by about 120FPS because now the grass's rotation/etc is recalculated every frame rather than only when it is agitated by the wind. :shock:

Still trying to figure out why the Water Node might interfere with this. :?
Granyte
Posts: 850
Joined: Tue Jan 25, 2011 11:07 pm
Contact:

Re: Grass Patch Scene Node doesn't work with Realistic Water

Post by Granyte »

well the water node call a draw all wich redraw the scene a second time every frame so maybe the grass did not enjoy beeing redrawn a second time without a end scene or something between
Post Reply