Skip to content

Instantly share code, notes, and snippets.

@wolftype
Last active September 26, 2016 00:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wolftype/cc8c0856db26dffa51b01000e9f20a28 to your computer and use it in GitHub Desktop.
Save wolftype/cc8c0856db26dffa51b01000e9f20a28 to your computer and use it in GitHub Desktop.
Create a WebGL Shader Program
<html>
<script type="text/javascript">
var GL;
var shaderId;
var vertexBuffer;
var indexBuffer;
var timer = 0;
function initWebGL(){
// Get Canvas Element
var canvas = document.getElementById("glcanvas");
// Get A WebGL Context
GL = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
// Test for Success
if (!GL) {
alert("Unable to initialize WebGL. Your browser may not support it.");
}
// Set clear color to red, fully opaque
GL.clearColor(1.0, 0.0, 0.0, 1.0);
// Clear Screen
GL.clear(GL.COLOR_BUFFER_BIT| GL.DEPTH_BUFFER_BIT);
initShaderProgram();
initBuffers();
}
function initShaderProgram(){
//Create Program and Shaders
shaderId = GL.createProgram();
var vertId = GL.createShader(GL.VERTEX_SHADER);
var fragId = GL.createShader(GL.FRAGMENT_SHADER);
//Load Shader Source (source text are in scripts below)
var vert = document.getElementById("vertScript").text;
var frag = document.getElementById("fragScript").text;
GL.shaderSource(vertId, vert);
GL.shaderSource(fragId, frag);
//Compile Shaders
GL.compileShader(vertId);
GL.compileShader(fragId);
//Check Vertex Shader Compile Status
if (!GL.getShaderParameter(vertId, GL.COMPILE_STATUS)) {
alert("Vertex Shader Compiler Error: " + GL.getShaderInfoLog(id));
GL.deleteShader(vertId);
return null;
}
//Check Fragment Shader Compile Status
if (!GL.getShaderParameter(fragId, GL.COMPILE_STATUS)) {
alert("Fragment Shader Compiler Error: " + GL.getShaderInfoLog(id));
GL.deleteShader(fragId);
return null;
}
//Attach and Link Shaders
GL.attachShader(shaderId, vertId);
GL.attachShader(shaderId, fragId);
GL.linkProgram(shaderId);
//Check Shader Program Link Status
if (!GL.getProgramParameter(shaderId, GL.LINK_STATUS)) {
alert("Shader Linking Error: " + GL.getProgramInfoLog(shader));
}
}
function initBuffers(){
//Some Vertex Data
var vertices = new Float32Array( [
-1.0, -1.0, 0.0,
-1.0, 1.0, 0.0,
1.0, 1.0, 0.0,
1.0, -1.0, 0.0
]);
//Create A Buffer
vertexBuffer = GL.createBuffer();
//Bind it to Array Buffer
GL.bindBuffer(GL.ARRAY_BUFFER, vertexBuffer);
//Allocate Space on GPU
GL.bufferData(GL.ARRAY_BUFFER, vertices.byteLength, GL.STATIC_DRAW);
//Copy Data Over, passing in offset
GL.bufferSubData(GL.ARRAY_BUFFER, 0, vertices );
//Some Index Data
var indices = new Uint16Array([ 0,1,3,2 ]);
//Create A Buffer
indexBuffer = GL.createBuffer();
//Bind it to Element Array Buffer
GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, indexBuffer);
//Allocate Space on GPU
GL.bufferData(GL.ELEMENT_ARRAY_BUFFER, indices.byteLength, GL.STATIC_DRAW);
//Copy Data Over, passing in offset
GL.bufferSubData(GL.ELEMENT_ARRAY_BUFFER, 0, indices );
}
//ANIMATION FUNCTION (to be passed a callback) see also http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
window.requestAnimFrame = ( function() {
//Find best option given current browser
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
// if none of the above, use non-native timeout method
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
} ) ();
function animationLoop(){
// feedback loop requests new frame
requestAnimFrame( animationLoop );
// render function is defined below
render();
}
function render(){
timer+=.1;
//Bind Shader
GL.useProgram(shaderId);
//Update uniform variable on shader
var uID = GL.getUniformLocation(shaderId, "uTime");
GL.uniform1f(uID, timer);
//Enable Position Attribute
var attId = GL.getAttribLocation(shaderId, "position");
GL.enableVertexAttribArray(attId);
//Bind Vertex Buffer
GL.bindBuffer(GL.ARRAY_BUFFER, vertexBuffer);
///Point to Attribute (loc, size, datatype, normalize, stride, offset)
GL.vertexAttribPointer( attId, 3, GL.FLOAT, false, 0, 0);
//Bind Index Buffer
GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, indexBuffer);
//Draw! --( mode, number_of_elements, data type, offset )
GL.drawElements(GL.TRIANGLE_STRIP, 4, GL.UNSIGNED_SHORT, 0);
}
function start(){
initWebGL();
animationLoop();
}
</script>
<!-- VERTEX SHADER SOURCE -->
<script id="vertScript" type="text/glsl">
#ifdef GL_ES
precision lowp float;
#endif
attribute vec3 position;
void main(void) {
gl_Position = vec4(position,1.0);
}
</script>
<!-- FRAGMENT SHADER SOURCE -->
<script id="fragScript" type="text/glsl">
#ifdef GL_ES
precision lowp float;
#endif
#define PI 3.14159265359
uniform float uTime;
void main(void) {
//divide pixel location by canvas width and height
//to get values are now between 0.0 and 1.0
vec2 st = gl_FragCoord.xy/vec2(640,480);
//some fun functions for picking colors
float r = sin(uTime+8.*PI*st.x);
float g = fract( sin(3.*PI*st.y) );
float b = sin(uTime+PI*st.x*st.y);
vec3 color = vec3(r,b,g);
gl_FragColor = vec4(color,1.0);
}
</script>
<body onload = start() >
<canvas id="glcanvas" width=640 height=480 style = "margin:auto; display:block">
Oops, browser has no <code> canvas </code> tag support
</canvas>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment