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, 2014 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::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::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::IBuffer> rendering( mi::base::Handle<mi::neuraylib::INeuray> neuray,
081                                          const char* scene_file)
082 {
083     // Get the database, the global scope, which is the root for all transactions,
084     // and create a transaction 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::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::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( mi::base::Handle<mi::neuraylib::INeuray> neuray,
141                       mi::base::Handle<mi::IBuffer> buffer,
142                       const char* port)
143 {
144     // Create a server instance
145     mi::base::Handle<mi::http::IFactory> http_factory(
146         neuray->get_api_component<mi::http::IFactory>());
147     mi::base::Handle<mi::http::IServer> http_server(
148         http_factory->create_server());
149 
150     // Install our request and response handlers
151     mi::base::Handle<mi::http::IRequest_handler> request_handler(
152         new Request_handler( buffer));
153     http_server->install( request_handler.get());
154     mi::base::Handle<mi::http::IResponse_handler> response_handler(
155         new Response_handler());
156     http_server->install( response_handler.get());
157 
158     // Assemble server address
159     const char* ip = "0.0.0.0:";
160     char address[255];
161     address[0] = '\0';
162     strncat( address, ip, sizeof(address) - 1);
163     strncat( address, port, sizeof(address) - 1 - strlen(address));
164 
165     // Run server for fixed time interval
166     http_server->start( address);
167     sleep_seconds( 30);
168     http_server->shutdown();
169 }
170 
171 int main( int argc, char* argv[])
172 {
173     // Collect command line parameters
174     if( argc != 4) {
175         std::cerr << "Usage: example_http_server <scene_file> <mdl_path> <port>" << std::endl;
176         keep_console_open();
177         return EXIT_FAILURE;
178     }
179     const char* scene_file  = argv[1];
180     const char* mdl_path = argv[2];
181     const char* port        = argv[3];
182 
183     // Access the neuray library
184     mi::base::Handle<mi::neuraylib::INeuray> neuray( load_and_get_ineuray());
185     check_success( neuray.is_valid_interface());
186 
187     // Configure the neuray library
188     configuration( neuray, mdl_path);
189 
190     // Start the neuray library
191     check_success( neuray->start() == 0);
192 
193     // Do the actual rendering
194     mi::base::Handle<mi::IBuffer> buffer = rendering( neuray, scene_file);
195 
196     // Serve image via HTTP server on given port
197     run_http_server( neuray, buffer, port);
198     buffer = 0;
199 
200     // Shut down the neuray library
201     check_success( neuray->shutdown() == 0);
202     neuray = 0;
203 
204     // Unload the neuray library
205     check_success( unload());
206 
207     keep_console_open();
208     return EXIT_SUCCESS;
209 }