OpenGL Lighting example

Here is an example of how you set up lighting in OpenGL.

There is a main sketch file that sets up the scene lighting using glLightfv and a new version of Shape that sets up a material.

If you want to use lighting with OBJ files, you have to make sure you select the Normals options in the OBJ export dialog in Blender

This is a new version of the main sketch with lighting (the lighting code is in the draw method)

import saito.objloader.*;
 
/* a first person shooter type camera */
 
 
import processing.opengl.*;
import javax.media.opengl.*; 
 
Group graph;
 
// variables for the current position and rotation of the camera
PVector cameraPos, cameraRotation;
 
 
void setup()
{
   size(600, 600, OPENGL); 
 
   cameraPos = new PVector(0, 0);
   cameraRotation = new PVector(0, 0);
 
 
  graph = new Group();
  OBJFile box1 = new OBJFile(this, "sphere.obj");
  //box1.setPosition(new PVector(0, 0, 0));
  //box1.setRotation(new PVector(0, 45, 0));
  //box1.setScale(new PVector(200, 50, 100));
  box1.setDiffuse(1.0f, 1.0f, 0.0f);
  box1.setAmbient(1.0f, 0.0f, 0.0f);
  graph.addShape(box1);
 
  Box box2 = new Box();
  box2.setPosition(new PVector(-300, 0, 0));
  box2.setScale(new PVector(100, 100, 100));
  graph.addShape(box2);
 
}
 
 
// we need to move in the direction that the camera is facing
// tThat means that any camera rotation has to take the current camera rotation into account
// We have to rotate any movement vectors by the current camera rotation
// GL doesn't have a built in method to do this so this is an implementation based on the
// rotation equations
PVector transformDirection(PVector dir)
{
   PVector newDir = new PVector();
   // rotate about y
   newDir.x = dir.x*cos(radians(cameraRotation.y)) - dir.z*sin(radians(cameraRotation.y)); 
   newDir.z = dir.x*sin(radians(cameraRotation.y)) + dir.z*cos(radians(cameraRotation.y)); 
 
   // rotate about x
   newDir.y =  dir.y*cos(radians(cameraRotation.x)) + newDir.z*sin(radians(cameraRotation.x)); 
   newDir.z = -dir.y*sin(radians(cameraRotation.x)) + newDir.z*cos(radians(cameraRotation.x));
 
   return newDir; 
}
 
