Loading...
Logo
Processing Forum

Hiii,

I am implementing an application in processing in which I am using glDrawArrays function of openGL with mode as GL.GL_TRIANGLES.

for(int i=0i<maxParticlesi++) 
            
{
                
if(particles[i].alpha 0
                
{
                    particles[i]
.update();
                    
particles[i].updateVertexArrays(iposArraycolArray);
                
}
            }
            gl
.glEnableClientState(GL.GL_VERTEX_ARRAY);
            
gl.glVertexPointer(2GL.GL_FLOAT0posArray);

            
gl.glEnableClientState(GL.GL_COLOR_ARRAY);
            
gl.glColorPointer(3GL.GL_FLOAT0colArray); 
         
//   gl.glScalef(1.7,1.7,0.5);
            
gl.glDrawArrays(GL.GL_TRIANGLES0maxParticles 2);

I want to increase the size of particles of the triangle.For this I tried to use glScalef function too but after using this particles are not rendered at mouseX and mouseY position,rather the position has been translated.
Can anyone please help me out.

Replies(14)

Is particles an object of a class ? Is there a creation argument with the size of the particle in that class ?
Ya  there is a particle class and same as that of msafluiddemo application
///////////////////////////////////////////////////////////
class Particle
{
    final static float MOMENTUM = 0.5;
    final static float FLUID_FORCE = 0.6;

    float x, y;
    float vx, vy;
    float radius;       // particle's size
    float alpha;
    float mass;

    void init(float x, float y)
    {
        this.x = x;
        this.y = y;
        vx = 0;
        vy = 0;
        radius = 5;
        alpha  = random(.1,.5);
        mass = random(0.1, 1);
    }
////////////////////////////////////////////////////////////


and code to draw the particle is as follows:
///////////////////////////////////////////////////
PGraphicsOpenGL pgl = (PGraphicsOpenGL) g;         // processings opengl graphics object
        GL gl = pgl.beginGL();                            // JOGL's GL object

        gl.glEnable( GL.GL_BLEND );             // enable blending
        gl.glBlendFunc(GL.GL_ONE, GL.GL_ONE);  // additive blending (ignore alpha)
        gl.glEnable(GL.GL_LINE_SMOOTH);        // make points round
       
            for(int i=0; i<maxParticles; i++)
            {
                if(particles[i].alpha > 0)
                {
                    particles[i].update();
                    particles[i].updateVertexArrays(i, posArray, colArray);
                }
            }
            gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
            gl.glVertexPointer(2, GL.GL_FLOAT, 0, posArray);

            gl.glEnableClientState(GL.GL_COLOR_ARRAY);
            gl.glColorPointer(3, GL.GL_FLOAT, 0, colArray);
           // gl.glScalef(1.7,1.7,0.5);
            gl.glDrawArrays(GL.GL_TRIANGLES, 0, maxParticles * 2);                
            pgl.endGL();
           
  ///////////////////////////////////////////////////////////////

Basically i want to make following changes in this application:
1) change background color
2) change the  mode in glDrawArray to GL.GL_TRIANGLES and increase the size of particle on the mess.

Please help me out how to do this.

Well, to increase the size of the particle, I would start by experimenting with changing the radius in the init()... 
I have tried this too.Actually variable radius has been mentioned in the program but never used anywhere.
Changing the value of radius does not affect particle size.
hi, could you post the update() and updateVertexArray() methods of the Particle class?
 void update()
    {
        // update only if particle is visible
        if(alpha == 0) return;

        // read fluid info and add to velocity
       int fluidIndex = fluidSolver.getIndexForNormalizedPosition(x * invWidth, y * invHeight);//  here value of x is tcur.getX()*width :)
       vx = fluidSolver.u[fluidIndex] * width * mass * FLUID_FORCE + vx * MOMENTUM;  //not getting :(
       vy = fluidSolver.v[fluidIndex] * height * mass * FLUID_FORCE + vy * MOMENTUM; 
                      
        // update position
       x += vx;
       y += vy;

        // bounce of edges
        if(x<0) {
            x = 0;
            vx *= -1;
        }
        else if(x > width) {
            x = width;
            vx *= -1;
        }

        if(y<0) {
            y = 0;
            vy *= -1;
        }
        else if(y > height) {
            y = height;
            vy *= -1;
        }

        // make particles glitter when the slow down a lot
        if(vx * vx + vy * vy < 1) {
            vx = random(-1, 1);
            vy = random(-1, 1);
        }

        // fade out a bit (and kill if alpha == 0);
      //  alpha *= 0.99;
        if(alpha <=1)
           alpha *= 0.999;
        if(alpha < 0.01) alpha = 0;

    }


    void updateVertexArrays(int i, FloatBuffer posBuffer, FloatBuffer colBuffer)
    {
        int vi = i * 4;
       posBuffer.put(vi++, x - vx);// 2 points for previous cursor
       posBuffer.put(vi++, y - vy);
       posBuffer.put(vi++, x);//2 poits for current cursor
       posBuffer.put(vi++, y);

        int ci = i * 6;
        colBuffer.put(ci++, alpha);
        colBuffer.put(ci++, alpha);
        colBuffer.put(ci++, alpha);
        colBuffer.put(ci++, alpha);
        colBuffer.put(ci++, alpha);
        colBuffer.put(ci++, alpha);
    }
 }








