~ubuntu-branches/debian/stretch/3depict/stretch

« back to all changes in this revision

Viewing changes to src/gui/glPane.cpp

  • Committer: Package Import Robot
  • Author(s): D Haley
  • Date: 2015-05-01 23:59:48 UTC
  • mfrom: (1.1.9)
  • Revision ID: package-import@ubuntu.com-20150501235948-t38obogk535eg2h6
Tags: 0.0.18-1
Update to upstream 0.0.18

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 *      glPane.cpp - OpenGL panel implementation
3
 
 *      Copyright (C) 2013, D Haley 
 
3
 *      Copyright (C) 2015, D Haley 
4
4
 
5
5
 *      This program is free software: you can redistribute it and/or modify
6
6
 *      it under the terms of the GNU General Public License as published by
23
23
 
24
24
#include "common/stringFuncs.h"
25
25
#include "gl/select.h"
26
 
#include "gl/tr.h"
27
26
#include "glPane.h"
28
27
 
29
28
 
46
45
    #define GL_BGR 0x80E0
47
46
#endif
48
47
 
 
48
using std::string;
49
49
 
50
50
enum
51
51
{
67
67
EVT_LEAVE_WINDOW(BasicGLPane::mouseLeftWindow)
68
68
EVT_SIZE(BasicGLPane::resized)
69
69
EVT_KEY_DOWN(BasicGLPane::keyPressed)
70
 
EVT_CHAR(BasicGLPane::charEvent) 
71
70
EVT_KEY_UP(BasicGLPane::keyReleased)
72
71
EVT_MOUSEWHEEL(BasicGLPane::mouseWheelMoved)
73
72
EVT_PAINT(BasicGLPane::render)
89
88
                        1,
90
89
                        0,0};
91
90
 
92
 
BasicGLPane::BasicGLPane(wxWindow* parent) :
93
 
#if wxCHECK_VERSION(2,9,0)
94
 
wxGLCanvas(parent, wxID_ANY,  attribList)
95
 
#else
96
 
wxGLCanvas(parent, wxID_ANY,  wxDefaultPosition, wxDefaultSize, 0, wxT("GLCanvas"),attribList)
97
 
#endif
 
