mirror of
https://github.com/servo/servo.git
synced 2025-06-25 17:44:33 +01:00
321 lines
10 KiB
JavaScript
321 lines
10 KiB
JavaScript
// Copyright 2011 The Chromium Authors
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
WebGLTestUtils = (function() {
|
|
/**
|
|
* Converts a WebGL enum to a string
|
|
* @param {!WebGLContext} gl The WebGLContext to use.
|
|
* @param {number} value The enum value.
|
|
* @return {string} The enum as a string.
|
|
*/
|
|
var glEnumToString = function(gl, value) {
|
|
for (var p in gl) {
|
|
if (gl[p] == value) {
|
|
return p;
|
|
}
|
|
}
|
|
return '0x' + value.toString(16);
|
|
};
|
|
|
|
var lastError = '';
|
|
|
|
/**
|
|
* Returns the last compiler/linker error.
|
|
* @return {string} The last compiler/linker error.
|
|
*/
|
|
var getLastError = function() {
|
|
return lastError;
|
|
};
|
|
|
|
// clang-format off
|
|
|
|
/**
|
|
* A vertex shader for a single texture.
|
|
* @type {string}
|
|
*/
|
|
var simpleTextureVertexShader = [
|
|
'attribute vec4 vPosition;', //
|
|
'attribute vec2 texCoord0;',
|
|
'varying vec2 texCoord;',
|
|
'void main() {',
|
|
' gl_Position = vPosition;',
|
|
' texCoord = texCoord0;',
|
|
'}'
|
|
].join('\n');
|
|
|
|
/**
|
|
* A fragment shader for a single texture.
|
|
* @type {string}
|
|
*/
|
|
var simpleTextureFragmentShader = [
|
|
'precision mediump float;',
|
|
'uniform sampler2D tex;',
|
|
'varying vec2 texCoord;',
|
|
'void main() {',
|
|
' gl_FragData[0] = texture2D(tex, texCoord);',
|
|
'}'
|
|
].join('\n');
|
|
|
|
// clang-format on
|
|
|
|
/**
|
|
* Creates a simple texture vertex shader.
|
|
* @param {!WebGLContext} gl The WebGLContext to use.
|
|
* @return {!WebGLShader}
|
|
*/
|
|
var setupSimpleTextureVertexShader = function(gl) {
|
|
return loadShader(gl, simpleTextureVertexShader, gl.VERTEX_SHADER);
|
|
};
|
|
|
|
/**
|
|
* Creates a simple texture fragment shader.
|
|
* @param {!WebGLContext} gl The WebGLContext to use.
|
|
* @return {!WebGLShader}
|
|
*/
|
|
var setupSimpleTextureFragmentShader = function(gl) {
|
|
return loadShader(gl, simpleTextureFragmentShader, gl.FRAGMENT_SHADER);
|
|
};
|
|
|
|
/**
|
|
* Creates a program, attaches shaders, binds attrib locations, links the
|
|
* program and calls useProgram.
|
|
* @param {!Array.<!WebGLShader>} shaders The shaders to attach .
|
|
* @param {!Array.<string>} opt_attribs The attribs names.
|
|
* @param {!Array.<number>} opt_locations The locations for the attribs.
|
|
*/
|
|
var setupProgram = function(gl, shaders, opt_attribs, opt_locations) {
|
|
var realShaders = [];
|
|
var program = gl.createProgram();
|
|
for (var ii = 0; ii < shaders.length; ++ii) {
|
|
var shader = shaders[ii];
|
|
if (typeof shader == 'string') {
|
|
var element = document.getElementById(shader);
|
|
if (element) {
|
|
shader = loadShaderFromScript(gl, shader);
|
|
} else {
|
|
shader = loadShader(
|
|
gl, shader, ii ? gl.FRAGMENT_SHADER : gl.VERTEX_SHADER);
|
|
}
|
|
}
|
|
gl.attachShader(program, shader);
|
|
}
|
|
if (opt_attribs) {
|
|
for (var ii = 0; ii < opt_attribs.length; ++ii) {
|
|
gl.bindAttribLocation(
|
|
program, opt_locations ? opt_locations[ii] : ii, opt_attribs[ii]);
|
|
}
|
|
}
|
|
gl.linkProgram(program);
|
|
|
|
// Check the link status
|
|
var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
|
|
if (!linked) {
|
|
gl.deleteProgram(program);
|
|
return null;
|
|
}
|
|
|
|
gl.useProgram(program);
|
|
return program;
|
|
};
|
|
|
|
/**
|
|
* Creates a simple texture program.
|
|
* @param {!WebGLContext} gl The WebGLContext to use.
|
|
* @param {number} opt_positionLocation The attrib location for position.
|
|
* @param {number} opt_texcoordLocation The attrib location for texture
|
|
* coords.
|
|
* @return {WebGLProgram}
|
|
*/
|
|
var setupSimpleTextureProgram = function(
|
|
gl, opt_positionLocation, opt_texcoordLocation) {
|
|
opt_positionLocation = opt_positionLocation || 0;
|
|
opt_texcoordLocation = opt_texcoordLocation || 1;
|
|
var vs = setupSimpleTextureVertexShader(gl);
|
|
var fs = setupSimpleTextureFragmentShader(gl);
|
|
if (!vs || !fs) {
|
|
return null;
|
|
}
|
|
var program = setupProgram(
|
|
gl, [vs, fs], ['vPosition', 'texCoord0'],
|
|
[opt_positionLocation, opt_texcoordLocation]);
|
|
if (!program) {
|
|
gl.deleteShader(fs);
|
|
gl.deleteShader(vs);
|
|
}
|
|
gl.useProgram(program);
|
|
return program;
|
|
};
|
|
|
|
/**
|
|
* Creates buffers for a textured unit quad and attaches them to vertex
|
|
* attribs.
|
|
* @param {!WebGLContext} gl The WebGLContext to use.
|
|
* @param {number} opt_positionLocation The attrib location for position.
|
|
* @param {number} opt_texcoordLocation The attrib location for texture
|
|
* coords.
|
|
* @return {!Array.<WebGLBuffer>} The buffer objects that were
|
|
* created.
|
|
*/
|
|
var setupUnitQuad = function(gl, opt_positionLocation, opt_texcoordLocation) {
|
|
opt_positionLocation = opt_positionLocation || 0;
|
|
opt_texcoordLocation = opt_texcoordLocation || 1;
|
|
var objects = [];
|
|
|
|
var vertexObject = gl.createBuffer();
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
|
|
gl.bufferData(
|
|
gl.ARRAY_BUFFER, 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, -1.0,
|
|
-1.0, 0.0, 1.0, -1.0, 0.0
|
|
]),
|
|
gl.STATIC_DRAW);
|
|
gl.enableVertexAttribArray(opt_positionLocation);
|
|
gl.vertexAttribPointer(opt_positionLocation, 3, gl.FLOAT, false, 0, 0);
|
|
objects.push(vertexObject);
|
|
|
|
var vertexObject = gl.createBuffer();
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
|
|
gl.bufferData(
|
|
gl.ARRAY_BUFFER,
|
|
new Float32Array(
|
|
[1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0]),
|
|
gl.STATIC_DRAW);
|
|
gl.enableVertexAttribArray(opt_texcoordLocation);
|
|
gl.vertexAttribPointer(opt_texcoordLocation, 2, gl.FLOAT, false, 0, 0);
|
|
objects.push(vertexObject);
|
|
return objects;
|
|
};
|
|
|
|
/**
|
|
* Creates a program and buffers for rendering a textured quad.
|
|
* @param {!WebGLContext} gl The WebGLContext to use.
|
|
* @param {number} opt_positionLocation The attrib location for position.
|
|
* @param {number} opt_texcoordLocation The attrib location for texture
|
|
* coords.
|
|
* @return {!WebGLProgram}
|
|
*/
|
|
var setupTexturedQuad = function(
|
|
gl, opt_positionLocation, opt_texcoordLocation) {
|
|
var program = setupSimpleTextureProgram(
|
|
gl, opt_positionLocation, opt_texcoordLocation);
|
|
setupUnitQuad(gl, opt_positionLocation, opt_texcoordLocation);
|
|
return program;
|
|
};
|
|
|
|
/**
|
|
* Draws a previously setup quad.
|
|
* @param {!WebGLContext} gl The WebGLContext to use.
|
|
* @param {!Array.<number>} opt_color The color to fill clear with before
|
|
* drawing. A 4 element array where each element is in the range 0 to
|
|
* 255. Default [255, 255, 255, 255]
|
|
*/
|
|
var drawQuad = function(gl, opt_color) {
|
|
opt_color = opt_color || [255, 255, 255, 255];
|
|
gl.clearColor(
|
|
opt_color[0] / 255, opt_color[1] / 255, opt_color[2] / 255,
|
|
opt_color[3] / 255);
|
|
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
|
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
|
};
|
|
|
|
/**
|
|
* Links a WebGL program, throws if there are errors.
|
|
* @param {!WebGLContext} gl The WebGLContext to use.
|
|
* @param {!WebGLProgram} program The WebGLProgram to link.
|
|
* @param {function(string): void) opt_errorCallback callback for errors.
|
|
*/
|
|
var linkProgram = function(gl, program, opt_errorCallback) {
|
|
// Link the program
|
|
gl.linkProgram(program);
|
|
|
|
// Check the link status
|
|
var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
|
|
if (!linked) {
|
|
// something went wrong with the link
|
|
gl.deleteProgram(program);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
};
|
|
|
|
/**
|
|
* Loads a shader.
|
|
* @param {!WebGLContext} gl The WebGLContext to use.
|
|
* @param {string} shaderSource The shader source.
|
|
* @param {number} shaderType The type of shader.
|
|
* @param {function(string): void) opt_errorCallback callback for errors.
|
|
* @return {!WebGLShader} The created shader.
|
|
*/
|
|
var loadShader =
|
|
function(gl, shaderSource, shaderType, opt_errorCallback) {
|
|
var errFn = opt_errorCallback || (_ => {});
|
|
// Create the shader object
|
|
var shader = gl.createShader(shaderType);
|
|
if (shader == null) {
|
|
errFn('*** Error: unable to create shader \'' + shaderSource + '\'');
|
|
return null;
|
|
}
|
|
|
|
// Load the shader source
|
|
gl.shaderSource(shader, shaderSource);
|
|
var err = gl.getError();
|
|
if (err != gl.NO_ERROR) {
|
|
errFn(
|
|
'*** Error loading shader \'' + shader +
|
|
'\':' + glEnumToString(gl, err));
|
|
return null;
|
|
}
|
|
|
|
// Compile the shader
|
|
gl.compileShader(shader);
|
|
|
|
// Check the compile status
|
|
var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
|
|
if (!compiled) {
|
|
// Something went wrong during compilation; get the error
|
|
lastError = gl.getShaderInfoLog(shader);
|
|
errFn('*** Error compiling shader \'' + shader + '\':' + lastError);
|
|
gl.deleteShader(shader);
|
|
return null;
|
|
}
|
|
|
|
return shader;
|
|
}
|
|
|
|
/**
|
|
* Loads shaders from source, creates a program, attaches the shaders and
|
|
* links.
|
|
* @param {!WebGLContext} gl The WebGLContext to use.
|
|
* @param {string} vertexShader The vertex shader.
|
|
* @param {string} fragmentShader The fragment shader.
|
|
* @param {function(string): void) opt_errorCallback callback for errors.
|
|
* @return {!WebGLProgram} The created program.
|
|
*/
|
|
var loadProgram = function(
|
|
gl, vertexShader, fragmentShader, opt_errorCallback) {
|
|
var program = gl.createProgram();
|
|
gl.attachShader(
|
|
program,
|
|
loadShader(gl, vertexShader, gl.VERTEX_SHADER, opt_errorCallback));
|
|
gl.attachShader(
|
|
program,
|
|
loadShader(gl, fragmentShader, gl.FRAGMENT_SHADER, opt_errorCallback));
|
|
return linkProgram(gl, program, opt_errorCallback) ? program : null;
|
|
};
|
|
|
|
return {
|
|
drawQuad: drawQuad,
|
|
getLastError: getLastError,
|
|
glEnumToString: glEnumToString,
|
|
loadProgram: loadProgram,
|
|
loadShader: loadShader,
|
|
setupProgram: setupProgram,
|
|
setupSimpleTextureFragmentShader: setupSimpleTextureFragmentShader,
|
|
setupSimpleTextureProgram: setupSimpleTextureProgram,
|
|
setupSimpleTextureVertexShader: setupSimpleTextureVertexShader,
|
|
setupTexturedQuad: setupTexturedQuad,
|
|
setupUnitQuad: setupUnitQuad,
|
|
};
|
|
}());
|