Cocoa Programming for Mac OS X - Aaron Hillegass [134]
GLfloat ambient[] = {0.2, 0.2, 0.2, 1.0};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
// Initialize the light
GLfloat diffuse[] = {1.0, 1.0, 1.0, 1.0};
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
// and switch it on.
glEnable(GL_LIGHT0);
// Set the properties of the material under ambient light
GLfloat mat[] = {0.1, 0.1, 0.7, 1.0};
glMaterialfv(GL_FRONT, GL_AMBIENT, mat);
// Set the properties of the material under diffuse light
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat);
}
- (id)initWithCoder:(NSCoder *)c
{
self = [super initWithCoder:c];
if (self) {
[self prepare];
}
return self;
}
// Called when the view resizes
- (void)reshape
{
NSLog(@"reshaping");
// Convert up to window space, which is in pixel units.
NSRect baseRect = [self convertRectToBase:[self bounds]];
// Now the result is glViewport()-compatible.
glViewport(0, 0, baseRect.size.width, baseRect.size.height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, baseRect.size.width/baseRect.size.height,
0.2, 7);
}
- (void)awakeFromNib
{
[self changeParameter:self];
}
- (IBAction)changeParameter:(id)sender
{
lightX = [[sliderMatrix cellWithTag:LIGHT_X_TAG] floatValue];
theta = [[sliderMatrix cellWithTag:THETA_TAG] floatValue];
radius = [[sliderMatrix cellWithTag:RADIUS_TAG] floatValue];
[self setNeedsDisplay:YES];
}
- (void)drawRect:(NSRect)r
{
// Clear the background
glClearColor (0.2, 0.4, 0.1, 0.0);
glClear(GL_COLOR_BUFFER_BIT |
GL_DEPTH_BUFFER_BIT);
// Set the view point
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(radius * sin(theta), 0, radius * cos(theta),
0, 0, 0,
0, 1, 0);
// Put the light in place
GLfloat lightPosition[] = {lightX, 1, 3, 0.0};
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
if (!displayList)
{
displayList = glGenLists(1);
glNewList(displayList, GL_COMPILE_AND_EXECUTE);
// Draw the stuff
glTranslatef(0, 0, 0);
glutSolidTorus(0.3, 0.9, 35, 31);
glTranslatef(0, 0, -1.2);
glutSolidCone(1, 1, 17, 17);
glTranslatef(0, 0, 0.6);
glutSolidTorus(0.3, 1.8, 35, 31);
glEndList();
} else {
glCallList(displayList);
}
// Flush to screen
glFinish();
}
@end
Note that the OpenGL calls are broken into three parts: prepare, all the calls to be sent initially; reshape, all the calls to be sent when the view resizes; and drawRect, all the calls to be sent each time the view needs to be redrawn. Build and run the app.
Chapter 36. NSTask
Each application that you have created is a directory, and somewhere down in that directory is an executable file. To run an executable on a Unix machine, like your Mac, a process is forked, and the new process executes the code in that file. Many executables are command-line tools, and some are quite handy. This chapter, then, will be showing you how to run command-line tools from your Cocoa application by using the class NSTask.
NSTask is an easy-to-use wrapper for the Unix functions fork() and exec(). You give NSTask a path to an executable and launch it. Many processes read data from standard-in and write to standard-out and standard-error. Your application can use NSTask to attach pipes to carry data to and from the external process. Pipes are represented by the class NSPipe.
ZIPspector
The tool /usr/bin/zipinfo looks at the contents of a zip file. Find a zip file on your machine and try running zipinfo in the Terminal like this (1 is dash-one, not dash-el):
# /usr/bin/zipinfo -1 /Users/aaron/myfile.zip
greatfile.txt
swellfile.rtf
magnificent.pdf
You are going to create an application that uses zipinfo. Note that it will have to send some arguments and read from the process’s standard-out (Figure 36.1).
Figure 36.1. Completed Application
In Xcode, create a new Cocoa Application named ZIPspector, and enable Create Document-Based Application. Set the Class Prefix to My. This program will only view zip files, not edit them. In the Info panel for the target, set ZIPspector to be a viewer for files with the UTI com.pkware.zip-archive