I am using Mesa 10.1.3 to be able to use OpenGL 3.3 on my Linux computer. I request a core profile when I create the window since only the core profile has OpenGL 3.3. But when I tried to write a simple program to display a triangle on the screen, I got nothing. So I thought I screwed up somewhere in the code but I rechecked it and it was correct. To test this, I tried running the program in Windows and it was working as it should. So I experimented a little bit more with the code; I multiplied the vertex location in the vertex shader by 0.001 and only then I was able to see my triangle, but even then, it was not working as it should. The triangle I see was a right angle triangle whereas I intended it to be an equilateral one (in Windows I see an equilateral triangle). So my guess is vertex location is somehow different when using OpenGL Core profile, but I don't quite know how to fix this. What am I doing wrong and what should I be doing?
By the way, this is my vertex shader looks like:
#version 330
in vec3 position;
void main()
{
gl_Position = vec4(0.001*position, 1.0);
}
Fragment shader:
#version 330
out vec4 fragColor;
void main()
{
fragColor = vec4(0.0, 1.0, 1.0, 1.0);
}
Shader class:
public Shader()
{
program = glCreateProgram();
if(program == 0)
{
System.err.println("Shader creation failed: Could not find valid memory location");
System.exit(1);
}
}
public void bind()
{
glBindAttribLocation(program, 0, "position");
glUseProgram(program);
}
public void addVertexShader(String text)
{
addProgram(text, GL_VERTEX_SHADER);
}
public void addFragmentShader(String text)
{
addProgram(text, GL_FRAGMENT_SHADER);
}
public void addGeometryShader(String text)
{
addProgram(text, GL_GEOMETRY_SHADER);
}
public void compile()
{
glLinkProgram(program);
if(glGetProgrami(program, GL_LINK_STATUS) == 0)
{
System.err.println(glGetProgramInfoLog(program, 1024));
System.exit(1);
}
glValidateProgram(program);
if(glGetProgrami(program, GL_VALIDATE_STATUS) == 0)
{
System.err.println(glGetProgramInfoLog(program, 1024));
System.exit(1);
}
}
public void addProgram(String text, int type)
{
int shader = glCreateShader(type);
if(shader == 0)
{
System.err.println("Shader creation failed");
System.exit(1);
}
glShaderSource(shader, text);
glCompileShader(shader);
if(glGetShaderi(shader, GL_COMPILE_STATUS) == 0)
{
System.err.println(glGetShaderInfoLog(shader, 1024));
System.exit(1);
}
glAttachShader(program, shader);
}
And my array of vertices which I'm creating the VBO with:
Vertex[] data = new Vertex[] {
new Vertex(new Vector3f(-0.1f, -0.1f, 0)),
new Vertex(new Vector3f(0, 1, 0)),
new Vertex(new Vector3f( 1, -1, 0))};
My draw method:
public void draw()
{
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
//Vertex is a class which only holds a Vector3f for position, currently, so size is set to 3
glVertexAttribPointer(0, 3, GL_FLOAT, false, Vertex.SIZE * 4, 0);
glDrawArrays(GL_TRIANGLES, 0, size);
glDisableVertexAttribArray(0);
}
And this is the result that I'm getting:
Your
glBindAttribLocation()
call comes too late:glBindAttribLocation()
needs to be called before theglLinkProgram()
to have any effect. You can move it, or useglGetAttribLocation()
after linking to get the location that the linker assigned to the attribute. Or even easier, since you use GLSL 3.30, you can specify the location in the shader code:When using the Core Profile, you will also need to use Vertex Array Objects (VAO). If you don't have calls like
glGenVertexArrays()
andglBindVertexArray()
in your code, you will need those. There should be plenty of examples here on SO or on the rest of the internet if you search for "OpenGL VAO" or "OpenGL Vertex Array Object", so I won't repeat too much of it. Roughly, you will have something like this before you start initializing your vertex state:Then when you get ready to draw:
Your vertex data definition also looks like it could be a source of trouble:
While the code for filling this into the VBO is not shown, the data passed to
glBufferData()
needs to be a flat, contiguous array/buffer of floats, while this is an array of vector object references.