root / branches / tbeta / Windows-PS3EyeMuticam / libs / openFrameworks / app / ofAppGlutWindow.cpp @ 195

View | Annotate | Download (15.5 KB)

1
#include "ofAppGlutWindow.h"
2
#include "ofBaseApp.h"
3
#include "ofMain.h"
4
5
#include <windows.h>
6
7
// glut works with static callbacks UGH, so we need static variables here:
8
9
int                                windowMode;
10
bool                        bNewScreenMode;
11
float                        timeNow, timeThen, fps;
12
int                                nFramesForFPS;
13
int                                nFrameCount;
14
int                                buttonInUse;
15
bool                        bEnableSetupScreen;
16
17
bool                        bFrameRateSet;
18
int                         millisForFrame;
19
int                         prevMillis;
20
int                         diffMillis;
21
22
float                         frameRate;
23
24
int                                requestedWidth;
25
int                                requestedHeight;
26
int                         nonFullScreenX;
27
int                         nonFullScreenY;
28
int                                mouseX, mouseY;
29
ofBaseApp *                ofAppPtr;
30
31
32
//----------------------------------------------------------
33
ofAppGlutWindow::ofAppGlutWindow()
34
{
35
        timeNow                                = 0;
36
        timeThen                        = 0;
37
        fps                                        = 60; //give a realistic starting value - win32 issues
38
        windowMode                        = OF_WINDOW;
39
        bNewScreenMode                = true;
40
        nFramesForFPS                = 0;
41
        nFrameCount                        = 0;
42
        buttonInUse                        = 0;
43
        bEnableSetupScreen        = true;
44
        bFrameRateSet                = false;
45
        millisForFrame                = 0;
46
        prevMillis                        = 0;
47
        diffMillis                        = 0;
48
        frameRate                        = 0;
49
        requestedWidth                = 0;
50
        requestedHeight                = 0;
51
        nonFullScreenX                = -1;
52
        nonFullScreenY                = -1;
53
        mouseX                                = 0;
54
        mouseY                                = 0;
55
}
56
57
//------------------------------------------------------------
58
void ofAppGlutWindow::setupOpenGL(int w, int h, int screenMode)
59
{
60
        int argc = 1;
61
        char *argv = "openframeworks";
62
        char **vptr = &argv;
63
        glutInit(&argc, vptr);
64
        glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA);
65
66
        windowMode = screenMode;
67
        bNewScreenMode = true;
68
69
        if (windowMode != OF_GAME_MODE)
70
        {
71
                glutInitWindowSize(w, h);
72
                wndId = glutCreateWindow("");        // store window id
73
74
                //Default colors etc are now in ofGraphics - ofSetupGraphicDefaults
75
                ofSetupGraphicDefaults();
76
77
                /*
78
                ofBackground(200,200,200);                // default bg color
79
                ofSetColor(0xFFFFFF);                         // default draw color
80
                // used to be black, but
81
                // black + texture = black
82
                // so maybe grey bg
83
                // and "white" fg color
84
                // as default works the best...
85
                */
86
87
                requestedWidth  = glutGet(GLUT_WINDOW_WIDTH);
88
                requestedHeight = glutGet(GLUT_WINDOW_HEIGHT);
89
        } 
90
        else 
91
        {
92
                glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA );
93
            // w x h, 32bit pixel depth, 60Hz refresh rate
94
                char gameStr[64];
95
                sprintf( gameStr, "%dx%d:%d@%d", w, h, 32, 60 );
96
97
            glutGameModeString(gameStr);
98
99
            if (!glutGameModeGet(GLUT_GAME_MODE_POSSIBLE))
100
                {
101
                    ofLog(OF_LOG_ERROR,"game mode error: selected format (%s) not available \n", gameStr);
102
            }
103
            // start fullscreen game mode
104
            glutEnterGameMode();
105
        }
