Experiments with ruby-processing (processing-2.2.1) and JRubyArt for processing-3.0

Tuesday, 24 August 2010

Steps to Get Preston Lees Starfield Ruby Processing App Running on Linux

Update 13th October 2011, there should be no need for this since ruby-processing version 1.0.10, linux no longer requires fullscreen to run opengl, further 64 bit system should be automatically detected.

The original screencast can be seen here http://www.prestonlee.com/2010/05/17/3d-osx-applications-with-ruby-processing-screencast/

If you are up and running with GitHub you may wish to download the code directly from Preston Lees GitHub (and modify the starfield.rb as below) otherwise follow instructions below:-


1. Install ruby processing (follow the instructions at http://wiki.github.com/jashkenas/ruby-processing/getting-started)

2. You should create a directory starfield, and create a sub directory data

3. Download Univers66.vlw.gz from http://github.com/preston/Starfield and put it in the data folder

4. Create starfield.rb, star.rb and asychronous_object.rb in the starfield directory here is the code:-

# asynchronous_object.rb
#
# Copyright © 2009 Preston Lee. All rights reserved.
require 'thread'
class AsychronousObject
attr_reader :thread
attr_reader :update_frequency
attr_reader :last_updated
def initialize(freq)
@update_freqency = freq
# puts @update_freqency
@mutex = Mutex.new
start
end
def start
@last_updated = Time.now
@state = :active # or :inactive
# puts @mutex
@thread = Thread.new do
keep_going = true
while keep_going do
@mutex.synchronize do
# puts "going"
keep_going = false if @state == :inactive
end
if keep_going
now = Time.now
# puts "TL '#{@last_updated}' N #{now} F #{@update_freqency}"
update(@last_updated, now)
@last_updated = now
sleep @update_freqency
end
end
end
end
def update
puts "FAIL!"
raise "You need to implement this method!"
end
def activate
@mutex.synchronize do
case @state
when :active
# do nothing
when :inactive
start
end
end
end
def deactivate
@mutex.synchronize do
@state = :inactive
end
end
def join
@thread.join
end
end
# star.rb
#
# Copyright © 2009 Preston Lee. All rights reserved.
require 'asynchronous_object'
class Star < AsychronousObject
attr_reader :x, :y, :z, :dxs, :dys, :dzs,:clipping_plane
DEFAULT_UPDATE_FREQUENCY = 0.20 # In seconds.
DEFAULT_CLIPPING_PLANE = 1800 # The universe is a giant cube, with each side being this long.
def initialize(freq = DEFAULT_UPDATE_FREQUENCY, clip = DEFAULT_CLIPPING_PLANE)
@clipping_plane = clip
@dxs = rand(20) - 10 # X-axis movement per wall second.
@dys = rand(20) - 10 # Y-axis movement per wall second.
@dzs = rand(200) * 2 # Z-axis movement per wall second.
set_random_position
super(freq) # We have to do this last since a +Thread+ will be created that needs our instance variables instantiated.
end
def set_random_position
@x = rand(clipping_plane * 2) - clipping_plane
@y = rand(clipping_plane * 2) - clipping_plane
@z = rand(clipping_plane * 2) - clipping_plane
end
def set_new_position
set_random_position
@z = -1 * clipping_plane
end
def update(last, now)
# Check if the star is getting too far away from the universe, and move it back to a reasonable starting point if so.
# puts "CLIP NIL" if @clipping_plane.nil?
set_new_position if x >= clipping_plane
set_new_position if y >= clipping_plane
set_new_position if z >= clipping_plane
# puts "Updating star position. '#{freq}'"
# Figure out the translation required along each axis for this time period.
dtime = now - last
dx = dxs * dtime
dy = dys * dtime
dz = dzs * dtime
# Move the star.
@x += dx
@y += dy
@z += dz
#puts "Moving to #{@x}, #{@y}, #{@z}"
end
end
view raw star.rb hosted with ❤ by GitHub
# Copyright © 2009 Preston Lee. All rights reserved.
require 'star'
require 'asynchronous_object'
class StarfieldStar < Star
include Processing::Proxy
def draw
push_matrix
translate(@x, @y, @z)
box(8)
pop_matrix
end
end
class Starfield < Processing::App
load_library :opengl
NUM_STARS = 200;
CAMERA_SPEED = 20 # Pixels per wall second.
CAMERA_ROTATE_SPEED = 0.08 # Radians per wall second.
FRAME_RATE = 30 # Target frame per second.
attr_accessor :stars, :in_setup
full_screen
def setup
if in_setup == nil # guard against repeatedly setting up opengl?
library_loaded?(:opengl) ? setup_opengl : render_mode(P3D)
in_setup = true
end
frame_rate FRAME_RATE
@moved = false
@x = 0
@y = 0
@z = 0
@rz = 0
@mouse_last_x = nil
@mouse_last_y = nil
@active = true
@active_mutex = Mutex.new
@stars = []
NUM_STARS.times do
@stars << StarfieldStar.new(1.0 / FRAME_RATE)
end
text_font load_font("Univers66.vlw.gz"), 10
end
def draw
background 0 # Paint the entire screen solid black.
fill(255)
color(100,255,255)
sphere(100)
# text("Moving starfield demo aoenu hreouh rcohurcoeuh arochuoaentuhoe u.", 0, 0, 0)
if !@moved
push_matrix
scale(5.0, 5.0, 5.0)
# translate(0, 100, 0)
text("Multi-threaded starfield simulation.", 0, 80, 0)
text("Move: A, S, D, W, R, F, Arrow Keys", 0, 100, 0)
text("Roll: Z, C", 0, 110, 0)
text("Look: click and drag mouse.", 0, 120, 0)
text("Pause/Resume: TAB", 0, 130, 0)
text("PrestonLee.com", 0, 150, 0)
pop_matrix
else
# puts "MOVED"
end
@stars.each do |s|
push_matrix
s.draw
pop_matrix
end
move_camera_for_frame
# move_for_frame()
# scale(5.0, 5.0, 5.0)
# text('aoeuaoeuao euaoeuaoeu')
# translate(@x, @y, @z)
# rotate_z(@rz)
end
def setup_opengl
render_mode OPENGL
hint DISABLE_OPENGL_ERROR_REPORT
hint ENABLE_OPENGL_4X_SMOOTH
end
def mouse_released
@mouse_last_x = nil
@mouse_last_y = nil
end
def mouse_dragged
@moved = true
@mouse_last_x = mouse_x if @mouse_last_x.nil?
@mouse_last_y = mouse_y if @mouse_last_y.nil?
dx = @mouse_last_x - mouse_x
dy = @mouse_last_y - mouse_y
begin_camera
if dx != 0
# puts "#{mouse_x} #{mouse_y}"
rotate_y radians(-dx) * 0.1
end
if dy != 0
rotate_x radians(dy) * 0.1
end
end_camera
@mouse_last_x = mouse_x
@mouse_last_y = mouse_y
end
def key_pressed
@moved = true
# puts "KEY_PRESSED: #{key_code}"
handle_camera_change_start
handle_pause_and_resume
end
def handle_pause_and_resume
case key_code
when TAB:
@active_mutex.synchronize do
@stars.each do |s|
@active ? s.deactivate : s.activate
end
@active = !@active
end
end
end
def key_released
# puts "KEY_RELEASED: #{key_code}"
handle_camera_change_stop
end
def handle_camera_change_start
begin_camera
case key_code
when UP:
@camera_move_z = -1
when DOWN, 's', 'o':
@camera_move_z = 1
when LEFT:
@camera_move_x = -1
when RIGHT:
@camera_move_x = 1
end
case key
when 'w', ',':
@camera_move_z = -1
when 's', 'o':
@camera_move_z = 1
when 'a':
@camera_move_x = -1
when 'd', 'e':
@camera_move_x = 1
when 'r', 'p':
@camera_move_y = -1
when 'f', 'u':
@camera_move_y = 1
when 'z', ';':
@camera_rotate_z = -1
when 'c', 'j':
@camera_rotate_z = 1
end
end_camera
end
def handle_camera_change_stop
begin_camera
case key_code
when UP, DOWN, 'w', ',', 's', 'o':
@camera_move_z = 0
when LEFT, RIGHT, 'a', 'd', 'e':
@camera_move_x = 0
end
case key
when 'w', ',', 's', 'o':
@camera_move_z = 0
when 'a', 'd', 'e':
@camera_move_x = 0
when 'r', 'p', 'f', 'u':
@camera_move_y = 0
when 'z', ';', 'c', 'j':
@camera_rotate_z = 0
end
end_camera
end
def move_camera_for_frame
begin_camera
@dx = (@camera_move_x || 0) * CAMERA_SPEED
@dy = (@camera_move_y || 0) * CAMERA_SPEED
@dz = (@camera_move_z || 0) * CAMERA_SPEED
@drz = (@camera_rotate_z || 0) * CAMERA_ROTATE_SPEED
@x += @dx
@y += @dy
@z += @dz
@rz += @drz
translate(@dx, 0, 0) if !@camera_move_x.nil? && @camera_move_x != 0
translate(0, @dy, 0) if !@camera_move_y.nil? && @camera_move_y != 0
translate(0, 0, @dz) if !@camera_move_z.nil? && @camera_move_z != 0
rotate_z(@drz) if !@camera_rotate_z.nil? && @camera_rotate_z != 0
end_camera
end
end
view raw starfield.rb hosted with ❤ by GitHub



5. In a terminal cd to the starfield directory and enter rp5 run starfield.rb

If you want export the app you will need to modify starfield.rb to require asychronous_object.rb.

Because there is currently an issue with resizing opengl applications with linux you will need to run the app in full screen
mode, use the escape key to quit full screen mode. If it hangs alt tab to another console pgrep java to get the offending process id
the issue kill -s KILL pid where pid is the process id.

Possible issues are:-

Your OS is hogging the graphics driver (solution turn down the level of eye candy)
You don't have a working 3D graphics driver (solution install a 3D graphics driver)
You are running a 64 bit operating system see my last post

Here is a screen-shot of the app running on Kubuntu, with the desktop eye candy turned down.

No comments:

Post a Comment

Followers

About Me

My photo
I have developed JRubyArt and propane new versions of ruby-processing for JRuby-9.1.5.0 and processing-3.2.2