Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebGL 2.0 #37

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,13 @@ As you can see, in this example we are loading the fragment shader by setting th
* ```data-vertex``` : load a vertex shader by providing the content of the shader as a string
* ```data-vertex-url``` : load a vertex shader by providing a valid url
* ```data-textures```: add a list of texture urls separated by commas (ex: ```data-textures="texture.jpg,normal_map.png,something.jpg"```). Textures will be assigned in order to ```uniform sampler2D``` variables with names following this style: ```u_tex0```, ```u_tex1```, ```u_tex2```, etc.
* ```data-webgl``` : WebGL version (by default ```1```)
* ```data-glsl``` : GLSL ES version (by default ```100``` for WebGL and ```300``` for WebGL2)

All the cached ```.glslCanvas``` elements will be stored in the ```windows.glslCanvases``` array.

### The JS way

Create a ```<canvas>``` element and construct a ```glsCanvas()``` sandbox from it.

```javascript
Expand Down Expand Up @@ -78,13 +80,13 @@ You can also send your custom uniforms to a shader with ```.setUniform([name],[.
```javascript

// Assign .5 to "uniform float u_brightness"
sandbox.setUniform("u_brightness",.5);
sandbox.setUniform("u_brightness",.5);

// Assign (.2,.3) to "uniform vec2 u_position"
sandbox.setUniform("u_position",.2,.3);

// Assign a red color to "uniform vec3 u_color"
sandbox.setUniform("u_color",1,0,0);
sandbox.setUniform("u_color",1,0,0);

// Load a new texture and assign it to "uniform sampler2D u_texture"
sandbox.setUniform("u_texture","data/texture.jpg");
Expand All @@ -96,7 +98,7 @@ In the [```index.html```](https://github.com/patriciogonzalezvivo/glslCanvas/blo

[Demo page: patriciogonzalezvivo.github.io/glslCanvas/](http://patriciogonzalezvivo.github.io/glslCanvas/)

## Collaborate
## Collaborate

If you'd like to contribute to this code, you need to:

Expand Down
117 changes: 80 additions & 37 deletions dist/GlslCanvas.es.js
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ var ERROR_OTHER = 2;
* creation attributes you want to pass in.
* @return {WebGLRenderingContext} The created context.
*/
function setupWebGL(canvas, optAttribs, onError) {
function setupWebGL(canvas, optAttribs, options) {
function showLink(str) {
var container = canvas.parentNode;
if (container) {
Expand All @@ -258,22 +258,22 @@ function setupWebGL(canvas, optAttribs, onError) {
}

function handleError(errorCode, msg) {
if (typeof onError === 'function') {
onError(errorCode);
if (typeof options.onError === 'function') {
options.onError(errorCode);
} else {
showLink(msg);
}
}

if (!window.WebGLRenderingContext) {
if (options.webglVersion === 2 ? !window.WebGL2RenderingContext : !window.WebGLRenderingContext) {
handleError(ERROR_BROWSER_SUPPORT, GET_A_WEBGL_BROWSER);
return null;
}

var context = create3DContext(canvas, optAttribs);
var context = create3DContext(canvas, optAttribs, options.webglVersion);
if (!context) {
handleError(ERROR_OTHER, OTHER_PROBLEM);
} else {
} else if (options.webglVersion === 1) {
context.getExtension('OES_standard_derivatives');
}
return context;
Expand All @@ -285,8 +285,8 @@ function setupWebGL(canvas, optAttribs, onError) {
* from. If one is not passed in one will be created.
* @return {!WebGLContext} The created context.
*/
function create3DContext(canvas, optAttribs) {
var names = ['webgl', 'experimental-webgl'];
function create3DContext(canvas, optAttribs, webglVersion) {
var names = webglVersion === 2 ? ['webgl2'] : ['webgl', 'experimental-webgl'];
var context = null;
for (var ii = 0; ii < names.length; ++ii) {
try {
Expand Down Expand Up @@ -965,6 +965,24 @@ Texture.getMaxTextureSize = function (gl) {
// Global set of textures, by name
Texture.activeUnit = -1;

var vertexString100 = "\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nattribute vec2 a_position;\nattribute vec2 a_texcoord;\n\nvarying vec2 v_texcoord;\n\nvoid main() {\n gl_Position = vec4(a_position, 0.0, 1.0);\n v_texcoord = a_texcoord;\n}\n";

var fragmentString100 = "\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nvarying vec2 v_texcoord;\n\nvoid main(){\n gl_FragColor = vec4(0.0);\n}\n";

var vertexString300 = "#version 300 es\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nin vec2 a_position;\nin vec2 a_texcoord;\n\nout vec2 v_texcoord;\n\nvoid main() {\n gl_Position = vec4(a_position, 0.0, 1.0);\n v_texcoord = a_texcoord;\n}\n";

var fragmentString300 = "#version 300 es\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nin vec2 v_texcoord;\nout vec4 frag_color;\n\nvoid main(){\n frag_color = vec4(0.0);\n}\n";

function getDefaultShaderStrings(glslVersion) {
return glslVersion === 300 ? {
fragmentString: fragmentString300,
vertexString: vertexString300
} : {
fragmentString: fragmentString100,
vertexString: vertexString100
};
}

/*
The MIT License (MIT)

Expand Down Expand Up @@ -996,8 +1014,27 @@ var GlslCanvas = function () {

subscribeMixin$1(this);

contextOptions = contextOptions || {};
options = options || {};
contextOptions = Object.assign({}, contextOptions);
options = Object.assign({}, options);

['vertexString', 'backgroundColor', 'fragmentString'].forEach(function (property) {
if (property in contextOptions) {
console.warn('Property ' + property + ' should be used in options - not in contextOptions');
options[property] = contextOptions[property];
}
});

if (canvas.hasAttribute('data-webgl')) {
options.webglVersion = parseInt(canvas.getAttribute('data-webgl'), 10);
} else {
options.webglVersion = options.webglVersion || 1;
}

if (canvas.hasAttribute('data-glsl')) {
options.glslVersion = parseInt(canvas.getAttribute('data-glsl'), 10);
} else {
options.glslVersion = options.glslVersion || (options.webglVersion === 2 ? 300 : 100);
}

if (canvas.hasAttribute('data-fullscreen') && (canvas.getAttribute('data-fullscreen') == "1" || canvas.getAttribute('data-fullscreen') == "true")) {
this.width = window.innerWidth;
Expand All @@ -1009,6 +1046,8 @@ var GlslCanvas = function () {
this.height = canvas.clientHeight;
}

this.webglVersion = options.webglVersion === 2 ? 2 : 1;
this.glslVersion = options.glslVersion === 300 ? 300 : 100;
this.canvas = canvas;
this.gl = undefined;
this.deps = {};
Expand All @@ -1023,11 +1062,13 @@ var GlslCanvas = function () {
this.BUFFER_COUNT = 0;
// this.TEXTURE_COUNT = 0;

this.vertexString = contextOptions.vertexString || '\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nattribute vec2 a_position;\nattribute vec2 a_texcoord;\n\nvarying vec2 v_texcoord;\n\nvoid main() {\n gl_Position = vec4(a_position, 0.0, 1.0);\n v_texcoord = a_texcoord;\n}\n';
this.fragmentString = contextOptions.fragmentString || '\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nvarying vec2 v_texcoord;\n\nvoid main(){\n gl_FragColor = vec4(0.0);\n}\n';
this.defaultShaderStrings = getDefaultShaderStrings(this.glslVersion);

this.vertexString = options.vertexString || this.defaultShaderStrings.vertexString;
this.fragmentString = options.fragmentString || this.defaultShaderStrings.fragmentString;

// GL Context
var gl = setupWebGL(canvas, contextOptions, options.onError);
var gl = setupWebGL(canvas, contextOptions, options);
if (!gl) {
return;
}
Expand All @@ -1039,7 +1080,7 @@ var GlslCanvas = function () {
this.realToCSSPixels = window.devicePixelRatio || 1;

// Allow alpha
canvas.style.backgroundColor = contextOptions.backgroundColor || 'rgba(1,1,1,0)';
canvas.style.backgroundColor = options.backgroundColor || 'rgba(1,1,1,0)';

// Load shader
if (canvas.hasAttribute('data-fragment')) {
Expand Down Expand Up @@ -1211,7 +1252,7 @@ var GlslCanvas = function () {

// If Fragment shader fails load a empty one to sign the error
if (!fragmentShader) {
fragmentShader = createShader(this, 'void main(){\n\tgl_FragColor = vec4(1.0);\n}', this.gl.FRAGMENT_SHADER);
fragmentShader = createShader(this, this.defaultShaderStrings.fragmentString, this.gl.FRAGMENT_SHADER);
this.isValid = false;
} else {
this.isValid = true;
Expand Down Expand Up @@ -1247,15 +1288,16 @@ var GlslCanvas = function () {
}, {
key: 'test',
value: function test(callback, fragString, vertString) {
var _this2 = this;

// Thanks to @thespite for the help here
// https://www.khronos.org/registry/webgl/extensions/EXT_disjoint_timer_query/
var pre_test_vert = this.vertexString;
var pre_test_frag = this.fragmentString;
var pre_test_paused = this.paused;

var ext = this.gl.getExtension('EXT_disjoint_timer_query');
var query = ext.createQueryEXT();
var wasValid = this.isValid;
var ext = this.webglVersion === 2 ? this.gl.getExtension('EXT_disjoint_timer_query_webgl2') : this.gl.getExtension('EXT_disjoint_timer_query');
var query = this.webglVersion === 2 ? this.gl.createQuery() : ext.createQueryEXT();

if (fragString || vertString) {
this.load(fragString, vertString);
Expand All @@ -1265,37 +1307,36 @@ var GlslCanvas = function () {
}

this.paused = true;
ext.beginQueryEXT(ext.TIME_ELAPSED_EXT, query);
this.webglVersion === 2 ? this.gl.beginQuery(ext.TIME_ELAPSED_EXT, query) : ext.beginQueryEXT(ext.TIME_ELAPSED_EXT, query);
this.forceRender = true;
this.render();
ext.endQueryEXT(ext.TIME_ELAPSED_EXT);
this.webglVersion === 2 ? this.gl.endQuery(ext.TIME_ELAPSED_EXT) : ext.endQueryEXT(ext.TIME_ELAPSED_EXT);

var sandbox = this;
function finishTest() {
var finishTest = function finishTest() {
// Revert changes... go back to normal
sandbox.paused = pre_test_paused;
_this2.paused = pre_test_paused;
if (fragString || vertString) {
sandbox.load(pre_test_frag, pre_test_vert);
_this2.load(pre_test_frag, pre_test_vert);
}
}
function waitForTest() {
sandbox.forceRender = true;
sandbox.render();
var available = ext.getQueryObjectEXT(query, ext.QUERY_RESULT_AVAILABLE_EXT);
var disjoint = sandbox.gl.getParameter(ext.GPU_DISJOINT_EXT);
};
var waitForTest = function waitForTest() {
_this2.forceRender = true;
_this2.render();
var available = _this2.webglVersion === 2 ? _this2.gl.getQueryParameter(query, _this2.gl.QUERY_RESULT_AVAILABLE) : ext.getQueryObjectEXT(query, ext.QUERY_RESULT_AVAILABLE_EXT);
var disjoint = _this2.gl.getParameter(ext.GPU_DISJOINT_EXT);
if (available && !disjoint) {
var ret = {
wasValid: wasValid,
frag: fragString || sandbox.fragmentString,
vert: vertString || sandbox.vertexString,
timeElapsedMs: ext.getQueryObjectEXT(query, ext.QUERY_RESULT_EXT) / 1000000.0
frag: fragString || _this2.fragmentString,
vert: vertString || _this2.vertexString,
timeElapsedMs: _this2.webglVersion === 2 ? _this2.gl.getQueryParameter(query, _this2.gl.QUERY_RESULT) / 1000000.0 : ext.getQueryObjectEXT(query, ext.QUERY_RESULT_EXT) / 1000000.0
};
finishTest();
callback(ret);
} else {
window.requestAnimationFrame(waitForTest);
}
}
};
waitForTest();
}
}, {
Expand Down Expand Up @@ -1568,7 +1609,7 @@ var GlslCanvas = function () {
var buffer = buffers[key];
var fragment = createShader(glsl, buffer.fragment, gl.FRAGMENT_SHADER, 1);
if (!fragment) {
fragment = createShader(glsl, 'void main(){\n\tgl_FragColor = vec4(1.0);\n}', gl.FRAGMENT_SHADER);
fragment = createShader(glsl, this.defaultShaderStrings.fragmentString, gl.FRAGMENT_SHADER);
kdziamura marked this conversation as resolved.
Show resolved Hide resolved
glsl.isValid = false;
} else {
glsl.isValid = true;
Expand Down Expand Up @@ -1621,11 +1662,13 @@ var GlslCanvas = function () {

}, {
key: 'createBuffer',
value: function createBuffer(W, H, program) {
value: function createBuffer(W, H) {
var gl = this.gl;
var index = this.BUFFER_COUNT;
this.BUFFER_COUNT += 2;
gl.getExtension('OES_texture_float');
if (this.webglVersion === 1) {
gl.getExtension('OES_texture_float');
}
var texture = gl.createTexture();
gl.activeTexture(gl.TEXTURE0 + index);
gl.bindTexture(gl.TEXTURE_2D, texture);
Expand Down
Loading