public void render() {
			//Begin Rendering
			GraphicsContext graphics = getGraphicsContext();
			
			//Load Textures as Needed
			lock(this.texturesToLoad) {
				foreach(LoadableTexture lt in new List<LoadableTexture>(this.texturesToLoad)) {
					lock(lt) {try {
							Game.GAME_INSTANCE.getLogger().log ("Loading Texture " + lt.getTextureName());
							this.texturesToLoad.Remove(lt);
							if(lt.isLoaded()) continue;
							Texture2D texture;
							if(lt.getTextureName() != null) {
								texture = new Texture2D(lt.getTextureName(), false);
							} else {
								texture = new Texture2D(lt.getWidth(), lt.getHeight(), false, PixelFormat.Rgba, PixelBufferOption.Renderable);
							}
							
							if(lt.getImage() != null) {
								texture.SetPixels(0, lt.getImage().ToBuffer(), 0, 0, lt.getWidth(), lt.getHeight());
							}
							
							lt.setTexture(texture);
							Game.GAME_INSTANCE.getLogger().log ("...Done loading " + lt.getTextureName());
					} catch(Exception e) {Game.GAME_INSTANCE.getLogger().log ("Failed to load Texture..");}}
				} 
			}
			
			//Generate Depth Buffer Objects as Needed
			lock(this.depthBuffersToMake) {
				foreach(ThreadSafeDepthBuffer dsfb in new List<ThreadSafeDepthBuffer>(this.depthBuffersToMake)) {
					if(dsfb == null) continue;
					if(dsfb.getDepthBuffer() != null) continue;
					DepthBuffer db = new DepthBuffer(dsfb.getWidth(), dsfb.getHeight(), PixelFormat.Depth16);
					dsfb.setDepthBuffer(db);
					this.depthBuffersToMake.Remove(dsfb);
				}
			}
			
			//Generate Frame Buffer Objects as Needed
			lock(this.frameBuffersToMake) {
				foreach(ThreadSafeFrameBuffer tsfb in new List<ThreadSafeFrameBuffer>(this.frameBuffersToMake)) {
					if(tsfb == null) continue;
					if(tsfb.getFrameBuffer() != null) continue;
					FrameBuffer fb = new FrameBuffer();
					tsfb.setFrameBuffer(fb);
					
					if(tsfb.getLoadableTexture() != null && tsfb.getLoadableTexture().isLoaded()) {
						fb.SetColorTarget(tsfb.getLoadableTexture().getTexture(), 0);
					}
					
					if(tsfb.getThreadSafeDepthBuffer() != null && tsfb.getThreadSafeDepthBuffer().getDepthBuffer() != null) {
						fb.SetDepthTarget(tsfb.getThreadSafeDepthBuffer().getDepthBuffer());
					}
					this.frameBuffersToMake.Remove(tsfb);
				}
			}
			
			//Put Things on VBO as needed
			lock(this.vboWaitingList) {
				foreach(Model m in new List<Model>(this.vboWaitingList)) {
					Game.GAME_INSTANCE.getLogger().log ("Putting " + m.GetType() + "(" + m.getName() + ") on the VBO");
					m.putOnVBO();
					this.vboWaitingList.Remove(m);
				}
			}
			
			lock(this.getCamera()) {				
				List<Model> models = this.getModels();
				
				try {
					models.Sort(
						delegate(Model p1, Model p2) {
							if(p1 == null || p2 == null) return 0;
							lock(p1) {
								lock(p2) {
									Location p1Abs = p1.getLocation().getAbsoluteLocation();
									Location p2Abs = p2.getLocation().getAbsoluteLocation();
									double p1Dist = getCamera().getLocation().getDistance(p1Abs);
									double p2Dist = getCamera().getLocation().getDistance(p2Abs);
									return p1Dist.CompareTo(p2Dist);
								}
							}
						}
					);
				} catch(Exception e) {}
				
				//Render Objects
				if(Scene.getActiveScene() != null) {
					try {
						lock(Scene.getActiveScene()) {
							Scene.getActiveScene().onRender();
						}
					} catch(Exception e) {}
				}
				
				renderToBuffer(models, getCamera());
				
				//Add Custom Models as Needed
				if(Game.GAME_INSTANCE.getDebugMode()) {
					
					FontModel fps = new FontModel("FPS: " + this.getCamera().getFrameRate());
					fps.render(getCamera());
					fps.getTexture().Dispose();
					fps.getVBO().Dispose();
					fps.Dispose();
				}
			}
			
			graphics.SwapBuffers ();
			System.GC.Collect();
		}