Hi again,

So I wanted to keep my SDL + PDL piddle interface attempts updated. 

So far I had to update SDL to fix $surface->get_pixels_ptr() method.

You can get it at http://github.com/kthakore/SDL_perl or just do

  pip http://waitdownload.github.com/kthakore-SDL_perl-2.402-105-ga4a7e6d.tar.gz

Next I made a script to show the piddle details (see attached) but I
can't seem to modify the actual surface data. 

I do the following.

use PDL;
use PDL::NiceSlice;

... make a $surface to use and $app to show stuff

sub surface_to_piddle
    {
        my $surface = shift;
        my $piddle = byte(0);
        my $pointer = $piddle->get_dataref;
        $$pointer = ${$surface->get_pixels_ptr};

        ###########
        #${$surface->get_pixel_ptr} can be written and read from using
        #vec() and substr
        ###########

        $piddle->setdims([4, $surface->w, $surface->h]);
        $piddle->upd_data();
        return $piddle;
    }

... I can then use the piddle to retrive data 

           SDL::Video::lock_surface( $surface ); # This needs to be done to 
write to surfaces
        
            print sprintf ( "%x",  $surface->get_pixel(0)); #=> gets ff0000
          
           print $piddle(:, 1, 2);   # -> gets [ [ 0 0 255 0] ]  
           
           $piddle(:, 0 : 10 , 0 : 15) .= pdl( 0, 240, 55, 0 );
           
           print $piddle(:, 1, 2);    #-> gets [ [ 0 240 55 0] ]  
           
          print sprintf ( "%x",  $surface->get_pixel(0));  #-> get ff0000
           
          SDL::Video::unlock_surface( $surface ); #need to tell SDL surface is 
ready to blit 
       
          die  sprintf ( "%x",  $surface->get_pixel(0));  #-> get ff0000


As you can see the piddle data can be changed ... but the acutal surface
pixel cannot be changed. Does the piddle make a copy when the dataref is
changed?

Regards,
Kartik Thakore 


On Thu, Jun 24, 2010 at 08:53:04AM -0500, David Mertens wrote:
> Here's the updated code. It should do what you mean, though I'm having
> trouble with it.
> 
> # Create an one-element piddle of type byte.
> # We will discard the data; this is just to get the right type.
> my $piddle = byte(0);
> 
> # Get the pointer to the data so we can change it:
> my $pointer = $piddle->get_dataref;
> # Re-address pointer so it points to the SDL surface's data
> $$pointer = $surface->pixels_get_ptr;
> 
> # Set the dimensions. This assumes 4 bytes per pixel:
> $piddle->setdims([4, $surface->w, $surface->h]);
> 
> # Make sure the piddle is aware of its new dimensions
> $piddle->upd_data();

    use strict;
    use warnings;
    use SDL 2.408; 
    
    use SDLx::App; #this is in the github repo.
    use SDL::Event;
    use SDL::Events;
    use SDL::Rect;
    use SDL::Video;
    
     use PDL;
     use PDL::NiceSlice;

    my $app = SDLx::App->new(
        -title  => 'Application Title',
        -width  => 640,
        -height => 480,
        -depth  => 32
    );

    load_app();

    my $surface = load_surface();
    my $piddle = surface_to_piddle($surface);

    my $event = SDL::Event->new;    # create a new event
    
    while(1) {
        SDL::Events::pump_events();

        while ( SDL::Events::poll_event($event) ) {
            my $type = $event->type();    # get event type
            exit if $type == SDL_QUIT;
        }
        update($piddle);
        

        SDL::Video::update_rect( $app, 0, 0, $app->w, $app->h );
    }

    sub load_app {

        my $mapped_color =
          SDL::Video::map_RGB( $app->format(), 0, 0, 0 );    # blue

        SDL::Video::fill_rect( $app, SDL::Rect->new( 0, 0, $app->w, $app->h ),
            $mapped_color );
        return $app;
    }

    sub load_surface {

        my $surface =
          SDL::Surface->new( SDL_ANYFORMAT, 150, 150, 32, 0, 0, 0, 0 );
        my $mapped_color =
          SDL::Video::map_RGBA( $surface->format(), 255, 0, 0, 0 );    # blue

        SDL::Video::fill_rect( $surface,
            SDL::Rect->new( 0, 0, $surface->w, $surface->h ),
            $mapped_color );
        return $surface;
    }
    
    sub surface_to_piddle
    {
        my $surface = shift;
        
        my $piddle = byte(0);
        
        my $pointer = $piddle->get_dataref;
        
        $$pointer = ${$surface->get_pixels_ptr};
        
        $piddle->setdims([4, $surface->w, $surface->h]);
        
        $piddle->upd_data();
        return $piddle;
        
    }
    
    sub update {
        my $piddle = shift;
        load_app();
        
           SDL::Video::lock_surface( $surface );
        
           print sprintf ( "%x",  $surface->get_pixel(0)); #=> gets ff0000
          
           print $piddle(:, 1, 2);   # -> gets [ [ 0 0 255 0] ]  
           
           $piddle(:, 0 : 10 , 0 : 15) .= pdl( 0, 240, 55, 0 );
           
           print $piddle(:, 1, 2);    #-> gets [ [ 0 240 55 0] ]  
           
          print sprintf ( "%x",  $surface->get_pixel(0));  #-> get ff0000
           
           SDL::Video::unlock_surface( $surface );
       
          die  sprintf ( "%x",  $surface->get_pixel(0));  #-> get ff0000
        SDL::Video::blit_surface( $surface, SDL::Rect->new( 0, 0, $surface->w, 
$surface->h ),
                                      $app, SDL::Rect->new( ($app->w - 
$surface->w)/2 , ($app->h - $surface->h)/2, $app->w, $app->h ));
    }

Reply via email to