Hi
Can anyone explain why the JOGL program pasted at the bottom runs fine on my desktop but throws shader compile and link exceptions on my laptop?
My desktop is running WinXP-64 with an NVIDIA Quadro FX1400, which supports OpenGL2 but accepts the 330 shader version. The program throws no exceptions and runs as expected. I also still don’t fully understand how an OpenGL2 card can accept a shader verion of 330, which apears to contradict the Table on Wikipedia: http://en.wikipedia.org/wiki/GLSL.
The program throws shader compile and program link exceptions on my Win7-64 laptop with an ATI Mobility Radeon HD 5470 [version 8.672.1.3000], which from the following spec website supports OpenGL 3.2:
http://www.amd.com/uk/products/notebook/graphics/ati-mobility-hd-5400/Pages/hd-5450-specs.aspx
On both machines I’m using the same jars/dlls from the most recent JOGL download at www.jogamp.org.
Thanks
Graham
===
package modern_gl_prog;
// java
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.Canvas;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.charset.Charset;
// gl
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GL3;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;
import com.jogamp.common.nio.Buffers;
/**
-
Java port of JL McKesson’s tut1.cpp tutorial; Tutorial 0.3.7\Tut 01 Hello triangle
-
@author gmseed
*/
public class tut1 extends JFrame
{
private JPanel contentPane;
private Canvas canvas;static { GLProfile.initSingleton(true); } // recommended first call
/**
- Launch the application.
*/
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
try
{
tut1 frame = new tut1();
frame.setVisible(true);
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
}
/**
-
Create the frame.
*/
public tut1()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 545, 536);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);// OpenGL 2.1 profile
GLProfile prof = GLProfile.get(GLProfile.GL2);
GLCapabilities caps = new GLCapabilities(prof);
canvas = new tut1Canvas(caps);
canvas.setBounds(0, 0, 517, 390);
contentPane.add(canvas);
}
} // class tut1
- Launch the application.
class tut1Canvas extends GLCanvas
implements GLEventListener
{
protected int mTheProgram; // handle to program object
protected int mPositionBufferObject; // handle to buffer object
protected int mvao; // vertex array object
protected int mVertexCount = 3;
protected FloatBuffer mVertexPositions = null;
public tut1Canvas()
{
super();
this.addGLEventListener(this);
}
public tut1Canvas(GLCapabilities caps)
{
super(caps);
this.addGLEventListener(this);
}
private int createShader(GL2 gl, int eShaderType, String strShaderFile)
{
int shader = gl.glCreateShader(eShaderType);
String[] strings = new String[1]; strings[0] = strShaderFile;
gl.glShaderSource(shader, 1, strings,(int[])null,0); // glShaderSource(int shader, int count, java.lang.String[] string, int[] length, int length_offset);
gl.glCompileShader(shader);
int[] statusArray = new int[1];
int status;
gl.glGetShaderiv(shader, GL2.GL_COMPILE_STATUS, statusArray,0);
status = statusArray[0];
if (status == GL.GL_FALSE)
{
int[] infoLogLengthArray = new int[1];
int infoLogLength;
gl.glGetShaderiv(shader, GL2.GL_INFO_LOG_LENGTH,infoLogLengthArray,0);
infoLogLength = infoLogLengthArray[0];
IntBuffer intValue = IntBuffer.allocate(1);
ByteBuffer strInfoLog = Buffers.newDirectByteBuffer(infoLogLength);
gl.glGetShaderInfoLog(shader, infoLogLength, intValue, strInfoLog);
String strShaderType = null;
switch(eShaderType)
{
case GL2.GL_VERTEX_SHADER: strShaderType = "vertex"; break;
case GL3.GL_GEOMETRY_SHADER: strShaderType = "geometry"; break;
case GL2.GL_FRAGMENT_SHADER: strShaderType = "fragment"; break;
}
// decode byte buffer
String encoding = System.getProperty("file.encoding");
CharBuffer charBuff = Charset.forName(encoding).decode(strInfoLog);
String buffString = charBuff.toString();
String msg = "Compile failure in " + strShaderType + " shader: " + buffString;
System.out.println(msg);
}
return shader;
}
private int createProgram(GL2 gl, int[] shaderList)
{
int program = gl.glCreateProgram();
for(int iLoop = 0; iLoop < shaderList.length; iLoop++)
{
gl.glAttachShader(program, shaderList[iLoop]);
}
gl.glLinkProgram(program);
int[] statusArray = new int[1];
int status;
gl.glGetProgramiv(program,GL2.GL_LINK_STATUS,statusArray,0);
status = statusArray[0];
if (status == GL.GL_FALSE)
{
int[] infoLogLengthArray = new int[1];
int infoLogLength;
gl.glGetShaderiv(program, GL2.GL_INFO_LOG_LENGTH,infoLogLengthArray,0);
infoLogLength = infoLogLengthArray[0];
IntBuffer intValue = IntBuffer.allocate(1);
ByteBuffer strInfoLog = ByteBuffer.allocate(infoLogLength);
gl.glGetProgramInfoLog(program, infoLogLength, intValue, strInfoLog);
// decode byte buffer
String encoding = System.getProperty("file.encoding");
CharBuffer charBuff = Charset.forName(encoding).decode(strInfoLog);
String buffString = charBuff.toString();
String msg = "Linker failure: " + buffString;
System.out.println(msg);
}
for(int iLoop = 0; iLoop < shaderList.length; iLoop++)
{
gl.glDetachShader(program, shaderList[iLoop]);
}
return program;
}
public String strVertexShader()
{
String s = new String();
s += "#version 340
";
s += "layout(location = 0) in vec4 position;
";
s += "void main()
";
s += "{
";
s += " gl_Position = position;
";
s += "}
";
return s;
}
public String strFragmentShader()
{
String s = new String();
s += "#version 340
";
s += "out vec4 outputColor;
";
s += "void main()
";
s += "{
";
s += " outputColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);
";
s += "}
";
return s;
};
void initializeProgram(GL2 gl)
{
String vertexShaderString = strVertexShader();
String fragmentShaderString = strFragmentShader();
int vertexShader = createShader(gl,GL2.GL_VERTEX_SHADER,vertexShaderString);
int fragmentShader = createShader(gl,GL2.GL_FRAGMENT_SHADER,fragmentShaderString);
int[] shaderList = new int[2];
shaderList[0] = vertexShader;
shaderList[1] = fragmentShader;
mTheProgram = createProgram(gl,shaderList);
}
void initializeVertexBuffer(GL2 gl)
{
int[] array = new int[1];
gl.glGenBuffers(1, array, 0);
mPositionBufferObject = array[0];
// allocate vertex buffer [4 for (x,y,z,w) for each vertex]
mVertexPositions = Buffers.newDirectFloatBuffer(4*mVertexCount);
mVertexPositions.put(0.75f); mVertexPositions.put(0.75f); mVertexPositions.put(0.75f); mVertexPositions.put(1.0f);
mVertexPositions.put(0.75f); mVertexPositions.put(-0.75f); mVertexPositions.put(0.0f); mVertexPositions.put(1.0f);
mVertexPositions.put(-0.75f); mVertexPositions.put(-0.75f); mVertexPositions.put(0.0f); mVertexPositions.put(1.0f);
// invoke this method to prepare for a sequence of channel-write or relative get operations
mVertexPositions.flip();
gl.glBindBuffer(GL2.GL_ARRAY_BUFFER,mPositionBufferObject);
gl.glBufferData(GL2.GL_ARRAY_BUFFER,4*mVertexCount*Buffers.SIZEOF_FLOAT,mVertexPositions,GL2.GL_STATIC_DRAW);
gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0);
}
@Override
public void init(GLAutoDrawable gLDrawable)
{
GL2 gl = gLDrawable.getGL().getGL2();
initializeProgram(gl);
initializeVertexBuffer(gl);
// generate vertex array and bind
int[] array = new int[1];
gl.glGenVertexArrays(1,array,0);
mvao = array[0];
gl.glBindVertexArray(mvao);
}
@Override
public void display(GLAutoDrawable gLDrawable)
{
final GL2 gl = gLDrawable.getGL().getGL2();
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
gl.glClear(GL.GL_COLOR_BUFFER_BIT);
gl.glUseProgram(mTheProgram);
gl.glBindBuffer(GL2.GL_ARRAY_BUFFER,mPositionBufferObject);
gl.glEnableVertexAttribArray(0); // GL2ES2
gl.glVertexAttribPointer(0, 4, GL.GL_FLOAT,false, 0, 0);
gl.glDrawArrays(GL.GL_TRIANGLES, 0, 3);
gl.glDisableVertexAttribArray(0);
gl.glUseProgram(0);
gLDrawable.swapBuffers();
}
@Override
public void reshape(GLAutoDrawable gLDrawable, int x, int y, int width, int height)
{
GL2 gl = gLDrawable.getGL().getGL2();
if (height <= 0)
{
height = 1;
}
gl.glViewport(0,0,width,height);
}
@Override
public void dispose(GLAutoDrawable arg0)
{
// do nothing
}
} // class tut1Canvas