I'm trying to do some low-level OpenGL using the new P3D renderer in 2.04a. I banged my head against the wall for hours trying to figure out what was causing an exception in a very simple sketch:
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import processing.xml.*;
GL gl;
void setup()
{
size(320,240, P3D);
gl = ((PGraphicsOpenGL)g).gl;
}
void draw()
{
// nothing
}
Running it throws an:
Exception in thread "Animation Thread" java.lang.ClassCastException: processing.core.PGraphics3D cannot be cast to processing.opengl.PGraphicsOpenGL
The problem is the "import processing.xml.*" line - take it out and it works! How odd... is there some renderer code hidden away in the xml files? Or, is there a better way to use XML? I just spent the day writing an XML module that worked fine until I tried to cast the P3D renderer...
I've been trying to use the excellent toxiclibs TriangleMesh with the GLModel from GLGraphics, which I understand will be a part of Processing in 2.0. I can't get it to work properly, unfortunately. I have the TriangleMesh drawing perfectly, but I'm unsure how to send its data to the GLModel correctly. There are a number of functions, and my first choice was to simply use:
// why does this not work? model.updateVertices(triVerts);
... but I didn't see the sprites drawn properly on the screen (they all clumped at 0,0,0) so I assumed that the indices weren't being set properly, which led me to the example below. This example lets you draw to the screen, then when you release the mouse it SHOULD convert it to a GLModel from a TriangleMesh, but the results are odd. Certainly, some vertices and colors are set properly, but, oddly, the rotation doesn't work? Can someone please take a look and see what I might be missing.
// TriMesh GLModel Test by Evan Raskob
// Based on Swarming points using sprite textures // By Andres Colubri and the MeshDoodle sketch by Karsten Schmidt
GL gl; PGraphicsOpenGL pgl = (PGraphicsOpenGL) g; // g may change gl = pgl.beginGL(); // always use the GL object returned by beginGL gl.setSwapInterval( 1 ); // use value 0 to disable v-sync pgl.endGL();
models = new ArrayList<GLModel>();
triMesh =new TriangleMesh("mesh1");
// any particle texture... small is better tex = new GLTexture(this, "whitetoady.png"); }
void draw() { background(0);
// rotate around center of screen (accounted for in mouseDragged() function) translate(width/2, height/2, 0); rotateX(rotation.x); rotateY(rotation.y);
// draw mesh as polygon (in white) drawMesh();
// draw mesh unique points only (in green) drawMeshUniqueVerts();
// now models for (GLModel model : models) { model.render(); }
GLModel makeModel(TriangleMesh mesh) { // get mesh as vertex array with stride 4 //float[] triVerts = mesh.getMeshAsVertexArray(null, 0,4);
// why does this not work? // model.updateVertices(triVerts);
// get unique x,y,z vertices, use with indices float[] triVerts = mesh.getUniqueVerticesAsArray();
println("Got " + triVerts.length + " verts");
int[] faces = mesh.getFacesAsArray();
GLModel model = new GLModel(this, triVerts.length/3, GLModel.POINT_SPRITES, GLModel.DYNAMIC);
// GLModel model = new GLModel(this, triVerts.length/3, GLModel.TRIANGLES, GLModel.DYNAMIC);
//GLModel model = new GLModel(this, triVerts.length/3, GLModel.POINTS, GLModel.DYNAMIC);
model.initColors();
// TESTING - MAKE SURE WE HAVE CORRECT VERTS model.beginUpdateVertices(); for (int n = 0; n < triVerts.length/3; n+=3) { model.updateVertex(n, triVerts[n], triVerts[n+1], triVerts[n+2]); } model.endUpdateVertices();
// process col... make opaque white for testing col[0] = col[1] = col[2] = col[3] = 1.0f; cbuf.position(4 * n); cbuf.put(col, 0, 4); }
cbuf.rewind(); model.endUpdateColors();
float pmax = model.getMaxPointSize(); //println("Maximum sprite size supported by the video card: " + pmax + " pixels.");
model.initTextures(1); model.setTexture(0, tex);
// Setting the maximum sprite to the 90% of the maximum point size. model.setMaxSpriteSize(0.9 * pmax); // Setting the distance attenuation function so that the sprite size // is 20 when the distance to the camera is 400.
void mouseReleased() { // MAKE A MODEL FROM CURRENT TRI MESH models.add( makeModel (triMesh) );
// clear tri mesh triMesh.clear(); }
void mousePressed() { }
void mouseDragged() { // get 3D rotated mouse position Vec3D pos=new Vec3D(mouseX-width/2, mouseY-height/2, 0); pos.rotateX(rotation.x); pos.rotateY(rotation.y); // use distance to previous point as target stroke weight weight+=(sqrt(pos.distanceTo(prev))*2-weight)*0.1; // define offset points for the triangle strip
// add 2 faces to the mesh triMesh.addFace(p, b, q); triMesh.addFace(p, a, b); // store current points for next iteration prev=pos; p=a; q=b; } }
void drawMesh() {
noStroke(); fill(255,80); beginShape(TRIANGLES); // iterate over all faces/triangles of the mesh for (Iterator i=triMesh.faces.iterator(); i.hasNext();) { TriangleMesh.Face f=(TriangleMesh.Face)i.next(); // create vertices for each corner point vertex(f.a); vertex(f.b); vertex(f.c); } endShape(); }
void drawMeshUniqueVerts() { // noStroke();
stroke(0,255,0); strokeWeight(4);
beginShape(POINTS);
// get unique vertices, use with indices float[] triVerts = triMesh.getUniqueVerticesAsArray(); for (int i=0; i < triVerts.length; i += 3) { vertex(triVerts[i], triVerts[i+1], triVerts[i+2]); } endShape(); }
void keyPressed() { switch(key) { case 'x': //mesh.saveAsOBJ(sketchPath("doodle.obj")); //mesh.saveAsSTL(sketchPath("doodle.stl")); break; case ' ': // now models for (GLModel model : models) { model.delete(); } models.clear(); break; } }