We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › Speed Optimization Question
Page Index Toggle Pages: 1
Speed Optimization Question (Read 543 times)
Speed Optimization Question
Mar 6th, 2009, 12:53am
 
Hi!
I'm a beginner and I tried to make another RGB-Cube with an offscreen buffer...
My problem is that I got REALLY slow framerates! I don't know how to optimize it.
Would be great if someone can have a look and tell me how to handle it!?
Thanks in advance
Powder

//PART ONE----------------------

int WIDTH, HEIGHT, ANZ_POINTS_1DIM, ANZ_POINTS_GES, DEPTH,
   anz_rects, alphaVal;
double DELTA, ROT_DELTA, ROT_DELTA_DELTA, rot;
Point pnts[][][];
Rect3D rects[];
PGraphics buffer;

void setup()
{
 frame.removeNotify();
 frame.setUndecorated(true);
 frame.addNotify();
 WIDTH = screen.width;
 HEIGHT = screen.height;
 size(WIDTH, HEIGHT, P3D);
 buffer = createGraphics(width, height, P3D);
 frameRate(30);
 background(0);
 noStroke();
 smooth();
 noCursor();
 
 // Set up variables
 ANZ_POINTS_1DIM = 20;
 DELTA = WIDTH/ANZ_POINTS_1DIM;  //Aenderung
 ANZ_POINTS_GES = ANZ_POINTS_1DIM*ANZ_POINTS_1DIM*ANZ_POINTS_1DIM;
 anz_rects = ANZ_POINTS_GES*100; //Stimmt nicht, nur Testwert
 DEPTH = 100;
 ROT_DELTA = PI/20.0;
 ROT_DELTA_DELTA = 0.1;
 rot = 0;
 alphaVal = 40;
 
 pnts = new Point[ANZ_POINTS_1DIM][ANZ_POINTS_1DIM][ANZ_POINTS_1DIM];
 rects = new Rect3D[anz_rects];
 
 // Fill Array
 for(int i=0; i<ANZ_POINTS_1DIM; i++)
 {
   for(int j=0; j<ANZ_POINTS_1DIM; j++)
   {
     for(int k=0; k<ANZ_POINTS_1DIM; k++)
     {
       pnts[i][j][k] = new Point((float)(i*DELTA-WIDTH/2), (float)(j*DELTA-HEIGHT/2), (float)(k*DELTA-DEPTH/2));
     }
   }
 }
 
 createRects();
}

void draw()
{
 buffer.beginDraw();
 buffer.background(0);
 buffer.noStroke();
 buffer.translate(WIDTH/2, HEIGHT/2, DEPTH/2-3000);
 buffer.rotateX((float)rot*0.2);
 buffer.rotateY((float)rot);
 buffer.rotateZ((float)rot*0.5);
 drawRects();  
 buffer.endDraw();  image(buffer, 0, 0);

 rot += ROT_DELTA;
}

void drawRects()
{
 for(int i=0; i<anz_rects; ++i)
 {
   rects[i].drawRect3D();  
 }
}
Re: Speed Optimization Question
Reply #1 - Mar 6th, 2009, 12:53am
 
//PART TWO--------------------------------

void createRects()
{
 int curRect = 0;
 for(int i=0; i<ANZ_POINTS_1DIM; i++)
 {
   for(int j=0; j<ANZ_POINTS_1DIM; j++)
   {
     for(int k=0; k<ANZ_POINTS_1DIM; k++)
     {
       checkArraySizeRects(curRect);
       //x-y-Rect
       if( pointExistsInArray( i+1, j, k ) && pointExistsInArray( i, j+1, k ) && pointExistsInArray( i+1, j+1, k ) )
       {
         Point p1 = new Point(pnts[i][j][k].x, pnts[i][j][k].y, pnts[i][j][k].z);
         Point p2 = new Point(pnts[i+1][j][k].x, pnts[i+1][j][k].y, pnts[i+1][j][k].z);
         Point p3 = new Point(pnts[i+1][j+1][k].x, pnts[i+1][j+1][k].y, pnts[i+1][j+1][k].z);
         Point p4 = new Point(pnts[i][j+1][k].x, pnts[i][j+1][k].y, pnts[i][j+1][k].z);
         color col = color(0, random(10, 255), 0);
         //color col = color(random(10, 255), random(10, 255), random(10, 255));
         rects[curRect] = new Rect3D(p1, p2, p3, p4, col);
         anz_rects = curRect+1;
         curRect++;          
       }
       //y-z-Rect
       if( pointExistsInArray( i, j, k+1 ) && pointExistsInArray( i, j+1, k ) && pointExistsInArray( i, j+1, k+1 ) )
       {
         Point p1 = new Point(pnts[i][j][k].x, pnts[i][j][k].y, pnts[i][j][k].z);
         Point p2 = new Point(pnts[i][j][k+1].x, pnts[i][j][k+1].y, pnts[i][j][k+1].z);
         Point p3 = new Point(pnts[i][j+1][k+1].x, pnts[i][j+1][k+1].y, pnts[i][j+1][k+1].z);
         Point p4 = new Point(pnts[i][j+1][k].x, pnts[i][j+1][k].y, pnts[i][j+1][k].z);
         //color col = color(random(10, 255), random(10, 255), random(10, 255));
         color col = color(random(10, 255), 0, 0);
         rects[curRect] = new Rect3D(p1, p2, p3, p4, col);
         anz_rects = curRect+1;
         curRect++;          
       }
       //x-z-Rect
       if( pointExistsInArray( i+1, j, k ) && pointExistsInArray( i, j, k+1 ) && pointExistsInArray( i+1, j, k+1 ) )
       {
         Point p1 = new Point(pnts[i][j][k].x, pnts[i][j][k].y, pnts[i][j][k].z);
         Point p2 = new Point(pnts[i][j][k+1].x, pnts[i][j][k+1].y, pnts[i][j][k+1].z);
         Point p3 = new Point(pnts[i+1][j][k+1].x, pnts[i+1][j][k+1].y, pnts[i+1][j][k+1].z);
         Point p4 = new Point(pnts[i+1][j][k].x, pnts[i+1][j][k].y, pnts[i+1][j][k].z);
         //color col = color(random(10, 255), random(10, 255), random(10, 255));
         color col = color(0, 0, random(10, 255));
         rects[curRect] = new Rect3D(p1, p2, p3, p4, col);
         anz_rects = curRect+1;
         curRect++;          
       }
     }  
   }
 }
}

