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.