Skip to content

Commit 01e7c44

Browse files
vladbat00devongovett
authored andcommitted
Add GLSL assets support (#831)
1 parent 76fa1ed commit 01e7c44

12 files changed

Lines changed: 335 additions & 14 deletions

File tree

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@
7171
"coffeescript": "^2.0.3",
7272
"cross-env": "^5.1.1",
7373
"eslint": "^4.13.0",
74+
"glslify-bundle": "^5.0.0",
75+
"glslify-deps": "^1.3.0",
7476
"graphql": "^0.11.7",
7577
"graphql-tag": "^2.6.0",
7678
"husky": "^0.14.3",

src/Parser.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ class Parser {
3838

3939
this.registerExtension('webmanifest', './assets/WebManifestAsset');
4040

41+
this.registerExtension('glsl', './assets/GLSLAsset');
42+
this.registerExtension('vert', './assets/GLSLAsset');
43+
this.registerExtension('frag', './assets/GLSLAsset');
44+
4145
let extensions = options.extensions || {};
4246
for (let ext in extensions) {
4347
this.registerExtension(ext, extensions[ext]);

src/Resolver.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,10 @@ class Resolver {
4141
}
4242

4343
// Get file extensions to search
44-
let extensions = Object.keys(this.options.extensions);
44+
let extensions = Array.isArray(this.options.extensions)
45+
? this.options.extensions.slice()
46+
: Object.keys(this.options.extensions);
47+
4548
if (parent) {
4649
// parent's extension given high priority
4750
const parentExt = path.extname(parent);

src/assets/GLSLAsset.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
const Asset = require('../Asset');
2+
const localRequire = require('../utils/localRequire');
3+
const path = require('path');
4+
const promisify = require('../utils/promisify');
5+
const Resolver = require('../Resolver');
6+
7+
class GLSLAsset extends Asset {
8+
constructor(name, pkg, options) {
9+
super(name, pkg, options);
10+
this.type = 'js';
11+
}
12+
13+
async parse() {
14+
const glslifyDeps = await localRequire('glslify-deps', this.name);
15+
16+
// Use the Parcel resolver rather than the default glslify one.
17+
// This adds support for parcel features like alises, and tilde paths.
18+
const resolver = new Resolver({
19+
extensions: ['.glsl', '.vert', '.frag'],
20+
rootDir: this.options.rootDir
21+
});
22+
23+
// Parse and collect dependencies with glslify-deps
24+
let cwd = path.dirname(this.name);
25+
let depper = glslifyDeps({
26+
cwd,
27+
resolve: async (target, opts, next) => {
28+
try {
29+
let res = await resolver.resolve(
30+
target,
31+
path.join(opts.basedir, 'index')
32+
);
33+
next(null, res.path);
34+
} catch (err) {
35+
next(err);
36+
}
37+
}
38+
});
39+
40+
return await promisify(depper.inline.bind(depper))(this.contents, cwd);
41+
}
42+
43+
collectDependencies() {
44+
for (let dep of this.ast) {
45+
if (!dep.entry) {
46+
this.addDependency(dep.file, {includedInParent: true});
47+
}
48+
}
49+
}
50+
51+
async generate() {
52+
// Generate the bundled glsl file
53+
const glslifyBundle = await localRequire('glslify-bundle', this.name);
54+
let glsl = glslifyBundle(this.ast);
55+
56+
return {
57+
js: `module.exports=${JSON.stringify(glsl)};`
58+
};
59+
}
60+
}
61+
62+
module.exports = GLSLAsset;

test/glsl.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
const assert = require('assert');
2+
const fs = require('fs');
3+
const {bundle, run, assertBundleTree} = require('./utils');
4+
5+
describe('glsl', function() {
6+
it('should support requiring GLSL files via glslify', async function() {
7+
let b = await bundle(__dirname + '/integration/glsl/index.js');
8+
9+
assertBundleTree(b, {
10+
name: 'index.js',
11+
assets: ['index.js', 'local.glsl', 'local.vert', 'local.frag'],
12+
childBundles: [
13+
{
14+
type: 'map'
15+
}
16+
]
17+
});
18+
19+
let shader = fs.readFileSync(
20+
__dirname + '/integration/glsl/compiled.glsl',
21+
'utf8'
22+
);
23+
24+
let output = run(b);
25+
assert.equal(typeof output, 'function');
26+
assert.ok(
27+
output().reduce((acc, requiredShader) => {
28+
return acc && shader === requiredShader;
29+
}, true)
30+
);
31+
});
32+
});
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#version 300 es
2+
3+
void someUniqFunction() {
4+
}
5+
6+
precision mediump float;
7+
#define GLSLIFY 1
8+
9+
void main() {
10+
someUniqFunction();
11+
}

test/integration/glsl/index.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
const shaders = [
2+
require('./local.glsl'),
3+
require('./local.vert'),
4+
require('./local.frag'),
5+
];
6+
7+
module.exports = function () {
8+
return shaders;
9+
};

test/integration/glsl/lib.glsl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
void someUniqFunction() {
2+
}
3+
4+
#pragma glslify: export(someUniqFunction)

test/integration/glsl/local.frag

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#version 300 es
2+
3+
#pragma glslify: test = require('./lib')
4+
5+
precision mediump float;
6+
7+
void main() {
8+
test();
9+
}

test/integration/glsl/local.glsl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#version 300 es
2+
3+
#pragma glslify: test = require('./lib.glsl')
4+
5+
precision mediump float;
6+
7+
void main() {
8+
test();
9+
}

0 commit comments

Comments
 (0)