Subversion Repositories gelsvn

Rev

Rev 656 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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