如何将变量zize的sruct数组从顶点着色器传递到片段着色器

时间:2015-08-03 17:34:00

标签: libgdx glsl

我的glsl程序遇到了一些问题,尝试在后期渲染中渲染对象。为了它的工作,我需要将一个2D数组的结构传递给我的片段着色器,我在我的顶点着色器中使用其他数组。我正在使用Libgdx。我如何欺骗glsl使它工作?

我试图给阵列一个固定的大小,但它对于glsl来说太大了,对我来说太小了......

//顶点着色器

#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();
}

//片段着色器

#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();
}

编辑1

我想指出,如果我给阵列一个固定的大小,我的计算机使用50%的CPU,程序没有响应。否则它会出错并制作一个黑屏...它会产生编译错误,需要固定的数组大小。在之前的情况下,它什么也没做,似乎没有编译。

0 个答案:

没有答案