Subversion Repositories gelsvn

Rev

Rev 648 | Rev 657 | 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
{
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];
656 janba 165
        [[self openGLContext] makeCurrentContext];
648 janba 166
        Vec2i pos(location.x,location.y);
656 janba 167
        pos *= int([[self window]backingScaleFactor]);
168
        if(!me.grab_mesh(pos))
169
            me.grab_ball(ROTATE_ACTION,pos);
648 janba 170
	}
171
}
172
 
173
 
174
 
175
// ---------------------------------
176
 
177
- (void)rightMouseDown:(NSEvent *)theEvent // pan
178
{
179
	NSPoint location = [self convertPoint:[theEvent locationInWindow] fromView:nil];
180
    Vec2i pos(location.x,location.y);
656 janba 181
    pos *= int([[self window]backingScaleFactor]);
648 janba 182
    me.grab_ball(PAN_ACTION,pos);
183
}
184
 
185
// ---------------------------------
186
 
187
- (void)otherMouseDown:(NSEvent *)theEvent //dolly
188
{
189
}
190
 
191
// ---------------------------------
192
 
193
- (void)mouseUp:(NSEvent *)theEvent
194
{
656 janba 195
    me.release_mesh();
648 janba 196
    me.release_ball();
197
}
198
 
199
// ---------------------------------
200
 
201
- (void)rightMouseUp:(NSEvent *)theEvent
202
{
203
	[self mouseUp:theEvent];
204
}
205
 
206
// ---------------------------------
207
 
208
- (void)otherMouseUp:(NSEvent *)theEvent
209
{
210
	[self mouseUp:theEvent];
211
}
212
 
213
// ---------------------------------
214
 
215
- (void)mouseDragged:(NSEvent *)theEvent
216
{
217
	NSPoint location = [self convertPoint:[theEvent locationInWindow] fromView:nil];
218
    Vec2i pos(location.x,location.y);
656 janba 219
    pos *= int([[self window]backingScaleFactor]);
220
    [[self openGLContext] makeCurrentContext];
221
    if(!me.drag_mesh(pos))
222
        me.roll_ball(pos);
648 janba 223
    [self setNeedsDisplay: YES];
656 janba 224
 
648 janba 225
}
226
 
227
// ---------------------------------
228
 
229
- (void)scrollWheel:(NSEvent *)theEvent
230
{
231
    Vec2i pos(0,300);
232
    me.grab_ball(ZOOM_ACTION,pos);
233
    pos[1] -= 3*[theEvent deltaY];
234
    me.roll_ball(pos);
235
    me.release_ball();
236
    [self setNeedsDisplay: YES];
237
}
238
 
239
// ---------------------------------
240
 
241
- (void)rightMouseDragged:(NSEvent *)theEvent
242
{
243
	[self mouseDragged: theEvent];
244
}
245
 
246
// ---------------------------------
247
 
248
- (void)otherMouseDragged:(NSEvent *)theEvent
249
{
250
	[self mouseDragged: theEvent];
251
}
252
 
253
// ---------------------------------
254
 
255
- (void) drawRect:(NSRect)rect
256
{
257
    NSOpenGLContext* ctxt = [self openGLContext];
258
    if(ctxt != nil) {
259
        [ctxt makeCurrentContext];
260
        me.display(int([[self window]backingScaleFactor]));
261
        [ctxt flushBuffer];
262
    }
263
}
264
 
265
// ---------------------------------
266
 
267
// set initial OpenGL state (current context is set)
268
// called after context is created
269
- (void) prepareOpenGL
270
{
271
    [[self openGLContext] makeCurrentContext];
272
    GLint swapInt = 1;
273
    [[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval]; // set to vbl sync
274
    me.init();
275
    NSLog(@"OpenGL Initialized");
276
}
277
// ---------------------------------
278
 
279
// this can be a troublesome call to do anything heavyweight, as it is called on window moves, resizes, and display config changes.  So be
280
// careful of doing too much here.
281
- (void) update // window resizes, moves and display changes (resize, depth and display config change)
282
{
283
	[super update];
284
	if (![self inLiveResize])  {// if not doing live resize
285
	}
286
 
287
}
288
 
289
// ---------------------------------
290
 
291
-(id) initWithFrame: (NSRect) frameRect
292
{
293
	self = [super initWithFrame: frameRect ];
294
    return self;
295
}
296
 
297
// ---------------------------------
298
 
299
- (BOOL)acceptsFirstResponder
300
{
301
    return YES;
302
}
303
 
304
// ---------------------------------
305
 
306
- (BOOL)becomeFirstResponder
307
{
308
    return  YES;
309
}
310
 
311
// ---------------------------------
312
 
313
- (BOOL)resignFirstResponder
314
{
315
    return YES;
316
}
317
 
318
// ---------------------------------
319
 
320
- (void) awakeFromNib
321
{
322
	timer = [NSTimer timerWithTimeInterval:(1.0f/60.0f) target:self selector:@selector(animationTimer:) userInfo:nil repeats:YES];
323
	[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
324
	[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSEventTrackingRunLoopMode]; // ensure timer fires during resize
325
    [[NSApplication sharedApplication] setDelegate: self];
326
    [self registerForDraggedTypes: [NSArray arrayWithObjects: (id) kUTTypeData,nil]];
327
}
328
 
329
-(IBAction)open_file_dialog:(id)sender
330
{
331
    NSOpenPanel* openDlg = [NSOpenPanel openPanel];
332
    [openDlg setCanChooseFiles:YES];
333
    [openDlg setCanChooseDirectories:NO];
334
    [openDlg setAllowsMultipleSelection:YES];
335
    if ( [openDlg runModal] == NSOKButton )
336
        for(NSURL *fileURL in [openDlg URLs]) {
337
            me.add_file([ [fileURL path] UTF8String]);
338
            [[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL: fileURL];
339
        }
340
    [self setNeedsDisplay: YES];
341
}
342
 
343
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
344
{
345
    if(me.add_file([ filename UTF8String])) {
346
        [[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL:[NSURL fileURLWithPath:filename]];
347
        [self setNeedsDisplay: YES];
348
        return YES;
349
    }
656 janba 350
    return NO;
648 janba 351
}
352
 
353
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
354
{
355
    NSURL* fileURL = [NSURL URLFromPasteboard: [sender draggingPasteboard]];
356
    me.add_file([[fileURL path] UTF8String]);
357
    [[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL: fileURL];
358
    [self setNeedsDisplay: YES];
359
    return YES;
360
}
361
 
362
- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
363
{
364
    return YES;
365
}
366
 
367
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
368
{
369
    return NSDragOperationCopy;
370
}
371
 
372
 
373
@end