91
BasicGLPane::BasicGLPane(wxWindow* parent) : wxGLCanvas(parent, wxID_ANY,  attribList)
98
92
{
99
93
        haveCameraUpdates=false;
100
94
        applyingDevice=false;
102
96
 
103
97
        keyDoubleTapTimer=new wxTimer(this,ID_KEYPRESS_TIMER);
104
98
        lastKeyDoubleTap=(unsigned int)-1;
105
 
#if wxCHECK_VERSION(2,9,0)
106
99
        context=0;
107
 
#endif
108
100
 
109
101
        mouseMoveFactor=mouseZoomFactor=1.0f;   
110
102
        dragging=false;
121
113
 
122
114
bool BasicGLPane::displaySupported() const
123
115
{
124
 
#if wxCHECK_VERSION(2,9,0)
125
116
        return IsDisplaySupported(attribList);
126
 
#else
127
 
        ASSERT(false);
128
 
        //Lets hope so. If its not, then its just going to fail anyway. 
129
 
        //If it is, then returning false would simply create a roadblock.
130
 
        //Either way, you shouldn't get here.
131
 
        return true; 
132
 
#endif
133
117
}
134
118
 
135
119
void BasicGLPane::setSceneInteractionAllowed(bool enabled)
136
120
{
137
 
        currentScene.lockInteraction(!enabled);
 
121
        currentScene->lockInteraction(!enabled);
138
122
}
139
123
 
140
124
unsigned int  BasicGLPane::selectionTest(const wxPoint &p,bool &shouldRedraw)
141
125
{
142
126
 
143
 
        if(currentScene.isInteractionLocked())
 
127
        if(currentScene->isInteractionLocked())
144
128
        {
145
129
                shouldRedraw=false;
146
130
                return -1; 
161
145
        gluPickMatrix(p.x, oldViewport[3]-p.y,5, 5, oldViewport);
162
146
        glMatrixMode(GL_MODELVIEW);
163
147
 
164
 
        int lastSelected = currentScene.getLastSelected();
165
 
        int selectedObject=currentScene.glSelect();
 
148
        int lastSelected = currentScene->getLastSelected();
 
149
        int selectedObject=currentScene->glSelect();
166
150
 
167
151
        //If the object selection hasn't changed, we don't need to redraw
168
152
        //if it has changed, we should redraw
182
166
unsigned int  BasicGLPane::hoverTest(const wxPoint &p,bool &shouldRedraw)
183
167
{
184
168
 
185
 
        if(currentScene.isInteractionLocked())
 
169
        if(currentScene->isInteractionLocked())
186
170
        {
187
171
                shouldRedraw=false;
188
172
                return -1;
199
183
        gluPickMatrix(p.x, oldViewport[3]-p.y,5, 5, oldViewport);
200
184
        glMatrixMode(GL_MODELVIEW);
201
185
 
202
 
        unsigned int lastHover = currentScene.getLastHover();
203
 
        unsigned int hoverObject=currentScene.glSelect(false);
 
186
        unsigned int lastHover = currentScene->getLastHover();
 
187
        unsigned int hoverObject=currentScene->glSelect(false);
204
188
 
205
189
        //FIXME: Should be able to make this more efficient     
206
190
        shouldRedraw =  lastHover!=(unsigned int)-1;
207
191
 
208
192
        //Set the scene's hover value
209
 
        currentScene.setLastHover(hoverObject);
210
 
        currentScene.setHoverMode(hoverObject != (unsigned int)-1);
 
193
        currentScene->setLastHover(hoverObject);
 
194
        currentScene->setHoverMode(hoverObject != (unsigned int)-1);
211
195
 
212
196
        //Restore the previous matirx
213
197
        glPopMatrix();
226
210
        wxPaintEvent ptEvent;
227
211
        wxPostEvent(this,ptEvent);
228
212
 
229
 
        //Hack to fix panel redraw commands not working under windows
230
 
        //--
231
 
#if defined(__WIN32) || defined(__WIN64)
232
 
        wxYield();
233
 
 
234
 
        Hide();
235
 
        Show();
236
 
 
237
 
#endif
238
 
        //--
239
213
}
240
214
 
241
215
// some useful events to use
253
227
 
254
228
        if(selectionMode )
255
229
        {
256
 
                if(currentScene.isInteractionLocked())
 
230
                if(currentScene->isInteractionLocked())
257
231
                {
258
232
                        event.Skip();
259
233
                        return;
271
245
                if(wxm.ShiftDown())
272
246
                        keyFlags|=FLAG_SHIFT;
273
247
 
274
 
#if wxCHECK_VERSION(2,9,0)
275
248
                if(wxm.LeftIsDown())
276
249
                        mouseFlags|= SELECT_BUTTON_LEFT;
277
250
                if(wxm.RightIsDown())
278
251
                        mouseFlags|= SELECT_BUTTON_RIGHT;
279
252
                if(wxm.MiddleIsDown())
280
253
                        mouseFlags|= SELECT_BUTTON_MIDDLE;
281
 
#else
282
 
                if(wxm.LeftDown())
283
 
                        mouseFlags|= SELECT_BUTTON_LEFT;
284
 
                if(wxm.RightDown())
285
 
                        mouseFlags|= SELECT_BUTTON_RIGHT;
286
 
                if(wxm.MiddleDown())
287
 
                        mouseFlags|= SELECT_BUTTON_MIDDLE;
288
 
#endif
 
254
                
289
255
                //We can get  a mouse move event which reports no buttons before a mouse-up event,
290
256
                //this occurs frequently under windows, but sometimes under GTK
291
257
                if(!mouseFlags)
298
264
                GetClientSize(&w, &h);
299
265
 
300
266
 
301
 
                currentScene.applyDevice((float)draggingStart.x/(float)w,
 
267
                currentScene->applyDevice((float)draggingStart.x/(float)w,
302
268
                                        (float)draggingStart.y/(float)h,
303
269
                                         p.x/(float)w,p.y/(float)h,
304
270
                                         keyFlags,mouseFlags,
335
301
        {
336
302
                //Commit the current temp cam using the last camera rate
337
303
                //and then restart the motion.
338
 
                if(!lastMoveShiftDown && currentScene.haveTempCam())
339
 
                        currentScene.commitTempCam();
 
304
                if(!lastMoveShiftDown && currentScene->haveTempCam())
 
305
                        currentScene->commitTempCam();
340
306
 
341
307
                camMultRate*=5.0f;
342
308
 
347
313
        {
348
314
                //Commit the current temp cam using the last camera rate
349
315
                //and then restart the motion.
350
 
                if(lastMoveShiftDown && currentScene.haveTempCam())
351
 
                        currentScene.commitTempCam();
 
316
                if(lastMoveShiftDown && currentScene->haveTempCam())
 
317
                        currentScene->commitTempCam();
352
318
 
353
319
                lastMoveShiftDown=false;
354
320
        }
383
349
        switch(camMode)
384
350
        {
385
351
                case CAM_TRANSLATE:
386
 
                        currentScene.discardTempCam();
387
 
                        currentScene.setTempCam();
388
 
                        currentScene.getTempCam()->translate(lrMove,-udMove);
 
352
                        currentScene->discardTempCam();
 
353
                        currentScene->setTempCam();
 
354
                        currentScene->getTempCam()->translate(lrMove,-udMove);
389
355
                        break;
390
356
                case CAM_PIVOT:
391
 
                        currentScene.discardTempCam();
392
 
                        currentScene.setTempCam();
393
 
                        currentScene.getTempCam()->pivot(lrMove,udMove);
 
357
                        currentScene->discardTempCam();
 
358
                        currentScene->setTempCam();
 
359
                        currentScene->getTempCam()->pivot(lrMove,udMove);
394
360
                        break;
395
361
                case CAM_MOVE:
396
 
                        currentScene.setTempCam();
397
 
                        currentScene.getTempCam()->move(lrMove,udMove);
 
362
                        currentScene->setTempCam();
 
363
                        currentScene->getTempCam()->move(lrMove,udMove);
398
364
                        break;
399
365
                case CAM_ROLL:
400
 
                        currentScene.setTempCam();
401
 
                        currentScene.getTempCam()->roll(atan2(udMove,lrMove));
 
366
                        currentScene->setTempCam();
 
367
                        currentScene->getTempCam()->roll(atan2(udMove,lrMove));
402
368
                                                
403
369
                        break;  
404
370
                default:
409
375
        if(!event.m_leftDown)
410
376
        {
411
377
                dragging=false;
412
 
                currentScene.commitTempCam();
 
378
                currentScene->commitTempCam();
413
379
        }
414
380
        
415
381
        haveCameraUpdates=true;
427
393
        //a temp cam is activated in the scene, or a binding refresh is underway,
428
394
        //which is currently considered bad
429
395
        if(!dragging && !applyingDevice && !selectionMode 
430
 
                        && !currentScene.isInteractionLocked())
 
396
                        && !currentScene->isInteractionLocked())
431
397
        {
432
398
                //Check to see if the user has clicked an object in the scene
433
399
                bool redraw;
435
401
 
436
402
 
437
403
                //If the selected object is valid, then
438
 
                //we did select an object. Treat this as a seletion event
439
 
                if(currentScene.getLastSelected() != (unsigned int)-1)
 
404
                //we did select an object. Treat this as a selection event
 
405
                if(currentScene->getLastSelected() != (unsigned int)-1)
440
406
                {
441
407
                        selectionMode=true;
442
 
                        currentScene.setSelectionMode(true);
 
408
                        currentScene->setSelectionMode(true);
443
409
                }
444
410
                else
445
411
                {
465
431
                        Refresh();
466
432
        }
467
433
 
468
 
        event.Skip();
469
434
}
470
435
 
471
436
void BasicGLPane::mouseWheelMoved(wxMouseEvent& event) 
481
446
 
482
447
        cameraMoveRate*=CAMERA_SCROLL_RATE;
483
448
        //Move by specified delta
484
 
        currentScene.getActiveCam()->forwardsDolly(cameraMoveRate);
 
449
        currentScene->getActiveCam()->forwardsDolly(cameraMoveRate);
485
450
 
486
451
        //if we are using a temporary camera, update that too
487
 
        if(currentScene.haveTempCam())
488
 
                currentScene.getTempCam()->forwardsDolly(cameraMoveRate);
 
452
        if(currentScene->haveTempCam())
 
453
                currentScene->getTempCam()->forwardsDolly(cameraMoveRate);
489
454
 
490
455
        haveCameraUpdates=true;
491
456
        Refresh();
492
 
        event.Skip();
493
457
}
494
458
 
495
459
void BasicGLPane::mouseReleased(wxMouseEvent& event) 
496
460
{
497
 
        if(currentScene.isInteractionLocked())
 
461
        if(currentScene->isInteractionLocked())
498
462
        {
499
463
                event.Skip();
500
464
                return;
513
477
                        applyingDevice=true;
514
478
 
515
479
 
516
 
                        currentScene.applyDevice((float)draggingStart.x/(float)w,
 
480
                        currentScene->applyDevice((float)draggingStart.x/(float)w,
517
481
                                                (float)draggingStart.y/(float)h,
518
482
                                                 p.x/(float)w,p.y/(float)h,
519
483
                                                 lastKeyFlags,lastMouseFlags,
523
487
 
524
488
 
525
489
                        selectionMode=false;
526
 
                        currentScene.setSelectionMode(selectionMode);
 
490
                        currentScene->setSelectionMode(selectionMode);
527
491
 
528
492
                        Refresh();
529
493
                }
532
496
        }
533
497
        
534
498
 
535
 
        if(currentScene.haveTempCam())
536
 
                currentScene.commitTempCam();
537
 
        currentScene.finaliseCam();
 
499
        if(currentScene->haveTempCam())
 
500
                currentScene->commitTempCam();
 
501
        currentScene->finaliseCam();
538
502
 
539
503
        haveCameraUpdates=true;
540
504
        dragging=false;
541
505
 
542
506
        Refresh();
543
 
        event.Skip();
544
507
        
545
508
}
546
509
 
558
521
                GetClientSize(&w, &h);
559
522
 
560
523
                applyingDevice=true;
561
 
                currentScene.applyDevice((float)draggingStart.x/(float)w,
 
524
                currentScene->applyDevice((float)draggingStart.x/(float)w,
562
525
                                        (float)draggingStart.y/(float)h,
563
526
                                         p.x/(float)w,p.y/(float)h,
564
527
                                         lastKeyFlags,lastMouseFlags,
565
528
                                         true);
566
529
 
567
530
                selectionMode=false;
568
 
                currentScene.setSelectionMode(selectionMode);
 
531
                currentScene->setSelectionMode(selectionMode);
569
532
                Refresh();
570
533
                applyingDevice=false;
571
534
 
576
539
 
577
540
        if(event.m_leftDown)
578
541
        {
579
 
                if(currentScene.haveTempCam())
 
542
                if(currentScene->haveTempCam())
580
543
                {
581
 
                        currentScene.commitTempCam();
 
544
                        currentScene->commitTempCam();
582
545
                        dragging=false;
583
546
                }
584
547
        }
585
 
        event.Skip();
586
548
}
587
549
 
588
550
void BasicGLPane::keyPressed(wxKeyEvent& event) 
600
562
            // needs to be control in apple as cmd-space open spotlight
601
563
                        unsigned int keyMask;
602
564
#ifdef __APPLE__
603
 
    #if wxCHECK_VERSION(2,9,0)
604
565
                        keyMask = (event.RawControlDown() ? 1 : 0);
605
 
    #else
606
 
                        keyMask = (event.ControlDown() ? 1 : 0);
607
 
    #endif
608
566
#else
609
567
                        keyMask = (event.CmdDown() ? 1 : 0);
610
568
#endif
666
624
                                }
667
625
 
668
626
                                
669
 
                                currentScene.ensureVisible(visibleDir);
670
 
                                parentStatusBar->SetStatusText(wxTRANS("Use shift/ctrl-space or double tap to alter reset axis"));
 
627
                                currentScene->ensureVisible(visibleDir);
 
628
                                parentStatusBar->SetStatusText(TRANS("Use shift/ctrl-space or double tap to alter reset axis"));
671
629
                                parentStatusBar->SetBackgroundColour(*wxCYAN)
672
630
                                        ;
673
631
                                parentStatusTimer->Start(statusDelay,wxTIMER_ONE_SHOT);
676
634
                        }
677
635
                }
678
636
                break;
 
637
                default:
 
638
                        event.Skip();
679
639
        }
680
 
        event.Skip();
681
640
}
682
641
 
683
642
void BasicGLPane::setGlClearColour(float r, float g, float b)
686
645
        ASSERT(g >= 0.0f && g <= 1.0f);
687
646
        ASSERT(b >= 0.0f && b <= 1.0f);
688
647
        
689
 
        currentScene.setBackgroundColour(r,g,b);
 
648
        currentScene->setBackgroundColour(r,g,b);
690
649
        
691
650
        Refresh();
692
651
}
707
666
                case WXK_SUBTRACT:
708
667
                {
709
668
                        //Do a backwards dolly by fixed amount
710
 
                        currentScene.getActiveCam()->forwardsDolly(cameraMoveRate);
711
 
                        if(currentScene.haveTempCam())
712
 
                                currentScene.getTempCam()->forwardsDolly(cameraMoveRate);
 
669
                        currentScene->getActiveCam()->forwardsDolly(cameraMoveRate);
 
670
                        if(currentScene->haveTempCam())
 
671
                                currentScene->getTempCam()->forwardsDolly(cameraMoveRate);
713
672
                        break;
714
673
                }
715
674
                case '+':
722
681
                        cameraMoveRate= -cameraMoveRate;
723
682
                        
724
683
                        //Do a forwards dolly by fixed amount
725
 
                        currentScene.getActiveCam()->forwardsDolly(cameraMoveRate);
726
 
                        if(currentScene.haveTempCam())
727
 
                                currentScene.getTempCam()->forwardsDolly(cameraMoveRate);
 
684
                        currentScene->getActiveCam()->forwardsDolly(cameraMoveRate);
 
685
                        if(currentScene->haveTempCam())
 
686
                                currentScene->getTempCam()->forwardsDolly(cameraMoveRate);
728
687
                        break;
729
688
                }
730
689
                default:
731
 
                ;
 
690
                        event.Skip();
732
691
        }
733
692
 
734
693
        Refresh();
735
 
        event.Skip();
736
 
}
737
 
 
738
 
