I wrote the
Part 4 of the OpenGL ES From the Ground Up series using plain arrays of
GLfloats. That is the most common way of doing it that you will see out in the wild as it's the most portable, since it doesn't use any data structures not defined within OpenGL itself.
I took the opportunity to rewrite the
setupView: method to use the
Vertex3D,
Vector3D, and
Color3D structs we defined back in
Part 1. Neither approach is "better", but I thought it might be interesting to see it done a little different way. When I was first learning OpenGL, I found it easier to think in terms of Vertices, Colors, and Triangles, rather than all the various-length arrays of floats. If you're like I was, then you may find this version easier to read and understand.
In addition to use our custom data structures, I also reduced the amount of the ambient light component and moved the light over to the right. I then used the
Vector3DMakeWithStartAndEndPoints() to point the moved light at the icosahedron. By moving the light over and having it strike the object at an angle, the effect is a little more dramatic.
-(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);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
static const Color3D light0Ambient[] = {{0.05, 0.05, 0.05, 1.0}};
glLightfv(GL_LIGHT0, GL_AMBIENT, (const GLfloat *)light0Ambient);
static const Color3D light0Diffuse[] = {{0.4, 0.4, 0.4, 1.0}};
glLightfv(GL_LIGHT0, GL_DIFFUSE, (const GLfloat *)light0Diffuse);
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);
static const Vertex3D light0Position[] = {{10.0, 10.0, 10.0}};
glLightfv(GL_LIGHT0, GL_POSITION, (const GLfloat *)light0Position);
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);
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 25.0);
glLoadIdentity();
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}
You should feel free to play with the light attributes, add additional lights or icosahedrons, and generally just play around to get a feel for how changes will effect your scene. This stuff is conceptually hard to grok, so don't expect it to come overnight (and if it does, count yourself lucky).
No comments:
Post a Comment