Iray Programmer's Manual

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 }