// Create a volume rendering node with all desired attachments
NodePtr makeVolume(ImagePtr datImage)
{  
    vol         = DVRVolume::create();
    DVRAppearancePtr     app         = DVRAppearance::create(); 
    DVRVolumeTexturePtr  tex         = DVRVolumeTexture::create();

    beginEditCP(tex);
    tex->setImage(datImage);
    endEditCP(tex);

    // Attach the volume texture to the appearance
    beginEditCP(app, Node::AttachmentsFieldMask);
    app->addAttachment(tex);
    endEditCP  (app, Node::AttachmentsFieldMask);

    // Assign the appearance to the volume core
    beginEditCP(vol);
    vol->setAppearance(app);
    vol->setShader(DVRSimpleShader::create());
    endEditCP(vol);

    // Create a node for the volume core
    NodePtr newGeom = Node::create();
    beginEditCP(newGeom);
    newGeom->setCore(vol);
    endEditCP(newGeom);
    
    return newGeom;
}
// Create a volume rendering node with all desired attachments
NodePtr makeVolume( const char * datFile)
{
    DVRVolumePtr         vol         = DVRVolume::create();
    DVRAppearancePtr     app         = DVRAppearance::create();
    DVRVolumeTexturePtr  tex         = DVRVolumeTexture::create();
    DVRLookupTablePtr    lut         = DVRLookupTable::create();

    volume = vol;

    // Load the 3D-image and store it in the volume texture attachment
    ImagePtr datImage = Image::create();
    if (false == datImage->read(datFile)) {
        SLOG << "File: " << datFile << " not found" << std::endl;
        exit (-1);
    }
    beginEditCP(tex);
    tex->setImage(datImage);
    tex->setFileName(datFile);
    endEditCP(tex);

    //!! FIXME - Initialize the lookup table
    //!! This should not be neccessary if the OpenSG reader works correctly
    beginEditCP(lut, DVRLookupTable::TouchedFieldMask);
    lut->setTouched(true);
    endEditCP(lut, DVRLookupTable::TouchedFieldMask);

    // Initialize the lookup table
    beginEditCP(lut, DVRLookupTable::DataFieldMask);
    for (int i = 0; i < 1024; i++)
        lut->getData()[i] = lutData[i];
    endEditCP(lut, DVRLookupTable::DataFieldMask);

    // Attach the volume texture and lookup table to the appearance
    beginEditCP(app, Node::AttachmentsFieldMask);
    app->addAttachment(tex);
    app->addAttachment(lut);
    endEditCP  (app, Node::AttachmentsFieldMask);

    // Create a shader
    shader = DVRSimpleLUTShader::create();

    // Assign the appearance and shader to the volume core
    beginEditCP(vol);
    vol->setFileName(datFile);
    vol->setAppearance(app);
    vol->setShader(shader);
    endEditCP(vol);

    // Create a node for the volume core
    NodePtr newGeom = Node::create();
    beginEditCP(newGeom);
    newGeom->setCore(vol);
    endEditCP(newGeom);

    return newGeom;
}
// react to keys
void keyboard(unsigned char k, int OSG_CHECK_ARG(x), int OSG_CHECK_ARG(y))
{
    switch(k)
    {
        case 27:        
        {
            OSG::osgExit();
            exit(0);
        }
        break;
        case 'a':
        {
            OSG::beginEditCP(vol, OSG::DVRVolume::SamplingFieldMask);
            vol->setSampling(vol->getSampling() * 1.1);
            OSG::endEditCP(vol, OSG::DVRVolume::SamplingFieldMask);
            std::cout << "Sampling set to " << vol->getSampling() 
                      << std::endl;
            glutPostRedisplay();
        }
        break;
        case 'z':
        {
            OSG::beginEditCP(vol, OSG::DVRVolume::SamplingFieldMask);
            vol->setSampling(vol->getSampling() * 0.9);
            OSG::endEditCP(vol, OSG::DVRVolume::SamplingFieldMask);
            std::cout << "Sampling set to " << vol->getSampling() 
                      << std::endl;
            glutPostRedisplay();
        }
        break;
    }
}
// Create a volume rendering node with all desired attachments
NodePtr makeVolume( const char * datFile)
{  
    DVRVolumePtr         vol         = DVRVolume::create();
    DVRAppearancePtr     app         = DVRAppearance::create(); 
    DVRVolumeTexturePtr  tex         = DVRVolumeTexture::create();

    // Load the 3D-image and store it in the volume texture attachment
    ImagePtr datImage = Image::create();
    if (false == datImage->read(datFile)) {
        SLOG << "File: " << datFile << " not found" << std::endl;
	exit (-1);
    }
    beginEditCP(tex);
    tex->setImage(datImage);
    tex->setFileName(datFile);
    endEditCP(tex);

    // Attach the volume texture to the appearance
    beginEditCP(app, Node::AttachmentsFieldMask);
    app->addAttachment(tex);
    endEditCP  (app, Node::AttachmentsFieldMask);

    // Assign the appearance to the volume core
    beginEditCP(vol);
    vol->setFileName(datFile);
    vol->setAppearance(app);
    vol->setShader(DVRSimpleShader::create());
    endEditCP(vol);

    // Create a node for the volume core
    NodePtr newGeom = Node::create();
    beginEditCP(newGeom);
    newGeom->setCore(vol);
    endEditCP(newGeom);
    
    return newGeom;
}