import { GLShader } from 'pixi-gl-core';
import { WRAP_MODES, SCALE_MODES, PRECISION} from '../../const';
import RenderTarget from './utils/RenderTarget';
import { removeItems } from '../../utils';
/**
* Helper class to create a webGL Texture
*
* @class
* @memberof PIXI
*/
export default class ShaderManager
{
/**
* @param {PIXI.WebGLRenderer} renderer - A reference to the current renderer
*/
constructor(renderer)
{
/**
* A reference to the current renderer
*
* @member {PIXI.WebGLRenderer}
*/
this.renderer = renderer;
/**
* The current WebGL rendering context
*
* @member {WebGLRenderingContext}
*/
this.gl = renderer.gl;
}
bindShader(shader)
{
let glShader = shader.glShaders[renderer.CONTEXT_UID] || this.generateShader(shader);
this.renderer._bindGLShader(glShader);
this.syncUniforms(glShader, shader);
}
generateShader(shader)
{
const attribMap = {};
for (const i in shader.attributeData)
{
attribMap[i] = shader.attributeData[i].location;
}
const glShader = new GLShader(this.gl, shader.vertexSrc, shader.fragmentSrc, PRECISION.DEFAULT, attribMap);
//TODO should I add this a s a prototype
glShader.dirtyFlags = {};
for (var i in shader.realUniforms) {
glShader.dirtyFlags[i] = 0;
};
console.log(glShader.dirtyFlags)
shader.glShaders[renderer.CONTEXT_UID] = glShader;
return glShader
}
/**
* Uploads the uniforms of the filter.
*
* @param {GLShader} shader - The underlying gl shader.
* @param {PIXI.Filter} filter - The filter we are synchronizing.
*/
syncUniforms(glShader, shader)
{
const uniformData = shader.uniformData;
const realUniforms = shader.realUniforms;
const dirtyFlags = glShader.dirtyFlags;
// 0 is reserverd for the pixi texture so we start at 1!
let textureCount = 1;
// TODO don't need to use the uniform
for (const i in uniformData)
{
if(dirtyFlags[i] === uniformData[i].dirtyId)
{
continue;
}
dirtyFlags[i] = uniformData[i].dirtyId;
if (uniformData[i].type === 'sampler2D' && uniformData[i].value !== 0)
{
if (uniformData[i].value.baseTexture)
{
glShader.uniforms[i] = this.renderer.bindTexture(uniformData[i].value, textureCount);
}
else
{
glShader.uniforms[i] = textureCount;
// TODO
// this is helpful as renderTargets can also be set.
// Although thinking about it, we could probably
// make the filter texture cache return a RenderTexture
// rather than a renderTarget
const gl = this.renderer.gl;
gl.activeTexture(gl.TEXTURE0 + textureCount);
uniforms[i].texture.bind();
}
textureCount++;
}
else if (uniformData[i].type === 'mat3')
{
// check if its pixi matrix..
if (uniformData[i].value.a !== undefined)
{
glShader.uniforms[i] = uniformData[i].value.toArray(true);
}
else
{
glShader.uniforms[i] = uniformData[i].value;
}
}
else if (uniformData[i].type === 'vec2')
{
// check if its a point..
if (uniformData[i].value.x !== undefined)
{
const val = glShader.uniforms[i] || new Float32Array(2);
val[0] = uniformData[i].value.x;
val[1] = uniformData[i].value.y;
glShader.uniforms[i] = val;
}
else
{
glShader.uniforms[i] = uniformData[i].value;
}
}
else if (uniformData[i].type === 'float')
{
if (glShader.uniforms.data[i].value !== uniformData[i].value)
{
glShader.uniforms[i] = uniformData[i].value;
}
}
else
{
glShader.uniforms[i] = uniformData[i].value;
}
}
}
/**
* Destroys this manager and removes all its textures
*/
destroy()
{
}
}