Subversion Repositories gelsvn

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
688 khor 1
#import "BasicOpenGLView.h"
2
#include <GEL/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 backRect = [self convertRectToBacking:[self bounds]];
51
    glViewport (0, 0, NSWidth(backRect), NSHeight(backRect));
52
	me.reshape(NSWidth(backRect),NSHeight(backRect));
53
}
54
 
55
// ---------------------------------
56
// ---------------------------------
57
 
58
// per-window timer function, basic time based animation preformed here
59
- (void)animationTimer:(NSTimer *)timer
60
{
61
    if(me.try_spinning_ball())
62
        [self setNeedsDisplay: YES];
63
}
64
 
65
-(IBAction)save_window_to_pasteboard:(id)sender
66
{
67
    // Get the pasteboard.
68
    NSPasteboard *pb = [NSPasteboard generalPasteboard];
69
 
70
    // Telling the pasteboard what type of data we're going to send in
71
    [pb declareTypes:[NSArray arrayWithObjects:NSPasteboardTypePNG,nil] owner:self];
72
 
73
    // Get the size of the image in a retina safe way
74
    NSRect backRect = [self convertRectToBacking: [self bounds]];
75
    int W = NSWidth(backRect);
76
    int H = NSHeight(backRect);
77
 
78
    // Create image. Note no alpha channel. I don't copy that.
79
    NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
80
                                                                    pixelsWide: W
81
                                                                    pixelsHigh: H
82
                                                                 bitsPerSample: 8
83
                                                               samplesPerPixel: 3
84
                                                                      hasAlpha: NO
85
                                                                      isPlanar: NO
86
                                                                colorSpaceName: NSCalibratedRGBColorSpace
87
                                                                   bytesPerRow: 3*W
88
                                                                  bitsPerPixel: 0];
89
 
90
    // The following block does the actual reading of the image
91
    glPushAttrib(GL_PIXEL_MODE_BIT); // Save state about reading buffers
92
    glReadBuffer(GL_FRONT);
93
    glPixelStorei(GL_PACK_ALIGNMENT, 1); // Dense packing
94
    glReadPixels(0, 0, W, H, GL_RGB, GL_UNSIGNED_BYTE, [rep bitmapData]);
95
    glPopAttrib();
96
 
97
    // So we need one more image, since we must flip its orientation.
98
    NSBitmapImageRep* flipped =  [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
99
                                                                         pixelsWide: W
100
                                                                         pixelsHigh: H
101
                                                                      bitsPerSample: 8
102
                                                                    samplesPerPixel: 3
103
                                                                           hasAlpha: NO
104
                                                                           isPlanar: NO
105
                                                                     colorSpaceName: NSCalibratedRGBColorSpace
106
                                                                        bytesPerRow: 3*W
107
                                                                       bitsPerPixel: 0];
108
 
109
    // Primitive double for loop flipping the row order. Should be a better way. Can't find it.
110
    for(int j=1; j< H+1; ++j)
111
        for(int i=0;i<W;++i)
112
        {
113
            NSUInteger pixels[4];
114
            [rep getPixel: pixels atX:i y:j];
115
            [flipped setPixel: pixels atX:i y:H-j];
116
        }
117
 
118
    // Converting the representation to PNG and sending it to the pasteboard (with type indicated)
119
    [pb setData:[flipped representationUsingType:NSPNGFileType properties:nil] forType:NSPasteboardTypePNG];
120
}
121
 
122
 
123
 
124
-(void)keyDown:(NSEvent *)theEvent
125
{
126
    switch ([theEvent keyCode]) {
127
        case 123:
128
            me.key_left();
129
            break;
130
        case 124:
131
            me.key_right();
132
            break;
133
        case 126:
134
            me.key_up();
135
            break;
136
        case 125:
137
            me.key_down();
138
            break;
139
        case 115:
140
            me.key_home();
141
            break;
142
        case 119:
143
            me.key_end();
144
            break;
145
        default:
146
            NSString *characters = [theEvent characters];
147
            if ([characters length]) {
148
                unichar character = [characters characterAtIndex:0];
149
                me.keyparse(character);
150
            }
151
            break;
152
    }
153
    [self setNeedsDisplay: YES];
154
}
155
 
156
 
157
// ---------------------------------
158
 
159
- (void)mouseDown:(NSEvent *)theEvent // trackball
160
{
161
    if ([theEvent modifierFlags] & NSAlternateKeyMask) // send to pan
162
		[self rightMouseDown:theEvent];
163
	else {
164
 
165
        NSPoint location = [self convertPoint:[theEvent locationInWindow] fromView:nil];
166
        [[self openGLContext] makeCurrentContext];
167
        Vec2i pos(location.x,location.y);
168
        pos *= int([[self window]backingScaleFactor]);
169
        if([theEvent modifierFlags] & NSShiftKeyMask)
170
            me.grab_mesh(pos);
171
        else if([theEvent modifierFlags] & NSControlKeyMask) {
172
            if(me.select_vertex(pos))
173
                [self setNeedsDisplay: YES];
174
        }
175
        else
176
            me.grab_ball(ROTATE_ACTION,pos);
177
	}
178
}
179
 
180
 
181
 
182
// ---------------------------------
183
 
184
- (void)rightMouseDown:(NSEvent *)theEvent // pan
185
{
186
	NSPoint location = [self convertPoint:[theEvent locationInWindow] fromView:nil];
187
    Vec2i pos(location.x,location.y);
188
    pos *= int([[self window]backingScaleFactor]);
189
    me.grab_ball(PAN_ACTION,pos);
190
}
191
 
192
// ---------------------------------
193
 
