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 )); }