Horde3D

Next-Generation Graphics Engine
It is currently 26.11.2024, 05:28

All times are UTC + 1 hour




Post new topic Reply to topic  [ 4 posts ] 
Author Message
PostPosted: 09.05.2009, 17:59 
Offline

Joined: 18.04.2009, 16:21
Posts: 4
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 :cry: . So I strive for a better approach.

Thanks


Top
 Profile  
Reply with quote  
PostPosted: 10.05.2009, 01:21 
Offline

Joined: 08.11.2006, 03:10
Posts: 384
Location: Australia
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,
                                  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;
}
And my main loop looks like this:
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;
   }


Top
 Profile  
Reply with quote  
PostPosted: 10.05.2009, 12:14 
Offline

Joined: 18.04.2009, 16:21
Posts: 4
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.


Top
 Profile  
Reply with quote  
PostPosted: 11.05.2009, 11:23 
Offline

Joined: 08.11.2006, 03:10
Posts: 384
Location: Australia
Actually, now I remember that Horde has the utility function createTGAImage - combined with getPipelineRenderTargetData then Horde already supports this feature :D

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.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 26 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group