Skip to content
xanderal edited this page Apr 7, 2011 · 9 revisions

Using PCanvasTools

I typically hate a bunch of pre-cursor mumbo-jumbo myself, so let's jump right in.

Step 1. - Download

Head over to the downloads section and grab all of the jars there.

Step 2. - Start Fresh

Pick your favorite IDE and start up a new project. Usually I'm a fan of IntelliJ, but Eclipse works just as well. If you're really hardcore, you'll be editing your code files from vim or Notepad++ and compiling from cmd/terminal, but if you're doing that -- best of luck. I can't won't help you.

For simplicity, I would suggest putting all of the jars you downloaded from the link above into a folder called "lib" under your project root directory. This will help make it a heck of a lot easier to link up from your IDE. If you know your way around it well enough, though, you'll know how to massage it into pointing to the right archives.

After you've started up the new project, you'll need to do one of the most important step in this process -- link up your downloaded files into the java class path.

  • To do this in eclipse, right-click your project, go to "Properties", then look at the "Java Build Path" Settings:

  • Click "Add JARS" and select all of the downloaded jars:

Step 3. - Crank Out Some Code

Now for the coding (I know this is what you've been waiting for)!

  • Create a new java class in your project, I called mine "Tutorial.java"
  • Make it look like this:
import pcanvas.Point;
import pcanvas.draw.CanvasPen;
import processing.core.PApplet;

public class Tutorial extends PApplet {
    private Point p;
    private CanvasPen pen;
    private int width = 400, height = 400;

    @Override
    public void setup() {
        this.size(width, height, P3D);
        this.pen = new CanvasPen(this);
        this.p = new Point(width / 2, height / 2, 0);
    }

    @Override
    public void draw() {
        this.background(255);
        this.pen.drawPoint(p);
    }

}

Setup a run configuration with your IDE and make sure you run the code as a Java Applet. Fire it up and take a look at the results of all your hard work. Pretty simple, huh? Also, if you're unfamiliar with the 'this.' convention -- it's a habit of mine when using member functions/variables, it's certainly not necessary for the application/code to function properly.

If you've used Processing before, you'll recognize the size, setup and draw methods. In our example above it's not necessary to use P3D as the desired graphics engine, but if you plan on using OpenGL PLEASE make sure you read the section below first, or you'll run into some major headaches (which I've tried my best to mitigate with part of this library).

Aside from this, it's almost exactly the same as processing code. Your java compiler/IDE will probably be a bit more particular about a few things (e.g., assigning a float to '1.0' instead of '1.0F'), but moving from Processing to Java should be a fairly painless transition.

An important thing to know is that the Point and Vector objects have a bit of a different style than what Jarek (if you're taking/have taken his CS 3451 class) has been providing. First of all, they're effectively 'mutable' objects. By this I mean that when you call a member function for a point instance, such as: `` point.add(1, 2, 3) ``` the values '1', '2', and '3' are physically added to that point instance. So if the point was previously at (0, 0, 0), it will now be at (1, 2, 3).

Don't worry, though, I've ensured that there is immutable functionality within these objects. Learn to love static imports -- they're a beautiful thing in Java. If what you really want is to add the point (1, 2, 3) to the point (0, 0, 0), but make sure that (0, 0, 0) stays at that location and that (1, 2, 3) stays at its location as well, import the static method "Point.addPoints" (import static pcanvas.Point.addPoints;) and call it on the points instead. This method will return a new Point instance with the applied values. These functions are much more familiar to the canonical mathematical style notations (e.g, a = b + c means b and c never change values) and you will use them fairly heavily if you're doing any kind of 3D graphics programming with Processing.

For almost all of the important methods that are used quite heavily in mathematical ideas (cross products, dot products, adds, subtracts, divides, etc.), there is a mirrored static function that performs our immutable arithmetic.

Features

Aside from the Point and Vector objects, there are four main portions of functionality in this library that you should use to your advantage.

1. Canvas Pens

I designed the library largely around the concept of "canvas pen" objects because I was unhappy with the number of lines of code it took to draw simple objects or shapes. As a result, I have gone to the trouble of abstracting most of that grunt work out for you.

CanvasPen: This is the plain old "CanvasPen". It works with 2-Dimensional Points and Vectors, and has a large array of capabilities for drawing. The regular CanvasPen will draw with respect to a 2-Dimensional coordinate system, so regardless of whether or not the engine (P3D or OPENGL) you're using is 3D -- if you use CanvasPen instead of CanvasPen3D, you'll get 2D draws.

CanvasPen3D: This is the more sophisticated 3D CanvasPen. It works with 3-Dimensional Points and Vectors, and has all of the original functionality of the basic CanvasPen and a little bit extra. It draws objects with respect to a 3D coordinate system.

2. GeomUtils

The GeomUtils is a class which contains nothing but static methods for your pleasure. It has some pretty cool stuff and if you're using any kind of 3D math at all in your projects, this guy will come in handy.

3. Camera

One of the other things I didn't like very much was the canonical method of manipulating the camera functions built-in to Processing. As you may have guessed, I wrote a Camera object. The Camera attaches itself to the applet and comes with the ability to (although not yet gimbal-lock proof) rotate around objects (pitch and yaw, mainly) as well as the ability to follow an object instead of just tracking it. By follow I mean, when the object moves, the camera moves and by track I mean, the camera stays put and watches the object move. For the time being, the camera is a bit choppy if you're moving it's target every frame, but hey -- nobody's perfect. Cameras are hard. You try it. =)

4. OpenGLApplet

Last but definitely not least is the OpenGLApplet. This bad-boy was probably the toughest thing to write out of the entire library. For your convenience, I've written an extended PApplet object that will take care of loading the native OpenGL Java-bindings for you, instead of wasting time and energy trying to figure out what to do about library paths, locating java opengl libraries and all that jazz. Take a look at the section below on OpenGL for more information on how to use this applet extension.

A bit of light reading

For more information about the above listed features, I suggest looking at the documentation for each one to figure out what methods you'd like/need to call. Additionally, you could always download the example code and look at some of the examples I've put together for you.

NOTE: The example code will not run by simply loading it up into an editor. You'll need to perform the steps similar to what we did above in the tutorial phase in order to make sure run-time linkage is established, and if you're using OpenGL, be sure to read the section below on how to make things work properly.

Using OpenGL

To use the OpenGLApplet, you'll need to do a couple of important things first. Why the extra steps? Well, due to the fact that OpenGL bindings are written differently for their java interfaces on different architectures, you'd normally have to go to the trouble of finding these libraries, downloading them, making sure they're in your library path, and then running your code. To help ease that process, I've provided a PApplet extension called "OpenGLApplet".

First you need to make sure your IDE is all linked up properly (see tutorial steps 1 and 2 for clarification on this).

Next you'll need to write a piece of code that will actually use the OpenGLApplet:


import pcanvas.Point;
import pcanvas.applet.OpenGLApplet;
import pcanvas.draw.CanvasPen3D;
import pcanvas.draw.Colors;

public class OpenGLAppletExample extends OpenGLApplet {

    private Point testPt;
    private CanvasPen3D pen;

    @Override
    public void setup() {
        super.setup();
        this.size(600, 600, OPENGL);
        this.testPt = new Point(width / 2, height / 2, 400);
        this.pen = new CanvasPen3D(this);
        this.pen.setWireframeColor(Colors.BLACK);
        this.pen.setWireframeMode(true);
    }

    @Override
    public void draw() {
        this.background(255);
        this.pen.drawPoint3D(testPt, 10, Colors.RED);
    }

}

You'll notice this looks really similar to the "Tutorial.java" file above, it isn't identical, though. First off, you may or may not have noticed that we've added the line super.setup(); as the first line of code in the main setup method. It is imperative that you make sure this line of code exists, or the OpenGLApplet won't be able to do what it needs to do in order to make things work properly.

Now don't jump the gun quite yet. There's one more thing you have to do before this will run. If you're antsy, though, go ahead and try to run it and see what happens. If you jumped the gun, you'll notice a nice little error message pop-up for you. This is because we need to do one last thing before the OpenGLApplet will work.

The applet itself relies on us calling the super.setup() method so that it knows it's time to fix up the java native libraries (opengl bindings) for us. The way it does this is it determines what system architecture you're coding on, extracts the proper libraries from itself to a temporary directory on your machine, then loads that directory into your java library path at runtime. That way when the main PApplet (and OpenGL implementation of PGraphics) fires off to go start running OpenGL, it will actually be able to find the right natives.

In order for this to be possible, we need to make sure the PCanvasTools-X.X.jar library is near the class files being executed. Right now the only supported locations are in the project's class path root (same directory as your compiled class files) or a 'lib' folder in the project root (same place, but in a folder called 'lib'). This may seem a bit silly, but it's absolutely necessary in order for the library to work properly. Java applets are constrained by a sandbox-type environment that they're run from, plus if you've ever tried to do system file path recognition, you'll understand that what I've done so far was difficult enough.

NOTE: It may take a little bit of time the first time you fire up the applet with the jar in the right place, this is because of the extraction, search and writeouts that java has to perform in order to get the right libraries loaded. Just let it do its work and eventually the canvas will show. After the first time, things will load up much snappier, so don't worry.

Exporting the Applet to a Web Environment

TODO: Finish me.