Subversion Repositories gelsvn

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
649 janba 1
#import "BasicOpenGLView.h"
2
#include <GLGraphics/MeshEditor.h>
3
 
4
using namespace CGLA;
5
using namespace GLGraphics;
6
 
7
MeshEditor me;
8
 
9
// ==================================
10
#pragma mark ---- Error Reporting ----
11
 
12
// error reporting as both window message and debugger string
13
void reportError (char * strError, int where)
14
{
15
    NSMutableDictionary *attribs = [NSMutableDictionary dictionary];
16
    [attribs setObject: [NSFont fontWithName: @"Monaco" size: 9.0f] forKey: NSFontAttributeName];
17
    [attribs setObject: [NSColor whiteColor] forKey: NSForegroundColorAttributeName];
18
 
19
    //	gErrorTime = getElapsedTime ();
20
	NSString * errString = [NSString stringWithFormat:@"Error: %s @ line %d", strError, where ];
21
	NSLog (@"%@\n", errString);
22
}
23
 
24
// ---------------------------------
25
 
26
// if error dump gl errors to debugger string, return error
27
GLenum glReportError (int where = -1)
28
{
29
	GLenum err = glGetError();
30
	if (GL_NO_ERROR != err)
31
		reportError ((char *) gluErrorString (err), where);
32
	return err;
33
}
34
 
35
#pragma mark ---- OpenGL Utils ----
36
 
37
// ---------------------------------
38
 
39
 
40
// ===================================
41
 
42
@implementation BasicOpenGLView
43
 
44
// ---------------------------------
45
 
46
// handles resizing of GL need context update and if the window dimensions change, a
47
// a window dimension update, reseting of viewport and an update of the projection matrix
48
- (void) reshape
49
{
50
	NSRect rectView = [self bounds];
51
	me.reshape(rectView.size.width,rectView.size.height);
52
    NSRect backRect = [self convertRectToBacking:rectView];
53
    glViewport (0, 0, NSWidth(backRect), NSHeight(backRect));
54
}
55
 
56
// ---------------------------------
57
// ---------------------------------
58
 
59
// per-window timer function, basic time based animation preformed here
60
- (void)animationTimer:(NSTimer *)timer
61
{
62
    if(me.try_spinning_ball())
63
        [self setNeedsDisplay: YES];
64
}
65
 
66
-(IBAction)save_window_to_pasteboard:(id)sender
67
{
68
 
69
    NSPasteboard *pb = [NSPasteboard generalPasteboard];
70
 
71
    // Telling the pasteboard what type of data we're going to send in
72
    [pb declareTypes:[NSArray arrayWithObjects:NSPasteboardTypePNG,nil] owner:self];
73
 
74
    NSRect backRect = [self convertRectToBacking: [self bounds]];
75
    NSSize sz;
76
    sz.width = NSWidth(backRect);
77
    sz.height = NSHeight(backRect);
78
 
79
    NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
80
                                                                    pixelsWide: sz.width
81
                                                                    pixelsHigh: sz.height
82
                                                                 bitsPerSample: 8
83
                                                               samplesPerPixel: 3
84
                                                                      hasAlpha: NO
85
                                                                      isPlanar: NO
86
                                                                colorSpaceName: NSCalibratedRGBColorSpace
87
                                                                   bytesPerRow: 0				// indicates no empty bytes at row end
88
                                                                  bitsPerPixel: 0];
89
 
90
    glReadBuffer(GL_FRONT);
91
    int bytesPerRow = [rep bytesPerRow];
92
	glPixelStorei(GL_PACK_ROW_LENGTH, 8*bytesPerRow/[rep bitsPerPixel]);
93
    glReadPixels(0, 0, NSWidth(backRect), NSHeight(backRect), GL_RGB, GL_UNSIGNED_BYTE,  [rep bitmapData]);
94
 
95
    NSBitmapImageRep* flipped =  [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
96
                                                                         pixelsWide: sz.width
97
                                                                         pixelsHigh: sz.height
98
                                                                      bitsPerSample: 8
99
                                                                    samplesPerPixel: 3
100
                                                                           hasAlpha: NO
101
                                                                           isPlanar: NO
102
                                                                     colorSpaceName: NSCalibratedRGBColorSpace
103
                                                                        bytesPerRow: 0				// indicates no empty bytes at row end
104
                                                                       bitsPerPixel: 0];
