Running an HTTP server
The program example_http_server.cpp provides a very simple HTTP server which serves one particular image. The image is rendered in the same way as previous examples such as A first image.
The example_http_server.cpp program uses a simple request handler that always serves a fixed image, independent of the requested URL. A response handler is installed to set the content type to image/jpeg. This is just done for illustration purposes; the content type could also be set directly by the request handler.
Note:
For a general introduction to the HTTP server, see HTTP server.
example_http_server.cpp
001 /****************************************************************************** 002 * © 1986, 2016 NVIDIA Corporation. All rights reserved. 003 *****************************************************************************/ 004 005 // examples/example_http_server.cpp 006 // 007 // Imports a scene file, renders the scene, and serves the image via the HTTP server 008 // 009 // The example expects the following command line arguments: 010 // 011 // example_rendering <scene_file> <mdl_path> <port> 012 // 013 // scene_file some scene file, e.g., main.mi 014 // mdl_path path to the MDL modules, e.g., iray-<version>/mdl 015 // port port for the HTTP server 016 017 #include <iostream> 018 019 #include <mi/neuraylib.h> 020 021 // Include code shared by all examples. 022 #include "example_shared.h" 023 // Include an implementation of IRender_target. 024 #include "example_render_target_simple.h" 025 026 // Simple request handler which always sends the buffer passed in the constructor 027 class Request_handler : public mi::base::Interface_implement<mi::http::IRequest_handler> 028 { 029 public: 030 // Constructor. Stores the passed buffer. 031 Request_handler( mi::base::Handle<mi::neuraylib::IBuffer> buffer) 032 { 033 m_buffer = buffer; 034 } 035 036 // Send buffer contents over the connection. 037 bool handle( mi::http::IConnection* connection) 038 { 039 connection->enqueue( m_buffer.get()); 040 return true; 041 } 042 private: 043 // The stored buffer 044 mi::base::Handle<mi::neuraylib::IBuffer> m_buffer; 045 }; 046 047 // Simple response handler which always sets the content type for JPG images 048 class Response_handler : public mi::base::Interface_implement<mi::http::IResponse_handler> 049 { 050 public: 051 void handle( mi::http::IConnection* connection) 052 { 053 mi::http::IResponse* iresponse( connection->get_response()); 054 iresponse->set_header( "Content-Type", "image/jpeg"); 055 } 056 }; 057 058 void configuration( mi::base::Handle<mi::neuraylib::INeuray> neuray, const char* mdl_path) 059 { 060 // Configure the neuray library. Here we set the search path for .mdl files. 061 mi::base::Handle<mi::neuraylib::IRendering_configuration> rendering_configuration( 062 neuray->get_api_component<mi::neuraylib::IRendering_configuration>()); 063 check_success( rendering_configuration.is_valid_interface()); 064 check_success( rendering_configuration->add_mdl_path( mdl_path) == 0); 065 066 // Load the FreeImage, Iray Photoreal, and .mi importer plugins. 067 mi::base::Handle<mi::neuraylib::IPlugin_configuration> plugin_configuration( 068 neuray->get_api_component<mi::neuraylib::IPlugin_configuration>()); 069 #ifndef MI_PLATFORM_WINDOWS 070 check_success( plugin_configuration->load_plugin_library( "freeimage.so") == 0); 071 check_success( plugin_configuration->load_plugin_library( "libiray.so") == 0); 072 check_success( plugin_configuration->load_plugin_library( "mi_importer.so") == 0); 073 #else 074 check_success( plugin_configuration->load_plugin_library( "freeimage.dll") == 0); 075 check_success( plugin_configuration->load_plugin_library( "libiray.dll") == 0); 076 check_success( plugin_configuration->load_plugin_library( "mi_importer.dll") == 0); 077 #endif 078 } 079 080 mi::base::Handle<mi::neuraylib::IBuffer> rendering( 081 mi::base::Handle<mi::neuraylib::INeuray> neuray, const char* scene_file) 082 { 083 // Get the database, the global scope of the database, and create a transaction in the global 084 // scope for importing the scene file and storing the scene. 085 mi::base::Handle<mi::neuraylib::IDatabase> database( 086 neuray->get_api_component<mi::neuraylib::IDatabase>()); 087 check_success( database.is_valid_interface()); 088 mi::base::Handle<mi::neuraylib::IScope> scope( 089 database->get_global_scope()); 090 mi::base::Handle<mi::neuraylib::ITransaction> transaction( 091 scope->create_transaction()); 092 check_success( transaction.is_valid_interface()); 093 094 // Import the scene file 095 mi::base::Handle<mi::neuraylib::IImport_api> import_api( 096 neuray->get_api_component<mi::neuraylib::IImport_api>()); 097 check_success( import_api.is_valid_interface()); 098 mi::base::Handle<const mi::IString> uri( import_api->convert_filename_to_uri( scene_file)); 099 mi::base::Handle<const mi::neuraylib::IImport_result> import_result( 100 import_api->import_elements( transaction.get(), uri->get_c_str())); 101 check_success( import_result->get_error_number() == 0); 102 103 // Create the scene object 104 mi::base::Handle<mi::neuraylib::IScene> scene( 105 transaction->create<mi::neuraylib::IScene>( "Scene")); 106 scene->set_rootgroup( import_result->get_rootgroup()); 107 scene->set_options( import_result->get_options()); 108 scene->set_camera_instance( import_result->get_camera_inst()); 109 transaction->store( scene.get(), "the_scene"); 110 111 // Create the render context using the Iray Photoreal render mode 112 scene = transaction->edit<mi::neuraylib::IScene>( "the_scene"); 113 mi::base::Handle<mi::neuraylib::IRender_context> render_context( 114 scene->create_render_context( transaction.get(), "iray")); 115 check_success( render_context.is_valid_interface()); 116 mi::base::Handle<mi::IString> scheduler_mode( transaction->create<mi::IString>()); 117 scheduler_mode->set_c_str( "batch"); 118 render_context->set_option( "scheduler_mode", scheduler_mode.get()); 119 scene = 0; 120 121 // Create the render target and render the scene 122 mi::base::Handle<mi::neuraylib::IImage_api> image_api( 123 neuray->get_api_component<mi::neuraylib::IImage_api>()); 124 mi::base::Handle<mi::neuraylib::IRender_target> render_target( 125 new Render_target( image_api.get(), "Color", 512, 384)); 126 check_success( render_context->render( transaction.get(), render_target.get(), 0) >= 0); 127 128 // Access the first canvas of the render target 129 mi::base::Handle<mi::neuraylib::ICanvas> canvas( render_target->get_canvas( 0)); 130 131 // Convert content of the canvas to an JPG image 132 mi::base::Handle<mi::neuraylib::IBuffer> buffer( 133 image_api->create_buffer_from_canvas( canvas.get(), "jpg", "Rgb", "100")); 134 135 transaction->commit(); 136 137 return buffer; 138 } 139 140 void run_http_server( 141 mi::base::Handle<mi::neuraylib::INeuray> neuray, 142 mi::base::Handle<mi::neuraylib::IBuffer> buffer, 143 const char* port) 144 { 145 // Create a server instance 146 mi::base::Handle<mi::http::IFactory> http_factory( 147 neuray->get_api_component<mi::http::IFactory>()); 148 mi::base::Handle<mi::http::IServer> http_server( 149 http_factory->create_server()); 150 151 // Install our request and response handlers 152 mi::base::Handle<mi::http::IRequest_handler> request_handler( new Request_handler( buffer)); 153 http_server->install( request_handler.get()); 154 mi::base::Handle<mi::http::IResponse_handler> response_handler( new Response_handler()); 155 http_server->install( response_handler.get()); 156 157 // Assemble server address 158 std::string address = "0.0.0.0:"; 159 address += port; 160 161 // Run server for fixed time interval 162 http_server->start( address.c_str()); 163 sleep_seconds( 30); 164 http_server->shutdown(); 165 } 166 167 int main( int argc, char* argv[]) 168 { 169 // Collect command line parameters 170 if( argc != 4) { 171 std::cerr << "Usage: example_http_server <scene_file> <mdl_path> <port>" << std::endl; 172 keep_console_open(); 173 return EXIT_FAILURE; 174 } 175 const char* scene_file = argv[1]; 176 const char* mdl_path = argv[2]; 177 const char* port = argv[3]; 178 179 // Access the neuray library 180 mi::base::Handle<mi::neuraylib::INeuray> neuray( load_and_get_ineuray()); 181 check_success( neuray.is_valid_interface()); 182 183 // Configure the neuray library 184 configuration( neuray, mdl_path); 185 186 // Start the neuray library 187 mi::Sint32 result = neuray->start(); 188 check_start_success( result); 189 190 // Do the actual rendering 191 mi::base::Handle<mi::neuraylib::IBuffer> buffer = rendering( neuray, scene_file); 192 193 // Serve image via HTTP server on given port 194 run_http_server( neuray, buffer, port); 195 buffer = 0; 196 197 // Shut down the neuray library 198 check_success( neuray->shutdown() == 0); 199 neuray = 0; 200 201 // Unload the neuray library 202 check_success( unload()); 203 204 keep_console_open(); 205 return EXIT_SUCCESS; 206 }