import extractUniformsFromSrc from './extractUniformsFromSrc';
import extractAttributesFromSrc from './extractAttributesFromSrc';
import generateUniformsSync from './generateUniformsSync';
let UID = 0;
// let math = require('../../../math');
/**
* @class
* @memberof PIXI
* @extends PIXI.Shader
*/
class Shader
{
/**
* @param {string} [vertexSrc] - The source of the vertex shader.
* @param {string} [fragmentSrc] - The source of the fragment shader.
* @param {object} [uniforms] - Custom uniforms to use to augment the built-in ones.
*/
constructor(vertexSrc, fragmentSrc, uniforms)
{
/**
* The vertex shader.
*
* @member {string}
*/
this.vertexSrc = vertexSrc || Shader.defaultVertexSrc;
/**
* The fragment shader.
*
* @member {string}
*/
this.fragmentSrc = fragmentSrc || Shader.defaultFragmentSrc;
// pull out the vertex and shader uniforms if they are not specified..
// currently this does not extract structs only default types
this.uniformData = uniforms || extractUniformsFromSrc(this.vertexSrc, this.fragmentSrc);
// TODO - 'projectionMatrix|uSampler|translationMatrix');
this.attributeData = extractAttributesFromSrc(this.vertexSrc);
this.uniforms = {};
// time to build some getters and setters!
// I guess down the line this could sort of generate an instruction list rather than use dirty ids?
// does the trick for now though!
for (const i in this.uniformData)
{
if (!this.uniforms[i])
{
this.uniforms[i] = this.uniformData[i].value;
}
}
// this is where we store shader references..
// TODO we could cache this!
this.glShaders = {};
this.syncUniforms = generateUniformsSync(this.uniformData);
this.id = UID++;
}
/**
* The default vertex shader source
*
* @static
* @constant
*/
static get defaultVertexSrc()
{
return [
'attribute vec2 aVertexPosition;',
'attribute vec2 aTextureCoord;',
'uniform mat3 projectionMatrix;',
'uniform mat3 filterMatrix;',
'varying vec2 vTextureCoord;',
'varying vec2 vFilterCoord;',
'void main(void){',
' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);',
' vFilterCoord = ( filterMatrix * vec3( aTextureCoord, 1.0) ).xy;',
' vTextureCoord = aTextureCoord ;',
'}',
].join('\n');
}
/**
* The default fragment shader source
*
* @static
* @constant
*/
static get defaultFragmentSrc()
{
return [
'varying vec2 vTextureCoord;',
'varying vec2 vFilterCoord;',
'uniform sampler2D uSampler;',
'uniform sampler2D filterSampler;',
'void main(void){',
' vec4 masky = texture2D(filterSampler, vFilterCoord);',
' vec4 sample = texture2D(uSampler, vTextureCoord);',
' vec4 color;',
' if(mod(vFilterCoord.x, 1.0) > 0.5)',
' {',
' color = vec4(1.0, 0.0, 0.0, 1.0);',
' }',
' else',
' {',
' color = vec4(0.0, 1.0, 0.0, 1.0);',
' }',
' gl_FragColor = mix(sample, masky, 0.5);',
' gl_FragColor *= sample.a;',
'}',
].join('\n');
}
}
export default Shader;