int checkArraySizeRects(int pos)
{
 if(pos >= (rects.length-1))
   //Double size of Array
   rects = (Rect3D[])expand(rects);
   return rects.length;
}

boolean pointExistsInArray(int i, int j, int k)
{
 if(i<ANZ_POINTS_1DIM && j<ANZ_POINTS_1DIM && k<ANZ_POINTS_1DIM)
   return true;
 return false;
}

class Rect3D
{
 Point p1, p2, p3, p4;
 color col;
 Rect3D(Point p1, Point p2, Point p3, Point p4, color col)
 {
   this.p1 = p1;
   this.p2 = p2;
   this.p3 = p3;
   this.p4 = p4;
   this.col = col;
 }
 void drawRect3D()
 {
   buffer.fill(col, alphaVal);
   buffer.beginShape();
   buffer.vertex(p1.x, p1.y, p1.z);
   buffer.vertex(p2.x, p2.y, p2.z);  
   buffer.vertex(p3.x, p3.y, p3.z);  
   buffer.vertex(p4.x, p4.y, p4.z);  
   buffer.endShape(CLOSE);
 }
 
}

class Point
{
 float x, y, z;
 Point()
 {
   this.x = 0.0;
   this.y = 0.0;
   this.z = 0.0;
 }
 Point(float x, float y, float z)
 {
   this.x = x;
   this.y = y;
   this.z = z;
 }
 void drawPnt()
 {
   point(this.x, this.y, this.z);  
 }
}
Re: Speed Optimization Question
Reply #2 - Mar 6th, 2009, 9:18am
 
i think your main problem is drawing 21660 rectangles every frame 8) especially as you're doing it to a buffer (which means copying the buffer to the main screen every frame also. have you tried rendering it directly to the main screen?)

i also don't see much point in this (which is setup and so won't help the speed):

Code:

Point p1 = new Point(pnts[i][j][k].x, pnts[i][j][k].y, pnts[i][j][k].z);
Point p2 = new Point(pnts[i+1][j][k].x, pnts[i+1][j][k].y, pnts[i+1][j][k].z);
Point p3 = new Point(pnts[i+1][j+1][k].x, pnts[i+1][j+1][k].y, pnts[i+1][j+1][k].z);
Point p4 = new Point(pnts[i][j+1][k].x, pnts[i][j+1][k].y, pnts[i][j+1][k].z);
...
rects[curRect] = new Rect3D(p1, p2, p3, p4, col);


you seem to be copying the source points (pnt[i][j][k]) into a new point (p1) just so you can pass it to the Rect constructor. why not just use pnt[i][j][k] in the call?

Code:

rects[curRect] = new Rect3D(pnts[i][j][k], pnts[i+1][j][k], pnts[i+1][j+1][k], pnts[i][j+1][k], col);
Re: Speed Optimization Question
Reply #3 - Mar 6th, 2009, 1:44pm
 
OK thanks for your answer!
I edited what you mentioned (copying the point before passing it to the Rect3D constructor) but it's not faster...

Is there any possibility to let it run faster? :(

Without the buffer it runs even slower!
Re: Speed Optimization Question
Reply #4 - Mar 6th, 2009, 5:01pm
 
I tried some things with your sketch, but I haven't found an optimization. I think, you just reached a the performance limits of your machine and especially of java (which isn't the fastest environment).

It's not just drawing 21660 rectangles. It's also drawing them in this size. If you shrink the canvas and the buffer for example to 400x400 pixels, you will get a much higher frame rate.

It would be really interesting, if anyone finds an optimization for this sketch :-)
Re: Speed Optimization Question
Reply #5 - Mar 9th, 2009, 6:02am
 
So, I got your code to run okay with the following modifications:

1. I commented out this stuff :
Code:

//frame.removeNotify();
//frame.setUndecorated(true);
//frame.addNotify();


2. I changed the renderer to OpenGL by including this:
Code:
  import processing.opengl.*;  


And changing the size() line to this:
Code:
   size(WIDTH, WIDTH, OPENGL); 
hint(DISABLE_OPENGL_ERROR_REPORT);


3. I got rid of the off screen buffer, since you can't use OpenGL off screen.

To clarify, it was running at about 15fps at a 1900x1200 resolution. And 20 fps at 640x480.

This isn't really an optimization though, to get it to draw faster I would try vertex arrays. There is an example with 1,000,000 points here: http://processing.org/hacks/hacks:1000000points
Page Index Toggle Pages: 1