1

I have got some issue with my glsl program, trying to render objects in post rendering. For it to work i need to pass a 2D array of structs to my fragment shader that i made in my vertex shader with other arrays. I am using Libgdx. How do I trick glsl to make it work?

I have tried to give the array a fixed size but it was too big for glsl and too small for me...

//vertex shader

#version 150
#extension GL_ARB_arrays_of_arrays: require
struct Info{
  bool joints[8];
  vec2 jpos[8];
  vec4 col;
  vec2 uv;
  vec2 pos;
  float flooded;
  bool exists;
};
in vec4 a_position;
in vec4 a_color;
in vec2 a_texCoord0;

uniform mat4 u_projTrans;
uniform vec2 u_pos;
uniform vec2 u_size;
uniform float u_zoom;

uniform ivec2 sSize;
uniform float exists[];
uniform vec2 positions[];
uniform float flooded[];
uniform float colors[];
uniform vec2 uvs[];
uniform float hozj[];
uniform float verj[];
uniform float nej[];
uniform float nwj[];
uniform int Mode;


out vec2 vTexCoord0;
out vec2 vWldCoord0;

out Info infos[][];

float getverj(in int x, in int y){
    if (x>=0 && y>=0 && x<sSize.x&&y<sSize.y-1){
        return verj[x+y*(sSize.x)];
    }else{
        return 0.;
    }
 }
 float gethozj(in int x, in int y){
     if (x>=0 && y>=0 && x<sSize.x-1&&y<sSize.y){
         return verj[x+y*(sSize.x-1)];
     }else{
         return 0.;
     }
  }
  float getnej(in int x, in int y){
      if (x>=0 && y>=0 && x<sSize.x-1&&y<sSize.y-1){
          return verj[x+y*(sSize.x-1)];
      }else{
          return 0.;
      }
   }
   float getnwj(in int x, in int y){
       if (x>=0 && y>=0 && x<sSize.x-1&&y<sSize.y-1){
           return verj[x+y*(sSize.x-1)];
       }else{
           return 0.;
       }
    }

float getSJ(in int i,in int x,in int y){
        if (i == 0){
            return getverj(x,y);

        }else if (i == 1){
            return getnej(x,y);

        }else if (i == 2){
            return gethozj(x,y);

        }else if (i == 3){
            return getnwj(x,y-1);

        }else if (i == 4){
            return getverj(x,y-1);

        }else if (i == 5){
            return getnej(x-1,y-1);

        }else if (i == 6){
            return gethozj(x-1,y);

        }else if (i == 7){
            return getnwj(x-1,y+1);

        }else{
            return -1.;
        }

    }

    ivec2 getRP(in int i,in ivec2 pos){
            if (i == 0){
                return pos+ivec2(0,1);
            }else if (i == 1){
                return pos+ivec2(1,1);

            }else if (i == 2){
                return pos+ivec2(1,0);

            }else if (i == 3){
                return pos+ivec2(1,-1);

            }else if (i == 4){
                return pos+ivec2(0,-1);

            }else if (i == 5){
                return pos+ivec2(-1,-1);

            }else if (i == 6){
                return pos+ivec2(-1,0);

            }else if (i == 7){
                return pos+ivec2(-1,1);

            }else{
                return ivec2(-1);
            }

        }

bool isInScreen(in vec2 pos){
    bool inside = true;
    vec2 size = u_size*u_zoom;
    vec2 bigger = u_pos+size/2.;
    vec2 smaller = u_pos-size/2.;
    if (bigger.x<pos.x||bigger.y<pos.y||smaller.x>pos.x||smaller.y>pos.y){
        inside = false;
    }
    return inside;
}

vec4 pack_depth(const in float depth)
{
    const vec4 bit_shift = vec4(256.0*256.0*256.0, 256.0*256.0, 256.0, 1.0);
    const vec4 bit_mask  = vec4(0.0, 1.0/256.0, 1.0/256.0, 1.0/256.0);
    vec4 res = fract(depth * bit_shift);
    res -= res.xxyz * bit_mask;
    return res;
}

void ProcessArrays(void){
    int i = 0;
    for (int x = 0; x<sSize.x; x++){
        for (int y = 0; y<sSize.y; y++){
            float e = exists[x+y*sSize.x];
            if (e == 1. && !isInScreen(positions[i])){
            e = 0.;
            }
            if (e == 0.){
                infos[x][y].exists = false;
            }else{
                infos[x][y].exists = true;
                infos[x][y].col = pack_depth(colors[i]);
                infos[x][y].pos = positions[i];
                infos[x][y].uv = uvs[i];
                infos[x][y].flooded = flooded[i];
                i++;
            }
        }
    }
    for (int x = 0; x<sSize.x; x++){
            for (int y = 0; y<sSize.y; y++){
                if (infos[x][y].exists){
                    for (int i = 0;i<8;i++){
                        if (getSJ(i,x,y) == 1.){
                            ivec2 pos = getRP(i,ivec2(x,y));
                            infos[x][y].joints[i] = true;
                            infos[x][y].jpos[i] = pos;
                        }else{
                            infos[x][y].joints[i] = false;
                        }
                    }
                }

            }
        }

}

