Example for the HTTP server
This example imports a scene file, renders the scene, and serves the image via an HTTP server
Detailed Description
- Running an HTTP server
-
This example provides a very simple HTTP server which just serves one particular image. The image is rendered in the same way as in the Example for Rendering. See HTTP server for a general introduction to the HTTP server.
This examples uses a simple request handler which always serves a fixed image, independent of the requested URL, etc. A response handler is installed to set the content type to 'image/jpeg'. Note that this is just done for illustration purposes. The content type could also be set directly by the request handler.
Example Source
Source Code Location: examples/example_http_server.cpp
/****************************************************************************** * Copyright 1986, 2011 NVIDIA Corporation. All rights reserved. *****************************************************************************/ // examples/example_http_server.cpp // // Imports a scene file, renders the scene, and serves the image via the HTTP server #include <iostream> #include <mi/neuraylib.h> // Include code shared by all examples. #include "example_shared.h" // Include an implementation of ITile, ICanvas, and IRender_target. #include "example_render_target.h" // Simple request handler which always sends the buffer passed in the constructor class Request_handler : public mi::base::Interface_implement<mi::http::IRequest_handler> { public: // Constructor. Stores the passed buffer. Request_handler( mi::base::Handle< mi::IBuffer> buffer) { m_buffer = buffer; } // Send buffer contents over the connection. bool handle( mi::http::IConnection* connection) { connection->enqueue( m_buffer.get()); return true; } private: // The stored buffer mi::base::Handle< mi::IBuffer> m_buffer; }; // Simple response handler which always sets the content type for JPG images class Response_handler : public mi::base::Interface_implement<mi::http::IResponse_handler> { public: void handle( mi::http::IConnection* connection) { mi::http::IResponse* iresponse( connection->get_response()); iresponse->set_header( "Content-Type", "image/jpeg"); } }; void configuration( mi::base::Handle< mi::neuraylib::INeuray> neuray, const char* shader_path) { // Configure the neuray library. Here we set some paths needed by the renderer. mi::base::Handle< mi::neuraylib::IRendering_configuration> rendering_configuration( neuray->get_api_component<mi::neuraylib::IRendering_configuration>()); check_success( rendering_configuration.is_valid_interface()); check_success( rendering_configuration->add_shader_path( shader_path) == 0); // Load the FreeImage image plugin and the LLVM backend for MetaSL. mi::base::Handle< mi::neuraylib::IPlugin_configuration> plugin_configuration( neuray->get_api_component<mi::neuraylib::IPlugin_configuration>()); #ifndef MI_PLATFORM_WINDOWS check_success( plugin_configuration->load_plugin_library( "freeimage.so") == 0); check_success( plugin_configuration->load_plugin_library( "gen_llvm.so") == 0); #else check_success( plugin_configuration->load_plugin_library( "freeimage.dll") == 0); check_success( plugin_configuration->load_plugin_library( "gen_llvm.dll") == 0); #endif } mi::base::Handle< mi::IBuffer> rendering( mi::base::Handle< mi::neuraylib::INeuray> neuray, const char* scene_file) { // Get the database, the global scope, which is the root for all transactions, // and create a transaction for importing the scene file and storing the scene. mi::base::Handle< mi::neuraylib::IDatabase> database( neuray->get_api_component<mi::neuraylib::IDatabase>()); check_success( database.is_valid_interface()); mi::base::Handle< mi::neuraylib::IScope> scope( database->get_global_scope()); mi::base::Handle< mi::neuraylib::ITransaction> transaction( scope->create_transaction()); check_success( transaction.is_valid_interface()); // Import the scene file mi::base::Handle< mi::neuraylib::IImport_api> import_api( neuray->get_api_component<mi::neuraylib::IImport_api>()); check_success( import_api.is_valid_interface()); mi::base::Handle< const mi::IImport_result> import_result( import_api->import_elements( transaction.get(), scene_file)); check_success( import_result->get_error_number() == 0); // Create the scene object mi::base::Handle< mi::neuraylib::IScene> scene( transaction->create<mi::neuraylib::IScene>( "Scene")); scene->set_rootgroup( import_result->get_rootgroup()); scene->set_options( import_result->get_options()); scene->set_camera_instance( import_result->get_camera_inst()); transaction->store( scene.get(), "the_scene"); // Create the render context using the default renderer scene = transaction->edit<mi::neuraylib::IScene>( "the_scene"); mi::base::Handle< mi::neuraylib::IRender_context> render_context( scene->get_render_context( transaction.get(), "default")); scene = 0; // Create the render target and render the scene Render_target render_target( 512, 384); check_success( render_context->render( transaction.get(), &render_target, NULL) == 0); // Access the first canvas of the render target mi::base::Handle< mi::neuraylib::ICanvas> canvas( render_target.get_canvas( 0)); // Convert content of the canvas to an JPG image mi::base::Handle< mi::neuraylib::IImage_api> image_api( neuray->get_api_component<mi::neuraylib::IImage_api>()); mi::base::Handle< mi::IBuffer> buffer( image_api->create_buffer_from_canvas( canvas.get(), "jpg", "Rgb", "100")); // All transactions need to get committed or aborted, not really important in this example. transaction->commit(); return buffer; } void run_http_server( mi::base::Handle< mi::neuraylib::INeuray> neuray, mi::base::Handle< mi::IBuffer> buffer, const char* port) { // Create a server instance mi::base::Handle< mi::http::IFactory> http_factory( neuray->get_api_component<mi::http::IFactory>()); mi::base::Handle< mi::http::IServer> http_server( http_factory->create_server()); // Install our request and response handlers mi::base::Handle< mi::http::IRequest_handler> request_handler( new Request_handler( buffer)); http_server->install( request_handler.get()); mi::base::Handle< mi::http::IResponse_handler> response_handler( new Response_handler()); http_server->install( response_handler.get()); // Assemble server address const char* ip = "0.0.0.0:"; char address[255]; address[0] = '\0'; strncat( address, ip, sizeof(address) - 1); strncat( address, port, sizeof(address) - 1 - strlen(address)); // Run server for fixed time interval http_server->start( address); sleep_seconds( 30); http_server->shutdown(); } // The example takes the following command line arguments: // // example_rendering <scene_file> <shader_path> <port> // // scene_file some scene file, e.g., main.mi // shader_path path to the shaders, e.g., neuray-<version>/shaders // port port for the HTTP server // int main( int argc, char* argv[]) { // Collect command line parameters if( argc != 4) { std::cerr << "Usage: example_rendering <scene_file> <shader_path> <port>" << std::endl; return EXIT_FAILURE; } const char* scene_file = argv[1]; const char* shader_path = argv[2]; const char* port = argv[3]; // Access the neuray library mi::base::Handle< mi::neuraylib::INeuray> neuray( load_and_get_ineuray()); check_success( neuray.is_valid_interface()); // Configure the neuray library configuration ( neuray, shader_path); // Start the neuray library check_success( neuray->start( true) == 0); // Do the actual rendering mi::base::Handle< mi::IBuffer> buffer = rendering( neuray, scene_file); // Serve image via HTTP server on given port run_http_server( neuray, buffer, port); buffer = 0; // Shut down the neuray library check_success( neuray->shutdown() == 0); neuray = 0; // Unload the neuray library check_success( unload()); return EXIT_SUCCESS; }