1 package com.jogamp.opengl.test.junit.jogl.glsl;
2 
3 import com.jogamp.opengl.test.junit.util.NEWTGLContext;
4 import com.jogamp.opengl.test.junit.util.UITestCase;
5 
6 import java.io.ByteArrayOutputStream;
7 import java.io.PrintStream;
8 
9 import com.jogamp.opengl.GL;
10 import com.jogamp.opengl.GL2ES2;
11 import com.jogamp.opengl.GL2ES3;
12 import com.jogamp.opengl.GL3;
13 import com.jogamp.opengl.GLCapabilities;
14 import com.jogamp.opengl.GLException;
15 import com.jogamp.opengl.GLProfile;
16 
17 import org.junit.Assert;
18 import org.junit.Test;
19 import org.junit.FixMethodOrder;
20 import org.junit.runners.MethodSorters;
21 
22 import com.jogamp.opengl.util.glsl.ShaderUtil;
23 
24 import java.io.IOException;
25 
26 /**
27  * Bug 'Function glTransformFeedbackVaryings incorrectly passes argument'
28  * http://jogamp.org/bugzilla/show_bug.cgi?id=407
29  */
30 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
31 public class TestTransformFeedbackVaryingsBug407NEWT extends UITestCase {
32 
33     private static final boolean debugGL = true;
34 
35     private static final String VERTEX_SHADER_TEXT =
36                   "#version 150                           \n"
37                 + "                                       \n"
38                 + "out vec4 Position;                     \n"
39                 + "                                       \n"
40                 + "void main() {                          \n"
41                 + "  Position = vec4(1.0, 1.0, 1.0, 1.0); \n"
42                 + "}                                      \n";
43 
44     static class MyShader {
45         int shaderProgram;
46         int vertShader;
47 
MyShader(final int shaderProgram, final int vertShader)48         MyShader(final int shaderProgram, final int vertShader) {
49             this.shaderProgram = shaderProgram;
50             this.vertShader = vertShader;
51         }
52     }
53 
attachShader(final GL3 gl, final String text, final int type)54     private MyShader attachShader(final GL3 gl, final String text, final int type) {
55         final ByteArrayOutputStream baos = new ByteArrayOutputStream();
56         final PrintStream pbaos = new PrintStream(baos);
57 
58         final int shaderProgram = gl.glCreateProgram();
59 
60         final int vertShader = gl.glCreateShader(type);
61 
62         final String[] lines = new String[]{text};
63         final int[] lengths = new int[]{lines[0].length()};
64         gl.glShaderSource(vertShader, lines.length, lines, lengths, 0);
65         gl.glCompileShader(vertShader);
66 
67         if(!ShaderUtil.isShaderStatusValid(gl, vertShader, GL2ES2.GL_COMPILE_STATUS, pbaos)) {
68             System.out.println("getShader:postCompile: "+baos.toString());
69             Assert.assertTrue(false);
70         }
71         pbaos.flush(); baos.reset();
72 
73         gl.glAttachShader(shaderProgram, vertShader);
74         Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
75 
76         return new MyShader(shaderProgram, vertShader);
77     }
78 
releaseShader(final GL3 gl, final MyShader myShader)79     private void releaseShader(final GL3 gl, final MyShader myShader) {
80         if(null!=myShader) {
81             gl.glDetachShader(myShader.shaderProgram, myShader.vertShader);
82             gl.glDeleteShader(myShader.vertShader);
83             gl.glDeleteProgram(myShader.shaderProgram);
84         }
85         Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
86     }
87 
88     final static String glps = GLProfile.GL3;
89 
prepareTest()90     private NEWTGLContext.WindowContext prepareTest() throws GLException, InterruptedException {
91         final NEWTGLContext.WindowContext winctx = NEWTGLContext.createWindow(
92                 new GLCapabilities(GLProfile.getMaxProgrammable(true)), 480, 480, debugGL);
93         if(!winctx.context.getGL().isGL3()) {
94             System.err.println("GL3 not available");
95             cleanupTest(winctx);
96             return null;
97         }
98         Assert.assertEquals(GL.GL_NO_ERROR, winctx.context.getGL().glGetError());
99         return winctx;
100     }
101 
cleanupTest(final NEWTGLContext.WindowContext winctx)102     private void cleanupTest(final NEWTGLContext.WindowContext winctx) {
103         if(null!=winctx) {
104             NEWTGLContext.destroyWindow(winctx);
105         }
106     }
107 
108     @Test(timeout=60000)
testGlTransformFeedbackVaryings_WhenVarNameOK()109     public void testGlTransformFeedbackVaryings_WhenVarNameOK() throws GLException, InterruptedException {
110         final NEWTGLContext.WindowContext winctx = prepareTest();
111         if(null == winctx) {
112             return;
113         }
114         final ByteArrayOutputStream baos = new ByteArrayOutputStream();
115         final PrintStream pbaos = new PrintStream(baos);
116 
117         // given
118 
119         final GL3 gl = winctx.context.getGL().getGL3();
120         Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
121 
122         final MyShader myShader = attachShader(gl, VERTEX_SHADER_TEXT, GL2ES2.GL_VERTEX_SHADER);
123         final String[] vars = new String[]{"Position"};
124 
125         // when
126 
127         gl.glTransformFeedbackVaryings(myShader.shaderProgram, 1, vars, GL2ES3.GL_SEPARATE_ATTRIBS);
128         gl.glLinkProgram(myShader.shaderProgram);
129         Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
130 
131         // then
132 
133         boolean error = false;
134 
135         if(!ShaderUtil.isProgramLinkStatusValid(gl, myShader.shaderProgram, pbaos)) {
136             System.out.println("Error (unexpected link error) - testGlTransformFeedbackVaryings_WhenVarNameOK:postLink: "+baos.toString());
137             error = true;
138         }
139         pbaos.flush(); baos.reset();
140         Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
141 
142         releaseShader(gl, myShader);
143         cleanupTest(winctx);
144         Assert.assertFalse(error);
145     }
146 
147     @Test(timeout=60000)
testGlTransformFeedbackVaryings_WhenVarNameWrong()148     public void testGlTransformFeedbackVaryings_WhenVarNameWrong() throws GLException, InterruptedException {
149         final NEWTGLContext.WindowContext winctx = prepareTest();
150         if(null == winctx) {
151             return;
152         }
153         final ByteArrayOutputStream baos = new ByteArrayOutputStream();
154         final PrintStream pbaos = new PrintStream(baos);
155 
156         // given
157 
158         final GL3 gl = winctx.context.getGL().getGL3();
159         Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
160 
161         final MyShader myShader = attachShader(gl, VERTEX_SHADER_TEXT, GL2ES2.GL_VERTEX_SHADER);
162         final String[] vars = new String[]{"PPPosition"};
163 
164         // when
165 
166         gl.glTransformFeedbackVaryings(myShader.shaderProgram, 1, vars, GL2ES3.GL_SEPARATE_ATTRIBS);
167         gl.glLinkProgram(myShader.shaderProgram);
168 
169         // then
170 
171         boolean error = false;
172 
173         if(!ShaderUtil.isProgramLinkStatusValid(gl, myShader.shaderProgram, pbaos)) {
174             System.out.println("GOOD (expected link error) - testGlTransformFeedbackVaryings_WhenVarNameWrong:postLink: "+baos.toString());
175             // should be invalid, due to wrong var name
176         } else {
177             // oops
178             System.out.println("Error (unexpected link success) - testGlTransformFeedbackVaryings_WhenVarNameWrong link worked, but it should not");
179             error = true;
180         }
181         pbaos.flush(); baos.reset();
182         Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
183 
184         releaseShader(gl, myShader);
185         cleanupTest(winctx);
186 
187         Assert.assertFalse(error);
188     }
189 
main(final String args[])190     public static void main(final String args[]) throws IOException {
191         final String tstname = TestTransformFeedbackVaryingsBug407NEWT.class.getName();
192         org.junit.runner.JUnitCore.main(tstname);
193     }
194 
195 }
196