void BasicGLPane::charEvent(wxKeyEvent& event) 
739
 
{
740
 
 
741
 
}
742
 
 
 
694
}
 
695
 
743
696
 
744
697
void BasicGLPane::resized(wxSizeEvent& evt)
745
698
{
746
 
#if !wxCHECK_VERSION(2,9,0)
747
 
        wxGLCanvas::OnSize(evt);
748
 
#endif
749
699
        prepare3DViewport(0,0,getWidth(),getHeight()); 
750
700
        wxClientDC *dc=new wxClientDC(this);
751
701
        Refresh();
764
714
        GLint dims[2]; 
765
715
        glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims); 
766
716
 
767
 
        //Ensure that the opengGL function didn't tell us porkies
768
 
        //but double check for the non-debug bulds next line
 
717
        //Ensure that the openGL function didn't tell us porkies
 
718
        //but double check for the non-debug builds next line
769
719
        ASSERT(dims[0] && dims[1]);
770
720
 
771
721
        //check for exceeding max viewport and we have some space
776
726
        glViewport( tlx, tly, brx-tlx, bry-tly);
777
727
 
778
728
        float aspect = (float)(brx-tlx)/(float)(bry-tly);
779
 
        currentScene.setWinSize(brx-tlx,bry-tly);
780
 
        currentScene.setAspect(aspect);
 
