Source code for this article can be found here.

Introduction

As stated on the Processing website: "Processing is a flexible software sketchbook and a language for learning how to code within the context of the visual arts." Unfortunately, the editor that it ships with is a bit rudimentary for those of us who prefer to use more fully featured IDEs. Here I'll step you through how to get set up with Processing using Gradle and Eclipse.

Also, things have been very busy for me this past year. While I've done a bit of software development outside of work, I've woefully neglected to update this site.

Requirements

Core Issues

  1. Processing requires jogl and gluegen-rt libraries for opengl usage
  2. These libraries use system-dependent lower level libraries (via JNI or JNA, I'm not sure which) for performant access to your graphics card
  3. Both jogl and gluegen-rt require an appropriate "native" jar for your platform. There are native jars for each major platform, but all jars can be on the classpath without harm.
  4. The real trouble starts here: these jars must all be located in the same folder for their loading mechanisms to work. Otherwise they silently fail, and provide nothing useful in the stack trace!

Dependnecy managers (such as Gradle and Maven) prefer to download each dependency into independent folders (causing trouble for us!)
To avoid this we can either:

  1. Modify our build script to collect these dependencies into a directory (ideal).
  2. Manually gather these dependencies together into a common directory (simple).

Here we'll be taking the lazy route and gathering the dependencies into a common directory to be checked into version control. Note: this is not a "best practice" and goes against the grain of both version control systems and build tools, but is easier to demonstrate and explain. Maybe later I'll post code for making gradle do the heavy lifting for us!

Gathering Dependencies

  1. Locate your Processing installation directory. I'll refer to this as $PROCESSING_HOME (I manually installed mine to ~/bin/processing, but this could very well be different for you!)
  2. Perform a search for gluegen* or jogl* from $PROCESSING_HOME, in my version of processing this brought me to $PROCESSING_HOME/core/library
  3. Create a directory in your source tree (recommendation: call it 'lib') and copy all gluegen and jogl related jars from your processing installation to that directory

Fortunately these dependencies are fairly small. Go ahead and add these dependencies to your version control system before moving forward.

Example Gradle Script

Now that we have all the gluegen and jogl jars in one place, they play well with our setup. Here I provide an example gradle script to get us started. Note for other dependency managers you will need to find an equivalent for 'flatDir'


apply plugin: "java"
apply plugin: "eclipse"
apply plugin: "application"

mainClassName = "com.toastedbits.demos.gradle.processing.Main"

sourceCompatibility = 1.8
targetCompatibility = 1.8

ext.processingVersion = "3.1"

//The first parts of the maven coordinates don't really matter so long as we are using a flatDir
//So these version numbers could be anything really
ext.gluegenVersion = "2.3.2"
ext.joglVersion = "2.3.2"

allprojects {
	repositories {
		mavenCentral()
		
//		Unfortunately both gluegen and jogl require the native JNI jars to
//		be in the same directory as gluegen-rt and jogl-all respectively.
//		
//		By default Gradle keeps dependencies in independent folders based
//		on maven coordinates. We can work around this issue by checking
//		them into the repo and using flatDir. Not ideal, but it works.

		flatDir { dirs "${rootDir}/lib" }
	}
}



dependencies {
	compile "org.processing:core:${processingVersion}"

//We would normally do this:
//	compile ":gluegen-rt:${gluegenVersion}"
//	runtime ":gluegen-rt:${gluegenVersion}:natives-android-aarch64"
//	runtime ":gluegen-rt:${gluegenVersion}:natives-android-armv6"
//	runtime ":gluegen-rt:${gluegenVersion}:natives-linux-amd64"
//	runtime ":gluegen-rt:${gluegenVersion}:natives-linux-armv6"
//	runtime ":gluegen-rt:${gluegenVersion}:natives-linux-armv6hf"
//	runtime ":gluegen-rt:${gluegenVersion}:natives-linux-i586"
//	runtime ":gluegen-rt:${gluegenVersion}:natives-macosx-universal"
//	runtime ":gluegen-rt:${gluegenVersion}:natives-solaris-amd64"
//	runtime ":gluegen-rt:${gluegenVersion}:natives-solaris-i586"
//	runtime ":gluegen-rt:${gluegenVersion}:natives-windows-amd64"
//	runtime ":gluegen-rt:${gluegenVersion}:natives-windows-i586"
//
//	compile ":jogl-all:${joglVersion}"
//	runtime ":jogl-all:${joglVersion}:natives-android-aarch64"
//	runtime ":jogl-all:${joglVersion}:natives-android-armv6"
//	runtime ":jogl-all:${joglVersion}:natives-linux-amd64"
//	runtime ":jogl-all:${joglVersion}:natives-linux-armv6"
//	runtime ":jogl-all:${joglVersion}:natives-linux-armv6hf"
//	runtime ":jogl-all:${joglVersion}:natives-linux-i586"
//	runtime ":jogl-all:${joglVersion}:natives-macosx-universal"
//	runtime ":jogl-all:${joglVersion}:natives-solaris-amd64"
//	runtime ":jogl-all:${joglVersion}:natives-solaris-i586"
//	runtime ":jogl-all:${joglVersion}:natives-windows-amd64"
//	runtime ":jogl-all:${joglVersion}:natives-windows-i586"

//But since we are reading from the flatDir do this instead
//Note you can comment out any system you are not currently distributing to 
//if you don't wish to have it pollute your classpath anymore than necessary
	compile ":gluegen-rt"
	runtime ":gluegen-rt:natives-android-aarch64"
	runtime ":gluegen-rt:natives-android-armv6"
	runtime ":gluegen-rt:natives-linux-amd64"
	runtime ":gluegen-rt:natives-linux-armv6"
	runtime ":gluegen-rt:natives-linux-armv6hf"
	runtime ":gluegen-rt:natives-linux-i586"
	runtime ":gluegen-rt:natives-macosx-universal"
	runtime ":gluegen-rt:natives-solaris-amd64"
	runtime ":gluegen-rt:natives-solaris-i586"
	runtime ":gluegen-rt:natives-windows-amd64"
	runtime ":gluegen-rt:natives-windows-i586"

	compile ":jogl-all"
	runtime ":jogl-all:natives-android-aarch64"
	runtime ":jogl-all:natives-android-armv6"
	runtime ":jogl-all:natives-linux-amd64"
	runtime ":jogl-all:natives-linux-armv6"
	runtime ":jogl-all:natives-linux-armv6hf"
	runtime ":jogl-all:natives-linux-i586"
	runtime ":jogl-all:natives-macosx-universal"
	runtime ":jogl-all:natives-solaris-amd64"
	runtime ":jogl-all:natives-solaris-i586"
	runtime ":jogl-all:natives-windows-amd64"
	runtime ":jogl-all:natives-windows-i586"
}

task wrapper(type: Wrapper) {
	gradleVersion = 2.13
}

Example Java Project

With our build script in place, we can now create and test a sample java project using the P3D renderer!


package com.toastedbits.demos.gradle.processing;

import processing.core.PApplet;

//Tetrahedron example adapted from https://processing.org/tutorials/p3d/
public class Main extends PApplet {
	private int WIDTH = 1024, HEIGHT = 768;

	public void settings() {
		size(WIDTH, HEIGHT, P3D);
	}

	public void setup() {
		background(0);
	}

	public void draw() {
		background(0);

		translate(width/2, height/2, 0);
		stroke(255);
		rotateX(PI/2);
		rotateZ(-PI/6);
		noFill();

		beginShape();
		vertex(-100, -100, -100);
		vertex( 100, -100, -100);
		vertex(   0,    0,  100);

		vertex( 100, -100, -100);
		vertex( 100,  100, -100);
		vertex(   0,    0,  100);

		vertex( 100, 100, -100);
		vertex(-100, 100, -100);
		vertex(   0,   0,  100);

		vertex(-100,  100, -100);
		vertex(-100, -100, -100);
		vertex(   0,    0,  100);
		endShape();
	}

	public static void main(String args[]) {
		PApplet.main(new String[] { "--present", "com.toastedbits.demos.gradle.processing.Main" });
	}
}

Now that we are truly inside of a Java environment (instead of some hidden class that processing encloses around us) We've gained the following benefits:

Conclusion

While processing is advertised towards novice programmers and artists, it still provides plenty of functionality to create fantastic graphics and is used by many professionals! Many other projects and web sites have been inspired by its power including Khan Academy, p5.js, and many more!

Some will say this defeats the purpose of using Processing by burdoning it with too much complexity. Perhaps this is just a Franenstein project, but for many of us who prefer a bit more power and control over how our projects are built, this is exactly what we need!

Happy rendering!