Rendering custom mesh causes segfault

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
jake.anq
Posts: 2
Joined: Wed Jan 04, 2012 6:38 am

Rendering custom mesh causes segfault

Post by jake.anq »

Hi

This code is causing a segfault to occur when smgr->drawAll(); is called. The code compiles cleanly, and gdb reports:

Code: Select all

(gdb) run
Starting program: /home/jake/C++/mapclass/maptest 
[Thread debugging using libthread_db enabled]
INFO:  [1325652806] Creating IrrlichtDevice
Irrlicht Engine version 1.7.2
Linux 3.0.0-14-generic #23-Ubuntu SMP Mon Nov 21 20:28:43 UTC 2011 x86_64
Creating X window...
Visual chosen: : 276
Using renderer: OpenGL 2.1
Gallium 0.4 on AMD RV730: X.Org
OpenGL driver version is 1.2 or better.
GLSL version: 1.2
INFO:  [1325652806] Creating Map
INFO:  [1325652806] Creating BlockRenderer
INFO:  [1325652806] Loading texture from textures/sd.png
Loaded texture: /home/jake/C++/mapclass/textures/sd.png
INFO:  [1325652806] Rendering Chunk 0,0,0
INFO:  [1325652806] Loading Chunk
INFO:  [1325652806] Attempting to read chunk
INFO:  [1325652806] Cannot open ifstream for the reading of this chunk
INFO:  [1325652806] Creating Camera
INFO:  [1325652806] Adding lights
INFO:  [1325652806] Entering event loop
 
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff795a402 in irr::scene::CSceneManager::isCulled(irr::scene::ISceneNode const*) const () from /usr/lib/libIrrlicht.so.1.7a
(gdb) bt
#0  0x00007ffff795a402 in irr::scene::CSceneManager::isCulled(irr::scene::ISceneNode const*) const () from /usr/lib/libIrrlicht.so.1.7a
#1  0x00007ffff795a96e in irr::scene::CSceneManager::registerNodeForRendering(irr::scene::ISceneNode*, irr::scene::E_SCENE_NODE_RENDER_PASS) ()
   from /usr/lib/libIrrlicht.so.1.7a
#2  0x00007ffff78e4aa8 in irr::scene::CMeshSceneNode::OnRegisterSceneNode() () from /usr/lib/libIrrlicht.so.1.7a
#3  0x00007ffff78e262a in irr::scene::ISceneNode::OnRegisterSceneNode() () from /usr/lib/libIrrlicht.so.1.7a
#4  0x00007ffff7959243 in irr::scene::CSceneManager::drawAll() () from /usr/lib/libIrrlicht.so.1.7a
#5  0x0000000000407ee7 in main () at map_test.cpp:71
(gdb) 
The code that appears to be causing the problems is the mesh generator code:

(some irrelevant code left out for clarity.)

Code: Select all