729
        currentScene->setWinSize(brx-tlx,bry-tly);
 
730
        currentScene->setAspect(aspect);
781
731
 
782
732
        //Set modelview and projection matrices to the identity
783
733
        // matrix
810
760
        if (!IsShown()) 
811
761
                return;
812
762
        
813
 
#if wxCHECK_VERSION(2,9,0)
814
763
        if(!context)
815
764
        {
816
765
                context = new wxGLContext(this);
817
766
                SetCurrent(*context);
818
767
        }
819
 
#else
820
 
        wxGLCanvas::SetCurrent();
821
 
#endif
 
768
 
822
769
        if(!paneInitialised)
823
770
        {
824
771
                paneInitialised=true;
826
773
        }
827
774
 
828
775
        wxPaintDC(this); 
829
 
        currentScene.draw();
 
776
        currentScene->draw();
830
777
        glFlush();
831
778
        SwapBuffers();
832
779
}
839
786
void BasicGLPane::updateClearColour()
840
787
{
841
788
        float rClear,gClear,bClear;
842
 
        currentScene.getBackgroundColour(rClear,gClear,bClear);
 
789
        currentScene->getBackgroundColour(rClear,gClear,bClear);
843
790
        //Can't set the opengl window without a proper context
844
791
        ASSERT(paneInitialised);
845
792
        setGlClearColour(rClear,gClear,bClear);
848
795
                                bClear,1.0f);
