OpenGL code too slow
in
Core Library Questions
•
1 year ago
Hello, I've created an animation in OpenGL of random points forming a solid (cube, sphere, cone or cylinder). On the background I have some random points moving randomly. The points are little sphere cause my project is in 3D and should be in stereo vision soon.
The problem is that the code makes the animation slow, and when I add the library for stereo vision it gets even slower. Is there any way I can optimize it?
Here's the source:
The problem is that the code makes the animation slow, and when I add the library for stereo vision it gets even slower. Is there any way I can optimize it?
Here's the source:
- import processing.opengl.*;
String solidtype = "cube";
String particlestype = "s";
int spheredetail = 3;
int xsize = 1000;
int ysize = 1000;
int zsize = 1000;
float halfxsize;
float halfysize;
float halfzsize;
float thistime;
float starttime = 2000;
float vel = 10;
float velr = 10;
float solidx = width/2;
float solidy = height/2;
float solidz = 1;
float solidxrotation = -PI/6;
float solidyrotation = -PI/6;
float solidzrotation = 0;
float density = 0.004;
int numr = 300;
int nums;
int ballsize = 3;
float side = 150;
float sradius = 150;
float cyradius = 150;
float coradius = 150;
float cyheight = 250;
float coheight = 250;
int backgroundcolor = 80;
int solidcolor = 100;
PVector[] randomp; //random pts
PVector[] solidp; //solid pts
int spheresup;
float[] xsphere;
float[] ysphere;
float[] zsphere;
int circocysup;
int cysup;
float halfcyheightneg;
float halfcyheightpos;
float[] xcylinder;
float[] ycylinder;
float[] zcylinder;
float[] xcylinderbase;
float[] ycylinderbase;
int circocosup;
double apotema;
int cosup;
float[] xcone;
float[] ycone;
float[] zcone;
float[] xconebase;
float[] yconebase;
float[] zconebase;
int qusup;
float[] xcube;
float[] ycube;
float[] zcube;
PVector[] qube;
float randomMvmtRange = 10;
float solidMvmtRange = 10;
float[] randomMvmt;
float[] solidMvmt;
void setup() {
initParametri();
colorMode(HSB);
//smooth(); //antialiasing
noStroke();
thistime = millis();
size(screen.width, screen.height, OPENGL);
camera(0, 0, 500, 0, 0, 0, 0, 1, 0);
}
void draw() {
render();
}
void render() {
background(0);
noFill();
renderBackground();
if (millis() > thistime + starttime) {
if (solidtype.equals("sphere")) renderSphere(sradius);
if (solidtype.equals("cylinder")) renderCylinder(cyradius, cyheight);
if (solidtype.equals("cone")) renderCone(coradius, coheight);
if (solidtype.equals("cube")) renderCube(side);
}
}
void renderBackground() {
int k;
pushMatrix();
//random points
for (int i=0; i<numr; i++) {
pushMatrix();
translate(randomp[i].x, randomp[i].y, randomp[i].z);
k = (int)random(0, numr-4);
randomp[i].x+=randomMvmt[k];
randomp[i].y+=randomMvmt[k+1];
randomp[i].z+=randomMvmt[k+2];
//collision detection
if (randomp[i].x>halfxsize) {
randomp[i].x=halfxsize;
randomp[i].x*=-1;
}
if (randomp[i].y>halfysize) {
randomp[i].y=halfysize;
randomp[i].y*=-1;
}
if (randomp[i].z>halfzsize) {
randomp[i].z=halfzsize;
randomp[i].z*=-1;
}
if (randomp[i].x<-halfxsize) {
randomp[i].x=halfxsize;
randomp[i].x*=-1;
}
if (randomp[i].y<-halfysize) {
randomp[i].y=halfysize;
randomp[i].y*=-1;
}
if (randomp[i].z<-halfzsize) {
randomp[i].z=halfzsize;
randomp[i].z*=-1;
}
fill(0, 0, backgroundcolor);
noStroke();
if (particlestype.equals("e")) {
ellipse(0, 0, ballsize, ballsize);
}
if (particlestype.equals("s")) {
sphereDetail(spheredetail);
sphere(ballsize);
}
popMatrix();
}
//solid points
rotateX(solidxrotation);
rotateY(solidyrotation);
rotateZ(solidzrotation);
for (int i=0; i<nums; i++) {
pushMatrix();
translate(solidp[i].x, solidp[i].y, solidp[i].z);
k = (int)random(0, nums-4);
solidp[i].x+=solidMvmt[k];
solidp[i].y+=solidMvmt[k+1];
solidp[i].z+=solidMvmt[k+2];
//collision detection
if (solidp[i].x>halfxsize) {
solidp[i].x=halfxsize;
solidp[i].x*=-1;
}
if (solidp[i].y>halfysize) {
solidp[i].y=halfysize;
solidp[i].y*=-1;
}
if (solidp[i].z>halfzsize) {
solidp[i].z=halfzsize;
solidp[i].z*=-1;
}
if (solidp[i].x<-halfxsize) {
solidp[i].x=halfxsize;
solidp[i].x*=-1;
}
if (solidp[i].y<-halfysize) {
solidp[i].y=halfysize;
solidp[i].y*=-1;
}
if (solidp[i].z<-halfzsize) {
solidp[i].z=halfzsize;
solidp[i].z*=-1;
}
fill(0, 0, solidcolor);
noStroke();
if (particlestype.equals("e")) {
ellipse(0, 0, ballsize, ballsize);
}
if (particlestype.equals("s")) {
sphereDetail(spheredetail);
sphere(ballsize);
}
popMatrix();
}
popMatrix();
}
void renderSphere(float sradius) {
for (int i=0; i<spheresup; i++) {
if(solidp[i].x>xsphere[i]) solidp[i].x-=vel;
if(solidp[i].x<xsphere[i]) solidp[i].x+=vel;
if(solidp[i].y>ysphere[i]) solidp[i].y-=vel;
if(solidp[i].y<ysphere[i]) solidp[i].y+=vel;
if(solidp[i].z>zsphere[i]) solidp[i].z-=vel;
if(solidp[i].z<zsphere[i]) solidp[i].z+=vel;
}
}
void renderCylinder(float sradius, float cyheight) {
for (int i=0; i<cysup; i++) {
if(solidp[i].x>xcylinder[i]) solidp[i].x-=vel;
if(solidp[i].x<xcylinder[i]) solidp[i].x+=vel;
if(solidp[i].z>ycylinder[i]) solidp[i].z-=vel;
if(solidp[i].z<ycylinder[i]) solidp[i].z+=vel;
if(solidp[i].y>zcylinder[i]) solidp[i].y-=vel;
if(solidp[i].y<zcylinder[i]) solidp[i].y+=vel;
}
for (int i=0; i<circocysup; i++) {
if(solidp[i+cysup].x>xcylinderbase[i]) solidp[i+cysup].x-=vel;
if(solidp[i+cysup].x<xcylinderbase[i]) solidp[i+cysup].x+=vel;
if(solidp[i+cysup].z>ycylinderbase[i]) solidp[i+cysup].z-=vel;
if(solidp[i+cysup].z<ycylinderbase[i]) solidp[i+cysup].z+=vel;
if(solidp[i+cysup].y>halfcyheightpos) solidp[i+cysup].y-=vel;
if(solidp[i+cysup].y<halfcyheightpos) solidp[i+cysup].y+=vel;
}
for (int i=0; i<circocysup; i++) {
if(solidp[i+cysup+circocysup].x>xcylinderbase[i]) solidp[i+cysup+circocysup].x-=vel;
if(solidp[i+cysup+circocysup].x<xcylinderbase[i]) solidp[i+cysup+circocysup].x+=vel;
if(solidp[i+cysup+circocysup].z>ycylinderbase[i]) solidp[i+cysup+circocysup].z-=vel;
if(solidp[i+cysup+circocysup].z<ycylinderbase[i]) solidp[i+cysup+circocysup].z+=vel;
if(solidp[i+cysup+circocysup].y>halfcyheightneg) solidp[i+cysup+circocysup].y-=vel;
if(solidp[i+cysup+circocysup].y<halfcyheightneg) solidp[i+cysup+circocysup].y+=vel;
}
}
void renderCone(float sradius, float coheight) {
for (int i=0; i<cosup; i++) {
if(solidp[i].x>xcone[i]) solidp[i].x-=vel;
if(solidp[i].x<xcone[i]) solidp[i].x+=vel;
if(solidp[i].z>zcone[i]) solidp[i].z-=vel;
if(solidp[i].z<zcone[i]) solidp[i].z+=vel;
if(solidp[i].y>ycone[i]) solidp[i].y-=vel;
if(solidp[i].y<ycone[i]) solidp[i].y+=vel;
}
for (int i=0; i<circocosup; i++) {
if(solidp[i+cosup].x>xconebase[i]) solidp[i+cosup].x-=vel;
if(solidp[i+cosup].x<xconebase[i]) solidp[i+cosup].x+=vel;
if(solidp[i+cosup].z>zconebase[i]) solidp[i+cosup].z-=vel;
if(solidp[i+cosup].z<zconebase[i]) solidp[i+cosup].z+=vel;
if(solidp[i+cosup].y>yconebase[i]) solidp[i+cosup].y-=vel;
if(solidp[i+cosup].y<yconebase[i]) solidp[i+cosup].y+=vel;
}
}
void renderCube(float side) {
for (int i=0; i<qusup; i++) {
if(solidp[i].x>xcube[i]) solidp[i].x-=vel;
if(solidp[i].x<xcube[i]) solidp[i].x+=vel;
if(solidp[i].y>ycube[i]) solidp[i].y-=vel;
if(solidp[i].y<ycube[i]) solidp[i].y+=vel;
if(solidp[i].z>zcube[i]) solidp[i].z-=vel;
if(solidp[i].z<zcube[i]) solidp[i].z+=vel;
}
}
void initParametri() {
randomp = new PVector[numr]; //random points
if (xsize == 0)
xsize = screen.width;
if (ysize == 0)
ysize = screen.height;
if (zsize == 0)
zsize = screen.width;
halfxsize = xsize/2;
halfysize = ysize/2;
halfzsize = zsize/2;
float stheta;
float sphi;
spheresup = (int)(4*PI*sradius*sradius*density);
xsphere = new float[spheresup];
ysphere = new float[spheresup];
zsphere = new float[spheresup];
circocysup = (int)(PI*cyradius*cyradius*density);
cysup = (int)(2*PI*cyradius*cyheight*density);
float cytheta;
float cyphi;
float om;
float r;
float ucy;
xcylinder = new float[cysup];
ycylinder = new float[cysup];
zcylinder = new float[cysup];
xcylinderbase = new float[circocysup];
ycylinderbase = new float[circocysup];
apotema = Math.sqrt((coradius*coradius)+(coheight*coheight));
cosup = (int)(PI*coradius*apotema*density);
circocosup = (int)(PI*coradius*coradius*density);
float cotheta;
float cophi;
float omco;
float rco;
float uco;
float thisradius;
xcone = new float[cosup];
ycone = new float[cosup];
zcone = new float[cosup];
xconebase = new float[circocosup];
yconebase = new float[circocosup];
zconebase = new float[circocosup];
qusup = (int)(6*side*side*density);
int c;
int q;
qube = new PVector[qusup];
xcube = new float[qusup];
ycube = new float[qusup];
zcube = new float[qusup];
for(int i=0; i<numr; i++) {
randomp[i] = new PVector(random(-xsize/2, xsize/2), random(-ysize/2, ysize/2), random(-zsize/2, zsize/2));
//randomp[i] = new PVector(random(0, xsize), random(0, ysize), random(-zsize, 0));
}
if (solidtype.equals("sphere")) {
solidp = new PVector[spheresup];
nums = spheresup;
}
if (solidtype.equals("cylinder")) {
solidp = new PVector[cysup+circocysup+circocysup];
nums = cysup+circocysup+circocysup;
}
if (solidtype.equals("cone")) {
solidp = new PVector[cosup+circocosup];
nums = cosup+circocosup;
}
if (solidtype.equals("cube")) {
solidp = new PVector[qusup];
nums = qusup;
}
for (int i=0; i<solidp.length; i++) {
solidp[i] = new PVector(random(-xsize/2, xsize/2), random(-ysize/2, ysize/2), random(-zsize/2, zsize/2));
if (solidtype.equals("sphere")) {
stheta = TWO_PI * random(0,1);
sphi = acos(2 * random(0,1) - 1);
xsphere[i] = cos(stheta)*sin(sphi)*sradius;
ysphere[i] = sin(stheta)*sin(sphi)*sradius;
zsphere[i] = cos(sphi)*sradius;
}
if (solidtype.equals("cube")) {
q =(int)(Math.random() * (5 + 1));
qube[i]=new PVector();
c = q%3;
setxyz(i, c, (q>2?1:0));
setxyz(i, (c+1)%3, random(0, 1));
setxyz(i, (c+2)%3, random(0, 1));
xcube[i] = qube[i].x*side-side/2;
ycube[i] = qube[i].y*side-side/2;
zcube[i] = qube[i].z*side-side/2;
}
}
if (solidtype.equals("cylinder")) {
for (int i=0; i<cysup; i++) {
cytheta = random(TWO_PI);
cyphi = random(cyheight);
xcylinder[i] = cos(cytheta)*cyradius;
ycylinder[i] = sin(cytheta)*cyradius;
zcylinder[i] = cyphi-cyheight/2;
}
for (int i=0; i<circocysup; i++) {
om = random(TWO_PI);
ucy = random(1)+random(1);
if(ucy>1) ucy = 2-ucy;
r = ucy*cyradius;
xcylinderbase[i] = sin(om)*r;
ycylinderbase[i] = cos(om)*r;
halfcyheightpos = cyheight/2;
halfcyheightneg = -halfcyheightpos;
}
}
if (solidtype.equals("cone")) {
for (int i=0; i<circocosup; i++) {
omco = random(TWO_PI);
uco = random(1)+random(1);
if(uco>1) uco = 2-uco;
rco= uco * coradius;
xconebase[i] = sin(omco)*rco;
yconebase[i] = coheight/2;
zconebase[i] = cos(omco)*rco;
}
for (int i=0; i<cosup; i++) {
uco = random(1)+random(1); //per distribuire i punti uniformemente
if(uco>1) uco = 2-uco;
cophi = uco * coheight; //per distribuire i punti uniformemente
//cophis[i] = random(coheight);
cotheta = random(TWO_PI);
thisradius = coradius * (cophi/coheight);
xcone[i] = cos(cotheta)*thisradius;
ycone[i] = cophi-coheight/2;
zcone[i] = sin(cotheta)*thisradius;
}
}
randomMvmt = new float[numr];
solidMvmt = new float[nums];
for(int i=0; i<numr; i++) {
randomMvmt[i] = random(-1,1) * randomMvmtRange;
}
for(int i=0; i<nums; i++) {
solidMvmt[i] = random(-1,1) * solidMvmtRange;
}
}
void setxyz(int index, int xyz, float value) {
if (xyz==0) qube[index].x = value;
else if (xyz==1) qube[index].y = value;
else if (xyz==2) qube[index].z = value;
}
Thanks!
1