virtualritz / nsi

High level Rust bindings for Illumination Research’s Nodal Scene Interface – ɴsɪ.
BSD 3-Clause "New" or "Revised" License
14 stars 0 forks source link

no valid output driver was found (ferris) #6

Closed luke-titley closed 3 years ago

luke-titley commented 3 years ago

Hey, I'm just trying out the nsi crate. 3delight installed etc, it's obviously picking it up. What doesn't seem to be working is the ferris output driver, seems like 3delight can't find it.

3DL ERROR E6032 no image will be rendered because no valid output driver was found.

Likely I'm missing a connection in my nsi somewhere, but I've got like 5 minutes worth of NSI experience... so... Getting this error when copying the FinishCallback example.

    let ctx = nsi::Context::new(&[]).expect("Could not create NSI context.");

    // Create a perspective camera
    ctx.create("camera", nsi::NodeType::PerspectiveCamera, &[]);

    // Setup a screen.
    ctx.create("screen", nsi::NodeType::Screen, &[]);

    // We pretend we defined a camera node earlier.
    ctx.connect("screen", "", "camera", "screens", &[]);
    ctx.set_attribute(
        "screen",
        &[
            // The resolution becomes the width & height passed to
            // FnOpen, FnWrite and FnFinish type callbacks.
            nsi::integers!("resolution", &[512, 256]).array_len(2),
        ],
    );

    // Setup an RGBA output layer.
    ctx.create("beauty", nsi::NodeType::OutputLayer, &[]);
    ctx.set_attribute(
        "beauty",
        &[
            // The Ci variable comes from Open Shading Language.
            nsi::string!("variablename", "Ci"),
            // We want the data as raw, 32 bit float.
            nsi::string!("scalarformat", "float"),
            nsi::integer!("withalpha", 1),
        ],
    );
    ctx.connect("beauty", "", "screen", "outputlayers", &[]);

    // Setup an output driver.
    ctx.create("driver", nsi::NodeType::OutputDriver, &[]);
    ctx.connect("driver", "", "beauty", "outputdrivers", &[]);

    // Our FnFinish callback. We will be called once.
    let finish = nsi::output::FinishCallback::new(
        |// Passed from the output driver node, below.
         image_filename: &str,
         // Passed from the screen node, above.
         width: usize,
         // Passed from the screen node, above.
         height: usize,
         pixel_format: nsi::output::PixelFormat,
         pixel_data: Vec<f32>| {
             /*
            // Call some function to write our image to an OpenEXR file.
            write_exr(
                (String::from(image_filename) + ".exr").as_str(),
                width,
                height,
                pixel_format.len(),
                &pixel_data,
            );
            */

           // Do nothing for now

            nsi::output::Error::None
        },
    );

    ctx.set_attribute(
        "driver",
        &[
            // Important: FERRIS is the built-in output driver
            // that understands the closure parameters.
            nsi::string!("drivername", "ferris"),
            // This will end up in the `name` parameter passed
            // to finish().
            nsi::string!("imagefilename", "render"),
            nsi::callback!("callback.finish", finish),
        ],
    );

    ctx.render_control(&[nsi::string!("action", "start")]);

    // The finish() closure will be called once, before the next call returns.
    ctx.render_control(&[nsi::string!("action", "wait")]);
virtualritz commented 3 years ago

You forgot to connect your camera to the scene's .root. 😉

So you have everything nicely connected. Except the top node, the camera itself, is dangling.

Add this line after creating the camera:

ctx.connect("camera", "", ".root", "objects", &[]);

See also Basic Scene Anatomy.