const GLSL_TO_SINGLE_SETTERS_CACHED = {
float: `if(cacheValue !== value)
{
cacheValue.value = value;
gl.uniform1f(location, value)
}`,
vec2: `if(cacheValue[0] !== value[0] || cacheValue[1] !== value[1])
{
cacheValue[0] = value[0];
cacheValue[1] = value[1];
gl.uniform2f(location, value[0], value[1])
}`,
vec3: `if(cacheValue[0] !== value[0] || cacheValue[1] !== value[1] || cacheValue[2] !== value[2])
{
cacheValue[0] = value[0];
cacheValue[1] = value[1];
cacheValue[2] = value[2];
gl.uniform3f(location, value[0], value[1], value[2])
}`,
vec4: 'gl.uniform4f(location, value[0], value[1], value[2], value[3])',
int: 'gl.uniform1i(location, value)',
ivec2: 'gl.uniform2i(location, value[0], value[1])',
ivec3: 'gl.uniform3i(location, value[0], value[1], value[2])',
ivec4: 'gl.uniform4i(location, value[0], value[1], value[2], value[3])',
bool: 'gl.uniform1i(location, value)',
bvec2: 'gl.uniform2i(location, value[0], value[1])',
bvec3: 'gl.uniform3i(location, value[0], value[1], value[2])',
bvec4: 'gl.uniform4i(location, value[0], value[1], value[2], value[3])',
mat2: 'gl.uniformMatrix2fv(location, false, value)',
mat3: 'gl.uniformMatrix3fv(location, false, value)',
mat4: 'gl.uniformMatrix4fv(location, false, value)',
sampler2D: 'gl.uniform1i(location, value)',
samplerCube: 'gl.uniform1i(location, value)',
sampler2DArray: 'gl.uniform1i(location, value)',
};
const GLSL_TO_ARRAY_SETTERS = {
float: `gl.uniform1fv(location, value)`,
vec2: `gl.uniform2fv(location, value)`,
vec3: `gl.uniform3fv(location, value)`,
vec4: 'gl.uniform4fv(location, value)',
int: 'gl.uniform1iv(location, value)',
ivec2: 'gl.uniform2iv(location, value)',
ivec3: 'gl.uniform3iv(location, value)',
ivec4: 'gl.uniform4iv(location, value)',
bool: 'gl.uniform1iv(location, value)',
bvec2: 'gl.uniform2iv(location, value)',
bvec3: 'gl.uniform3iv(location, value)',
bvec4: 'gl.uniform4iv(location, value)',
sampler2D: 'gl.uniform1iv(location, value)',
samplerCube: 'gl.uniform1iv(location, value)',
sampler2DArray: 'gl.uniform1iv(location, value)',
};
export default function generateUniformsSync2(group, uniformData)
{
let textureCount = 0;
let func = `var value = null;
var cacheValue = null
var gl = renderer.gl`;
for (const i in group.uniforms)
{
const data = uniformData[i];
//group.uniforms[i];
// console.log(i, data);
if(!data)
{
if(group.uniforms[i].group)
{
func += `
renderer.shader.syncUniformGroup(uniformValues.${i});
`
}
continue;
}
// TODO && uniformData[i].value !== 0 <-- do we still need this?
if (data.type === 'float' && data.size === 1)
{
func += `\nif(uniformValues.${i} !== uniformData.${i}.value)
{
uniformData.${i}.value = uniformValues.${i}
gl.uniform1f(uniformData.${i}.location, uniformValues.${i})
}\n`;
}
else if ( (data.type === 'sampler2D' || data.type === 'samplerCube' || data.type === 'sampler2DArray') && data.size === 1)
{
func += `\nif (uniformValues.${i}.baseTexture)
{
renderer.texture.bind(uniformValues.${i}, ${textureCount})
if(uniformData.${i}.value !== ${textureCount})
{
uniformData.${i}.value = ${textureCount};
gl.uniform1i(uniformData.${i}.location, ${textureCount});\n; // eslint-disable-line max-len
}
/*
var location = renderer.bindTexture(uniformValues.${i}.baseTexture, ${textureCount}, false);
if(uniformData.${i}.value !== location)
{
uniformData.${i}.value = location;
gl.uniform1i(uniformData.${i}.location, location);\n; // eslint-disable-line max-len
}*/
}
else if(uniformValues.${i}._new)
{
renderer.texture.bind(uniformValues.${i}, ${textureCount})
if(uniformData.${i}.value !== ${textureCount})
{
uniformData.${i}.value = ${textureCount};
gl.uniform1i(uniformData.${i}.location, ${textureCount});\n; // eslint-disable-line max-len
}
}
else
{
// console.log("binding..")
uniformData.${i}.value = ${textureCount};
renderer.boundTextures[${textureCount}] = renderer.emptyTextures[${textureCount}];
gl.activeTexture(gl.TEXTURE0 + ${textureCount});
uniformValues.${i}.bind();
}`;
textureCount++;
}
else if (data.type === 'mat3' && data.size === 1)
{
func += `\nvalue = uniformValues.${i};
gl.uniformMatrix3fv(uniformData.${i}.location, false, (value.a === undefined) ? value : value.toArray(true));\n`;
}
else if (data.type === 'vec2' && data.size === 1)
{
// TODO - do we need both here?
// maybe we can get away with only using points?
func += `\ncacheValue = uniformData.${i}.value;
value = uniformValues.${i};
if(value.x !== undefined)
{
if(cacheValue[0] !== value.x || cacheValue[1] !== value.y)
{
cacheValue[0] = value.x;
cacheValue[1] = value.y;
gl.uniform2f(uniformData.${i}.location, value.x, value.y);
}
}
else
{
if(cacheValue[0] !== value[0] || cacheValue[1] !== value[1])
{
cacheValue[0] = value[0];
cacheValue[1] = value[1];
gl.uniform2f(uniformData.${i}.location, value[0], value[1]);
}
}\n`;
}
else
{
const templateType = (data.size === 1) ? GLSL_TO_SINGLE_SETTERS_CACHED : GLSL_TO_ARRAY_SETTERS;
const template = templateType[data.type].replace('location', `uniformData.${i}.location`);
func += `\ncacheValue = uniformData.${i}.value;
value = uniformValues.${i};
${template};\n`;
}
}
console.log(' --------------- ')
console.log(func);
return new Function('uniformData', 'uniformValues', 'renderer', func); // eslint-disable-line no-new-func
}