1. include <stdlib.h>
  2. include <stdio.h>
  3. include <math.h>
  4. include <GL/glut.h>
  5. include <GL/glu.h>


GLUquadric *quadSphere, *quadCyl; int windowWidth;

// Putar scene pada axis y GLfloat yrot;

// Lokasi target dan objek camera float target[3], camera[3];


  1. define DELTA 0.25f

static void key (unsigned char k, int x, int y) {

   switch (k) {
   case 'q': target[0] -= DELTA; break;
   case 'Q': target[0] += DELTA; break;
   case 'w': target[1] -= DELTA; break;
   case 'W': target[1] += DELTA; break;
   case 'e': target[2] -= DELTA; break;
   case 'E': target[2] += DELTA; break;
   case 'a': camera[0] -= DELTA; break;
   case 'A': camera[0] += DELTA; break;
   case 's': camera[1] -= DELTA; break;
   case 'S': camera[1] += DELTA; break;
   case 'd': camera[2] -= DELTA; break;
   case 'D': camera[2] += DELTA; break;
       break;
   default:
       exit(0);
   }
   glutPostRedisplay ();

}


// Kira hasil pendaraban dan kembali kepada nilai tersebut static void cross (float dst[3], float srcA[3], float srcB[3]) {

   dst[0] = srcA[1]*srcB[2] - srcA[2]*srcB[1];
   dst[1] = srcA[2]*srcB[0] - srcA[0]*srcB[2];
   dst[2] = srcA[0]*srcB[1] - srcA[1]*srcB[0];

}

// Menormalkan vektor input static void normalize (float vec[3]) {

   const float squaredLen = vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2];
   const float invLen = 1.f / (float) sqrt (squaredLen);
   vec[0] *= invLen;
   vec[1] *= invLen;
   vec[2] *= invLen;

}

// Skala vektor yang diberikan static void scale (float v[3], float s) {

   v[0] *= s;
   v[1] *= s;
   v[2] *= s;

}

