package glredbook11;
import java.awt.event.*;
import javax.swing.*;
import javax.media.opengl.*;
import javax.media.opengl.glu.*;
/**
* 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).
*
* @author Kiet Le (Java conversion)
* @NOTE Java arrays are column major whereas C arrays are row major
*/
public class tess
extends JFrame
implements GLEventListener, KeyListener
{
private GLCapabilities caps;
private GLCanvas canvas;
private GLU glu;
private int startList;
public tess()
{
super("tess");// name of file as title in window bar
/*
* display mode (single buffer and RGBA)
*/
caps = new GLCapabilities();
caps.setDoubleBuffered(false);
System.out.println(caps.toString());
canvas = new GLCanvas(caps);
canvas.addGLEventListener(this);
canvas.addKeyListener(this);
getContentPane().add(canvas);
}
/*
* Declare initial window size, position, and set frame's close behavior. Open
* window with "hello" in its title bar. Call initialization routines.
* Register callback function to display graphics. Enter main loop and process
* events.
*/
public void run()
{
setSize(500, 500);
setLocationRelativeTo(null); // center
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
canvas.requestFocusInWindow();
}
public static void main(String[] args)
{
new tess().run();
}
public void init(GLAutoDrawable drawable)
{
GL gl = drawable.getGL();
glu = new GLU();
/*
* jogl specific addition for tessellation
*/
tessellCallBack tessCallback = new tessellCallBack(gl, glu);
double rect[][] = new double[][]
{ // [4][3] in C; reverse here
{ 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[][]
{// [3][3]
{ 75.0, 75.0, 0.0 },
{ 125.0, 175.0, 0.0 },
{ 175.0, 75.0, 0.0 } };
double star[][] = new double[][]
{// [5][6]; 6x5 in java
{ 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();
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);
/* rectangle with triangular hole inside */
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);// vertexCallback);
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);
/* smooth shaded, self-intersecting star */
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);
}
public void display(GLAutoDrawable drawable)
{
GL gl = drawable.getGL();
gl.glClear(GL.GL_COLOR_BUFFER_BIT);
gl.glColor3f(1.0f, 1.0f, 1.0f);
gl.glCallList(startList);
gl.glCallList(startList + 1);
gl.glFlush();
}
public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h)
{
GL gl = drawable.getGL();
gl.glViewport(0, 0, w, h);
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluOrtho2D(0.0, (double) w, 0.0, (double) h);
}
public void displayChanged(GLAutoDrawable drawable, boolean modeChanged,
boolean deviceChanged)
{
}
public void keyTyped(KeyEvent e)
{
}
public void keyPressed(KeyEvent key)
{
switch (key.getKeyCode()) {
case KeyEvent.VK_ESCAPE:
System.exit(0);
default:
break;
}
}
public void keyReleased(KeyEvent e)
{
}
/*
* Tessellator callback implemenation with all the callback routines. YOu
* could use GLUtesselatorCallBackAdapter instead. But
*/
class tessellCallBack
implements GLUtessellatorCallback
{
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)
{
double[] pointer;
if (vertexData instanceof double[])
{
pointer = (double[]) vertexData;
if (pointer.length == 6) gl.glColor3dv(pointer, 3);
gl.glVertex3dv(pointer, 0);
}
}
public void vertexData(Object vertexData, Object polygonData)
{
}
/*
* 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. In this program, color
* is weighted.
*/
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/* 7OutOfBounds from C! */; 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;
}
public void combineData(double[] coords, Object[] data, //
float[] weight, Object[] outData, Object polygonData)
{
}
public void error(int errnum)
{
String estring;
estring = glu.gluErrorString(errnum);
System.err.println("Tessellation Error: " + estring);
System.exit(0);
}
public void beginData(int type, Object polygonData)
{
}
public void endData(Object polygonData)
{
}
public void edgeFlag(boolean boundaryEdge)
{
}
public void edgeFlagData(boolean boundaryEdge, Object polygonData)
{
}
public void errorData(int errnum, Object polygonData)
{
}
}// tessellCallBack
}// tess
|
You can share your information about this topic using the form below!
Please do not post your questions with this form! Thanks.