class Param {
String name;
int type;
float minValue, maxValue;
float value;
int[] osciModes;
Param(String name_, int type_, float minValue_, float maxValue_, int[] osciModes_) {
name = name_;
type = type_; //FLOATVAL or INTVAL
minValue = minValue_;
maxValue = maxValue_;
osciModes = osciModes_;
}
}
class Shader {
int id;
int pos, previousPos;
boolean previousActive;
String name;
ArrayList params = new ArrayList();
ArrayList paramValues = new ArrayList();
boolean paramChanged = true;
PGraphics canvas = createGraphics(renderer.width, renderer.height);
PGraphics result;
int direction = 0;
int directionParamIndex = -1;
Shader() {
canvas.beginDraw();
canvas.image(renderer, 0, 0, canvas.width, canvas.height);
canvas.endDraw();
}
void getValuesFromGUI() {
try { //problematic
params = gui.bricks.get(pos).params;
}
catch(Exception e) {
println(e);
}
//this is only for checking if a param has changed. paramValues could also be used for a save/load function
if (paramValues.size() != params.size()) {
for (int i = 0; i < params.size(); i++) {
paramValues.add(0.0);
}
}
paramChanged = false;
for (int i = 0; i < params.size(); i++) {
if (paramValues.get(i) != params.get(i).value) {
paramValues.set(i, params.get(i).value);
paramChanged = true;
}
}
if (pos != previousPos) {
paramChanged = true;
}
previousPos = pos;
try{
if (previousActive != gui.bricks.get(pos).active) { //fails if brick has not yet been loaded but shader has
paramChanged = true;
}
previousActive = gui.bricks.get(pos).active;
} catch (Exception e){
println("Brick not yet loaded, couldn't catch active state");
}
if (!paramChanged) {
if (imageChanged) paramChanged = true;
for (int i = this.pos; i >= 0; i--) {
if (gui.shaderList.get(i).paramChanged) paramChanged = true;
}
}
if (frameRate < 1) println("Rendering " + this + " on position " + pos + "...");
}
void changeParam(int paramNo, Param newParam) {
gui.bricks.get(pos).params.remove(paramNo);
gui.bricks.get(pos).params.add(paramNo, newParam);
gui.bricks.get(pos).exchangeSlider(paramNo, newParam);
paramChanged = true;
}
void shade() {
if (renderSizeChanged || paramChanged) {
this.setupCanvas();
this.apply();
this.render();
} else {
// println("nothing changed");
renderer.beginDraw();
renderer.image(result, 0, 0);
renderer.endDraw();
}/*
this.setupCanvas();
this.apply();
this.render();
*/
}
void setupCanvas() {
if (directionParamIndex >= 0) direction = (int)this.params.get(directionParamIndex).value;
int cw = (direction == 0 || direction == 2) ? renderer.width : renderer.height;
int ch = (direction == 0 || direction == 2) ? renderer.height : renderer.width;
canvas = createGraphics(cw, ch);
canvas.beginDraw();
canvas.imageMode(CENTER);
canvas.clear();
canvas.pushMatrix();
canvas.translate(cw/2, ch/2);
canvas.rotate((PI/2)*direction);
canvas.image(renderer, 0, 0);
canvas.popMatrix();
canvas.endDraw();
}
void apply() {
}; //override me with an actual fragment shader
void render() {
renderer.beginDraw();
renderer.imageMode(CENTER);
renderer.pushMatrix();
renderer.translate(renderer.width/2, renderer.height/2);
renderer.rotate(-(PI/2)*direction);
renderer.image(canvas, 0, 0);
renderer.popMatrix();
renderer.imageMode(CORNER);
renderer.endDraw();
result = createGraphics(renderer.width, renderer.height);
result.beginDraw();
result.image(renderer, 0, 0);
result.endDraw();
if (pos == gui.bricks.size()-1) {
//println("Finished rendering");
if (imageChanged) { //kind of hacky but it does synchronize the threads. sometimes.
stepOne++;
if (stepOne == 2) {
stepOne = 0;
imageChanged = false;
}
}
}
}
@ Override String toString() {
return getClass().getName();
}
}
int stepOne = 0;