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.
Page Index Toggle Pages: 1
Sprites (Read 2781 times)
Sprites
Jun 5th, 2008, 8:44am
 
Long Version:
I know you can use a PNG24 on a quad and float it in 3d but what happens when you spin the camera around the quad? Your nice flare or what have you will be really skinny and at some angles non-existent. Is there a way to implement a sprite object so that you don't have to use code to keep re orientating your quad so that it's face to face with the camera?

Short Version:
Plunk down an image in 3d so that it's always facing the camera. Anyway to do itbesides always rotating a Quad with the image as a texture?

Please no strictly OpenGL suggestions (hacks), I'd like to stay flexible and stick to a processing solution for portability to P3D.
Re: Sprites
Reply #1 - Jun 5th, 2008, 6:03pm
 
Rotating the quad towards the camera is the way to do it.  Its not too hard either, here's a tutorial:

http://nehe.gamedev.net/data/articles/article.asp?article=19
Re: Sprites
Reply #2 - Jun 5th, 2008, 6:45pm
 
Many thanks! I suppose you could write your own library for a sprite object and then just use that. I was curious if the functionality was already built in.

Thanks!!!
Re: Sprites
Reply #3 - Jun 10th, 2008, 3:36pm
 
hi movax, thx for posting that tutorial, this is something ive been meaning to figure out for ages.

im going through it now but getting stuck.
here is my working for an individual billboard.

1) look vector = camera position vector - billboard location vector.
2) right vector = camera up vec ( i get this from OCD lib), crossed with look vec.
3) up vector = look vec crossed with right vec.

Vec3D look  = camPosition.subSelf( loc ).normalize();
Vec3D right = camUp.cross( look );
Vec3D up    = look.cross( right );

I suspect im going somewhere wrong here, as the tutorial only shows how to transform the coordinate space using a rotation matrix.

float degX = degrees( right.angleBetween( Vec3D.X_AXIS ) );
float degY = degrees( up.angleBetween( Vec3D.Y_AXIS ) );

gl.glPushMatrix();
gl.glTranslatef( loc.x, loc.y, loc.z );
gl.glRotatef( degX, 1, 0, 0 );
gl.glRotatef( degY, 0, 1, 0 );
... draw quad.

any examples anyone might have would be great.
Re: Sprites
Reply #4 - Jun 13th, 2008, 5:33pm
 
here is a quick way of rotating particles to face the camera.

float deltaX = camTarget.x - camPosition.x;
float deltaY = camTarget.y - camPosition.y;
float deltaZ = camTarget.z - camPosition.z;

float angleZ   = atan2( deltaY,deltaX );
float hyp      = sqrt( sq( deltaX ) + sq( deltaY ) );
float angleY   = atan2( hyp,deltaZ );

gl.glPushMatrix();
gl.glTranslatef( loc.x, loc.y, loc.z );
gl.glRotatef( degrees( angleZ ), 0, 0,    1.0f );
gl.glRotatef( degrees( angleY ), 0, 1.0f, 0    );
gl.glScalef( renderSize, renderSize, 0 );
gl.glBegin( GL.GL_QUADS );

gl.glColor4f( 1, 1, 1, 1 );
gl.glTexCoord2f( 0, 0 );
gl.glVertex3f( -0.5f, -0.5f, 0 );
gl.glTexCoord2f( 0, 1 );
gl.glVertex3f( -0.5f,  0.5f, 0 );
gl.glTexCoord2f( 1, 1 );
gl.glVertex3f(  0.5f,  0.5f, 0 );
gl.glTexCoord2f( 1, 0 );
gl.glVertex3f(  0.5f, -0.5f, 0 );

gl.glEnd();
gl.glPopMatrix();

problem with this method is the particles rotate around the Z axis, not sure why.  Won't notice this is your particle texture is circular but you will notice it rotate if its any other shape.
Re: Sprites
Reply #5 - Jun 13th, 2008, 9:33pm
 
Julapy,

Im doing using a simular method as what you put forth. I also notice my sprites rotating around the Z axis as I move the camera. Im trying to make floating labels with normals pointing to the camera as well as aligned to the cameras up vector.

Just thinking outloud: Take the angle difference between the Camera View normal and the world Z axix (0,0,1) then rotate the Z of the sprite in the opposite direction that amount.

Going to give that a try.
Re: Sprites
Reply #6 - Jun 13th, 2008, 10:29pm
 
Yeah... that didn't work at all. I miss understood the relationship of the rotation. Seems that the rotation of the sprite controlled by movement on all three axii. Will be tough to nail that down.

