I am trying to render three points using array buffers, but I can't get anything rendered.
This is my code:
import java.nio.*;
import javax.media.opengl.*;
public class SimpleScene implements GLEventListener
{
private GL3 gl;
int myIdentityShader;
@Override
public void display(GLAutoDrawable drawable) {
gl.glClear(GL3.GL_COLOR_BUFFER_BIT);
gl.glUseProgram(myIdentityShader);
gl.glDrawArrays(GL3.GL_POINTS, 0, 3);
}
@Override
public void dispose(GLAutoDrawable drawable) {
gl.glDeleteProgram(myIdentityShader);
gl.glDeleteVertexArrays(1, vertexArrayObject, 0);
}
@Override
public void init(GLAutoDrawable drawable) {
gl = drawable.getGL().getGL3();
try {
myIdentityShader = createShaderProgram();
} catch (Exception e) {
e.printStackTrace();
return;
}
gl.glPointSize(30);
gl.glClearColor(0.7f, 0, 0, 1);
float[] floatData = {
0.25f, -0.25f, 0.5f, 1.0f,
-0.25f, -0.25f, 0.5f, 1.0f,
0.25f, 0.25f, 0.5f, 1.0f
};
FloatBuffer data = FloatBuffer.allocate(3 * 4);
for (int i=0;i<12;i++)
data.put(floatData[i]);
gl.glGenVertexArrays(1, vertexArrayObject, 0);
gl.glBindVertexArray(vertexArrayObject[0]);
int[] buffers = new int[1];
gl.glGenBuffers(1, buffers, 0);
gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, buffers[0]);
gl.glBufferData(GL3.GL_ARRAY_BUFFER, data.capacity(), data, GL3.GL_STATIC_DRAW);
gl.glVertexAttribPointer(2, 4, GL3.GL_FLOAT, false, 0, 0);
gl.glEnableVertexAttribArray(2);
}
@Override
public void reshape(GLAutoDrawable drawable, int arg1, int arg2, int arg3,
int arg4) {
// TODO Add reshape code
}
private String vertexShader = "#version 130 \n" +
"in vec4 position; \n" +
"void main(void) \n" +
"{ \n" +
" gl_Position = position; \n" +
"} \n";
private String fragmentShader = "#version 130 \n" +
"out vec4 vFragColor; \n" +
"void main(void) \n" +
"{ \n" +
" vFragColor = vec4(0.0, 0.8, 1.0, 1.0); \n" +
"} \n";
private int[] vertexArrayObject = new int[1];
private int createShaderProgram() throws Exception
{
int hVertexShader, hFragmentShader, hShaderProgram;
int[] successTest = new int[] {1};
hVertexShader = gl.glCreateShader(GL3.GL_VERTEX_SHADER);
hFragmentShader = gl.glCreateShader(GL3.GL_FRAGMENT_SHADER);
gl.glShaderSource(hVertexShader, 1, new String[] {vertexShader}, null);
gl.glShaderSource(hFragmentShader, 1, new String[] {fragmentShader}, null);
gl.glCompileShader(hVertexShader);
gl.glCompileShader(hFragmentShader);
gl.glGetShaderiv(hVertexShader, GL3.GL_COMPILE_STATUS, successTest, 0);
if (successTest[0] == 0)
{
byte[] infoLog = new byte[1024];
gl.glGetShaderInfoLog(hVertexShader, 1024, null, 0, infoLog, 0);
gl.glDeleteShader(hVertexShader);
gl.glDeleteShader(hFragmentShader);
throw new Exception("Vertex shader compilation failed with: " + new String(infoLog));
}
gl.glGetShaderiv(hFragmentShader, GL3.GL_COMPILE_STATUS, successTest, 0);
if (successTest[0] == 0)
{
byte[] infoLog = new byte[1024];
gl.glGetShaderInfoLog(hFragmentShader, 1024, null, 0, infoLog, 0);
gl.glDeleteShader(hVertexShader);
gl.glDeleteShader(hFragmentShader);
throw new Exception("Fragment shader compilation failed with: " + new String(infoLog));
}
hShaderProgram = gl.glCreateProgram();
gl.glAttachShader(hShaderProgram, hVertexShader);
gl.glAttachShader(hShaderProgram, hFragmentShader);
gl.glBindAttribLocation(hShaderProgram, 2, "position");
gl.glLinkProgram(hShaderProgram);
gl.glGetProgramiv(hShaderProgram, GL3.GL_LINK_STATUS, successTest, 0);
if (successTest[0] == 0)
{
byte[] infoLog = new byte[1024];
gl.glGetProgramInfoLog(hShaderProgram, 1024, null, 0, infoLog, 0);
gl.glDeleteProgram(hShaderProgram);
throw new Exception("Shader linking failed with: " + new String(infoLog);
}
gl.glDeleteShader(hVertexShader);
gl.glDeleteShader(hFragmentShader);
return hShaderProgram;
}
}
I am absolutely sure the shaders and the createShaderProgram method are correct. When I use glVertexAttrib4fv, all three points get rendered in the same location (as expected), but when I use glVertexAttribPointer nothing gets rendered and there’s no error (glGetError returns 0).
I discovered that glVertexAttrib4fv does not send the coordinates if the attribute index is 0, thus resulting in all points being rendered in the center of the screen. This doesn't happen with glVertexAttribPointer, so the coordinates are sent.