How can I use custom shaders with a GUI in order to manipulate transformations of an object?

edited January 2018 in Library Questions

Fair warning, I am very new to coding, Processing and shaders. This is the code I have which uses ControlP5 sliders to change the rotation, scaling and translation of three objects, even though you can only do it with one object at a time. I was told to implement the same program using GLSL shaders but after reading about shaders for a couple days I still have no idea how to conceptualize that. I tried just using generic examples along with this code here, but I keep getting an error that my shader has to be of COLOR, TEXTURE and LIGHT type to render the geometry. How can the objects need three different shaders??

//See draw method to change the shape that appears when program is run.

import peasy.*;
import controlP5.*;

PeasyCam cam;
ControlP5 cp5;
PShape shape;
Accordion accordion;

float Tx, Ty, Tz, Rx, Ry, Rz, Sx, Sy, Sz; //variables for each axis that will be used for the transformations. T - translate, R - rotate, S - scale

  void keyPressed() {
    cam.setActive(false); //stops camera from moving after pressing any key
  }

  void setup() {
    size(800, 400, P3D);  
    cam = new PeasyCam(this, 500);
    gui();

  }

  //sets up the sliders used to controll the transformations
  void gui() {

    cp5 = new ControlP5(this);
    cp5.setAutoDraw(false);

    Group g1 = cp5.addGroup("translations")
                .setBackgroundColor(color(0, 64))
                .setBackgroundHeight(70)
                ;

    cp5.addSlider("Tx")
       .setPosition(0, 0)
       .setSize(100, 20)
       .setRange(-200, 200)
       .setValue(0)
       .moveTo(g1);

       cp5.addSlider("Ty")
       .setPosition(0, 30)
       .setSize(100, 20)
       .setRange(-200, 200)
       .setValue(0)
       .moveTo(g1);

       cp5.addSlider("Tz")
       .setPosition(0, 60)
       .setSize(100, 20)
       .setRange(-200, 200)
       .setValue(0)
       .moveTo(g1);

    Group g2 = cp5.addGroup("rotations")
                .setBackgroundColor(color(0, 64))
                .setBackgroundHeight(70)
                ;

    cp5.addSlider("Rx")
       .setPosition(0, 0)
       .setSize(100, 20)
       .setRange(-360, 360)
       .setValue(0)
       .moveTo(g2);

       cp5.addSlider("Ry")
       .setPosition(0, 30)
       .setSize(100, 20)
       .setRange(-360, 360)
       .setValue(0)
       .moveTo(g2);

       cp5.addSlider("Rz")
       .setPosition(0, 60)
       .setSize(100, 20)
       .setRange(-360, 360)
       .setValue(0)
       .moveTo(g2);   

    Group g3 = cp5.addGroup("scaling")
                .setBackgroundColor(color(0, 64))
                .setBackgroundHeight(70)
                ;

    cp5.addSlider("Sx")
       .setPosition(0, 0)
       .setSize(100, 20)
       .setRange(0, 5)
       .setValue(1)
       .moveTo(g3);

       cp5.addSlider("Sy")
       .setPosition(0, 30)
       .setSize(100, 20)
       .setRange(0, 5)
       .setValue(1)
       .moveTo(g3);

       cp5.addSlider("Sz")
       .setPosition(0, 60)
       .setSize(100, 20)
       .setRange(0, 5)
       .setValue(1)
       .moveTo(g3); 

       accordion = cp5.addAccordion("acc")
                 .setPosition(40,40)
                 .setWidth(100)
                 .addItem(g1)
                 .addItem(g2)
                 .addItem(g3)
                 ;

       accordion.setCollapseMode(Accordion.MULTI);

  }


void move (float x, float y, float z) {
  translate(x, y, z);
}
void turn (float x, float y, float z) {
  rotateX(radians(x));
  rotateY(radians(y));
  rotateZ(radians(z));
}
void stretch (float x, float y, float z) {
  scale(x, y, z);  
}

void draw(){
  background(0);
  lights();
  fill(156, 85, 232);
  stroke(255);

  //to display a different shape, add comments to whichever line is not commented below and remove comments from a different line
  //example: add comments to line 142 and remove comments from 143 to draw a torus

  //shape = createShape(BOX, 100,200,300); //stores box in shape
  //shape = getTorus(100,50,32,32); //stores torus in shape
  shape = loadShape("deer.obj"); //stores deer.obj in shape

  move (Tx, Ty, Tz);
  turn (Rx, Ry, Rz);
  stretch (Sx, Sy, Sz);
  shape(shape); //draws shape

  inFront();
  }

  //allows for drawing the 2D gui in front of the 3D objects
  void inFront() {
  hint(DISABLE_DEPTH_TEST); 
  cam.beginHUD();
  cp5.draw();
  cam.endHUD();
  hint(ENABLE_DEPTH_TEST);
}

//creates torus shape
PShape getTorus(float outerRad, float innerRad, int numc, int numt) {

  PShape sh = createShape();
  sh.beginShape(TRIANGLE_STRIP);
  sh.noStroke();

  float x, y, z, s, t, u, v;
  float nx, ny, nz;
  float a1, a2;
  int idx = 0;
  for (int i = 0; i < numc; i++) {
    for (int j = 0; j <= numt; j++) {
      for (int k = 1; k >= 0; k--) {
         s = (i + k) % numc + 0.5;
         t = j % numt;
         u = s / numc;
         v = t / numt;
         a1 = s * TWO_PI / numc;
         a2 = t * TWO_PI / numt;

         x = (outerRad + innerRad * cos(a1)) * cos(a2);
         y = (outerRad + innerRad * cos(a1)) * sin(a2);
         z = innerRad * sin(a1);

         nx = cos(a1) * cos(a2); 
         ny = cos(a1) * sin(a2);
         nz = sin(a1);
         sh.normal(nx, ny, nz);
         sh.vertex(x, y, z);

      }
    }
  }
   sh.endShape(); 
  return sh;
}

Answers

  • I am not an expert in shaders. I can recommend you review carefully: https://processing.org/tutorials/pshader/

    Then you do a bit more of research on the uniform vec4 transform as that is the field you should modify. You might need to get into the OpenGL documentation if you haven't done so. I wish I could help more but not much experience there... Hopefully you can get more feedback from other forum goers.

    Kf

Sign In or Register to comment.