279 282














Open GL Super Bible:Lighting and Lamps















To access the contents, click the chapter and section titles.


Open GL Super Bible


(Publisher: Macmillan Computer Publishing)

Author(s): Waite group Press

ISBN: 1571690735

Publication Date: 08/01/96

 




Previous
Table of Contents
Next




Finding a Normal
Figure 9-13 presents another polygon that is not simply lying in one of the axis planes. The normal vector pointing away from this surface is more difficult to guess, so we need an easy way to calculate the normal for any arbitrary polygon in 3D coordinates.


Figure 9-13  A nontrivial normal problem
You can easily calculate the normal vector for any polygon consisting of at least three points that lie in a single plane (a flat polygon). Figure 9-14 shows three points, P1, P2, and P3, that you can use to define two vectors: vector V1 from P1 to P2, and vector V2 from P1 to P2. Mathematically, two vectors in three-dimensional space define a plane (your original polygon lies in this plane). If you take the cross product of those two vectors (written mathematically as V1 X V2, the resulting vector is perpendicular to that plane (or normal). Figure 9-15 shows the vector V3 derived by taking the cross product of V1 and V2.


Figure 9-14  Two vectors defined by three points on a plane

Figure 9-15  A normal vector as cross product of two vectors
Donłt worry if you donłt know how to take the cross product of two vectors; all you need is the function in Listing 9-3. To use this function, pass it an array containing any three vertices from your polygon (specify in counterclockwise winding order), and an array that will contain the normal vector on return. The constant values x, y, and z are provided for your benefit if you want to see how the function works.

Listing 9-3 Function to calculate a normal vector with any three vertices from a polygon

// Points p1, p2, & p3 specified in counterclockwise order
void calcNormal(float v[3][3], float out[3])
{
float v1[3],v2[3];
static const int x = 0;
static const int y = 1;
static const int z = 2;

// Calculate two vectors from the three points
v1[x] = v[0][x] - v[1][x];
v1[y] = v[0][y] - v[1][y];
v1[z] = v[0][z] - v[1][z];

v2[x] = v[1][x] - v[2][x];
v2[y] = v[1][y] - v[2][y];
v2[z] = v[1][z] - v[2][z];

// Take the cross product of the two vectors to get
// the normal vector which will be stored in out[]
out[x] = v1[y]*v2[z] - v1[z]*v2[y];
out[y] = v1[z]*v2[x] - v1[x]*v2[z];
out[z] = v1[x]*v2[y] - v1[y]*v2[x];

// Normalize the vector (shorten length to one)
ReduceToUnit(out);
}

Setting Up a Source
Now that you understand the requirements of setting up your polygons to receive and interact with a light source, itłs time to turn on the lights! Listing 9-4 shows the SetupRC() function from the example program LITJET. Part of the setup process for this sample program creates a light source and places it to the upper-left, slightly behind the viewer. The light source GL_LIGHT0 has its ambient and diffuse components set to the intensities specified by the arrays ambientLight[], and diffuseLight[].This results in a moderate white light source.


GLfloat ambientLight[] = { 0.3f, 0.3f, 0.3f, 1.0f };
GLfloat diffuseLight[] = { 0.7f, 0.7f, 0.7f, 1.0f };


// Setup and enable light 0
glLightfv(GL_LIGHT0,GL_AMBIENT,ambientLight);
glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight);

The light is positioned by this code:


GLfloat lightPos[] = { -50.f, 50.0f, 100.0f, 1.0f };


glLightfv(GL_LIGHT0,GL_POSITION,lightPos);

Here lightPos[] contains the position of the light. The last value in this array is 1.0, which specifies that the designated coordinates are the position of the light source. If the last value in the array is 0.0, it indicates that the light is an infinite distance away along the vector specified by this array. Wełll touch more on this later.

Finally, the light source GL_LIGHT0 is enabled:

glEnable(GL_LIGHT0);

Listing 9-4 Light and rendering context setup for LITJET

// This function does any needed initialization on the rendering
// context. Here it sets up and initializes the lighting for
// the scene.
void SetupRC()
{
// Light values and coordinates
GLfloat ambientLight[] = { 0.3f, 0.3f, 0.3f, 1.0f };
GLfloat diffuseLight[] = { 0.7f, 0.7f, 0.7f, 1.0f };
Glfloat lightPos[] = { -50.f, 50.0f, 100.0f, 1.0f };

glEnable(GL_DEPTH_TEST); // Hidden surface removal
glFrontFace(GL_CCW); // Counter clock-wise polygons face out
glEnable(GL_CULL_FACE); // Do not calculate inside of jet

// Enable lighting
glEnable(GL_LIGHTING);

// Setup and enable light 0
glLightfv(GL_LIGHT0,GL_AMBIENT,ambientLight);
glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight);
glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
glEnable(GL_LIGHT0);

// Enable color tracking
glEnable(GL_COLOR_MATERIAL);

// Set Material properties to follow glColor values
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);

// Light blue background
glClearColor(0.0f, 0.0f, 1.0f, 1.0f );
}

Setting the Material Properties
Notice in Listing 9-4 that color tracking is enabled, and the properties to be tracked are the ambient and diffuse reflective properties for the front surface of the polygons. This is just as it was defined in the AMBIENT sample program:


// Enable color tracking
glEnable(GL_COLOR_MATERIAL);

// Set Material properties to follow glColor values
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);





Previous
Table of Contents
Next














 


Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.












Wyszukiwarka

Podobne podstrony:
279 282
rozdzial (279)
282 01
III CSK 282 11 1
278 279
279 281 ryvlygit7x6kx4rpzyopztpswwn4bk6rqqmnn7i
Nuestro Circulo 282 Nogues Acuna
282 283
07 (279)
282 Married With Children
282 283
282 04
282 08
rozdzial (279)
276 279

więcej podobnych podstron