diff --git a/script.js b/script.js index df97d6afa16310e29b1557af717a5ff2c17056f0..ac49d763f6357d0fadf671381691de1ecb9064dc 100644 --- a/script.js +++ b/script.js @@ -24,7 +24,7 @@ SOFTWARE. 'use strict'; -// Promo code +// Mobile promo section const promoPopup = document.getElementsByClassName('promo')[0]; const promoPopupClose = document.getElementsByClassName('promo-close')[0]; @@ -51,7 +51,7 @@ googleLink.addEventListener('click', e => { window.open('https://play.google.com/store/apps/details?id=games.paveldogreat.fluidsimfree'); }); -// Simulation code +// Simulation section const canvas = document.getElementsByTagName('canvas')[0]; resizeCanvas(); @@ -918,8 +918,22 @@ const blit = (() => { gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(0); - return (destination) => { - gl.bindFramebuffer(gl.FRAMEBUFFER, destination); + return (target, clear = false) => { + if (target == null) + { + gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + } + else + { + gl.viewport(0, 0, target.width, target.height); + gl.bindFramebuffer(gl.FRAMEBUFFER, target.fbo); + } + if (clear) + { + gl.clearColor(0.0, 0.0, 0.0, 1.0); + gl.clear(gl.COLOR_BUFFER_BIT); + } gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0); } })(); @@ -966,6 +980,8 @@ function initFramebuffers () { const r = ext.formatR; const filtering = ext.supportLinearFiltering ? gl.LINEAR : gl.NEAREST; + gl.disable(gl.BLEND); + if (dye == null) dye = createDoubleFBO(dyeRes.width, dyeRes.height, rgba.internalFormat, rgba.format, texType, filtering); else @@ -1084,7 +1100,7 @@ function resizeFBO (target, w, h, internalFormat, format, type, param) { let newFBO = createFBO(w, h, internalFormat, format, type, param); copyProgram.bind(); gl.uniform1i(copyProgram.uniforms.uTexture, target.attach(0)); - blit(newFBO.fbo); + blit(newFBO); return newFBO; } @@ -1205,12 +1221,11 @@ function applyInputs () { function step (dt) { gl.disable(gl.BLEND); - gl.viewport(0, 0, velocity.width, velocity.height); curlProgram.bind(); gl.uniform2f(curlProgram.uniforms.texelSize, velocity.texelSizeX, velocity.texelSizeY); gl.uniform1i(curlProgram.uniforms.uVelocity, velocity.read.attach(0)); - blit(curl.fbo); + blit(curl); vorticityProgram.bind(); gl.uniform2f(vorticityProgram.uniforms.texelSize, velocity.texelSizeX, velocity.texelSizeY); @@ -1218,18 +1233,18 @@ function step (dt) { gl.uniform1i(vorticityProgram.uniforms.uCurl, curl.attach(1)); gl.uniform1f(vorticityProgram.uniforms.curl, config.CURL); gl.uniform1f(vorticityProgram.uniforms.dt, dt); - blit(velocity.write.fbo); + blit(velocity.write); velocity.swap(); divergenceProgram.bind(); gl.uniform2f(divergenceProgram.uniforms.texelSize, velocity.texelSizeX, velocity.texelSizeY); gl.uniform1i(divergenceProgram.uniforms.uVelocity, velocity.read.attach(0)); - blit(divergence.fbo); + blit(divergence); clearProgram.bind(); gl.uniform1i(clearProgram.uniforms.uTexture, pressure.read.attach(0)); gl.uniform1f(clearProgram.uniforms.value, config.PRESSURE); - blit(pressure.write.fbo); + blit(pressure.write); pressure.swap(); pressureProgram.bind(); @@ -1237,7 +1252,7 @@ function step (dt) { gl.uniform1i(pressureProgram.uniforms.uDivergence, divergence.attach(0)); for (let i = 0; i < config.PRESSURE_ITERATIONS; i++) { gl.uniform1i(pressureProgram.uniforms.uPressure, pressure.read.attach(1)); - blit(pressure.write.fbo); + blit(pressure.write); pressure.swap(); } @@ -1245,7 +1260,7 @@ function step (dt) { gl.uniform2f(gradienSubtractProgram.uniforms.texelSize, velocity.texelSizeX, velocity.texelSizeY); gl.uniform1i(gradienSubtractProgram.uniforms.uPressure, pressure.read.attach(0)); gl.uniform1i(gradienSubtractProgram.uniforms.uVelocity, velocity.read.attach(1)); - blit(velocity.write.fbo); + blit(velocity.write); velocity.swap(); advectionProgram.bind(); @@ -1257,17 +1272,15 @@ function step (dt) { gl.uniform1i(advectionProgram.uniforms.uSource, velocityId); gl.uniform1f(advectionProgram.uniforms.dt, dt); gl.uniform1f(advectionProgram.uniforms.dissipation, config.VELOCITY_DISSIPATION); - blit(velocity.write.fbo); + blit(velocity.write); velocity.swap(); - gl.viewport(0, 0, dye.width, dye.height); - if (!ext.supportLinearFiltering) gl.uniform2f(advectionProgram.uniforms.dyeTexelSize, dye.texelSizeX, dye.texelSizeY); gl.uniform1i(advectionProgram.uniforms.uVelocity, velocity.read.attach(0)); gl.uniform1i(advectionProgram.uniforms.uSource, dye.read.attach(1)); gl.uniform1f(advectionProgram.uniforms.dissipation, config.DENSITY_DISSIPATION); - blit(dye.write.fbo); + blit(dye.write); dye.swap(); } @@ -1287,31 +1300,29 @@ function render (target) { gl.disable(gl.BLEND); } - let width = target == null ? gl.drawingBufferWidth : target.width; - let height = target == null ? gl.drawingBufferHeight : target.height; - gl.viewport(0, 0, width, height); - - let fbo = target == null ? null : target.fbo; if (!config.TRANSPARENT) - drawColor(fbo, normalizeColor(config.BACK_COLOR)); + drawColor(target, normalizeColor(config.BACK_COLOR)); if (target == null && config.TRANSPARENT) - drawCheckerboard(fbo); - drawDisplay(fbo, width, height); + drawCheckerboard(target); + drawDisplay(target); } -function drawColor (fbo, color) { +function drawColor (target, color) { colorProgram.bind(); gl.uniform4f(colorProgram.uniforms.color, color.r, color.g, color.b, 1); - blit(fbo); + blit(target); } -function drawCheckerboard (fbo) { +function drawCheckerboard (target) { checkerboardProgram.bind(); gl.uniform1f(checkerboardProgram.uniforms.aspectRatio, canvas.width / canvas.height); - blit(fbo); + blit(target); } -function drawDisplay (fbo, width, height) { +function drawDisplay (target) { + let width = target == null ? gl.drawingBufferWidth : target.width; + let height = target == null ? gl.drawingBufferHeight : target.height; + displayMaterial.bind(); if (config.SHADING) gl.uniform2f(displayMaterial.uniforms.texelSize, 1.0 / width, 1.0 / height); @@ -1324,7 +1335,7 @@ function drawDisplay (fbo, width, height) { } if (config.SUNRAYS) gl.uniform1i(displayMaterial.uniforms.uSunrays, sunrays.attach(3)); - blit(fbo); + blit(target); } function applyBloom (source, destination) { @@ -1342,16 +1353,14 @@ function applyBloom (source, destination) { gl.uniform3f(bloomPrefilterProgram.uniforms.curve, curve0, curve1, curve2); gl.uniform1f(bloomPrefilterProgram.uniforms.threshold, config.BLOOM_THRESHOLD); gl.uniform1i(bloomPrefilterProgram.uniforms.uTexture, source.attach(0)); - gl.viewport(0, 0, last.width, last.height); - blit(last.fbo); + blit(last); bloomBlurProgram.bind(); for (let i = 0; i < bloomFramebuffers.length; i++) { let dest = bloomFramebuffers[i]; gl.uniform2f(bloomBlurProgram.uniforms.texelSize, last.texelSizeX, last.texelSizeY); gl.uniform1i(bloomBlurProgram.uniforms.uTexture, last.attach(0)); - gl.viewport(0, 0, dest.width, dest.height); - blit(dest.fbo); + blit(dest); last = dest; } @@ -1363,7 +1372,7 @@ function applyBloom (source, destination) { gl.uniform2f(bloomBlurProgram.uniforms.texelSize, last.texelSizeX, last.texelSizeY); gl.uniform1i(bloomBlurProgram.uniforms.uTexture, last.attach(0)); gl.viewport(0, 0, baseTex.width, baseTex.height); - blit(baseTex.fbo); + blit(baseTex); last = baseTex; } @@ -1372,22 +1381,19 @@ function applyBloom (source, destination) { gl.uniform2f(bloomFinalProgram.uniforms.texelSize, last.texelSizeX, last.texelSizeY); gl.uniform1i(bloomFinalProgram.uniforms.uTexture, last.attach(0)); gl.uniform1f(bloomFinalProgram.uniforms.intensity, config.BLOOM_INTENSITY); - gl.viewport(0, 0, destination.width, destination.height); - blit(destination.fbo); + blit(destination); } function applySunrays (source, mask, destination) { gl.disable(gl.BLEND); sunraysMaskProgram.bind(); gl.uniform1i(sunraysMaskProgram.uniforms.uTexture, source.attach(0)); - gl.viewport(0, 0, mask.width, mask.height); - blit(mask.fbo); + blit(mask); sunraysProgram.bind(); gl.uniform1f(sunraysProgram.uniforms.weight, config.SUNRAYS_WEIGHT); gl.uniform1i(sunraysProgram.uniforms.uTexture, mask.attach(0)); - gl.viewport(0, 0, destination.width, destination.height); - blit(destination.fbo); + blit(destination); } function blur (target, temp, iterations) { @@ -1395,11 +1401,11 @@ function blur (target, temp, iterations) { for (let i = 0; i < iterations; i++) { gl.uniform2f(blurProgram.uniforms.texelSize, target.texelSizeX, 0.0); gl.uniform1i(blurProgram.uniforms.uTexture, target.attach(0)); - blit(temp.fbo); + blit(temp); gl.uniform2f(blurProgram.uniforms.texelSize, 0.0, target.texelSizeY); gl.uniform1i(blurProgram.uniforms.uTexture, temp.attach(0)); - blit(target.fbo); + blit(target); } } @@ -1424,20 +1430,18 @@ function multipleSplats (amount) { } function splat (x, y, dx, dy, color) { - gl.viewport(0, 0, velocity.width, velocity.height); splatProgram.bind(); gl.uniform1i(splatProgram.uniforms.uTarget, velocity.read.attach(0)); gl.uniform1f(splatProgram.uniforms.aspectRatio, canvas.width / canvas.height); gl.uniform2f(splatProgram.uniforms.point, x, y); gl.uniform3f(splatProgram.uniforms.color, dx, dy, 0.0); gl.uniform1f(splatProgram.uniforms.radius, correctRadius(config.SPLAT_RADIUS / 100.0)); - blit(velocity.write.fbo); + blit(velocity.write); velocity.swap(); - gl.viewport(0, 0, dye.width, dye.height); gl.uniform1i(splatProgram.uniforms.uTarget, dye.read.attach(0)); gl.uniform3f(splatProgram.uniforms.color, color.r, color.g, color.b); - blit(dye.write.fbo); + blit(dye.write); dye.swap(); }