void BlockRender::render_chunk(core::vector3df loc){
        Chunk* ch = mp->chunk_pointer(loc);
        SMeshBufferBuffer smbb;
        video::SColor sc(255,0,0,0);
        core::vector3df pos;
        for(pos.X = loc.X;pos.X<(S_CHUNK+loc.X);pos.X++)
                for(pos.Y = loc.Y;pos.Y<(S_CHUNK+loc.Y);pos.Y++)
                        for(pos.Z = loc.Z;pos.Z<(S_CHUNK+loc.Z);pos.Z++){
                        if(ch->map[int(pos.X)][int(pos.Y)][int(pos.Z)].type!=0)
                                        NormalRender(*(imgc[1]).texture, &smbb, sc, pos, NULL);
                        }
        scene::SMesh s;
        smbb.attach(&s);
        //IMeshSceneNode* meshnode=
        s.recalculateBoundingBox();
        if(s.getMeshBufferCount() == 0)
        {
                logger.log("Meshbuffers have disappeared (!)");
        }
        IMeshSceneNode* meshnode = smgr -> addMeshSceneNode(&s);
 
        meshnode->setMaterialFlag(video::EMF_BACK_FACE_CULLING, false);
}
void BlockRender::NormalRender(video::ITexture &tex, SMeshBufferBuffer *smbb, video::SColor &c, core::vector3df &pos, f32* txc){
        //TODO: Tidy this entire function
        f32 tu0=0;
        f32 tu1=tex.getSize().Width;
        f32 tv0=0;
        f32 tv1=tex.getSize().Height;
        f32 txus=tu0;
        f32 txvs=tu1;
        video::SMaterial material;
        material.setTexture(0, &tex);
        f32 rx = 1;
        f32 ry = 1;
        f32 rz = 1;
        video::S3DVertex v[4] =
        {
                video::S3DVertex(0,0,0, 0,0,0, c, tu0, tv1),
                video::S3DVertex(0,0,0, 0,0,0, c, tu1, tv1),
                video::S3DVertex(0,0,0, 0,0,0, c, tu1, tv0),
                video::S3DVertex(0,0,0, 0,0,0, c, tu0, tv0)
        };
 
        for(int i=0;i<6;i++)
        {
                switch(i)
                {
                        case 0: // top
                                v[0].Pos.X=-rx; v[0].Pos.Y= ry; v[0].Pos.Z=-rz;
                                v[1].Pos.X=-rx; v[1].Pos.Y= ry; v[1].Pos.Z= rz;
                                v[2].Pos.X= rx; v[2].Pos.Y= ry; v[2].Pos.Z= rz;
                                v[3].Pos.X= rx; v[3].Pos.Y= ry, v[3].Pos.Z=-rz;
                                break;
                        case 1: // back
                                v[0].Pos.X=-rx; v[0].Pos.Y= ry; v[0].Pos.Z=-rz;
                                v[1].Pos.X= rx; v[1].Pos.Y= ry; v[1].Pos.Z=-rz;
                                v[2].Pos.X= rx; v[2].Pos.Y=-ry; v[2].Pos.Z=-rz;
                                v[3].Pos.X=-rx; v[3].Pos.Y=-ry, v[3].Pos.Z=-rz;
                                break;
                        case 2: //right
                                v[0].Pos.X= rx; v[0].Pos.Y= ry; v[0].Pos.Z=-rz;
                                v[1].Pos.X= rx; v[1].Pos.Y= ry; v[1].Pos.Z= rz;
                                v[2].Pos.X= rx; v[2].Pos.Y=-ry; v[2].Pos.Z= rz;
                                v[3].Pos.X= rx; v[3].Pos.Y=-ry, v[3].Pos.Z=-rz;
                                break;
                        case 3: // front
                                v[0].Pos.X= rx; v[0].Pos.Y= ry; v[0].Pos.Z= rz;
                                v[1].Pos.X=-rx; v[1].Pos.Y= ry; v[1].Pos.Z= rz;
                                v[2].Pos.X=-rx; v[2].Pos.Y=-ry; v[2].Pos.Z= rz;
                                v[3].Pos.X= rx; v[3].Pos.Y=-ry, v[3].Pos.Z= rz;
                                break;
                        case 4: // left
                                v[0].Pos.X=-rx; v[0].Pos.Y= ry; v[0].Pos.Z= rz;
                                v[1].Pos.X=-rx; v[1].Pos.Y= ry; v[1].Pos.Z=-rz;
                                v[2].Pos.X=-rx; v[2].Pos.Y=-ry; v[2].Pos.Z=-rz;
                                v[3].Pos.X=-rx; v[3].Pos.Y=-ry, v[3].Pos.Z= rz;
                                break;
                        case 5: // bottom
                                v[0].Pos.X= rx; v[0].Pos.Y=-ry; v[0].Pos.Z= rz;
                                v[1].Pos.X=-rx; v[1].Pos.Y=-ry; v[1].Pos.Z= rz;
                                v[2].Pos.X=-rx; v[2].Pos.Y=-ry; v[2].Pos.Z=-rz;
                                v[3].Pos.X= rx; v[3].Pos.Y=-ry, v[3].Pos.Z=-rz;
                                break;
                }
 
                if(txc!=NULL)
                {
                        v[0].TCoords.X=tu0+txus*txc[0]; v[0].TCoords.Y=tv0+txvs*txc[3];
                        v[1].TCoords.X=tu0+txus*txc[2]; v[1].TCoords.Y=tv0+txvs*txc[3];
                        v[2].TCoords.X=tu0+txus*txc[2]; v[2].TCoords.Y=tv0+txvs*txc[1];
                        v[3].TCoords.X=tu0+txus*txc[0]; v[3].TCoords.Y=tv0+txvs*txc[1];
                        txc+=4;
                }
 
                for(u16 i=0; i<4; i++)
                        v[i].Pos += pos;
                u16 indices[] = {0,1,2,2,3,0};
                smbb->append(material, v, 4, indices, 6);
 
        }
 
}
 
 
void SMeshBufferBuffer::append(video::SMaterial material, const video::S3DVertex* const vertices, u32 numVertices, const u16* const indices, u32 numIndices)
{
                MeshBufferBuffer *p = NULL;
                for(u32 i=0; i<m_prebuffers.size(); i++)
                {
                        MeshBufferBuffer &pp = m_prebuffers[i];
                        if(pp.material != material)
                                continue;
 
                        p = &pp;
                        break;
                }
 
                if(p == NULL)
                {
                        MeshBufferBuffer pp;
                        pp.material = material;
                        m_prebuffers.push_back(pp);
                        p = &m_prebuffers[m_prebuffers.size()-1];
                }
 
                u32 vertex_count = p->vertices.size();
                for(u32 i=0; i<numIndices; i++)
                {
                        u32 j = indices[i] + vertex_count;
                        if(j > 65535)
                        {
                                logger.log("FIXME: Meshbuffer ran out of indices");//dstream<<"FIXME: Meshbuffer ran out of indices"<<std::endl;
                                // NOTE: Fix is to just add an another MeshBuffer
                        }
                        p->indices.push_back(j);
                }
                for(u32 i=0; i<numVertices; i++)
                {
                        p->vertices.push_back(vertices[i]);
                }
}
 
