<!--
Copyright (c) 2019 The Khronos Group Inc.
Use of this source code is governed by an MIT-style license that can be
found in the LICENSE.txt file.
-->

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>WebGL Shader Translator</title>
<style>
textarea {
    min-width: 70%;
    min-height: 200px;
    font-family: monospace;
    background: #def;
}
#disabled {
    color: red;
    font-weight: bold;
}
</style>
<script>
// Needed by wtu.create3DContext():
var testFailed = function() {};
</script>
<script src="../js/webgl-test-utils.js"> </script>
<script>
"use strict";
window.onload = main;

var gl;
var debugShaders;
var enabledExtensions = [];

var translateButton;
var extButton;

function main() {
  translateButton = document.getElementById('translate');
  extButton = document.getElementById('getExts');

  var wtu = WebGLTestUtils;
  // Prioritize creating a WebGL 2 context if possible - if not, fall back to WebGL 1.
  gl = wtu.create3DContext(undefined, undefined, 2);
  if (!gl || !gl.getExtension('WEBGL_debug_shaders'))
  {
    gl = wtu.create3DContext();
  }
  if (!gl) {
    disable();
    return;
  }

  debugShaders = gl.getExtension('WEBGL_debug_shaders');
  if (!debugShaders) {
    disable();
  }
}

function disable() {
  translateButton.disabled = true;
  extButton.disabled = true;
  document.getElementById('disabled').style.display = 'block';
}

function getExtensions() {
    getExtensionSet([
        'EXT_frag_depth',
        'EXT_shader_texture_lod',
        'OES_standard_derivatives',
        'WEBGL_draw_buffers'
    ]);
}

function getExtensionSet(shaderExtensions) {
    for (var i = 0; i < shaderExtensions.length; ++i) {
        if (enabledExtensions.indexOf(shaderExtensions[i]) < 0) {
            var ext = gl.getExtension(shaderExtensions[i]);
            if (ext) {
                enabledExtensions.push(shaderExtensions[i]);
            }
        }
    }
    if (enabledExtensions.length > 0) {
        document.getElementById('enabled-extensions').textContent = enabledExtensions.join(', ');
    }
}

function translateShader() {
    var sourceElement = document.getElementById('original-shader');
    var source = sourceElement.value;

    var output = document.getElementById('translated-shader');
    var infoLog = document.getElementById('info-log');
    var shaderType = document.getElementById('shader-type');
    infoLog.value = '';

    // Try compiling the source as both vertex and fragment shader and see if either one works
    var tryCompile = function(type) {
        var shader = gl.createShader(type);
        gl.shaderSource(shader, source);
        gl.compileShader(shader);
        var shaderTypeStr;
        if (type == gl.FRAGMENT_SHADER) {
            shaderTypeStr = 'Fragment shader';
        } else {
            shaderTypeStr = 'Vertex shader';
        }
        if (gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
            shaderType.textContent = shaderTypeStr;
            var translatedSource = debugShaders.getTranslatedShaderSource(shader);
            output.value = translatedSource;
            infoLog.value = gl.getShaderInfoLog(shader);
            return true;
        } else {
            infoLog.value += 'Info log when compiling as ' + shaderTypeStr + ':\n' + gl.getShaderInfoLog(shader) + '\n';
            return false;
        }
    }

    if (!tryCompile(gl.FRAGMENT_SHADER) && !tryCompile(gl.VERTEX_SHADER)) {
        output.value = 'Invalid shader, compilation failed as both fragment and vertex shader.';
        shaderType.textContent = 'Shader not';
    }
}
</script>
</head>
<body>
<h1>WebGL Shader Translator</h1>
<p>This page uses the browser's built-in shader translation facilities to show how a shader
is changed before being passed on to the underlying platform's graphics driver.</p>
<p id="disabled" style="display: none;">
    WebGL or WEBGL_debug_shaders extension is not available on this browser configuration.
    Use a different browser or look for other alternatives to enable the extension to be able to use this page.
    The extension might be behind a runtime flag for privacy considerations.
</p>
<h2>WebGL GLSL shader</h2>
<textarea id="original-shader"></textarea>
<p>
<input type="button" id="translate" value="Translate" onclick="translateShader()"></input>
<input type="button" id="getExts" value="Enable supported GLSL extensions" onclick="getExtensions()"></input>
</p>
<h2><span id="shader-type">Shader</span> translated for graphics driver</h2>
<textarea id="translated-shader"></textarea>
<h2>Enabled shader extensions</h2>
<p id="enabled-extensions">None</p>
<h2>Shader info log</h2>
<textarea id="info-log"></textarea>
</body>
</html>

