1 /**
2  * Copyright 2011 JogAmp Community. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification, are
5  * permitted provided that the following conditions are met:
6  *
7  *    1. Redistributions of source code must retain the above copyright notice, this list of
8  *       conditions and the following disclaimer.
9  *
10  *    2. Redistributions in binary form must reproduce the above copyright notice, this list
11  *       of conditions and the following disclaimer in the documentation and/or other materials
12  *       provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  * The views and conclusions contained in the software and documentation are those of the
25  * authors and should not be interpreted as representing official policies, either expressed
26  * or implied, of JogAmp Community.
27  */
28 
29 package com.jogamp.opengl.test.junit.jogl.awt;
30 
31 import java.awt.event.WindowAdapter;
32 import java.awt.event.WindowEvent;
33 import java.awt.image.BufferedImage;
34 import java.lang.reflect.InvocationTargetException;
35 
36 import com.jogamp.opengl.GL;
37 import com.jogamp.opengl.GL2;
38 import com.jogamp.opengl.GLAutoDrawable;
39 import com.jogamp.opengl.GLCapabilities;
40 import com.jogamp.opengl.GLDrawableFactory;
41 import com.jogamp.opengl.GLEventListener;
42 import com.jogamp.opengl.GLOffscreenAutoDrawable;
43 import com.jogamp.opengl.GLProfile;
44 import javax.swing.ImageIcon;
45 import javax.swing.JFrame;
46 import javax.swing.JLabel;
47 
48 import org.junit.Assert;
49 import org.junit.Test;
50 import org.junit.FixMethodOrder;
51 import org.junit.runners.MethodSorters;
52 
53 import com.jogamp.opengl.test.junit.util.UITestCase;
54 import com.jogamp.opengl.util.awt.AWTGLReadBufferUtil;
55 
56 /**
57  * Tests for bug 461, a failure of PBuffer GLDrawableFactory.createOffscreenAutoDrawable(..) on Windows
58  * when the stencil buffer is turned on.
59  *
60  * @author Wade Walker (from code sample provided by Owen Dimond), et al.
61  */
62 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
63 public class TestBug461PBufferSupersamplingSwingAWT extends UITestCase implements GLEventListener {
64     JFrame jframe;
65     GLOffscreenAutoDrawable offScreenBuffer;
66     AWTGLReadBufferUtil screenshot;
67 
render(final GLAutoDrawable drawable)68     private void render(final GLAutoDrawable drawable) {
69         final GL2 gl = drawable.getGL().getGL2();
70         Assert.assertNotNull(gl);
71         gl.glClear(GL.GL_COLOR_BUFFER_BIT);
72 
73         // draw a triangle filling the window
74         gl.glBegin(GL.GL_TRIANGLES);
75         gl.glColor3f(1, 0, 0);
76         gl.glVertex2d(-1, -1);
77         gl.glColor3f(0, 1, 0);
78         gl.glVertex2d(0, 1);
79         gl.glColor3f(0, 0, 1);
80         gl.glVertex2d(1, -1);
81         gl.glEnd();
82     }
83 
84     /* @Override */
init(final GLAutoDrawable drawable)85     public void init(final GLAutoDrawable drawable) {
86         screenshot = new AWTGLReadBufferUtil(drawable.getGLProfile(), false);
87     }
88 
89     /* @Override */
reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height)90     public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {
91     }
92 
93     /* @Override */
display(final GLAutoDrawable drawable)94     public void display(final GLAutoDrawable drawable) {
95         render(offScreenBuffer);
96         final BufferedImage outputImage = screenshot.readPixelsToBufferedImage(drawable.getGL(), 0, 0, 200, 200, true /* awtOrientation */);
97         Assert.assertNotNull(outputImage);
98         final ImageIcon imageIcon = new ImageIcon(outputImage);
99         final JLabel imageLabel = new JLabel(imageIcon);
100         jframe.getContentPane().add(imageLabel);
101     }
102 
103     /* @Override */
dispose(final GLAutoDrawable drawable)104     public void dispose(final GLAutoDrawable drawable) {
105         screenshot.dispose(drawable.getGL());
106         try {
107             javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
108                 public void run() {
109                     jframe.setVisible(false);
110                     jframe.dispose();
111                 }});
112         } catch (final Exception e) {
113             e.printStackTrace();
114         }
115     }
116 
117     @Test
test01DefaultOffscreenSupersampling()118     public void test01DefaultOffscreenSupersampling() throws InterruptedException, InvocationTargetException {
119         final GLProfile glp = GLProfile.get(GLProfile.GL2);
120         Assert.assertNotNull(glp);
121         final GLCapabilities glCap = new GLCapabilities(glp);
122         test(glCap);
123     }
124 
125     @Test
test02PBufferOffscreenSupersampling()126     public void test02PBufferOffscreenSupersampling() throws InterruptedException, InvocationTargetException {
127         final GLProfile glp = GLProfile.get(GLProfile.GL2);
128         Assert.assertNotNull(glp);
129         final GLCapabilities glCap = new GLCapabilities(glp);
130         glCap.setPBuffer(true);
131         test(glCap);
132     }
133 
test(final GLCapabilities glCap)134     void test(final GLCapabilities glCap) throws InterruptedException, InvocationTargetException {
135         jframe = new JFrame("Offscreen Supersampling");
136         Assert.assertNotNull(jframe);
137         jframe.setSize( 300, 300);
138         jframe.addWindowListener(new WindowAdapter() {
139             public void windowClosing(final WindowEvent e) {
140                 System.exit(0);
141             }
142         });
143 
144         final GLDrawableFactory fac = GLDrawableFactory.getFactory(glCap.getGLProfile());
145         Assert.assertNotNull(fac);
146 
147         // COMMENTING OUT THIS LINE FIXES THE ISSUE.
148         // Setting this in JOGL1 works. Thus this is a JOGL2 issue.
149         glCap.setSampleBuffers(true);
150         glCap.setNumSamples(4);
151 
152         // Without line below, there is an error on Windows.
153         glCap.setDoubleBuffered(false);
154         // Needed for drop shadows
155         glCap.setStencilBits(1);
156 
157         //makes a new buffer
158         offScreenBuffer = fac.createOffscreenAutoDrawable(null, glCap, null, 200, 200);
159         Assert.assertNotNull(offScreenBuffer);
160         offScreenBuffer.addGLEventListener(this);
161         offScreenBuffer.display();
162         javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
163             public void run() {
164                 jframe.setVisible(true);
165             }});
166         offScreenBuffer.destroy();
167     }
168 
main(final String args[])169     public static void main(final String args[]) {
170         org.junit.runner.JUnitCore.main(TestBug461PBufferSupersamplingSwingAWT.class.getName());
171     }
172 }
173 
174