public function get3DRender($output = 'return')
    {
        global $minX, $maxX, $minY, $maxY;
        $this->times = array(array('Start', $this->microtime_float()));
        $this->getPlayerSkin();
        // Downlaod and check the player skin
        $this->times[] = array('Download-Image', $this->microtime_float());
        $this->hd_ratio = imagesx($this->playerSkin) / 64;
        // Set HD ratio to 2 if the skin is 128x64. Check via width, not height because of new skin type.
        // check if new skin type. If both sides are equaly long: new skin type
        if (imagesx($this->playerSkin) == imagesy($this->playerSkin)) {
            $this->isNewSkinType = true;
        }
        $this->playerSkin = img::convertToTrueColor($this->playerSkin);
        // Convert the image to true color if not a true color image
        $this->times[] = array('Convert-to-true-color-if-needed', $this->microtime_float());
        $this->makeBackgroundTransparent();
        // make background transparent (fix for weird rendering skins)
        $this->times[] = array('Made-Background-Transparent', $this->microtime_float());
        // Quick fix for 1.8:
        // Copy the extra layers ontop of the base layers
        if ($this->layers) {
            $this->fixNewSkinTypeLayers();
        }
        $this->calculateAngles();
        $this->times[] = array('Angle-Calculations', $this->microtime_float());
        $this->facesDetermination();
        $this->times[] = array('Determination-of-faces', $this->microtime_float());
        $this->generatePolygons();
        $this->times[] = array('Polygon-generation', $this->microtime_float());
        $this->memberRotation();
        $this->times[] = array('Members-rotation', $this->microtime_float());
        $this->createProjectionPlan();
        $this->times[] = array('Projection-plan', $this->microtime_float());
        $result = $this->displayImage($output);
        $this->times[] = array('Display-image', $this->microtime_float());
        if ($output == 'return') {
            return $result;
        }
        for ($i = 1; $i < count($this->times); $i++) {
            header('generation-time-' . $i . '-' . $this->times[$i][0] . ': ' . ($this->times[$i][1] - $this->times[$i - 1][1]) * 1000 . 'ms');
        }
        header('generation-time-' . count($this->times) . '-TOTAL: ' . ($this->times[count($this->times) - 1][1] - $this->times[0][1]) * 1000 . 'ms');
        switch ($this->format) {
            case 'svg':
                header('Content-Type: image/svg+xml');
                echo '<?xml version="1.0" standalone="no"?>
						<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
						"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">' . $result . "\n";
                for ($i = 1; $i < count($this->times); $i++) {
                    echo '<!-- ' . ($this->times[$i][1] - $this->times[$i - 1][1]) * 1000 . 'ms : ' . $this->times[$i][0] . ' -->' . "\n";
                }
                echo '<!-- TOTAL : ' . ($this->times[count($this->times) - 1][1] - $this->times[0][1]) * 1000 . 'ms -->' . "\n";
                break;
            case 'base64':
                header('Content-Type: text/plain');
                echo $result;
                break;
            case 'png':
            default:
                header('Content-type: image/png');
                imagepng($result);
                imagedestroy($result);
                break;
        }
    }