849
796
}
850
797
 
 
798
TRcontext *BasicGLPane::generateTileContext(unsigned int width, unsigned int height, unsigned char *imageBuffer, bool alpha) const
 
799
{
 
800
        int panelWidth,panelHeight;
 
801
        GetClientSize(&panelWidth,&panelHeight);
 
802
        
 
803
        //Create TR library tile context
 
804
        TRcontext *tr = trNew();
 
805
        //Tile size
 
806
        trTileSize(tr,panelWidth,panelHeight,0);
 
807
        //Set overall image size
 
808
        trImageSize(tr, width, height);
 
809
        //Set buffer for overall image
 
810
        if(alpha)
 
811
                trImageBuffer(tr, GL_RGBA, GL_UNSIGNED_BYTE, imageBuffer);
 
812
        else
 
813
                trImageBuffer(tr, GL_RGB, GL_UNSIGNED_BYTE, imageBuffer);
 
814
        //Set the row order for the image
 
815
        trRowOrder(tr, TR_BOTTOM_TO_TOP);
 
816
 
 
817
        return tr;
 
818
}
 
819
 
851
820
bool BasicGLPane::saveImage(unsigned int width, unsigned int height,
852
821
                const char *filename, bool showProgress, bool needPostPaint)
853
822
{
863
832
        //create new image
864
833
        wxImage *image = new wxImage(width,height);
865
834
 
 
835
 
 
836
        unsigned char *imageBuffer= (unsigned char*) malloc(3*(width)*height);
 
837
        if(!imageBuffer)
 
838
                return false;
 
839
 
 
840
 
 
841
        glLoadIdentity();
 
842
        const Camera *cm = currentScene->getActiveCam();
 
843
 
866
844
        //We cannot seem to draw outside the current viewport.
867
845
        //in a cross platform manner.
868
846
        //fall back to stitching the image together by hand
869
 
        int panelWidth,panelHeight;
870
 
        GetClientSize(&panelWidth,&panelHeight);
871
 
 
872
 
        unsigned char *imageBuffer= (unsigned char*) malloc(3*(width)*height);
873
 
 
874
 
        glLoadIdentity();
875
 
        //Create TR library tile context
876
 
        TRcontext *tr = trNew();
877
 
        const Camera *cm = currentScene.getActiveCam();
878
847
 
879
848
        //Initialise tile data
880
 
        {
881
 
        //Tile size
882
 
        trTileSize(tr,panelWidth,panelHeight,0);
883
 
        //Set overall image size
884
 
        trImageSize(tr, width, height);
885
 
        //Set buffer for overall image
886
 
        trImageBuffer(tr, GL_RGB, GL_UNSIGNED_BYTE, imageBuffer);
887
 
        //Set the row order for the image
888
 
        trRowOrder(tr, TR_BOTTOM_TO_TOP);
889
 
 
 
849
        TRcontext *tr; 
890
850
        //Inform the tiling system about our camera config
891
 
        BoundCube bc = currentScene.getBound();
892
 
        float farPlane = 1.5*bc.getMaxDistanceToBox(cm->getOrigin());
 
851
        float aspect=currentScene->getAspect();
 
852
        
 
853
        {
 
854
        float farPlane; 
 
855
        tr=generateTileContext(width,height, imageBuffer);
 
856
        BoundCube bc = currentScene->getBound();
 
857
        farPlane = 1.5*bc.getMaxDistanceToBox(cm->getOrigin());
893
858
        
894
859
        if(cm->getProjectionMode() == PROJECTION_MODE_PERSPECTIVE)
895
860
        {
896
861
                if(cm->type() == CAM_LOOKAT)
897
862
                {
898
 
                        const CameraLookAt *cl =(const CameraLookAt*) currentScene.getActiveCam();
899
 
                        trPerspective(tr,cl->getFOV()/2.0,currentScene.getAspect(),
 
863
                        const CameraLookAt *cl =(const CameraLookAt*) currentScene->getActiveCam();
 
864
                        trPerspective(tr,cl->getFOV()/2.0,currentScene->getAspect(),
900
865
                                                        cl->getNearPlane(),farPlane);
901
866
                }
902
867
                else
907
872
        }
908
873
        else
909
874
        {
910
 
                float aspect=currentScene.getAspect();
911
 
                float orthoScale=cm->getOrthoScale();
 
875
                float orthoScale = cm->getOrthoScale();
912
876
                trOrtho(tr,-orthoScale*aspect,orthoScale*aspect,
913
877
                                -orthoScale,orthoScale,0.0f,farPlane);
914
878
 
915
879
        }
916
880
        }
917
881
 
918
 
 
919
 
        //Obtain tile count
920
 
        unsigned int nRow,nCol;
 
882
        //Obtain tile count from the renderer & init progress
 
883
        //--
 
884
        unsigned int totalTiles;
 
885
        {
 
886
        unsigned int nRow,nCol,nPass;
921
887
        nRow=trGet(tr,TR_ROWS);
922
888
        nCol=trGet(tr,TR_COLUMNS);
 
889
        if(currentScene->hasOverlays())
 
890
                nPass = 2;
 
891
        else
 
892
                nPass=1;
 
893
 
 
894
        totalTiles=nRow*nCol*nPass;
 
895
        }
923
896
 
924
897
        wxProgressDialog *wxD=0;        
925
 
 
926
 
 
927
 
        //Only show progress for multiple tiles
928
 
        std::string tmpStr,tmpStrTwo;
929
 
        stream_cast(tmpStrTwo,nRow*nCol);
930
 
        
931
 
        showProgress=showProgress && ( nRow*nCol > 1);
 
898
        showProgress=showProgress && ( totalTiles > 1);
932
899
        if(showProgress)
933
900
        {
934
 
                wxD = new wxProgressDialog(wxTRANS("Image progress"), 
935
 
                                        wxTRANS("Rendering tiles..."), nRow*nCol);
 
901
                wxD = new wxProgressDialog(TRANS("Image progress"), 
 
902
                                        TRANS("Rendering tiles..."), totalTiles);
936
903
 
937
 
                wxD->Show();
938
904
        }
 
905
        //--
 
906
 
 
907
 
 
908
        //We have to do two passes. First we have to
 
909
        // do a 3D pass, then we have to separately
 
910
        // draw the overlays.
 
911
 
 
912
        // As we have 2 cameras, one for the normal scene
 
913
        // and one for the overlay, we build the images,
 
914
        // then merge the images, rather than trying to composite the entire scene in situ.
 
915
 
 
916
        //PASS 1:
 
917
        //--------------        
939
918
 
940
919
        //HACK: Flip the all but scene's light z coordinate
941
 
        // for some reason, the frustrum has an inversion
942
 
        // somwhere in the coordinate system, and I can't find it!
943
 
        // inverting the tile frustrum ends up with the depth test 
 
920
        // for some reason, the frustum has an inversion
 
921
        // somewhere in the coordinate system, and I can't find it!
 
922
        // inverting the tile frustum ends up with the depth test 
944
923
        // also inverting.
 
924
        const bool FLIP_LIGHT_HACK=true;
 
925
        //x,y,z and w axis.
 
926
        const bool IMPORTANT_AXIS[4]={true,false,true,false};
 
927
 
 
928
        //opengl light has 4 
945
929
        float oldLightPos[4];
946
 
        currentScene.getLightPos(oldLightPos);
947
 
        const int UNTRANS_AXIS=2;
948
 
        for(size_t ui=0;ui<3;ui++)
 
930
        if(FLIP_LIGHT_HACK)
949
931
        {
950
 
                if(ui == UNTRANS_AXIS)
951
 
                        continue;
952
 
 
953
 
                oldLightPos[ui]=-oldLightPos[ui];
954
 
        
 
932
                currentScene->getLightPos(oldLightPos);
 
933
                float newLightPos[4];
 
934
                for(size_t ui=0;ui<4;ui++)
 
935
                {
 
936
                        if(IMPORTANT_AXIS[ui])
 
937
                                newLightPos[ui]=oldLightPos[ui];
 
938
                        else
 
939
                                newLightPos[ui]=-oldLightPos[ui];
 
940
                
 
941
                }
 
942
                currentScene->setLightPos(newLightPos);
955
943
        }
956
 
        currentScene.setLightPos(oldLightPos);
957
944
        
 
945
        if(showProgress)
 
946
                wxD->Show();
958
947
 
959
 
        //Loop through the tiles
 
948
        //Loop through the tiles/ 
 
949
        // note that 2D overlays will not be drawn in this pass
960
950
        unsigned int thisTileNum=0;
961
951
        int haveMoreTiles=1;
962
952
        while(haveMoreTiles)
963
953
        {
964
 
                
965
 
                
966
954
                thisTileNum++;
967
 
                //tell user which image tile we are making from the total image
968
 
                stream_cast(tmpStr,thisTileNum);
969
 
                tmpStr = std::string(TRANS("Tile ")) + tmpStr + std::string(TRANS(" of ")) + tmpStrTwo + "...";
970
 
                //Update progress bar, if required
971
 
                if(showProgress)
972
 
                        wxD->Update(thisTileNum,wxStr(tmpStr));
973
955
 
974
956
                //Manually set the camera
975
957
                //--
983
965
        
984
966
                //Start the tile
985
967
                trBeginTile(tr);
986
 
                currentScene.draw(true);
 
968
                currentScene->draw(true);
987
969
 
988
970
                glPopMatrix();
989
971
 
 
972
                //ending the tile copies
 
973
                // data 
990
974
                haveMoreTiles=trEndTile(tr);
 
975
        
 
976
                if(showProgress)        
 
977
                        wxD->Update(thisTileNum);
991
978
 
992
979
        }
993
980
 
994
 
        //re-set light coordinates
995
 
        for(size_t ui=0;ui<3;ui++)
 
981
        if(FLIP_LIGHT_HACK)
996
982
        {
997
 
                if (ui == UNTRANS_AXIS)
998
 
                        continue;
999
 
                oldLightPos[ui]=-oldLightPos[ui];
 
983
                //re-set light coordinates
 
984
                currentScene->setLightPos(oldLightPos);
1000
985
        }
1001
 
        currentScene.setLightPos(oldLightPos);
1002
986
 
1003
 
        if(showProgress)
1004
 
                wxD->Destroy();
1005
987
        trDelete(tr);
1006
988
 
1007
989
        //Transfer pointer to image, which will perform free-ing of the buffer
1008
990
        image->SetData(imageBuffer);
1009
 
        
1010
991
        //HACK : Tiling function returns upside-down image. Fix in post-process
1011
992
        // argument is to set mirror axis such that x axis is unchanged
1012
993
        *image=image->Mirror(false);
1013
 
        
1014
 
        bool isOK=image->SaveFile(wxCStr(filename),wxBITMAP_TYPE_PNG);
1015
 
 
 
994
        //--------------        
 
995
 
 
996
        //PASS 2
 
997
        //--------------        
 
998
 
 
999
        if(currentScene->hasOverlays())
 
1000
        {
 
1001
                //alllocate RGBA (4-channel) image
 
1002
                imageBuffer= (unsigned char*) malloc(4*(width)*height);
 
1003
                if(!imageBuffer)
 
1004
                        return false;
 
1005
 
 
1006
 
 
1007
                tr=generateTileContext(width,height,imageBuffer,true);
 
1008
                trOrtho(tr,0.0f,aspect,
 
1009
                                0.0f,1.0f,-1.0f,1.0f);
 
1010
                
 
1011
 
 
1012
                haveMoreTiles=1;
 
1013
 
 
1014
        
 
1015
                float rClear,gClear,bClear;
 
1016
                currentScene->getBackgroundColour(rClear,gClear,bClear);
 
1017
                glClearColor( rClear, gClear, 
 
1018
                                        bClear,0.0f);
 
1019
 
 
1020
                //I am unclear why, but the faces are reversed
 
1021
                glDisable(GL_CULL_FACE);
 
1022
                while(haveMoreTiles)
 
1023
                {
 
1024
                        thisTileNum++;
 
1025
                        //Start the tile
 
1026
                        trBeginTile(tr);
 
1027
                        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
 
1028
                        currentScene->drawOverlays(true);
 
1029
                        //ending the tile copies
 
1030
                        // data 
 
1031
                        haveMoreTiles=trEndTile(tr);
 
1032
                
 
1033
                        if(showProgress)        
 
1034
                                wxD->Update(thisTileNum);
 
1035
                }       
 
1036
                glEnable(GL_CULL_FACE);
 
1037
                //restore the GL clear colour
 
1038
                updateClearColour();
 
1039
 
 
1040
                ///unpack the tile buffer into a wx image
 
1041
                wxImage imageOverlay(width,height);
 
1042
                imageOverlay.InitAlpha();
 
1043
 
 
1044
                //FIXME: HACK - using "blue screen" effect
 
1045
                //don't use background as mask colour.
 
1046
                // use depth buffer or gl alpha
 
1047
                const unsigned char mask[3] = {(unsigned char)rClear*255.0f,
 
1048
                                (unsigned char)gClear*255.0f,(unsigned char)bClear*255.0f};
 
1049
                copyRGBAtoWXImage(width,height,imageBuffer,imageOverlay,mask);
 
1050
 
 
1051
                free(imageBuffer);
 
1052
 
 
1053
                combineWxImage(*image,imageOverlay);
 
1054
        }
 
1055
 
 
1056
        //Free the tile buffer
 
1057
        trDelete(tr);
 
1058
        
 
1059
        //--------------        
 
1060
        bool isOK=image->SaveFile(filename,wxBITMAP_TYPE_PNG);
 
1061
        
 
1062
 
 
1063
        if(showProgress)
 
1064
                wxD->Destroy();
 
1065
        
1016
1066
        delete image;
1017
1067
 
1018
1068
        if (needPostPaint) {
1036
1086
        //
1037
1087
 
1038
1088
 
1039
 
        ASSERT(!currentScene.haveTempCam());
 
1089
        ASSERT(!currentScene->haveTempCam());
1040
1090
        std::string outFile;
1041
 
        wxProgressDialog *wxD = new wxProgressDialog(wxTRANS("Animation progress"), 
1042
 
                                        wxTRANS("Rendering sequence..."), nFrames,this,wxPD_CAN_ABORT|wxPD_APP_MODAL );
 
1091
        wxProgressDialog *wxD = new wxProgressDialog(TRANS("Animation progress"), 
 
1092
                                        TRANS("Rendering sequence..."), nFrames,this,wxPD_CAN_ABORT|wxPD_APP_MODAL );
1043
1093
 
1044
1094
        wxD->Show();
1045
1095
        std::string tmpStr,tmpStrTwo;
1046
1096
        stream_cast(tmpStrTwo,nFrames);
1047
1097
 
1048
 
        Camera *origCam=currentScene.getActiveCam()->clone();
 
1098
        Camera *origCam=currentScene->getActiveCam()->clone();
1049
1099
        
1050
1100
        
1051
1101
        for(unsigned int ui=0;ui<nFrames;ui++)
1063
1113
                Camera *modifiedCam;
1064
1114
                modifiedCam=origCam->clone();
1065
1115
                modifiedCam->move(angle,0);
1066
 
                currentScene.setActiveCam(modifiedCam);
 
1116
                currentScene->setActiveCam(modifiedCam);
1067
1117
 
1068
1118
                //Save the result
1069
1119
                outFile = string(stlStr(path))+ string("/") + 
1070
1120
                                string(stlStr(prefix))+digitStr+ string(".") + string(stlStr(ext));
1071
1121
                if(!saveImage(resX,resY,outFile.c_str(),false, false))
1072
1122
                {
1073
 
                        currentScene.setActiveCam(origCam);
 
1123
                        currentScene->setActiveCam(origCam);
1074
1124
                        return false;
1075
1125
                }
1076
1126
 
1078
1128
                stream_cast(tmpStr,ui+1);
1079
1129
                //Tell user which image from the animation we are saving
1080
1130
                tmpStr = std::string(TRANS("Saving Image ")) + tmpStr + std::string(TRANS(" of ")) + tmpStrTwo + "...";
1081
 
                if(!wxD->Update(ui,wxStr(tmpStr)))
 
1131
                if(!wxD->Update(ui,tmpStr))
1082
1132
                        break;
1083
1133
 
1084
1134
                Refresh();
1085
1135
        }
1086
1136
 
1087
 
        currentScene.setActiveCam(origCam);
 
1137
        currentScene->setActiveCam(origCam);
1088
1138
 
1089
1139
        //Discard the current temp. cam to return the scene back to normal
1090
 
        currentScene.discardTempCam();
 
1140
        currentScene->discardTempCam();
1091
1141
        wxD->Destroy();
1092
1142
        
1093
1143
        wxPaintEvent event;