diff --git a/src/core.js b/src/core.js
index 0bd4390d..b1a21d47 100644
--- a/src/core.js
+++ b/src/core.js
@@ -51,16 +51,21 @@ this.PhiloGL = null;
         optEvents = opt.events,
         optTextures = opt.textures,
         optProgram = $.splat(opt.program),
-        optScene = opt.scene;
+        optScene = opt.scene
+        program = null;
 
-    //get Context global to all framework
-    gl = PhiloGL.WebGL.getContext(canvasId, optContext);
+    //Get the 3D context, holds the application
+    var gl = PhiloGL.WebGL.getContext(canvasId, optContext);
+    PhiloGL.glConstants = gl;
 
     if (!gl) {
         opt.onError("The WebGL context couldn't been initialized");
         return null;
     }
 
+    //make app instance
+    var app = new PhiloGL.WebGL.Application({gl: gl});
+
     //get Program
     var popt = {
       'defaults': 'fromDefaultShaders',
@@ -80,7 +85,7 @@ this.PhiloGL = null;
               count--;
               if (count === 0 && !error) {
                 loadProgramDeps(gl, programLength == 1? p : programs, function(app) {
-                  opt.onLoad(PhiloGL.app);
+                  opt.onLoad(app);
                 });
               }
             },
@@ -94,13 +99,15 @@ this.PhiloGL = null;
 
     optProgram.forEach(function(optProgram, i) {
       var pfrom = optProgram.from, program;
+      optProgram.gl = gl;
+      optProgram.app = app;
       for (var p in popt) {
         if (pfrom == p) {
-          try {
+          //try {
             program = PhiloGL.Program[popt[p]]($.extend(programCallback, optProgram));
-          } catch(e) {
-            programCallback.onError(e);
-          }
+          //} catch(e) {
+          //  programCallback.onError(e);
+          //}
           break;
         }
       }
@@ -122,14 +129,10 @@ this.PhiloGL = null;
       //get Scene
       var scene = new PhiloGL.Scene(program, camera, optScene);
 
-      PhiloGL.app = new PhiloGL.WebGL.Application({
-        gl: gl,
-        canvas: canvas,
-        program: program,
-        scene: scene,
-        camera: camera
-      });
-      var app = PhiloGL.app;
+      app.program = program;
+      app.canvas = canvas;
+      app.scene = scene;
+      app.camera = camera;
 
       //Use program
       if (program.$$family == 'program') {
@@ -149,7 +152,7 @@ this.PhiloGL = null;
           onComplete: function() {
             callback(app);
           }
-        }));
+        }), app);
       } else {
         callback(app);
       }
@@ -176,9 +179,6 @@ this.PhiloGL = null;
 //Version
 PhiloGL.version = '1.5.2';
 