105
 
106
    for(int j=1; j< sz.height+1; ++j)
107
        for(int i=0;i<sz.width;++i)
108
        {
109
            NSUInteger pixels[4];
110
            [rep getPixel: pixels atX:i y:j];
111
            [flipped setPixel: pixels atX:i y:sz.height-j];
112
        }
113
 
114
    // Converting the representation to PNG and sending it to the pasteboard (with type indicated)
115
    [pb setData:[flipped representationUsingType:NSPNGFileType properties:nil] forType:NSPasteboardTypePNG];
116
 
117
 
118
 
119
}
120
 
121
 
122
 
123
-(void)keyDown:(NSEvent *)theEvent
124
{
125
    switch ([theEvent keyCode]) {
126
        case 123:
127
            me.key_left();
128
            break;
129
        case 124:
130
            me.key_right();
131
            break;
132
        case 126:
133
            me.key_up();
134
            break;
135
        case 125:
136
            me.key_down();
137
            break;
138
        case 115:
139
            me.key_home();
140
            break;
141
        case 119:
142
            me.key_end();
143
            break;
144
        default:
145
            NSString *characters = [theEvent characters];
146
            if ([characters length]) {
147
                unichar character = [characters characterAtIndex:0];
148
                me.keyparse(character);
149
            }
150
            break;
151
    }
152
    [self setNeedsDisplay: YES];
153
}
154
 
155
 
156
// ---------------------------------
157
 
158
- (void)mouseDown:(NSEvent *)theEvent // trackball
159
{
160
    if ([theEvent modifierFlags] & NSAlternateKeyMask) // send to pan
161
		[self rightMouseDown:theEvent];
162
	else {
163
 
164
        NSPoint location = [self convertPoint:[theEvent locationInWindow] fromView:nil];
165
 
166
        Vec2i pos(location.x,location.y);
167
        me.grab_ball(ROTATE_ACTION,pos);
168
	}
169
}
170
 
171
 
172
 
173
// ---------------------------------
174
 
175
- (void)rightMouseDown:(NSEvent *)theEvent // pan
176
{
177
	NSPoint location = [self convertPoint:[theEvent locationInWindow] fromView:nil];
178
    Vec2i pos(location.x,location.y);
179
    me.grab_ball(PAN_ACTION,pos);
180
}
181
 
182
// ---------------------------------
183
 
184
- (void)otherMouseDown:(NSEvent *)theEvent //dolly
185
{
186
}
187
 
188
// ---------------------------------
189
 
190
- (void)mouseUp:(NSEvent *)theEvent
191
{
192
    me.release_ball();
193
}
194
 
195
// ---------------------------------
196
 
197
- (void)rightMouseUp:(NSEvent *)theEvent
198
{
199
	[self mouseUp:theEvent];
200
}
201
 
202
// ---------------------------------
203
 
204
- (void)otherMouseUp:(NSEvent *)theEvent
205
{
206
	[self mouseUp:theEvent];
207
}
208
 
209
// ---------------------------------
210
 
211
- (void)mouseDragged:(NSEvent *)theEvent
212
{
213
	NSPoint location = [self convertPoint:[theEvent locationInWindow] fromView:nil];
214
    Vec2i pos(location.x,location.y);
215
    me.roll_ball(pos);
216
    [self setNeedsDisplay: YES];
217
 
218
}
219
 
220
// ---------------------------------
221
 
222
- (void)scrollWheel:(NSEvent *)theEvent
223
{
224
    Vec2i pos(0,300);
225
    me.grab_ball(ZOOM_ACTION,pos);
226
    pos[1] -= 3*[theEvent deltaY];
227
    me.roll_ball(pos);
228
    me.release_ball();
229
    [self setNeedsDisplay: YES];
230
}
231
 
232
// ---------------------------------
233
 
234
- (void)rightMouseDragged:(NSEvent *)theEvent
235
{
236
	[self mouseDragged: theEvent];
237
}
238
 
239
// ---------------------------------
240
 
