MDL SDK API nvidia_logo_transpbg.gif Up
Example for Function Calls
[Previous] [Up] [Next]

This example uses function calls to create a textured material.

New Topics

  • Rationale for expressions vs values
  • Creating a textured material

Detailed Description

Rationale for expressions vs values


Arguments of material instances and function calls are not values, but expressions. For example, the argument for the "tint" parameter in the previous example is an instance of mi::neuraylib::IExpression, and not of mi::neuraylib::IValue_color. Why is this indirection needed?

If material instances and function calls are only used in isolation, simple values like mi::neuraylib::IValue_color would be sufficient. However, much of the flexibility of MDL comes from the fact that one can create connections between material instances and function calls (provided the return type and the parameter type match). These connections are represented by call expressions while simple values are represented by constant expressions.

Creating a textured material


The method create_textured_material() shows all the steps needed to create a textured material in a bottom-up order. First we create a DB element of type mi::neuraylib::IImage that represents the provided .png file, and a DB element of type mi::neuraylib::ITexture that references the image.

Next we load the MDL modules we want to use. The example module contains the material definition that we are going to use later. The base module contains a function definition that we are using in the next step to make use of the texture.

The function definition base::file_texture() is used to access the texture object in the DB. Apart from the texture name it provides several arguments to influence the texture lookup process. In this example we just set the texture name and leave the other arguments at their defaults. This step uses mi::neuraylib::IModule::get_function_overloads() to retrieve the exact name of a function definition (which includes the signature). Using this method frees one from hardcoding the signature if there is only one overload.

The return type of the function definition base::file_texture() is base::texture_return, a struct of two fields: "tint" of type mi::neuraylib::IType_color and "mono" of type mi::neuraylib::IType_float. Since the material definition we plan to use has a parameter of type mi::neuraylib::IType_color we cannot directly attach the function call of base::file_texture(). Instead we have to isolate the "tint" field in the returned struct. This can be done by a so-called member selection operator (see Structs for details). In this case, the name of the required struct getter is base::texture_return.tint().

Finally, we connect the just created instance of the member selection operator to the "tint" argument of our diffuse material. The dump of the material instance and all function calls clearly shows the created call expressions.

Example Source

Source Code Location: examples/mdl_sdk/calls/example_calls.cpp