-//Holds the 3D context, holds the application
-var gl
-
 //Utility functions
 (function() {
   PhiloGL.$ = function (d) {
diff --git a/src/io.js b/src/io.js
index 1196e2ae..d468699d 100644
--- a/src/io.js
+++ b/src/io.js
@@ -266,8 +266,7 @@
   };
 
   //Load multiple textures from images
-  var Textures = function(opt) {
-    var app = PhiloGL.app;
+  var Textures = function(opt, app) {
     opt = $.merge({
       src: [],
       noCache: false,
diff --git a/src/media.js b/src/media.js
index 37d9ef57..57ebca2a 100644
--- a/src/media.js
+++ b/src/media.js
@@ -18,8 +18,8 @@
       position: { x: 0, y: 0, z: 1.205 }
     }), scene = new PhiloGL.Scene({}, camera);
 
-    return function(opt) {
-      var app = PhiloGL.app,
+    return function(opt, app) {
+      var gl = app.gl,
           program = app.program.$$family ? app.program : app.program[opt.program],
           textures = opt.fromTexture ? $.splat(opt.fromTexture) : [],
           framebuffer = opt.toFrameBuffer,
@@ -39,7 +39,6 @@
           scene.add(plane);
       }
 
-      var app = PhiloGL.app;
       if (framebuffer) {
         //create framebuffer
         if (!(framebuffer in app.frameBufferMemo)) {
diff --git a/src/o3d.js b/src/o3d.js
index d4b29cc0..4ba8d940 100644
--- a/src/o3d.js
+++ b/src/o3d.js
@@ -157,12 +157,13 @@
     },
 
     setIndices: function(program) {
+      var glc = PhiloGL.glConstants
       if (!this.$indices) return;
 
       if (this.dynamic) {
         program.setBuffer('indices-' + this.id, {
-          bufferType: gl.ELEMENT_ARRAY_BUFFER,
-          drawType: gl.STATIC_DRAW,
+          bufferType: glc.ELEMENT_ARRAY_BUFFER,
+          drawType: glc.STATIC_DRAW,
           value: this.$indices,
           size: 1
         });
@@ -237,7 +238,8 @@
     },
 
     setTextures: function(program, force) {
-      var app = PhiloGL.app;
+      var app = program.app;
+          glc = PhiloGL.glConstants;
       this.textures = this.textures? $.splat(this.textures) : [];
       var dist = 5;
       for (var i = 0, texs = this.textures, l = texs.length, mtexs = PhiloGL.Scene.MAX_TEXTURES; i < mtexs; i++) {
@@ -245,10 +247,10 @@
           var isCube = app.textureMemo[texs[i]].isCube;
           if (isCube) {
             program.setUniform('hasTextureCube' + (i + 1), true);
-            program.setTexture(texs[i], gl['TEXTURE' + (i + dist)]);
+            program.setTexture(texs[i], glc['TEXTURE' + (i + dist)]);
           } else {
             program.setUniform('hasTexture' + (i + 1), true);
-            program.setTexture(texs[i], gl['TEXTURE' + i]);
+            program.setTexture(texs[i], glc['TEXTURE' + i]);
           }
         } else {
           program.setUniform('hasTextureCube' + (i + 1), false);
@@ -272,7 +274,8 @@
     },
 
     unsetState: function(program) {
-      var attributes = program.attributes;
+      var attributes = program.attributes,
+          gl = program.gl;
 
       //unbind the array and element buffers
       gl.bindBuffer(gl.ARRAY_BUFFER, null);
diff --git a/src/program.js b/src/program.js
index 9166e1c4..a94bdf3f 100644
--- a/src/program.js
+++ b/src/program.js
@@ -26,7 +26,7 @@
   };
   
   //Creates a program from vertex and fragment shader sources.
-  var createProgram = function(gl, vertexShader, fragmentShader) {
+  var createProgram = function(vertexShader, fragmentShader, gl, app) {
     var program = gl.createProgram();
     gl.attachShader(
         program,
@@ -207,10 +207,10 @@
   };
 
   //Program Class: Handles loading of programs and mapping of attributes and uniforms
-  var Program = function(vertexShader, fragmentShader) {
-    var program = createProgram(gl, vertexShader, fragmentShader);
+  var Program = function(vertexShader, fragmentShader, gl, app) {
+    var program = createProgram(vertexShader, fragmentShader, gl);
     if (!program) return false;
-    
+
     var attributes = {},
         attributeEnabled = {},
         uniforms = {},
@@ -240,6 +240,10 @@
     this.attributes = attributes;
     this.attributeEnabled = attributeEnabled;
     this.uniforms = uniforms;
+    this.app = app;
+    this.gl = gl;
+
+    return this;
   };
 
   Program.prototype = {
@@ -263,7 +267,7 @@
 
   ['setBuffer', 'setBuffers', 'use'].forEach(function(name) {
     Program.prototype[name] = function() {
-      var app = PhiloGL.app;
+      var app = this.app;
       var args = Array.prototype.slice.call(arguments);
       args.unshift(this);
       app[name].apply(app, args);
@@ -274,7 +278,7 @@
   ['setFrameBuffer', 'setFrameBuffers', 'setRenderBuffer', 
    'setRenderBuffers', 'setTexture', 'setTextures'].forEach(function(name) {
     Program.prototype[name] = function() {
-      var app = PhiloGL.app;
+      var app = this.app;
       app[name].apply(app, arguments);
       return this;
     };
@@ -283,10 +287,11 @@
   //Get options in object or arguments
   function getOptions(args, base) {
     var opt;
-    if (args.length == 2) {
+    if (args.length == 3) {
       opt = {
         vs: args[0],
-        fs: args[1]
+        fs: args[1],
+        gl: args[2]
       };
     } else {
       opt = args[0] || {};
@@ -296,23 +301,30 @@
 
   //Create a program from vertex and fragment shader node ids
   Program.fromShaderIds = function() {
-    var opt = getOptions(arguments),
+    var $ = PhiloGL.$,
+      opt = getOptions(arguments),
       vs = $(opt.vs),
-      fs = $(opt.fs);
-    return preprocess(opt.path, vs.innerHTML, function(vectexShader) {
+      fs = $(opt.fs),
+      gl = opt.gl,
+      app = opt.app
+      program = null;
+    preprocess(opt.path, vs.innerHTML, function(vectexShader) {
       return preprocess(opt.path, fs.innerHTML, function(fragmentShader) {
-        opt.onSuccess(new Program(vectexShader, fragmentShader), opt);
+        opt.onSuccess(program = new Program(vectexShader, fragmentShader, gl, app), opt);
       });
     });
+    return program;
   };
 
   //Create a program from vs and fs sources
   Program.fromShaderSources = function() {
-    var opt = getOptions(arguments, {path: './'});
+    var opt = getOptions(arguments, {path: './'})
+        gl = opt.gl,
+        app = opt.app;
     return preprocess(opt.path, opt.vs, function(vectexShader) {
       return preprocess(opt.path, opt.fs, function(fragmentShader) {
         try {
-          var program = new Program(vectexShader, fragmentShader);
+          var program = new Program(vectexShader, fragmentShader, gl, app);
           if(opt.onSuccess) {
             opt.onSuccess(program, opt); 
           } else {
diff --git a/src/scene.js b/src/scene.js
index cfade0ad..d8f617f1 100644
--- a/src/scene.js
+++ b/src/scene.js
@@ -41,6 +41,7 @@
     }, opt || {});
 
     this.program = opt.program ? program[opt.program] : program;
+    this.app = this.program.app;
     this.camera = camera;
     this.models = [];
     this.config = opt;
@@ -212,7 +213,8 @@
     },
 
     renderToTexture: function(name, opt) {
-      var app = PhiloGL.app;
+      var app = this.app,
+          gl = app.gl;
       opt = opt || {};
       var texture = app.textures[name + '-texture'],
           texMemo = app.textureMemo[name + '-texture'];
@@ -232,6 +234,8 @@
           world = view.mulMat4(object),
           worldInverse = world.invert(),
           worldInverseTranspose = worldInverse.transpose();
+          app = program.app,
+          gl = app.gl;
 
       obj.setState(program);
 
@@ -261,9 +265,9 @@
 
     //setup picking framebuffer
     setupPicking: function() {
-      var app = PhiloGL.app;
+      var app = this.app;
       //create picking program
-      var program = PhiloGL.Program.fromDefaultShaders(),
+      var program = PhiloGL.Program.fromDefaultShaders({app: app, gl: app.gl}),
           floor = Math.floor;
       //create framebuffer
       app.setFrameBuffer('$picking', {
@@ -287,7 +291,6 @@
 
     //returns an element at the given position
     pick: function(x, y, lazy) {
-      var app = PhiloGL.app;
       //setup the picking program if this is
       //the first time we enter the method.
       if (!this.pickingProgram) {
diff --git a/src/webgl.js b/src/webgl.js
index 35b0a4c8..623d0b64 100644
--- a/src/webgl.js
+++ b/src/webgl.js
@@ -79,6 +79,7 @@
     $$family: 'application',
 
     setBuffer: function(program, name, opt) {
+      var gl = this.gl;
       //unbind buffer
       if (opt === false || opt === null) {
         opt = this.bufferMemo[name];
@@ -158,6 +159,7 @@
     },
 
     setFrameBuffer: function(name, opt) {
+      var gl = this.gl;
       //bind/unbind framebuffer
       if (typeof opt != 'object') {
         gl.bindFramebuffer(gl.FRAMEBUFFER, opt? this.frameBuffers[name] : null);
@@ -235,6 +237,7 @@
     },
 
     setRenderBuffer: function(name, opt) {
+      var gl = this.gl;
       if (typeof opt != 'object') {
         gl.bindRenderbuffer(gl.RENDERBUFFER, opt? this.renderBufferMemo[name] : null);
         return;
@@ -270,6 +273,7 @@
     },
 
     setTexture: function(name, opt) {
+      var gl = this.gl;
       //bind texture
       if (!opt || typeof opt != 'object') {
         gl.activeTexture(opt || gl.TEXTURE0);
@@ -401,6 +405,7 @@
     },
 
     use: function(program) {
+      var gl = this.gl;
       gl.useProgram(program.program);
       //remember last used program.
       this.usedProgram = program;