package com.jogamp.opengl.test.junit.jogl.glsl; import com.jogamp.opengl.test.junit.util.NEWTGLContext; import com.jogamp.opengl.test.junit.util.UITestCase; import java.io.ByteArrayOutputStream; import java.io.PrintStream; import com.jogamp.opengl.GL; import com.jogamp.opengl.GL2ES2; import com.jogamp.opengl.GL2ES3; import com.jogamp.opengl.GL3; import com.jogamp.opengl.GLCapabilities; import com.jogamp.opengl.GLException; import com.jogamp.opengl.GLProfile; import org.junit.Assert; import org.junit.Test; import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters; import com.jogamp.opengl.util.glsl.ShaderUtil; import java.io.IOException; /** * Bug 'Function glTransformFeedbackVaryings incorrectly passes argument' * http://jogamp.org/bugzilla/show_bug.cgi?id=407 */ @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class TestTransformFeedbackVaryingsBug407NEWT extends UITestCase { private static final boolean debugGL = true; private static final String VERTEX_SHADER_TEXT = "#version 150 \n" + " \n" + "out vec4 Position; \n" + " \n" + "void main() { \n" + " Position = vec4(1.0, 1.0, 1.0, 1.0); \n" + "} \n"; static class MyShader { int shaderProgram; int vertShader; MyShader(final int shaderProgram, final int vertShader) { this.shaderProgram = shaderProgram; this.vertShader = vertShader; } } private MyShader attachShader(final GL3 gl, final String text, final int type) { final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final PrintStream pbaos = new PrintStream(baos); final int shaderProgram = gl.glCreateProgram(); final int vertShader = gl.glCreateShader(type); final String[] lines = new String[]{text}; final int[] lengths = new int[]{lines[0].length()}; gl.glShaderSource(vertShader, lines.length, lines, lengths, 0); gl.glCompileShader(vertShader); if(!ShaderUtil.isShaderStatusValid(gl, vertShader, GL2ES2.GL_COMPILE_STATUS, pbaos)) { System.out.println("getShader:postCompile: "+baos.toString()); Assert.assertTrue(false); } pbaos.flush(); baos.reset(); gl.glAttachShader(shaderProgram, vertShader); Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError()); return new MyShader(shaderProgram, vertShader); } private void releaseShader(final GL3 gl, final MyShader myShader) { if(null!=myShader) { gl.glDetachShader(myShader.shaderProgram, myShader.vertShader); gl.glDeleteShader(myShader.vertShader); gl.glDeleteProgram(myShader.shaderProgram); } Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError()); } final static String glps = GLProfile.GL3; private NEWTGLContext.WindowContext prepareTest() throws GLException, InterruptedException { final NEWTGLContext.WindowContext winctx = NEWTGLContext.createWindow( new GLCapabilities(GLProfile.getMaxProgrammable(true)), 480, 480, debugGL); if(!winctx.context.getGL().isGL3()) { System.err.println("GL3 not available"); cleanupTest(winctx); return null; } Assert.assertEquals(GL.GL_NO_ERROR, winctx.context.getGL().glGetError()); return winctx; } private void cleanupTest(final NEWTGLContext.WindowContext winctx) { if(null!=winctx) { NEWTGLContext.destroyWindow(winctx); } } @Test(timeout=60000) public void testGlTransformFeedbackVaryings_WhenVarNameOK() throws GLException, InterruptedException { final NEWTGLContext.WindowContext winctx = prepareTest(); if(null == winctx) { return; } final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final PrintStream pbaos = new PrintStream(baos); // given final GL3 gl = winctx.context.getGL().getGL3(); Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError()); final MyShader myShader = attachShader(gl, VERTEX_SHADER_TEXT, GL2ES2.GL_VERTEX_SHADER); final String[] vars = new String[]{"Position"}; // when gl.glTransformFeedbackVaryings(myShader.shaderProgram, 1, vars, GL2ES3.GL_SEPARATE_ATTRIBS); gl.glLinkProgram(myShader.shaderProgram); Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError()); // then boolean error = false; if(!ShaderUtil.isProgramLinkStatusValid(gl, myShader.shaderProgram, pbaos)) { System.out.println("Error (unexpected link error) - testGlTransformFeedbackVaryings_WhenVarNameOK:postLink: "+baos.toString()); error = true; } pbaos.flush(); baos.reset(); Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError()); releaseShader(gl, myShader); cleanupTest(winctx); Assert.assertFalse(error); } @Test(timeout=60000) public void testGlTransformFeedbackVaryings_WhenVarNameWrong() throws GLException, InterruptedException { final NEWTGLContext.WindowContext winctx = prepareTest(); if(null == winctx) { return; } final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final PrintStream pbaos = new PrintStream(baos); // given final GL3 gl = winctx.context.getGL().getGL3(); Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError()); final MyShader myShader = attachShader(gl, VERTEX_SHADER_TEXT, GL2ES2.GL_VERTEX_SHADER); final String[] vars = new String[]{"PPPosition"}; // when gl.glTransformFeedbackVaryings(myShader.shaderProgram, 1, vars, GL2ES3.GL_SEPARATE_ATTRIBS); gl.glLinkProgram(myShader.shaderProgram); // then boolean error = false; if(!ShaderUtil.isProgramLinkStatusValid(gl, myShader.shaderProgram, pbaos)) { System.out.println("GOOD (expected link error) - testGlTransformFeedbackVaryings_WhenVarNameWrong:postLink: "+baos.toString()); // should be invalid, due to wrong var name } else { // oops System.out.println("Error (unexpected link success) - testGlTransformFeedbackVaryings_WhenVarNameWrong link worked, but it should not"); error = true; } pbaos.flush(); baos.reset(); Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError()); releaseShader(gl, myShader); cleanupTest(winctx); Assert.assertFalse(error); } public static void main(final String args[]) throws IOException { final String tstname = TestTransformFeedbackVaryingsBug407NEWT.class.getName(); org.junit.runner.JUnitCore.main(tstname); } }