This is the complete application:

import msafluid.*;
//import fullscreen.*;
import processing.opengl.*;
import javax.media.opengl.*;

final float FLUID_WIDTH = 120;

float invWidth, invHeight;    // inverse of screen dimensions
float aspectRatio, aspectRatio2;

MSAFluidSolver2D fluidSolver;

ParticleSystem particleSystem;

PImage imgFluid;

boolean drawFluid = true;
//FullScreen fs;
void setup()
{
    size(1024,768,OPENGL);    // use OPENGL rendering for bilinear filtering on texture
    //    size(screen.width * 49/50, screen.height * 49/50, OPENGL);
    hint( ENABLE_OPENGL_4X_SMOOTH );    // Turn on 4X antialiasing
  //  fs = new FullScreen(this);
   // fs.enter();
    invWidth = 1.0f/width;
    invHeight = 1.0f/height;
    aspectRatio = width * invHeight;
    aspectRatio2 = aspectRatio * aspectRatio;

    // create fluid and set options
    fluidSolver = new MSAFluidSolver2D((int)(FLUID_WIDTH), (int)(FLUID_WIDTH * height/width));
    fluidSolver.enableRGB(true).setFadeSpeed(0.3).setDeltaT(0.03).setVisc(0.001);
     background(0,120,234);
    // create image to hold fluid picture
    imgFluid = createImage(fluidSolver.getWidth(), fluidSolver.getHeight(), RGB);

    // create particle system
    particleSystem = new ParticleSystem();

    // init TUIO
    initTUIO();
}


void draw()
{
    background(0,120,234); 
    updateTUIO();
    fluidSolver.update();

     for(int i=0; i<fluidSolver.getNumCells(); i++)
        {
            int d = 2;
            imgFluid.pixels[i] = color(fluidSolver.r[i] * d, fluidSolver.g[i] * d, fluidSolver.b[i] * d);
        } 
    background(0,120,234); 
   
    imgFluid.updatePixels();    
    image(imgFluid, 0, 0, width, height);
    particleSystem.updateAndDraw();
}

// add force and dye to fluid, and create particles
void addForce(float x, float y, float dx, float dy)
{
   // balance the x and y components of speed with the screen aspect ratio
    float speed = dx * dx  + dy * dy * aspectRatio2;
    if(speed > 0)
    {
        if(x<0)
           x = 0;
        else if(x>1)
            x = 1;
        if(y<0)
           y = 0;
        else if(y>1)
              y = 1;

        float colorMult = 5;
        float velocityMult = 50.0f;

        int index = fluidSolver.getIndexForNormalizedPosition(x, y);

        color drawColor;

        colorMode(HSB, 360, 1, 1);
        float hue = ( (x+y)*180 ) % 360;
        // float saturation = (x*90)%360;
         // float brightness = (y*90)%360;
        drawColor = color(hue,1,1);
        colorMode(RGB, 1); 
/*
        fluidSolver.rOld[index]  += red(drawColor) * colorMult;
        fluidSolver.rOld[index]  += (drawColor>> 16 & 0xFF) *colorMult;
        fluidSolver.gOld[index]  += green(drawColor) * colorMult;
        fluidSolver.bOld[index]  += blue(drawColor) * colorMult;
*/
        particleSystem.addParticles(x * width, y * height, 10);
        fluidSolver.uOld[index] += dx * velocityMult;
        fluidSolver.vOld[index] += dy * velocityMult;
    }
}

class Particle
{
    final static float MOMENTUM = 0.5;
    final static float FLUID_FORCE = 0.6;

    float x, y;
    float vx, vy;
    float radius;       // particle's size
    float alpha;
    float mass;

    void init(float x, float y)
    {
        this.x = x;
        this.y = y;
        vx = 0;
        vy = 0;
        radius = 20;
        alpha  = random(.1,.5);
        mass = random(0.1, 1);
    }


    void update()
    {
        // update only if particle is visible
        if(alpha == 0) return;

        // read fluid info and add to velocity
       int fluidIndex = fluidSolver.getIndexForNormalizedPosition(x * invWidth, y * invHeight);//  here value of x is tcur.getX()*width :)
       vx = fluidSolver.u[fluidIndex] * width * mass * FLUID_FORCE + vx * MOMENTUM;  //not getting :(
       vy = fluidSolver.v[fluidIndex] * height * mass * FLUID_FORCE + vy * MOMENTUM; 
                      
        // update position
       x += vx;
       y += vy;

        // bounce of edges
        if(x<0) {
            x = 0;
            vx *= -1;
        }
        else if(x > width) {
            x = width;
            vx *= -1;
        }

        if(y<0) {
            y = 0;
            vy *= -1;
        }
        else if(y > height) {
            y = height;
            vy *= -1;
        }

        // make particles glitter when the slow down a lot
        if(vx * vx + vy * vy < 1) {
            vx = random(-1, 1);
            vy = random(-1, 1);
        }

        // fade out a bit (and kill if alpha == 0);
      //  alpha *= 0.99;
        if(alpha <=1)
           alpha *= 0.999;
        if(alpha < 0.01) alpha = 0;

    }


