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 & HelpSyntax Questions › draw only once but still possible to rotate
Page Index Toggle Pages: 1
draw only once but still possible to rotate? (Read 1913 times)
draw only once but still possible to rotate?
Apr 16th, 2009, 5:04am
 
I calculate positions for sphere's according to the rgb values.
Drawning this on the screen goes quite slow (a few seconds).

Is it possible to speed this up, so I can rotate it with the mouse?

Code:
PImage img;

void setup(){
 size(600, 600, P3D);
 noStroke();
 smooth();
 //noFill();
 img = loadImage("img.png");
 noLoop();
}


void draw(){
 lights();

//  pushMatrix();
//
 translate(width/2, height/2, 0);
//  rotateX( radians(mouseY));
//  rotateY( radians(mouseX));
 //box(250);

 translate( -128,   -128, -128);

 for (int i=0; i<img.pixels.length; i++){
   fill(color(img.pixels[i]));
   
   pushMatrix();
   translate(red(img.pixels[i]), green(img.pixels[i]), blue(img.pixels[i]));
   sphere(5);
   popMatrix();
 }

}
Re: draw only once but still possible to rotate?
Reply #1 - Apr 16th, 2009, 5:36am
 
I couldn't get your drawing to work, but thought I would offer an idea.  Peasycam (http://mrfeinberg.com/peasycam/) is a nice library for camera movement and rotation.  If you load it up, then it should allow you to rotation the camera, instead of the object, which may give the same effect your looking for.  
Re: draw only once but still possible to rotate?
Reply #2 - Apr 16th, 2009, 6:08am
 
peasycam is nice but the speed is the problem.

p.s. why didn't you get the drawning to work?
Re: draw only once but still possible to rotate?
Reply #3 - Apr 16th, 2009, 6:44am
 
Don't know... I added an image to the data directory but the program wouldn't do anything... I saw no sphere, no images, no background... nada.  Just sat there doing nothing.  My guess was that my image wasn't like your image or something... since your doing some odd pixel counts.

As far as speed, if you can compute the information once (in the start) and put it into an array, then you could just call the array during draw and I think it would be much faster.  Don't recompute stuff more than once unless you have to.  And don't send it to your video card more than once unless you have to.  You may want to look at digging into OpenGL a bit.  Display lists, shaders, and such...
Re: draw only once but still possible to rotate?
Reply #4 - Apr 16th, 2009, 8:29am
 
clankill3r wrote on Apr 16th, 2009, 6:08am:
why didn't you get the drawning to work

Aren't you supposed to use loadPixels() before accessing pixels[] array
Re: draw only once but still possible to rotate?
Reply #5 - Apr 16th, 2009, 9:45am
 
maybe the image you tried was to big, my is 52x50 and that still takes a few seconds (5 or something).

Peasycam requires redrawning the scene aswell so that won't speed up.
Using an array will help a litle bit but it's mostly drawning 2600 sphere's and light them.. OpenGL looks to complicated to me..
I have some ideas to speed up, so maybe I will work on that later.

Philho, it works by me and I dont use loadpixels, I think the image he tried was to huge so calculating took to long.
Re: draw only once but still possible to rotate?
Reply #6 - Apr 18th, 2009, 3:05am
 
I can't offer you a solution, but I remember the red() green() and blue() functions to be very processor intensive. You'd better run them once, and store the values.
Re: draw only once but still possible to rotate?
Reply #7 - Apr 18th, 2009, 4:35am
 
i guess that will work for this example, but clankiller, dont you intend to use a webcam input ?
Re: draw only once but still possible to rotate?
Reply #8 - Apr 18th, 2009, 5:59am
 
this one is to slow for webcam but else I would have Smiley
Re: draw only once but still possible to rotate?
Reply #9 - Apr 19th, 2009, 11:43am
 
As already been pointed out the main problem is speed of rendering the sphere, change sphere to box and things really race, but its not so pretty.
In a 24bit image the number of unique colours will be close to the number of pixels. I did some tests with a 3200 pixel image with 2633 unique colours, this would result in approx 567 duplicate spheres, also many of the spheres were so close in color that the spheres overlapped and it was impossible to distiguish the difference in colour.
The approach I took was to remove duplicates and to reduce the number of spheres where the colour difference was small. The changes in code are significant but fairly straightforward.
Using the image mentioned above the code below resulted in 239 spheres and a 12 fold increase in speed.
Code:

