Hello everyone,

I tried again the multithread example from OpenSG 2.0 
(13multithreading2.cpp) and it works without any problems. Then I modified 
the example (see code below) so that it read files from hard disk in the 
second thread. Unfortunately it crashes in commitChanges() called from the 
render thread (in display function).

I'm using a self compiled OpenSG 2.0 32bit version (checked out this 
week).
What am I doing wrong? Is this problem related to my previous problems 
posted a few weeks ago?


Thanks
Marc



Error message:
Assertion failed: Self::_ptrStore.size() == Self::_vParentPos.size(), file 
d:\marc\osg\opensg\source\base\fieldcontainer\fields\pointerfields\OSGParentPointerMField.inl,
 
line 639

Callstack:
msvcr80d.dll!_NMSG_WRITE(int rterrnum=10)  Zeile 198    C
msvcr80d.dll!abort()  Zeile 59 + 0x7 Bytes      C
msvcr80d.dll!_wassert(const wchar_t * expr=0x0167f8f8, const wchar_t * 
filename=0x0167f978, unsigned int lineno=639)  Zeile 212        C
OSGSystemD.dll!OSG::ParentPointerMField<OSG::FieldContainer 
*,OSG::NoRefCountPolicy,1>::begin()  Zeile 639 + 0x30 Bytes     C++
OSGSystemD.dll!OSG::Image::changed(const unsigned __int64 
whichField=18446744073709551615, unsigned int origin=8, unsigned __int64 
details=0)  Zeile 131 + 0xf Bytes       C++
OSGBaseD.dll!OSG::ContainerChangeEntry::commitChanges()  Zeile 183 + 0x1d 
Bytes   C++
OSGBaseD.dll!OSG::ChangeList::doCommitChanges<&OSG::ContainerChangeEntry::commitChanges>()
 
 Zeile 420      C++
OSGBaseD.dll!OSG::ChangeList::commitChanges()  Zeile 441        C++
DynamicLoad.exe!OSG::commitChanges()  Zeile 201 + 0x19 Bytes    C++
DynamicLoad.exe!display()  Zeile 328    C++



// all needed include files
#include <OSGGLUT.h>
#include <OSGConfig.h>
#include <OSGSimpleGeometry.h>
#include <OSGGLUTWindow.h>
#include <OSGSimpleSceneManager.h>

#include <OSGThreadManager.h>

OSG::SimpleSceneManager *mgr;

// we will store the transformation globally - this
// is not necessary, but comfortable
// Note that these global objects are accessed from different aspects,
// therefore you need to use MTRecPtr here, so that you get a pointer to 
the
// correct aspect copy of the object.

OSG::TransformMTRecPtr  trans;
OSG::NodeMTRecPtr       scene;
OSG::Thread            *animationThread;
OSG::Thread            *applicationThread;
OSG::Barrier           *syncBarrier;
bool do_sync;

int setupGLUT(int *argc, char *argv[]);

OSG::NodeTransitPtr createScenegraph(void)
{
    // the scene must be created here
    OSG::NodeRecPtr n = OSG::makeTorus(.5,2,16,16);
 
    //add a simple Transformation
    trans = OSG::Transform::create();
    OSG::Matrix m;
    m.setIdentity();
    trans->setMatrix(m);
 
    OSG::NodeRecPtr transNode = OSG::Node::create();
    transNode->setCore(trans);
    transNode->addChild(n);
 
    return OSG::NodeTransitPtr(transNode);
}

//this function will run in a thread and simply will
//rotate the cube by setting a new transformation matrix
void rotate(void *args)
{
    // sync this thread to the main thread, i.e. pull in all changes done
    // during scene construction
    syncBarrier->enter(2);
    applicationThread->getChangeList()->applyAndClear();
    syncBarrier->enter(2);

    // clear the local changelist as we only want to sync the
    // real changes we make back.
    OSG::commitChanges();
    animationThread->getChangeList()->clear();

    std::vector<std::string> file_list;
        std::string base_path = "D:\\Marc\\objects\\";
    std::ifstream file;
    file.open((base_path+"files.txt").c_str());
    while (!file.eof())
    {
        std::string line;
        std::getline(file, line);
                if (!line.empty())
                        file_list.push_back(line);
    }
    unsigned int file_index = 0;

    // we won't stop calculating new matrices....
    while(true)
    {
        if (file_index == file_list.size())
            break;

        std::string file_name = file_list[file_index];
        std::cout << "Loading [" << file_name << "] - (" << file_index << 
" / " << file_list.size() << ")\n" << std::flush;

        NodeRecPtr new_node = 
SceneFileHandler::the()->read((base_path+file_name).c_str());
                if (new_node)
                {
                        scene->addChild(new_node);
                        OSG::commitChanges();
                        do_sync = true;
                        syncBarrier->enter(2);    // barrier (1)
                        syncBarrier->enter(2);    // barrier (2)
                } 
    }
}

int main(int argc, char **argv)
{
        OSG::preloadSharedObject("OSGImageFileIO");
        OSG::preloadSharedObject("OSGFileIO");

    OSG::ChangeList::setReadWriteDefault(true);
    OSG::osgInit(argc,argv);
 
        do_sync = false;
    {
        int winid = setupGLUT(&argc, argv);
        OSG::GLUTWindowRecPtr gwin = OSG::GLUTWindow::create();
        gwin->setGlutId(winid);
        gwin->init();
 
        scene = createScenegraph();
 
        //create the barrier, that will be used to
        //synchronize threads
 
        //instead of NULL you could provide a name
        syncBarrier = OSG::Barrier::get(NULL);
 
        mgr = new OSG::SimpleSceneManager;
        mgr->setWindow(gwin );
        mgr->setRoot  (scene);
        mgr->showAll();
 
        // store a pointer to the application thread
        applicationThread = 
            dynamic_cast<OSG::Thread 
*>(OSG::ThreadManager::getAppThread());
 
        //create the thread that will run generation of new matrices
        animationThread = 
            dynamic_cast<OSG::Thread *>(
                OSG::ThreadManager::the()->getThread("anim"));
 
        //do it...
        animationThread->runFunction(rotate, 1, NULL);
 
        // wait for animationThread to complete its sync
        syncBarrier->enter(2);
        syncBarrier->enter(2);
 
        OSG::commitChanges();
    }
 
    glutMainLoop();

    return 0;
}

void reshape(int w, int h)
{
    mgr->resize(w, h);
    glutPostRedisplay();
}

void display(void)
{
        if (do_sync)
        {
                do_sync = false;

                // we wait here until the animation thread enters
                // barrier (1)
                syncBarrier->enter(2);

                //now we sync data
                animationThread->getChangeList()->applyAndClear();

                // update dependend data
                OSG::commitChanges();

                // now wait for animation thread to enter barrier (2)
                syncBarrier->enter(2);
        } 
    // !!!! Attention
    // you will find a more detailed description
    // of what's going on here in the documentation
    // itself!
 
    // now render...
    mgr->redraw();
}

void mouse(int button, int state, int x, int y)
{
    if (state)
        mgr->mouseButtonRelease(button, x, y);
    else
        mgr->mouseButtonPress(button, x, y);
 
    glutPostRedisplay();
}

void motion(int x, int y)
{
    mgr->mouseMove(x, y);
    glutPostRedisplay();
}

int setupGLUT(int *argc, char *argv[])
{
    glutInit(argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
 
    int winid = glutCreateWindow("OpenSG First Application");
 
    glutDisplayFunc(display);
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutReshapeFunc(reshape);
    glutIdleFunc(display);
 
    return winid;
} 
------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with 
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Opensg-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensg-users

Reply via email to