Hi
I was trying to build a Java port of the Hello, Triangle! tut1.cpp example at:
It fails at the linking stage in createProgram() with “status” equal to 0.
Does anyone know why?
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.FloatBuffer;
import java.nio.IntBuffer;
// 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.GLEventListener;
import javax.media.opengl.awt.GLCanvas;
import com.jogamp.common.nio.Buffers;
public class tut1 extends JFrame
{
private JPanel contentPane;
private Canvas canvas;
/**
* 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);
canvas = new tut1Canvas();
canvas.setBounds(0, 0, 517, 390);
contentPane.add(canvas);
}
} // class tut1
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);
}
/*
private void checkLogInfo(GL gl, int programObject) {
IntBuffer intValue = BufferUtils.newIntBuffer(1);
gl.glGetObjectParameterivARB(programObject, GL.GL_OBJECT_INFO_LOG_LENGTH_ARB, intValue);
int lengthWithNull = intValue.get();
if (lengthWithNull <= 1) {
return;
}
ByteBuffer infoLog = BufferUtils.newByteBuffer(lengthWithNull);
intValue.flip();
gl.glGetInfoLogARB(programObject, lengthWithNull, intValue, infoLog);
int actualLength = intValue.get();
byte[] infoBytes = new byte[actualLength];
infoLog.get(infoBytes);
System.out.println("GLSL Validation >> " + new String(infoBytes));
}*/
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); // public void 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 + 1);
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;
}
System.out.println("Compile failure in " + strShaderType + " shader: " + strInfoLog);
}
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);
//gl.glValidateProgram(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 + 1);
gl.glGetProgramInfoLog(program, infoLogLength, intValue, strInfoLog);
System.out.println("Linker failure: " + strInfoLog);
}
for(int iLoop = 0; iLoop < shaderList.length; iLoop++)
{
gl.glDetachShader(program, shaderList[iLoop]);
}
return program;
}
public String strVertexShader()
{
String s = new String();
s += "#version 330
";
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 330
";
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_VERTEX_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 [3 for (x,y,z,w) for each vertex]
mVertexPositions = FloatBuffer.allocate(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);
gl.glBindBuffer(GL2.GL_ARRAY_BUFFER,mPositionBufferObject);
gl.glBufferData(GL2.GL_ARRAY_BUFFER,3*mVertexCount,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.glUseProgram(mTheProgram);
gl.glBindBuffer(GL2.GL_ARRAY_BUFFER,mPositionBufferObject);
gl.glEnableVertexAttribArray(0);
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