package demos.es2;
import java.nio.*;
import java.util.*;
import com.jogamp.opengl.*;
import com.jogamp.nativewindow.*;
import com.jogamp.opengl.util.*;
import com.jogamp.opengl.util.glsl.*;
import com.jogamp.newt.*;
import com.jogamp.newt.event.*;
import com.jogamp.newt.opengl.*;
public class RedSquare extends Thread implements WindowListener, KeyListener, MouseListener, GLEventListener {
public Window nWindow = null;
public GLWindow window;
private GLProfile glp;
private boolean quit = false;
private final String glprofile;
private final int type;
public RedSquare() {
this(null, USE_NEWT);
}
public RedSquare(String glprofile, int type) {
super();
this.glprofile=glprofile;
this.type=type;
}
public void windowRepaint(WindowUpdateEvent e) { }
public void windowResized(WindowEvent e) { }
public void windowMoved(WindowEvent e) { }
public void windowGainedFocus(WindowEvent e) { }
public void windowLostFocus(WindowEvent e) { }
public void windowDestroyNotify(WindowEvent e) {
System.out.println("WINDOW-DESTROY NOTIFY "+Thread.currentThread()+" QUIT "+e);
quit = true;
}
public void windowDestroyed(WindowEvent e) {
System.out.println("WINDOW-DESTROYED "+Thread.currentThread());
}
public void keyPressed(KeyEvent e) {
System.out.println("KEY-PRESSED "+Thread.currentThread()+" UNHANDLED "+e);
}
public void keyReleased(KeyEvent e) {
System.out.println("KEY-RELEASED "+Thread.currentThread()+" UNHANDLED "+e);
if( !e.isPrintableKey() || e.isAutoRepeat() ) {
return;
}
if(e.getKeyChar()=='f') {
System.out.println("KEY-TYPED "+Thread.currentThread()+" FULLSCREEN "+e);
window.setFullscreen(!window.isFullscreen());
} else if(e.getKeyChar()=='q') {
System.out.println("KEY-TYPED "+Thread.currentThread()+" QUIT "+e);
quit = true;
} else {
System.out.println("KEY-TYPED "+Thread.currentThread()+" UNHANDLED "+e);
}
}
public void mouseClicked(MouseEvent e) {
System.out.println("MOUSE-CLICKED "+Thread.currentThread()+" UNHANDLED "+e);
switch(e.getClickCount()) {
case 1:
if(e.getButton()>MouseEvent.BUTTON1) {
window.setFullscreen(!window.isFullscreen());
}
break;
default:
quit=true;
break;
}
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
}
public void mouseDragged(MouseEvent e) {
}
public void mouseWheelMoved(MouseEvent e) {
}
public boolean shouldQuit() { return quit; }
public void run() {
int width = 800;
int height = 480;
glp = GLProfile.get(glprofile);
System.out.println("RUN "+Thread.currentThread()+" "+glp);
try {
GLCapabilities caps = new GLCapabilities(glp);
if(0!=(type&USE_AWT)) {
Display nDisplay = NewtFactory.createDisplay(NativeWindowFactory.TYPE_AWT, null); // local display
Screen nScreen = NewtFactory.createScreen(nDisplay, 0); // screen 0
nWindow = NewtFactory.createWindow(nScreen, caps);
window = GLWindow.create(nWindow);
} else {
window = GLWindow.create(caps);
}
window.addWindowListener(this);
window.addMouseListener(this);
window.addKeyListener(this);
window.addGLEventListener(this);
// Size OpenGL to Video Surface
window.setSize(width, height);
// window.setFullscreen(true);
window.setVisible(true);
window.setUpdateFPSFrames(FPSCounter.DEFAULT_FRAMES_PER_INTERVAL, System.err);
if(!oneThread) {
do {
display();
} while (!quit && window.getTotalFPSDuration() < 20000) ;
shutdown();
}
} catch (Throwable t) {
t.printStackTrace();
}
}
public void display() {
try {
window.display();
} catch (Throwable t) {
t.printStackTrace();
}
}
public void shutdown() {
try {
// Shut things down cooperatively
window.destroy();
window = null;
if(null!=nWindow) {
nWindow.destroy();
nWindow=null;
}
System.out.println("SHUTDOWN "+Thread.currentThread()+" cleanly");
} catch (Throwable t) {
t.printStackTrace();
}
}
ShaderState st;
PMVMatrix pmvMatrix;
private void initShader(GL2ES2 gl) {
// Create & Compile the shader objects
ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, RedSquare.class,
"shader", "shader/bin", "redsquare", false);
ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, RedSquare.class,
"shader", "shader/bin", "redsquare", false);
// Create & Link the shader program
ShaderProgram sp = new ShaderProgram();
sp.add(rsVp);
sp.add(rsFp);
if(!sp.link(gl, System.err)) {
throw new GLException("Couldn't link program: "+sp);
}
// Let's manage all our states using ShaderState.
st = new ShaderState();
st.attachShaderProgram(gl, sp, false);
}
public void init(GLAutoDrawable drawable) {
GL2ES2 gl = drawable.getGL().getGL2ES2();
if(swapInterval>=0) {
gl.setSwapInterval(swapInterval);
}
System.err.println(Thread.currentThread()+" Entering initialization");
System.err.println(Thread.currentThread()+" GL Profile: "+gl.getGLProfile());
System.err.println(Thread.currentThread()+" GL:" + gl);
System.err.println(Thread.currentThread()+" GL_VERSION=" + gl.glGetString(gl.GL_VERSION));
System.err.println(Thread.currentThread()+" GL_EXTENSIONS:");
System.err.println(Thread.currentThread()+" " + gl.glGetString(gl.GL_EXTENSIONS));
System.err.println(Thread.currentThread()+" swapInterval: " + swapInterval + " (GL: "+gl.getSwapInterval()+")");
System.err.println(Thread.currentThread()+" isShaderCompilerAvailable: " + ShaderUtil.isShaderCompilerAvailable(gl));
if(debuggl) {
try {
// Debug ..
gl = (GL2ES2) gl.getContext().setGL( GLPipelineFactory.create("com.jogamp.opengl.Debug", GL2ES2.class, gl, null) );
// Trace ..
gl = (GL2ES2) gl.getContext().setGL( GLPipelineFactory.create("com.jogamp.opengl.Trace", GL2ES2.class, gl, new Object[] { System.err } ) );
} catch (Exception e) {e.printStackTrace();}
}
pmvMatrix = new PMVMatrix();
initShader(gl);
// Push the 1st uniform down the path
st.useProgram(gl, true);
pmvMatrix.glMatrixMode(pmvMatrix.GL_PROJECTION);
pmvMatrix.glLoadIdentity();
pmvMatrix.glMatrixMode(pmvMatrix.GL_MODELVIEW);
pmvMatrix.glLoadIdentity();
if(!st.uniform(gl, new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf()))) {
throw new GLException("Error setting PMVMatrix in shader: "+st);
}
// Allocate vertex arrays
GLArrayDataClient vertices = GLArrayDataClient.createGLSL("mgl_Vertex", 3, gl.GL_FLOAT, false, 4);
{
// Fill them up
FloatBuffer verticeb = (FloatBuffer)vertices.getBuffer();
verticeb.put(-2); verticeb.put( 2); verticeb.put( 0);
verticeb.put( 2); verticeb.put( 2); verticeb.put( 0);
verticeb.put(-2); verticeb.put( -2); verticeb.put( 0);
verticeb.put( 2); verticeb.put( -2); verticeb.put( 0);
}
vertices.seal(gl, true);
GLArrayDataClient colors = GLArrayDataClient.createGLSL("mgl_Color", 4, gl.GL_FLOAT, false, 4);
{
// Fill them up
FloatBuffer colorb = (FloatBuffer)colors.getBuffer();
colorb.put( 1); colorb.put( 0); colorb.put( 0); colorb.put( 1);
colorb.put( 0); colorb.put( 0); colorb.put( 1); colorb.put( 1);
colorb.put( 1); colorb.put( 0); colorb.put( 0); colorb.put( 1);
colorb.put( 1); colorb.put( 0); colorb.put( 0); colorb.put( 1);
}
colors.seal(gl, true);
// OpenGL Render Settings
gl.glClearColor(0, 0, 0, 1);
gl.glEnable(GL2ES2.GL_DEPTH_TEST);
st.useProgram(gl, false);
// Let's show the completed shader state ..
System.out.println(Thread.currentThread()+" "+st);
}
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
if(null==st) return;
GL2ES2 gl = drawable.getGL().getGL2ES2();
st.useProgram(gl, true);
// Set location in front of camera
pmvMatrix.glMatrixMode(pmvMatrix.GL_PROJECTION);
pmvMatrix.glLoadIdentity();
pmvMatrix.gluPerspective(45.0f, (float)width / (float)height, 1.0f, 100.0f);
//pmvMatrix.glOrthof(-4.0f, 4.0f, -4.0f, 4.0f, 1.0f, 100.0f);
GLUniformData ud = st.getUniform("mgl_PMVMatrix");
if(null!=ud) {
// same data object
st.uniform(gl, ud);
}
st.useProgram(gl, false);
}
public void dispose(GLAutoDrawable drawable) {
if(null==st) return;
GL2ES2 gl = drawable.getGL().getGL2ES2();
System.out.println(Thread.currentThread()+" RedSquare.dispose: "+gl.getContext());
st.destroy(gl);
st=null;
pmvMatrix=null;
System.out.println(Thread.currentThread()+" RedSquare.dispose: FIN");
}
public void display(GLAutoDrawable drawable) {
if(null==st) return;
GL2ES2 gl = drawable.getGL().getGL2ES2();
st.useProgram(gl, true);
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT);
// One rotation every four seconds
pmvMatrix.glMatrixMode(pmvMatrix.GL_MODELVIEW);
pmvMatrix.glLoadIdentity();
pmvMatrix.glTranslatef(0, 0, -10);
float ang = (window.getTotalFPSDuration() * 360.0f) / 4000.0f;
pmvMatrix.glRotatef(ang, 0, 0, 1);
pmvMatrix.glRotatef(ang, 0, 1, 0);
GLUniformData ud = st.getUniform("mgl_PMVMatrix");
if(null!=ud) {
// same data object
st.uniform(gl, ud);
}
// Draw a square
gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, 4);
st.useProgram(gl, false);
}
public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
}
public static int USE_NEWT = 0;
public static int USE_AWT = 1 << 0;
public static boolean oneThread = false;
public static int swapInterval = -1;
public static boolean debuggl = false;
public static void main(String[] args) {
NewtFactory.setUseEDT(true); // should be the default
int type = USE_NEWT ;
List threads = new ArrayList();
for(int i=0; i<args.length; i++) {
if(args[i].equals("-swapi")) {
i++;
try {
swapInterval = Integer.parseInt(args[i]);
} catch (Exception ex) { ex.printStackTrace(); }
} else if(args[i].equals("-debug")) {
debuggl=true;
} else if(args[i].equals("-1thread")) {
oneThread=true;
} else if(args[i].equals("-awt")) {
type |= USE_AWT;
} else if(args[i].startsWith("-GL")) {
threads.add(new RedSquare(args[i].substring(1), type));
}
}
if(threads.size()==0) {
threads.add(new RedSquare(GLProfile.GL2ES2, type));
}
if(!oneThread) {
for(Iterator i = threads.iterator(); i.hasNext(); ) {
((Thread)i.next()).start();
}
boolean done = false;
while(!done) {
int aliveCount = 0;
for(Iterator i = threads.iterator(); i.hasNext(); ) {
if ( ((Thread)i.next()).isAlive() ) {
try {
Thread.sleep(100);
} catch (InterruptedException ie) {}
aliveCount++;
}
}
done = 0==aliveCount ;
}
} else {
// init all ..
for(Iterator i = threads.iterator(); i.hasNext(); ) {
((Thread)i.next()).run();
}
while (threads.size()>0) {
for(Iterator i = threads.iterator(); i.hasNext(); ) {
RedSquare app = (RedSquare) i.next();
if(app.shouldQuit()) {
app.shutdown();
i.remove();
} else {
app.display();
}
}
}
}
}
}