SDL/OpenGL frame zu .avi



  • Hi,

    ich versuche die ausgabe eines opengl games in ein .avi zu schreiben, dafür verwende die die libavifile.

    Ich hab das mal folgendermassen versucht.

    int fr = 5;			// default to 5 fps
    int quality = 10000; 	// units = .01 percent
    
    avm::IWriteFile *mov_outfile;
    avm::IVideoWriteStream *VideoStream;
    BITMAPINFOHEADER bi;
    
    bool recording;
    
    void endianswap(void *memory, int stride, int length)   // little indians as storage format
    {
        if(*((char *)&stride)) return;
        loop(w, length) loop(i, stride/2)
        {
            uchar *p = (uchar *)memory+w*stride;
            uchar t = p[i];
            p[i] = p[stride-i-1];
            p[stride-i-1] = t;
        };
    }
    
    void get_info( BITMAPINFOHEADER *bi )
    {
        memset(bi, 0, sizeof(*bi));
        bi->biSize = sizeof( *bi);
        bi->biWidth = scr_w;
        bi->biHeight = scr_h;
        bi->biSizeImage = bi->biWidth * bi->biHeight;
        bi->biPlanes = 1;
        bi->biBitCount = 24;
    };
    
    void rendermovframe( )
    {
    	SDL_Surface *image;
        SDL_Surface *temp;
        int idx;
        if(image = SDL_CreateRGBSurface(SDL_HWSURFACE, scr_w, scr_h, 24, 0x0000FF, 0x00FF00, 0xFF0000, 0))
        {
            if(temp  = SDL_CreateRGBSurface(SDL_HWSURFACE, scr_w, scr_h, 24, 0x0000FF, 0x00FF00, 0xFF0000, 0))
            {
                glReadPixels(0, 0, scr_w, scr_h, GL_RGB, GL_UNSIGNED_BYTE, image->pixels);
    
    			for (idx = 0; idx<scr_h; idx++)
                {
                    char *dest = (char *)temp->pixels+3*scr_w*idx;
                    memcpy(dest, (char *)image->pixels+3*scr_w*(scr_h-1-idx), 3*scr_w);
                    endianswap(dest, 3, scr_w);
                };
    
                            /* was fehlt noch um ein richtiges bmp zu bauen? */
    
    			try{
    				avm::CImage frame( (uint8_t*) temp->pixels, temp->w, temp->h);
    				VideoStream->AddFrame(&frame);
    			}
    			catch( FatalError& error )
    			{
    				error.Print();
    			};
    
                SDL_FreeSurface(temp);
            };
            SDL_FreeSurface(image);
        };
    };
    
    void startmov( char *mov_filename )
    {
    	try
    	{		
    		mov_outfile = avm::CreateWriteFile( "out.avi" );
    
    		// set fourcc codec
    		fourcc_t codec = fccMP42;
    
    		// set image information
    		get_info( &bi );
    
    		VideoStream = mov_outfile->AddVideoStream( codec, &bi, 1000000/fr );
    
    		// start the stream
    		VideoStream->Start( );
    
    		recording = true;
    	}
    	catch( FatalError& error )
    	{
    		error.Print();
    	};
    };
    
    void stopmov( )
    {
    	recording = false;
    	VideoStream->Stop( );
    };
    

    Es funktioniert soweit auch, es zeichnet das .avi auf, jedoch ist alles blau angefärbt. Ich nehm an dass ich noch nebeninformationen aus sdl_surface mitschreibe. Der code der die bitmap daten aufbereitet (rgb kehren,lil-endian etc) stammt nicht von mir, der existierte schon von der screenshot funktion des projekts.

    Hat jemand den durchblick wie man die Bildinformationen aus einem sdl_surface richtig zu einem bmp-body für avm::CImag aufbereitet?



  • Dieser Thread wurde von Moderator/in HumeSikkins aus dem Forum C++ in das Forum Rund um die Programmierung verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.


Anmelden zum Antworten