I managed to get my vertex shader program to work in a few easy steps. The actual vertex shaders are stored in their own files with a .vs extension (the extension doesn't particularly matter, yet the program understands how to read them in that way). The shader files themselves are actually their own programs. They are attached to objects in the main program and the command glUseProgram(Obj) actually loads the shader and executes it.






#2) Running Source Code



















#3) gluLookAt(...) and glTransformf(...) are both transform views, glTransformf(...) is just a matrix multiply instead of specifying every little detail of the eyepoint, center and up vector.

#5) For this implemenation, I basically centered the object on the origin, so the objects origin is the world origin. With this in mind, no transformations were needed and keypresses control the rotation of the world.






































#include
#include

// Rotation amounts
static GLfloat xangle = 0.0f;
static GLfloat yangle = 0.0f;

void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_FLAT);
}

void SpecialKeys(int key, int x, int y)
{
if(key == GLUT_KEY_UP) {
yangle++;
}

if(key == GLUT_KEY_DOWN) {
yangle--;
}

if(key == GLUT_KEY_LEFT) {
xangle--;
}

if(key == GLUT_KEY_RIGHT) {
xangle++;
}
// Refresh the Window
glutPostRedisplay();
}


void display(void)
{
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (1.0, 1.0, 1.0);
glLoadIdentity (); /* clear the matrix */
/* viewing transformation */
//gluLookAt(eye, center, up vector);
gluLookAt (0, 0, 5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glRotatef(xangle, 0, 1, 0);
glRotatef(yangle, 1, 0, 0);

//Front Face
glBegin(GL_QUADS);
glNormal3f(0.0f, 0.0f, 1.0f);
glVertex3f(1, 1, 1);
glVertex3f(1, -1, 1);
glVertex3f(-1, -1, 1);
glVertex3f(-1, 1, 1);
glEnd();

//Back Face
glBegin(GL_QUADS);
glNormal3f(0.0f, 0.0f, -1.0f);
glVertex3f(1, 1, -1);
glVertex3f(1, -1, -1);
glVertex3f(-1, -1, -1);
glVertex3f(-1, 1, -1);
glEnd();

glColor3f(0.0f, 1.0f, 0.0f);
//Right Face
glBegin(GL_QUADS);
glNormal3f(1.0f, 0.0f, 0.0f);
glVertex3f(1, 1, 1);
glVertex3f(1, -1, 1);
glVertex3f(1, -1, -1);
glVertex3f(1, 1, -1);
glEnd();

//Left Face
glBegin(GL_QUADS);
glNormal3f(-1.0f, 0.0f, 0.0f);
glVertex3f(-1, 1, 1);
glVertex3f(-1, -1, 1);
glVertex3f(-1, -1, -1);
glVertex3f(-1, 1, -1);
glEnd();

glColor3f(0.0f, 0.0f, 1.0f);
//Top Face
glBegin(GL_QUADS);
glNormal3f(0.0f, 1.0f, 0.0f);
glVertex3f(1, 1, 1);
glVertex3f(-1, 1, 1);
glVertex3f(-1, 1, -1);
glVertex3f(1, 1, -1);
glEnd();

//Bottom Face
glBegin(GL_QUADS);
glNormal3f(0.0f, -1.0f, 0.0f);
glVertex3f(1, -1, 1);
glVertex3f(-1, -1, 1);
glVertex3f(-1, -1, -1);
glVertex3f(1, -1, -1);
glEnd();

glFlush ();
}

void reshape (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
glMatrixMode (GL_MODELVIEW);
}

int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display);
glutSpecialFunc(SpecialKeys);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}


The Perspect Example introduces a perspective view of 3 dimensional objects. In relation to real life, things that are farther away will appear smaller than they actually are. With an increase in distance from the observer, the volume or field of view that is taken in gets larger, yet the objects appear smaller.

Also seen in the Perspect example is the use of lighting to give a better approach of perspective. Lighting gives the appearance of being luminated by some form of light, therefore giving shadow or shade.

Each quad face is specified by connecting 4 vertices and a normal which specifies the projection of the plane.