void draw()
{
   background(255);
   strokeWeight(5);
 
  //directionalLight(255, 255, 255, -1, 0, 0);   
 
  lights();
 
  // camera control
 
  // w/s for in and out
  // a/d for left right strafe
  // q/z for up and down
  // We use the transformDirection method to rotate all movement
  // vectors by the current camera rotation and then add them to 
  // the current camera position
  if (keyPressed)
  {
   if (key == 'w')
     cameraPos.add(transformDirection(new PVector(0.0f, 0.0f, -10.0f)));
   if (key == 's')
     cameraPos.add(transformDirection(new PVector(0.0f, 0.0f,  10.0f)));
   if (key == 'a')
     cameraPos.add(transformDirection(new PVector(-10.0f, 0.0f, 0.0f)));
   if (key == 'd')
     cameraPos.add(transformDirection(new PVector( 10.0f, 0.0f, 0.0f)));
   if (key == 'q')
     cameraPos.add(transformDirection(new PVector(0.0f, -10.0f, 0.0f)));
   if (key == 'z')
     cameraPos.add(transformDirection(new PVector(0.0f,  10.0f, 0.0f)));
  }
 
 
  // rotate the camera based on the mouse
  if (mousePressed)
  {
    cameraRotation.x += -float(mouseY-pmouseY);
    cameraRotation.y += float(mouseX-pmouseX);
  }
 
  PGraphicsOpenGL pgl = (PGraphicsOpenGL) g;  // g may changes
  GL gl = pgl.beginGL();  // always use the GL object returned by beginGL
 
 
  // use smooth shading (phong)
  gl.glShadeModel(GL.GL_SMOOTH);
 
  // glLightModelfv sets general parameters of the lighting setup
 
  // add ambient light
  // ambient light simulates light bouncing of surfaces
  // its everywhere, not coming from a specific light sources
  float ambientlight[] = {0.1f, 0.1f, 0.1f, 1.0f};
  gl.glLightModelfv(gl.GL_LIGHT_MODEL_AMBIENT, ambientlight, 0);
  gl.glLightModelf(gl.GL_LIGHT_MODEL_TWO_SIDE, 0.0f);
 
  // glLightfv set up parameters of individual lights
  // GL has a set of built in lights with identifiers
  // GL_LIGHT0, GL_LIGHT1 etc
  // You pass in the indentifier to say which light you are setting
  // The next argument is which lighting parameter you are setting
  // Then you pass in a float array with the actual values
  // the final parameter is an offset, which will almost always
  // be 0
 
  // set the parameters of LIGHT0
  // position, if the 4th component of the position is 0
  // then the light is directional and the other components
  // are the x, y, z of the direction, not the position
  float light0Pos[] = {-200, -100, 0, 0};
  gl.glLightfv(gl.GL_LIGHT0, gl.GL_POSITION, light0Pos,0);
  // the colour of the diffuse component of the light 
  // in RGB, the last number is alpha (transparency)
  float light0Diffuse[] = {1.0f, 1.0f, 0.0f, 1.0f};
  gl.glLightfv(gl.GL_LIGHT0, gl.GL_DIFFUSE,  light0Diffuse,0);
  // colour of the specular component
  float light0Specular[] = {1.0f, 1.0f, 1.0f, 1.0f};
  gl.glLightfv(gl.GL_LIGHT0, gl.GL_SPECULAR, light0Specular,0);
 
  // set the parameters of LIGHT1
  // position, as the final component is 1, this is 
  // a point light and we are settings its position
  // to 200, -200, 0
  float light1Pos[] = {200, -200, 0, 1};
  gl.glLightfv(gl.GL_LIGHT1, gl.GL_POSITION, light1Pos,0);
  float light1Diffuse[] = {0.0f, 0.0f, 1.0f, 1.0f};
  gl.glLightfv(gl.GL_LIGHT1, gl.GL_DIFFUSE,  light1Diffuse,0);
 
  // glEnable enables various features of 
  // OpenGL
  // here we are using it to set up lighting
 
  // enable lighting
  gl.glEnable(gl.GL_LIGHTING);
 
  // enable the two lights we are using
  gl.glEnable(gl.GL_LIGHT0);
  gl.glEnable(gl.GL_LIGHT1);
 
  // enable the z-buffer
  gl.glEnable(GL.GL_DEPTH_TEST);  
 
 
  // work on the camera transforms
  gl.glMatrixMode(gl.GL_MODELVIEW);
  // set the transform to the identity (do nothing)
  gl.glLoadIdentity();
 
  // use gluLook at to get it looking along z and using y as up
  pgl.glu.gluLookAt(0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
 
  // these are the camera transforms
  // in this order they move they rotate the camera about its position
  gl.glRotatef(cameraRotation.x, 1, 0, 0);
  gl.glRotatef(cameraRotation.y, 0, 1, 0);
  gl.glTranslatef(cameraPos.x, cameraPos.y, cameraPos.z);
 
  graph.update();
 
  graph.draw(gl);
 
 
  pgl.endGL();
}

This is a new version of the Shape object that includes materials (NB, you can also set up the materials for your OBJ files in blender)

 
import processing.opengl.*;
import javax.media.opengl.*; 
 
 
class Shape
{
  PVector position;
  PVector rotation;
 
  // have arrays for your material values
  // the object can have different colours for 
  // ambient, diffuse and specular components
  // they are all RGB colours with an alpha 
  // component
  float ambientColour[] = {0.8f, 0.8f, 0.8f, 1.0f};
  float diffuseColour[] = {0.8f, 0.8f, 0.8f, 1.0f};
  float specularColour[] = {1.0f, 1.0f, 1.0f, 1.0f};
 
  PVector scale;
  Shape()
   {
     position = new PVector(0, 0, 0);
     rotation = new PVector(0, 0, 0);
     scale    = new PVector(1, 1, 1);
     //ambientColour  = {0.8f, 0.8f, 0.8f, 1.0f};
     //diffuseColour  = {0.8f, 0.8f, 0.8f, 1.0f};
     //specularColour = {1.0f, 1.0f, 1.0f, 1.0f};
   }
 
  // set the colour values
  void setAmbient(float r, float g, float b)
  {
     ambientColour[0] = r;
     ambientColour[1] = g;
     ambientColour[2] = b; 
  }
 
  void setDiffuse(float r, float g, float b)
  {
     diffuseColour[0] = r;
     diffuseColour[1] = g;
     diffuseColour[2] = b; 
  }
 
  void setSpecular(float r, float g, float b)
  {
     specularColour[0] = r;
     specularColour[1] = g;
     specularColour[2] = b; 
  }
 
  void setPosition(PVector p)
  {
    position.x = p.x;
    position.y = p.y;
    position.z = p.z;
  }
 
  void setRotation(PVector p)
  {
    rotation.x = p.x;
    rotation.y = p.y;
    rotation.z = p.z;
  }
 
  void setScale(PVector p)
  {
    scale.x = p.x;
    scale.y = p.y;
    scale.z = p.z;
  }
 
  void update()
  {
 
  }
 
  void drawShape(GL gl)
  {
 
  }
 
  void draw(GL gl)
  {
    gl.glColor3f(1.0f, 1.0f, 1.0f);
 
    // glMaterialfv sets the material parameters
    // It works a bit like glLightfv
    // GL_FRONT is the front of the polygon 
    // (you will almost always use GL_FRONT)
    // the second argument is the parameter you 
    // want to set (the component)
    // then you pass a float array of the values
    // the final parameter is an offset which is
    // almost always 0
    gl.glMaterialfv(gl.GL_FRONT, gl.GL_AMBIENT, ambientColour,0);
    gl.glMaterialfv(gl.GL_FRONT, gl.GL_DIFFUSE, diffuseColour,0);
    gl.glMaterialfv(gl.GL_FRONT, gl.GL_SPECULAR, specularColour,0);
 
    gl.glPushMatrix();
    gl.glTranslatef(position.x, position.y, position.z);
    gl.glRotatef(rotation.x, 1.0f, 0.0f, 0.0f);
    gl.glRotatef(rotation.y, 0.0f, 1.0f, 0.0f);
    gl.glRotatef(rotation.z, 0.0f, 0.0f, 1.0f);
    gl.glScalef(scale.x, scale.y, scale.z);
    drawShape(gl);
    gl.glPopMatrix();
 
  }
}
PDF    Send article as PDF to