void SMeshBufferBuffer::attach(scene::SMesh *mesh)
{
        for(u32 i=0; i<m_prebuffers.size(); i++)
        {
                MeshBufferBuffer &p = m_prebuffers[i];
                scene::SMeshBuffer *buf = new scene::SMeshBuffer();
                buf->Material = p.material;
                mesh->addMeshBuffer(buf);
                buf->drop();
                //buf->append(p.vertices.pointer(), p.vertices.size(), p.indices.pointer(), p.indices.size());
                buf->recalculateBoundingBox();
        }
}
Just in case, here is the main function: (This should be fine, I tested this by substituting the my mesh for the mesh from example 23)(Irrelevant code removed again)

Code: Select all

#include <irrlicht/irrlicht.h>
#include "map.hpp"
#include "worldrender.hpp"
#include "typedef.hpp"
#include "error.hpp"
#include <iostream>
 
using namespace irr;
using namespace std;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
 
int main()
{
    logger.log("Creating IrrlichtDevice",0);
    IrrlichtDevice* device = irr::createDevice(video::EDT_OPENGL, core::dimension2du(800, 600));
    if(device == 0)
        return 1;
 
    IVideoDriver *driver = device->getVideoDriver();
    ISceneManager *smgr = device->getSceneManager();
    device->setWindowCaption(L"Epicnium V0.001");
    logger.log("Creating Map",0);
    Map mp("test_world");
    logger.log("Creating BlockRenderer",0);
    BlockRender br(device,&mp);
    br.loadTexture("sd.png",1);
    logger.log("Rendering Chunk 0,0,0",0);
    br.render_chunk(core::vector3df(0,0,0)); //this is my custom mesh generator
 
    logger.log("Creating Camera",0);
    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);
    }
    else
    {
        logger.log("Something happened to the camera");
        return 1;
    }
    logger.log("Adding lights",0);
    ILightSceneNode *node = smgr->addLightSceneNode(0, vector3df(0,100,0),
 
                SColorf(1.0f, 0.6f, 0.7f, 1.0f), 500.0f);
 
        if (node)
 
        {
 
                node->getLightData().Attenuation.set(0.f, 1.f/500.f, 0.f);
 
                ISceneNodeAnimator* anim = smgr->createFlyCircleAnimator(vector3df(0,150,0),250.0f);
 
                if (anim)
 
                {
 
                        node->addAnimator(anim);
 
                        anim->drop();
 
                }
 
        }
    logger.log("Entering event loop",0);
    while(device->run())
    {
        if(!device->isWindowActive())
        {
            device->sleep(100);
            continue;
        }
 
        driver->beginScene(true, true, SColor(0xff000000));
        smgr->drawAll();
        driver->endScene();
    }
    logger.log("Shutting down...",0);
    device->drop();
    return 0;
}
I hope I have posted the right information in the right places...

Thanks in advance.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: Rendering custom mesh causes segfault

Post by hybrid »

Reference counted things need to be created with new. Don't create a statically allocated mesh. The memory will be re-used and things are crashing.
jake.anq
Posts: 2
Joined: Wed Jan 04, 2012 6:38 am

Re: Rendering custom mesh causes segfault

Post by jake.anq »

That has fixed it.

Thanks
Post Reply