void main() {
  vTexCoord0 = a_texCoord0;
  vWldCoord0 = (a_position.xy-(u_size*0.5))*u_zoom-u_pos;
  gl_Position = u_projTrans * a_position;
  ProcessArrays();
}

//fragment shader

#version 150
#extension GL_ARB_arrays_of_arrays: require
struct Info{
  bool joints[8];
  vec2 jpos[8];
  vec4 col;
  vec2 uv;
  vec2 pos;
  float flooded;
  bool exists;
};

in vec2 vTexCoord0;
in vec2 vWldCoord0;
uniform sampler2D u_texture;

uniform vec2 u_pos;
uniform vec2 u_size;
uniform float u_zoom;

uniform ivec2 sSize;

uniform int Mode;

in Info infos[][];


float minimum_distance( in vec2 a, in vec2 b, in vec2 p ){
    vec2 pa = p - a, ba = b - a;
    float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
    return length( pa - ba*h );

}

float DrawLine(in vec2 a, in vec2 b, in float t, in vec2 co){
    float dst = minimum_distance(a,b,co);
    return 1.0-smoothstep( t, t+1.0, dst );
}

vec3 toBari(in vec2 a,in vec2 b,in vec2 c,in vec2 p){
    vec3 coord = vec3(0);
    float det = (b.y-c.y)*(a.x-c.x)+(c.x-b.x)*(a.y-c.y);
    coord.x = ((b.y-c.y)*(p.x-c.x)+(c.x-b.x)*(p.y-c.y))/det;
    coord.y = ((c.y-a.y)*(p.x-c.x)+(a.x-c.x)*(p.y-c.y))/det;
    coord.z = 1.-coord.x-coord.y;
    return coord;
}
vec2 toCartesian(in vec2 a,in vec2 b,in vec2 c,in vec3 p){
    return a*p.x+b*p.y+c*p.z;
}

float DrawQuad(in vec2 a, in vec2 b,in vec2 c,in vec2 d,in float t,in vec2 co){
    float f = 0.;
    f= max(f,DrawLine(a,b,t,co));
    f= max(f,DrawLine(a,c,t,co));
    f= max(f,DrawLine(a,d,t,co));
    f= max(f,DrawLine(b,c,t,co));
    f= max(f,DrawLine(b,d,t,co));
    f= max(f,DrawLine(c,d,t,co));
    return f;
}

vec4 Iterate(){
    float mask = 0.;
    vec4 col = vec4(0);
    float sdst = 16000.;

    for (int x = 0; x<sSize.x; x++){
        for (int y = 0; y<sSize.y; y++){
            if (infos[x][y].exists == true){
                bool bound;
                for (int i = 0;i<8;i++){
                    if (infos[x][y].joints[i] == true){
                        bound = true;
                        mask = max(mask,DrawLine(infos[x][y].pos,infos[x][y].jpos[i],u_zoom,vWldCoord0));
                    }
                }
                if (bound == false){
                    mask = max(mask,DrawLine(infos[x][y].pos,infos[x][y].pos,u_zoom,vWldCoord0));
                }
                float f = distance(infos[x][y].pos,vWldCoord0);
                if (f < sdst){
                    sdst = f;
                    col = infos[x][y].col;
                }
            }
        }
    }
    return col*mask;
}

void main(void) {
    gl_FragColor = Iterate();
}

EDIT 1

I'd like to point out that if i give a fixed size to the array my computer uses 50% cpu and the program doesn't respond. Else it gives an error and makes a balck screen... it gives a compile error that it needs fixed array size. in the previous case it just does nothing, seems not to compile.

Wicpar
  • 195
  • 3
  • 13
  • Reconsider your approach. GLSL ES requires the length of the array to be known at compile time. Even more, it typically only supports a limited amount of varyings (say 8 or so). Note that they are aligned at four floats (so if it really would matter, you're better off packing them into vec4's). http://stackoverflow.com/questions/29551458/max-varying-vectors-and-floats-for-gles-2-0 – Xoppa Aug 03 '15 at 18:32
  • the thing is i only use libgdx for desktop, so if it is possible avoiding opengl es and do it with desktop opengl I'd be happy. – Wicpar Aug 03 '15 at 18:59
  • You won't gain enough for your usecase (perhaps 32 varyings or so). Don't take my word for it, you can query it yourself if you like to know it for your gpu. – Xoppa Aug 03 '15 at 19:40
  • ok thanks :), i think i'll go for a cpu computed info transmitted with a texture (or multiple) – Wicpar Aug 03 '15 at 19:54

0 Answers0