/*

   multLookAt -- Buat matriks untuk membuat objek, seperti
       kamera, "look at" objek atau lokasi lain, dari
       kedudukan yang dinyatakan.
   Parameters:
       eye[x|y|z] Lokasi yang dikehendaki objek kamera
       at[x|y|z]  Lokasi untuk kamera melihat
       up[x|y|z]  Vektor Up kamera
  algoritma:
       Oleh itu, transformasi yang diingini diperoleh dengan matriks 4x4 ini:
           | [Xaxis] 0 |
           | [up] 0 |
           | [-at] 0 |
           | [eye] 1 |
       Jika 'xaxis', 'up' dan 'at' adalah X, Y, dan Z paksi
       objek transformasi baru,'eye' input
       lokasi baru objek berubah.
       
   andaian:
       Geometri kamera ditakrifkan menghadapi
       Z paksi yang negatif.
   penggunaan:
       multLookAt mewujudkan matriks dan membiak ke
       matriks tindanan semasa. Kegunaan yang khas adalah seperti berikut:
           glMatrixMode (GL_MODELVIEW);
           / / Tentukan transformasi pandangan biasa di sini menggunakan
           / / GluLookAt atau apa sahaja.
           glPushMatrix ();
           multLookAt (orig [0], orig [1], orig [2],
               at [0], at [1], at [2],
               up [0], up [1], up [2]);
           / / Tentukan "kamera" objek geometri di sini
           glPopMatrix ();
   Amaran: Keputusan menjadi undefined sebagai pendekatan kebetulan (at-eye)
           dengan (up).
  • /

static void multLookAt (float eyex, float eyey, float eyez,

                       float atx, float aty, float atz,
                       float upx, float upy, float upz)

{

   float m[16];
   float *xaxis = &m[0],
       *up = &m[4],
       *at = &m[8];
   // Pengiraan vektor baru yang akan
   // menjadi negatif paksi Z objek yang berubah.
   at[0] = atx-eyex; at[1] = aty-eyey; at[2] = atz-eyez;
   normalize (at);
   // Membuat salinan boleh guna vektor up semasa.
   up[0] = upx; up[1] = upy; up[2] = upz;
   / / Hasil produk baru pada vektor dan semasa
   / / Up vektor akan menghasilkan vektor yang baru
   / / X positif paksi objek transformasi.
   cross (xaxis, at, up);
   normalize (xaxis);
   / / Vektor yang baru akan dikira, dimana akan menjadi
   / / Y paksi positif objek transformasi. Nota:
   / / Akan berada di satah yang sama seperti vektor baru dan vektor lama
   cross(up, xaxis, at);
   / / Geometri akan ditakrifkan sebagai
   / / titik di sepanjang paksi-Z negatif.
   scale (at, -1.f);
   //Isi lain ke matriks 4x4
   m[3] = 0.f;     // xaxis is m[0..2]
   m[7] = 0.f;     // up is m[4..6]
   m[11] = 0.f;    // -at is m[8..10]
   m[12] = eyex; m[13] = eyey; m[14] = eyez;
   m[15] = 1.f;
   // Darab ke dalam tindanan matriks semasa. (current matrix stack)
   glMultMatrixf (m);

}


static void display( void ) {

   glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity ();
  / / View tranformasi, 'eye' tempat di (0,1,5), dan membenarkan scene
   / / untuk berputar di sekeliling paksi Y di hadapan mata.
   glTranslatef (0., -1., -5.);
   glRotatef (yrot, 0., 1., 0.);
   // Melukis target
   glColor3f (.7, .4, 1.);
   glPushMatrix ();
   glTranslatef (target[0], target[1], target[2]);
   gluSphere (quadSphere, .5, 24, 12);
   glPopMatrix ();
   glPushMatrix ();
   / / Membuat transformasi supaya geometri akan
   / / "look at" sasaran.
   multLookAt (camera[0], camera[1], camera[2],
               target[0], target[1], target[2],
               0., 1., 0.);
   / / Melukis "camera" yang hanya kon oren
   / / Menghala ke arah satu sasaran dan kon putih menunjukkan
   / / tempatan arah kamera "up".
   glRotatef (-90., 1., 0., 0.);
   glColor3f (1., 1., 1.);
   gluCylinder (quadCyl, .15, 0., .5, 8, 2);
   glRotatef (-90., 1., 0., 0.);
   glColor3f (1., .6, .4);
   gluCylinder (quadCyl, .25, 0., 1., 8, 2);
   glPopMatrix ();
   glutSwapBuffers();

}

void reshape(int w, int h) {

   windowWidth=w;
   glViewport (0, 0, w, h);       
   glMatrixMode (GL_PROJECTION);  
   glLoadIdentity ();
   gluPerspective (50., (float)w/(float)h, 1., 20.);

}

static void mouse (int x, int y) {

   yrot = (float)x*360.f/(float)windowWidth - 180.f;
   glutPostRedisplay ();

}

static void init () {

   target[0] = target[1] = target[2] = 1.25f;
   camera[0] = camera[1] = camera[2] = 0.f;
   yrot = 0.f;
   glEnable (GL_DEPTH_TEST);
   {
       GLfloat pos[4] = {3., 5., 2., 1.};
       GLfloat white[4] = {1., 1., 1., 1.};
       GLfloat black[4] = {0., 0., 0., 0.};
       /* Penyediaan light1 */
       glEnable (GL_LIGHTING);
       glEnable (GL_LIGHT1);
       glLightfv (GL_LIGHT1, GL_POSITION, pos);
       glLightfv (GL_LIGHT1, GL_DIFFUSE, white);
       glLightfv (GL_LIGHT1, GL_SPECULAR, black);
       /* ambien dan sebaran akan menjejaki glColor */
       glEnable (GL_COLOR_MATERIAL);
       glColorMaterial (GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
       glMaterialfv (GL_FRONT, GL_SPECULAR, black);
   }
   quadSphere = gluNewQuadric ();
   quadCyl = gluNewQuadric ();
   glutDisplayFunc (display); 
   glutReshapeFunc (reshape);
   glutMotionFunc (mouse);
   glutKeyboardFunc (key);

}

void main(int argc, char** argv) {

   glutInit (&argc,argv);
   glutInitDisplayMode (GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); 
   glutInitWindowSize (windowWidth=300,300);
   glutInitWindowPosition (0,0); 
   glutCreateWindow ("Looking at an object");
   init ();
   printf ("Left mouse button rotates the scene.\n");
   printf ("Move the target object:\n");
   printf ("\tq/Q\talong the X axis;\n");
   printf ("\tw/W\talong the Y axis;\n");
   printf ("\te/E\talong the Z axis.\n");
   printf ("Move the camera object:\n");
   printf ("\ta/A\talong the X axis;\n");
   printf ("\ts/S\talong the Y axis;\n");
   printf ("\td/D\talong the Z axis.\n");
   printf ("Any other key exits.\n");
   glutMainLoop ();

}