194
- (void)otherMouseDown:(NSEvent *)theEvent //dolly
195
{
196
}
197
 
198
// ---------------------------------
199
 
200
- (void)mouseUp:(NSEvent *)theEvent
201
{
202
    me.release_mesh();
203
    me.release_ball();
204
}
205
 
206
// ---------------------------------
207
 
208
- (void)rightMouseUp:(NSEvent *)theEvent
209
{
210
	[self mouseUp:theEvent];
211
}
212
 
213
// ---------------------------------
214
 
215
- (void)otherMouseUp:(NSEvent *)theEvent
216
{
217
	[self mouseUp:theEvent];
218
}
219
 
220
// ---------------------------------
221
 
222
- (void)mouseDragged:(NSEvent *)theEvent
223
{
224
	NSPoint location = [self convertPoint:[theEvent locationInWindow] fromView:nil];
225
    Vec2i pos(location.x,location.y);
226
    pos *= int([[self window]backingScaleFactor]);
227
//    NSLog(@"Pos <%d %d> ", pos[0], pos[1]);
228
    [[self openGLContext] makeCurrentContext];
229
    if(!me.drag_mesh(pos))
230
        me.roll_ball(pos);
231
    [self setNeedsDisplay: YES];
232
 
233
}
234
 
235
// ---------------------------------
236
 
237
- (void)scrollWheel:(NSEvent *)theEvent
238
{
239
    Vec2i pos(0,300);
240
    me.grab_ball(ZOOM_ACTION,pos);
241
    pos[1] -= 3*[theEvent deltaY];
242
    me.roll_ball(pos);
243
    me.release_ball();
244
    [self setNeedsDisplay: YES];
245
}
246
 
247
// ---------------------------------
248
 
249
- (void)rightMouseDragged:(NSEvent *)theEvent
250
{
251
	[self mouseDragged: theEvent];
252
}
253
 
254
// ---------------------------------
255
 
256
- (void)otherMouseDragged:(NSEvent *)theEvent
257
{
258
	[self mouseDragged: theEvent];
259
}
260
 
261
// ---------------------------------
262
 
263
- (void) drawRect:(NSRect)rect
264
{
265
    NSOpenGLContext* ctxt = [self openGLContext];
266
    if(ctxt != nil) {
267
        [ctxt makeCurrentContext];
268
        me.display(int([[self window]backingScaleFactor]));
269
        [ctxt flushBuffer];
270
    }
271
}
272
 
273
// ---------------------------------
274
 
275
// set initial OpenGL state (current context is set)
276
// called after context is created
277
- (void) prepareOpenGL
278
{
279
    [[self openGLContext] makeCurrentContext];
280
    GLint swapInt = 1;
281
    [[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval]; // set to vbl sync
282
    me.init();
283
    NSLog(@"OpenGL Initialized");
284
}
285
// ---------------------------------
286
 
287
// this can be a troublesome call to do anything heavyweight, as it is called on window moves, resizes, and display config changes.  So be
288
// careful of doing too much here.
289
- (void) update // window resizes, moves and display changes (resize, depth and display config change)
290
{
291
	[super update];
292
	if (![self inLiveResize])  {// if not doing live resize
293
	}
294
 
295
}
296
 
297
// ---------------------------------
298
 
299
-(id) initWithFrame: (NSRect) frameRect
300
{
301
	self = [super initWithFrame: frameRect ];
302
    return self;
303
}
304
 
305
// ---------------------------------
306
 
307
- (BOOL)acceptsFirstResponder
308
{
309
    return YES;
310
}
311
 
312
// ---------------------------------
313
 
314
- (BOOL)becomeFirstResponder
315
{
316
    return  YES;
317
}
318
 
319
// ---------------------------------
320
 
321
- (BOOL)resignFirstResponder
322
{
323
    return YES;
324
}
325
 
326
// ---------------------------------
327
 
328
- (void) awakeFromNib
329
{
330
	timer = [NSTimer timerWithTimeInterval:(1.0f/60.0f) target:self selector:@selector(animationTimer:) userInfo:nil repeats:YES];
331
	[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
332
	[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSEventTrackingRunLoopMode]; // ensure timer fires during resize
333
    [[NSApplication sharedApplication] setDelegate: self];
334
    [self registerForDraggedTypes: [NSArray arrayWithObjects: (id) kUTTypeData,nil]];
335
}
336
 
337
-(IBAction)open_file_dialog:(id)sender
338
{
339
    NSOpenPanel* openDlg = [NSOpenPanel openPanel];
340
    [openDlg setCanChooseFiles:YES];
341
    [openDlg setCanChooseDirectories:NO];
342
    [openDlg setAllowsMultipleSelection:YES];
343
    if ( [openDlg runModal] == NSOKButton )
344
        for(NSURL *fileURL in [openDlg URLs]) {
345
            me.add_file([ [fileURL path] UTF8String]);
346
            [[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL: fileURL];
347
        }
348
    [self setNeedsDisplay: YES];
349
}
350
 
351
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
352
{
353
    if(me.add_file([ filename UTF8String])) {
354
        [[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL:[NSURL fileURLWithPath:filename]];
355
        [self setNeedsDisplay: YES];
356
        return YES;
357
    }
358
    return NO;
359
}
360
 
361
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
362
{
363
    NSURL* fileURL = [NSURL URLFromPasteboard: [sender draggingPasteboard]];
364
    me.add_file([[fileURL path] UTF8String]);
365
    [[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL: fileURL];
366
    [self setNeedsDisplay: YES];
367
    return YES;
368
}
369
 
370
- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
371
{
372
    return YES;
373
}
374
 
375
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
376
{
377
    return NSDragOperationCopy;
378
}
379
 
380
 
381
@end