/*
* File: SimpleShader.js
*
* Implements a SimpleShader object.
*
*/
/*jslint node: true, vars: true */
/*global gEngine: false, document: false, alert: false */
"use strict"; // Operate in Strict mode such that variables must be declared before used!
function SimpleShader(fragmentShaderPath, vertexShaderPath) {
// instance variables
// Convention: all instance variables: mVariables
this.mCompiledShader = null; // reference to the compiled shader in webgl context
this.mShaderVertexPositionAttribute = null; // reference to SquareVertexPosition within the shader
this.mPixelColor = null; // reference to the pixelColor uniform in the fragment shader
var gl = gEngine.Core.getGL();
// start of constructor
//
// Load and compile vertex and fragment shaders
var fragmentShader = this._loadAndCompileShader(fragmentShaderPath, gl.FRAGMENT_SHADER);
var vertexShader = this._loadAndCompileShader(vertexShaderPath, gl.VERTEX_SHADER);
// Creat eand link the shaders into a program
this.mCompiledShader = gl.createProgram();
gl.attachShader(this.mCompiledShader, vertexShader);
gl.attachShader(this.mCompiledShader, fragmentShader);
gl.linkProgram(this.mCompiledShader);
// check for errors
if(!gl.getProgramParameter(this.mCompiledShader, gl.LINK_STATUS)) {
alert("Error Linking Shader");
return null;
}
// gets a reference to the aSquareVertexPosition attribute
this.mShaderVertexPositionAttirbute = gl.getAttribLocation(this.mCompiledShader, "aSquareVertexPosition");
// Activates the vertex buffer loaded in Engine.Core_VertexBuffer
gl.bindBuffer(gl.ARRAY_BUFFER, gEngine.VertexBuffer.getGLVertexRef());
// Describe the characteristics of the vertex position attribute
gl.vertexAttribPointer(this.mShaderVertexPositionAttribute,
3, // each element is a 3-float
gl.FLOAT, // data type is FLOAT
false, // if the content is normailed vectors
0, // numbers of bytes to skip in between elements
0); // offsets to the first element
// gets reference to the uniform
this.mPixelColor = gl.getUniformLocation(this.mCompiledShader, "uPixelColor");
}
SimpleShader.prototype.getShader = function() { return this.mCompiledShader; };
// Activate the shader for rendering
SimpleShader.prototype.activateShader = function (pixelColor) {
var gl = gEngine.Core.getGL();
gl.useProgram(this.mCompiledShader);
gl.bindBuffer(gl.ARRAY_BUFFER, gEngine.VertexBuffer.getGLVertexRef());
gl.vertexAttribPointer(this.mShaderVertexPositionAttribute,
3, // each element is a 3-float (x,y.z)
gl.FLOAT, // data type is FLOAT
false, // if the content is normalized vectors
0, // number of bytes to skip in between elements
0); // offsets to the first element
gl.enableVertexAttribArray(this.mShaderVertexPositionAttribute);
gl.uniform4fv(this.mPixelColor, pixelColor); // Copies the floating point values
};
// Returns a compiled Shader from a shader in the dom
// the ID is the ID of the script
SimpleShader.prototype._loadAndCompileShader = function(filePath, shaderType) {
var gl = gEngine.Core.getGL();
var xmlReq, shaderSource = null, compiledShader = null;
// Request the text from the given location
xmlReq = new XMLHttpRequest();
xmlReq.open('GET', filePath, false);
try {
xmlReq.send();
} catch(error) {
alert("Failed to load shader: " + filePath);
return null;
}
shaderSource = xmlReq.responseText;
if(shaderSource === null) {
alert("WARNING: Loading of: " + filePath + "Failed");
return null;
}
// create the shader based on the shader type: vertex / Fragment
compiledShader = gl.createShader(shaderType);
//compile the created shader
gl.shaderSource(compiledShader, shaderSource);
gl.compileShader(compiledShader);
// check for errors
if(!gl.getShaderParameter(compiledShader, gl.COMPILE_STATUS)) {
var error = "ERROR: Shader Compiling Error: " + gl.getShaderInfoLog(compiledShader);
alert(error);
console.log(error);
}
return compiledShader;
};