/*******************************************************************************
* Copyright 2012 Geoscience Australia
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package au.gov.ga.earthsci.application.parts;
import javax.inject.Inject;
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.glu.GLU;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.newt.swt.NewtCanvasSWT;
import com.jogamp.opengl.util.Animator;
/**
* OpenGL test part which tests the {@link NewtCanvasSWT}.
*
* @author Michael de Hoog (michael.dehoog@ga.gov.au)
*/
public class OpenGLTestPart
{
private int rot = 0;
@Inject
public void init(Composite parent)
{
GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GL2));
final GLWindow glWindow = GLWindow.create(caps);
new NewtCanvasSWT(parent, SWT.NONE, glWindow)
{
@Override
public void setBounds(int x, int y, int width, int height)
{
//do not allow a size of 0,0, because NEWT window becomes invisible (https://jogamp.org/bugzilla/show_bug.cgi?id=822)
super.setBounds(x, y, Math.max(1, width), Math.max(1, height));
}
};
glWindow.addGLEventListener(new MyGlEventListener());
Animator animator = new Animator(glWindow);
animator.setUpdateFPSFrames(1, null);
animator.start();
}
/**
* GLEventListener which draws a spinning torus. From
* https://github.com/sgothel
* /jogl-demos/blob/master/src/demos/swt/Snippet209.java.
*/
private class MyGlEventListener implements GLEventListener
{
@Override
public void init(GLAutoDrawable drawable)
{
GL2 gl = drawable.getGL().getGL2();
gl.setSwapInterval(1);
gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
gl.glColor3f(1.0f, 0.0f, 0.0f);
gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST);
gl.glClearDepth(1.0);
gl.glLineWidth(2);
gl.glEnable(GL2.GL_DEPTH_TEST);
}
@Override
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)
{
float fAspect = (float) width / (float) height;
GL2 gl = drawable.getGL().getGL2();
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glLoadIdentity();
GLU glu = new GLU();
glu.gluPerspective(45.0f, fAspect, 0.5f, 400.0f);
gl.glMatrixMode(GL2.GL_MODELVIEW);
gl.glLoadIdentity();
}
@Override
public void display(GLAutoDrawable drawable)
{
GL2 gl = drawable.getGL().getGL2();
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
gl.glClearColor(.3f, .5f, .8f, 1.0f);
gl.glLoadIdentity();
gl.glTranslatef(0.0f, 0.0f, -10.0f);
gl.glRotatef(0.15f * rot, 2.0f * rot, 10.0f * rot, 1.0f);
gl.glRotatef(0.3f * rot, 3.0f * rot, 1.0f * rot, 1.0f);
rot++;
gl.glPolygonMode(GL2.GL_FRONT_AND_BACK, GL2.GL_LINE);
gl.glColor3f(0.9f, 0.9f, 0.9f);
drawTorus(gl, 1, 1.9f + ((float) Math.sin((0.004f * rot))), 15, 15);
}
@Override
public void dispose(GLAutoDrawable drawable)
{
}
protected void drawTorus(GL2 gl, float r, float R, int nsides, int rings)
{
float ringDelta = 2.0f * (float) Math.PI / rings;
float sideDelta = 2.0f * (float) Math.PI / nsides;
float theta = 0.0f, cosTheta = 1.0f, sinTheta = 0.0f;
for (int i = rings - 1; i >= 0; i--)
{
float theta1 = theta + ringDelta;
float cosTheta1 = (float) Math.cos(theta1);
float sinTheta1 = (float) Math.sin(theta1);
gl.glBegin(GL2.GL_QUAD_STRIP);
float phi = 0.0f;
for (int j = nsides; j >= 0; j--)
{
phi += sideDelta;
float cosPhi = (float) Math.cos(phi);
float sinPhi = (float) Math.sin(phi);
float dist = R + r * cosPhi;
gl.glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi);
gl.glVertex3f(cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi);
gl.glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi);
gl.glVertex3f(cosTheta * dist, -sinTheta * dist, r * sinPhi);
}
gl.glEnd();
theta = theta1;
cosTheta = cosTheta1;
sinTheta = sinTheta1;
}
}
}
}