0

I have a uniform variable called control_count (count of the control points in a bezier curve). In the marked part in my code, if I replace the constant 4 with this variable, it's just stops working, if it's 4 it's working fine. The variable must have the value 4 in it, I tested it before and after the loop as well, I marked this in the code too. It should be an unrolling problem? How do I force the compiler not to do this?

#version 150


layout(lines_adjacency) in;

layout(line_strip, max_vertices = 101) out;

out vec4 gs_out_col; 

uniform mat4 MVP;
uniform int control_count;
uniform int tess_count;

int degree;

int binom( int n, int k );

void main() 
{

degree = control_count - 1;

vec3 b[10];
float B[10];

////////////MARK//////////////////
//control_count must be 4, other ways it'd draw less points
for(int i = 0; i < control_count; ++i){
    b[i] = gl_in[i].gl_Position.xyz;
}
////////////END MARK//////////////////

for(int i = 0; i <= tess_count; ++i){
    float t = i / float(tess_count);

    gl_Position = vec4(0);

    ////////////MARK//////////////////
    //here, if I write control_count instead of 4, I don't get what I expect
    for(int j = 0; j < 4; ++j){         
    ////////////END MARK//////////////////
        B[j] = binom(3, j) * pow(1 - t, 3 - j) * pow(t, j);
        gl_Position += vec4(b[j] * B[j], B[j]);
    }

    gl_Position = MVP * gl_Position;

    ////////////MARK//////////////////
    //control_count - 4 --> I get red color,
    //control_count - 3 --> I get purple, 
    //so the variable must have the value 4
    gs_out_col = vec4(1, 0, control_count - 4, 1);//gl_Position;
    ////////////END MARK//////////////////

    EmitVertex();
}

}

The "good" result using the constant 4: enter image description here

The "wrong" result using the variable control_count: enter image description here

Ferenc Dajka
  • 1,052
  • 3
  • 17
  • 45
  • 1
    Realistically, there is not much benefit to unrolling a loop when you know nothing about the number of iterations at compile time (as is the case with the GLSL compiler when using a uniform for flow control). No, the actual problem here is the size of `gl_in [...]` when the input primitive is Line Adjacency; **4**. Assuming I understand your question correctly... – Andon M. Coleman May 13 '14 at 23:24
  • The real problem is that you're using the geometry shader to do tessellation, which is inefficient because the GPU cannot easily parallelize it. Use the OpenGL 4+ tessellation stages for better performance. – Colonel Thirty Two May 14 '14 at 00:34
  • @ColonelThirtyTwo: Good luck doing that in OpenGL 3.2 (GLSL 1.50) ;) – Andon M. Coleman May 14 '14 at 00:41
  • It's probably because an out of bounds read on gl_in. Also what does "not working" mean. Compile fail? Link fail? GL error? Just no rendering? – starmole May 14 '14 at 05:23
  • sorry I should be more precise, I updated my post with the "good" and the "wrong" result – Ferenc Dajka May 14 '14 at 07:56
  • Why do you want to make that into a `uniform` anyway? Your shader already hard-codes the size of `gl_in [...]` to **4** with this statement: `layout(lines_adjacency) in;`. Can you show your actual drawing code? I would be curious to see if you properly match the primitive type up. – Andon M. Coleman May 14 '14 at 22:19
  • because I have to make the application be able to change the number of the control points, the points coming from the vertex shader actually doesn't matter now, since I have a uniform array containing the coordinates of the control points. there are alway 8 control points passed to the geom shader, but I want to use only as many as the control_count variable counts, what can be changed by the user in the c++ app – Ferenc Dajka May 16 '14 at 14:15
  • @FerencDajka That will never work, you have already hard-coded the size of `gl_in` to **4**. Likewise, there is no primitive type that will feed the GS 8 points per-primitive, triangle adjacency only gets you 6. – Andon M. Coleman May 18 '14 at 00:16

0 Answers0