我在從零開始學習OpenGL ES之四 – 光效 一文中使用了一個普通GLfloat數組。由於它沒有使用任何非OpenGL定義的數據結構,所以是最爲普通和方便的方式。
但在此我使用在第一部分中定義的Vertex3D, Vector3D和 Color3D數據結構重寫了 setupView:方法。並不是這種方法“更好”,但是它是一種不同的方式。當我第一次學習OpenGL時,我發現使用頂點,顏色和三角形的術語比可變長度浮點數組更容易理解。如果你和我一樣,那麼你會發現這個版本更容易理解。
除了使用自定義數據結構外,我還減少了環境光元素的數量並將光源向右移動了一點。然後使用Vector3DMakeWithStartAndEndPoints()將移動的光源指向二十面體。這樣做使得光效更爲生動一點。
-(void)setupView:(GLView*)view
{
const GLfloat zNear = 0.01, zFar = 1000.0, fieldOfView = 45.0;
GLfloat size;
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
size = zNear * tanf(DEGREES_TO_RADIANS(fieldOfView) / 2.0);
CGRect rect = view.bounds;
glFrustumf(-size, size, -size / (rect.size.width / rect.size.height), size /
(rect.size.width / rect.size.height), zNear, zFar);
glViewport(0, 0, rect.size.width, rect.size.height);
glMatrixMode(GL_MODELVIEW);
// Enable lighting
glEnable(GL_LIGHTING);
// Turn the first light on
glEnable(GL_LIGHT0);
// Define the ambient component of the first light
static const Color3D light0Ambient[] = {{0.05, 0.05, 0.05, 1.0}};
glLightfv(GL_LIGHT0, GL_AMBIENT, (const GLfloat *)light0Ambient);
// Define the diffuse component of the first light
static const Color3D light0Diffuse[] = {{0.4, 0.4, 0.4, 1.0}};
glLightfv(GL_LIGHT0, GL_DIFFUSE, (const GLfloat *)light0Diffuse);
// Define the specular component and shininess of the first light
static const Color3D light0Specular[] = {{0.7, 0.7, 0.7, 1.0}};
glLightfv(GL_LIGHT0, GL_SPECULAR, (const GLfloat *)light0Specular);
glLightf(GL_LIGHT0, GL_SHININESS, 0.4);
// Define the position of the first light
// const GLfloat light0Position[] = {10.0, 10.0, 10.0};
static const Vertex3D light0Position[] = {{10.0, 10.0, 10.0}};
glLightfv(GL_LIGHT0, GL_POSITION, (const GLfloat *)light0Position);
// Calculate light vector so it points at the object
static const Vertex3D objectPoint[] = {{0.0, 0.0, -3.0}};
const Vertex3D lightVector = Vector3DMakeWithStartAndEndPoints(light0Position[0], objectPoint[0]);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, (GLfloat *)&lightVector);
// Define a cutoff angle. This defines a 50° field of vision, since the cutoff
// is number of degrees to each side of an imaginary line drawn from the light's
// position along the vector supplied in GL_SPOT_DIRECTION above
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 25.0);
glLoadIdentity();
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}
你可以隨意調整光的屬性,增加額外的光源或二十面體,體驗一下這些調整會爲場景帶來什麼樣的變化。這些東西是很難體驗出來的,所以不要指望一晚上就理解了所有東西。
原文見:setupView: from Part IV Rewritten