Any other ideas?
Re: Sprites
Reply #7 - Jun 14th, 2008, 9:38am
 
Are you trying to get "billboarding" to work?
Cause I have an old sketch with that implemented:
http://www.seltar.org/projects/particle3D/v2/

best of luck,
seltar
Re: Sprites
Reply #8 - Jun 15th, 2008, 5:16am
 
Perfect, thanks selter.
Re: Sprites
Reply #9 - Jun 15th, 2008, 6:52pm
 
In the end I just re-read the tutorial posted above and was able to solve the problem with a quick matrix.

void billBoard() {
   // make sure translation is already in place. expects position of object to be at 0, 0, 0
   applyMatrix
   (
     right.x, up.x, look.x, 0,
     right.y, up.y, look.y, 0,
     right.z, up.z, look.z, 0,
     0, 0, 0, 1
   );
}

Where right, up and look are the cameras normal vectors.
the right most column, is the world position of the sprite . I expect that im translating to this point to place the sprite before calling the billboard so the coords will be (0,0,0)

To calculate the camera normals: Using OCD and toxi Vec3D:
   Vec3D loc;
   Vec3D target;
   Vec3D up;
   Vec3D look;
   Vec3D right;

   float[] l = cam.position();
   float[] t = cam.target();
   float[] u = cam.up();
   
   loc.set(l[0], l[1], l[2]);
   target.set(t[0], t[1], t[2]);
   
   look = loc.sub(target).normalize();
   up.set(u[0], u[1], u[2]);
   right = up.cross(look);
Re: Sprites
Reply #10 - Jun 15th, 2008, 9:38pm
 
EDIT: I apologize. I'm too often eager to jump to answers before i have given the problem my full attention ( let's call it ego creep ). My suggestion below is _strictly_ openGL and consequently an invalid suggestion to the initial question. I will leave it in-tact just for those who are searching the forums...

The fastest way i have found to do billboards in _pure openGL_ is point sprites (if your card works with them). I will be posting a way to do fast 2d text right after i finish this reply using Point sprites. They are _always_ facing the camera. They have absolutely no rotation whatsoever.
Basically a point sprite is a texture across a point so that you only have to specify the center of the sprite instead of 4 for a quad - in other words its pretty efficient but it can be tricky.

Important Note: Point Sprites will only work with Power of Two textures created with GL_TEXTURE_2D. this is because the texture coordinates are automatically generated across a range of 0.0-1.0. Non Power of Two textures use actual pixel distance to specify texture coordinates and so they don't work.

Example Time:

Code:

//enable point sprites
gl.glEnable(GL.GL_POINT_SPRITE);
//set up auto tex coords, point sprites wont work without it
gl.glTexEnvi(GL.GL_POINT_SPRITE, GL.GL_COORD_REPLACE, GL.GL_TRUE);

gl.glBegin(GL.GL_POINTS);
for( int i=0; i< NumberOfSprites; i++){
   gl.glPointSize(Sprite[i].Size);
   //render all your points here
   gl.glVertex3f(  Sprite[i].centerX, Sprite[i].centerY, Sprite[i].Z );
}
gl.glEnd();



Now about the sprite size: You can change the sprite size for each individual sprite or let openGL do it for you. If you want to let openGL do it look into the parameters
Code:

