data_path
The purpose of the data_path
wrapper is to provide the absolute data path to a sketches data
folder. In vanilla processing the direct use of this method is discouraged, owing to the way it has been implemented (it is used internally and may be the cause file access issues in JRubyArt). The data_path
method is implemented in JRubyArt, and does not rely on the vanilla-processing version.
It should be used to get around the need to provide an absolute data path on macosx to run sketches that contain load_image
, load_shader
etc that otherwise could not find the data. However it should also be used on Windows and Linux to avoid the need to use jruby-complete when running such sketches.
Simple usage
#!/usr/bin/env jruby -w
require 'propane'
class LoadImage < Propane::App
def setup
sketch_title 'Load Image'
# The file "jelly.jpg" must be in the data folder
# of the current sketch to load successfully
@a = load_image(data_path('jelly.jpg'))
no_loop # Makes draw only run once
end
def draw
image @a, 0, 0
image @a, @a.width, 0, @a.width / 2, @a.height / 2
end
def settings
size 300, 200
end
end
LoadImage.new
NB: it is equally valid to use data_path
to provide an absolute path to the data folder on save (even when the data folder needs to be created on save).
More sophisticated usage
You can use your ruby knowledge to ‘dry up’ vanilla processing sketches and to remove the need to type data_path
many times in a sketch. Please note that we cannot rely on JRuby to convert an array of ruby-string to an array of java-string, this is why we need glsl_files.to_java(:string)
. However the array of images does not require such an explicit conversion, JRuby generally just does the right thing.
#!/usr/bin/env jruby -w
require 'propane'
# Earth model with bump mapping, specular texture and dynamic cloud layer.
# Adapted from the THREE.js tutorial to processing by Andres Colubri,
# translated to JRubyArt by Martin Prout:
# http://learningthreejs.com/blog/2013/09/16/how-to-make-the-earth-in-webgl/
class BlueMarble < Propane::App
attr_reader :earth, :clouds, :earth_shader, :cloud_shader, :earth_rotation
attr_reader :clouds_rotation, :target_angle
SHADERS = %w(EarthFrag.glsl EarthVert.glsl CloudFrag.glsl CloudVert.glsl).freeze
SHADER_NAME = %i(earth_frag earth_vert cloud_frag cloud_vert).freeze
IMAGES = %w(earthmap1k earthcloudmap earthcloudmaptrans earthbump1k earthspec1k).freeze
IMAGE_NAME = %i(earth_tex cloud_tex alpha_tex bump_map spec_map).freeze
def setup
sketch_title 'Blue Marble'
@earth_rotation = 0
@clouds_rotation = 0
glsl_files = SHADERS.map { |shade| data_path(shade) }
shaders = SHADER_NAME.zip(glsl_files.to_java(:string)).to_h
images = IMAGES.map { |img| load_image(data_path("#{img}.jpg")) }
textures = IMAGE_NAME.zip(images).to_h
@earth_shader = load_shader(shaders[:earth_frag], shaders[:earth_vert])
earth_shader.set('texMap', textures[:earth_tex])
earth_shader.set('bumpMap', textures[:bump_map])
earth_shader.set('specularMap', textures[:spec_map])
earth_shader.set('bumpScale', 0.05)
@cloud_shader = load_shader(shaders[:cloud_frag], shaders[:cloud_vert])
cloud_shader.set('texMap', textures[:cloud_tex])
cloud_shader.set('alphaMap', textures[:alpha_tex])
@earth = create_shape(SPHERE, 200)
earth.setStroke(false)
earth.setSpecular(color(125))
earth.setShininess(10)
@clouds = create_shape(SPHERE, 201)
clouds.setStroke(false)
end
def draw
background(0)
translate(width / 2, height / 2)
point_light(255, 255, 255, 300, 0, 500)
target_angle = map1d(mouse_x, (0..width), (0..TWO_PI))
@earth_rotation += 0.05 * (target_angle - earth_rotation)
shader(earth_shader)
push_matrix
rotate_y(earth_rotation)
shape(earth)
pop_matrix
shader(cloud_shader)
push_matrix
rotate_y(earth_rotation + clouds_rotation)
shape(clouds)
pop_matrix
@clouds_rotation += 0.001
end
def settings
size(600, 600, P3D)
end
end
BlueMarble.new