106
}
107
108
//------------------------------------------------------------
109
void ofAppGlutWindow::initializeWindow()
110
{
111
         //----------------------
112
         // setup the callbacks
113
         glutMouseFunc(mouse_cb);
114
         glutMotionFunc(motion_cb);
115
         glutPassiveMotionFunc(passive_motion_cb);
116
         glutIdleFunc(idle_cb);
117
         glutDisplayFunc(display);
118
119
         glutKeyboardFunc(keyboard_cb);
120
         glutKeyboardUpFunc(keyboard_up_cb);
121
         glutSpecialFunc(special_key_cb);
122
         glutSpecialUpFunc(special_key_up_cb);
123
124
         glutReshapeFunc(resize_cb);
125
}
126
127
//------------------------------------------------------------
128
void ofAppGlutWindow::runAppViaInfiniteLoop(ofBaseApp * appPtr)
129
{
130
        static ofEventArgs voidEventArgs;
131
132
        ofAppPtr = appPtr;
133
134
        if(ofAppPtr)
135
        {
136
                ofAppPtr->setup();
137
                ofAppPtr->update();
138
        }
139
        #ifdef OF_USING_POCO
140
                ofNotifyEvent( ofEvents.setup, voidEventArgs );
141
                ofNotifyEvent( ofEvents.update, voidEventArgs );
142
        #endif
143
144
        // AlexP this fix allows for clean opengl mail loop exit
145
        try
146
        {
147
                glutMainLoop();
148
        }
149
        catch(...)
150
        {
151
        }
152
        // AlexP
153
        glutDestroyWindow(wndId);
154
}
155
156
//------------------------------------------------------------
157
float ofAppGlutWindow::getFrameRate()
158
{
159
        return frameRate;
160
}
161
162
//------------------------------------------------------------
163
int ofAppGlutWindow::getFrameNum()
164
{
165
        return nFrameCount;
166
}
167
168
//------------------------------------------------------------
169
void ofAppGlutWindow::setWindowTitle(string title)
170
{
171
        glutSetWindowTitle(title.c_str());
172
}
173
174
//------------------------------------------------------------
175
ofPoint ofAppGlutWindow::getWindowSize()
176
{
177
        int width = glutGet(GLUT_WINDOW_WIDTH);
178
        int height = glutGet(GLUT_WINDOW_HEIGHT);
179
        return ofPoint(width, height,0);
180
}
181
182
//------------------------------------------------------------
183
ofPoint ofAppGlutWindow::getWindowPosition()
184
{
185
        int x = glutGet(GLUT_WINDOW_X);
186
        int y = glutGet(GLUT_WINDOW_Y);
187
        return ofPoint(x,y,0);
188
}
189
190
//------------------------------------------------------------
191
ofPoint ofAppGlutWindow::getScreenSize()
192
{
193
        int width = glutGet(GLUT_SCREEN_WIDTH);
194
        int height = glutGet(GLUT_SCREEN_HEIGHT);
195
        return ofPoint(width, height,0);
196
}
197
198
//------------------------------------------------------------
199
void ofAppGlutWindow::setWindowPosition(int x, int y)
200
{
201
        glutPositionWindow(x,y);
202
}
203
204
//------------------------------------------------------------
205
void ofAppGlutWindow::setWindowShape(int w, int h)
206
{
207
        glutReshapeWindow(w, h);
208
        // this is useful, esp if we are in the first frame (setup):
209
        requestedWidth  = w;
210
        requestedHeight = h;
211
}
212
213
//------------------------------------------------------------
214
void ofAppGlutWindow::hideCursor()
215
{
216
        glutSetCursor(GLUT_CURSOR_NONE);
217
}
218
219
//------------------------------------------------------------
220
void ofAppGlutWindow::showCursor()
221
{
222
        glutSetCursor(GLUT_CURSOR_LEFT_ARROW);
223
}
224
225
//------------------------------------------------------------
226
void ofAppGlutWindow::setFrameRate(float targetRate)
227
{
228
        // given this FPS, what is the amount of millis per frame
229
        // that should elapse?
230
231
        // --- > f / s
232
233
        if (targetRate == 0)
234
        {
235
                bFrameRateSet = false;
236
                return;
237
        }
238
239
        bFrameRateSet                         = true;
240
        float durationOfFrame         = 1.0f / (float)targetRate;
241
        millisForFrame                         = (int)(1000.0f * durationOfFrame);
242
243
        frameRate                                = targetRate;
244
}
245
246
//------------------------------------------------------------
247
int ofAppGlutWindow::getWindowMode()
248
{
249
        return windowMode;
250
}
251
252
//------------------------------------------------------------
253
void ofAppGlutWindow::toggleFullscreen()
254
{
255
        if( windowMode == OF_GAME_MODE)        return;
256
        if( windowMode == OF_WINDOW )        windowMode = OF_FULLSCREEN;
257
        else                                                        windowMode = OF_WINDOW;
258
        bNewScreenMode = true;
259
}
260
261
//------------------------------------------------------------
262
void ofAppGlutWindow::setFullscreen(bool fullscreen)
263
{
264
    if( windowMode == OF_GAME_MODE)return;
265
266
    if(fullscreen && windowMode != OF_FULLSCREEN)
267
        {
268
        bNewScreenMode  = true;
269
        windowMode      = OF_FULLSCREEN;
270
    }
271
        else if(!fullscreen && windowMode != OF_WINDOW) 
272
        {
273
        bNewScreenMode  = true;
274
        windowMode      = OF_WINDOW;
275
    }
276
}
277
278
//------------------------------------------------------------
279
void ofAppGlutWindow::enableSetupScreen()
280
{
281
        bEnableSetupScreen = true;
282
}
283
284
//------------------------------------------------------------
285
void ofAppGlutWindow::disableSetupScreen()
286
{
287
        bEnableSetupScreen = false;
288
}
289
290
//------------------------------------------------------------
291
void ofAppGlutWindow::display(void)
292
{
293
        static ofEventArgs voidEventArgs;
294
295
        //--------------------------------
296
        // when I had "glutFullScreen()"
297
        // in the initOpenGl, I was getting a "heap" allocation error
298
        // when debugging via visual studio.  putting it here, changes that.
299
        // maybe it's voodoo, or I am getting rid of the problem
300
        // by removing something unrelated, but everything seems
301
        // to work if I put fullscreen on the first frame of display.
302
303
        if (windowMode != OF_GAME_MODE)
304
        {
305
                if ( bNewScreenMode )
306
                {
307
                        if( windowMode == OF_FULLSCREEN)
308
                        {
309
                                //----------------------------------------------------
310
                                // before we go fullscreen, take a snapshot of where we are:
311
                                nonFullScreenX = glutGet(GLUT_WINDOW_X);
312
                                nonFullScreenY = glutGet(GLUT_WINDOW_Y);
313
                                //----------------------------------------------------
314
315
                                glutFullScreen();
316
317
                                #ifdef TARGET_OSX
318
                                        SetSystemUIMode(kUIModeAllHidden,NULL);
319
                                #endif
320
321
                        }
322
                        else if( windowMode == OF_WINDOW )
323
                        {
324
                                glutReshapeWindow(requestedWidth, requestedHeight);
325
326
                                //----------------------------------------------------
327
                                // if we have recorded the screen position, put it there
328
                                // if not, better to let the system do it (and put it where it wants)
329
                                if (nFrameCount > 0)
330
                                {
331
                                        glutPositionWindow(nonFullScreenX,nonFullScreenY);
332
                                }
333
                                //----------------------------------------------------
334
335
                                #ifdef TARGET_OSX
336
                                        SetSystemUIMode(kUIModeNormal,NULL);
337
                                #endif
338
                                #ifdef TARGET_WIN32
339
                                        // AlexP (remove minimize, maximize, close buttons, no resize)
340
                                        HWND hwnd=FindWindowA("GLUT", NULL);
341
                                        SetWindowLongPtr(hwnd, GWL_STYLE, WS_BORDER|WS_CAPTION);
342
                                        SetWindowPos(hwnd, NULL, 100, 100, 0, 0, SWP_NOZORDER|SWP_NOSIZE|SWP_SHOWWINDOW);
343
                                #endif
344
                        }
345
                        bNewScreenMode = false;
346
                }
347
        }
348
349
        int width, height;
350
351
        width  = ofGetWidth();
352
        height = ofGetHeight();
353
354
        height = height > 0 ? height : 1;
355
        // set viewport, clear the screen
356
        glViewport( 0, 0, width, height );
357
        float * bgPtr = ofBgColorPtr();
358
        bool bClearAuto = ofbClearBg();
359
360
        // I don't know why, I need more than one frame at the start in fullscreen mode
361
        // also, in non-fullscreen mode, windows/intel graphics, this bClearAuto just fails.
362
        // I seem to have 2 buffers, alot of flickering
363
        // and don't accumulate the way I expect.
364
        // with this line:   if ((bClearAuto == true) || nFrameCount < 3){
365
        // we do nFrameCount < 3, so that the buffers are cleared at the start of the app
366
        // or else we have video memory garbage to draw on to...
367
368
        #ifdef TARGET_WIN32
369
                //windows doesn't get accumulation in window mode
370
                if ((bClearAuto == true || windowMode == OF_WINDOW) || nFrameCount < 3)
371
                {
372
        #else
373
                //mac and linux does :)
374
                if ( bClearAuto == true || nFrameCount < 3)
375
                {
376
        #endif
377
                        glClearColor(bgPtr[0],bgPtr[1],bgPtr[2], bgPtr[3]);
378
                        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
379
                }
380
381
        if( bEnableSetupScreen )        ofSetupScreen();
382
383
        if(ofAppPtr)
384
                ofAppPtr->draw();
385
386
        #ifdef OF_USING_POCO
387
                ofNotifyEvent( ofEvents.draw, voidEventArgs );
388
        #endif
389
390
          glutSwapBuffers();
391
392
          // -------------- fps calculation:
393
        timeNow = ofGetElapsedTimef();
394
        if( (timeNow-timeThen) > 0.05f || nFramesForFPS == 0 ) 
395
        {
396
                 fps = (double)nFramesForFPS / (timeNow-timeThen);
397
              timeThen = timeNow;
398
                nFramesForFPS = 0;
399
400
                //hack for windows - was getting NAN - maybe unitialized vars???
401
                if( nFrameCount < 5) frameRate = fps;
402
                else frameRate = 0.9f * frameRate + 0.1f * fps;
403
          }
404
          nFramesForFPS++;
405
          // --------------
406
        nFrameCount++;                // increase the overall frame count
407
        //setFrameNum(nFrameCount); // get this info to ofUtils for people to access
408
}
409
410
//------------------------------------------------------------
411
void ofAppGlutWindow::mouse_cb(int button, int state, int x, int y) 
412
{
413
        static ofMouseEventArgs mouseEventArgs;
414
415
        if (nFrameCount > 0)
416
        {
417
                if(ofAppPtr)
418
                {
419
                        ofAppPtr->mouseX = x;
420
                        ofAppPtr->mouseY = y;
421
                }
422
423
                if (state == GLUT_DOWN) 
424
                {
425
                        if(ofAppPtr)
426
                                ofAppPtr->mousePressed(x,y,button);
427
428
                        #ifdef OF_USING_POCO
429
                                mouseEventArgs.x = x;
430
                                mouseEventArgs.y = y;
431
                                mouseEventArgs.button = button;
432
                                ofNotifyEvent( ofEvents.mousePressed, mouseEventArgs );
433
                        #endif
434
                } 
435
                else if (state == GLUT_UP) 
436
                {
437
                        if(ofAppPtr)
438
                        {
439
                                ofAppPtr->mouseReleased(x,y,button);
440
                                ofAppPtr->mouseReleased();
441
                        }
442
443
                        #ifdef OF_USING_POCO
444
                                mouseEventArgs.x = x;
445
                                mouseEventArgs.y = y;
446
                                mouseEventArgs.button = button;
447
                                ofNotifyEvent( ofEvents.mouseReleased, mouseEventArgs );
448
                        #endif
449
                }
450
                buttonInUse = button;
451
        }
452
}
453
454
//------------------------------------------------------------
455
void ofAppGlutWindow::motion_cb(int x, int y) 
456
{
457
        static ofMouseEventArgs mouseEventArgs;
458
459
        if (nFrameCount > 0)
460
        {
461
                if(ofAppPtr)
462
                {
463
                        ofAppPtr->mouseX = x;
464
                        ofAppPtr->mouseY = y;
465
                        ofAppPtr->mouseDragged(x,y,buttonInUse);
466
                }
467
468
                #ifdef OF_USING_POCO
469
                        mouseEventArgs.x = x;
470
                        mouseEventArgs.y = y;
471
                        mouseEventArgs.button = buttonInUse;
472
                        ofNotifyEvent( ofEvents.mouseDragged, mouseEventArgs );
473
                #endif
474
        }
475
}
476
477
//------------------------------------------------------------
478
void ofAppGlutWindow::passive_motion_cb(int x, int y) 
479
{
480
        static ofMouseEventArgs mouseEventArgs;
481
482
        if (nFrameCount > 0)
483
        {
484
                if(ofAppPtr)
485
                {
486
                        ofAppPtr->mouseX = x;
487
                        ofAppPtr->mouseY = y;
488
                        ofAppPtr->mouseMoved(x,y);
489
                }
490
491
                #ifdef OF_USING_POCO
492
                        mouseEventArgs.x = x;
493
                        mouseEventArgs.y = y;
494
                        ofNotifyEvent( ofEvents.mouseMoved, mouseEventArgs );
495
                #endif
496
        }
497
}
498
499
500
//------------------------------------------------------------
501
void ofAppGlutWindow::idle_cb(void) 
502
{
503
        static ofEventArgs voidEventArgs;
504
505
        //        thanks to jorge for the fix:
506
        //        http://www.openframeworks.cc/forum/viewtopic.php?t=515&highlight=frame+rate
507
508
        if (nFrameCount != 0 && bFrameRateSet == true)
509
        {
510
                diffMillis = ofGetElapsedTimeMillis() - prevMillis;
511
                if (diffMillis > millisForFrame)
512
                {
513
                        ; // we do nothing, we are already slower than target frame
514
                } 
515
                else 
516
                {
517
                        int waitMillis = millisForFrame - diffMillis;
518
                        #ifdef TARGET_WIN32
519
                                Sleep(waitMillis);         //windows sleep in milliseconds
520
                        #else
521
                                usleep(waitMillis * 1000);   //mac sleep in microseconds - cooler :)
522
                        #endif
523
                }
524
        }
525
        prevMillis = ofGetElapsedTimeMillis(); // you have to measure here
526
527
        if(ofAppPtr)
528
                ofAppPtr->update();
529
530
        #ifdef OF_USING_POCO
531
        ofNotifyEvent(ofEvents.update, voidEventArgs);
532
        #endif
533
534
        glutPostRedisplay();
535
}
536
537
538
//------------------------------------------------------------
539
void ofAppGlutWindow::keyboard_cb(unsigned char key, int x, int y)
540
{
541
        static ofKeyEventArgs keyEventArgs;
542
543
        if(ofAppPtr)
544
                ofAppPtr->keyPressed(key);
545
546
        #ifdef OF_USING_POCO
547
                keyEventArgs.key = key;
548
                ofNotifyEvent( ofEvents.keyPressed, keyEventArgs );
549
        #endif
550
551
        if (key == OF_KEY_ESC)
552
                // AlexP this exception will cause the opengl main loop to exit
553
                // after which the opengl window will be destroyed and
554
                // with this the opengl hang issue is solved
555
                throw "Exit OpenGL Main Loop";
556
}
557
558
//------------------------------------------------------------
559
void ofAppGlutWindow::keyboard_up_cb(unsigned char key, int x, int y) 
560
{
561
        static ofKeyEventArgs keyEventArgs;
562
563
        if(ofAppPtr)
564
                ofAppPtr->keyReleased(key);
565
566
        #ifdef OF_USING_POCO
567
                keyEventArgs.key = key;
568
                ofNotifyEvent( ofEvents.keyReleased, keyEventArgs );
569
        #endif
570
}
571
572
//------------------------------------------------------
573
void ofAppGlutWindow::special_key_cb(int key, int x, int y)
574
{
575
        static ofKeyEventArgs keyEventArgs;
576
577
        if(ofAppPtr)
578
                ofAppPtr->keyPressed(key | OF_KEY_MODIFIER);
579
580
        #ifdef OF_USING_POCO
581
                keyEventArgs.key = (key | OF_KEY_MODIFIER);
582
                ofNotifyEvent( ofEvents.keyPressed, keyEventArgs );
583
        #endif
584
}
585
586
//------------------------------------------------------------
587
void ofAppGlutWindow::special_key_up_cb(int key, int x, int y) 
588
{
589
        static ofKeyEventArgs keyEventArgs;
590
591
        if(ofAppPtr)
592
                ofAppPtr->keyReleased(key | OF_KEY_MODIFIER);
593
594
        #ifdef OF_USING_POCO
595
                keyEventArgs.key = (key | OF_KEY_MODIFIER);
596
                ofNotifyEvent( ofEvents.keyReleased, keyEventArgs );
597
        #endif
598
}
599
600
//------------------------------------------------------------
601
void ofAppGlutWindow::resize_cb(int w, int h) 
602
{
603
        static ofResizeEventArgs resizeEventArgs;
604
605
        if(ofAppPtr)
606
                ofAppPtr->windowResized(w,h);
607
608
        #ifdef OF_USING_POCO
609
                resizeEventArgs.width = w;
610
                resizeEventArgs.height = h;
611
                ofNotifyEvent( ofEvents.windowResized, resizeEventArgs );
612
        #endif
613
}