glPointParameterfARB( GL_POINT_FADE_THRESHOLD_SIZE_ARB, ### );
glPointParameterfARB( GL_POINT_SIZE_MIN_ARB, ### );
glPointParameterfARB( GL_POINT_SIZE_MAX_ARB, ### );
glPointParameterfvARB( GL_POINT_DISTANCE_ATTENUATION_ARB,  ###);


Re: Sprites
Reply #11 - Jun 20th, 2008, 6:55pm
 
hey,

I'm new to this board and I have a problem that might apply to this topic - what if I just move the camera eyeX and eyeY. Like in this example:

Code:

import processing.opengl.*;

float camZpos; //Cam Z Position
float camXpos; //Cam X Position
float camYpos; //Cam Y Position
float camZcenter; //Cam Z Center
int camout;


void setup() {
size(400, 400, OPENGL);
smooth();

camZpos = (height/2.0) / tan(PI*60.0 / 360.0); //camZpos default
camXpos = width/2;
camYpos = height/2.0;
camZcenter = 0.0; //CamZcenter default
camout = -150;

}

void draw() {
background(0);

camera(camXpos, camYpos, camZpos, // eyeX, eyeY, eyeZ
width/2.0, height/2.0, camZcenter, // centerX, centerY, centerZ
0.0, 1.0, 0.0); // upX, upY, upZ

pushMatrix();
translate(width/2,80,0);
box(100);
popMatrix();

translate(width/2,height/2,0);
fill(30);
stroke(255);
rect(0,0,100,100);
}

void keyPressed() {
if (key == CODED) {
if (keyCode == DOWN && camYpos<height-camout) {
camYpos = camYpos+10.0;
} else if (keyCode == UP && camYpos>camout) {
camYpos = camYpos-10.0;
} else if (keyCode == LEFT && camXpos>camout) {
camXpos = camXpos-20.0;
} else if (keyCode == RIGHT && camXpos<width-camout) {
camXpos = camXpos+20.0;
}
} else if (key == 32) {
//camZpos = (height/2.0) / tan(PI*60.0 / 360.0); //camZpos default
camXpos = width/2;
camYpos = height/2;
}
}


I wan't the rectangle to always face the camera to use it later for an interface. The question might already be answered, but I wasn't able to apply this to my example.

Re: Sprites
Reply #12 - Feb 2nd, 2009, 4:12am
 
Hello all,
  Hopefully I can reply in this thread and get some eyes!  I am using point sprites after very excitedly finding out about them from this thread and others.  I have run into a bit of a snag.  Looking at ness's example above, it seems that you should be able to change the size of individual sprites within the same gl.glBegin(GL.GL_POINTS) -->  gl.glEnd() sequence.  Unfortunately, I could never get it to work, and ended up calling a new glBegin upon every iteration in my array of points, in order to get them to be different sizes.
  Now, in the hopes of improving real time performance, I'd like to revisit this problem and see if anyone knows what's up.  Firstly, if I could change the point size within the glBegin command, would this improve my performance?  And secondly, if I can do this, what am I doing wrong?
  When I put the gl.glPointSize command within the points iteration, it reduces all of the sprites' size to tiny specks.  Here is the offending code:

Quote:
void renderSprites(){
  gl.glEnable(GL.GL_TEXTURE_2D);
  gl.glBindTexture(GL.GL_TEXTURE_2D,mapPointTexture1.getTextureID());
  gl.glEnable(GL.GL_POINT_SPRITE);
  gl.glTexEnvi(GL.GL_POINT_SPRITE, GL.GL_COORD_REPLACE, GL.GL_TRUE);
  gl.glEnable(GL.GL_POINT_SMOOTH);
  gl.glBegin(GL.GL_POINTS); 

  for(int a = 0; a < numA; a ++){
    for(int b = 0; b < numB;b++){
      gl.glPointSize(grid[a][b][3]);
      gl.glPointParameteri(GL.GL_POINT_SIZE_MAX, 400);
      gl.glVertex3f(grid[a][b][0],grid[a][b][1],grid[a][b][2]);
    }
  }
  gl.glEnd();
  gl.glDisable(GL.GL_POINT_SPRITE);
  gl.glDisable(GL.GL_POINT_SMOOTH);
  gl.glDisable(GL.GL_TEXTURE_2D);
}



and here is what I have had to do to make it work (including colorizing the sprites):

Quote:
  void renderSprites(){
    gl.glEnable(GL.GL_TEXTURE_2D);
    gl.glBindTexture(GL.GL_TEXTURE_2D,mapPointTexture1.getTextureID());
    gl.glEnable(GL.GL_POINT_SPRITE);
    gl.glTexEnvi(GL.GL_POINT_SPRITE, GL.GL_COORD_REPLACE, GL.GL_TRUE);
    gl.glEnable(GL.GL_POINT_SMOOTH);

    for(int a = 0; a < numA; a ++){
      for(int b = 0; b < numB;b++){
        gl.glPointSize(grid[a][b][3]);
        gl.glPointParameteri(GL.GL_POINT_SIZE_MAX, 400);
        gl.glBegin(GL.GL_POINTS); 
        color _col = cm.getColFade1(gCol[0].getColPrime(a,b), gCol[0].getColSecon(a,b),grid[a][b][6]);
        gl.glColor4f(red(_col), green(_col), blue(_col), alpha(_col));
        gl.glVertex3f(grid[a][b][0],grid[a][b][1],grid[a][b][2]);
        gl.glEnd();
      }
    }
    gl.glDisable(GL.GL_POINT_SPRITE);
    gl.glDisable(GL.GL_POINT_SMOOTH);
    gl.glDisable(GL.GL_TEXTURE_2D);
  }



Any help would be greatly appreciated, thank you!
Page Index Toggle Pages: 1