GcodeRaymarchSimulator.prototype.init = function(gl) { this._gl = gl; this.raymarchProgram = createRaymarchProgram(gl); this.raymarchProgram.bind(); this.buffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 1, 1, 0, -1, 1, 0, -1, -1, 0, 1, 1, 0, 1, -1, 0, -1, -1, 0 ]), gl.STATIC_DRAW) this.raymarchProgram.attributes.position.pointer(); this.depthBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, this.depthBuffer); var width = this.raymarchProgram.uniforms.depth_width = 2048; var height = this.raymarchProgram.uniforms.depth_height = 2048; this.raymarchProgram.uniforms.depth_stride = width; this.depthArray = ndarray(new Float32Array(width*height), [width, height]); this.depthTexture = createTexture(gl, this.depthArray); this.depthTexture.bind(); }
function createText(gl, str, options) { options = options || {} var fontFamily = options.font ? " " + options.font : " monospace" var fontSize = options.size || 56 var fontColor = options.color || [0,0,0] var fontStyle = options.style ? options.style + " " : "" var font = [fontStyle, fontSize, "px", fontFamily].join("") drawContext.font = font drawContext.textAlign = "center" drawContext.textBaseline = "middle" var dims = drawContext.measureText(str) var w = bits.nextPow2(dims.width) var h = bits.nextPow2(2 * (fontSize|0)) drawCanvas.width = w drawCanvas.height = h drawContext.clearRect(0, 0, w, h) drawContext.fillStyle = makeColorString(fontColor) drawContext.font = font drawContext.textAlign = "center" drawContext.textBaseline = "middle" drawContext.fillText(str, w/2, h/2) var texture = createTexture(gl, drawCanvas) texture.generateMipmap() texture.magFilter = gl.LINEAR texture.minFilter = gl.LINEAR_MIPMAP_LINEAR return texture }
test('checking if texture RGBA matches correctly...', function(t) { if (!gl) throw new Error("no WebGL context available") var tex = createTex(gl, baboon) var imgWidth = tex.shape[0]/2 var canvas = document.createElement("canvas") var array = getPixels(tex, { x: imgWidth, width: imgWidth }) canvas.width = imgWidth canvas.height = tex.shape[1] var context = canvas.getContext("2d") var imgData = context.createImageData(imgWidth, tex.shape[1]) imgData.data.set(array) context.putImageData(imgData, 0, 0) var result = context.getImageData(0, 0, imgWidth, tex.shape[1]) t.deepEqual(array, result.data, 'does match RGBA pixels') t.end() getPixels.dispose() })
function start(gl, width, height) { document.body.style.backgroundColor = '#fff' var info = document.querySelector('.info') css(info, { display: 'block', margin: 10, padding: 0 }) drawBunny = createBunny(gl) fbo = createFBO(gl, FRAME_SIZE, { depth: true, stencil: false }) buffer = new Uint8Array(FRAME_SIZE[0]*FRAME_SIZE[1]*4) batch = SpriteBatch(gl, { capacity: motion.points.length }) shader = createShader(gl, { texcoord: true, color: true, normal: false }) brushTexture = createTexture(gl, brushImage) ;[brushTexture].forEach(function(t) { t.minFilter = gl.LINEAR_MIPMAP_LINEAR t.magFilter = gl.LINEAR t.generateMipmap() }) //initially white clear(gl) }
Cloth.prototype.initBuffers = function () { var i, j; var gl = this.gl; var w = this.grid.width; var h = this.grid.height; var computeBuffer = this.grid.computeBuffer; computeBuffer.vertices = createBuffer(gl, [-1, -1, 1, -1, 1, 1, -1, 1], gl.ARRAY_BUFFER, gl.STATIC_DRAW); computeBuffer.texCoords = createBuffer(gl, [0, 0, 1, 0, 1, 1, 0, 1], gl.ARRAY_BUFFER, gl.STATIC_DRAW); computeBuffer.indices = createBuffer(gl, [0, 1, 2, 0, 2, 3], gl.ELEMENT_ARRAY_BUFFER, gl.STATIC_DRAW); computeBuffer.frameBufferObject = gl.createFramebuffer(); computeBuffer.frameBuffer = new Float32Array(w * h * 4); //this.debugBuf = new Float32Array(w*h*4); for (i = 0; i < this.nBuf * 2; i++) { computeBuffer.textures[i] = createTexture2D(gl, w, h, gl.RGBA, gl.FLOAT); } var renderBuffer = this.grid.renderBuffer; var renderIndicesData; if (this.wireframe) { renderIndicesData = this.generateWireframeVertices(); } else { renderIndicesData = this.generateTriangleStripsVertices(); } var texCoordData = new Float32Array(w * h * 2); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { texCoordData[i * w * 2 + j * 2] = j / (w - 1); texCoordData[i * w * 2 + j * 2 + 1] = i / (h - 1); } } renderBuffer.indices = createBuffer(gl, renderIndicesData, gl.ELEMENT_ARRAY_BUFFER, gl.STATIC_DRAW); renderBuffer.indices.nItems = renderIndicesData.length; renderBuffer.vertices = createBuffer(gl, computeBuffer.frameBuffer); renderBuffer.texCoords = createBuffer(gl, texCoordData, gl.ARRAY_BUFFER, gl.STATIC_DRAW); renderBuffer.textures[0] = this.generateFabricPattern(true); renderBuffer.textures[1] = this.generateFabricPattern(false); renderBuffer.normalBuffer = new Float32Array(w * h * 4); renderBuffer.normals = createBuffer(gl, renderBuffer.normalBuffer); renderBuffer.normalTexture = createTexture2D(gl, w, h, gl.RGBA, gl.FLOAT); };
this.image.onload = function () { // Texture Element self.texture = createTexture2d( gl, [ self.image.width, self.image.height ] ) self.texture.setPixels( self.image ) self.isReady = true }
img.onload = function (){ tex = createTexture(gl, img); tex.bind(0); tex.generateMipmap() tex.minFilter = gl.LINEAR_MIPMAP_LINEAR tex.magFilter = gl.LINEAR //and repeat wrapping tex.wrap = gl.REPEAT }
constructor() { const canvas = document.createElement("canvas"); canvas.width = canvas.height = 2; const opts = { preserveDrawingBuffer: true }; const gl = canvas.getContext("webgl", opts); if (!gl) return; gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); const texture = createTexture(gl, [2, 2]); const buffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, buffer); gl.bufferData( gl.ARRAY_BUFFER, new Float32Array([ -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0 ]), gl.STATIC_DRAW ); const copyShader = createShader( gl, ` attribute vec2 _p; varying vec2 uv; void main() { gl_Position = vec4(_p,0.0,1.0); uv = vec2(0.5, 0.5) * (_p+vec2(1.0, 1.0)); } `, ` precision highp float; varying vec2 uv; uniform sampler2D t; void main () { vec4 c = texture2D(t, uv); gl_FragColor = c; }` ); copyShader.bind(); copyShader.attributes._p.pointer(); this.copyShader = copyShader; this.texture = texture; this.canvas = canvas; this.gl = gl; }
function GLAudioAnalyser(gl, audio, ctx) { if (!(this instanceof GLAudioAnalyser)) return new GLAudioAnalyser(gl, audio, ctx) this.gl = gl this.audio = audio this.ctx = ctx || new AudioContext this.waa = Analyser(this.audio, this.ctx) var size = (this.waa.analyser[0] || this.waa.analyser).frequencyBinCount this.waveNda = ndarray(new Float32Array(size), [size, 1]) this.waveTex = Texture(gl, this.waveNda, { float: true }) this.waveFlt = this.waveNda.data this.freqNda = ndarray(new Float32Array(size), [size, 1]) this.freqTex = Texture(gl, this.freqNda, { float: true }) this.freqFlt = this.freqNda.data }
constructor(gl, image) { this.texture = createTexture(gl, image); gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); this.texture.generateMipmap(); this.texture.wrap = [gl.REPEAT, gl.REPEAT]; this.texture.magFilter = gl.LINEAR; this.texture.minFilter = gl.LINEAR_MIPMAP_LINEAR; this.unit = ++unit; }
//Initialize a texture object function initTexture(gl, width, height, type, format, attachment) { if(!type) { return null } var result = createTexture(gl, width, height, format, type) result.magFilter = gl.NEAREST result.minFilter = gl.NEAREST result.mipSamples = 1 result.bind() gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, result.handle, 0) return result }
test('gl-texture2d-read-float', function(t) { const canvas = document.body.appendChild(document.createElement('canvas')) const gl = canvas.getContext('webgl') const data = new Float32Array([0, 1.2, 2.4, 3.6, 4, 5, 6, 7]) const stride1 = [2, 1, 4] const stride2 = [1, 2, 4] const tex1 = Texture(gl, ndarray(data, stride1), { float: true }) const tex2 = Texture(gl, ndarray(data, stride2), { float: true }) t.plan(4) read(tex1, function(err, res) { t.ifError(err, 'ran without error') t.deepEqual(res, data, 'RGBA: data returned is equivalent to what was passed in') }) read(tex2, function(err, res) { t.ifError(err, 'ran without error') t.deepEqual(res, data, 'RGBA: data returned is equivalent to what was passed in') }) })
genBlurBuffer(gl, img) { const { width, height } = this.props; const shader = createShader(gl, require('./shader/common.vert'), require('./shader/blur.frag')); const texture = createTexture(gl, img); const vao = createVAO(gl, [{ size: 3, buffer: createBuffer(gl, [ -1, -1, 0, 1, -1, 0, -1, 1, 0, 1, 1, 0 ]) }]); let prevFBO = createFBO(gl, [img.width, img.height]); let currFBO = createFBO(gl, [img.width, img.height]); for (var i = 0; i < 8; i++) { var radius = (8 - i); currFBO.bind() shader.bind() shader.uniforms = { resolution: [width, height], texResolution: [img.width, img.height], texture: i === 0 ? texture.bind() : prevFBO.color[0].bind(), direction: i % 2 === 0 ? [radius, 0] : [0, radius] } gl.clearColor(0, 0, 0, 0); gl.clear(gl.COLOR_BUFFER_BIT); vao.bind(); vao.draw(gl.TRIANGLE_STRIP, 4); vao.unbind(); var t = currFBO; currFBO = prevFBO; prevFBO = t } return { width: img.width, height: img.height, origin: texture, blur: currFBO.color[0], }; }
function createTileMap(gl, tileSheet, tileMap, tileShape) { if(tileMap.shape.length !== 3 && tileMap[2] !== 2) { throw new Error("Invalid shape for tilemap") } if(!gl.__TILEMAP_SHADER) { gl.__TILEMAP_SHADER = createTileMapShader(gl) } var texture = createTexture(gl, tileMap) texture.wrapS = gl.REPEAT texture.wrapT = gl.REPEAT texture.minFilter = gl.NEAREST texture.magFilter = gl.NEAREST return new TileMap(gl, tileSheet, texture, tileShape) }
GcodeRaymarchSimulator.prototype.init = function(gl) { this._gl = gl; this.raymarchProgram = createShader( gl, fragmentShader, vertexShader ); this._eye = [ 0, 0, 3 ]; this._camera = createCamera( this._eye.concat(), [0.25, 0.25, 0.125], [0, 1, 0] ); this.raymarchProgram.bind(); this.buffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 1, 1, 0, -1, 1, 0, -1, -1, 0, 1, 1, 0, 1, -1, 0, -1, -1, 0 ]), gl.STATIC_DRAW) this.raymarchProgram.attributes.position.pointer(); this.depthBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, this.depthBuffer); var width = this.raymarchProgram.uniforms.depth_width = 2048; var height = this.raymarchProgram.uniforms.depth_height = 2048; this.raymarchProgram.uniforms.depth_stride = width; this.depthArray = ndarray(new Float32Array(width*height), [width, height]); this.depthTexture = createTexture(gl, this.depthArray); this.depthTexture.bind(); }
return loadImage(opt.src, function(err, img) { if (err) return cb(err) var t = createTex(gl, img) if (opt.wrap) t.wrap = opt.wrap if (opt.minFilter) t.minFilter = opt.minFilter if (opt.magFilter) t.magFilter = opt.magFilter cb(null, t) })
"canplaythrough", function () { if ( self.isReady == false ) { // Video Element self.domElement.currentTime = Math.random() * self.domElement.duration self.domElement.play() // Texture Element self.texture = createTexture2d( gl, [ self.domElement.videoWidth , self.domElement.videoHeight ] ) self.texture.setPixels( self.domElement ) self.isReady = true } }
shell.on("gl-init", function() { var gl = shell.gl var tileSheet = createTexture(gl, tileMap) tileMap = createTileMap(gl, tileSheet, tiles, [16,16]) //Randomize all the tiles every second setInterval(function() { for(var i=0; i<128; ++i) { for(var j=0; j<128; ++j) { tiles.set(i, j, 0, (Math.random()*16)|0) tiles.set(i, j, 1, (Math.random()*16)|0) } } tileMap.update(tiles) }, 1000) })
StitchPlugin.prototype.createGLTexture = function(gl, cb) { var atlas = this.atlas; var showLevels = this.debug; var self = this; // get pixel data (note: similar to get-pixels, but directly from the canvas, not a URL) var context = atlas.canvas.getContext('2d'); // TODO: cache? var s = this.atlasSize; var pixels = context.getImageData(0, 0, s, s); var array = ndarray(new Uint8Array(pixels.data), [s, s, 4], [4*s, 4, 1], 0); var pyramid = rectMipMap(array, atlas); if (self.verbose) console.log('pyramid=',pyramid); if (showLevels) { // add each mip level to the page for debugging TODO: refactor with rect-mip-map demo pyramid.forEach(function(level, i) { var img = new Image(); img.src = savePixels(level, 'canvas').toDataURL(); img.style.border = '1px dotted black'; document.body.appendChild(document.createElement('br')); document.body.appendChild(img); document.body.appendChild(document.createTextNode(' level #'+i+' ('+img.width+'x'+img.height+')')); }); } // TODO: multiple texture atlases, ref https://github.com/deathcap/voxel-texture-shader/issues/2 self.texture = createTexture(gl, pyramid[0]); self.texture.generateMipmap(); // TODO: ? for (var i = 1; i < pyramid.length; ++i) { self.texture.setPixels(pyramid[i], 0, 0, i); } self.texture.magFilter = gl.NEAREST self.texture.minFilter = gl.LINEAR_MIPMAP_LINEAR self.texture.mipSamples = 4 cb(null, self.texture); };
function createTileMap(gl, tiles, pad) { var pyramid = tileMipMap(tiles, pad) //Fill in mip levels var tex = createTexture(gl, reshapeTileMap(pyramid[0])) //Allocate memory (stupid way to do this) tex.generateMipmap() //Set up mipmaps for(var i=1; i<pyramid.length; ++i) { tex.setPixels(reshapeTileMap(pyramid[i]), 0, 0, i) } //Set sample parameters tex.magFilter = gl.LINEAR tex.minFilter = gl.LINEAR_MIPMAP_LINEAR tex.mipSamples = 4 return tex }
/* Constructor */ function GUI(gl) { /* We use this single shader to render the GUI. */ this.shader = createShader(gl, shaders.vert, shaders.frag); /* These buffers contain all the geometry data. */ this.positionBufferObject = createBuffer(gl, [], gl.ARRAY_BUFFER, gl.DYNAMIC_DRAW); this.colorBufferObject = createBuffer(gl, [], gl.ARRAY_BUFFER, gl.DYNAMIC_DRAW); this.uvBufferObject = createBuffer(gl, [], gl.ARRAY_BUFFER, gl.DYNAMIC_DRAW); this.indexBufferObject = createBuffer(gl, [], gl.ELEMENT_ARRAY_BUFFER, gl.DYNAMIC_DRAW); this._setupDefaultSettings(); this.fontAtlasTexture = createTexture(gl, fontAtlas); this.fontAtlasTexture.magFilter = gl.LINEAR; this.fontAtlasTexture.minFilter = gl.LINEAR; /* DO NOT CHANGE THIS VALUE. The entire GUI layout will break! */ this.textScale = 1.0; /* Keeps track of the ID of the widget that is currently being pressed down. We need to keep track of this, because otherwise we can't, for instance, affect the value of a slider while the mouse is OUTSIDE the hitbox of the slider. */ this.activeWidgetId = null; /* See _moveWindowCaret() for an explanation. */ this.sameLineActive = false; this.prevWidgetSizes = null; }
function Plane(gl, img) { this.planeArray = new Float32Array(18); this.items = 6; this.gl = gl; this.program = createShader(gl); gl.program.bind(); gl.program.attributes.position.location = 0; gl.program.attributes.normal.location = 1 this.planeBuffer = createBuffer(gl, this.planeArray); this.planeNormals = createBuffer(gl, new Float32Array([ 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, ])); // Texturing this.texture = createTexture(gl, img); this.texture.wrap = gl.REPEAT; }
function PostProcess(gl, el, frag, vert) { if (!(this instanceof PostProcess)) return new PostProcess(gl, el, frag, vert) this.gl = gl this.el = el this.texture = createTexture(gl, el) this.texture.minFilter = gl.NEAREST this.texture.maxFilter = gl.NEAREST this.texture.wrapS = gl.CLAMP_TO_EDGE this.texture.wrapT = gl.CLAMP_TO_EDGE this.dynamic = ( el instanceof HTMLCanvasElement || el instanceof HTMLVideoElement ) this.shader = typeof frag !== 'string' ? frag : createShader(gl , vert || defaultVertexShader , frag ) var verts = new Float32Array([ -1, -1, +1, -1, -1, +1, -1, +1, +1, -1, +1, +1, ]) this.vao = createVAO(gl, null, [{ buffer: createBuffer(gl, verts) , type: gl.FLOAT , size: 2 , offset: 0 , stride: 0 , normalized: false }]) }
.then(image => createTexture(gl, image))
] comparison.mode = 'slide' comparison.amount = 0.5 require('../common')({ description: readme , dirname: process.env.dirname , compare: comparison , canvas: canvas , test: verify }) window.addEventListener('resize', fit(canvas), false) var baboonTexture = createTexture(gl, baboon.step(-1,1)) baboonTexture.wrap = gl.REPEAT var actualShader = createShader({ frag: process.env.file_fragment_glsl , vert: './shaders/vertex.glsl' })(gl) var expectedShader = createShader({ frag: './shaders/fragment.glsl' , vert: './shaders/vertex.glsl' })(gl) var tick function render() {
Object.keys(shell.grades).forEach(function(key) { shell.grades[key] = createTexture(shell.gl, shell.grades[key]) })
function texture (img) { if (textures.has(img)) return textures.get(img); const t = createTexture(gl, img); textures.set(img, t); return t; }
// ************************ Init ************************ // init params: // reference to gl context // Image object // size for comparison framebuffer (2^n, default 256) function init( glRef, imageRef, size ) { if (!glRef) { throw new Error("Need a reference to a gl context") } gl = glRef var s = parseInt(size) fboSize = (s && s>=16) ? s : 256 // make texture for target image if (imageRef) { refTexture = createTexture(gl, imageRef) } else { // if no image was passed in, library is probably being used to paint output // so skip texture. But future calls to runGeneration will fail. refTexture = null } // gl settings gl.disable(gl.DEPTH_TEST) gl.enable(gl.BLEND) gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA ) //Create shaders camShader = createCameraShader(gl) flatShader = createFlatShader(gl) if (refTexture) { // these use highp precision and may throw errors on devices // but aren't needed if we're only viewing a projection, // so we skip their creation if there's no reference image diffReduceShader = createDiffShader(gl) avgReduceShader = createAvgShader(gl) } // TODO: this should be generalized... referenceFB = createFBO(gl, [fboSize, fboSize], {color:1} ) referenceFB.drawn = false scratchFB = createFBO(gl, [fboSize, fboSize], {color:1} ) reducedFBs = [] var reducedSize = fboSize/4 while (reducedSize >= 16) { var buff = createFBO(gl, [reducedSize, reducedSize], {color:1} ) reducedFBs.push(buff) reducedSize /= 4 } if (reducedFBs.length===0) { throw new Error('Comparison framebuffer is too small - increase "fboSize"') } // init polygon data, then vertex arrays and buffers polys.init(1) vertBuffer = createBuffer(gl, polys.vertArr) colBuffer = createBuffer(gl, polys.colArr) polyBuffersOutdated = false dataVao = createVAO(gl, [ { "buffer": vertBuffer, "type": gl.FLOAT, "size": 3 }, { "buffer": colBuffer, "type": gl.FLOAT, "size": 4 } ]) var squareBuffer = createBuffer( gl, [-1,-1, -1,1, 1,-1, 1,1, -1,1, 1,-1] ) flatVao = createVAO(gl, [ { "buffer": squareBuffer, "type": gl.FLOAT, "size": 2 } ]) // draw reference texture into ref framebuffer if (refTexture) { drawFlat(refTexture, referenceFB, true) } currentScore = defaultScore initialized = true }
_drawSlides(reset) { const currentSlide = this._slides[this._currentSlideIndex]; const nextSlide = this._slides[this._currentSlideIndex === this._slides.length - 1 ? 0 : this._currentSlideIndex + 1]; const prevSlide = this._slides[this._currentSlideIndex === 0 ? this._slides.length - 1 : this._currentSlideIndex - 1]; let transitionOptions; // Rerender the current slide eg. if canvas has been resized if (reset) { currentSlide._rendered = false; } // Only render if we need to ie. only during transitions // or if the current slide contains video(s) if (!currentSlide._hasVideo && currentSlide._rendered && !this._transitionInProgress() && this._currentSlideIndex === this._transitionToIndex) { return; } this._drawSlide(this._currentContext, currentSlide); this._drawSlide(this._nextContext, nextSlide); this._drawSlide(this._prevContext, prevSlide); // Dispose of textures used in previous frame if (this._fromTexture) { this._fromTexture.dispose(); } if (this._toTexture) { this._toTexture.dispose(); } // Transition is already running or has been triggered by a change of _transitionToIndex if (this._transitionToIndex !== this._currentSlideIndex || this._transitionInProgress()) { // We're heading to the next slide (or the transition has been cancelled halfway through) if ((this._transitionToIndex !== this._currentSlideIndex && this._transitionDirection === TRANSITION_FORWARDS) || (this._transitionToIndex === this._currentSlideIndex && this._transitionDirection === TRANSITION_BACKWARDS)) { this._fromTexture = createTexture(this._renderContext, this._currentCanvas); this._toTexture = createTexture(this._renderContext, this._nextCanvas); transitionOptions = this._getTransition(currentSlide.transitionNext, nextSlide.transitionPrev); } // We're heading to the previous slide (or the transition has been cancelled halfway through) if ((this._transitionToIndex !== this._currentSlideIndex && this._transitionDirection === TRANSITION_BACKWARDS) || (this._transitionToIndex === this._currentSlideIndex && this._transitionDirection === TRANSITION_FORWARDS)) { this._fromTexture = createTexture(this._renderContext, this._prevCanvas); this._toTexture = createTexture(this._renderContext, this._currentCanvas); transitionOptions = this._getTransition(currentSlide.transitionPrev, prevSlide.transitionNext); } } else { // We're not transitioning so just rerender current slide (only if needed) this._fromTexture = createTexture(this._renderContext, this._currentCanvas); this._toTexture = this._fromTexture; } if (transitionOptions && !this._transitionInProgress() && (!this._transitionOptions || this._transitionOptions.name !== transitionOptions.name || this._transitionOptions.name === TRANSITION_RANDOM)) { // Update transition options if required this._transitionOptions = transitionOptions; if (this._transition) { // Destroy current transition in preparation to create a new one this._transition.dispose(); this._transition = null; } } if (this._transitionOptions) { if (!this._transition) { this._transition = createTransition(this._renderContext, this._transitionOptions.glsl.shader); } if (this._transitionToIndex !== this._currentSlideIndex || this._transitionInProgress()) { // Increment the transition progress depending on the direction const progressIncrement = 60 / this._transitionOptions.duration; if (this._transitionDirection === TRANSITION_FORWARDS) { this._transitionProgress = this._transitionInProgress() ? this._transitionProgress + progressIncrement : progressIncrement; } if (this._transitionDirection === TRANSITION_BACKWARDS) { this._transitionProgress = this._transitionInProgress() ? this._transitionProgress - progressIncrement : 1 - progressIncrement; } } // We've reached the end of the transition if (this._transitionProgress > 1) { this._transitionProgress = 1; } if (this._transitionProgress < 0) { this._transitionProgress = 0; } const easedTransitionProgress = eases[this._transitionOptions.ease](this._transitionProgress); this._transition.render(easedTransitionProgress, this._fromTexture, this._toTexture, this._transitionOptions.glsl.uniforms); } else { // No transition specified, just render if (!this._transition) { this._transition = createTransition(this._renderContext, TRANSITION_NONE_SHADER); } this._transition.render(1, this._fromTexture, this._toTexture); } // We have rendered the current slide for the first time if (currentSlide._ready) { currentSlide._rendered = true; if (!this._currentSlideRendered) { this._currentSlideRendered = true; this._playSlideContent(this._transitionToIndex); this._slideRendered(); } } // Transition is finished if (this._transitionToIndex !== this._currentSlideIndex && !this._transitionInProgress()) { this._currentSlideIndex = this._transitionToIndex; this._clearContext(this._currentContext); this._clearContext(this._nextContext); this._clearContext(this._prevContext); this._pauseSlideContent(); this._transitionEnded(); } }
Cloth.prototype.generateFabricPattern = function (is_front) { var canvas = document.createElement("canvas"); var size = 1024; canvas.width = size; canvas.height = size; var context = canvas.getContext("2d"); if (is_front) { context.fillStyle = "rgb(223,31,25)"; } else { context.fillStyle = "rgb(9,59,147)"; } context.fillRect(0, 0, size, size); var boundaryCircleRadius = size / 8.5; var margin = boundaryCircleRadius * 0.75; var circleRadius = boundaryCircleRadius * 0.55; var longArmLength = circleRadius * 0.75; var shortArmLength = circleRadius * 0.6; var armWidth = circleRadius * 0.25; context.strokeStyle = "rgb(9,6,5)"; var i, j; var isOddRow = true; for (i = 0; i < size; i += boundaryCircleRadius * Math.sqrt(2)) { for (j = 0; j < size + boundaryCircleRadius; j += boundaryCircleRadius * 2) { var cx = j + ((Math.random() * 2 - 1) * (margin - circleRadius)); var cy = i + ((Math.random() * 2 - 1) * (margin - circleRadius)); if (!isOddRow) { cx += boundaryCircleRadius; } if (is_front) { context.fillStyle = "rgb(252,248,133)"; } else { context.fillStyle = "rgb(205,230,231)"; } context.lineWidth = 4; context.beginPath(); context.arc(cx, cy, circleRadius, 0, 2 * Math.PI); context.fill(); context.stroke(); var theta = Math.random() * 2 * Math.PI; var phi = Math.random() * (135.0 / 180.0) * Math.PI + (45.0 / 180) * Math.PI; context.fillStyle = "rgb(9,6,5)"; context.lineWidth = 2; context.beginPath(); context.moveTo(cx + shortArmLength * Math.cos(theta), cy + shortArmLength * Math.sin(theta)); context.lineTo(cx + 0.5 * armWidth * Math.cos(theta + phi * 0.5), cy + 0.5 * armWidth * Math.sin(theta + phi * 0.5)); context.lineTo(cx + longArmLength * Math.cos(theta + phi), cy + longArmLength * Math.sin(theta + phi)); context.lineTo(cx - 0.5 * armWidth * Math.cos(theta + phi * 0.5), cy - 0.5 * armWidth * Math.sin(theta + phi * 0.5)); context.lineTo(cx + shortArmLength * Math.cos(theta), cy + shortArmLength * Math.sin(theta)); context.fill(); context.stroke(); } isOddRow = !isOddRow; } var texture = createTexture2D(this.gl, canvas); texture.generateMipmap(); texture.minFilter = this.gl.LINEAR_MIPMAP_LINEAR; texture.magFilter = this.gl.LINEAR; return texture; };