I altered the example to produce a blue table, changing the color, evening up the sides and removing some faces :). Although its quite interesting to model this way, I have found maya to be somewhat quite easier :(, given a drawing program instead of coding.



















I hard coded the coordinates for the points and plotted the connected vertices for each B(t) in 3Dimensions.

OpenGL is an API tied to the hardware, not a programming language or compiler.

One thing that stuck out at me when reading the three articles is that there exists an OpenGL ES, which is a subset of the functionality taken from desktop OpenGL and used in embedded devices such as phones, consoles, appliances and vehicles that have smaller hardware. Such functionality is giving way to awesome graphical interfaces for entertainment or applicational purposes, such as a car's GPS.

Another thing that I found interesting is that OpenGL, again being an API, is supported by multiple programming languages. With the persistant use of Processing 1.0 in class, we can find that the OpenGL library is highly supported by the language. By importing the library, we can directly accelerate the graphics card to provide substantial use for what we code. Since Processing 1.0 is a well defined language for graphic design, it's methods are closely related to the OpenGL library. After importing the library, all methods could be substatially the same. A call to line(x0, y0, x1, y1) will execute the same way, yet they will be rendered differently and more likely faster.

The last thing I found interesting is how other languages provide use for the library. Processing 1.0 is just one example, yet the possibilites of what other languages provide is quite extravagant. PyOpenGL is a python supported version of OpenGL. Python is a scripting language which runs in real time and can provide fast and direct access to the uses of OpenGL. With the access of the real time capabilities simply drawing objects and shapes can be accomplished. Instead of having to compile everytime a change is made, the real time capabilites can be seen almost instantaneously. When looking at programs such as Maya, an advanced modeling application, we can see the possibilites of these uses. Maya offers its own language, the Maya Embedded Language or MEL for short, but also includes the uses of Python. Both offer the concept of creating, removing, saving and manipulating graphical objects with simple commands.


Bounce.cpp running in Dev-C++
















In the process of creating my Super Creatures set, I wanted a dynamically random simulation of the Super Formula designed by Johan Gielis to produce a body, secondary body and facial features. The program I wrote has setup two useful methods.

One method is “creature”, which will randomly create a creature around the world origin, wherever that may be. The creature method will distinctly develop a random body, a transparent secondary body which is also color coordinated with the base body, a random number of eyes between 2 and 4 and a mouth.

The body parts and the mouth are all developed using the method called “superform”, which implies the super formula. The “superform” method accepts a few key parameters including: the desired width & height and the six distinct parameters of the super formula, notably A, B, m, n1, n2, n3. Through the use of the parameters we can plug them into the super formula, which at a certain degree between 0 and 2PI (a full circle), will produce a point. Cycling through the range of 0 to 2PI in increments of .0001, we can come up with multiple vertices and finally connect them all to produce a shape. This shape is then displayed according to the previously defined fills and stroke qualities.

The desired width and height were usually decreased as the body pieces began to fit on the body. Yet to keep the dynamics of the program, all super shapes developed were and are random. Mostly modifying the parameters m, n1, n2 and n3, we can come up with all kinds of shapes.

Further exploration of radians between 0 and multiples of 2PI has shown quite extravagant shapes. Yet the way it has been implemented, the allowed range will only go from 0 to 4PI, since the program can run out of allowable memory due to so many vertices of a shape.


Also this formula can be simulated to produce 3 dimensional values and produce 3D Super Shapes.

I give credit to Johan Gielis for a functional method to produce super shapes and nodebox.com for giving me inspiration.
















void setup() {
size(720, 480);
noLoop();
}
void draw() {
//Push original matrix
pushMatrix();
//Translate to center
translate(width/2, height/2);
//Outer Grey Squares
scale(2);
for(float k = 0; k < 2; k += .5) {
rotate(k * PI);
fill(102);
rect(20, 20, 150, 150);
}
//Diagonal Grey Squares
scale(.55);
rotate(.25 * PI);
for(float k = 0; k < 2; k += .5) {
rotate(k * PI);
rect(20, 20, 150, 150);
}
//Black Center
for(float k = 0; k < 2; k += .10) {
rotate(k*PI);
fill(0);
rect(20, 20, 90, 90);
}
//Pop to orinal origin
popMatrix();
//Pop original origin
pushMatrix();

//Left diagonal of Triangles
for(int i = 0; i < 3; i++) {
translate(width/4, height/4);
for(float k = 1; k < 3; k += .10) {
rotate(k * PI);
triangle(0, 0, 15, 0, 0, 20);
}
}
popMatrix();

pushMatrix();
translate(width, 0);
//Right Diagonal of Rotated Triangles
for(int i = 0; i < 3; i++) {
translate(-width/4, height/4);
for(float k = 1; k < 3; k += .10) {
rotate(k * PI);
triangle(0, 0, 15, 0, 0, 20);
}
}
}















//Program will draw a single random point triangle and rotate it
//multiple times in increments of .25*PI radians.
int screenwid = 720;
int screenhei = 480;
float[][] rotation = new float[2][2];

void setup() {
size(screenwid, screenhei);
noLoop();
}

void draw() {
//Create a random triangle
int x0, y0, x1, y1, x2, y2;
x0 = int(random(screenwid));
y0 = int(random(screenhei));
x1 = int(random(screenwid));
y1 = int(random(screenhei));
x2 = int(random(screenwid));
y2 = int(random(screenhei));
//Rotate it in increments of .25*PI radians
for(float i = 0; i < 2; i += .25) {
rotation(x0, y0, x1, y1, x2, y2, (i*PI));
}
}

void rotation(int x0, int y0, int x1, int y1, int x2, int y2, float rotat) {
//Set rotation angle
setRotation(rotat);
//Calculate origin of desired triangle
int origx = int((x0+x1+x2)/3);
int origy = int((y0+y1+y2)/3);
//Create point matrix based on origin
float[][] points = {{x0-origx, y0-origy}, {x1-origx, y1-origy}, {x2-origx, y2-origy}};
//Multiply by rotation matrix
points = multiply(points, rotation);
//Add back origin
for(int i = 0; i < points.length; i++) {
for(int j = 0; j < points[0].length; j++) {
if(j == 0)
points[i][j] += origx;
else
points[i][j] += origy;
}
}
//Show rotated triangle
triangle(points[0][0], points[0][1], points[1][0], points[1][1], points[2][0], points[2][1]);
}

//Sets the values of the rotation matrix
void setRotation(float rotat) {
rotation[0][0] = cos(rotat);
rotation[0][1] = sin(rotat);
rotation[1][0] = -sin(rotat);
rotation[1][1] = cos(rotat);
}

//Used to multiply one matrix to another
float[][] multiply(float[][] a, float[][] b) {
float[][] c = new float[a.length][b[0].length];
for(int i = 0; i < c.length; i++) {
for(int j = 0; j < c[0].length; j++) {
for(int k = 0; k < b.length; k++) {
c[i][j] += a[i][k] * b[k][j];
}
}
}
return c;
}














//Set screen size
final int screenwid = 720;
final int screenhei = 480;
int bxmin, bxmax, bymin, bymax;

void setup()
{
size(screenwid, screenhei);
noLoop();
}

void draw()
{
//Declare clipping bounds and create rectangle
bxmin = screenwid/4;
bymin = screenhei/4;
bxmax = screenwid/4 + screenwid/2;
bymax = screenhei/4 + screenhei/2;
//rect(bxmin, bymin, screenwid/2, screenhei/2);
rect(bxmin, bymin, (bxmax - bxmin), (bymax - bymin));

//Produce 5 triangles with random points
int x0, x1, x2, y0, y1, y2;
for(int i = 0; i < 5; i++)
{
//Initiate points of triangle
x0 = int(random(screenwid));
x1 = int(random(screenwid));
x2 = int(random(screenwid));
y0 = int(random(screenhei));
y1 = int(random(screenhei));
y2 = int(random(screenhei));
//Draw edges
drawline(x0, y0, x1, y1);
drawline(x1, y1, x2, y2);
drawline(x2, y2, x0, y0);
}
}

//Calculate Sutherland-Cohen clipping code
int bP(int x, int y) {
int b = 0;
//X too low
if(x < bxmin)
b += 8;
//X too high
if(x > bxmax)
b += 4;
//Y too low
if(y > bymax)
b += 2;
//Y too high
if(y < bymin)
b += 1;
return b;
}

boolean rejectCheck(int b0, int b1) {
if((b0 & b1) != 0)
return true;
return false;
}

boolean acceptCheck(int b0, int b1) {
if((b0 == 0) && (b1 == 0))
return true;
return false;
}

boolean drawline(int x0, int y0, int x1, int y1) {
int b0, b1;
while(true) {
b0 = bP(x0, y0);
b1 = bP(x1, y1);
if(rejectCheck(b0, b1))
return false;
if(acceptCheck(b0, b1)) {
line(x0, y0, x1, y1);
return true;
}
if(b0 == 0) {
int tempCoord, tempCode;
tempCoord = x0; x0 = x1; x1 = tempCoord;
tempCoord = y0; y0 = y1; y1 = tempCoord;
tempCode = b0; b0 = b1; b1 = tempCode;
}
if((b0 & 1)!=0) {
x0 += (x1 - x0)*(bymax-y0)/(y1-y0);
y0 = bymax;
}
else if((b0 & 2)!=0) {
x0 += (x1 - x0)*(bymin-y0)/(y1-y0);
y0 = bymin;
}
else if((b0 & 4)!=0) {
y0 += (y1-y0)*(bxmax-x0)/(x1-x0);
x0 = bxmax;
}
else if((b0 & 8)!=0) {
y0 += (y1-y0)*(bymin-x0)/(x1-x0);
x0 = bxmin;
}
}
}

Processing 1.0 offers many features to provide a visual ease to a coding framework. With its simplified Java-like syntax, users can avoid the hassle of setting up programs and jump right into the graphic design. One particular project that caught my eye was music visualization. Car stereos, iTunes or any media player for that matter usually incorporates this into its program. I would like to implement a 2d version, with color changing frequency bars that ‘bounce’ to the music, or possibly some other form of visualization that oscillates or flows with the music. This is possible by analyzing the raw sound data, a few bytes for each frequency at a given time in a song. With the frequency numbers, lines & shapes can be assigned to follow the frequency values and therefore change with the sound. Although I don’t know how well audio is incorporated into Processing, a 3d version is available on the YouTube website, yet the frame rate is very low and the quality is poor.

Video















final int screenwid = 720;
final int screenhei = 480;

void setup()
{
size(screenwid, screenhei);
noLoop();
}

void draw()
{

for(int i = 0; i < 5; i++) {
triang(int(random(screenwid)), int(random(screenhei)),
int(random(screenwid)), int(random(screenhei)),
int(random(screenwid)), int(random(screenhei)));
}
}

void triang(int x0, int y0, int x1, int y1, int x2, int y2) {
line(x0, y0, x1, y1);
line(x1, y1, x2, y2);
line(x2, y2, x0, y0);
}




















//CUBIC BEZIER MOUSE CLICKS
int x0, x1, x2, x3, y0, y1, y2, y3;
int count = 0;
void setup()
{
size(300, 300);
}

void draw()
{

}

void mousePressed()
{
if(count%4 == 0) {
x0 = mouseX;
y0 = mouseY;
point(x0, y0);
}
else if(count%4 == 1) {
x1 = mouseX;
y1 = mouseY;
point(x1, y1);
}
else if(count%4 == 2) {
x2 = mouseX;
y2 = mouseY;
point(x2, y2);
}
else {
x3 = mouseX;
y3 = mouseY;
point(x3, y3);
cubic(x0, y0, x1, y1, x2, y2, x3, y3);
}
count++;
}

void cubic(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3)
{
float xB, yB;
for(float t = 0; t < 1; t += .001) {
xB = (1-t)*(1-t)*(1-t)*x0 + 3 *(1-t)*(1-t)*t*x1 + 3*(1-t)*t*t*x2 + t*t*t*x3;
yB = (1-t)*(1-t)*(1-t)*y0 + 3 *(1-t)*(1-t)*t*y1 + 3*(1-t)*t*t*y2 + t*t*t*y3;
point(xB, yB);
}




















void setup()
{
size(300, 300);
noLoop();
}

void draw()
{
drawline(100, 100, 200, 200);
quadratic(5, 120, 5, 200, 220, 220);
cubic(30, 20, 80, 5, 80, 75, 30, 75);
}

void drawline(int x0, int y0, int x1, int y1)
{
float xB, yB;
for(float t = 0; t < 1; t += .001) {
xB = (1 - t) * x0 + t * x1;
yB = (1 - t) * y0 + t * y1;
point(xB, yB);
}
}

void quadratic(int x0, int y0, int x1, int y1, int x2, int y2)
{
float xB, yB;
for(float t = 0; t < 1; t += .001) {
xB = (1 - t) * (1 - t) * x0 + 2 * (1 - t) * t * x1 + t * t * x2;
yB = (1 - t) * (1 - t) * y0 + 2 * (1 - t) * t * y1 + t * t * y2;
point(xB, yB);
}
}

void cubic(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3)
{
float xB, yB;
for(float t = 0; t < 1; t += .001) {
xB = (1-t)*(1-t)*(1-t)*x0 + 3 *(1-t)*(1-t)*t*x1 + 3*(1-t)*t*t*x2 + t*t*t*x3;
yB = (1-t)*(1-t)*(1-t)*y0 + 3 *(1-t)*(1-t)*t*y1 + 3*(1-t)*t*t*y2 + t*t*t*y3;
point(xB, yB);
}
}




















void setup()
{
size(300,300);
noLoop();
}

void draw()
{
drawLine(60, 70, 30, 200);

drawWeb(50);
drawCircle(50, 50, 20);
}

void drawLine(int x0, int y0, int x1, int y1)
{
int temp = 0;
boolean steep = abs(y1 - y0) > abs(x1 - x0);
if(steep)
{
temp = x0;
x0 = y0;
y0 = temp;
temp = x1;
x1 = y1;
y1 = temp;
}
if(x0 > x1) {
temp = x0;
x0 = x1;
x1 = temp;
temp = y0;
y0 = y1;
y1 = temp;
}
int deltax = x1 - x0;
int deltay = abs(y1 - y0);
float error = 0;
float deltaerr = (float)deltay/deltax;
int ystep;
int y = y0;

if(y0 < y1)
ystep = 1;
else
ystep = -1;

for(int x = x0; x <= x1; x++)
{
if(steep)
point(y, x);
else
point(x, y);

error += deltaerr;
if(error >= .5)
{
y += ystep;
error--;
}
}
}

void drawWeb(int n)
{
for(int i = 0; i < n; i++){
line(0, n-i, i, 0);
}
}

void drawCircle(int x0, int y0, int radius)
{
int f = 1 - radius;
int ddF_x = 1;
int ddF_y = -2*radius;
int x = 0;
int y = radius;

point(x0, y0 + radius);
point(x0, y0 - radius);
point(x0 + radius, y0);
point(x0 - radius, y0);

while(x < y) {
if(f >= 0) {
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
point(x0 + x, y0 + y);
point(x0 - x, y0 + y);
point(x0 + x, y0 - y);
point(x0 - x, y0 - y);
point(x0 + y, y0 + x);
point(x0 - y, y0 + x);
point(x0 + y, y0 - x);
point(x0 - y, y0 - x);
}
}



















//Set canvas size
size(300, 300);

//The letter 'M'
line(10, 40, 15, 10);
line(15, 10, 20, 30);
line(20, 30, 25, 10);
line(25, 10, 30, 40);

//The letter 'A'
ellipse(45, 30, 20, 20);
line(55, 20, 55, 40);

//Two 'T's
line(65, 10, 65, 40);
line(60, 20, 70, 20);
line(80, 10, 80, 40);
line(75, 20, 85, 20);

//Stick Face
ellipse(150, 150, 40, 60);
ellipse(140, 140, 10, 8);
ellipse(160, 140, 10, 8);
ellipse(150, 160, 20, 10);

//Stick Body
line(150, 180, 150, 250);
line(150, 250, 140, 285);
line(150, 250, 160, 285);
line(150, 200, 140, 240);
line(150, 200, 160, 220);
line(160, 220, 170, 195);