public void draw() {
		// Iterate over the atoms and draw them one by one
		// TODO: sort them by layer
		for (Atom a : atoms) {
			// Try to get a texture for our atom from its sprite
			BufferedImage buf = a.getCurrentImage();
			
			// Check if the image exists
			if(buf == null) continue;

			// Do we have the texture cached?
			if (!this.textures.containsKey(buf)) {
				// Texture isn't cached yet, need to generate it
				textures.put(buf, TextureLoader.loadTexture(buf));
			}
			
			// Load cached texture
			int t = this.textures.get(a.getCurrentImage());

			// Bind cached texture
			GL11.glBindTexture(GL11.GL_TEXTURE_2D, t);

			// Get the sprite dimensions
			int width = buf.getWidth();
			int height = buf.getHeight();
			
			// Check where to render the sprite on the buffer
			int offset_x = a.tile_x * Config.tileWidth + a.pixel_x;
			int offset_y = a.tile_y * Config.tileWidth + a.pixel_y;
			// Objects with onMap set are displayed relative to the
			// current viewport position(scrolling)
			if(a.onMap)
			{
				offset_x -= this.eye_x;
				offset_y -= this.eye_y;
			}

			// Draw the sprite as quad
			// TODO: Check if drawing two triangles is faster
			GL11.glBegin(GL11.GL_QUADS);
			GL11.glTexCoord2f(0, 0);
			GL11.glVertex2f(offset_x, offset_y);
			GL11.glTexCoord2f(1, 0);
			GL11.glVertex2f(offset_x + width, offset_y);
			GL11.glTexCoord2f(1, 1);
			GL11.glVertex2f(offset_x + width, offset_y + height);
			GL11.glTexCoord2f(0, 1);
			GL11.glVertex2f(offset_x, offset_y + height);
			GL11.glEnd();
		}
		
		// TODO: uncache unused textures if the cache is too crowded
	}