content: /*
   * Copyright (C) 2010-2014 - Andreas Maier 
   * CONRAD is developed as an Open Source project under the GNU General Public License (GPL).
  */
  package edu.stanford.rsl.apps.gui.opengl;
  
  import java.awt.Frame;
  import java.awt.event.WindowAdapter;
  import java.awt.event.WindowEvent;
  
  import javax.media.opengl.GL;
  import javax.media.opengl.GL2;
  import javax.media.opengl.GLAutoDrawable;
  import javax.media.opengl.GLCapabilities;
  import javax.media.opengl.GLEventListener;
  import javax.media.opengl.GLProfile;
  import javax.media.opengl.awt.GLCanvas;
  import javax.media.opengl.fixedfunc.GLLightingFunc;
  import javax.media.opengl.glu.GLU;
  import javax.media.opengl.glu.GLUnurbs;
  import javax.media.opengl.glu.gl2.GLUgl2;
  
  import com.jogamp.opengl.util.FPSAnimator;
  /**
   * @author Lloyd
   *
   * This class was written for the purpose of testing surface functionality in JOGL2
   * set the variable bDoNurbs to true and run the program, then set it to false and run.
   * I'm wandering if Nurbs rendering works in JOGL2.  It seems like its close but that
   * none of the lighting is working; by contrast use glEvalMesh2 method of rendering works
   *
   */
  public class SurfaceTest implements GLEventListener {
  
  	/* if this value is false it will draw surface using
  	 * glEvalMesh2  
  	 * if true then it will use
  	 * NurbsRenderer
  	 * The question is whether nurbs is properly implemented in JOGL2.
  	 * on my machine the lighting functionality seems to work with EvalMesh but
  	 * not with NurbsRenderer
  	 */
  	boolean bDoNurbs = true;
  
  	GLU glu;
  	Point3DF cameraUpDirection = new Point3DF(0.f, 1.f, 0.f);
  	float xCamera = 0.f;
  	float tval = 0.f;
  	private float deltaT = .05f;
  	Point3DF cameraLoc = new Point3DF(xCamera, 2.f, 8.f);
  	Point3DF lookAtPt = new Point3DF(0.f, -1.f, 0.f);
  
  	float red[] = { 0.8f, 0.1f, 0.0f, 1.0f };
  	float green[] = { 0.0f, 0.8f, 0.2f, 1.0f };
  	float blue[] = { 0.f, 0.1f, 0.8f, 0.5f };
  	float white[] = { 1.0f, 1.0f, 1.0f, 1.0f };
  	float[] ctlarray = new float[] {
  			-1.5f,-1.5f,4f,
  			-0.5f,-1.5f,2.f,
  			0.5f,-1.5f,-1.f,
  			1.5f,-1.5f,2.f,
  
  			-1.5f,-0.5f,1f,
  			-0.5f,-0.5f,3.f,
  			0.5f,-0.5f,0.f,
  			1.5f,-0.5f,-1f,
  
  			-1.5f,0.5f,4f,
  			-0.5f,0.5f,0f,
  			0.5f,0.5f,3f,
  			1.5f,0.5f,4f,
  
  			-1.5f,1.5f,-2.f,
  			-0.5f,1.5f,-2.0f,
  			0.5f,1.5f,0.0f,
  			1.5f,1.5f,-1.0f
  	};
  	// Point3DF class is only for readability purposes
  	class Point3DF {
  		float x;
  		float y;
  		float z;
  		Point3DF(float a, float b, float c) {
  			x=a;
  			y=b;
  			z=c;
  		}
  	}
  
  	public void display(GLAutoDrawable drawable) {
  		update(drawable.getGL().getGL2());
  		render(drawable);
  	}
  	private void update(GL2 gl) {
  		gl.glLoadIdentity();
  		glu.gluLookAt(cameraLoc.x, cameraLoc.y, cameraLoc.z,
  				lookAtPt.x, lookAtPt.y, lookAtPt.z,
  				cameraUpDirection.x, cameraUpDirection.y, cameraUpDirection.z);
  		tval += deltaT;
  		cameraLoc.x = (float) Math.sin(tval);
  	}
  	private void render(GLAutoDrawable drawable) {
  		if (bDoNurbs) {
  			drawNurbSurface(drawable);
  		}
  		else {
  			drawSurface(drawable);
  		}
  	}
  
  	public void dispose(GLAutoDrawable drawable) {
  		System.out.println("--dispose--");
  	}
  
  	public void init(GLAutoDrawable drawable) {
  		System.out.println("--init--");
  		GL2 gl = drawable.getGL().getGL2();
  		glu = new GLU();
  
  		System.out.println("INIT GL IS: " + gl.getClass().getName());
  		if (!bDoNurbs) {
  			gl.glMap2f(GL2.GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, ctlarray, 0);
  		}
  		gl.glEnable(GL2.GL_MAP2_VERTEX_3);
  		gl.glEnable(GL2.GL_AUTO_NORMAL);
  		gl.glMapGrid2f(20, 0.0f, 1.0f, 20, 0.0f, 1.0f);
  
  		setupLighting(drawable, gl);
  		float fovy=40.f;
  		float aspect=1.f;
  		float znear=1.f;
  		float zfar=20f;
  		glu.gluPerspective(fovy, aspect, znear, zfar);
  
  		gl.glMatrixMode(GL2.GL_MODELVIEW);
  		gl.glLoadIdentity();
  		glu.gluLookAt(cameraLoc.x, cameraLoc.y, cameraLoc.z,
  				lookAtPt.x, lookAtPt.y, lookAtPt.z,
  				cameraUpDirection.x, cameraUpDirection.y, cameraUpDirection.z);
  	}
  	private void setupLighting(GLAutoDrawable drawable, GL2 gl) {
  		int paramsOffset = 0;
  		float pos[] = { 2.0f, -2.0f, 10.0f, 0.0f };
  		float ambient[] = {0.5f, 0.5f, 0.5f, 1.0f};
  		float diffuse[] = {0.9f, 0.9f, 0.9f, 1.0f};
  		float specular[] = {0.05f, 0.05f, 0.99f, 1.0f};
  
  		gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_POSITION, pos, 0);
  		gl.glEnable(GL2.GL_LIGHTING);
  		gl.glEnable(GL2.GL_LIGHT0);
  		gl.glEnable(GL2.GL_DEPTH_TEST);
  		gl.glEnable(GL2.GL_AUTO_NORMAL);
  		gl.glEnable(GL2.GL_NORMALIZE);
  
  		gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_AMBIENT, ambient, paramsOffset);
  		gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_DIFFUSE, diffuse, paramsOffset);
  		gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_SPECULAR, specular, paramsOffset);
  		gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_POSITION, pos, paramsOffset);
  		gl.glLightModeli(GL2.GL_LIGHT_MODEL_LOCAL_VIEWER, GL2.GL_TRUE);
  
  		gl.glClearColor(1f, 1f, 1f, 1f);
  		gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
  		gl.glMatrixMode(GL2.GL_MODELVIEW);
  		gl.glLoadIdentity();
  		gl.glViewport(0, 0, drawable.getSurfaceWidth(), drawable.getSurfaceHeight());
  		gl.glMatrixMode(GL2.GL_PROJECTION);
  		gl.glLoadIdentity();
  		if (gl instanceof GLLightingFunc) {
  			((GLLightingFunc) gl).glMaterialfv(GL.GL_FRONT, GLLightingFunc.GL_AMBIENT_AND_DIFFUSE, blue, 0);
  			((GLLightingFunc) gl).glMaterialfv(GL.GL_FRONT, GLLightingFunc.GL_SPECULAR, white, 0);
  			float[] medHiShiny = new float[] {80.0f};
  			((GLLightingFunc) gl).glMaterialfv(GL.GL_FRONT, GLLightingFunc.GL_SHININESS, medHiShiny, 0);
  			((GLLightingFunc) gl).glShadeModel(GLLightingFunc.GL_FLAT);
  		}
  	}
  
  	public void reshape(GLAutoDrawable drawable, int x, int y, int width,
  			int height) {
  		System.out.println("--reshape--");
  	}
  
  	private void drawSurface(GLAutoDrawable drawable) {
  		GL2 gl = drawable.getGL().getGL2();
  		gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
  		gl.glPushMatrix();
  		gl.glEvalMesh2(GL2.GL_FILL, 0, 20, 0, 20);
  		gl.glPopMatrix();
  		gl.glFlush();
  	}
  	private void drawNurbSurface(GLAutoDrawable drawable) {
  		GL2 gl = drawable.getGL().getGL2();
  		gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
  
  		GLUgl2 glug12 = new GLUgl2();
  		GLUnurbs nurbsRenderer = glug12.gluNewNurbsRenderer();
  		//glug12.gluNurbsProperty(nurbsRenderer, , arg2)
  		glug12.gluBeginSurface(nurbsRenderer);
  		int uknot_cnt=8;
  		float[] uknot = new float[] {0.f, 0.f, 0.f, 0.f, 1.f, 1.f, 1.f, 1.f};
  		int vknot_cnt = 8;
  		float[] vknot = uknot;
  		int ustride=4*3;
  		int vstride=3;
  		int uorder=4;
  		int vorder=4;
  		int evl_type=GL2.GL_MAP2_NORMAL;
  		//glug12.gluNurbsSurface(nurbsRenderer, uknot_cnt, uknot, vknot_cnt, vknot, ustride, vstride, ctlarray, uorder, vorder, evl_type);
  		evl_type=GL2.GL_MAP2_VERTEX_3;
  		glug12.gluNurbsSurface(nurbsRenderer, uknot_cnt, uknot, vknot_cnt, vknot, ustride, vstride, ctlarray, uorder, vorder, evl_type);
  		glug12.gluEndSurface(nurbsRenderer);
  	}
  	/**
  	 * @param args
  	 */
  	 public static void main(String[] args) {
  		GLProfile.initSingleton();
  		GLProfile glp = GLProfile.getDefault();
  		GLCapabilities caps = new GLCapabilities(glp);
  		GLCanvas canvas = new GLCanvas(caps);
  
  		Frame frame = new Frame("Test Surface rendering in JOGL 2 using nurbs or eval-mesh");
  		frame.setSize(300, 300);
  		frame.add(canvas);
  		frame.setVisible(true);
  
  		// by default, an AWT Frame doesn't do anything when you click
  		// the close button; this bit of code will terminate the program when
  		// the window is asked to close
  		frame.addWindowListener(new WindowAdapter() {
  			public void windowClosing(WindowEvent e) {
  				System.exit(0);
  			}
  		});
  		canvas.addGLEventListener(new SurfaceTest());
  		FPSAnimator animator = new FPSAnimator(canvas, 5);
  		//animator.add(canvas);
  		animator.start();
  	 }
  } 
  