Comparing version 0.0.9 to 0.0.10
@@ -14,5 +14,5 @@ const vertex = ` | ||
const fragment = ` | ||
precision highp float; | ||
uniform sampler2D tMap; | ||
varying vec2 vUv; | ||
@@ -19,0 +19,0 @@ |
{ | ||
"name": "ogl", | ||
"version": "0.0.9", | ||
"version": "0.0.10", | ||
"description": "WebGL Framework", | ||
@@ -5,0 +5,0 @@ "main": "src", |
@@ -11,7 +11,3 @@ // attribute params | ||
// TODO: fit in transform feedback | ||
// this.boundingBox.center | ||
// TODO: when would I disableVertexAttribArray ? | ||
// TODO: do I need to unbind after drawing ? | ||
// TODO: test updating attributes on the fly | ||
// TODO: add fallback for non vao support (ie) | ||
@@ -24,2 +20,3 @@ | ||
let ID = 0; | ||
let ATTR_ID = 0; | ||
@@ -39,2 +36,5 @@ export class Geometry { | ||
// Alias for state store to avoid redundant calls for global state | ||
this.glState = this.gl.renderer.state; | ||
// create the buffers | ||
@@ -50,4 +50,8 @@ for (let key in attributes) { | ||
// Set options | ||
attr.id = ATTR_ID++; | ||
attr.size = attr.size || 1; | ||
attr.type = attr.type || key === 'index' ? this.gl.UNSIGNED_SHORT : this.gl.FLOAT; | ||
attr.type = attr.type || ( | ||
attr.data.constructor === Float32Array ? this.gl.FLOAT : | ||
attr.data.constructor === Uint16Array ? this.gl.UNSIGNED_SHORT : | ||
this.gl.UNSIGNED_INT); // Uint32Array | ||
attr.target = key === 'index' ? this.gl.ELEMENT_ARRAY_BUFFER : this.gl.ARRAY_BUFFER; | ||
@@ -58,2 +62,3 @@ attr.normalize = attr.normalize || false; | ||
attr.divisor = !attr.instanced ? 0 : typeof attr.instanced === 'number' ? attr.instanced : 1; | ||
attr.needsUpdate = false; | ||
@@ -79,5 +84,10 @@ // Push data to buffer | ||
updateAttribute(attr) { | ||
this.gl.bindBuffer(attr.target, attr.buffer); | ||
// Already bound, prevent gl command | ||
if (this.glState.boundBuffer !== attr.id) { | ||
this.gl.bindBuffer(attr.target, attr.buffer); | ||
this.glState.boundBuffer = attr.id; | ||
} | ||
this.gl.bufferData(attr.target, attr.data, this.gl.STATIC_DRAW); | ||
this.gl.bindBuffer(attr.target, null); | ||
attr.needsUpdate = false; | ||
} | ||
@@ -117,3 +127,4 @@ | ||
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, attr.buffer); | ||
this.gl.bindBuffer(attr.target, attr.buffer); | ||
this.glState.boundBuffer = attr.id; | ||
this.gl.vertexAttribPointer( | ||
@@ -157,2 +168,8 @@ location, | ||
// Check if any attributes need updating | ||
program.attributeLocations.forEach((location, name) => { | ||
const attr = this.attributes[name]; | ||
if (attr.needsUpdate) this.updateAttribute(attr); | ||
}); | ||
if (this.isInstanced) { | ||
@@ -159,0 +176,0 @@ if (this.attributes.index) { |
@@ -82,4 +82,15 @@ // TODO: upload empty texture if null ? maybe not | ||
// trim uniforms' names to omit array declarations | ||
uniform.uniformName = uniform.name.split('[')[0]; | ||
// split uniforms' names to separate array and struct declarations | ||
const split = uniform.name.match(/(\w+)/g); | ||
uniform.uniformName = split[0]; | ||
if (split.length === 3) { | ||
uniform.isStructArray = true; | ||
uniform.structIndex = Number(split[1]); | ||
uniform.structProperty = split[2]; | ||
} else if (split.length === 2 && isNaN(Number(split[1]))) { | ||
uniform.isStruct = true; | ||
uniform.structProperty = split[1]; | ||
} | ||
} | ||
@@ -100,16 +111,40 @@ | ||
checkTextureUnits() { | ||
const assignedTextureUnits = []; | ||
[...this.uniformLocations.keys()].every((activeUniform) => { | ||
const uniform = this.uniforms[activeUniform.uniformName]; | ||
if (uniform && uniform.value && uniform.value.texture) { | ||
if (assignedTextureUnits.indexOf(uniform.value.textureUnit) > -1) { | ||
let uniform = this.uniforms[activeUniform.uniformName]; | ||
// If reused, set flag to true to assign sequential units when drawn | ||
this.assignTextureUnits = true; | ||
return false; | ||
if (activeUniform.isStruct) { | ||
uniform = uniform[activeUniform.structProperty]; | ||
} | ||
if (activeUniform.isStructArray) { | ||
uniform = uniform[activeUniform.structIndex][activeUniform.structProperty]; | ||
} | ||
if (!(uniform && uniform.value)) return true; | ||
// Texture array | ||
if (uniform.value.length && uniform.value[0].texture) { | ||
for (let i = 0; i < uniform.value.length - 1; i++) { | ||
if (!checkDuplicate(uniform.value[i])) return false; | ||
} | ||
assignedTextureUnits.push(uniform.value.textureUnit); | ||
} | ||
if (uniform.value.texture) { | ||
if (!checkDuplicate(uniform.value)) return false; | ||
} | ||
return true; | ||
}); | ||
function checkDuplicate(value) { | ||
if (assignedTextureUnits.indexOf(value.textureUnit) > -1) { | ||
// If reused, set flag to true to assign sequential units when drawn | ||
this.assignTextureUnits = true; | ||
return false; | ||
} | ||
assignedTextureUnits.push(value.textureUnit); | ||
return true; | ||
} | ||
} | ||
@@ -164,11 +199,23 @@ | ||
this.uniformLocations.forEach((location, activeUniform) => { | ||
const name = activeUniform.uniformName; | ||
let name = activeUniform.uniformName; | ||
// get supplied uniform | ||
const uniform = this.uniforms[name]; | ||
let uniform = this.uniforms[name]; | ||
// For structs, get the specific property instead of the entire object | ||
if (activeUniform.isStruct) { | ||
uniform = uniform[activeUniform.structProperty]; | ||
name += `.${activeUniform.structProperty}`; | ||
} | ||
if (activeUniform.isStructArray) { | ||
uniform = uniform[activeUniform.structIndex][activeUniform.structProperty]; | ||
name += `[${activeUniform.structIndex}].${activeUniform.structProperty}`; | ||
} | ||
if (!uniform) { | ||
return console.warn(`Active uniform ${name} has not been supplied`); | ||
return warn(`Active uniform ${name} has not been supplied`); | ||
} | ||
if (uniform && uniform.value === undefined) { | ||
return console.warn(`${name} uniform is missing a value parameter`); | ||
return warn(`${name} uniform is missing a value parameter`); | ||
} | ||
@@ -252,2 +299,10 @@ | ||
return value; | ||
} | ||
let warnCount = 0; | ||
function warn(message) { | ||
if (warnCount > 100) return; | ||
console.warn(message); | ||
warnCount++; | ||
if (warnCount > 100) console.warn('More than 100 program warnings - stopping logs.'); | ||
} |
@@ -31,2 +31,3 @@ import {Mat4} from '../math/Mat4.js'; | ||
autoClear = true, | ||
webgl = 2, | ||
} = {}) { | ||
@@ -42,4 +43,4 @@ const attributes = {alpha, depth, stencil, antialias, premultipliedAlpha, preserveDrawingBuffer, powerPreference}; | ||
// Attempt WebGL2, otherwise fallback to WebGL1 | ||
this.gl = canvas.getContext('webgl2', attributes); | ||
// Attempt WebGL2 unless forced to 1, if not supported fallback to WebGL1 | ||
if (webgl === 2) this.gl = canvas.getContext('webgl2', attributes); | ||
this.isWebgl2 = !!this.gl; | ||
@@ -75,2 +76,3 @@ if (!this.gl) { | ||
this.state.activeTextureUnit = 0; | ||
this.state.boundBuffer = null; | ||
@@ -230,2 +232,12 @@ // store requested extensions | ||
sortUI(a, b) { | ||
if (a.renderOrder !== b.renderOrder) { | ||
return a.renderOrder - b.renderOrder; | ||
} else if (a.program.id !== b.program.id) { | ||
return a.program.id - b.program.id; | ||
} else { | ||
return b.id - a.id; | ||
} | ||
} | ||
getRenderList({scene, camera, frustumCull, sort}) { | ||
@@ -277,3 +289,3 @@ let renderList = []; | ||
transparent.sort(this.sortTransparent); | ||
ui.sort(this.sortTransparent); | ||
ui.sort(this.sortUI); | ||
@@ -280,0 +292,0 @@ renderList = opaque.concat(transparent, ui); |
// TODO: facilitate Compressed Textures | ||
// TODO: test data texture | ||
// TODO: cube map | ||
@@ -126,3 +125,3 @@ // TODO: delete texture | ||
if (this.wrapS !== this.state.wrapS) { | ||
this.gl.texParameteri(this.target, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE); | ||
this.gl.texParameteri(this.target, this.gl.TEXTURE_WRAP_S, this.wrapS); | ||
this.state.wrapS = this.wrapS; | ||
@@ -132,3 +131,3 @@ } | ||
if (this.wrapT !== this.state.wrapT) { | ||
this.gl.texParameteri(this.target, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE); | ||
this.gl.texParameteri(this.target, this.gl.TEXTURE_WRAP_T, this.wrapT); | ||
this.state.wrapT = this.wrapT; | ||
@@ -135,0 +134,0 @@ } |
@@ -7,3 +7,3 @@ import {Geometry} from '../core/Geometry.js'; | ||
const num = (wSegs + 1) * (hSegs + 1) * 2 + (wSegs + 1) * (dSegs + 1) * 2 + (hSegs + 1) * (dSegs + 1) * 2; | ||
const numIndices = wSegs * hSegs * 2 + wSegs * dSegs * 2 + hSegs * dSegs * 2; | ||
const numIndices = (wSegs * hSegs * 2 + wSegs * dSegs * 2 + hSegs * dSegs * 2) * 6; | ||
@@ -13,3 +13,3 @@ const position = new Float32Array(num * 3); | ||
const uv = new Float32Array(num * 2); | ||
const index = new Uint16Array(numIndices * 6); | ||
const index = (num > 65536) ? new Uint32Array(numIndices) : new Uint16Array(numIndices); | ||
@@ -16,0 +16,0 @@ let i = 0; |
@@ -1,2 +0,2 @@ | ||
// Based from ThreeJS' OrbitControls class, rewritten using es6 with some additions and subions. | ||
// Based from ThreeJS' OrbitControls class, rewritten using es6 with some additions and subtractions. | ||
// TODO: abstract event handlers so can be fed from other sources | ||
@@ -3,0 +3,0 @@ // TODO: make scroll zoom more accurate than just >/< zero |
@@ -8,3 +8,3 @@ import {Geometry} from '../core/Geometry.js'; | ||
const num = (wSegs + 1) * (hSegs + 1); | ||
const numIndices = wSegs * hSegs; | ||
const numIndices = wSegs * hSegs * 6; | ||
@@ -15,3 +15,3 @@ // Generate empty arrays once | ||
const uv = new Float32Array(num * 2); | ||
const index = new Uint16Array(numIndices * 6); | ||
const index = (num > 65536) ? new Uint32Array(numIndices) : new Uint16Array(numIndices); | ||
@@ -18,0 +18,0 @@ Plane.buildPlane(position, normal, uv, index, width, height, 0, wSegs, hSegs); |
@@ -13,6 +13,11 @@ // TODO: Destroy render targets if size changed and exists | ||
dpr, | ||
autoResize = false, | ||
wrapS = gl.CLAMP_TO_EDGE, | ||
wrapT = gl.CLAMP_TO_EDGE, | ||
minFilter = gl.LINEAR, | ||
magFilter = gl.LINEAR, | ||
} = {}) { | ||
this.gl = gl; | ||
this.options = {wrapS, wrapT, minFilter, magFilter}; | ||
this.passes = []; | ||
@@ -25,3 +30,2 @@ | ||
if (autoResize) window.addEventListener('resize', this.resize, false); | ||
this.resize({width, height, dpr}); | ||
@@ -44,2 +48,4 @@ } | ||
mesh, | ||
program, | ||
uniforms, | ||
enabled, | ||
@@ -67,5 +73,7 @@ textureUniform, | ||
//create | ||
this.target = new RenderTarget(this.gl, {width, height}); | ||
this.ping = new RenderTarget(this.gl, {width, height}); | ||
this.pong = new RenderTarget(this.gl, {width, height}); | ||
this.options.width = width; | ||
this.options.height = height; | ||
this.target = new RenderTarget(this.gl, this.options); | ||
this.ping = new RenderTarget(this.gl, this.options); | ||
this.pong = new RenderTarget(this.gl, this.options); | ||
} | ||
@@ -134,2 +142,2 @@ | ||
} | ||
`; | ||
`; |
@@ -7,3 +7,3 @@ import {Geometry} from '../core/Geometry.js'; | ||
const num = (wSegs + 1) * (hSegs + 1); | ||
const numIndices = wSegs * hSegs * 6; | ||
const numIndices = wSegs * hSegs * 6 ; | ||
@@ -13,3 +13,3 @@ const position = new Float32Array(num * 3); | ||
const uv = new Float32Array(num * 2); | ||
const index = new Uint16Array(numIndices); | ||
const index = (num > 65536) ? new Uint32Array(numIndices) : new Uint16Array(numIndices); | ||
@@ -16,0 +16,0 @@ let i = 0; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
15054148
161
21114