A134214
13 Oktober 2011 telah menyertai
- include <stdlib.h>
- include <stdio.h>
- include <math.h>
- include <GL/glut.h>
- 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];
- 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 ();
}