mirror of
https://github.com/patriciogonzalezvivo/thebookofshaders
synced 2024-11-17 21:25:40 +00:00
220 lines
6.3 KiB
HTML
220 lines
6.3 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>GLSL Shader Code Editor</title>
|
|
|
|
<!-- CodeMirror -->
|
|
<link type='text/css' rel='stylesheet' href="src/codemirror/css/codemirror.css">
|
|
<link type='text/css' rel="stylesheet" href="src/codemirror/addon/fold/foldgutter.css">
|
|
<link type='text/css' rel="stylesheet" href="src/codemirror/addon/dialog/dialog.css">
|
|
<link type='text/css' rel="stylesheet" href="src/codemirror/addon/hint/show-hint.css">
|
|
<link type='text/css' rel="stylesheet" href="src/codemirror/theme/monokai.css">
|
|
|
|
<script type="text/javascript" src="src/codemirror.js"></script>
|
|
<script type="text/javascript" src="src/codemirror/addon/search/searchcursor.js"></script>
|
|
<script type="text/javascript" src="src/codemirror/addon/search/search.js"></script>
|
|
<script type="text/javascript" src="src/codemirror/addon/dialog/dialog.js"></script>
|
|
<script type="text/javascript" src="src/codemirror/addon/edit/matchbrackets.js"></script>
|
|
<script type="text/javascript" src="src/codemirror/addon/edit/closebrackets.js"></script>
|
|
<script type="text/javascript" src="src/codemirror/addon/comment/comment.js"></script>
|
|
<script type="text/javascript" src="src/codemirror/addon/wrap/hardwrap.js"></script>
|
|
<script type="text/javascript" src="src/codemirror/addon/fold/foldcode.js"></script>
|
|
<script type="text/javascript" src="src/codemirror/addon/fold/brace-fold.js"></script>
|
|
<script type="text/javascript" src="src/codemirror/keymap/sublime.js"></script>
|
|
<script type="text/javascript" src="src/codemirror/addon/hint/show-hint.js"></script>
|
|
<script type="text/javascript" src="src/codemirror/mode/clike.js"></script>
|
|
|
|
<!-- GLSL Canvas -->
|
|
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/build/GlslCanvas.min.js"></script>
|
|
|
|
<style>
|
|
body {
|
|
background: #272822;
|
|
}
|
|
|
|
h1 {
|
|
color: white;
|
|
font-family: Courier, Arial;
|
|
}
|
|
|
|
pre {
|
|
font-size: 130%;
|
|
}
|
|
|
|
canvas.right {
|
|
position: fixed;
|
|
right: 10px;
|
|
top: 10px;
|
|
background-color: #fff;
|
|
border-radius: 15px;
|
|
overflow: hidden;
|
|
-webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);
|
|
}
|
|
|
|
.CodeMirror {
|
|
font-size: 110%;
|
|
line-height: 1.3;
|
|
right: 10px;
|
|
height: 100%;
|
|
}
|
|
|
|
.CodeMirror-linenumbers {
|
|
padding: 0 8px;
|
|
}
|
|
</style>
|
|
|
|
</head>
|
|
<body>
|
|
<h1 id="title" >FILE NAME.frag</h1>
|
|
<div id="editor"></div>
|
|
<canvas id="canvas" class="right" width="500" height="500"></canvas>
|
|
<script type="text/javascript">
|
|
window.addEventListener("hashchange", function () {
|
|
loadTag()
|
|
}, false);
|
|
|
|
var editor;
|
|
var billboard;
|
|
var imgs = [];
|
|
|
|
function fetchHTTP(url, methood){
|
|
var request = new XMLHttpRequest(), response;
|
|
|
|
request.onreadystatechange = function () {
|
|
if (request.readyState === 4 && request.status === 200) {
|
|
response = request.responseText;
|
|
}
|
|
}
|
|
request.open(methood ? methood : 'GET', url, false);
|
|
request.overrideMimeType("text/plain");
|
|
request.send(null);
|
|
return response;
|
|
}
|
|
|
|
window.requestAnimFrame = (function() {
|
|
return window.requestAnimationFrame ||
|
|
window.webkitRequestAnimationFrame ||
|
|
window.mozRequestAnimationFrame ||
|
|
window.oRequestAnimationFrame ||
|
|
window.msRequestAnimationFrame ||
|
|
function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element) {
|
|
return window.setTimeout(callback, 1000/60);
|
|
};
|
|
})();
|
|
|
|
// Keep track of the mouse
|
|
var mouse = {x: 0, y: 0};
|
|
document.addEventListener('mousemove', function(e){
|
|
mouse.x = e.clientX || e.pageX;
|
|
mouse.y = e.clientY || e.pageY
|
|
}, false);
|
|
|
|
function removeElementsByClass(className){
|
|
var elements = document.getElementsByClassName(className);
|
|
while(elements.length > 0){
|
|
elements[0].parentNode.removeChild(elements[0]);
|
|
}
|
|
}
|
|
|
|
function loadTag(){
|
|
var fragShader = "";
|
|
var fragFile = "";
|
|
|
|
while(imgs.length > 0) {
|
|
imgs.pop();
|
|
}
|
|
|
|
removeElementsByClass("CodeMirror");
|
|
|
|
if( window.location.hash === "" ){
|
|
fragShader = "#ifdef GL_ES\n\
|
|
precision mediump float;\n\
|
|
#endif\n\
|
|
\n\
|
|
uniform vec2 u_resolution;\n\
|
|
uniform vec2 u_mouse;\n\
|
|
uniform float u_time;\n\
|
|
\n\
|
|
void main(){\n\
|
|
vec2 st = gl_FragCoord.xy/u_resolution.xy;\n\
|
|
gl_FragColor = vec4(st.x,st.y,0.0,1.0);\n\
|
|
}";
|
|
} else {
|
|
var hashes = location.hash.split('&');
|
|
|
|
for(i in hashes){
|
|
var ext = hashes[i].substr(hashes[i].lastIndexOf('.') + 1);
|
|
var name = hashes[i];
|
|
|
|
// Extract hash if is present
|
|
if(name.search("#") === 0){
|
|
name = name.substr(1);
|
|
}
|
|
|
|
if(ext == "frag"){
|
|
fragFile = name;
|
|
fragShader = fetchHTTP(fragFile);
|
|
} else if (ext == "png" || ext == "jpg" || ext == "PNG" || ext == "JPG" ){
|
|
imgs.push(hashes[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
var demoTitle = document.getElementById("title");
|
|
if(demoTitle){
|
|
demoTitle.innerText = fragFile;
|
|
}
|
|
|
|
var demoCanvas = document.getElementById("canvas");
|
|
if (demoCanvas && fragShader !== "") {
|
|
demoCanvas.setAttribute("data-fragment-url", fragFile);
|
|
if (imgs.length > 0) {
|
|
var textureList = "";
|
|
for (i in imgs) {
|
|
textureList += imgs[i];
|
|
textureList += (i < imgs.length-1)?",":"";
|
|
}
|
|
demoCanvas.setAttribute("data-textures",textureList);
|
|
console.log("data-textures: " + textureList);
|
|
}
|
|
billboard = new GlslCanvas(demoCanvas);
|
|
}
|
|
|
|
var demoEditor = document.getElementById("editor");
|
|
if (demoEditor) {
|
|
editor = CodeMirror(demoEditor,{
|
|
value: fragShader,
|
|
lineNumbers: true,
|
|
matchBrackets: true,
|
|
mode: "x-shader/x-fragment",
|
|
keyMap: "sublime",
|
|
autoCloseBrackets: true,
|
|
extraKeys: {"Ctrl-Space": "autocomplete"},
|
|
showCursorWhenSelecting: true,
|
|
theme: "monokai",
|
|
indentUnit: 4
|
|
});
|
|
|
|
editor.on("change", function() {
|
|
demoCanvas.setAttribute("data-fragment", editor.getValue());
|
|
billboard.load(editor.getValue());
|
|
});
|
|
}
|
|
}
|
|
|
|
window.onload = function () {
|
|
loadTag();
|
|
render();
|
|
};
|
|
|
|
function render() {
|
|
billboard.setMouse(mouse)
|
|
billboard.render()
|
|
window.requestAnimFrame(render);
|
|
}
|
|
|
|
|
|
</script>
|
|
</body>
|
|
</html> |