Horde3D http://horde3d.org/forums/ |
|
Produce high quality demo movie http://horde3d.org/forums/viewtopic.php?f=1&t=732 |
Page 1 of 1 |
Author: | johnoriginal [ 09.05.2009, 17:59 ] |
Post subject: | Produce high quality demo movie |
Hi everyone, I am more or less finished with a crowd simulation application that I wrote using Horde3d. I would like to produce a high-quality demo movie. As a result, I don't want to screen capture the simulation using programs like e.g. fraps, but I intend to export the rendered frames into a series of image files and then produce the final movie. Thus, I would like to know if there is a clever (performance-wise) way to do that. Does Horde support this functionality? Of course I can read the pixels from the frame buffer using the glReadPixels() function and then store these into a an image format. However, since this will be done on the fly, it will significantly affect the frame rates . So I strive for a better approach. Thanks |
Author: | DarkAngel [ 10.05.2009, 01:21 ] |
Post subject: | Re: Produce high quality demo movie |
I recorded this horde video at 1280*1024 @ 60 fps as a stream of TGA files. The key for me was using a "delta time" value of 1/60s (0.0166...) for every frame of the simulation, ignoring how much time had actually past. This meant that the video is completely smooth, although to record 10 seconds of video took about 1 minute. I use this function to get the pixel-data out of Horde: Code: void CPipeline::RenderTargetData( const std::string& name, int bufIndex, uint& width, uint& height, And my main loop looks like this:uint& components, std::vector<float>& out ) { int w=0,h=0,c=0; Horde3D::getPipelineRenderTargetData( GetID(), name.c_str(), bufIndex, &w, &h, &c, NULL, 0 ); int s = w*h*c; out.resize( s ); if( s ) Horde3D::getPipelineRenderTargetData( GetID(), name.c_str(), bufIndex, 0, 0, 0, &out[0], s*sizeof(float) ); width = w; height = h; components = c; } Code: const float averageFrameRate = 1/60.0f;
float flDelta = averageFrameRate; double flLastTime = GetTime(); while( !m_exitApp ) { if( m_Record ) { flDelta = averageFrameRate; flLastTime += averageFrameRate; } UpdateScene( renderer, flLastTime, flDelta ); RenderScene( renderer ); if( m_Record ) { std::stringstream filename; filename << "record" << std::setw(4) << std::setfill('0') << m_RecordedFrames++ << ".tga"; uint w, h, c; std::vector<float> data; ScreenShot( w, h, c, data ); FILE* fp; if( w && h && c && (fp = fopen( filename.str().c_str(), "wb" )) ) { uint8 bpp = c*8; std::auto_ptr<uint8> apOutput( new uint8[w*h*c] ); uint8* imageOut = apOutput.get(); ASSERT( data.size() == w*h*c ); for( uint i=0; i<w*h*c; i+=c ) { if( c == 4 ) { imageOut[i+0] = (uint8)(data[i+2]*255.0f); imageOut[i+1] = (uint8)(data[i+1]*255.0f); imageOut[i+2] = (uint8)(data[i+0]*255.0f); imageOut[i+3] = (uint8)(data[i+3]*255.0f); } else if( c == 3 ) { imageOut[i+0] = (uint8)(data[i+2]*255.0f); imageOut[i+1] = (uint8)(data[i+1]*255.0f); imageOut[i+2] = (uint8)(data[i+0]*255.0f); } else { for( uint j=0; j<c; ++j ) imageOut[i+j] = (uint8)(data[i+j]*255.0f); } } // Build TGA header uint8 b; uint16 s; fwrite( &(b = 0), sizeof(uint8 ), 1, fp );// Number of ID bytes after header fwrite( &(b = 0), sizeof(uint8 ), 1, fp );// Color map type: none fwrite( &(b = 2), sizeof(uint8 ), 1, fp );// Image type: Uncompressed true color fwrite( &(s = 0), sizeof(uint16), 1, fp );// First color map index fwrite( &(s = 0), sizeof(uint16), 1, fp );// Color map length fwrite( &(b = 16), sizeof(uint8 ), 1, fp );// Color map bits per entry fwrite( &(s = 0), sizeof(uint16), 1, fp );// X origin fwrite( &(s = 0), sizeof(uint16), 1, fp );// Y origin fwrite( &(s = w), sizeof(uint16), 1, fp );// Width fwrite( &(s = h), sizeof(uint16), 1, fp );// Height fwrite( &(b =bpp), sizeof(uint8 ), 1, fp );// Bits per pixel fwrite( &(b = 0), sizeof(uint8 ), 1, fp );// Image descriptor fwrite( imageOut, sizeof(uint8 ), w*h*c, fp ); fclose( fp ); } } // Calculate FPS double flNewTime = GetTime(); flDelta = (float)(flNewTime-flLastTime); if( !m_Record ) flLastTime = flNewTime; m_curFPS = 1/flDelta; } |
Author: | johnoriginal [ 10.05.2009, 12:14 ] |
Post subject: | Re: Produce high quality demo movie |
Thanks DarkAngel. I 've also implemented a similar approach. I have a constant dt, as it is important for the accuracy of the crowd simulation. However, I didn't use the getPipelineRenderTargetData function but the glReadPixels to get the pixel out. Then, using a pretty simple TGA class, I export the output data into a series of TGA files. I think that it would be nice if a future release of Horde would support this kind of functionality. In the end, we want to demonstrate our work based on Horde3D and thus, high-quality movies are needed. |
Author: | DarkAngel [ 11.05.2009, 11:23 ] |
Post subject: | Re: Produce high quality demo movie |
Actually, now I remember that Horde has the utility function createTGAImage - combined with getPipelineRenderTargetData then Horde already supports this feature Implementing a fixed time-step and writing data to disc is outside the scope of the renderer, so this part doesn't really belong in Horde. |
Page 1 of 1 | All times are UTC + 1 hour |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |