From d4ade613e9eeed9c8c50f5d43540eb9d406e9438 Mon Sep 17 00:00:00 2001 From: drawcall Date: Fri, 10 Sep 2021 11:49:35 +0800 Subject: [PATCH] feat: add destroy method --- src/render/BaseRenderer.js | 2 + src/render/PixelRenderer.js | 36 +-- src/render/PixiRenderer.js | 33 +-- src/render/WebGLRenderer.js | 549 +++++++++++++++++++----------------- src/zone/CircleZone.js | 5 +- 5 files changed, 319 insertions(+), 306 deletions(-) diff --git a/src/render/BaseRenderer.js b/src/render/BaseRenderer.js index 67c51a3..c0693e1 100755 --- a/src/render/BaseRenderer.js +++ b/src/render/BaseRenderer.js @@ -63,6 +63,8 @@ export default class BaseRenderer { destroy() { this.remove(); + this.pool.destroy(); + this.element = null; } remove(proton) { diff --git a/src/render/PixelRenderer.js b/src/render/PixelRenderer.js index c00c9e3..8a87af3 100755 --- a/src/render/PixelRenderer.js +++ b/src/render/PixelRenderer.js @@ -20,27 +20,13 @@ export default class PixelRenderer extends BaseRenderer { } createImageData(rectangle) { - this.rectangle = rectangle - ? rectangle - : new Rectangle(0, 0, this.element.width, this.element.height); - this.imageData = this.context.createImageData( - this.rectangle.width, - this.rectangle.height - ); - this.context.putImageData( - this.imageData, - this.rectangle.x, - this.rectangle.y - ); + this.rectangle = rectangle ? rectangle : new Rectangle(0, 0, this.element.width, this.element.height); + this.imageData = this.context.createImageData(this.rectangle.width, this.rectangle.height); + this.context.putImageData(this.imageData, this.rectangle.x, this.rectangle.y); } onProtonUpdate() { - this.context.clearRect( - this.rectangle.x, - this.rectangle.y, - this.rectangle.width, - this.rectangle.height - ); + this.context.clearRect(this.rectangle.x, this.rectangle.y, this.rectangle.width, this.rectangle.height); this.imageData = this.context.getImageData( this.rectangle.x, this.rectangle.y, @@ -50,11 +36,7 @@ export default class PixelRenderer extends BaseRenderer { } onProtonUpdateAfter() { - this.context.putImageData( - this.imageData, - this.rectangle.x, - this.rectangle.y - ); + this.context.putImageData(this.imageData, this.rectangle.x, this.rectangle.y); } onParticleCreated(particle) {} @@ -63,8 +45,8 @@ export default class PixelRenderer extends BaseRenderer { if (this.imageData) { this.setPixel( this.imageData, - Math.floor(particle.p.x - this.rectangle.x), - Math.floor(particle.p.y - this.rectangle.y), + (particle.p.x - this.rectangle.x) >> 0, + (particle.p.y - this.rectangle.y) >> 0, particle ); } @@ -72,11 +54,9 @@ export default class PixelRenderer extends BaseRenderer { setPixel(imagedata, x, y, particle) { const rgb = particle.rgb; - if (x < 0 || x > this.element.width || y < 0 || y > this.elementwidth) - return; + if (x < 0 || x > this.element.width || y < 0 || y > this.elementwidth) return; const i = ((y >> 0) * imagedata.width + (x >> 0)) * 4; - imagedata.data[i] = rgb.r; imagedata.data[i + 1] = rgb.g; imagedata.data[i + 2] = rgb.b; diff --git a/src/render/PixiRenderer.js b/src/render/PixiRenderer.js index a72ba7e..49205e4 100755 --- a/src/render/PixiRenderer.js +++ b/src/render/PixiRenderer.js @@ -20,8 +20,7 @@ export default class PixiRenderer extends BaseRenderer { setPIXI(PIXI) { try { PIXIClass = PIXI || { Sprite: {} }; - this.createFromImage = - PIXIClass.Sprite.from || PIXIClass.Sprite.fromImage; + this.createFromImage = PIXIClass.Sprite.from || PIXIClass.Sprite.fromImage; } catch (e) {} } @@ -64,19 +63,6 @@ export default class PixiRenderer extends BaseRenderer { particle.body = null; } - destroy(particles) { - super.destroy(); - this.pool.destroy(); - - let i = particles.length; - while (i--) { - let particle = particles[i]; - if (particle.body) { - this.element.removeChild(particle.body); - } - } - } - transform(particle, target) { target.x = particle.p.x; target.y = particle.p.y; @@ -96,9 +82,7 @@ export default class PixiRenderer extends BaseRenderer { } createSprite(body) { - const sprite = body.isInner - ? this.createFromImage(body.src) - : new PIXIClass.Sprite(body); + const sprite = body.isInner ? this.createFromImage(body.src) : new PIXIClass.Sprite(body); sprite.anchor.x = 0.5; sprite.anchor.y = 0.5; @@ -120,4 +104,17 @@ export default class PixiRenderer extends BaseRenderer { return graphics; } + + destroy(particles) { + super.destroy(); + this.pool.destroy(); + + let i = particles.length; + while (i--) { + let particle = particles[i]; + if (particle.body) { + this.element.removeChild(particle.body); + } + } + } } diff --git a/src/render/WebGLRenderer.js b/src/render/WebGLRenderer.js index e5eea64..8789410 100755 --- a/src/render/WebGLRenderer.js +++ b/src/render/WebGLRenderer.js @@ -1,270 +1,307 @@ -import Mat3 from '../math/Mat3'; -import BaseRenderer from './BaseRenderer'; +import Mat3 from "../math/Mat3"; +import BaseRenderer from "./BaseRenderer"; -import Util from '../utils/Util'; -import ImgUtil from '../utils/ImgUtil'; -import MStack from '../utils/MStack'; -import DomUtil from '../utils/DomUtil'; -import WebGLUtil from '../utils/WebGLUtil'; -import MathUtil from '../math/MathUtil'; +import Util from "../utils/Util"; +import ImgUtil from "../utils/ImgUtil"; +import MStack from "../utils/MStack"; +import DomUtil from "../utils/DomUtil"; +import WebGLUtil from "../utils/WebGLUtil"; +import MathUtil from "../math/MathUtil"; export default class WebGLRenderer extends BaseRenderer { - - constructor(element) { - super(element); - - this.gl = this.element.getContext('experimental-webgl', { antialias: true, stencil: false, depth: false }); - if (!this.gl) alert('Sorry your browser do not suppest WebGL!'); - - this.initVar(); - this.setMaxRadius(); - this.initShaders(); - this.initBuffers(); - - this.gl.blendEquation(this.gl.FUNC_ADD); - this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA); - this.gl.enable(this.gl.BLEND); - - this.addImg2Body = this.addImg2Body.bind(this); - - this.name = 'WebGLRenderer'; - } - - init(proton) { - super.init(proton); - this.resize(this.element.width, this.element.height); - } - - resize(width, height) { - this.umat[4] = -2; - this.umat[7] = 1; - - this.smat[0] = 1 / width; - this.smat[4] = 1 / height; - - this.mstack.set(this.umat, 0); - this.mstack.set(this.smat, 1); - - this.gl.viewport(0, 0, width, height); - this.element.width = width; - this.element.height = height; + constructor(element) { + super(element); + + this.gl = this.element.getContext("experimental-webgl", { antialias: true, stencil: false, depth: false }); + if (!this.gl) alert("Sorry your browser do not suppest WebGL!"); + + this.initVar(); + this.setMaxRadius(); + this.initShaders(); + this.initBuffers(); + + this.gl.blendEquation(this.gl.FUNC_ADD); + this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA); + this.gl.enable(this.gl.BLEND); + this.addImg2Body = this.addImg2Body.bind(this); + + this.name = "WebGLRenderer"; + } + + init(proton) { + super.init(proton); + this.resize(this.element.width, this.element.height); + } + + resize(width, height) { + this.umat[4] = -2; + this.umat[7] = 1; + + this.smat[0] = 1 / width; + this.smat[4] = 1 / height; + + this.mstack.set(this.umat, 0); + this.mstack.set(this.smat, 1); + + this.gl.viewport(0, 0, width, height); + this.element.width = width; + this.element.height = height; + } + + setMaxRadius(radius) { + this.circleCanvasURL = this.createCircle(radius); + } + + getVertexShader() { + const vsSource = [ + "uniform vec2 viewport;", + "attribute vec2 aVertexPosition;", + "attribute vec2 aTextureCoord;", + "uniform mat3 tMat;", + "varying vec2 vTextureCoord;", + "varying float alpha;", + "void main() {", + "vec3 v = tMat * vec3(aVertexPosition, 1.0);", + "gl_Position = vec4(v.x, v.y, 0, 1);", + "vTextureCoord = aTextureCoord;", + "alpha = tMat[0][2];", + "}" + ].join("\n"); + return vsSource; + } + + getFragmentShader() { + const fsSource = [ + "precision mediump float;", + "varying vec2 vTextureCoord;", + "varying float alpha;", + "uniform sampler2D uSampler;", + "uniform vec4 color;", + "uniform bool useTexture;", + "uniform vec3 uColor;", + "void main() {", + "vec4 textureColor = texture2D(uSampler, vTextureCoord);", + "gl_FragColor = textureColor * vec4(uColor, 1.0);", + "gl_FragColor.w *= alpha;", + "}" + ].join("\n"); + return fsSource; + } + + initVar() { + this.mstack = new MStack(); + this.umat = Mat3.create([2, 0, 1, 0, -2, 0, -1, 1, 1]); + this.smat = Mat3.create([1 / 100, 0, 1, 0, 1 / 100, 0, 0, 0, 1]); + this.texturebuffers = {}; + } + + blendEquation(A) { + this.gl.blendEquation(this.gl[A]); + } + + blendFunc(A, B) { + this.gl.blendFunc(this.gl[A], this.gl[B]); + } + + getShader(gl, str, fs) { + const shader = fs ? gl.createShader(gl.FRAGMENT_SHADER) : gl.createShader(gl.VERTEX_SHADER); + + gl.shaderSource(shader, str); + gl.compileShader(shader); + + if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { + alert(gl.getShaderInfoLog(shader)); + return null; } - setMaxRadius(radius) { - this.circleCanvasURL = this.createCircle(radius); + return shader; + } + + initShaders() { + const fragmentShader = this.getShader(this.gl, this.getFragmentShader(), true); + const vertexShader = this.getShader(this.gl, this.getVertexShader(), false); + + this.sprogram = this.gl.createProgram(); + this.gl.attachShader(this.sprogram, vertexShader); + this.gl.attachShader(this.sprogram, fragmentShader); + this.gl.linkProgram(this.sprogram); + + if (!this.gl.getProgramParameter(this.sprogram, this.gl.LINK_STATUS)) alert("Could not initialise shaders"); + + this.gl.useProgram(this.sprogram); + this.sprogram.vpa = this.gl.getAttribLocation(this.sprogram, "aVertexPosition"); + this.sprogram.tca = this.gl.getAttribLocation(this.sprogram, "aTextureCoord"); + this.gl.enableVertexAttribArray(this.sprogram.tca); + this.gl.enableVertexAttribArray(this.sprogram.vpa); + + this.sprogram.tMatUniform = this.gl.getUniformLocation(this.sprogram, "tMat"); + this.sprogram.samplerUniform = this.gl.getUniformLocation(this.sprogram, "uSampler"); + this.sprogram.useTex = this.gl.getUniformLocation(this.sprogram, "useTexture"); + this.sprogram.color = this.gl.getUniformLocation(this.sprogram, "uColor"); + this.gl.uniform1i(this.sprogram.useTex, 1); + } + + initBuffers() { + const vs = [0, 3, 1, 0, 2, 3]; + let idx; + + this.unitIBuffer = this.gl.createBuffer(); + this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.unitIBuffer); + this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(vs), this.gl.STATIC_DRAW); + + let i; + let ids = []; + for (i = 0; i < 100; i++) ids.push(i); + idx = new Uint16Array(ids); + + this.unitI33 = this.gl.createBuffer(); + this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.unitI33); + this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, idx, this.gl.STATIC_DRAW); + + ids = []; + for (i = 0; i < 100; i++) ids.push(i, i + 1, i + 2); + idx = new Uint16Array(ids); + + this.stripBuffer = this.gl.createBuffer(); + this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.stripBuffer); + this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, idx, this.gl.STATIC_DRAW); + } + + createCircle(raidus) { + this.circleCanvasRadius = WebGLUtil.nhpot(Util.initValue(raidus, 32)); + const canvas = DomUtil.createCanvas("circle_canvas", this.circleCanvasRadius * 2, this.circleCanvasRadius * 2); + const context = canvas.getContext("2d"); + + context.beginPath(); + context.arc(this.circleCanvasRadius, this.circleCanvasRadius, this.circleCanvasRadius, 0, Math.PI * 2, true); + context.closePath(); + context.fillStyle = "#FFF"; + context.fill(); + + return canvas.toDataURL(); + } + + drawImg2Canvas(particle) { + const _w = particle.body.width; + const _h = particle.body.height; + + const _width = WebGLUtil.nhpot(particle.body.width); + const _height = WebGLUtil.nhpot(particle.body.height); + + const _scaleX = particle.body.width / _width; + const _scaleY = particle.body.height / _height; + + if (!this.texturebuffers[particle.data.src]) + this.texturebuffers[particle.data.src] = [ + this.gl.createTexture(), + this.gl.createBuffer(), + this.gl.createBuffer() + ]; + + particle.data.texture = this.texturebuffers[particle.data.src][0]; + particle.data.vcBuffer = this.texturebuffers[particle.data.src][1]; + particle.data.tcBuffer = this.texturebuffers[particle.data.src][2]; + + this.gl.bindBuffer(this.gl.ARRAY_BUFFER, particle.data.tcBuffer); + this.gl.bufferData( + this.gl.ARRAY_BUFFER, + new Float32Array([0.0, 0.0, _scaleX, 0.0, 0.0, _scaleY, _scaleY, _scaleY]), + this.gl.STATIC_DRAW + ); + this.gl.bindBuffer(this.gl.ARRAY_BUFFER, particle.data.vcBuffer); + this.gl.bufferData( + this.gl.ARRAY_BUFFER, + new Float32Array([0.0, 0.0, _w, 0.0, 0.0, _h, _w, _h]), + this.gl.STATIC_DRAW + ); + + const context = particle.data.canvas.getContext("2d"); + const data = context.getImageData(0, 0, _width, _height); + + this.gl.bindTexture(this.gl.TEXTURE_2D, particle.data.texture); + this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, data); + this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR); + this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR_MIPMAP_NEAREST); + this.gl.generateMipmap(this.gl.TEXTURE_2D); + + particle.data.textureLoaded = true; + particle.data.textureWidth = _w; + particle.data.textureHeight = _h; + } + + onProtonUpdate() { + // this.gl.clearColor(0, 0, 0, 1); + // this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT); + } + + onParticleCreated(particle) { + particle.data.textureLoaded = false; + particle.data.tmat = Mat3.create(); + particle.data.tmat[8] = 1; + particle.data.imat = Mat3.create(); + particle.data.imat[8] = 1; + + if (particle.body) { + ImgUtil.getImgFromCache(particle.body, this.addImg2Body, particle); + } else { + ImgUtil.getImgFromCache(this.circleCanvasURL, this.addImg2Body, particle); + particle.data.oldScale = particle.radius / this.circleCanvasRadius; } - - getVertexShader() { - const vsSource = ['uniform vec2 viewport;', 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', 'uniform mat3 tMat;', 'varying vec2 vTextureCoord;', 'varying float alpha;', 'void main() {', 'vec3 v = tMat * vec3(aVertexPosition, 1.0);', 'gl_Position = vec4(v.x, v.y, 0, 1);', 'vTextureCoord = aTextureCoord;', 'alpha = tMat[0][2];', '}'].join('\n'); - return vsSource; + } + + // private + addImg2Body(img, particle) { + if (particle.dead) return; + particle.body = img; + particle.data.src = img.src; + particle.data.canvas = ImgUtil.getCanvasFromCache(img); + particle.data.oldScale = 1; + + this.drawImg2Canvas(particle); + } + + onParticleUpdate(particle) { + if (particle.data.textureLoaded) { + this.updateMatrix(particle); + + this.gl.uniform3f(this.sprogram.color, particle.rgb.r / 255, particle.rgb.g / 255, particle.rgb.b / 255); + this.gl.uniformMatrix3fv(this.sprogram.tMatUniform, false, this.mstack.top()); + + this.gl.bindBuffer(this.gl.ARRAY_BUFFER, particle.data.vcBuffer); + this.gl.vertexAttribPointer(this.sprogram.vpa, 2, this.gl.FLOAT, false, 0, 0); + this.gl.bindBuffer(this.gl.ARRAY_BUFFER, particle.data.tcBuffer); + this.gl.vertexAttribPointer(this.sprogram.tca, 2, this.gl.FLOAT, false, 0, 0); + this.gl.bindTexture(this.gl.TEXTURE_2D, particle.data.texture); + this.gl.uniform1i(this.sprogram.samplerUniform, 0); + this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.unitIBuffer); + + this.gl.drawElements(this.gl.TRIANGLES, 6, this.gl.UNSIGNED_SHORT, 0); + this.mstack.pop(); } + } - getFragmentShader() { - const fsSource = ['precision mediump float;', 'varying vec2 vTextureCoord;', 'varying float alpha;', 'uniform sampler2D uSampler;', 'uniform vec4 color;', 'uniform bool useTexture;', 'uniform vec3 uColor;', 'void main() {', 'vec4 textureColor = texture2D(uSampler, vTextureCoord);', 'gl_FragColor = textureColor * vec4(uColor, 1.0);', 'gl_FragColor.w *= alpha;', '}'].join('\n'); - return fsSource; - } + onParticleDead(particle) {} - initVar() { - this.mstack = new MStack(); - this.umat = Mat3.create([2, 0, 1, 0, -2, 0, -1, 1, 1]); - this.smat = Mat3.create([1 / 100, 0, 1, 0, 1 / 100, 0, 0, 0, 1]); - this.texturebuffers = {}; - } + updateMatrix(particle) { + const moveOriginMatrix = WebGLUtil.makeTranslation( + -particle.data.textureWidth / 2, + -particle.data.textureHeight / 2 + ); + const translationMatrix = WebGLUtil.makeTranslation(particle.p.x, particle.p.y); - blendEquation(A) { - this.gl.blendEquation(this.gl[A]); - } + const angel = particle.rotation * MathUtil.PI_180; + const rotationMatrix = WebGLUtil.makeRotation(angel); - blendFunc(A, B) { - this.gl.blendFunc(this.gl[A], this.gl[B]); - } - - getShader(gl, str, fs) { - const shader = fs ? gl.createShader(gl.FRAGMENT_SHADER) : gl.createShader(gl.VERTEX_SHADER); + const scale = particle.scale * particle.data.oldScale; + const scaleMatrix = WebGLUtil.makeScale(scale, scale); + let matrix = WebGLUtil.matrixMultiply(moveOriginMatrix, scaleMatrix); - gl.shaderSource(shader, str); - gl.compileShader(shader); + matrix = WebGLUtil.matrixMultiply(matrix, rotationMatrix); + matrix = WebGLUtil.matrixMultiply(matrix, translationMatrix); - if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { - alert(gl.getShaderInfoLog(shader)); - return null; - } + Mat3.inverse(matrix, particle.data.imat); + matrix[2] = particle.alpha; - return shader; - } - - initShaders() { - const fragmentShader = this.getShader(this.gl, this.getFragmentShader(), true); - const vertexShader = this.getShader(this.gl, this.getVertexShader(), false); - - this.sprogram = this.gl.createProgram(); - this.gl.attachShader(this.sprogram, vertexShader); - this.gl.attachShader(this.sprogram, fragmentShader); - this.gl.linkProgram(this.sprogram); - - if (!this.gl.getProgramParameter(this.sprogram, this.gl.LINK_STATUS)) - alert('Could not initialise shaders'); - - this.gl.useProgram(this.sprogram); - this.sprogram.vpa = this.gl.getAttribLocation(this.sprogram, 'aVertexPosition'); - this.sprogram.tca = this.gl.getAttribLocation(this.sprogram, 'aTextureCoord'); - this.gl.enableVertexAttribArray(this.sprogram.tca); - this.gl.enableVertexAttribArray(this.sprogram.vpa); - - this.sprogram.tMatUniform = this.gl.getUniformLocation(this.sprogram, 'tMat'); - this.sprogram.samplerUniform = this.gl.getUniformLocation(this.sprogram, 'uSampler'); - this.sprogram.useTex = this.gl.getUniformLocation(this.sprogram, 'useTexture'); - this.sprogram.color = this.gl.getUniformLocation(this.sprogram, 'uColor'); - this.gl.uniform1i(this.sprogram.useTex, 1); - }; - - initBuffers() { - const vs = [0, 3, 1, 0, 2, 3]; - let idx; - - this.unitIBuffer = this.gl.createBuffer(); - this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.unitIBuffer); - this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(vs), this.gl.STATIC_DRAW); - - let i; - let ids = []; - for (i = 0; i < 100; i++) ids.push(i); - idx = new Uint16Array(ids); - - this.unitI33 = this.gl.createBuffer(); - this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.unitI33); - this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, idx, this.gl.STATIC_DRAW); - - ids = []; - for (i = 0; i < 100; i++) ids.push(i, i + 1, i + 2); - idx = new Uint16Array(ids); - - this.stripBuffer = this.gl.createBuffer(); - this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.stripBuffer); - this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, idx, this.gl.STATIC_DRAW); - }; - - createCircle(raidus) { - this.circleCanvasRadius = WebGLUtil.nhpot(Util.initValue(raidus, 32)); - const canvas = DomUtil.createCanvas('circle_canvas', this.circleCanvasRadius * 2, this.circleCanvasRadius * 2); - const context = canvas.getContext('2d'); - - context.beginPath(); - context.arc(this.circleCanvasRadius, this.circleCanvasRadius, this.circleCanvasRadius, 0, Math.PI * 2, true); - context.closePath(); - context.fillStyle = '#FFF'; - context.fill(); - - return canvas.toDataURL(); - }; - - drawImg2Canvas(particle) { - const _w = particle.body.width; - const _h = particle.body.height; - - const _width = WebGLUtil.nhpot(particle.body.width); - const _height = WebGLUtil.nhpot(particle.body.height); - - const _scaleX = particle.body.width / _width; - const _scaleY = particle.body.height / _height; - - if (!this.texturebuffers[particle.data.src]) - this.texturebuffers[particle.data.src] = [this.gl.createTexture(), this.gl.createBuffer(), this.gl.createBuffer()]; - - particle.data.texture = this.texturebuffers[particle.data.src][0]; - particle.data.vcBuffer = this.texturebuffers[particle.data.src][1]; - particle.data.tcBuffer = this.texturebuffers[particle.data.src][2]; - - this.gl.bindBuffer(this.gl.ARRAY_BUFFER, particle.data.tcBuffer); - this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array([0.0, 0.0, _scaleX, 0.0, 0.0, _scaleY, _scaleY, _scaleY]), this.gl.STATIC_DRAW); - this.gl.bindBuffer(this.gl.ARRAY_BUFFER, particle.data.vcBuffer); - this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array([0.0, 0.0, _w, 0.0, 0.0, _h, _w, _h]), this.gl.STATIC_DRAW); - - const context = particle.data.canvas.getContext('2d'); - const data = context.getImageData(0, 0, _width, _height); - - this.gl.bindTexture(this.gl.TEXTURE_2D, particle.data.texture); - this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, data); - this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR); - this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR_MIPMAP_NEAREST); - this.gl.generateMipmap(this.gl.TEXTURE_2D); - - particle.data.textureLoaded = true; - particle.data.textureWidth = _w; - particle.data.textureHeight = _h; - } - - onProtonUpdate() { - // this.gl.clearColor(0, 0, 0, 1); - // this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT); - } - - onParticleCreated(particle) { - particle.data.textureLoaded = false; - particle.data.tmat = Mat3.create(); - particle.data.tmat[8] = 1; - particle.data.imat = Mat3.create(); - particle.data.imat[8] = 1; - - if (particle.body) { - ImgUtil.getImgFromCache(particle.body, this.addImg2Body, particle); - } else { - ImgUtil.getImgFromCache(this.circleCanvasURL, this.addImg2Body, particle); - particle.data.oldScale = particle.radius / this.circleCanvasRadius; - } - } - - // private - addImg2Body(img, particle) { - if (particle.dead) return; - particle.body = img; - particle.data.src = img.src; - particle.data.canvas = ImgUtil.getCanvasFromCache(img); - particle.data.oldScale = 1; - - this.drawImg2Canvas(particle); - } - - onParticleUpdate(particle) { - if (particle.data.textureLoaded) { - this.updateMatrix(particle); - - this.gl.uniform3f(this.sprogram.color, particle.rgb.r / 255, particle.rgb.g / 255, particle.rgb.b / 255); - this.gl.uniformMatrix3fv(this.sprogram.tMatUniform, false, this.mstack.top()); - - this.gl.bindBuffer(this.gl.ARRAY_BUFFER, particle.data.vcBuffer); - this.gl.vertexAttribPointer(this.sprogram.vpa, 2, this.gl.FLOAT, false, 0, 0); - this.gl.bindBuffer(this.gl.ARRAY_BUFFER, particle.data.tcBuffer); - this.gl.vertexAttribPointer(this.sprogram.tca, 2, this.gl.FLOAT, false, 0, 0); - this.gl.bindTexture(this.gl.TEXTURE_2D, particle.data.texture); - this.gl.uniform1i(this.sprogram.samplerUniform, 0); - this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.unitIBuffer); - - this.gl.drawElements(this.gl.TRIANGLES, 6, this.gl.UNSIGNED_SHORT, 0); - - this.mstack.pop(); - } - } - - onParticleDead(particle) { } - - updateMatrix(particle) { - const moveOriginMatrix = WebGLUtil.makeTranslation(-particle.data.textureWidth / 2, -particle.data.textureHeight / 2); - const translationMatrix = WebGLUtil.makeTranslation(particle.p.x, particle.p.y); - - const angel = particle.rotation * (MathUtil.PI_180); - const rotationMatrix = WebGLUtil.makeRotation(angel); - - const scale = particle.scale * particle.data.oldScale; - const scaleMatrix = WebGLUtil.makeScale(scale, scale); - let matrix = WebGLUtil.matrixMultiply(moveOriginMatrix, scaleMatrix); - - matrix = WebGLUtil.matrixMultiply(matrix, rotationMatrix); - matrix = WebGLUtil.matrixMultiply(matrix, translationMatrix); - - Mat3.inverse(matrix, particle.data.imat); - matrix[2] = particle.alpha; - - this.mstack.push(matrix); - } -} \ No newline at end of file + this.mstack.push(matrix); + } +} diff --git a/src/zone/CircleZone.js b/src/zone/CircleZone.js index 34efc07..c6f1217 100755 --- a/src/zone/CircleZone.js +++ b/src/zone/CircleZone.js @@ -56,9 +56,6 @@ export default class CircleZone extends Zone { } getGradient(particle) { - return ( - -MathUtil.PI_2 + - Math.atan2(particle.p.y - this.center.y, particle.p.x - this.center.x) - ); + return -MathUtil.PI_2 + Math.atan2(particle.p.y - this.center.y, particle.p.x - this.center.x); } }