import java.util.TreeSet;


PixelBall[] pballs;
int nbrPixels;
TreeSet pbset = new TreeSet();

PImage img;
long time;


void setup(){
size(600, 600, P3D);
noStroke();
smooth();
//noFill();
img = loadImage("img.png");
// noLoop();

nbrPixels = img.pixels.length;

int x,y,z;
int col;
int value;
// This defines how similar colours are to be considered the same
// the larger the value then bigger differences are considered
// insignificant.
int similar = 16; // bigger the value less spheres
for (int i=0; i<nbrPixels; i++){
x = (int) red(img.pixels[i]);
y = (int) green(img.pixels[i]);
z = (int) blue(img.pixels[i]);
value = (x / similar) << 15;
value += (y / similar) << 8;
value += (z / similar);
col = img.pixels[i];
pbset.add(new PixelBall(x,y,z,col, value)); // does not allow 'dulicates'
}
println("Pixels " + nbrPixels + " --> " + pbset.size() + " spheres" );
// Convert set to array for fast traversal for rendering
pballs = (PixelBall[])pbset.toArray(new PixelBall[pbset.size()]);
pbset = null;

time = System.currentTimeMillis();
}


void draw(){
lights();
// pushMatrix();
//
translate(width/2, height/2, 0);
// rotateX( radians(mouseY));
// rotateY( radians(mouseX));
//box(250);

translate( -128, -128, -128);
//println(img.pixels.length);

for (int i=0; i<pballs.length; i++)
pballs[i].display();
//Time since last render complete
long t = System.currentTimeMillis();
println(t - time);
time = t;
}

public class PixelBall implements Comparable {
private int x,y,z;
private int col;
private int value;

PixelBall(int x, int y, int z, int col, int value){
this.x = x;
this.y = y;
this.z = z;
this.col = col;
this.value = value;
}

public void display(){
pushMatrix();
translate(x,y,z);
fill(col);
sphere(5);
popMatrix();
}

public int compareTo(Object o) {
PixelBall pb = (PixelBall) o;
// defines whether 2 PixelBalls are the 'same'
return (new Integer(value).compareTo(new Integer(pb.value)));
}

}

Re: draw only once but still possible to rotate?
Reply #10 - Apr 19th, 2009, 11:56am
 
thx a lot for helping in such a great way.

I'm quite busy with other things atm but I will look at it as soon as I have time for it (can take a while).
As for the boxes, I did the thing with boxes aswell and indeed it was a lot faster.

o yeah, where is this for ?:
import java.util.TreeSet;
Re: draw only once but still possible to rotate?
Reply #11 - Apr 19th, 2009, 2:56pm
 
clankill3r wrote on Apr 19th, 2009, 11:56am:
o yeah, where is this for :
import java.util.TreeSet;


This needs to be at the beginning of the code.

An array is a data structure used to store large amounts of data that we can easily access. The problem with the array is that it difficult to avoid storing duplicate values.

A TreeSet is a Java collection that can also hold large amounts of data but has the special property of not allowing duplicates.

In the code I created a class called PixelBall to represent the spheres to display. In this class there is an attribute called value which has been created from the pixel colour. The way value is calculated means that 2 pixels with similar but different colours can have the same value.

So for each pixel a PixelBall object is created and added to the TreeSet, but it will reject the PixelBall object if there is already one  with the same value in the TreeSet. So this then removes duplicate / similar pixels.

Finally because the TreeSet is slow to iterate through it is converted to an array to speed rendering.
Re: draw only once but still possible to rotate?
Reply #12 - Apr 19th, 2009, 3:27pm
 
it probably would be better to use OPENGL instead of P3D to get it working faster.

import processing.opengl.*;

then size(x, y, OPENGL);

it would be as simple as that to get opengl to work in this context.
Re: draw only once but still possible to rotate?
Reply #13 - Sep 8th, 2009, 12:47pm
 
maybe sphereDetail() will help you -- have a look at the reference if you've not tried it
Page Index Toggle Pages: 1