Jogamp
Adapt to JOGL changes commit fd418a69eca7b8c1bb74244982305fc6004d0a52
[jogl-demos.git] / src / demos / es2 / RedSquare.java
1 package demos.es2;
2
3 import java.nio.*;
4 import java.util.*;
5 import javax.media.opengl.*;
6 import javax.media.nativewindow.*;
7
8 import com.jogamp.opengl.util.*;
9 import com.jogamp.opengl.util.glsl.*;
10
11 import com.jogamp.newt.*;
12 import com.jogamp.newt.event.*;
13 import com.jogamp.newt.opengl.*;
14
15 public class RedSquare extends Thread implements WindowListener, KeyListener, MouseListener, GLEventListener {
16
17     public Window nWindow = null;
18     public GLWindow window;
19     private GLProfile glp;
20     private boolean quit = false;
21     private String glprofile;
22     private int type;
23     
24     public RedSquare() {
25         this(null, USE_NEWT);
26     }
27
28     public RedSquare(String glprofile, int type) {
29         super();
30         this.glprofile=glprofile;
31         this.type=type;
32     }
33
34     public void windowRepaint(WindowUpdateEvent e) { }
35     public void windowResized(WindowEvent e) { }
36     public void windowMoved(WindowEvent e) { }
37     public void windowGainedFocus(WindowEvent e) { }
38     public void windowLostFocus(WindowEvent e) { }
39     public void windowDestroyNotify(WindowEvent e) {
40         System.out.println("WINDOW-DESTROY NOTIFY "+Thread.currentThread()+" QUIT "+e);
41         quit = true;
42     }
43     public void windowDestroyed(WindowEvent e) {
44         System.out.println("WINDOW-DESTROYED "+Thread.currentThread());
45     }
46
47     public void keyPressed(KeyEvent e) { 
48         System.out.println("KEY-PRESSED "+Thread.currentThread()+" UNHANDLED "+e);
49     }
50     public void keyReleased(KeyEvent e) { 
51         System.out.println("KEY-RELEASED "+Thread.currentThread()+" UNHANDLED "+e);
52     }
53     public void keyTyped(KeyEvent e) { 
54         if(e.getKeyChar()=='f') {
55             System.out.println("KEY-TYPED "+Thread.currentThread()+" FULLSCREEN "+e);
56             window.setFullscreen(!window.isFullscreen());
57         } else if(e.getKeyChar()=='q') {
58             System.out.println("KEY-TYPED "+Thread.currentThread()+" QUIT "+e);
59             quit = true;
60         } else {
61             System.out.println("KEY-TYPED "+Thread.currentThread()+" UNHANDLED "+e);
62         }
63     }
64
65     public void mouseClicked(MouseEvent e) {
66         System.out.println("MOUSE-CLICKED "+Thread.currentThread()+" UNHANDLED "+e);
67         switch(e.getClickCount()) {
68             case 1:
69                 if(e.getButton()>MouseEvent.BUTTON1) {
70                     window.setFullscreen(!window.isFullscreen());
71                 }
72                 break;
73             default: 
74                 quit=true;
75                 break;
76         }
77     }
78     public void mouseEntered(MouseEvent e) {
79     }
80     public void mouseExited(MouseEvent e) {
81     }
82     public void mousePressed(MouseEvent e) {
83     }
84     public void mouseReleased(MouseEvent e) {
85     }
86     public void mouseMoved(MouseEvent e) {
87     }
88     public void mouseDragged(MouseEvent e) {
89     }
90     public void mouseWheelMoved(MouseEvent e) {
91     }
92
93     public boolean shouldQuit() { return quit; }
94
95     public void run() {
96         int width = 800;
97         int height = 480;
98         glp = GLProfile.get(glprofile);
99         System.out.println("RUN "+Thread.currentThread()+" "+glp);
100         try {
101             GLCapabilities caps = new GLCapabilities(glp);
102
103             if(0!=(type&USE_AWT)) {
104                 Display nDisplay = NewtFactory.createDisplay(NativeWindowFactory.TYPE_AWT, null); // local display
105                 Screen nScreen  = NewtFactory.createScreen(nDisplay, 0); // screen 0
106                 nWindow = NewtFactory.createWindow(nScreen, caps);
107                 window = GLWindow.create(nWindow);
108             } else {
109                 window = GLWindow.create(caps);
110             }
111
112             window.addWindowListener(this);
113             window.addMouseListener(this);
114             window.addKeyListener(this);
115             window.addGLEventListener(this);
116
117             // Size OpenGL to Video Surface
118             window.setSize(width, height);
119             // window.setFullscreen(true);
120             window.setVisible(true);
121             window.setUpdateFPSFrames(FPSCounter.DEFAULT_FRAMES_PER_INTERVAL, System.err);
122
123             if(!oneThread) {
124                 do {
125                     display();
126                 } while (!quit && window.getTotalFPSDuration() < 20000) ;
127
128                 shutdown();
129             }
130
131         } catch (Throwable t) {
132             t.printStackTrace();
133         }
134     }
135
136     public void display() {
137         try {
138             window.display();
139         } catch (Throwable t) {
140             t.printStackTrace();
141         }
142     }
143
144     public void shutdown() {
145         try {
146             // Shut things down cooperatively
147             window.destroy();
148             window = null;
149             if(null!=nWindow) {
150                 nWindow.destroy();
151                 nWindow=null;
152             }
153             System.out.println("SHUTDOWN "+Thread.currentThread()+" cleanly");
154         } catch (Throwable t) {
155             t.printStackTrace();
156         }
157     }
158
159
160     ShaderState st;
161     PMVMatrix pmvMatrix;
162
163     private void initShader(GL2ES2 gl) {
164         // Create & Compile the shader objects
165         ShaderCode rsVp = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, RedSquare.class,
166                                             "shader", "shader/bin", "redsquare", false);
167         ShaderCode rsFp = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, RedSquare.class,
168                                             "shader", "shader/bin", "redsquare", false);
169
170         // Create & Link the shader program
171         ShaderProgram sp = new ShaderProgram();
172         sp.add(rsVp);
173         sp.add(rsFp);
174         if(!sp.link(gl, System.err)) {
175             throw new GLException("Couldn't link program: "+sp);
176         }
177
178         // Let's manage all our states using ShaderState.
179         st = new ShaderState();
180         st.attachShaderProgram(gl, sp, false);
181     }
182
183     public void init(GLAutoDrawable drawable) {
184         GL2ES2 gl = drawable.getGL().getGL2ES2();
185         if(swapInterval>=0) {
186             gl.setSwapInterval(swapInterval);
187         }
188
189         System.err.println(Thread.currentThread()+" Entering initialization");
190         System.err.println(Thread.currentThread()+" GL Profile: "+gl.getGLProfile());
191         System.err.println(Thread.currentThread()+" GL:" + gl);
192         System.err.println(Thread.currentThread()+" GL_VERSION=" + gl.glGetString(gl.GL_VERSION));
193         System.err.println(Thread.currentThread()+" GL_EXTENSIONS:");
194         System.err.println(Thread.currentThread()+"   " + gl.glGetString(gl.GL_EXTENSIONS));
195         System.err.println(Thread.currentThread()+" swapInterval: " + swapInterval + " (GL: "+gl.getSwapInterval()+")");
196         System.err.println(Thread.currentThread()+" isShaderCompilerAvailable: " + ShaderUtil.isShaderCompilerAvailable(gl));
197
198         if(debuggl) {
199             try {
200                 // Debug ..
201                 gl = (GL2ES2) gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Debug", GL2ES2.class, gl, null) );
202
203                 // Trace ..
204                 gl = (GL2ES2) gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Trace", GL2ES2.class, gl, new Object[] { System.err } ) );
205             } catch (Exception e) {e.printStackTrace();}
206         }
207
208         pmvMatrix = new PMVMatrix();
209
210         initShader(gl);
211
212         // Push the 1st uniform down the path 
213         st.useProgram(gl, true);
214
215         pmvMatrix.glMatrixMode(pmvMatrix.GL_PROJECTION);
216         pmvMatrix.glLoadIdentity();
217         pmvMatrix.glMatrixMode(pmvMatrix.GL_MODELVIEW);
218         pmvMatrix.glLoadIdentity();
219
220         if(!st.uniform(gl, new GLUniformData("mgl_PMVMatrix", 4, 4, pmvMatrix.glGetPMvMatrixf()))) {
221             throw new GLException("Error setting PMVMatrix in shader: "+st);
222         }
223         // Allocate vertex arrays
224         GLArrayDataClient vertices = GLArrayDataClient.createGLSL("mgl_Vertex", 3, gl.GL_FLOAT, false, 4);
225         {
226             // Fill them up
227             FloatBuffer verticeb = (FloatBuffer)vertices.getBuffer();
228             verticeb.put(-2);  verticeb.put(  2);  verticeb.put( 0);
229             verticeb.put( 2);  verticeb.put(  2);  verticeb.put( 0);
230             verticeb.put(-2);  verticeb.put( -2);  verticeb.put( 0);
231             verticeb.put( 2);  verticeb.put( -2);  verticeb.put( 0);
232         }
233         vertices.seal(gl, true);
234
235         GLArrayDataClient colors = GLArrayDataClient.createGLSL("mgl_Color",  4, gl.GL_FLOAT, false, 4);
236         {
237             // Fill them up
238             FloatBuffer colorb = (FloatBuffer)colors.getBuffer();
239             colorb.put( 1);    colorb.put( 0);     colorb.put( 0);    colorb.put( 1);
240             colorb.put( 0);    colorb.put( 0);     colorb.put( 1);    colorb.put( 1);
241             colorb.put( 1);    colorb.put( 0);     colorb.put( 0);    colorb.put( 1);
242             colorb.put( 1);    colorb.put( 0);     colorb.put( 0);    colorb.put( 1);
243         }
244         colors.seal(gl, true);
245         
246         // OpenGL Render Settings
247         gl.glClearColor(0, 0, 0, 1);
248         gl.glEnable(GL2ES2.GL_DEPTH_TEST);
249
250         st.useProgram(gl, false);
251
252         // Let's show the completed shader state ..
253         System.out.println(Thread.currentThread()+" "+st);
254     }
255
256     public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
257         if(null==st) return;
258
259         GL2ES2 gl = drawable.getGL().getGL2ES2();
260
261         st.useProgram(gl, true);
262
263         // Set location in front of camera
264         pmvMatrix.glMatrixMode(pmvMatrix.GL_PROJECTION);
265         pmvMatrix.glLoadIdentity();
266         pmvMatrix.gluPerspective(45.0f, (float)width / (float)height, 1.0f, 100.0f);
267         //pmvMatrix.glOrthof(-4.0f, 4.0f, -4.0f, 4.0f, 1.0f, 100.0f);
268
269         GLUniformData ud = st.getUniform("mgl_PMVMatrix");
270         if(null!=ud) {
271             // same data object
272             st.uniform(gl, ud);
273         } 
274
275         st.useProgram(gl, false);
276     }
277
278     public void dispose(GLAutoDrawable drawable) {
279         if(null==st) return;
280
281         GL2ES2 gl = drawable.getGL().getGL2ES2();
282         System.out.println(Thread.currentThread()+" RedSquare.dispose: "+gl.getContext());
283
284         st.destroy(gl);
285         st=null;
286         pmvMatrix.destroy();
287         pmvMatrix=null;
288         System.out.println(Thread.currentThread()+" RedSquare.dispose: FIN");
289     }
290
291     public void display(GLAutoDrawable drawable) {
292         if(null==st) return;
293
294         GL2ES2 gl = drawable.getGL().getGL2ES2();
295
296         st.useProgram(gl, true);
297
298         gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT);
299
300         // One rotation every four seconds
301         pmvMatrix.glMatrixMode(pmvMatrix.GL_MODELVIEW);
302         pmvMatrix.glLoadIdentity();
303         pmvMatrix.glTranslatef(0, 0, -10);
304         float ang = ((float) window.getTotalFPSDuration() * 360.0f) / 4000.0f;
305         pmvMatrix.glRotatef(ang, 0, 0, 1);
306         pmvMatrix.glRotatef(ang, 0, 1, 0);
307
308         GLUniformData ud = st.getUniform("mgl_PMVMatrix");
309         if(null!=ud) {
310             // same data object
311             st.uniform(gl, ud);
312         } 
313
314         // Draw a square
315         gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, 4);
316
317         st.useProgram(gl, false);
318     }
319
320     public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
321     }
322
323     public static int USE_NEWT      = 0;
324     public static int USE_AWT       = 1 << 0;
325
326     public static boolean oneThread = false;
327     public static int swapInterval = -1;
328     public static boolean debuggl = false;
329
330     public static void main(String[] args) {
331         NewtFactory.setUseEDT(true); // should be the default
332         int type = USE_NEWT ;
333         List threads = new ArrayList();
334         for(int i=0; i<args.length; i++) {
335             if(args[i].equals("-swapi")) {
336                 i++;
337                 try {
338                     swapInterval = Integer.parseInt(args[i]);
339                 } catch (Exception ex) { ex.printStackTrace(); }
340             } else if(args[i].equals("-debug")) {
341                 debuggl=true;
342             } else if(args[i].equals("-1thread")) {
343                 oneThread=true;
344             } else if(args[i].equals("-awt")) {
345                 type |= USE_AWT; 
346             } else if(args[i].startsWith("-GL")) {
347                 threads.add(new RedSquare(args[i].substring(1), type));
348             }
349         }
350         if(threads.size()==0) {
351             threads.add(new RedSquare(GLProfile.GL2ES2, type));
352         }
353
354         if(!oneThread) {
355             for(Iterator i = threads.iterator(); i.hasNext(); ) {
356                 ((Thread)i.next()).start();
357             }
358
359             boolean done = false;
360
361             while(!done) {
362                 int aliveCount = 0;
363                 for(Iterator i = threads.iterator(); i.hasNext(); ) {
364                     if ( ((Thread)i.next()).isAlive() ) {
365                         try {
366                             Thread.sleep(100);
367                         } catch (InterruptedException ie) {}
368                         aliveCount++;
369                     }
370                 }
371                 done = 0==aliveCount ;
372             }
373         } else {
374             // init all ..
375             for(Iterator i = threads.iterator(); i.hasNext(); ) {
376                 ((Thread)i.next()).run();
377             }
378             while (threads.size()>0) {
379                 for(Iterator i = threads.iterator(); i.hasNext(); ) {
380                     RedSquare app = (RedSquare) i.next();
381                     if(app.shouldQuit()) {
382                         app.shutdown();
383                         i.remove();
384                     } else {
385                         app.display();
386                     }
387                 }
388             }
389         }
390     }
391 }
http://JogAmp.org git info: FAQ, tutorial and man pages.