Max Headroom

Processing script based off the TV show Max Headroom. 

float rotx = PI/4;
float roty = PI/4;

float boxSize = 800;
float lineNum = 30;
void setup()
{
  size(1020, 720, P3D);
  textureMode(NORMAL);
  shapeMode (CENTER);
}
 
void draw()
{
   
  background(0);
  translate(width/2.0, height/2.0, boxSize/2);
  rotateX(rotx);
  rotateY(roty);
  stroke(255);
  noFill();
  float z = boxSize/2;
  pushMatrix();
  int side = 0;
  for (float rotY = HALF_PI; rotY <= TWO_PI; rotY+= HALF_PI) {
    switch (side) {
      case(0):
      stroke(255,0,0);
      break;
      case(1):
      stroke(255,255,0);
      break;
      case(2):
      stroke(255,255,0);
      break;
      case(3):
      stroke(255,0,0);
      break;
    }
    side++;
    for (int i = 0; i <= lineNum; i++) {
      if (rotY == HALF_PI || rotY == TWO_PI) {
        drawLineFromX(-boxSize/2, boxSize/2, -boxSize/2 + i * boxSize/lineNum, z, 20);
      } else{
        drawLineFromY(-boxSize/2, boxSize/2, -boxSize/2 + i * boxSize/lineNum, z, 20);
      }
    }
    rotateY(rotY);
  }
  popMatrix();
  pushMatrix();
  rotateX(HALF_PI);
  stroke(0,0,255);
  for (int i = 0; i <= lineNum; i++) {
        drawLineFromY(-boxSize/2, boxSize/2, -boxSize/2 + i * boxSize/lineNum, z, 20);
  }
  popMatrix();
  pushMatrix();
  rotateX(-HALF_PI);
  stroke(0,255,0);
  for (int i = 0; i <= lineNum; i++) {
        drawLineFromY(-boxSize/2, boxSize/2, -boxSize/2 + i * boxSize/lineNum, z, 20);
  }
  popMatrix();
  lineNum = 20 + 10 * sin(frameCount / 100.0);
  boxSize = 700 + 100 * sin(frameCount / 100.0 + PI);
  if(!mousePressed){
    roty+=0.01;
    rotx+=0.02;
  }
}

float lineZOffset(int i, float z) {
  float size = 25 + 25 *sin(frameCount / 50.0 + PI /3);
  return z - size+ size * noise(frameCount / 100.0 + (float)i * 10000);
}

void drawLineFromX(float xStart, float xEnd, float y, float z, float points) {
  beginShape();
  float next = abs(xEnd - xStart) / points;
  curveVertex(xStart - next, y, z);
  curveVertex(xStart, y, z);
  int i = 1;
  for (float x = xStart + next; x < xEnd; x+= next) {
    curveVertex(x,  y, lineZOffset(2 + i, z));
    i++;
  }
  curveVertex(xEnd, y,  z);
  curveVertex(xEnd - next, y,  z);
  endShape();
}

void drawLineFromY(float yStart, float yEnd, float x, float z, float points) {
  beginShape();
  float next = abs(yEnd - yStart) / points;
  curveVertex(x,  yStart - next,z);
  curveVertex(x,  yStart, z);
  int i = 1;
  for (float y = yStart + next; y < yEnd; y+= next) {
  curveVertex(x,  y, lineZOffset(2 + i, z));
    i++;
  }
  curveVertex(x,  yEnd, z);
  curveVertex(x,  yEnd + next, z);
  endShape();
}
 

Quick and easy Spout Intergration into Alchemy

I got an email from someone asking if Spout could be integrated into Alchemy, Alchemy is an open source drawing program and Spout allows programs to share opengl textures. Alchemy is written in java and doesn't use opengl for its graphics. I decided to integrate it as quick and easy as possible. I did this by importing Processing and the Spout library for Processing into the Alchemy source code and then, whenever Alchemy redraws the drawing canvas, passing a copy of the canvas to Processing and then to Spout.

If you would like a copy of the program just contact me.

Alchemy: http://al.chemy.org/
Spout: http://spout.zeal.co/
Processing: https://processing.org/

