Smooth vertexnormals quick and dirty:
For round geometry you will need smoothed vertexnormals for a nice lightning. Instead of calculating all normals before rendering in a complicated way the vertexnormals could be taken from each vertexpoint if the geometry is build around [ 0, 0, 0 ]. Each vertexpoint is a vector from center that only has to be normalized.
Quick but dirty is this way not the mathematical exactly way, but for most cases it should be okay.
Quote:
import processing.opengl.*;
import javax.media.opengl.*;
import java.nio.*;
GL gl;
int Nu = 50; int Nv = 50; // MESH RESOLUTION X/Y
float uMin = -1; float uMax = 1; float vMin = -1; float vMax = 1;
float Du = ( uMax - uMin ) / Nu; float Dv = ( vMax - vMin ) / Nv;
float Mesh[][][] = new float[ Nu ][ Nv ][ 3 ];
float rot = 0.0;
void setup()
{
size( 800, 600, OPENGL );
noCursor();
InitGL();
InitLight();
InitParam();
}
void InitGL()
{
gl = (( PGraphicsOpenGL )g).gl;
gl.glShadeModel( GL.GL_SMOOTH );
gl.glClearColor( 0.0, 0.0, 0.0, 1.0 );
gl.glHint( GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST );
perspective( PI/3.0, float(width)/float(height), 0.1, -20000.0 );
}
void InitLight()
{
float[] lightDiffuse = { 0.7, 0.7, 0.4, 1.0 };
float[] lightAmbient = { 0.25, 0.1, 0.0, 1.0 };
float[] lightPosition = { 0.0, 5.0, 8.0, 0.0 };
gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, FloatBuffer.wrap( lightDiffuse ));
gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, FloatBuffer.wrap( lightAmbient ));
gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, FloatBuffer.wrap( lightPosition ));
}
void InitParam() // MESH DEFORMATION
{
float x, y, z, u, v;
for( int i=0; i<Nu; i++ ) {
for( int j=0; j<Nv; j++ ) {
u = uMin + i * Du; v = vMin + j * Dv;
x = u;
y = u * u * u - 2 * u * v * v;
z = v;
Mesh[ i ][ j ][ 0 ] = x; // MESH_X
Mesh[ i ][ j ][ 1 ] = y + 0.1; // MESH_Y
Mesh[ i ][ j ][ 2 ] = z; // MESH_Z
}
}
}
void draw()
{
gl.glClear( GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT );
gl.glLoadIdentity();
gl.glEnable( GL.GL_LIGHTING );
gl.glEnable( GL.GL_LIGHT0 );
gl.glTranslatef( 0.0, 0.0, -3.5 );
gl.glRotatef( rot, 1.0, 1.0, 1.0 );
for ( int x=0; x < Nu-1; x++) {
for ( int y=0; y < Nv-1; y++)
{
gl.glBegin( GL.GL_QUADS );
SetNormal( Mesh[x][y][0], Mesh[x][y][1], Mesh[x][y][2] );
gl.glVertex3d( Mesh[x][y][0], Mesh[x][y][1], Mesh[x][y][2] );
SetNormal( Mesh[x+1][y][0], Mesh[x+1][y][1], Mesh[x+1][y][2] );
gl.glVertex3d( Mesh[x+1][y][0], Mesh[x+1][y][1], Mesh[x+1][y][2] );
SetNormal( Mesh[x+1][y+1][0], Mesh[x+1][y+1][1], Mesh[x+1][y+1][2] );
gl.glVertex3d( Mesh[x+1][y+1][0], Mesh[x+1][y+1][1], Mesh[x+1][y+1][2] );
SetNormal( Mesh[x][y+1][0], Mesh[x][y+1][1], Mesh[x][y+1][2] );
gl.glVertex3d( Mesh[x][y+1][0], Mesh[x][y+1][1], Mesh[x][y+1][2] );
gl.glEnd();
}
}
rot += 0.5;
}
void SetNormal( float x, float y, float z ) // INPUT : VERTEX X/Y/Z
{
float Length = sqrt( x * x + y * y + z * z ); // VECTOR LENGTH
float vertex_N_x = x / Length; // NORMALIZE IT
float vertex_N_y = y / Length;
float vertex_N_z = z / Length;
gl.glNormal3d( vertex_N_x, vertex_N_y, vertex_N_z ); // SET VERTEX NORMAL
}