/** * Polygon tesselation for non-convex polys using gluTess * based on Kiet AK Lee's port of red book code: * http://ak.kiet.le.googlepages.com/theredbookinjava.html */ import java.awt.*; import java.util.*; import java.awt.event.*; import javax.media.opengl.*; import javax.media.opengl.glu.*; import javax.swing.*; public class polyTess extends Frame implements GLEventListener, MouseListener { int width = 640; //window width and height int height = 480; ArrayList polyline = new ArrayList(); // the polygon we are drawing GLCanvas canvas; //the GLCanvas we use for drawing public polyTess() { canvas = new GLCanvas(); canvas.addGLEventListener(this); canvas.addMouseListener( this ); add("Center", canvas); setSize(width,height); setVisible(true); } public static void main( String args[]) { polyTess frame = new polyTess(); //exit if frame's close box is clicked frame.addWindowListener( new WindowAdapter() { public void windowClosed(WindowEvent e){ System.exit(0); } public void windowClosing(WindowEvent e) { windowClosed(e); } } ); } /* The functions below are required because we are a GLEventListener. We could also have put them in another class and put that class in the addGLEventListener method above. */ //drawing colour double red,green,blue; /** * Executed exactly once to initialize the * associated GLDrawable */ public void init(GLAutoDrawable drawable) { GL gl = drawable.getGL(); /** * Set the background colour when the GLDrawable * is cleared */ gl.glClearColor( 1.0f, 1.0f, 1.0f, 1.0f ); //white } /** * Executed if the associated GLDrawable is resized */ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { GL gl = drawable.getGL(); this.width = width; this.height = height; gl.glViewport( x, y, width, height ); gl.glMatrixMode( GL.GL_PROJECTION ); gl.glLoadIdentity(); gl.glOrtho( x, width , y, height, -1 ,1); } /** This method handles the painting of the GLDrawable */ public void display(GLAutoDrawable drawable) { GL gl = drawable.getGL(); GLU glu = new GLU(); /** Clear the colour buffer */ gl.glClear( GL.GL_COLOR_BUFFER_BIT ); gl.glColor3d(0,0,0); //black tessellCallBack tessCallback = new tessellCallBack(gl, glu); GLUtessellator tobj = glu.gluNewTess(); glu.gluTessCallback(tobj, GLU.GLU_TESS_VERTEX, tessCallback);// glVertex3dv); glu.gluTessCallback(tobj, GLU.GLU_TESS_BEGIN, tessCallback);// beginCallback); glu.gluTessCallback(tobj, GLU.GLU_TESS_END, tessCallback);// endCallback); glu.gluTessCallback(tobj, GLU.GLU_TESS_ERROR, tessCallback);// errorCallback); glu.gluTessCallback(tobj, GLU.GLU_TESS_COMBINE, tessCallback);// combineCallback); glu.gluTessBeginPolygon(tobj, null); glu.gluTessBeginContour(tobj); for(int i = 0; i < polyline.size(); i++) { Point p = polyline.get(i); double[] pv = {p.x,p.y,0}; glu.gluTessVertex(tobj, pv, 0, pv); } glu.gluTessEndContour(tobj); glu.gluTessEndPolygon(tobj); } /** This method handles things if display depth changes */ public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged){ } //need these methods because we are a mouse listener public void mouseClicked(MouseEvent e) { if (e.isMetaDown()) { //right click //start new polyline polyline = new ArrayList(); } else { Point p = new Point (e.getX(), height - e.getY()); // AWT has y axis going up, GL, down polyline.add(p); } canvas.repaint(); } public void mouseEntered(MouseEvent e) { } public void mousePressed(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } public void mouseExited(MouseEvent e) { } /* * Tessellator callback implemenation with all the callback routines. YOu * could use GLUtesselatorCallBackAdapter instead. But */ class tessellCallBack // extends GLUtessellatorCallbackAdapter // { private GL gl; private GLU glu; public tessellCallBack(GL gl, GLU glu) { this.gl = gl; this.glu = glu; } public void begin(int type) { gl.glBegin(type); } public void end() { gl.glEnd(); } public void vertex(Object vertexData) { gl.glVertex3dv((double[]) vertexData, 0); } /* * combineCallback is used to create a new vertex when edges intersect. * coordinate location is trivial to calculate, but weight[4] may be * used to average color, normal, or texture coordinate data. */ public void combine(double[] coords, Object[] data, // float[] weight, Object[] outData) { double[] vertex = new double[3]; vertex[0] = coords[0]; vertex[1] = coords[1]; vertex[2] = coords[2]; outData[0] = vertex; } public void error(int errnum) { System.err.println("Tessellation Error: " + glu.gluErrorString(errnum)); System.exit(0); } } }