/******************************************************************************
* Copyright 2024 NVIDIA Corporation. All rights reserved.
*****************************************************************************/
// examples/mdl_sdk/calls/example_calls.cpp
//
// Uses function calls to create a textured material.
#include <iostream>
#include <string>
#include "example_shared.h"
// Utility function to dump the arguments of a material instance or function call.
template <class T>
void dump_instance(
mi::neuraylib::IExpression_factory* expression_factory, const T* material, std::ostream& s)
{
mi::Size count = material->get_parameter_count();
mi::base::Handle<const mi::neuraylib::IExpression_list> arguments( material->get_arguments());
for( mi::Size index = 0; index < count; index++) {
arguments->get_expression( index));
std::string name = material->get_parameter_name( index);
expression_factory->dump( argument.get(), name.c_str(), 1));
s << " argument " << argument_text->get_c_str() << std::endl;
}
s << std::endl;
}
// Creates a textured material.
void create_textured_material( mi::neuraylib::INeuray* neuray)
{
mi::base::Handle<mi::neuraylib::IScope> scope( database->get_global_scope());
mi::base::Handle<mi::neuraylib::ITransaction> transaction( scope->create_transaction());
mdl_factory->create_value_factory( transaction.get()));
mdl_factory->create_expression_factory( transaction.get()));
mdl_factory->create_execution_context());
{
// Create a DB element for the image and the texture referencing it.
transaction->create<mi::neuraylib::IImage>( "Image"));
check_success( image->reset_file( "nvidia/sdk_examples/resources/example.png") == 0);
transaction->store( image.get(), "nvidia_image");
transaction->create<mi::neuraylib::ITexture>( "Texture"));
texture->set_image( "nvidia_image");
// Setting the gamma override value here is not strictly necessary, since the canvas of
// the image has already a gamma value of 2.2. However, if new MDL source code is
// generated based on this texture, the explicit setting here causes "::tex::gamma_srgb" to
// be used instead of "::tex::gamma_default", which might be desired.
texture->set_gamma( 2.2f);
transaction->store( texture.get(), "nvidia_texture");
}
{
// Import the "::nvidia::sdk_examples::tutorials" and "base" module. The
// "::nvidia::sdk_examples::tutorials" module is found via the configured module search
// path.
check_success( mdl_impexp_api->load_module(
transaction.get(), "::nvidia::sdk_examples::tutorials", context.get()) >= 0);
check_success( print_messages( context.get()));
check_success( mdl_impexp_api->load_module(
transaction.get(), "::base", context.get()) >= 0);
check_success( print_messages( context.get()));
}
{
// Lookup the exact name of the DB element for the MDL function "base::file_texture".
transaction->access<mi::neuraylib::IModule>( "mdl::base"));
module->get_function_overloads( "mdl::base::file_texture"));
check_success( overloads->get_length() == 1);
overloads->get_element<mi::IString>( static_cast<mi::Uint32>( 0)));
// Prepare the arguments of the function call for "mdl::base::file_texture": set the
// "texture" argument to the "nvidia_texture" texture.
file_texture_name->get_c_str()));
function_definition->get_parameter_types());
mi::base::Handle<const mi::neuraylib::IType> arg_type( types->get_type( "texture"));
check_success( arg_type.is_valid_interface());
value_factory->create<mi::neuraylib::IValue_texture>( arg_type.get()));
check_success( arg_value.is_valid_interface());
check_success( arg_value->set_value( "nvidia_texture") == 0);
expression_factory->create_constant( arg_value.get()));
expression_factory->create_expression_list());
arguments->add_expression( "texture", arg_expr.get());
// Create a function call from the function definition "mdl::base::file_texture" with the
// just prepared arguments.
mi::Sint32 result;
function_definition->create_function_call( arguments.get(), &result));
check_success( result == 0);
transaction->store( function_call.get(), "call of file_texture");
}
{
// Prepare the arguments of the function call for "mdl::base::texture_return.tint": set the
// "s" argument to the "call of file_texture" function call.
expression_factory->create_call( "call of file_texture"));
check_success( arg_expr.is_valid_interface());
expression_factory->create_expression_list());
arguments->add_expression( "s", arg_expr.get());
// Create a function call from the function definition "mdl::base::file_texture" with the
// just prepared arguments.
"mdl::base::texture_return.tint(::base::texture_return)"));
mi::Sint32 result;
function_definition->create_function_call( arguments.get(), &result));
check_success( result == 0);
transaction->store( function_call.get(), "call of texture_return.tint");
}
{
// Prepare the arguments of the material instance for
// "mdl::nvidia::sdk_examples::tutorials::example_material":
// set the "tint" argument to the "call of texture_return.tint" function call.
expression_factory->create_call( "call of texture_return.tint"));
check_success( arg_expr.is_valid_interface());
expression_factory->create_expression_list());
arguments->add_expression( "tint", arg_expr.get());
// Create a material instance from the material definition
// "mdl::nvidia::sdk_examples::tutorials::example_material"
// with the just prepared arguments.
"mdl::nvidia::sdk_examples::tutorials::example_material(color,float)"));
mi::Sint32 result;
material_definition->create_function_call( arguments.get(), &result));
check_success( result == 0);
transaction->store( material_instance.get(), "instance of example_material");
}
{
// Dump the created material instance and function calls.
transaction->access<mi::neuraylib::IFunction_call>(
"instance of example_material"));
std::cout << "Dumping material instance \"instance of example_material\":" << std::endl;
dump_instance( expression_factory.get(), material_instance.get(), std::cout);
transaction->access<mi::neuraylib::IFunction_call>(
"call of texture_return.tint"));
std::cout << "Dumping function call \"call of texture_return.tint\":" << std::endl;
dump_instance( expression_factory.get(), function_call.get(), std::cout);
function_call = transaction->access<mi::neuraylib::IFunction_call>(
"call of file_texture");
std::cout << "Dumping function call \"call of file_texture\":" << std::endl;
dump_instance( expression_factory.get(), function_call.get(), std::cout);
}
transaction->commit();
}
int MAIN_UTF8( int argc, char* argv[])
{
// Access the MDL SDK
mi::base::Handle<mi::neuraylib::INeuray> neuray(mi::examples::mdl::load_and_get_ineuray());
if (!neuray.is_valid_interface())
exit_failure("Failed to load the SDK.");
// Configure the MDL SDK
if (!mi::examples::mdl::configure(neuray.get()))
exit_failure("Failed to initialize the SDK.");
// Start the MDL SDK
mi::Sint32 ret = neuray->start();
if (ret != 0)
exit_failure("Failed to initialize the SDK. Result code: %d", ret);
// Create a textured material
create_textured_material( neuray.get());
// Shut down the MDL SDK
if (neuray->shutdown() != 0)
exit_failure("Failed to shutdown the SDK.");
// Unload the MDL SDK
neuray = nullptr;
if (!mi::examples::mdl::unload())
exit_failure("Failed to unload the SDK.");
exit_success();
}
// Convert command line arguments to UTF8 on Windows
COMMANDLINE_TO_UTF8
A simple string class.
Definition: istring.h:22
Handle class template for interfaces, automatizing the lifetime control via reference counting.
Definition: handle.h:113
This interface is used to interact with the distributed database.
Definition: idatabase.h:289
The interface for creating expressions.
Definition: iexpression.h:648
virtual const IString * dump(const IExpression *expr, const char *name, Size depth=0) const =0
Returns a textual representation of an expression.
virtual IExpression_call * create_call(const char *name) const =0
Creates a call.
virtual IExpression_list * create_expression_list() const =0
Creates a new expression list.
virtual IExpression_constant * create_constant(IValue *value) const =0
Creates a constant (mutable).
This interface represents a function call.
Definition: ifunction_call.h:52
This interface represents a function definition.
Definition: ifunction_definition.h:44
This interface represents a pixel image file.
Definition: iimage.h:65
Factory for various MDL interfaces and functions.
Definition: imdl_factory.h:53
API component for MDL related import and export operations.
Definition: imdl_impexp_api.h:42
This interface represents an MDL module.
Definition: imodule.h:611
This is an object representing the MDL SDK library.
Definition: ineuray.h:44
virtual Sint32 shutdown(bool blocking=true)=0
Shuts down the library.
virtual base::IInterface * get_api_component(const base::Uuid &uuid) const =0
Returns an API component from the MDL SDK API.
virtual Sint32 start(bool blocking=true)=0
Starts the operation of the MDL SDK library.
Textures add image processing options to images.
Definition: itexture.h:68
A texture value.
Definition: ivalue.h:525
unsigned int Uint32
32-bit unsigned integer.
Definition: types.h:49
Uint64 Size
Unsigned integral type that is large enough to hold the size of all types.
Definition: types.h:112
signed int Sint32
32-bit signed integer.
Definition: types.h:46
[Previous] [Up] [Next]