angus Posted August 17, 2017 Share Posted August 17, 2017 I cannot figure out how to render the current window to an Image or ImagePtr object. Does anyone have an example code snipped that works? I have tried doing it with the console command "video_grab" but that isn't fast enough. I've also tried the Viewport object and the Renderer object's API. ImagePtr image = Image::create(); image->create2D(1024, 576, Image::FORMAT_RGBA8, 1, 1); PlayerSpectatorPtr player = PlayerSpectator::create(); player->setPosition(Math::Vec3(0, 0, 2.0f)); CameraPtr camera = player->getCamera()->clone(); ViewportPtr viewport = Viewport::create(); Render *render = Unigine::Render::get(); render->setViewport(viewport); image->create2D(1024, 576, Image::FORMAT_RGBA8, 1, 1, 1); render->renderImage2D(camera, image, 0); The last line cases a crash of the application. I am using the C++ interface on the 2.5 SDK. Link to comment
silent Posted August 18, 2017 Share Posted August 18, 2017 Hi Angus, You can try to use your own viewport rendering (disable the main renderer and draw yours instead). With a help of new Gbuffer access API you can copy textures at any time. Please, check the SDK Browser -> Samples -> C++ API -> GbufferRead. Thanks! How to submit a good bug report --- FTP server for test scenes and user uploads: ftp://files.unigine.com user: upload password: 6xYkd6vLYWjpW6SN Link to comment
angus Posted August 18, 2017 Author Share Posted August 18, 2017 Hi Silent, Thanks for the pointer. I have the samples from previous version downloaded in the SDK browser. How can I force an update of the samples to see the new ones? Also, I'm not trying to disable the main window, I just want the pixels out of it in an Image object. It does seem that that should be simpler than it appears to be. Link to comment
silent Posted August 18, 2017 Share Posted August 18, 2017 To enable new samples you need to make 2.5 SDK as default in SDKs tab. If you can describe your use case in more details (what do you want to implement), we probably can suggest you different approach. But that one from samples should be already enough. Thanks! How to submit a good bug report --- FTP server for test scenes and user uploads: ftp://files.unigine.com user: upload password: 6xYkd6vLYWjpW6SN Link to comment
angus Posted August 18, 2017 Author Share Posted August 18, 2017 Thank you for the pointers. I see the 2.5 samples now. I had 2.4.1 set as my default which was the issue. The use-case is that I'm porting UnigineScript to C++. My UnigineScript routine is below. It stores 30 screenshots in an array of Image. I then play them back as an "action replay" in a race by creating a WidgetSprite and calling setImage() on it to display the images in sequence. void buffer_and_playback() { Image images[0]; Player play = node_cast(engine.editor.getNodeByName("finishline_cam")); Camera cam = play.getCamera(); Viewport vp = new Viewport(); vp.setSkipFlags(VIEWPORT_SKIP_VELOCITY_BUFFER); forloop(int i = 0; 30) { images.append(new Image()); vp.renderImage2D(cam, images[i]); busy_sleep(1.0f/FPS); } ... The closest I have got so far is pasted below. This does render out an image to the PNG but I think it is done so before the sky is drawn and before anti-aliasing is done as they appear to be missing. void testit() { Log::message("Button pressed\n"); int width = 1024; int height = 576; Render *render = Render::get(); // Below line returns null. Is this a bug? //ViewportPtr viewport = render->getViewport(); ViewportPtr viewport = Viewport::create(); viewport->setRenderMode(Viewport::RENDER_DEPTH_GBUFFER_FINAL); viewport->setSkipFlags(0); PlayerPtr player = Game::get()->getPlayer(); CameraPtr camera = player->getCamera(); ImagePtr image = Image::create(); // Must be called before renderImage2D viewport->render(camera); image->create2D(width, height, 1, 1, 1); viewport->renderImage2D(camera, image, width, height, 0); image->save("test-image.png"); I have also tried the Texture interface rather than the Image interface and it gives the same result. The image produced form the above code is below. The darkness is fine as the quadratic exposure isn't going to be in a viewport but note the sky is missing and it's not anti-aliased as you can see if you zoom in. Am I going about this in the right way, or is there a different route I should be trying? Getting a screenshot of the final buffer sent to the screen seems like it should be easier than it appears. Link to comment
silent Posted August 18, 2017 Share Posted August 18, 2017 Hi Angus, If you can send us minimal sample with working UnigineScript code (basically, press key - record starting, press another - WidgetSprite appears and playback happens) we can see how can it be easily ported to C++ side. Thanks! How to submit a good bug report --- FTP server for test scenes and user uploads: ftp://files.unigine.com user: upload password: 6xYkd6vLYWjpW6SN Link to comment
angus Posted August 21, 2017 Author Share Posted August 21, 2017 Sure thing, Silent. I've attached a Uniginescript file showing the currently used method of capturing frames. screenshot_dev.cpp Link to comment
fox Posted August 23, 2017 Share Posted August 23, 2017 Hi Angus, I've attached a C++ example of a simple video grabber which uses the Viewport::RenderImage2D method. Please check it out, the source files include necessary comments. Just create a new C++ project and replace AppWorldLogic.* source files with the ones attached. TAA and exposure issues are associated with the fact that both of these features use series of subsequent frames, so we have to call Viewport::RenderImage2D each frame. You should notice TAA and adaptive exposure warm-up at the beginning of the playback. In order to see the sky the image should be converted to the RGB8 format. image->convertToFormat(Unigine::Image::FORMAT_RGB8); Hope this helps! Thanks! AppWorldLogic.cpp AppWorldLogic.h Link to comment
angus Posted August 25, 2017 Author Share Posted August 25, 2017 Thanks very much, Fox. I've downloaded that and we'll pick it apart to see how it works. Link to comment
Recommended Posts