Help with CDynamicMeshBuffer

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
Matix522
Posts: 15
Joined: Wed Jul 02, 2014 11:48 am
Location: Poland

Help with CDynamicMeshBuffer

Post by Matix522 »

Hi all , I have a problem with generaiting a mesh from CDynamicMeshBuffer
I edit the 23.SMeshHandling example to create my own terrainMesh (i don't want to use ITerrianSceneNode)
When i create this with CMeshBuffer it work exelent but need to create terrain bigger than 255x255 vertices.

Code: Select all

 
 class TMesh
{
private:
    u16 Width;
    u16 Height;
    f32 Scale;
    core::array<f32> data;
public:
    SMesh* Mesh;
 
    TMesh() : Mesh(0), Width(0), Height(0), Scale(1.f)
    {
        Mesh = new SMesh();
    }
 
    ~TMesh()
    {
        Mesh->drop();
    }
 
 
    void init(const IImage * hm, f32 scale, SColor cf, IVideoDriver *driver)
    {
        Scale = scale;
 
        const u32 mp = driver -> getMaximalPrimitiveCount();
        Width = hm->getDimension().Width;
        Height = hm->getDimension().Height;
 
        const u32 sw = mp / (6 * Height); // the width of each piece
 
        u32 i=0;
        for(u32 y0 = 0; y0 < Height; y0 += sw)
        {
            u16 y1 = y0 + sw;
            if (y1 >= Height)
                y1 = Height - 1; // the last one might be narrower
            addstrip(hm, cf, y0, y1, i);
            ++i;
        }
        if (i<Mesh->getMeshBufferCount())
        {
            // clear the rest
            for (u32 j=i; j<Mesh->getMeshBufferCount(); ++j)
            {
                Mesh->getMeshBuffer(j)->drop();
            }
            Mesh->MeshBuffers.erase(i,Mesh->getMeshBufferCount()-i);
        }
 
        Mesh->setDirty();
        Mesh->recalculateBoundingBox();
    }
 
    // Generate a SMeshBuffer which represents all the vertices and
    // indices for values of y between y0 and y1, and add it to the
    // mesh.
    f32 get(u16 x, u16 y) const { return data[y * Width + x]; }
        vector3df getnormal(u16 x, u16 y, f32 s) const
    {
 
        const f32 zc = x+ y*Width;
 
        f32 zl, zr, zu, zd;
 
        if (x == 0)
        {
            zr = (x + 1)+ y * Width;
            zl = zc + zc - zr;
        }
        else if (x == Width - 1)
        {
            zl = (x - 1)+ y * Width;
            zr = zc + zc - zl;
        }
        else
        {
            zr = (x + 1)+ y * Width;
            zl = (x - 1)+ y * Width;
        }
 
        if (y  == 0)
        {
            zd = x + (y+ 1) * Width;
            zu = zc + zc - zd;
        }
        else if (y  == Height - 1)
        {
            zu = x+ (y- 1) * Width;
            zd = zc + zc - zu;
        }
        else
        {
            zd = x+ (y+ 1) * Width;
            zu = x+ (y- 1) * Width;
        }
        return vector3df(s * 2 * (zl - zr), 4, s * 2 * (zd - zu)).normalize();
    }
    void addstrip(const IImage* hm, SColor cf, u16 y0, u16 y1, u32 bufNum)
    {
        CDynamicMeshBuffer *buf = 0;
        if (bufNum<Mesh->getMeshBufferCount())
        {
            buf = (CDynamicMeshBuffer*)Mesh->getMeshBuffer(bufNum);
        }
        else
        {
            // create new buffer
            buf = new CDynamicMeshBuffer( EVT_STANDARD,EIT_32BIT);
            Mesh->addMeshBuffer(buf);
            // to simplify things we drop here but continue using buf
            buf->drop();
        }
        int numberOfVertices=Height*Width;
        buf->getVertexBuffer().set_used(numberOfVertices+1);
 
        u32 i=0;
        for (u16 y = y0; y <= y1; ++y)
        {   cout<<"\nA"<<y<<" ";
            for (u16 x = 0; x < Width; ++x)
            {
                const f32 z = SColor(hm->getPixel(x, y)).getLightness()/255;
                const f32 xx = (f32)x/(f32)Width;
                const f32 yy = (f32)y/(f32)Height;
                cout<<x<<" ";
                //video::S3DVertex2TCoords& v= static_cast<video::S3DVertex2TCoords*>(buf->getVertexBuffer().pointer())[i++];
                S3DVertex& v = (buf->getVertexBuffer().pointer())[i++];
                v.Pos.set(x, Scale * z, y);
 
                v.Normal.set(getnormal(x, y, Scale));
 
                v.Color.set(255,255,255,255);
 
                v.TCoords.set(xx, yy);
 
            }
        }
 
        buf->getIndexBuffer().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->getIndexBuffer().push_back(n);
                buf->getIndexBuffer().push_back(n + Width);
                buf->getIndexBuffer().push_back(n + Width + 1);
                buf->getIndexBuffer().push_back(n + Width + 1);
                buf->getIndexBuffer().push_back(n + 1);
                buf->getIndexBuffer().push_back(n);
                i+=6;
            }
        }
                buf->recalculateBoundingBox();
    }
};
 
 
I don't know what i'm doing wrong. i'm geting crash in the loop when scene should be rendered
PS: sorry for my English
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: Help with CDynamicMeshBuffer

