@monkstone – Thank you for your concern. Unfortunately I don’t know Ruby and it seems the problem I’m facing has to do with the DwGLSLProgram
variable declaration. A variable that doesn’t seem to be used in your example sketches. Great contribution anyway.
@GoToLoop – I see. I deliberately reduced the Python code to the problematic snippet for clarity (that snippet should be working) but here’s my attempt to implement the MyParticleSystem
class in full sketch:
add_library('PixelFlow')
from com.jogamp.opengl import GL2ES2
def setup():
global fluid, pg_fluid, context, particles, tex_particles
size(1000, 800, P2D)
frameRate(1000)
smooth(8)
context = DwPixelFlow(this)
fluid = DwFluid2D(context, width, height, 0)
tex_particles = DwGLTexture.TexturePingPong()
pg_fluid = createGraphics(width, height, P2D)
particles = Particles(context, 1000 * 1000)
fluid.param.dissipation_velocity = 0.99
fluid.param.dissipation_density = 0.99
fluid.param.dissipation_temperature = 0.1
fluid.param.vorticity = 0.00
fluid.param.timestep = 0.1
fluid.addCallback_FluiData(MyFluidData())
def draw():
image(pg_fluid, 0, 0)
pg_fluid.beginDraw()
pg_fluid.background(0)
pg_fluid.endDraw()
fluid.update()
fluid.renderFluidTextures(pg_fluid, 0)
#particles.update(fluid)
#particles.render(pg_fluid, 0)
class MyFluidData(DwFluid2D.FluidData):
def update(_, fluid):
if mousePressed:
radius = 15
px = mouseX
py = height-mouseY
vx = (mouseX-pmouseX) * 15
vy = (mouseY-pmouseY) * -15
fluid.addVelocity(px, py, 20, vx, vy)
fluid.addDensity(px, py, 20, 0.0, 0.4, .7, .5)
#particles.spawn(fluid, px, py, radius, 100)
class Particles(object):
def __init__(self, context, n_particles):
self.context = context
self.npart = n_particles
self.ALIVE_LO = 0
self.ALIVE_HI = 0
self.ALIVE_PARTICLES = 0
self.dissipation = 0.90
self.intertia = 0.20
self.particles_x = 0
self.particles_y = 0
self.resiz(self.context, self.npart)
def dispose(self):
release()
def release(self):
tex_particles.release()
def resiz(self, context, n_particles):
self.particles_x = ceil(sqrt(n_particles))
self.particles_y = self.particles_x
context.begin()
self.release()
mxpart = self.particles_x * self.particles_y
shader_particleSpawn = context.createShader("data/particleSpawn.frag")
shader_particleUpdate = context.createShader("data/particleUpdate.frag")
shader_particleRender = context.createShader("data/particleRender.glsl", "data/particleRender.glsl")
shader_particleRender.vert.setDefine("SHADER_VERT", 1)
shader_particleRender.frag.setDefine("SHADER_FRAG", 1)
tex_particles.resize(context, GL2ES2.GL_RGBA32F, self.particles_x, self.particles_y, GL2ES2.GL_RGBA, GL2ES2.GL_FLOAT, GL2ES2.GL_NEAREST, 4, 4);
context.end("ParticleSystem.resize");
reset();
def spawn(self, fluid, px, py, radius, count):
count = round(count * 1.0)
spawn_lo = self.ALIVE_HI
spawn_hi = min(self.spawn.lo + count, n_particles)
no = float(random()) * PI
context.begin()
context.beginDraw(self.tex_articles.dst)
shader_particleSpawn.begin()
shader_particleSpawn.uniform1i("spawn_lo", self.spawn_lo)
shader_particleSpawn.uniform1i("spawn_hi", self.spawn_hi)
shader_particleSpawn.uniform2f("spawn_origin", px, py)
shader_particleSpawn.uniform1f("spawn_radius", radius)
shader_particleSpawn.uniform1f("noise", no)
shader_particleSpawn.uniform2f("wh_particles" , self.particles_x, self.particles_y)
shader_particleSpawn.uniformTexture("tex_particles" , tex_particles.src)
shader_particleSpawn.drawFullScreenQuad()
shader_particleSpawn.end()
context.endDraw()
context.end("ParticleSystem.spawn")
self.tex_particles.swap()
self.ALIVE_HI = spawn_hi;
self.ALIVE_PARTICLES = max(self.ALIVE_PARTICLES, self.ALIVE_HI - self.ALIVE_LO)
def update(self, fluid):
self.context.begin();
self.context.beginDraw(tex_particles.dst);
shader_particleUpdate.begin();
shader_particleUpdate.uniform2f("wh_fluid", fluid.fluid_w, fluid.fluid_h);
shader_particleUpdate.uniform2f("wh_particles", self.particles_x, self.particles_y);
shader_particleUpdate.uniform1f("timestep", fluid.param.timestep);
shader_particleUpdate.uniform1f("rdx", 1.0 / fluid.param.gridscale);
shader_particleUpdate.uniform1f("dissipation", self.dissipation);
shader_particleUpdate.uniform1f("inertia", self.inertia);
shader_particleUpdate.uniformTexture("tex_particles", tex_particles.src);
shader_particleUpdate.uniformTexture("tex_velocity" , fluid.tex_velocity.src);
shader_particleUpdate.uniformTexture("tex_obstacles", fluid.tex_obstacleC.src);
shader_particleUpdate.drawFullScreenQuad();
shader_particleUpdate.end();
self.context.endDraw();
self.context.end("ParticleSystem.update");
tex_particles.swap()
def render(self, dst, bg):
num_points_to_render = self.ALIVE_PARTICLES
w = dst.width
h = dst.height
dst.beginDraw();
dst.blendMode(PConstants.BLEND)
if bg == 0: dst.bendMode(PConstants.ADD)
context.begin();
shader_particleRender.begin()
shader_particleRender.uniform2f("wh_viewport", w, h)
shader_particleRender.uniform2i("num_particles", self.particles_x, self.particles_y)
shader_particleRender.uniform1f("point_size", 1.5)
shader_particleRender.uniformTexture("tex_particles", tex_particles.src)
shader_particleRender.drawFullScreenPoints(num_points_to_render)
shader_particleRender.end();
context.end("ParticleSystem.render");
dst.endDraw();