Crash on setMaterialType

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
eejin
Posts: 97
Joined: Sun Jul 24, 2011 11:50 am

Crash on setMaterialType

Post by eejin »

Hi, I'm trying to combine the Custom mesh and the Shader example and apply this shader to that mesh.
But as soon as the setMaterialType is called, the program stops responding. So the material must be false.
Have I forgotten to set something?

Code: Select all

#include <irrlicht.h>
#include <iostream>
#include <vector>
//#include "simplexnoise.h"
 
using namespace irr;
using namespace video;
using namespace core;
using namespace scene;
using namespace io;
using namespace gui;
 
IrrlichtDevice* device = 0;
 
class MyShaderCallBack : public video::IShaderConstantSetCallBack
{
public:
 
    virtual void OnSetConstants(video::IMaterialRendererServices* services,
            s32 userData)
    {
        video::IVideoDriver* driver = services->getVideoDriver();
 
        core::matrix4 invWorld = driver->getTransform(video::ETS_WORLD);
        invWorld.makeInverse();
 
        services->setVertexShaderConstant("mInvWorld", invWorld.pointer(), 16);
 
        core::matrix4 worldViewProj;
        worldViewProj = driver->getTransform(video::ETS_PROJECTION);
        worldViewProj *= driver->getTransform(video::ETS_VIEW);
        worldViewProj *= driver->getTransform(video::ETS_WORLD);
 
        services->setVertexShaderConstant("mWorldViewProj", worldViewProj.pointer(), 16);
 
        core::vector3df pos = device->getSceneManager()->
            getActiveCamera()->getAbsolutePosition();
 
        services->setVertexShaderConstant("mLightPos", reinterpret_cast<f32*>(&pos), 3);
 
        // set light color
 
        video::SColorf col(0.0f,1.0f,1.0f,0.0f);
 
        services->setVertexShaderConstant("mLightColor", reinterpret_cast<f32*>(&col), 4);
 
        // set transposed world matrix
 
        core::matrix4 world = driver->getTransform(video::ETS_WORLD);
        world = world.getTransposed();
 
        services->setVertexShaderConstant("mTransWorld", world.pointer(), 16);
 
        // set texture, for textures you can use both an int and a float setPixelShaderConstant interfaces (You need it only for an OpenGL driver).
        s32 TextureLayerID = 0;
        services->setPixelShaderConstant("myTexture", &TextureLayerID, 1);
    }
};
 
 
class TMesh
{
private:
    u16 Width;
    u16 Height;
    f32 Scale;
    std::vector <std::vector<float> > Heights; 
public:
    SMesh* Mesh;
    
    TMesh() : Mesh(0), Width(0), Height(0), Scale(1.f)
    {
        Mesh = new SMesh();
    }
 
    ~TMesh()
    {
        Mesh->drop();
    }
 
    void init(int width, int height, f32 scale, IVideoDriver *driver)
    {
        Scale = scale;
        Width = width;
        Height = height;
        Heights.resize( Width , std::vector<float>( Height , 0 ) );
        
        for (int i = 0; i < Width; i++) {
            for (int j = 0; j < Height; j++) {
                Heights[i][j] = 0.f;
//              octave_noise_2d( 2.f, 20.f, 0.02f, i,j)*4;
            }
        }
        
        const u32 mp = driver -> getMaximalPrimitiveCount();
            
        const u32 sw = mp / (6 * Height);
 
        u32 i=0;
        for(u32 y0 = 0; y0 < Height; y0 += sw)
        {
            u16 y1 = y0 + sw;
            if (y1 >= Height)
                y1 = Height - 1;
            addstrip(y0, y1, i);
            ++i;
        }
        if (i<Mesh->getMeshBufferCount())
        {
            for (u32 j=i; j<Mesh->getMeshBufferCount(); ++j)
            {
                Mesh->getMeshBuffer(j)->drop();
            }
            Mesh->MeshBuffers.erase(i,Mesh->getMeshBufferCount()-i);
        }
        Mesh->setDirty();
        Mesh->recalculateBoundingBox();
    }
 
    void addstrip(u16 y0, u16 y1, u32 bufNum)
    {
        SMeshBuffer *buf = 0;
        if (bufNum<Mesh->getMeshBufferCount())
        {
            buf = (SMeshBuffer*)Mesh->getMeshBuffer(bufNum);
        }
        else
        {
            buf = new SMeshBuffer();
            Mesh->addMeshBuffer(buf);
            buf->drop();
        }
        buf->Vertices.set_used((1 + y1 - y0) * Width);
 
        u32 i=0;
        for (u16 y = y0; y <= y1; ++y)
        {
            for (u16 x = 0; x < Width; ++x)
            {
                const f32 z = Heights[y][x];
                const f32 xx = (f32)x;
                const f32 yy = (f32)y;
 
                S3DVertex& v = buf->Vertices[i++];
                v.Pos.set(x, z, y);
                v.Color=SColor(255,255,255,255);
                v.TCoords.set(xx, yy);
            }
        }
 
        buf->Indices.set_used(6 * (Width - 1) * (y1 - y0));
        i=0;
        for(u16 y = y0; y < y1; ++y)
        {
            for(u16 x = 0; x < Width - 1; ++x)
            {
                const u16 n = (y-y0) * Width + x;
                buf->Indices[i]=n;
                buf->Indices[++i]=n + Width;
                buf->Indices[++i]=n + Width + 1;
                buf->Indices[++i]=n + Width + 1;
                buf->Indices[++i]=n + 1;
                buf->Indices[++i]=n;
                ++i;
            }
        }
 
        buf->recalculateBoundingBox();
    }
};
 