Post by hybrid »

Maybe try to drop buf only at the end of the insertion. Also try to debug which things are actually crashing.
Matix522
Posts: 15
Joined: Wed Jul 02, 2014 11:48 am
Location: Poland

Re: Help with CDynamicMeshBuffer

Post by Matix522 »

i never debug any applicaption this is my first time and I don't know how to read this.
I get this

Code: Select all

 
#0 5E80F523 nvoglv32!DrvGetProcAddress() (C:\Windows\SysWOW64\nvoglv32.dll:??)
#1 5E8542F5 nvoglv32!DrvGetProcAddress() (C:\Windows\SysWOW64\nvoglv32.dll:??)
#2 5E854CAC nvoglv32!DrvGetProcAddress() (C:\Windows\SysWOW64\nvoglv32.dll:??)
#3 5E84DEC7 nvoglv32!DrvGetProcAddress() (C:\Windows\SysWOW64\nvoglv32.dll:??)
#4 5E09D2FD ??() (C:\Windows\SysWOW64\nvoglv32.dll:??)
#5 5E652E93 ??() (C:\Windows\SysWOW64\nvoglv32.dll:??)
#6 5E655271 ??() (C:\Windows\SysWOW64\nvoglv32.dll:??)
#7 5E65508E ??() (C:\Windows\SysWOW64\nvoglv32.dll:??)
#8 5E654EE3 ??() (C:\Windows\SysWOW64\nvoglv32.dll:??)
#9 5E76C48C nvoglv32!DrvSwapLayerBuffers() (C:\Windows\SysWOW64\nvoglv32.dll:??)
#10 76AF338A    KERNEL32!BaseCleanupAppcompatCacheSupport() (C:\Windows\syswow64\kernel32.dll:??)
#11 02BFFFD4    ?? () (??:??)
#12 77859F72    ntdll!RtlpNtSetValueKey() (C:\Windows\system32\ntdll.dll:??)
#13 0327C7C0    ?? () (??:??)
#14 77859F45    ntdll!RtlpNtSetValueKey() (C:\Windows\system32\ntdll.dll:??)
#15 5E76C480    nvoglv32!DrvSwapLayerBuffers() (C:\Windows\SysWOW64\nvoglv32.dll:??)
#16 ??  ?? () (??:??)
 
 
Matix522
Posts: 15
Joined: Wed Jul 02, 2014 11:48 am
Location: Poland

Re: Help with CDynamicMeshBuffer

Post by Matix522 »

I know whats this mean, I exceeded the size of the array but I dont know which and where.
Can someone take a look at my code and write me this?
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: Help with CDynamicMeshBuffer

Post by hybrid »

Well, actually this looks like a crash inside the driver. This might happen due to some severely wrong setup of your mesh, yes, but it's quite unlikely. Maybe it's more a problem of using a 32bit driver under 64bit Windows?!
Matix522
Posts: 15
Joined: Wed Jul 02, 2014 11:48 am
Location: Poland

Re: Help with CDynamicMeshBuffer

Post by Matix522 »

No it's isn't problem with 32 bit in 64 bit windows. When I changed EIT_32BIT to EIT_16BIT crash was the same but find addnotaion in CIndexBuffer "// push const ref due to compiler problem with gcc 4.6, big endian" I use gcc 4.7 but i change push_back to method to this:

Code: Select all

 
        cout<<numberOfVertices;
        u32 val =6 * (Width - 1) * (y1 - y0);
       
        CIndexBuffer index = (CIndexBuffer&)buf->getIndexBuffer();
 
 
 
        index.reallocate(val);
        index.set_used(val);
        i=0;
 
        int abc;
        for(u16 y = y0; y < y1; ++y)
        {
            for(u16 x = 0; x < Width - 1; ++x)
            {
 
                cout<<6*((y*Width)+x)<<endl;
                const u32 n = (y-y0) * Width + x;
                index.Indices->setValue( i, n);
                ++i;
                index.Indices->setValue( i, n + Width);
                ++i;
                index.Indices->setValue( i, n + Width + 1);
                ++i;
                index.Indices->setValue( i, n + Width + 1);
                ++i;
                index.Indices->setValue( i, n + 1);
                ++i;
                index.Indices->setValue( i, n);
                ++i;
                cout<<i/6<<" ";
            }
            abc = 6*((y+1)*(Width-1));
        }
        cout<<abc<<endl;
 
 
 
Now i getting in debuger "this program received signal SIGILL ,lillegal instruction" and:

Code: Select all

 
#0 00ABEEA5 ?? () (??:??)
#1 0042C445 irr::scene::IDynamicMeshBuffer::getIndexType(this=0x5f13d28) (../../include/IDynamicMeshBuffer.h:144)
#2 6359666B irr::video::CNullDriver::drawMeshBuffer(irr::scene::IMeshBuffer const*) () (F:\irrlicht-1.8.1\bin\Win32-gcc\Irrlicht.dll:??)
 
 
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: Help with CDynamicMeshBuffer

Post by mongoose7 »

Read hybrid's message again. Very carefully.

Alternatively, uninstall your display driver and go to nvidia.com. Download the driver and ask NVIDIA to detect the driver, don't select it manually!
Post Reply