A Dark and Stormy Night, Programming with Poems

The above image was made using ADASN (A Dark and Stormy Night), a simple stack based programming language. I designed the code of the programming language to be written as normal English.  Every word of a sentence that has over 3 characters represents a number, 1 if it starts with a, 2 if it starts with b and etc. All the words in the sentence are then added up and if the resulting number corresponds to a command then the command is executed otherwise it is pushed onto the stack. Numbers 55 through to 86 represent commands. When the code is executed it generates a video where the code runs separately for each pixel every frame of the video.

The code tends to work best when written as a poem as it allows for more flexible sentence structure. The trick is to write code that not only describes how to make an image but what that image means.

Currently I have written a transpiler using JavaCC that converts the code into java and glsl, using processing to interface with opengl. This creates java source code that can then be compiled into a runnable jar file.

Commands

  • 55     time - pushes the current running time to the stack
  • 56    dup - duplicates the top of the stack
  • 57    push - pushes the number number to the stack even if its a command
  • 58    decimal - pops then pushes 1 / that numbers  
  • 59    <= - pops the top 2 from the stack then compares then and pushes 1 or 0
  • 60    >= - pops the top 2 from the stack then compares then and pushes 1 or 0
  • 61    < - pops the top 2 from the stack then compares then and pushes 1 or 0
  • 62    > - pops the top 2 from the stack then compares then and pushes 1 or 0
  • 63    = - pops the top 2 from the stack then compares then and pushes 1 or 0
  • 64    != - pops the top 2 from the stack then compares then and pushes 1 or 0
  • 65    + - pops the top 2 from the stack then pushes one plus the other
  • 66    - - pops the top 2 from the stack then pushes one minus the other
  • 67    * - pops the top 2 from the stack then pushes one times the other
  • 68    / - pops the top 2 from the stack then pushes one divided by the other
  • 69    % - pops the top 2 from the stack then pushes one modulus the other
  • 70    x - pushes the x position of the current pixel
  • 71    y - pushes the y position of the current pixel
  • 72    r - pushed the red color value of the current pixel
  • 73    g - pushed the green color value of the current pixel
  • 74    b - pushed the blue color value of the current pixel
  • 75    sR - pops then sets the current red color value to that number
  • 76    sG - pops then sets the current green color value to that number
  • 77    sB - pops then sets the current blue color value to that number
  • 78    sin - pops then pushes the sin of that number
  • 79    cos - pops then pushes the cos of that number
  • 80    tan - pops then pushes the tan of that number
  • 81    rand - pushes a random number
  • 82    width - pushes the width of the video
  • 83    height - pushes the height of the video
  • 84     pop - pops the stack
  • 85    length - pops the top 2 on the stack and pushes the length of them
  • 86    atan - pops the top 2 on the stack and pushes the atan of them

Example

Bolbus.

Terrifically gigantic,
floating a buv, 
up in the heavens,
floating with love.

Rising at morn,
falling at night,
quivering a buv.

Rising at morn,
falling at night,
soaring a buv.

Watching from far above,
shining down sun,
moving the fun.

Beautiful.

Terrifically gigantic,
floating above, 
up in the heavens,
floating with love.

Rising at morn,
falling at night,
quivering a buv.

Rising at morn,
falling at night,
soaring above.

Watching from far above,
shining down sun,
moving the fun.

Terrifically gigantic,
floating around all up a bove, 
up in the heavens,
floating with love.

Around, all bashly above.

Terrifically gigantic,
floating a buv, 
up in the heavens,
floating with love.

Rising at morn,
falling at night,
quivering a buv.

Watching from far above,
shining sun,
moving the fun.

Rising at morn,
falling at night,
xhuming the sun.

(As you can see i did cheat a bit by changing the spelling of some words, xhuming instead of exhuming and a buv/a bove instead of above)

Parsing

This is what it gets parsed down to:

  1. 2 82 68 70 66 2 83 68 71 66 85 4 82 68 62 75
  2. 2 width / x - 2 height / y - length  4 width / > setR
  3. R = length y - (height /2), x - (width /2)) >  width / 4