Code: Select all
/******************************************************************************
*******************************************************************************
OpenGL BillBpoard Example
Relminator (Richard Eric M. Lope)
Http://Rel.Phatcode.Net
Billboards are quads that are always Parallel to the screen.
They always face the screen no matter how you transform your
3D scene.
Notice that the quads always face the screen even when the 3D scene
rotates on all the axes.
They are mainly used for HUDS, Particle effects, Trees, Sprites, etc.
I made this out of necessity for a 2.5D game I'm working on and thought
I might share it.
Since the DS modelview matrix is a combo of Direction and Position,
we only need the direction vectors to use billboards. Apparently,
the Directional matrix is just a 3x3 matrix as oppposed to the
Position matrix which is 4x4.
*******************************************************************************
******************************************************************************/
#include <nds.h>
#include <stdio.h>
#include <math.h>
// Just a vector3D class
class Vector3Df32
{
public:
s32 x, y,z;
};
// Sets up some GL stuff
void InitGL()
{
// initialize gl
glInit();
//enable textures
glEnable( GL_TEXTURE_2D );
// enable antialiasing
glEnable( GL_ANTIALIAS );
// setup the rear plane
glClearColor( 0, 0, 0, 31 ); // BG must be opaque for AA to work
glClearPolyID( 63 ); // BG must have a unique polygon ID for AA to work
glClearDepth( GL_MAX_DEPTH );
//this should work the same as the normal gl call
glViewport(0,0,255,191);
//any floating point gl call is being converted to fixed prior to being implemented
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 70, 256.0 / 192.0, 1, 200 );
//not a real gl function and will likely change
glPolyFmt( POLY_ALPHA(31) | POLY_CULL_BACK );
}
int main()
{
//set mode 5, enable BG0 and set it to 3D
videoSetMode( MODE_5_3D );
consoleDemoInit();
// initialize gl
InitGL();
// Print some console stuff
iprintf("\x1b[1;1HBillboarding Example");
iprintf("\x1b[3;1HRelminator");
iprintf("\x1b[5;1HHttp://Rel.Phatcode.Net");
// Parameters for our PQ torus
s32 p = 0;
s32 q = 100;
// Billboad variables
Vector3Df32 P0, P1, P2, P3; // Quad Coordinates needed to draw our billboards
Vector3Df32 vUp, vRight; // Orthogonal vectors for our directional matrix transforms
s32 Matrix[9]; // Our 3x3 matrix to hold current diection
// Size of each billboard
v16 Size = floattov16(0.1);
int Frame = 0; // just the standard frame counter
// Right-handed system looks into -z
gluLookAt( 0.0, 0.0, 1.0, //camera position
0.0, 0.0, 0.0, //look at
0.0, 1.0, 0.0 ); //up
while( 1 )
{
Frame++;
// Animate PQ torus
p++;
q++;
// We are drawing simple gouraud shaded billboards
// so we disable texturing
glDisable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, 0 );
// So we don't mess with the above LookAt() transform
glPushMatrix();
// Reset current matrix
glLoadIdentity();
// Right-Handed so we translate negatively
glTranslate3f32( 0, 0, floattof32(-5) );
// Rotate our models on all axes
glRotateXi( Frame * 20);
glRotateYi( Frame * 40 );
glRotateZi( Frame * 80 );
// Get Matrix needed for billboards
// Set current matrix to modelview
glMatrixMode( GL_MODELVIEW );
glGetFixed ( GL_GET_MATRIX_VECTOR, Matrix ); // Get current directional matrix
// Copy orthogonal vectors
vRight.x = Matrix[0]; // X Axis
vRight.y = Matrix[3];
vRight.z = Matrix[6];
vUp.x = Matrix[1]; // Y Axis
vUp.y = Matrix[4];
vUp.z = Matrix[7];
// Get quad points( f32 ) relative to (0,0,0)
P0.x = ( (-vRight.x - vUp.x) * Size ) >> 12;
P0.y = ( (-vRight.y - vUp.y) * Size ) >> 12;
P0.z = ( (-vRight.z - vUp.z) * Size ) >> 12;
P1.x = ( ( vRight.x - vUp.x) * Size ) >> 12;
P1.y = ( ( vRight.y - vUp.y) * Size ) >> 12;
P1.z = ( ( vRight.z - vUp.z) * Size ) >> 12;
P2.x = ( ( vRight.x + vUp.x) * Size ) >> 12;
P2.y = ( ( vRight.y + vUp.y) * Size ) >> 12;
P2.z = ( ( vRight.z + vUp.z) * Size ) >> 12;
P3.x = ( (-vRight.x + vUp.x) * Size ) >> 12;
P3.y = ( (-vRight.y + vUp.y) * Size ) >> 12;
P3.z = ( (-vRight.z + vUp.z) * Size ) >> 12;
// Draw 360 Billboarded Quads
for( int i = 0; i < 360; i++)
{
// Fun with the PQ torus
s32 r = ((5 + (sinLerp(q * i)))) * 4;
s32 x = r * cosLerp(p * i);
s32 y = r * cosLerp(q * i);
s32 z = r * sinLerp(p * i);
// Draw the billboards
glPushMatrix();
glTranslate3f32( x >> 12, y >> 12, z >> 12 ); // Move relative to( 0,0,-5)
glBegin( GL_QUADS );
glColor(RGB15(31, i & 31, i & 31)); // Play with colors
glVertex3v16( P0.x, P0.y, P0.z ); // 1st coord
glColor(RGB15(i & 31, 31, i & 31));
glVertex3v16( P1.x, P1.y, P1.z );
glColor(RGB15(i & 31, i & 31, 31));
glVertex3v16( P2.x, P2.y, P2.z );
glColor(RGB15(31 - i, 31- i, 31 - i));
glVertex3v16( P3.x, P3.y, P3.z );
glEnd();
glPopMatrix( 1 );
}
glPopMatrix( 1 );
glFlush( 0 );
swiWaitForVBlank();
}
return 0;
}//end main
Feel free to add this in the 3D examples.
Here's the binary for the lazy:
http://rel.phatcode.net/junk.php?id=124