class MyEventReceiver : public IEventReceiver
{
public:
    virtual bool OnEvent(const SEvent& event)
    {
        if (event.EventType == irr::EET_KEY_INPUT_EVENT)
            KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
 
        return false;
    }
 
    virtual bool IsKeyDown(EKEY_CODE keyCode) const
    {
        return KeyIsDown[keyCode];
    }
 
    MyEventReceiver()
    {
        for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
            KeyIsDown[i] = false;
    }
 
private:
    bool KeyIsDown[KEY_KEY_CODES_COUNT];
};
 
int main(int argc, char* argv[])
{
 
    MyEventReceiver receiver;
    IrrlichtDevice* device = createDevice(video::EDT_OPENGL,
            core::dimension2du(1280, 720), 32, false, false, false,
            &receiver);
 
    if(device == 0)
        return 1;
 
    IVideoDriver *driver = device->getVideoDriver();
    ISceneManager *smgr = device->getSceneManager();
    device->setWindowCaption(L"Terrain Test");
        
        io::path vsFileName;
        io::path psFileName;
 
        psFileName = "../Media/Shaders/opengl.frag";
        vsFileName = "../Media/Shaders/opengl.vert";
        
        video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
        s32 tiledMaterialType = 0;
        
        if (gpu)
        {
            MyShaderCallBack* mc = new MyShaderCallBack();
            
                const video::E_GPU_SHADING_LANGUAGE shadingLanguage = video::EGSL_DEFAULT;
 
                // create material from high level shaders (hlsl, glsl or cg)
 
                tiledMaterialType = gpu->addHighLevelShaderMaterialFromFiles(
                    vsFileName, "vertexMain", video::EVST_VS_2_0,
                    psFileName, "pixelMain", video::EPST_PS_2_0,
                    mc, video::EMT_SOLID, 0, shadingLanguage);
 
            mc->drop();
        }
    
    TMesh mesh;
    mesh.init(255, 255, 50.f, driver);
 
    IMeshSceneNode* meshnode = smgr -> addMeshSceneNode(mesh.Mesh);
    meshnode->setMaterialType((video::E_MATERIAL_TYPE) tiledMaterialType);
    meshnode->setMaterialFlag(video::EMF_LIGHTING,false);
    meshnode->setMaterialTexture(0, driver->getTexture("../Media/Textures/Grass.jpg"));
 
    ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS();
    if (camera)
    {
        camera->setPosition(vector3df(-20.f, 150.f, -20.f));
        camera->setTarget(vector3df(200.f, -80.f, 150.f));
        camera->setFarValue(20000.0f);
    }
    
    while(device->run())
    {
        if(!device->isWindowActive())
        {
            device->sleep(100);
            continue;
        }
 
        if(receiver.IsKeyDown(irr::KEY_KEY_W))
        {
            meshnode->setMaterialFlag(video::EMF_WIREFRAME, !meshnode->getMaterial(0).Wireframe);
        }
 
        driver->beginScene(true, true, SColor(0xff000000));
        smgr->drawAll();
        driver->endScene();
    }
 
    device->drop();
 
    return 0;
}
The shader code is exactly the same as in the example. I'm sure that my system can handle the high level shaders as they worked in the example. Any idea?
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: Crash on setMaterialType

Post by mongoose7 »

IMeshSceneNode* meshnode = smgr -> addMeshSceneNode(mesh.Mesh);
Surely meshnode is 0 because you haven't added mesh.Mesh?
eejin
Posts: 97
Joined: Sun Jul 24, 2011 11:50 am

Re: Crash on setMaterialType

Post by eejin »

No, meshnode is not zero, it's a number larger than zero.
zerochen
Posts: 273
Joined: Wed Jan 07, 2009 1:17 am
Location: Germany

Re: Crash on setMaterialType

Post by zerochen »

i guess that tiledMaterialType is -1. maybe a shader error?
CuteAlien
Admin
Posts: 9930
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Crash on setMaterialType

Post by CuteAlien »

You have global variable device and a local variable device. You initialize the local one in main, but the global one stays at 0. So it will crash in MyShaderCallBack::OnSetConstants when trying to use it. I have no idea why it crashes for you already at setMaterialType - that does not happen here.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
AReichl
Posts: 269
Joined: Wed Jul 13, 2011 2:34 pm

Re: Crash on setMaterialType

Post by AReichl »

ahh - same problem here.
Depends on the compiler. With gcc it stops at setMaterialType, with VisualStudio in OnSetConstants.
Therefore i assumed some kind of memory problem and didn't look further, but you found it.
Post Reply