/* * Copyright (c) 1993-1997, Silicon Graphics, Inc. * ALL RIGHTS RESERVED * Permission to use, copy, modify, and distribute this software for * any purpose and without fee is hereby granted, provided that the above * copyright notice appear in all copies and that both the copyright notice * and this permission notice appear in supporting documentation, and that * the name of Silicon Graphics, Inc. not be used in advertising * or publicity pertaining to distribution of the software without specific, * written prior permission. */ /* * Created on 24/02/2006 * * TODO To change the template for this generated file go to * Window - Preferences - Java - Code Style - Code Templates */ /* * Tess.java * This program demonstrates polygon tessellation. * Two tesselated objects are drawn. The first is a * rectangle with a triangular hole. The second is a * smooth shaded, self-intersecting star. * * Note the exterior rectangle is drawn with its vertices * in counter-clockwise order, but its interior clockwise. * Note the combineCallback is needed for the self-intersecting * star. Also note that removing the TessProperty for the * star will make the interior unshaded (WINDING_ODD). * * * @converted to Java by Wu Shin - Ting * * TODO To change the template for this generated type comment go to * Window - Preferences - Java - Code Style - Code Templates */ import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.media.opengl.*; import javax.media.opengl.glu.*; public class Tess extends JFrame implements GLEventListener, KeyListener { public static final Dimension PREFERRED_FRAME_SIZE = new Dimension(500, 500); private int startList; /** Constructor. */ public Tess() { // init JFrame super ("Tess - JMDM version "); System.out.println("Constructor"); } /** We'd like to be 500x500, please. */ public Dimension getPreferredSize(){ return PREFERRED_FRAME_SIZE; } /* * METHODS DEFINED BY GLEventListener */ /** Called by drawable to initiate drawing. * Draw 2 diagonal lines to form an X */ public void display(GLAutoDrawable drawable) { System.out.println("Display"); GL gl = drawable.getGL(); gl.glClear(GL.GL_COLOR_BUFFER_BIT); gl.glColor3d(1.0, 1.0, 1.0); gl.glCallList(startList); gl.glCallList(startList + 1); gl.glFlush(); } /** Called by drawable to indicate mode or device has changed. */ public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged){} /** Called after OpenGL is init'ed */ public void init(GLAutoDrawable drawable) { GL gl = drawable.getGL(); GLU glu = new GLU(); System.out.println("init()"); System.err.println("INIT GL IS: " + gl.getClass().getName()); System.err.println("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR)); System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER)); System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION)); //Add the key listener drawable.addKeyListener(this); double[][] rect = new double[][]{{50.0, 50.0, 0.0}, {200.0, 50.0, 0.0}, {200.0, 200.0, 0.0}, {50.0, 200.0, 0.0}}; double[][] tri = new double[][]{{75.0, 75.0, 0.0}, {125.0, 175.0, 0.0}, {175.0, 75.0, 0.0}}; double[][] star = new double[][]{{250.0, 50.0, 0.0, 1.0, 0.0, 1.0}, {325.0, 200.0, 0.0, 1.0, 1.0, 0.0}, {400.0, 50.0, 0.0, 0.0, 1.0, 1.0}, {250.0, 150.0, 0.0, 1.0, 0.0, 0.0}, {400.0, 150.0, 0.0, 0.0, 1.0, 0.0}}; gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); startList = gl.glGenLists(2); GLUtessellator tobj = glu.gluNewTess(); TessCallback tessCallback = new TessCallback(gl, glu); glu.gluTessCallback(tobj, GLU.GLU_TESS_VERTEX, tessCallback); glu.gluTessCallback(tobj, GLU.GLU_TESS_BEGIN, tessCallback); glu.gluTessCallback(tobj, GLU.GLU_TESS_END, tessCallback); glu.gluTessCallback(tobj, GLU.GLU_TESS_ERROR, tessCallback); gl.glNewList(startList, GL.GL_COMPILE); gl.glShadeModel(GL.GL_FLAT); glu.gluTessBeginPolygon(tobj, null); glu.gluTessBeginContour(tobj); glu.gluTessVertex(tobj, rect[0], 0, rect[0]); glu.gluTessVertex(tobj, rect[1], 0, rect[1]); glu.gluTessVertex(tobj, rect[2], 0, rect[2]); glu.gluTessVertex(tobj, rect[3], 0, rect[3]); glu.gluTessEndContour(tobj); glu.gluTessBeginContour(tobj); glu.gluTessVertex(tobj, tri[0], 0, tri[0]); glu.gluTessVertex(tobj, tri[1], 0, tri[1]); glu.gluTessVertex(tobj, tri[2], 0, tri[2]); glu.gluTessEndContour(tobj); glu.gluTessEndPolygon(tobj); gl.glEndList(); glu.gluTessCallback(tobj, GLU.GLU_TESS_VERTEX, tessCallback); glu.gluTessCallback(tobj, GLU.GLU_TESS_BEGIN, tessCallback); glu.gluTessCallback(tobj, GLU.GLU_TESS_END, tessCallback); glu.gluTessCallback(tobj, GLU.GLU_TESS_ERROR, tessCallback); glu.gluTessCallback(tobj, GLU.GLU_TESS_COMBINE, tessCallback); gl.glNewList(startList + 1, GL.GL_COMPILE); gl.glShadeModel(GL.GL_SMOOTH); glu.gluTessProperty(tobj, GLU.GLU_TESS_WINDING_RULE, GLU.GLU_TESS_WINDING_POSITIVE); glu.gluTessBeginPolygon(tobj, null); glu.gluTessBeginContour(tobj); glu.gluTessVertex(tobj, star[0], 0, star[0]); glu.gluTessVertex(tobj, star[1], 0, star[1]); glu.gluTessVertex(tobj, star[2], 0, star[2]); glu.gluTessVertex(tobj, star[3], 0, star[3]); glu.gluTessVertex(tobj, star[4], 0, star[4]); glu.gluTessEndContour(tobj); glu.gluTessEndPolygon(tobj); gl.glEndList(); glu.gluDeleteTess(tobj); } /** Called to indicate the drawing surface has been moved and/or resized. */ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height){ GL gl = drawable.getGL(); System.out.println("reshape()"); gl.glMatrixMode(GL.GL_PROJECTION); gl.glLoadIdentity(); gl.glOrtho( 0, 450, 0, 250, -1, 1 ); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glLoadIdentity(); } /* * OUR HELPER METHODS */ // Methods required for Tessellation Callback public static class TessCallback extends javax.media.opengl.glu.GLUtessellatorCallbackAdapter { GL gl; GLU glu; public TessCallback(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 data) { if (data instanceof double[]) { double[] d = (double[]) data; if (d.length == 6) { gl.glColor3dv(d, 3); } gl.glVertex3dv(d, 0); } } public void error(int errnum) { String estring; estring = glu.gluErrorString(errnum); System.out.println("Tessellation Error: " + estring); //System.exit(0); throw new RuntimeException(); } public void combine(double[] coords, Object[] data, float[] weight, Object[] outData) { double[] vertex = new double[6]; int i; vertex[0] = coords[0]; vertex[1] = coords[1]; vertex[2] = coords[2]; for (i = 3; i < 6; i++) vertex[i] = weight[0] * ((double[]) data[0])[i] + weight[1] * ((double[]) data[1])[i] + weight[2] * ((double[]) data[2])[i] + weight[3] * ((double[]) data[3])[i]; outData[0] = vertex; } } // Methods required for the implementation of KeyListener public void keyPressed(KeyEvent e){ System.out.println("Key pressed"); if (e.getKeyChar() == 27) { /* Escape Key */ System.exit(0); } } public void keyReleased(KeyEvent e){} public void keyTyped(KeyEvent e){} /** main creates and shows a Tess-JFrame */ public static void main(String[] args){ Tess g = new Tess(); GLCapabilities gl_c = new GLCapabilities(); // Disable double buffer gl_c.setDoubleBuffered(false); // get a GLCanvas GLCanvas canvas = new GLCanvas(gl_c); // add a GLEventListener, which will get called when the // canvas is resized or needs a repaint canvas.addGLEventListener(g); // now add the canvas to the JFrame. Note we use BorderLayout.CENTER // to make the canvas stretch to fill the container (ie, the frame) g.getContentPane().add(canvas, BorderLayout.CENTER); g.pack(); g.setVisible(true); } }