I have some code that draws squares by passing points through a geometry shader. I construct an array which is sequences of 3 floats, bind that to the in vec3 vert
attribute of my vertex shader, and everything is fine.
However, I want to add another float which the fragment shader will use to calculate color. This is in the vertex shader (to pass through) as in float val
. Despite being able to find vert
, glGetAttribLocation
can't find val
(get_program_attrib(): Atrrib val not found (-1)
).
Code:
void load_model(GLuint* vao, GLuint* vbo) {
glGenVertexArrays(1, vao);
glBindVertexArray(*vao);
glGenBuffers(1, vbo);
glBindBuffer(GL_ARRAY_BUFFER, *vbo);
float data[SQUARES_PER_AXIS_SQ * 4] = {0};
squares_count = 0;
for (int i = 0; i < SQUARES_PER_AXIS_SQ; i++) {
int x_pos = i % SQUARES_PER_AXIS;
int y_pos = i / SQUARES_PER_AXIS;
if (fabs(squares[i]) > 0.0) {
data[squares_count * 4 + 0] = x_pos / ((float)SQUARES_PER_AXIS) * 2 - 1;
data[squares_count * 4 + 1] = (SQUARES_PER_AXIS - y_pos) / ((float)SQUARES_PER_AXIS) * 2 - 1;
data[squares_count * 4 + 2] = 0.5f;
data[squares_count * 4 + 3] = (float)squares[i];
squares_count++;
}
}
DPRINT("Loaded %d squares\n", squares_count);
glBufferData(GL_ARRAY_BUFFER, squares_count * 4 * sizeof(float), data, GL_STATIC_DRAW);
glEnableVertexAttribArray(get_program_attrib(main_shader, "vert"));
glEnableVertexAttribArray(get_program_attrib(main_shader, "val"));
glVertexAttribPointer(get_program_attrib(main_shader, "vert"), 3, GL_FLOAT, GL_FALSE, 4, NULL);
glVertexAttribPointer(get_program_attrib(main_shader, "val"), 1, GL_FLOAT, GL_FALSE, 4, (float*)(3 * sizeof(float)));
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
GLuint get_program_attrib(program_t* prog, GLchar* name) {
if (!name) {
DPRINT("ERROR: name == NULL\n");
return -1;
}
GLint attrib = glGetAttribLocation(prog->id, name);
if (attrib < 0)
DPRINT("Atrrib %s not found (%d)\n", name, attrib);
return attrib;
}
Vertex shader:
#version 150
in vec3 vert;
in float val;
out float value;
void main() {
gl_Position = vec4(vert, 1);
value = val;
}
Fragment shader:
#version 150
in float value;
out vec4 color;
void main() {
color = vec4(value, 0, 0, 1);
}
Geometry shader:
#version 150
layout (points) in;
layout (triangle_strip, max_vertices=4) out;
uniform float square_size;
void main() {
vec4 position = gl_in[0].gl_Position;
gl_Position = vec4(position.x, position.y, position.zw);
EmitVertex();
gl_Position = vec4(position.x, position.y + square_size, position.zw);
EmitVertex();
gl_Position = vec4(position.x + square_size, position.y, position.zw);
EmitVertex();
gl_Position = vec4(position.x + square_size, position.y + square_size, position.zw);
EmitVertex();
EndPrimitive();
}
value
, which is based onval
. If it is not attached, thenval
is not an active attribute.vert
, on the other hand, is used to assigngl_Position
; anything used to computegl_Position
will be active no matter what the contents of your fragment shader looks like.gl_Position
togl_Position = vec4 (vert, val)
does that change anything? I still think the problem is to do with your fragment shader.value
through?