Using an Iray Bridge server
You need to configure the address and port of the Iray Bridge server. See the following example program for details:
For a render request, select the render mode iray_cloud. No other changes are required.
The example shows how to create a snapshot of the uploaded scene on the server side. This operation is asynchronous. The example program simply waits for the operation to finish since there is nothing else to do. The created snapshot can be imported later using the cb_importer plugin (with the same setting for the cache directory on the server).
example_bridge_server.cpp
001 /****************************************************************************** 002 * © 1986, 2014 NVIDIA Corporation. All rights reserved. 003 *****************************************************************************/ 004 005 // examples/example_bridge_server.cpp 006 // 007 // Starts listening for Iray Bridge clients. It will accept client rendering and snapshot requests. 008 // 009 // The example expects the following command line argument: 010 // 011 // example_bridge_server <mdl_path> <path_to_disk_cache> <listen_address> 012 // 013 // mdl_path path to the MDL modules, e.g., iray-<version>/mdl 014 // path_to_disk_cache directory where the server can cache uploaded elements 015 // listen_address the address to listen on, e.g., 0.0.0.0:8998 016 017 #include <cstdio> 018 019 #include <mi/neuraylib.h> 020 021 // Include code shared by all examples. 022 #include "example_shared.h" 023 024 void run_bridge_server( mi::base::Handle<mi::neuraylib::INeuray> neuray) 025 { 026 // Create a server instance 027 mi::base::Handle<mi::neuraylib::IRemote_server> bridge_server( 028 neuray->get_api_component<mi::neuraylib::IRemote_server>()); 029 bridge_server->start(); 030 sleep_seconds( 60); 031 } 032 033 void configuration( mi::base::Handle<mi::neuraylib::INeuray> neuray, 034 const char* mdl_path, 035 const char* disk_cache_path, 036 const char* server_address) 037 { 038 // Configure the Remote server 039 mi::base::Handle<mi::neuraylib::IRemote_configuration> remote_configuration( 040 neuray->get_api_component<mi::neuraylib::IRemote_configuration>()); 041 check_success( remote_configuration.is_valid_interface()); 042 check_success( remote_configuration->set_remote_disk_cache_path( disk_cache_path) == 0); 043 check_success( remote_configuration->set_scene_export_path( disk_cache_path) == 0); 044 check_success( remote_configuration->set_remote_server_listen_address( server_address) == 0); 045 046 // set the search path for .mdl files. 047 mi::base::Handle<mi::neuraylib::IRendering_configuration> rendering_configuration( 048 neuray->get_api_component<mi::neuraylib::IRendering_configuration>()); 049 check_success( rendering_configuration.is_valid_interface()); 050 check_success( rendering_configuration->add_mdl_path( mdl_path) == 0); 051 052 // Load the FreeImage, Iray Photoreal, and cloud render plugins. 053 mi::base::Handle<mi::neuraylib::IPlugin_configuration> plugin_configuration( 054 neuray->get_api_component<mi::neuraylib::IPlugin_configuration>()); 055 #ifndef MI_PLATFORM_WINDOWS 056 check_success( plugin_configuration->load_plugin_library( "freeimage.so") == 0); 057 check_success( plugin_configuration->load_plugin_library( "libiray.so") == 0); 058 check_success( plugin_configuration->load_plugin_library( "cloud_render_server.so") == 0); 059 #else 060 check_success( plugin_configuration->load_plugin_library( "freeimage.dll") == 0); 061 check_success( plugin_configuration->load_plugin_library( "libiray.dll") == 0); 062 check_success( plugin_configuration->load_plugin_library( "cloud_render_server.dll") == 0); 063 #endif 064 } 065 066 int main( int argc, char* argv[]) 067 { 068 // Collect command line parameters 069 if( argc != 4) { 070 fprintf( stderr, 071 "Usage: example_bridge_server <mdl_path> <path_to_disk_cache> <listen_address>\n"); 072 keep_console_open(); 073 return EXIT_FAILURE; 074 } 075 const char* mdl_path = argv[1]; 076 const char* disk_cache_path = argv[2]; 077 const char* listen_address = argv[3]; 078 079 // Access the neuray library 080 mi::base::Handle<mi::neuraylib::INeuray> neuray( load_and_get_ineuray()); 081 check_success( neuray.is_valid_interface()); 082 083 // Configure the neuray library 084 configuration( neuray, mdl_path, disk_cache_path, listen_address); 085 086 // Start the neuray library 087 check_success( neuray->start() == 0); 088 089 // Prepare to listen to bridge clients 090 run_bridge_server( neuray); 091 092 // Shut down the neuray library 093 check_success( neuray->shutdown() == 0); 094 neuray = 0; 095 096 // Unload the neuray library 097 check_success( unload()); 098 099 keep_console_open(); 100 return EXIT_SUCCESS; 101 }
example_bridge_client.cpp
001 /****************************************************************************** 002 * © 1986, 2014 NVIDIA Corporation. All rights reserved. 003 *****************************************************************************/ 004 005 // examples/example_bridge_client.cpp 006 // 007 // Connects to an Iray Bridge server, uploads a scene, makes a snapshot, and asks the server to 008 // render it. 009 // 010 // The example expects the following command line argument: 011 // 012 // example_bridge_client <scene_file> <bridge_server_address> 013 // 014 // scene_file the path to a scene file 015 // mdl_path to the MDL modules, e.g., iray-<version>/mdl 016 // bridge_server_address address of the bridge server on the form <ip:port> 017 // 018 // The rendered image is written to a file named "example_bridge_rendering.png". 019 020 #include <cstdio> 021 022 #include <mi/neuraylib.h> 023 024 // Include code shared by all examples. 025 #include "example_shared.h" 026 // Include an implementation of IRender_target. 027 #include "example_render_target_simple.h" 028 029 // Save snapshot ready callback implementation. 030 class Save_snapshot_ready_callback : 031 public mi::base::Interface_implement<mi::neuraylib::IRemote_ready_callback> 032 { 033 public: 034 void ready( mi::Sint32 /*async_token*/, mi::Sint32 error_code, const char* /*file_name*/) 035 { 036 if( error_code == 0) 037 fprintf( stderr, "Successfully created cb snapshot.\n"); 038 else 039 fprintf( stderr, "Failed to create cb snapshot.\n"); 040 m_cond.signal(); 041 } 042 043 void wait_for_commit() 044 { 045 m_cond.wait(); 046 } 047 048 private: 049 mi::base::Condition m_cond; 050 }; 051 052 // Progress callback implementation. 053 class Progress_callback : public mi::base::Interface_implement<mi::neuraylib::IProgress_callback> 054 { 055 public: 056 void progress( mi::Float64 value, const char* area, const char* message) 057 { 058 fprintf( stderr, "Progress: %.4f %s %s\n", value, area, message); 059 } 060 }; 061 062 void configuration( mi::base::Handle<mi::neuraylib::INeuray> neuray, 063 const char* mdl_path, 064 const char* bridge_server_address) 065 { 066 // Configure the Remote server 067 mi::base::Handle<mi::neuraylib::IRemote_configuration> remote_configuration( 068 neuray->get_api_component<mi::neuraylib::IRemote_configuration>()); 069 check_success( remote_configuration.is_valid_interface()); 070 check_success( remote_configuration->set_remote_address( bridge_server_address) == 0); 071 072 // Set the search path for .mdl files. 073 mi::base::Handle<mi::neuraylib::IRendering_configuration> rendering_configuration( 074 neuray->get_api_component<mi::neuraylib::IRendering_configuration>()); 075 check_success( rendering_configuration.is_valid_interface()); 076 check_success( rendering_configuration->add_mdl_path( mdl_path) == 0); 077 078 // Load the FreeImage, cloud render, and .mi importer plugins. 079 mi::base::Handle<mi::neuraylib::IPlugin_configuration> plugin_configuration( 080 neuray->get_api_component<mi::neuraylib::IPlugin_configuration>()); 081 #ifndef MI_PLATFORM_WINDOWS 082 check_success( plugin_configuration->load_plugin_library( "freeimage.so") == 0); 083 check_success( plugin_configuration->load_plugin_library( "cloud_render.so") == 0); 084 check_success( plugin_configuration->load_plugin_library( "mi_importer.so") == 0); 085 #else 086 check_success( plugin_configuration->load_plugin_library( "freeimage.dll") == 0); 087 check_success( plugin_configuration->load_plugin_library( "cloud_render.dll") == 0); 088 check_success( plugin_configuration->load_plugin_library( "mi_importer.dll") == 0); 089 #endif 090 } 091 092 void import_and_store_scene( mi::base::Handle<mi::neuraylib::INeuray> neuray, 093 const char* scene_file) 094 { 095 // Get the database, the global scope, which is the root for all transactions, 096 // and create a transaction. 097 mi::base::Handle<mi::neuraylib::IDatabase> database 098 (neuray->get_api_component<mi::neuraylib::IDatabase>()); 099 check_success( database.is_valid_interface()); 100 mi::base::Handle<mi::neuraylib::IScope> scope( database->get_global_scope()); 101 mi::base::Handle<mi::neuraylib::ITransaction> transaction( scope->create_transaction()); 102 check_success( transaction.is_valid_interface()); 103 104 // Import the scene file 105 mi::base::Handle<mi::neuraylib::IImport_api> import_api( 106 neuray->get_api_component<mi::neuraylib::IImport_api>()); 107 check_success( import_api.is_valid_interface()); 108 mi::base::Handle<const mi::IString> uri( import_api->convert_filename_to_uri( scene_file)); 109 mi::base::Handle<const mi::IImport_result> import_result( 110 import_api->import_elements( transaction.get(), uri->get_c_str())); 111 check_success( import_result->get_error_number() == 0); 112 113 // Create the scene object 114 mi::base::Handle<mi::neuraylib::IScene> scene( 115 transaction->create<mi::neuraylib::IScene>("Scene")); 116 check_success( scene.is_valid_interface()); 117 scene->set_rootgroup( import_result->get_rootgroup()); 118 scene->set_options( import_result->get_options()); 119 scene->set_camera_instance( import_result->get_camera_inst()); 120 121 // And store it in the database 122 transaction->store( scene.get(), "the_scene"); 123 scene = 0; 124 transaction->commit(); 125 } 126 127 void rendering( mi::base::Handle<mi::neuraylib::INeuray> neuray) 128 { 129 // Get the database, the global scope, which is the root for all transactions, 130 // and create a transaction. 131 mi::base::Handle<mi::neuraylib::IDatabase> database( 132 neuray->get_api_component<mi::neuraylib::IDatabase>()); 133 check_success( database.is_valid_interface()); 134 mi::base::Handle<mi::neuraylib::IScope> scope( database->get_global_scope()); 135 mi::base::Handle<mi::neuraylib::ITransaction> transaction( scope->create_transaction()); 136 check_success( transaction.is_valid_interface()); 137 138 // Create the render context using the iray_cloud render mode. 139 mi::base::Handle<mi::neuraylib::IScene> scene( 140 transaction->edit<mi::neuraylib::IScene>( "the_scene")); 141 mi::base::Handle<mi::neuraylib::IRender_context> render_context( 142 scene->create_render_context( transaction.get(), "iray_cloud")); 143 check_success( render_context.is_valid_interface()); 144 mi::base::Handle<mi::IString> scheduler_mode( transaction->create<mi::IString>()); 145 scheduler_mode->set_c_str( "batch"); 146 render_context->set_option( "scheduler_mode", scheduler_mode.get()); 147 mi::base::Handle<mi::IString> video_format( transaction->create<mi::IString>()); 148 video_format->set_c_str( "jpg"); 149 render_context->set_option( "video_format", video_format.get()); 150 151 scene = 0; 152 153 // Create the render target and render the scene 154 mi::base::Handle<mi::neuraylib::IImage_api> image_api( 155 neuray->get_api_component<mi::neuraylib::IImage_api>()); 156 mi::base::Handle<mi::neuraylib::IRender_target> render_target( 157 new Render_target( image_api.get(), "Color", 512, 384)); 158 check_success( render_context->render( transaction.get(), render_target.get(), 0) >= 0); 159 160 // Write the image to disk 161 mi::base::Handle<mi::neuraylib::IExport_api> export_api( 162 neuray->get_api_component<mi::neuraylib::IExport_api>()); 163 check_success( export_api.is_valid_interface()); 164 mi::base::Handle<mi::neuraylib::ICanvas> canvas( render_target->get_canvas( 0)); 165 export_api->export_canvas( "file:example_bridge_client.png", canvas.get()); 166 167 transaction->commit(); 168 } 169 170 void make_snapshot( mi::base::Handle<mi::neuraylib::INeuray> neuray) 171 { 172 // Get the global scope, which is the root for all transactions, 173 // and create a transaction. 174 mi::base::Handle<mi::neuraylib::IDatabase> database( 175 neuray->get_api_component<mi::neuraylib::IDatabase>()); 176 mi::base::Handle<mi::neuraylib::IScope> scope( database->get_global_scope()); 177 mi::base::Handle<mi::neuraylib::ITransaction> transaction( scope->create_transaction()); 178 179 // Get the Remote client interface 180 mi::base::Handle<mi::neuraylib::IRemote_client> bridge_client( 181 neuray->get_api_component<mi::neuraylib::IRemote_client>()); 182 check_success( bridge_client.is_valid_interface()); 183 184 mi::base::Handle<Progress_callback> progress( new Progress_callback()); 185 mi::base::Handle<Save_snapshot_ready_callback> ready( new Save_snapshot_ready_callback()); 186 187 check_success( bridge_client->create_remote_snapshot( 188 transaction.get(), "the_scene", "cb_name_on_server.cb", ready.get(), progress.get()) >= 0); 189 190 // Wait for the ready callback. 191 ready->wait_for_commit(); 192 193 transaction->commit(); 194 } 195 196 int main( int argc, char* argv[]) 197 { 198 // Collect command line parameters 199 if( argc != 4) { 200 fprintf( stderr, 201 "Usage: example_bridge_client <scene_file> <mdl_path> <bridge_server_address>\n"); 202 keep_console_open(); 203 return EXIT_FAILURE; 204 } 205 const char* scene_file = argv[1]; 206 const char* mdl_path = argv[2]; 207 const char* bridge_server_address = argv[3]; 208 209 // Access the neuray library 210 mi::base::Handle<mi::neuraylib::INeuray> neuray( load_and_get_ineuray()); 211 check_success( neuray.is_valid_interface()); 212 213 // Configure the neuray library 214 configuration( neuray, mdl_path, bridge_server_address); 215 216 // Start the neuray library 217 check_success( neuray->start() == 0); 218 219 // Import the scene into the DB 220 import_and_store_scene( neuray, scene_file); 221 222 // Upload scene and render in the cloud, then export the rendered image to disk 223 rendering( neuray); 224 225 // Make a snapshot of the scene on the bridge server 226 make_snapshot( neuray); 227 228 // Shut down the neuray library 229 check_success( neuray->shutdown() == 0); 230 neuray = 0; 231 232 // Unload the neuray library 233 check_success( unload()); 234 235 keep_console_open(); 236 return EXIT_SUCCESS; 237 }