    void updateVertexArrays(int i, FloatBuffer posBuffer, FloatBuffer colBuffer)
    {
        int vi = i * 4;
       posBuffer.put(vi++, x - vx);// 2 points for previous cursor
       posBuffer.put(vi++, y - vy);
       posBuffer.put(vi++, x);//2 poits for current cursor
       posBuffer.put(vi++, y);

        int ci = i * 6;
        colBuffer.put(ci++, alpha);
        colBuffer.put(ci++, alpha);
        colBuffer.put(ci++, alpha);
        colBuffer.put(ci++, alpha);
        colBuffer.put(ci++, alpha);
        colBuffer.put(ci++, alpha);
    }
 }


import java.nio.FloatBuffer;
import com.sun.opengl.util.*;


class ParticleSystem
{
    FloatBuffer posArray;
    FloatBuffer colArray;

    final static int maxParticles = 5000;
    int curIndex;

    Particle[] particles;

    ParticleSystem()
    {
        particles = new Particle[maxParticles];
        for(int i=0; i<maxParticles; i++) particles[i] = new Particle();
        curIndex = 0;

        posArray = BufferUtil.newFloatBuffer(maxParticles * 2 * 2);// 2 coordinates per point, 2 points per particle (current and previous)
        colArray = BufferUtil.newFloatBuffer(maxParticles * 3 * 2);//for color..
    }


    void updateAndDraw()
    {
        PGraphicsOpenGL pgl = (PGraphicsOpenGL) g;         // processings opengl graphics object
        GL gl = pgl.beginGL();                            // JOGL's GL object

        gl.glEnable( GL.GL_BLEND );             // enable blending
        gl.glBlendFunc(GL.GL_ONE, GL.GL_ONE);  // additive blending (ignore alpha)
        gl.glEnable(GL.GL_LINE_SMOOTH);        // make points round
       
            for(int i=0; i<maxParticles; i++)
            {
                if(particles[i].alpha > 0)
                {
                    particles[i].update();
                    particles[i].updateVertexArrays(i, posArray, colArray);
                }
            }
           // gl.glColor4f(1,0,0,1);
            gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
            gl.glVertexPointer(2, GL.GL_FLOAT, 0, posArray);

          gl.glEnableClientState(GL.GL_COLOR_ARRAY);
          gl.glColorPointer(3, GL.GL_FLOAT, 0, colArray);
         ///   gl.glScalef(1.7,1.7,0.5);
            gl.glDrawArrays(GL.GL_TRIANGLES, 0, maxParticles * 2);                
            pgl.endGL();
           
           
    }


    void addParticles(float x, float y, int count ){
        for(int i=0; i<count; i++) addParticle(x + random(-15, 15), y + random(-15, 15));
    }


    void addParticle(float x, float y)
    {
        particles[curIndex].init(x, y);
        curIndex++;
        if(curIndex >= maxParticles) curIndex = 0;
    }

}








in the original code, the line
gl.glDrawArrays(GL.GL_TRIANGLES, 0, maxParticles * 2);  
was
 gl.glDrawArrays(GL.GL_LINES, 0, maxParticles * 2);

wich makes sense because when you fill the posArray, you only add two points 
posBuffer.put(vi++, x - vx);
posBuffer.put(vi++, y - vy);
posBuffer.put(vi++, x);
posBuffer.put(vi++, y);

and those two points are for a line (if you really wanted to render some triangles, you would need 3 points)

so your particles are drawn like small lines. if you want to change them to points you shoud use
gl.glDrawArrays(GL.GL_POINTS, 0, maxParticles*2);

and gl.glPointSize(5); //after beginGL

Now it all depends on what you're trying to do...


Hummm you are right.It makes senses that 2 points are added to draw a line.
But when I added the following line after gl.beginGL

gl.glPointSize(5);

in the original MSAFluid application,still the size of particle is same as earlier ....
did you replace 
gl.glDrawArrays(GL.GL_LINES, 0, maxParticles*2);
by
gl.glDrawArrays(GL.GL_POINTS, 0, maxParticles*2);
?
It's working, look well because the default example brings

in
 void updateAndDraw(){    ....
 gl.glLineWidth(1); //  it's a different sintaxis working with points

in 
if(renderUsingVA) {  ....

 gl.glDrawArrays(GL.GL_LINES, 0, maxParticles * 2);


/////////////////////////// POINTS

in
 void updateAndDraw(){    ....

"gl.glPointSize(10);" // it's a different sintaxis working with points
 
in 
if(renderUsingVA) {  ....

gl.glDrawArrays(GL.GL_POINTS, 0, maxParticles*2);