We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I want to pass a shader a texture of encoded locations, and have it draw points at the decoded locations.
I have a particle system stored in a texture that's 3000x1, with the x and y locations encoded into RGBA.
Currently I'm having to use the CPU to loop through particles and use point() to draw it to a new texture. I know this is being done properly in a shader in the PixelFlow library, but I can't figure it out, studying particleRender.glsl.
How can I get a shader to replicate whats going on in draw()? It feels like it should be easy but from what I've read on the PShader page and book of shaders I can't piece it together.
Edit: I've updated with my attempt at hacking away at PixelFlow's particleRender.glsl, it isn't throwing errors, but it isn't drawing anything either. I'm not used to the way version 150 works so maybe it's something simple. I've tried lots of trouble shooting and I can't get that shader to draw anything at all.
edit2: I've worked at it for hours, only a tiny bit of progress, a little sign of life from the shader, but I have no idea what it's doing. It's drawing what seems to be a random quad.

PGraphics pgLocs; 
PShader psRender;
void setup() {
  size(800, 800, P3D);
  int totalPoints = 3000;
  pgLocs = createGraphics(totalPoints, 1, P2D);
  psRender = loadShader("pointFrag.frag", "pointVert.glsl");
  psRender.set("tex_position", pgLocs);
  psRender.set("wh_viewport", width, height);
  psRender.set("wh_position", totalPoints, 1);
  psRender.set("point_size", 4);
  psRender.set("totalPoints", totalPoints);
  randomFill();
}
void randomFill() {
  pgLocs.beginDraw(); // fill pgLocs with random locations
  for (int i = 0; i < pgLocs.width; i++) {  
    PVector loc = new PVector(random(width)/width, random(height)/height);
    pgLocs.set(i, 0, xyToRGBA(loc));
  }
  pgLocs.endDraw();
  psRender.set("tex_position",pgLocs);
}
void keyPressed() {
  randomFill();
}
void draw() {
  stroke(0);
  strokeWeight(5);
  background(55);
  // // What I wish would work
  shader(psRender);
  //ill(255,100);
  //rect(0, 0, width, height);
  pgLocs.loadPixels();
  for (int i = 0; i < pgLocs.width; i++) { // What I'd like to do in a shader instead
    color c = pgLocs.pixels[i];// //get pixel color
    PVector loc = RGBAtoXY(c); // decode location
    stroke(c);                 // set color just for fun
   point(loc.x*width, loc.y*height); // show location was stored in the texture properly
  }
  filter(psRender);
}
color xyToRGBA(PVector loc) { // pack x into r g, y into b a
  PVector l = loc.copy().mult(255);
  int xi = floor(l.x);
  int yi = floor(l.y);
  int xr = floor((l.x-xi)*255);
  int yr = floor((l.y-yi)*255);
  return (yr << 24) | (xi << 16) | (xr << 8) | yi;
}
PVector RGBAtoXY(color c) { 
  int a = ((c >> 24) & 0xff) ;
  int r = ((c >> 16) & 0xff) ;
  int g = ((c >> 8)  & 0xff) ;
  int b =  (c        & 0xff) ;
  return new PVector((r+g/255.0)/255.0, (b+a/255.0)/255.0);
}
pointFrag.frag
#version 150
uniform vec2      wh_viewport;
uniform sampler2D tex_position;
uniform sampler2D tex_sprite;
uniform vec4      col_A = vec4(1, 1, 1, 1.0);
uniform vec4      col_B = vec4(0, 0, 0, 0.0);
in vec2 location;
in float my_PointSize;
out vec4 out_frag;
void main(){
  vec2 my_PointCoord = ((location * wh_viewport) - gl_FragCoord.xy) / my_PointSize + 0.5;
  out_frag = vec4(1.0,0,0,0);
}
pointVert.glsl
#version 150
uniform float     point_size;
uniform sampler2D tex_position;
uniform vec4      col_A = vec4(1, 1, 1, 1.0);
uniform vec4      col_B = vec4(0, 0, 0, 0.0);
uniform int  totalPoints;
out vec2 location;
 out float my_PointSize;
vec2 posDecode(vec4 c) {
  float r = c.r;
  float g = c.g/255.0;
  float b = c.b;
  float a = c.a/255.0;
  return vec2((r+g), (b+a));
}
void main(){
  float x = gl_VertexID/ float(totalPoints);
  vec4 color = vec4(texture2D(tex_position, vec2(x,1.0)));
  location = posDecode(color);
  location.y = 1-location.y;
  gl_Position  = vec4(location * 2.0 - 1.0, 0, 1); //vec4(location.x,location.y,0,1);//
  gl_PointSize = point_size;
  my_PointSize = point_size;
}
edit3: Still no luck figuring it out. I found more of the puzzle in pixelflow. These calls seem important gl.glEnable(GL3.GL_PROGRAM_POINT_SIZE); gl.glDrawArrays(GL2.GL_POINTS, 0, num_points);
This is what I'm trying to implement this into. I think I could do a million path finders instead of tens of thousands. 

Answers
I got it working. I'm using a magic number, I have no idea where it comes from and it's probably because I'm doing something wrong/improperly. Any ideas where this 1.731875 number in my vert shader comes from? It's needed to match the scale. Also none of my .set("var",var) type stuff is working with my shader, any idea what could cause that?
.....
....
sketch
To push values into the shader's "wh" variable, cast "width" and "height" to floats. (or send f[0] and f[1] for width and height respectively)
Vec'n' types expect to have floating point values. There are integer vectors uvec'n' and ivec'n' but that is a whole other can of worms. ;)
https://www.khronos.org/opengl/wiki/Data_Type_(GLSL)#Vectors
As for 1.731875, it is nearly the square root of 3 which would also be the length of a vector (1,1,1)... but that is all I have without guessing.