241
- (void)otherMouseDragged:(NSEvent *)theEvent
242
{
243
	[self mouseDragged: theEvent];
244
}
245
 
246
// ---------------------------------
247
 
248
- (void) drawRect:(NSRect)rect
249
{
250
    glReportError (__LINE__);
251
 
252
    NSOpenGLContext* ctxt = [self openGLContext];
253
    glReportError (__LINE__);
254
    if(ctxt != nil) {
255
        [ctxt makeCurrentContext];
256
        glReportError (__LINE__);
257
        me.display(int([[self window]backingScaleFactor]));
258
        glReportError (__LINE__);
259
        [ctxt flushBuffer];
260
        glReportError (__LINE__);
261
    }
262
}
263
 
264
// ---------------------------------
265
 
266
// set initial OpenGL state (current context is set)
267
// called after context is created
268
- (void) prepareOpenGL
269
{
270
    glReportError (__LINE__);
271
    [[self openGLContext] makeCurrentContext];
272
    glReportError (__LINE__);
273
    GLint swapInt = 1;
274
    glReportError (__LINE__);
275
    [[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval]; // set to vbl sync
276
    glReportError (__LINE__);
277
    me.init();
278
    glReportError (__LINE__);
279
    NSLog(@"OpenGL Initialized");
280
}
281
// ---------------------------------
282
 
283
// this can be a troublesome call to do anything heavyweight, as it is called on window moves, resizes, and display config changes.  So be
284
// careful of doing too much here.
285
- (void) update // window resizes, moves and display changes (resize, depth and display config change)
286
{
287
	[super update];
288
	if (![self inLiveResize])  {// if not doing live resize
289
	}
290
 
291
}
292
 
293
// ---------------------------------
294
 
295
-(id) initWithFrame: (NSRect) frameRect
296
{
297
	self = [super initWithFrame: frameRect ];
298
    return self;
299
}
300
 
301
// ---------------------------------
302
 
303
- (BOOL)acceptsFirstResponder
304
{
305
    return YES;
306
}
307
 
308
// ---------------------------------
309
 
310
- (BOOL)becomeFirstResponder
311
{
312
    return  YES;
313
}
314
 
315
// ---------------------------------
316
 
317
- (BOOL)resignFirstResponder
318
{
319
    return YES;
320
}
321
 
322
// ---------------------------------
323
 
324
- (void) awakeFromNib
325
{
326
	timer = [NSTimer timerWithTimeInterval:(1.0f/60.0f) target:self selector:@selector(animationTimer:) userInfo:nil repeats:YES];
327
	[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
328
	[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSEventTrackingRunLoopMode]; // ensure timer fires during resize
329
    [[NSApplication sharedApplication] setDelegate: self];
330
    [self registerForDraggedTypes: [NSArray arrayWithObjects: (id) kUTTypeData,nil]];
331
}
332
 
333
-(IBAction)open_file_dialog:(id)sender
334
{
335
    NSOpenPanel* openDlg = [NSOpenPanel openPanel];
336
    [openDlg setCanChooseFiles:YES];
337
    [openDlg setCanChooseDirectories:NO];
338
    [openDlg setAllowsMultipleSelection:YES];
339
    if ( [openDlg runModal] == NSOKButton )
340
        for(NSURL *fileURL in [openDlg URLs]) {
341
            me.add_file([ [fileURL path] UTF8String]);
342
            [[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL: fileURL];
343
        }
344
    [self setNeedsDisplay: YES];
345
}
346
 
347
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
348
{
349
    if(me.add_file([ filename UTF8String])) {
350
        [[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL:[NSURL fileURLWithPath:filename]];
351
        [self setNeedsDisplay: YES];
352
        return YES;
353
    }
354
       return NO;
355
}
356
 
357
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
358
{
359
    NSURL* fileURL = [NSURL URLFromPasteboard: [sender draggingPasteboard]];
360
    me.add_file([[fileURL path] UTF8String]);
361
    [[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL: fileURL];
362
    [self setNeedsDisplay: YES];
363
    return YES;
364
}
365
 
366
- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
367
{
368
    return YES;
369
}
370
 
371
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
372
{
373
    return NSDragOperationCopy;
374
}
375
 
376
 
377
@end