Loading...
Logo
Processing Forum
Hi all,

I have a little math problem with glsl scaled translation:
I have a GSMovie playing in a GLTexture tex, i apply a GLTextureFilter ClipFilter that translate my movie following mouse coords, and apply Opacity and Scale.
The problem is: i want to apply Scale from the center of the translation .

So, here is my program:

GLSLClip.pde:
Copy code
  1. import processing.opengl.*;
  2. import codeanticode.glgraphics.*;
  3. import codeanticode.gsvideo.*;

  4. GSMovie movie;
  5. GLTexture tex, texFiltered;

  6. GLTextureFilter ClipFilter;
  7. float Opacity=.5, Scale=1.0;

  8. void setup() {
  9. size(640, 480, GLConstants.GLGRAPHICS);
  10.  
  11. tex = new GLTexture(this);
  12. texFiltered = new GLTexture(this);
  13.  
  14. movie = new GSMovie(this, "station.mov");
  15. movie.setPixelDest(tex);
  16. movie.loop();
  17.  
  18. ClipFilter = new GLTextureFilter(this, "ClipFilter.xml");
  19. }

  20. void movieEvent(GSMovie movie) {
  21. movie.read();
  22. }

  23. void draw() {
  24. if (movie.ready() && movie.width>1) {
  25. if (tex.putPixelsIntoTexture()) {
  26. background(255, 0, 0);

  27. float x = map(mouseX, 0, width, -.5, .5);
  28. float y = map(mouseY, 0, height, -.5, .5);
  29. ClipFilter.setParameterValue("posXY", new float[]{x, y});
  30. ClipFilter.setParameterValue("Scale", Scale); 
  31. ClipFilter.setParameterValue("Opacity", Opacity);
  32. tex.filter(ClipFilter, texFiltered);
  33. image(texFiltered, 0, 0, width, height);
  34. }
  35. }
  36. }

  37. void keyPressed() {
  38. if(key == CODED){
  39. if (keyCode == UP && Opacity<1){
  40. Opacity += .1;
  41. println("Opacity: "+Opacity);
  42. }
  43. else if (keyCode == DOWN && Opacity>0){
  44. Opacity -= .1;
  45. println("Opacity: "+Opacity);
  46. }
  47. else if (keyCode == LEFT && Scale>.1){
  48. Scale -= .1;
  49. println("Scale: "+Scale);
  50. }
  51. else if (keyCode == RIGHT && Scale<3){
  52. Scale += .1;
  53. println("Scale: "+Scale);
  54. }
  55. }
  56. }

ClipFilter.xml:
Copy code
  1. <filter name="Clip Filter">
  2. <description>Clip Filter with posXY,Scale,Opacity</description>
  3. <fragment>ClipFilter.glsl</fragment>
  4. <textures input="1" output="1"></textures>
  5. <parameter type="vec2" name="posXY" label="Clip position">0 0</parameter>
  6. <parameter type="float" name="Scale" label="Scale">1</parameter>
  7. <parameter type="float" name="Opacity" label="Opacity">1</parameter>
  8. </filter>

ClipFilter.glsl:
Copy code
  1. uniform sampler2D src_tex_unit0;
  2. uniform vec2 src_tex_offset0;

  3. uniform vec2 posXY;
  4. uniform float Scale;
  5. uniform float Opacity;

  6. void main(void)
  7. {
  8. vec2 tex_coord = (gl_TexCoord[0].st - posXY)/Scale; // Here is the problem
  9. vec4 color0 = texture2D(src_tex_unit0, tex_coord);
  10. if(tex_coord[0] <= 0) gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
  11. else if(tex_coord[0] >= 1) gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
  12. else if(tex_coord[1] <= 0) gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
  13. else if(tex_coord[1] >= 1) gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
  14. else gl_FragColor = vec4(color0.rgb, Opacity);
  15. }
Must be something not so hard but can't resolve it at the moment (not really used to GLSL coords transformation).

Thanks.

@admins: i'wasn't sure of the section, so feel free to move it if you think it is more a "Processing with Other Languages" (or else) thread.

Makio135
http://makio135.com/

Replies(7)

