diff --git a/src/core/renderers/webgl/systems/geometry/GeometrySystem.js b/src/core/renderers/webgl/systems/geometry/GeometrySystem.js index be19ee5..3f95a06 100644 --- a/src/core/renderers/webgl/systems/geometry/GeometrySystem.js +++ b/src/core/renderers/webgl/systems/geometry/GeometrySystem.js @@ -307,6 +307,7 @@ if(attribute.instance) { + //TODO calculate instance count based of this... if(this.hasInstance) { gl.vertexAttribDivisor(location, 1); diff --git a/src/core/renderers/webgl/systems/geometry/GeometrySystem.js b/src/core/renderers/webgl/systems/geometry/GeometrySystem.js index be19ee5..3f95a06 100644 --- a/src/core/renderers/webgl/systems/geometry/GeometrySystem.js +++ b/src/core/renderers/webgl/systems/geometry/GeometrySystem.js @@ -307,6 +307,7 @@ if(attribute.instance) { + //TODO calculate instance count based of this... if(this.hasInstance) { gl.vertexAttribDivisor(location, 1); diff --git a/src/core/renderers/webgl/systems/shader/ShaderSystem.js b/src/core/renderers/webgl/systems/shader/ShaderSystem.js index 0ee6743..670dd72 100644 --- a/src/core/renderers/webgl/systems/shader/ShaderSystem.js +++ b/src/core/renderers/webgl/systems/shader/ShaderSystem.js @@ -1,7 +1,7 @@ import WebGLSystem from '../WebGLSystem'; import GLShader from './GLShader'; import { PRECISION } from '../../../../const'; -import generateUniformsSync from '../../../../shader/generateUniformsSync2'; +import generateUniformsSync from '../../../../shader/generateUniformsSync'; let UID = 0; diff --git a/src/core/renderers/webgl/systems/geometry/GeometrySystem.js b/src/core/renderers/webgl/systems/geometry/GeometrySystem.js index be19ee5..3f95a06 100644 --- a/src/core/renderers/webgl/systems/geometry/GeometrySystem.js +++ b/src/core/renderers/webgl/systems/geometry/GeometrySystem.js @@ -307,6 +307,7 @@ if(attribute.instance) { + //TODO calculate instance count based of this... if(this.hasInstance) { gl.vertexAttribDivisor(location, 1); diff --git a/src/core/renderers/webgl/systems/shader/ShaderSystem.js b/src/core/renderers/webgl/systems/shader/ShaderSystem.js index 0ee6743..670dd72 100644 --- a/src/core/renderers/webgl/systems/shader/ShaderSystem.js +++ b/src/core/renderers/webgl/systems/shader/ShaderSystem.js @@ -1,7 +1,7 @@ import WebGLSystem from '../WebGLSystem'; import GLShader from './GLShader'; import { PRECISION } from '../../../../const'; -import generateUniformsSync from '../../../../shader/generateUniformsSync2'; +import generateUniformsSync from '../../../../shader/generateUniformsSync'; let UID = 0; diff --git a/src/core/shader/Shader.js b/src/core/shader/Shader.js index 005402d..2f8dc56 100644 --- a/src/core/shader/Shader.js +++ b/src/core/shader/Shader.js @@ -42,7 +42,7 @@ { if (this.uniformGroup.uniforms[i] instanceof Array) { - this.uniformGroup.uniforms[i] = new Float32Array(uniform); + this.uniformGroup.uniforms[i] = new Float32Array(this.uniformGroup.uniforms[i]); } } } @@ -74,37 +74,7 @@ { return this.uniformGroup.uniforms; } -/* -var offsetBuffer = gl.createBuffer(); -gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer); -gl.bufferData(gl.ARRAY_BUFFER, offsets, gl.STATIC_DRAW); - -var colorBuffer = gl.createBuffer(); -gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); -gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW); - -var instanceCount = 4; -var ext = gl.getExtension("ANGLE_instanced_arrays"); // Vendor prefixes may apply! - -// Bind the rest of the vertex attributes normally -bindMeshArrays(gl); - -// Bind the instance position data -gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer); -gl.enableVertexAttribArray(offsetLocation); -gl.vertexAttribPointer(offsetLocation, 3, gl.FLOAT, false, 12, 0); -ext.vertexAttribDivisorANGLE(offsetLocation, 1); // This makes it instanced! - -// Bind the instance color data -gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); -gl.enableVertexAttribArray(colorLocation); -gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 16, 0); -ext.vertexAttribDivisorANGLE(colorLocation, 1); // This makes it instanced! - -// Draw the instanced meshes -ext.drawElementsInstancedANGLE(gl.TRIANGLES, indexCount, gl.UNSIGNED_SHORT, 0, instanceCount); -*/ /** * A short hand function to create a shader based of a vertex and fragment shader * diff --git a/src/core/renderers/webgl/systems/geometry/GeometrySystem.js b/src/core/renderers/webgl/systems/geometry/GeometrySystem.js index be19ee5..3f95a06 100644 --- a/src/core/renderers/webgl/systems/geometry/GeometrySystem.js +++ b/src/core/renderers/webgl/systems/geometry/GeometrySystem.js @@ -307,6 +307,7 @@ if(attribute.instance) { + //TODO calculate instance count based of this... if(this.hasInstance) { gl.vertexAttribDivisor(location, 1); diff --git a/src/core/renderers/webgl/systems/shader/ShaderSystem.js b/src/core/renderers/webgl/systems/shader/ShaderSystem.js index 0ee6743..670dd72 100644 --- a/src/core/renderers/webgl/systems/shader/ShaderSystem.js +++ b/src/core/renderers/webgl/systems/shader/ShaderSystem.js @@ -1,7 +1,7 @@ import WebGLSystem from '../WebGLSystem'; import GLShader from './GLShader'; import { PRECISION } from '../../../../const'; -import generateUniformsSync from '../../../../shader/generateUniformsSync2'; +import generateUniformsSync from '../../../../shader/generateUniformsSync'; let UID = 0; diff --git a/src/core/shader/Shader.js b/src/core/shader/Shader.js index 005402d..2f8dc56 100644 --- a/src/core/shader/Shader.js +++ b/src/core/shader/Shader.js @@ -42,7 +42,7 @@ { if (this.uniformGroup.uniforms[i] instanceof Array) { - this.uniformGroup.uniforms[i] = new Float32Array(uniform); + this.uniformGroup.uniforms[i] = new Float32Array(this.uniformGroup.uniforms[i]); } } } @@ -74,37 +74,7 @@ { return this.uniformGroup.uniforms; } -/* -var offsetBuffer = gl.createBuffer(); -gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer); -gl.bufferData(gl.ARRAY_BUFFER, offsets, gl.STATIC_DRAW); - -var colorBuffer = gl.createBuffer(); -gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); -gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW); - -var instanceCount = 4; -var ext = gl.getExtension("ANGLE_instanced_arrays"); // Vendor prefixes may apply! - -// Bind the rest of the vertex attributes normally -bindMeshArrays(gl); - -// Bind the instance position data -gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer); -gl.enableVertexAttribArray(offsetLocation); -gl.vertexAttribPointer(offsetLocation, 3, gl.FLOAT, false, 12, 0); -ext.vertexAttribDivisorANGLE(offsetLocation, 1); // This makes it instanced! - -// Bind the instance color data -gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); -gl.enableVertexAttribArray(colorLocation); -gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 16, 0); -ext.vertexAttribDivisorANGLE(colorLocation, 1); // This makes it instanced! - -// Draw the instanced meshes -ext.drawElementsInstancedANGLE(gl.TRIANGLES, indexCount, gl.UNSIGNED_SHORT, 0, instanceCount); -*/ /** * A short hand function to create a shader based of a vertex and fragment shader * diff --git a/src/core/shader/UniformGroup.js b/src/core/shader/UniformGroup.js index 8768226..e2ed22a 100644 --- a/src/core/shader/UniformGroup.js +++ b/src/core/shader/UniformGroup.js @@ -1,5 +1,3 @@ -import Program from './Program'; -import generateUniformsSync from './generateUniformsSync'; let UID = 0; diff --git a/src/core/renderers/webgl/systems/geometry/GeometrySystem.js b/src/core/renderers/webgl/systems/geometry/GeometrySystem.js index be19ee5..3f95a06 100644 --- a/src/core/renderers/webgl/systems/geometry/GeometrySystem.js +++ b/src/core/renderers/webgl/systems/geometry/GeometrySystem.js @@ -307,6 +307,7 @@ if(attribute.instance) { + //TODO calculate instance count based of this... if(this.hasInstance) { gl.vertexAttribDivisor(location, 1); diff --git a/src/core/renderers/webgl/systems/shader/ShaderSystem.js b/src/core/renderers/webgl/systems/shader/ShaderSystem.js index 0ee6743..670dd72 100644 --- a/src/core/renderers/webgl/systems/shader/ShaderSystem.js +++ b/src/core/renderers/webgl/systems/shader/ShaderSystem.js @@ -1,7 +1,7 @@ import WebGLSystem from '../WebGLSystem'; import GLShader from './GLShader'; import { PRECISION } from '../../../../const'; -import generateUniformsSync from '../../../../shader/generateUniformsSync2'; +import generateUniformsSync from '../../../../shader/generateUniformsSync'; let UID = 0; diff --git a/src/core/shader/Shader.js b/src/core/shader/Shader.js index 005402d..2f8dc56 100644 --- a/src/core/shader/Shader.js +++ b/src/core/shader/Shader.js @@ -42,7 +42,7 @@ { if (this.uniformGroup.uniforms[i] instanceof Array) { - this.uniformGroup.uniforms[i] = new Float32Array(uniform); + this.uniformGroup.uniforms[i] = new Float32Array(this.uniformGroup.uniforms[i]); } } } @@ -74,37 +74,7 @@ { return this.uniformGroup.uniforms; } -/* -var offsetBuffer = gl.createBuffer(); -gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer); -gl.bufferData(gl.ARRAY_BUFFER, offsets, gl.STATIC_DRAW); - -var colorBuffer = gl.createBuffer(); -gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); -gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW); - -var instanceCount = 4; -var ext = gl.getExtension("ANGLE_instanced_arrays"); // Vendor prefixes may apply! - -// Bind the rest of the vertex attributes normally -bindMeshArrays(gl); - -// Bind the instance position data -gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer); -gl.enableVertexAttribArray(offsetLocation); -gl.vertexAttribPointer(offsetLocation, 3, gl.FLOAT, false, 12, 0); -ext.vertexAttribDivisorANGLE(offsetLocation, 1); // This makes it instanced! - -// Bind the instance color data -gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); -gl.enableVertexAttribArray(colorLocation); -gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 16, 0); -ext.vertexAttribDivisorANGLE(colorLocation, 1); // This makes it instanced! - -// Draw the instanced meshes -ext.drawElementsInstancedANGLE(gl.TRIANGLES, indexCount, gl.UNSIGNED_SHORT, 0, instanceCount); -*/ /** * A short hand function to create a shader based of a vertex and fragment shader * diff --git a/src/core/shader/UniformGroup.js b/src/core/shader/UniformGroup.js index 8768226..e2ed22a 100644 --- a/src/core/shader/UniformGroup.js +++ b/src/core/shader/UniformGroup.js @@ -1,5 +1,3 @@ -import Program from './Program'; -import generateUniformsSync from './generateUniformsSync'; let UID = 0; diff --git a/src/core/shader/generateUniformsSync.js b/src/core/shader/generateUniformsSync.js index b7241ef..8a7cf55 100644 --- a/src/core/shader/generateUniformsSync.js +++ b/src/core/shader/generateUniformsSync.js @@ -1,153 +1,190 @@ + + +//cv = CachedValue +//v = value +//ud = uniformData +//uv = uniformValue +//l = loaction const GLSL_TO_SINGLE_SETTERS_CACHED = { - float: `if(cacheValue !== value) -{ - cacheValue.value = value; - gl.uniform1f(location, value) -}`, + float:` + if(cv !== v) + { + cv.v = v; + gl.uniform1f(location, v) + }`, - 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]; + vec2:` + if(cv[0] !== v[0] || cv[1] !== v[1]) + { + cv[0] = v[0]; + cv[1] = v[1]; + gl.uniform2f(location, v[0], v[1]) + }`, - gl.uniform3f(location, value[0], value[1], value[2]) -}`, - vec4: 'gl.uniform4f(location, value[0], value[1], value[2], value[3])', + vec3:` + if(cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2]) + { + cv[0] = v[0]; + cv[1] = v[1]; + cv[2] = v[2]; - 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])', + gl.uniform3f(location, v[0], v[1], v[2]) + }`, - 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])', + vec4: 'gl.uniform4f(location, v[0], v[1], v[2], v[3])', - mat2: 'gl.uniformMatrix2fv(location, false, value)', - mat3: 'gl.uniformMatrix3fv(location, false, value)', - mat4: 'gl.uniformMatrix4fv(location, false, value)', + int: 'gl.uniform1i(location, v)', + ivec2: 'gl.uniform2i(location, v[0], v[1])', + ivec3: 'gl.uniform3i(location, v[0], v[1], v[2])', + ivec4: 'gl.uniform4i(location, v[0], v[1], v[2], v[3])', - sampler2D: 'gl.uniform1i(location, value)', - samplerCube: 'gl.uniform1i(location, value)' + bool: 'gl.uniform1i(location, v)', + bvec2: 'gl.uniform2i(location, v[0], v[1])', + bvec3: 'gl.uniform3i(location, v[0], v[1], v[2])', + bvec4: 'gl.uniform4i(location, v[0], v[1], v[2], v[3])', + + mat2: 'gl.uniformMatrix2fv(location, false, v)', + mat3: 'gl.uniformMatrix3fv(location, false, v)', + mat4: 'gl.uniformMatrix4fv(location, false, v)', + + sampler2D: 'gl.uniform1i(location, v)', + samplerCube: 'gl.uniform1i(location, v)', + sampler2DArray: 'gl.uniform1i(location, v)', }; const GLSL_TO_ARRAY_SETTERS = { - float: `gl.uniform1fv(location, value)`, + float: `gl.uniform1fv(location, v)`, - vec2: `gl.uniform2fv(location, value)`, - vec3: `gl.uniform3fv(location, value)`, - vec4: 'gl.uniform4fv(location, value)', + vec2: `gl.uniform2fv(location, v)`, + vec3: `gl.uniform3fv(location, v)`, + vec4: 'gl.uniform4fv(location, v)', - int: 'gl.uniform1iv(location, value)', - ivec2: 'gl.uniform2iv(location, value)', - ivec3: 'gl.uniform3iv(location, value)', - ivec4: 'gl.uniform4iv(location, value)', + int: 'gl.uniform1iv(location, v)', + ivec2: 'gl.uniform2iv(location, v)', + ivec3: 'gl.uniform3iv(location, v)', + ivec4: 'gl.uniform4iv(location, v)', - bool: 'gl.uniform1iv(location, value)', - bvec2: 'gl.uniform2iv(location, value)', - bvec3: 'gl.uniform3iv(location, value)', - bvec4: 'gl.uniform4iv(location, value)', + bool: 'gl.uniform1iv(location, v)', + bvec2: 'gl.uniform2iv(location, v)', + bvec3: 'gl.uniform3iv(location, v)', + bvec4: 'gl.uniform4iv(location, v)', - sampler2D: 'gl.uniform1iv(location, value)', - samplerCube: 'gl.uniform1iv(location, value)' + sampler2D: 'gl.uniform1iv(location, v)', + samplerCube: 'gl.uniform1iv(location, v)', + sampler2DArray: 'gl.uniform1iv(location, v)', }; -export default function generateUniformsSync(uniformData) + +export default function generateUniformsSync(group, uniformData) { - let textureCount = 1; - let func = `var value = null; - var cacheValue = null + let textureCount = 0; + let func = `var v = null; + var cv = null var gl = renderer.gl`; - for (const i in uniformData) + for (const i in group.uniforms) { const data = uniformData[i]; - // console.log(i, data.size); + + if(!data) + { + if(group.uniforms[i].group) + { + func += ` + renderer.shader.syncUniformGroup(uv.${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`; + func += ` + if(uv.${i} !== ud.${i}.value) + { + ud.${i}.value = uv.${i} + gl.uniform1f(ud.${i}.location, uv.${i}) + }\n`; } - else if (data.type === 'sampler2D' && data.size === 1) + else if ( (data.type === 'sampler2D' || data.type === 'samplerCube' || data.type === 'sampler2DArray') && data.size === 1 && !data.isArray) { - func += `\nif (uniformValues.${i}.baseTexture) -{ - var location = renderer.bindTexture(uniformValues.${i}.baseTexture, ${textureCount++}, false); + func += ` + renderer.texture.bind(uv.${i}, ${textureCount}); - if(uniformData.${i}.value !== location) - { - uniformData.${i}.value = location; - gl.uniform1i(uniformData.${i}.location, location);\n; // eslint-disable-line max-len - } -} -else -{ - uniformData.${i}.value = ${textureCount}; - renderer.boundTextures[${textureCount}] = renderer.emptyTextures[${textureCount}]; - gl.activeTexture(gl.TEXTURE0 + ${textureCount++}); + if(ud.${i}.value !== ${textureCount}) + { + ud.${i}.value = ${textureCount}; + gl.uniform1i(ud.${i}.location, ${textureCount});\n; // eslint-disable-line max-len + }\n` - 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`; + if(group.uniforms[i].a !== undefined) + { + // TODO and some smart caching dirty ids here! + func += ` + gl.uniformMatrix3fv(ud.${i}.location, false, uv.${i}.toArray(true)); + \n`; + } + else + { + func += ` + gl.uniformMatrix3fv(ud.${i}.location, false, uv.${i}); + \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(group.uniforms[i].x !== undefined) + { + func += ` + cv = ud.${i}.value; + v = uv.${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`; + if(cv[0] !== v.x || cv[1] !== v.y) + { + cv[0] = v.x; + cv[1] = v.y; + gl.uniform2f(ud.${i}.location, v.x, v.y); + }\n`; + } + else + { + func += ` + cv = ud.${i}.value; + v = uv.${i}; + + if(cv[0] !== v[0] || cv[1] !== v[1]) + { + cv[0] = v[0]; + cv[1] = v[1]; + gl.uniform2f(ud.${i}.location, v[0], v[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`); + const template = templateType[data.type].replace('location', `ud.${i}.location`); - func += `\ncacheValue = uniformData.${i}.value; -value = uniformValues.${i}; -${template};\n`; + func += ` + cv = ud.${i}.value; + v = uv.${i}; + ${template};\n`; } } - //console.log(' --------------- ') - // console.log(func); + // console.log(' --------------- ') + // console.log(func); - return new Function('uniformData', 'uniformValues', 'renderer', func); // eslint-disable-line no-new-func + return new Function('ud', 'uv', 'renderer', func); // eslint-disable-line no-new-func } diff --git a/src/core/renderers/webgl/systems/geometry/GeometrySystem.js b/src/core/renderers/webgl/systems/geometry/GeometrySystem.js index be19ee5..3f95a06 100644 --- a/src/core/renderers/webgl/systems/geometry/GeometrySystem.js +++ b/src/core/renderers/webgl/systems/geometry/GeometrySystem.js @@ -307,6 +307,7 @@ if(attribute.instance) { + //TODO calculate instance count based of this... if(this.hasInstance) { gl.vertexAttribDivisor(location, 1); diff --git a/src/core/renderers/webgl/systems/shader/ShaderSystem.js b/src/core/renderers/webgl/systems/shader/ShaderSystem.js index 0ee6743..670dd72 100644 --- a/src/core/renderers/webgl/systems/shader/ShaderSystem.js +++ b/src/core/renderers/webgl/systems/shader/ShaderSystem.js @@ -1,7 +1,7 @@ import WebGLSystem from '../WebGLSystem'; import GLShader from './GLShader'; import { PRECISION } from '../../../../const'; -import generateUniformsSync from '../../../../shader/generateUniformsSync2'; +import generateUniformsSync from '../../../../shader/generateUniformsSync'; let UID = 0; diff --git a/src/core/shader/Shader.js b/src/core/shader/Shader.js index 005402d..2f8dc56 100644 --- a/src/core/shader/Shader.js +++ b/src/core/shader/Shader.js @@ -42,7 +42,7 @@ { if (this.uniformGroup.uniforms[i] instanceof Array) { - this.uniformGroup.uniforms[i] = new Float32Array(uniform); + this.uniformGroup.uniforms[i] = new Float32Array(this.uniformGroup.uniforms[i]); } } } @@ -74,37 +74,7 @@ { return this.uniformGroup.uniforms; } -/* -var offsetBuffer = gl.createBuffer(); -gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer); -gl.bufferData(gl.ARRAY_BUFFER, offsets, gl.STATIC_DRAW); - -var colorBuffer = gl.createBuffer(); -gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); -gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW); - -var instanceCount = 4; -var ext = gl.getExtension("ANGLE_instanced_arrays"); // Vendor prefixes may apply! - -// Bind the rest of the vertex attributes normally -bindMeshArrays(gl); - -// Bind the instance position data -gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer); -gl.enableVertexAttribArray(offsetLocation); -gl.vertexAttribPointer(offsetLocation, 3, gl.FLOAT, false, 12, 0); -ext.vertexAttribDivisorANGLE(offsetLocation, 1); // This makes it instanced! - -// Bind the instance color data -gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); -gl.enableVertexAttribArray(colorLocation); -gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 16, 0); -ext.vertexAttribDivisorANGLE(colorLocation, 1); // This makes it instanced! - -// Draw the instanced meshes -ext.drawElementsInstancedANGLE(gl.TRIANGLES, indexCount, gl.UNSIGNED_SHORT, 0, instanceCount); -*/ /** * A short hand function to create a shader based of a vertex and fragment shader * diff --git a/src/core/shader/UniformGroup.js b/src/core/shader/UniformGroup.js index 8768226..e2ed22a 100644 --- a/src/core/shader/UniformGroup.js +++ b/src/core/shader/UniformGroup.js @@ -1,5 +1,3 @@ -import Program from './Program'; -import generateUniformsSync from './generateUniformsSync'; let UID = 0; diff --git a/src/core/shader/generateUniformsSync.js b/src/core/shader/generateUniformsSync.js index b7241ef..8a7cf55 100644 --- a/src/core/shader/generateUniformsSync.js +++ b/src/core/shader/generateUniformsSync.js @@ -1,153 +1,190 @@ + + +//cv = CachedValue +//v = value +//ud = uniformData +//uv = uniformValue +//l = loaction const GLSL_TO_SINGLE_SETTERS_CACHED = { - float: `if(cacheValue !== value) -{ - cacheValue.value = value; - gl.uniform1f(location, value) -}`, + float:` + if(cv !== v) + { + cv.v = v; + gl.uniform1f(location, v) + }`, - 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]; + vec2:` + if(cv[0] !== v[0] || cv[1] !== v[1]) + { + cv[0] = v[0]; + cv[1] = v[1]; + gl.uniform2f(location, v[0], v[1]) + }`, - gl.uniform3f(location, value[0], value[1], value[2]) -}`, - vec4: 'gl.uniform4f(location, value[0], value[1], value[2], value[3])', + vec3:` + if(cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2]) + { + cv[0] = v[0]; + cv[1] = v[1]; + cv[2] = v[2]; - 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])', + gl.uniform3f(location, v[0], v[1], v[2]) + }`, - 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])', + vec4: 'gl.uniform4f(location, v[0], v[1], v[2], v[3])', - mat2: 'gl.uniformMatrix2fv(location, false, value)', - mat3: 'gl.uniformMatrix3fv(location, false, value)', - mat4: 'gl.uniformMatrix4fv(location, false, value)', + int: 'gl.uniform1i(location, v)', + ivec2: 'gl.uniform2i(location, v[0], v[1])', + ivec3: 'gl.uniform3i(location, v[0], v[1], v[2])', + ivec4: 'gl.uniform4i(location, v[0], v[1], v[2], v[3])', - sampler2D: 'gl.uniform1i(location, value)', - samplerCube: 'gl.uniform1i(location, value)' + bool: 'gl.uniform1i(location, v)', + bvec2: 'gl.uniform2i(location, v[0], v[1])', + bvec3: 'gl.uniform3i(location, v[0], v[1], v[2])', + bvec4: 'gl.uniform4i(location, v[0], v[1], v[2], v[3])', + + mat2: 'gl.uniformMatrix2fv(location, false, v)', + mat3: 'gl.uniformMatrix3fv(location, false, v)', + mat4: 'gl.uniformMatrix4fv(location, false, v)', + + sampler2D: 'gl.uniform1i(location, v)', + samplerCube: 'gl.uniform1i(location, v)', + sampler2DArray: 'gl.uniform1i(location, v)', }; const GLSL_TO_ARRAY_SETTERS = { - float: `gl.uniform1fv(location, value)`, + float: `gl.uniform1fv(location, v)`, - vec2: `gl.uniform2fv(location, value)`, - vec3: `gl.uniform3fv(location, value)`, - vec4: 'gl.uniform4fv(location, value)', + vec2: `gl.uniform2fv(location, v)`, + vec3: `gl.uniform3fv(location, v)`, + vec4: 'gl.uniform4fv(location, v)', - int: 'gl.uniform1iv(location, value)', - ivec2: 'gl.uniform2iv(location, value)', - ivec3: 'gl.uniform3iv(location, value)', - ivec4: 'gl.uniform4iv(location, value)', + int: 'gl.uniform1iv(location, v)', + ivec2: 'gl.uniform2iv(location, v)', + ivec3: 'gl.uniform3iv(location, v)', + ivec4: 'gl.uniform4iv(location, v)', - bool: 'gl.uniform1iv(location, value)', - bvec2: 'gl.uniform2iv(location, value)', - bvec3: 'gl.uniform3iv(location, value)', - bvec4: 'gl.uniform4iv(location, value)', + bool: 'gl.uniform1iv(location, v)', + bvec2: 'gl.uniform2iv(location, v)', + bvec3: 'gl.uniform3iv(location, v)', + bvec4: 'gl.uniform4iv(location, v)', - sampler2D: 'gl.uniform1iv(location, value)', - samplerCube: 'gl.uniform1iv(location, value)' + sampler2D: 'gl.uniform1iv(location, v)', + samplerCube: 'gl.uniform1iv(location, v)', + sampler2DArray: 'gl.uniform1iv(location, v)', }; -export default function generateUniformsSync(uniformData) + +export default function generateUniformsSync(group, uniformData) { - let textureCount = 1; - let func = `var value = null; - var cacheValue = null + let textureCount = 0; + let func = `var v = null; + var cv = null var gl = renderer.gl`; - for (const i in uniformData) + for (const i in group.uniforms) { const data = uniformData[i]; - // console.log(i, data.size); + + if(!data) + { + if(group.uniforms[i].group) + { + func += ` + renderer.shader.syncUniformGroup(uv.${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`; + func += ` + if(uv.${i} !== ud.${i}.value) + { + ud.${i}.value = uv.${i} + gl.uniform1f(ud.${i}.location, uv.${i}) + }\n`; } - else if (data.type === 'sampler2D' && data.size === 1) + else if ( (data.type === 'sampler2D' || data.type === 'samplerCube' || data.type === 'sampler2DArray') && data.size === 1 && !data.isArray) { - func += `\nif (uniformValues.${i}.baseTexture) -{ - var location = renderer.bindTexture(uniformValues.${i}.baseTexture, ${textureCount++}, false); + func += ` + renderer.texture.bind(uv.${i}, ${textureCount}); - if(uniformData.${i}.value !== location) - { - uniformData.${i}.value = location; - gl.uniform1i(uniformData.${i}.location, location);\n; // eslint-disable-line max-len - } -} -else -{ - uniformData.${i}.value = ${textureCount}; - renderer.boundTextures[${textureCount}] = renderer.emptyTextures[${textureCount}]; - gl.activeTexture(gl.TEXTURE0 + ${textureCount++}); + if(ud.${i}.value !== ${textureCount}) + { + ud.${i}.value = ${textureCount}; + gl.uniform1i(ud.${i}.location, ${textureCount});\n; // eslint-disable-line max-len + }\n` - 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`; + if(group.uniforms[i].a !== undefined) + { + // TODO and some smart caching dirty ids here! + func += ` + gl.uniformMatrix3fv(ud.${i}.location, false, uv.${i}.toArray(true)); + \n`; + } + else + { + func += ` + gl.uniformMatrix3fv(ud.${i}.location, false, uv.${i}); + \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(group.uniforms[i].x !== undefined) + { + func += ` + cv = ud.${i}.value; + v = uv.${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`; + if(cv[0] !== v.x || cv[1] !== v.y) + { + cv[0] = v.x; + cv[1] = v.y; + gl.uniform2f(ud.${i}.location, v.x, v.y); + }\n`; + } + else + { + func += ` + cv = ud.${i}.value; + v = uv.${i}; + + if(cv[0] !== v[0] || cv[1] !== v[1]) + { + cv[0] = v[0]; + cv[1] = v[1]; + gl.uniform2f(ud.${i}.location, v[0], v[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`); + const template = templateType[data.type].replace('location', `ud.${i}.location`); - func += `\ncacheValue = uniformData.${i}.value; -value = uniformValues.${i}; -${template};\n`; + func += ` + cv = ud.${i}.value; + v = uv.${i}; + ${template};\n`; } } - //console.log(' --------------- ') - // console.log(func); + // console.log(' --------------- ') + // console.log(func); - return new Function('uniformData', 'uniformValues', 'renderer', func); // eslint-disable-line no-new-func + return new Function('ud', 'uv', 'renderer', func); // eslint-disable-line no-new-func } diff --git a/src/core/shader/generateUniformsSync2.js b/src/core/shader/generateUniformsSync2.js deleted file mode 100644 index a643add..0000000 --- a/src/core/shader/generateUniformsSync2.js +++ /dev/null @@ -1,190 +0,0 @@ -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 && !data.isArray) - { - 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 -} diff --git a/src/core/renderers/webgl/systems/geometry/GeometrySystem.js b/src/core/renderers/webgl/systems/geometry/GeometrySystem.js index be19ee5..3f95a06 100644 --- a/src/core/renderers/webgl/systems/geometry/GeometrySystem.js +++ b/src/core/renderers/webgl/systems/geometry/GeometrySystem.js @@ -307,6 +307,7 @@ if(attribute.instance) { + //TODO calculate instance count based of this... if(this.hasInstance) { gl.vertexAttribDivisor(location, 1); diff --git a/src/core/renderers/webgl/systems/shader/ShaderSystem.js b/src/core/renderers/webgl/systems/shader/ShaderSystem.js index 0ee6743..670dd72 100644 --- a/src/core/renderers/webgl/systems/shader/ShaderSystem.js +++ b/src/core/renderers/webgl/systems/shader/ShaderSystem.js @@ -1,7 +1,7 @@ import WebGLSystem from '../WebGLSystem'; import GLShader from './GLShader'; import { PRECISION } from '../../../../const'; -import generateUniformsSync from '../../../../shader/generateUniformsSync2'; +import generateUniformsSync from '../../../../shader/generateUniformsSync'; let UID = 0; diff --git a/src/core/shader/Shader.js b/src/core/shader/Shader.js index 005402d..2f8dc56 100644 --- a/src/core/shader/Shader.js +++ b/src/core/shader/Shader.js @@ -42,7 +42,7 @@ { if (this.uniformGroup.uniforms[i] instanceof Array) { - this.uniformGroup.uniforms[i] = new Float32Array(uniform); + this.uniformGroup.uniforms[i] = new Float32Array(this.uniformGroup.uniforms[i]); } } } @@ -74,37 +74,7 @@ { return this.uniformGroup.uniforms; } -/* -var offsetBuffer = gl.createBuffer(); -gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer); -gl.bufferData(gl.ARRAY_BUFFER, offsets, gl.STATIC_DRAW); - -var colorBuffer = gl.createBuffer(); -gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); -gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW); - -var instanceCount = 4; -var ext = gl.getExtension("ANGLE_instanced_arrays"); // Vendor prefixes may apply! - -// Bind the rest of the vertex attributes normally -bindMeshArrays(gl); - -// Bind the instance position data -gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer); -gl.enableVertexAttribArray(offsetLocation); -gl.vertexAttribPointer(offsetLocation, 3, gl.FLOAT, false, 12, 0); -ext.vertexAttribDivisorANGLE(offsetLocation, 1); // This makes it instanced! - -// Bind the instance color data -gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); -gl.enableVertexAttribArray(colorLocation); -gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 16, 0); -ext.vertexAttribDivisorANGLE(colorLocation, 1); // This makes it instanced! - -// Draw the instanced meshes -ext.drawElementsInstancedANGLE(gl.TRIANGLES, indexCount, gl.UNSIGNED_SHORT, 0, instanceCount); -*/ /** * A short hand function to create a shader based of a vertex and fragment shader * diff --git a/src/core/shader/UniformGroup.js b/src/core/shader/UniformGroup.js index 8768226..e2ed22a 100644 --- a/src/core/shader/UniformGroup.js +++ b/src/core/shader/UniformGroup.js @@ -1,5 +1,3 @@ -import Program from './Program'; -import generateUniformsSync from './generateUniformsSync'; let UID = 0; diff --git a/src/core/shader/generateUniformsSync.js b/src/core/shader/generateUniformsSync.js index b7241ef..8a7cf55 100644 --- a/src/core/shader/generateUniformsSync.js +++ b/src/core/shader/generateUniformsSync.js @@ -1,153 +1,190 @@ + + +//cv = CachedValue +//v = value +//ud = uniformData +//uv = uniformValue +//l = loaction const GLSL_TO_SINGLE_SETTERS_CACHED = { - float: `if(cacheValue !== value) -{ - cacheValue.value = value; - gl.uniform1f(location, value) -}`, + float:` + if(cv !== v) + { + cv.v = v; + gl.uniform1f(location, v) + }`, - 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]; + vec2:` + if(cv[0] !== v[0] || cv[1] !== v[1]) + { + cv[0] = v[0]; + cv[1] = v[1]; + gl.uniform2f(location, v[0], v[1]) + }`, - gl.uniform3f(location, value[0], value[1], value[2]) -}`, - vec4: 'gl.uniform4f(location, value[0], value[1], value[2], value[3])', + vec3:` + if(cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2]) + { + cv[0] = v[0]; + cv[1] = v[1]; + cv[2] = v[2]; - 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])', + gl.uniform3f(location, v[0], v[1], v[2]) + }`, - 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])', + vec4: 'gl.uniform4f(location, v[0], v[1], v[2], v[3])', - mat2: 'gl.uniformMatrix2fv(location, false, value)', - mat3: 'gl.uniformMatrix3fv(location, false, value)', - mat4: 'gl.uniformMatrix4fv(location, false, value)', + int: 'gl.uniform1i(location, v)', + ivec2: 'gl.uniform2i(location, v[0], v[1])', + ivec3: 'gl.uniform3i(location, v[0], v[1], v[2])', + ivec4: 'gl.uniform4i(location, v[0], v[1], v[2], v[3])', - sampler2D: 'gl.uniform1i(location, value)', - samplerCube: 'gl.uniform1i(location, value)' + bool: 'gl.uniform1i(location, v)', + bvec2: 'gl.uniform2i(location, v[0], v[1])', + bvec3: 'gl.uniform3i(location, v[0], v[1], v[2])', + bvec4: 'gl.uniform4i(location, v[0], v[1], v[2], v[3])', + + mat2: 'gl.uniformMatrix2fv(location, false, v)', + mat3: 'gl.uniformMatrix3fv(location, false, v)', + mat4: 'gl.uniformMatrix4fv(location, false, v)', + + sampler2D: 'gl.uniform1i(location, v)', + samplerCube: 'gl.uniform1i(location, v)', + sampler2DArray: 'gl.uniform1i(location, v)', }; const GLSL_TO_ARRAY_SETTERS = { - float: `gl.uniform1fv(location, value)`, + float: `gl.uniform1fv(location, v)`, - vec2: `gl.uniform2fv(location, value)`, - vec3: `gl.uniform3fv(location, value)`, - vec4: 'gl.uniform4fv(location, value)', + vec2: `gl.uniform2fv(location, v)`, + vec3: `gl.uniform3fv(location, v)`, + vec4: 'gl.uniform4fv(location, v)', - int: 'gl.uniform1iv(location, value)', - ivec2: 'gl.uniform2iv(location, value)', - ivec3: 'gl.uniform3iv(location, value)', - ivec4: 'gl.uniform4iv(location, value)', + int: 'gl.uniform1iv(location, v)', + ivec2: 'gl.uniform2iv(location, v)', + ivec3: 'gl.uniform3iv(location, v)', + ivec4: 'gl.uniform4iv(location, v)', - bool: 'gl.uniform1iv(location, value)', - bvec2: 'gl.uniform2iv(location, value)', - bvec3: 'gl.uniform3iv(location, value)', - bvec4: 'gl.uniform4iv(location, value)', + bool: 'gl.uniform1iv(location, v)', + bvec2: 'gl.uniform2iv(location, v)', + bvec3: 'gl.uniform3iv(location, v)', + bvec4: 'gl.uniform4iv(location, v)', - sampler2D: 'gl.uniform1iv(location, value)', - samplerCube: 'gl.uniform1iv(location, value)' + sampler2D: 'gl.uniform1iv(location, v)', + samplerCube: 'gl.uniform1iv(location, v)', + sampler2DArray: 'gl.uniform1iv(location, v)', }; -export default function generateUniformsSync(uniformData) + +export default function generateUniformsSync(group, uniformData) { - let textureCount = 1; - let func = `var value = null; - var cacheValue = null + let textureCount = 0; + let func = `var v = null; + var cv = null var gl = renderer.gl`; - for (const i in uniformData) + for (const i in group.uniforms) { const data = uniformData[i]; - // console.log(i, data.size); + + if(!data) + { + if(group.uniforms[i].group) + { + func += ` + renderer.shader.syncUniformGroup(uv.${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`; + func += ` + if(uv.${i} !== ud.${i}.value) + { + ud.${i}.value = uv.${i} + gl.uniform1f(ud.${i}.location, uv.${i}) + }\n`; } - else if (data.type === 'sampler2D' && data.size === 1) + else if ( (data.type === 'sampler2D' || data.type === 'samplerCube' || data.type === 'sampler2DArray') && data.size === 1 && !data.isArray) { - func += `\nif (uniformValues.${i}.baseTexture) -{ - var location = renderer.bindTexture(uniformValues.${i}.baseTexture, ${textureCount++}, false); + func += ` + renderer.texture.bind(uv.${i}, ${textureCount}); - if(uniformData.${i}.value !== location) - { - uniformData.${i}.value = location; - gl.uniform1i(uniformData.${i}.location, location);\n; // eslint-disable-line max-len - } -} -else -{ - uniformData.${i}.value = ${textureCount}; - renderer.boundTextures[${textureCount}] = renderer.emptyTextures[${textureCount}]; - gl.activeTexture(gl.TEXTURE0 + ${textureCount++}); + if(ud.${i}.value !== ${textureCount}) + { + ud.${i}.value = ${textureCount}; + gl.uniform1i(ud.${i}.location, ${textureCount});\n; // eslint-disable-line max-len + }\n` - 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`; + if(group.uniforms[i].a !== undefined) + { + // TODO and some smart caching dirty ids here! + func += ` + gl.uniformMatrix3fv(ud.${i}.location, false, uv.${i}.toArray(true)); + \n`; + } + else + { + func += ` + gl.uniformMatrix3fv(ud.${i}.location, false, uv.${i}); + \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(group.uniforms[i].x !== undefined) + { + func += ` + cv = ud.${i}.value; + v = uv.${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`; + if(cv[0] !== v.x || cv[1] !== v.y) + { + cv[0] = v.x; + cv[1] = v.y; + gl.uniform2f(ud.${i}.location, v.x, v.y); + }\n`; + } + else + { + func += ` + cv = ud.${i}.value; + v = uv.${i}; + + if(cv[0] !== v[0] || cv[1] !== v[1]) + { + cv[0] = v[0]; + cv[1] = v[1]; + gl.uniform2f(ud.${i}.location, v[0], v[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`); + const template = templateType[data.type].replace('location', `ud.${i}.location`); - func += `\ncacheValue = uniformData.${i}.value; -value = uniformValues.${i}; -${template};\n`; + func += ` + cv = ud.${i}.value; + v = uv.${i}; + ${template};\n`; } } - //console.log(' --------------- ') - // console.log(func); + // console.log(' --------------- ') + // console.log(func); - return new Function('uniformData', 'uniformValues', 'renderer', func); // eslint-disable-line no-new-func + return new Function('ud', 'uv', 'renderer', func); // eslint-disable-line no-new-func } diff --git a/src/core/shader/generateUniformsSync2.js b/src/core/shader/generateUniformsSync2.js deleted file mode 100644 index a643add..0000000 --- a/src/core/shader/generateUniformsSync2.js +++ /dev/null @@ -1,190 +0,0 @@ -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 && !data.isArray) - { - 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 -} diff --git a/src/core/textures/BaseTexture.js b/src/core/textures/BaseTexture.js index 57c4cc5..13417a1 100644 --- a/src/core/textures/BaseTexture.js +++ b/src/core/textures/BaseTexture.js @@ -450,6 +450,7 @@ } } +BaseTexture.fromFrame = BaseTexture.fromFrame; BaseTexture.fromImage = BaseTexture.from; BaseTexture.fromSVG = BaseTexture.from; BaseTexture.fromCanvas = BaseTexture.from; \ No newline at end of file diff --git a/src/core/renderers/webgl/systems/geometry/GeometrySystem.js b/src/core/renderers/webgl/systems/geometry/GeometrySystem.js index be19ee5..3f95a06 100644 --- a/src/core/renderers/webgl/systems/geometry/GeometrySystem.js +++ b/src/core/renderers/webgl/systems/geometry/GeometrySystem.js @@ -307,6 +307,7 @@ if(attribute.instance) { + //TODO calculate instance count based of this... if(this.hasInstance) { gl.vertexAttribDivisor(location, 1); diff --git a/src/core/renderers/webgl/systems/shader/ShaderSystem.js b/src/core/renderers/webgl/systems/shader/ShaderSystem.js index 0ee6743..670dd72 100644 --- a/src/core/renderers/webgl/systems/shader/ShaderSystem.js +++ b/src/core/renderers/webgl/systems/shader/ShaderSystem.js @@ -1,7 +1,7 @@ import WebGLSystem from '../WebGLSystem'; import GLShader from './GLShader'; import { PRECISION } from '../../../../const'; -import generateUniformsSync from '../../../../shader/generateUniformsSync2'; +import generateUniformsSync from '../../../../shader/generateUniformsSync'; let UID = 0; diff --git a/src/core/shader/Shader.js b/src/core/shader/Shader.js index 005402d..2f8dc56 100644 --- a/src/core/shader/Shader.js +++ b/src/core/shader/Shader.js @@ -42,7 +42,7 @@ { if (this.uniformGroup.uniforms[i] instanceof Array) { - this.uniformGroup.uniforms[i] = new Float32Array(uniform); + this.uniformGroup.uniforms[i] = new Float32Array(this.uniformGroup.uniforms[i]); } } } @@ -74,37 +74,7 @@ { return this.uniformGroup.uniforms; } -/* -var offsetBuffer = gl.createBuffer(); -gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer); -gl.bufferData(gl.ARRAY_BUFFER, offsets, gl.STATIC_DRAW); - -var colorBuffer = gl.createBuffer(); -gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); -gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW); - -var instanceCount = 4; -var ext = gl.getExtension("ANGLE_instanced_arrays"); // Vendor prefixes may apply! - -// Bind the rest of the vertex attributes normally -bindMeshArrays(gl); - -// Bind the instance position data -gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer); -gl.enableVertexAttribArray(offsetLocation); -gl.vertexAttribPointer(offsetLocation, 3, gl.FLOAT, false, 12, 0); -ext.vertexAttribDivisorANGLE(offsetLocation, 1); // This makes it instanced! - -// Bind the instance color data -gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); -gl.enableVertexAttribArray(colorLocation); -gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 16, 0); -ext.vertexAttribDivisorANGLE(colorLocation, 1); // This makes it instanced! - -// Draw the instanced meshes -ext.drawElementsInstancedANGLE(gl.TRIANGLES, indexCount, gl.UNSIGNED_SHORT, 0, instanceCount); -*/ /** * A short hand function to create a shader based of a vertex and fragment shader * diff --git a/src/core/shader/UniformGroup.js b/src/core/shader/UniformGroup.js index 8768226..e2ed22a 100644 --- a/src/core/shader/UniformGroup.js +++ b/src/core/shader/UniformGroup.js @@ -1,5 +1,3 @@ -import Program from './Program'; -import generateUniformsSync from './generateUniformsSync'; let UID = 0; diff --git a/src/core/shader/generateUniformsSync.js b/src/core/shader/generateUniformsSync.js index b7241ef..8a7cf55 100644 --- a/src/core/shader/generateUniformsSync.js +++ b/src/core/shader/generateUniformsSync.js @@ -1,153 +1,190 @@ + + +//cv = CachedValue +//v = value +//ud = uniformData +//uv = uniformValue +//l = loaction const GLSL_TO_SINGLE_SETTERS_CACHED = { - float: `if(cacheValue !== value) -{ - cacheValue.value = value; - gl.uniform1f(location, value) -}`, + float:` + if(cv !== v) + { + cv.v = v; + gl.uniform1f(location, v) + }`, - 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]; + vec2:` + if(cv[0] !== v[0] || cv[1] !== v[1]) + { + cv[0] = v[0]; + cv[1] = v[1]; + gl.uniform2f(location, v[0], v[1]) + }`, - gl.uniform3f(location, value[0], value[1], value[2]) -}`, - vec4: 'gl.uniform4f(location, value[0], value[1], value[2], value[3])', + vec3:` + if(cv[0] !== v[0] || cv[1] !== v[1] || cv[2] !== v[2]) + { + cv[0] = v[0]; + cv[1] = v[1]; + cv[2] = v[2]; - 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])', + gl.uniform3f(location, v[0], v[1], v[2]) + }`, - 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])', + vec4: 'gl.uniform4f(location, v[0], v[1], v[2], v[3])', - mat2: 'gl.uniformMatrix2fv(location, false, value)', - mat3: 'gl.uniformMatrix3fv(location, false, value)', - mat4: 'gl.uniformMatrix4fv(location, false, value)', + int: 'gl.uniform1i(location, v)', + ivec2: 'gl.uniform2i(location, v[0], v[1])', + ivec3: 'gl.uniform3i(location, v[0], v[1], v[2])', + ivec4: 'gl.uniform4i(location, v[0], v[1], v[2], v[3])', - sampler2D: 'gl.uniform1i(location, value)', - samplerCube: 'gl.uniform1i(location, value)' + bool: 'gl.uniform1i(location, v)', + bvec2: 'gl.uniform2i(location, v[0], v[1])', + bvec3: 'gl.uniform3i(location, v[0], v[1], v[2])', + bvec4: 'gl.uniform4i(location, v[0], v[1], v[2], v[3])', + + mat2: 'gl.uniformMatrix2fv(location, false, v)', + mat3: 'gl.uniformMatrix3fv(location, false, v)', + mat4: 'gl.uniformMatrix4fv(location, false, v)', + + sampler2D: 'gl.uniform1i(location, v)', + samplerCube: 'gl.uniform1i(location, v)', + sampler2DArray: 'gl.uniform1i(location, v)', }; const GLSL_TO_ARRAY_SETTERS = { - float: `gl.uniform1fv(location, value)`, + float: `gl.uniform1fv(location, v)`, - vec2: `gl.uniform2fv(location, value)`, - vec3: `gl.uniform3fv(location, value)`, - vec4: 'gl.uniform4fv(location, value)', + vec2: `gl.uniform2fv(location, v)`, + vec3: `gl.uniform3fv(location, v)`, + vec4: 'gl.uniform4fv(location, v)', - int: 'gl.uniform1iv(location, value)', - ivec2: 'gl.uniform2iv(location, value)', - ivec3: 'gl.uniform3iv(location, value)', - ivec4: 'gl.uniform4iv(location, value)', + int: 'gl.uniform1iv(location, v)', + ivec2: 'gl.uniform2iv(location, v)', + ivec3: 'gl.uniform3iv(location, v)', + ivec4: 'gl.uniform4iv(location, v)', - bool: 'gl.uniform1iv(location, value)', - bvec2: 'gl.uniform2iv(location, value)', - bvec3: 'gl.uniform3iv(location, value)', - bvec4: 'gl.uniform4iv(location, value)', + bool: 'gl.uniform1iv(location, v)', + bvec2: 'gl.uniform2iv(location, v)', + bvec3: 'gl.uniform3iv(location, v)', + bvec4: 'gl.uniform4iv(location, v)', - sampler2D: 'gl.uniform1iv(location, value)', - samplerCube: 'gl.uniform1iv(location, value)' + sampler2D: 'gl.uniform1iv(location, v)', + samplerCube: 'gl.uniform1iv(location, v)', + sampler2DArray: 'gl.uniform1iv(location, v)', }; -export default function generateUniformsSync(uniformData) + +export default function generateUniformsSync(group, uniformData) { - let textureCount = 1; - let func = `var value = null; - var cacheValue = null + let textureCount = 0; + let func = `var v = null; + var cv = null var gl = renderer.gl`; - for (const i in uniformData) + for (const i in group.uniforms) { const data = uniformData[i]; - // console.log(i, data.size); + + if(!data) + { + if(group.uniforms[i].group) + { + func += ` + renderer.shader.syncUniformGroup(uv.${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`; + func += ` + if(uv.${i} !== ud.${i}.value) + { + ud.${i}.value = uv.${i} + gl.uniform1f(ud.${i}.location, uv.${i}) + }\n`; } - else if (data.type === 'sampler2D' && data.size === 1) + else if ( (data.type === 'sampler2D' || data.type === 'samplerCube' || data.type === 'sampler2DArray') && data.size === 1 && !data.isArray) { - func += `\nif (uniformValues.${i}.baseTexture) -{ - var location = renderer.bindTexture(uniformValues.${i}.baseTexture, ${textureCount++}, false); + func += ` + renderer.texture.bind(uv.${i}, ${textureCount}); - if(uniformData.${i}.value !== location) - { - uniformData.${i}.value = location; - gl.uniform1i(uniformData.${i}.location, location);\n; // eslint-disable-line max-len - } -} -else -{ - uniformData.${i}.value = ${textureCount}; - renderer.boundTextures[${textureCount}] = renderer.emptyTextures[${textureCount}]; - gl.activeTexture(gl.TEXTURE0 + ${textureCount++}); + if(ud.${i}.value !== ${textureCount}) + { + ud.${i}.value = ${textureCount}; + gl.uniform1i(ud.${i}.location, ${textureCount});\n; // eslint-disable-line max-len + }\n` - 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`; + if(group.uniforms[i].a !== undefined) + { + // TODO and some smart caching dirty ids here! + func += ` + gl.uniformMatrix3fv(ud.${i}.location, false, uv.${i}.toArray(true)); + \n`; + } + else + { + func += ` + gl.uniformMatrix3fv(ud.${i}.location, false, uv.${i}); + \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(group.uniforms[i].x !== undefined) + { + func += ` + cv = ud.${i}.value; + v = uv.${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`; + if(cv[0] !== v.x || cv[1] !== v.y) + { + cv[0] = v.x; + cv[1] = v.y; + gl.uniform2f(ud.${i}.location, v.x, v.y); + }\n`; + } + else + { + func += ` + cv = ud.${i}.value; + v = uv.${i}; + + if(cv[0] !== v[0] || cv[1] !== v[1]) + { + cv[0] = v[0]; + cv[1] = v[1]; + gl.uniform2f(ud.${i}.location, v[0], v[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`); + const template = templateType[data.type].replace('location', `ud.${i}.location`); - func += `\ncacheValue = uniformData.${i}.value; -value = uniformValues.${i}; -${template};\n`; + func += ` + cv = ud.${i}.value; + v = uv.${i}; + ${template};\n`; } } - //console.log(' --------------- ') - // console.log(func); + // console.log(' --------------- ') + // console.log(func); - return new Function('uniformData', 'uniformValues', 'renderer', func); // eslint-disable-line no-new-func + return new Function('ud', 'uv', 'renderer', func); // eslint-disable-line no-new-func } diff --git a/src/core/shader/generateUniformsSync2.js b/src/core/shader/generateUniformsSync2.js deleted file mode 100644 index a643add..0000000 --- a/src/core/shader/generateUniformsSync2.js +++ /dev/null @@ -1,190 +0,0 @@ -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 && !data.isArray) - { - 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 -} diff --git a/src/core/textures/BaseTexture.js b/src/core/textures/BaseTexture.js index 57c4cc5..13417a1 100644 --- a/src/core/textures/BaseTexture.js +++ b/src/core/textures/BaseTexture.js @@ -450,6 +450,7 @@ } } +BaseTexture.fromFrame = BaseTexture.fromFrame; BaseTexture.fromImage = BaseTexture.from; BaseTexture.fromSVG = BaseTexture.from; BaseTexture.fromCanvas = BaseTexture.from; \ No newline at end of file diff --git a/src/core/textures/resources/VideoResource.js b/src/core/textures/resources/VideoResource.js index 7d525c0..3402f96 100644 --- a/src/core/textures/resources/VideoResource.js +++ b/src/core/textures/resources/VideoResource.js @@ -58,6 +58,7 @@ update() { + //TODO - slow down and base on the videos framerate this.resourceUpdated.emit(); }