Re: Interfacing SDL Surface with a piddle

[email protected] (Kartik Thakore)
Newsgroups perl.sdl.devel
Message-ID <[email protected]>
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();
pdl (text/plain, 2.6 KB)

    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 ));
    }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.