See (again?) the Forum Guidelines: if you use a contributed library (ie. one you had to install), put it here (I moved the topic). You don't use "another language", do you?
This section exists because it can be scanned by those used to use such library (your subject is good with regard to this), or even the makers of the library; and those not able to answer it (like me!) because they don't use it, can skip it.
Hey Philho, 
it's not a GLGraphics problem nor a GSVideo one, so it's not a Contributed Library problem, (by the way, it seems you haven't chaged the topic).
Scaling and translation are a Maths problem (so i figured it would go in Programming Question) but it is in a GLSL so there probably is a GLSL way of solving it, and GLSL IS another language.

Maths or GSL, here is the problem of the section 

Back to the real issue, no one?
Copy code
  1. vec2 tex_coord = gl_TexCoord[0].st - posXY; // gives a good translation following mouse
Copy code
  1. vec2 tex_coord = (gl_TexCoord[0].st - posXY)/Scale; // Scale is applied from top left corner
I'm looking for a centered scale
Copy code
  1. vec2 tex_coord = (gl_TexCoord[0].st - posXY)/Scale - posXY*Scale;
This is a bit better but still not ok

Makio135
http://makio135.com/
Ah, indeed, I missed the fact it was about coding shaders. But you are not coding "processing in another language" but using another language within Processing.
Someday, I might post about using Lua to script a Processing sketch, it still belongs to the library I will use to do so. If code a Processing sketch in Lua (which is also possible), it indeed belongs to the "other language" section.
Yes, classification is a bit subtle, arbitrary and with gray areas...
But your topic needs some knowledge of the required library, so I finally moved it here.
Thanks for your concern about the placement (as opposed to the "I don't care" attitude of some people).

(And sorry as I can't help, I never tried to use shaders.)
I don't know... 

are Shaders in a GL Matrix (-1,1) ??
Is there any translate functionality in GLSL ?? 
Can you pass a shader a value to offset (center to screen space) as an argument ??

Just throwing out ideas... 

Have you tried the Orange Book or any of it's ilk ??
Shaders are in Matrix (0,1)
i pass the Value posXY corresponding to mouseX, mouseY to translate my tex_coor successfully.
i also pass the scale:
vec2 tex_coord = (gl_TexCoord[0].st - posXY)/Scale - posXY*Scale

there are translate/scale functionnalities: but they seem to be matrix functions manipulation, can't find anything simplier
Ok, i did a little sketch doing what happens in the shader:
Copy code
  1. float posX, posY, Scale=1;
  2. PImage img;

  3. void setup(){
  4. size(800,600);
  5. img=loadImage("data/1.png");
  6. }

  7. void draw(){
  8. background(255);
  9. if(img.width>1) image(img,0,0,img.width, img.height);
  10. stroke(255);
  11. strokeWeight(5);
  12. noFill();
  13. rect(0,0,width,height);

  14. posX = map(mouseX,0,width,-.5,.5);
  15. posY = map(mouseY,0,height,-.5,.5);
  16. stroke(255,0,0);
  17. strokeWeight(5);
  18. noFill();
  19. rect(0+posX*width+(width-(width/Scale))/2,0+posY*height+(height-(height/Scale))/2,width/Scale,height/Scale);
  20. }

  21. void keyPressed() {
  22. if(key == CODED){
  23. if (keyCode == LEFT && Scale>.1){
  24. Scale -= .1;
  25. console.log("Scale: "+Scale);
  26. }
  27. else if (keyCode == RIGHT && Scale<3){
  28. Scale += .1;
  29. console.log("Scale: "+Scale);
  30. }
  31. }
  32. }

  33. void mousePressed(){
  34. console.log("posX: "+posX+"   posY: "+posY);
  35. }
So here is the solution doing Maths only:
Copy code
  1. uniform sampler2D src_tex_unit0;
  2. uniform vec2 src_tex_offset0;

  3. uniform vec2 posXY;
  4. uniform float Scale;
  5. uniform float Opacity;

  6. void main(void)
  7. {
  8. vec2 centre = vec2((1-(1/Scale))/2, (1-(1/Scale))/2);
  9. vec2 tex_coord = gl_TexCoord[0].st/Scale + centre - posXY/Scale;
  10. vec4 color0 = texture2D(src_tex_unit0, tex_coord);

  11. if(tex_coord[0] <= 0) gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
  12. else if(tex_coord[0] >= 1) gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
  13. else if(tex_coord[1] <= 0) gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
  14. else if(tex_coord[1] >= 1) gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
  15. else gl_FragColor = vec4(color0.rgb, Opacity);
  16. }


Makio135
http://makio135.com/