92
BasicGLPane::BasicGLPane(wxWindow* parent) :
93
#if wxCHECK_VERSION(2,9,0)
94
wxGLCanvas(parent, wxID_ANY, attribList)
96
wxGLCanvas(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, wxT("GLCanvas"),attribList)
91
BasicGLPane::BasicGLPane(wxWindow* parent) : wxGLCanvas(parent, wxID_ANY, attribList)
99
93
haveCameraUpdates=false;
100
94
applyingDevice=false;
122
114
bool BasicGLPane::displaySupported() const
124
#if wxCHECK_VERSION(2,9,0)
125
116
return IsDisplaySupported(attribList);
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.
135
119
void BasicGLPane::setSceneInteractionAllowed(bool enabled)
137
currentScene.lockInteraction(!enabled);
121
currentScene->lockInteraction(!enabled);
140
124
unsigned int BasicGLPane::selectionTest(const wxPoint &p,bool &shouldRedraw)
143
if(currentScene.isInteractionLocked())
127
if(currentScene->isInteractionLocked())
145
129
shouldRedraw=false;
161
145
gluPickMatrix(p.x, oldViewport[3]-p.y,5, 5, oldViewport);
162
146
glMatrixMode(GL_MODELVIEW);
164
int lastSelected = currentScene.getLastSelected();
165
int selectedObject=currentScene.glSelect();
148
int lastSelected = currentScene->getLastSelected();
149
int selectedObject=currentScene->glSelect();
167
151
//If the object selection hasn't changed, we don't need to redraw
168
152
//if it has changed, we should redraw
199
183
gluPickMatrix(p.x, oldViewport[3]-p.y,5, 5, oldViewport);
200
184
glMatrixMode(GL_MODELVIEW);
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);
205
189
//FIXME: Should be able to make this more efficient
206
190
shouldRedraw = lastHover!=(unsigned int)-1;
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);
212
196
//Restore the previous matirx
271
245
if(wxm.ShiftDown())
272
246
keyFlags|=FLAG_SHIFT;
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;
283
mouseFlags|= SELECT_BUTTON_LEFT;
285
mouseFlags|= SELECT_BUTTON_RIGHT;
287
mouseFlags|= SELECT_BUTTON_MIDDLE;
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
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);
391
currentScene.discardTempCam();
392
currentScene.setTempCam();
393
currentScene.getTempCam()->pivot(lrMove,udMove);
357
currentScene->discardTempCam();
358
currentScene->setTempCam();
359
currentScene->getTempCam()->pivot(lrMove,udMove);
396
currentScene.setTempCam();
397
currentScene.getTempCam()->move(lrMove,udMove);
362
currentScene->setTempCam();
363
currentScene->getTempCam()->move(lrMove,udMove);
400
currentScene.setTempCam();
401
currentScene.getTempCam()->roll(atan2(udMove,lrMove));
366
currentScene->setTempCam();
367
currentScene->getTempCam()->roll(atan2(udMove,lrMove));
482
447
cameraMoveRate*=CAMERA_SCROLL_RATE;
483
448
//Move by specified delta
484
currentScene.getActiveCam()->forwardsDolly(cameraMoveRate);
449
currentScene->getActiveCam()->forwardsDolly(cameraMoveRate);
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);
490
455
haveCameraUpdates=true;
495
459
void BasicGLPane::mouseReleased(wxMouseEvent& event)
497
if(currentScene.isInteractionLocked())
461
if(currentScene->isInteractionLocked())
558
521
GetClientSize(&w, &h);
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,
567
530
selectionMode=false;
568
currentScene.setSelectionMode(selectionMode);
531
currentScene->setSelectionMode(selectionMode);
570
533
applyingDevice=false;
722
681
cameraMoveRate= -cameraMoveRate;
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);
738
void BasicGLPane::charEvent(wxKeyEvent& event)
744
697
void BasicGLPane::resized(wxSizeEvent& evt)
746
#if !wxCHECK_VERSION(2,9,0)
747
wxGLCanvas::OnSize(evt);
749
699
prepare3DViewport(0,0,getWidth(),getHeight());
750
700
wxClientDC *dc=new wxClientDC(this);
798
TRcontext *BasicGLPane::generateTileContext(unsigned int width, unsigned int height, unsigned char *imageBuffer, bool alpha) const
800
int panelWidth,panelHeight;
801
GetClientSize(&panelWidth,&panelHeight);
803
//Create TR library tile context
804
TRcontext *tr = trNew();
806
trTileSize(tr,panelWidth,panelHeight,0);
807
//Set overall image size
808
trImageSize(tr, width, height);
809
//Set buffer for overall image
811
trImageBuffer(tr, GL_RGBA, GL_UNSIGNED_BYTE, imageBuffer);
813
trImageBuffer(tr, GL_RGB, GL_UNSIGNED_BYTE, imageBuffer);
814
//Set the row order for the image
815
trRowOrder(tr, TR_BOTTOM_TO_TOP);
851
820
bool BasicGLPane::saveImage(unsigned int width, unsigned int height,
852
821
const char *filename, bool showProgress, bool needPostPaint)
863
832
//create new image
864
833
wxImage *image = new wxImage(width,height);
836
unsigned char *imageBuffer= (unsigned char*) malloc(3*(width)*height);
842
const Camera *cm = currentScene->getActiveCam();
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);
872
unsigned char *imageBuffer= (unsigned char*) malloc(3*(width)*height);
875
//Create TR library tile context
876
TRcontext *tr = trNew();
877
const Camera *cm = currentScene.getActiveCam();
879
848
//Initialise tile data
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);
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();
855
tr=generateTileContext(width,height, imageBuffer);
856
BoundCube bc = currentScene->getBound();
857
farPlane = 1.5*bc.getMaxDistanceToBox(cm->getOrigin());
894
859
if(cm->getProjectionMode() == PROJECTION_MODE_PERSPECTIVE)
896
861
if(cm->type() == CAM_LOOKAT)
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);
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);
920
unsigned int nRow,nCol;
882
//Obtain tile count from the renderer & init progress
884
unsigned int totalTiles;
886
unsigned int nRow,nCol,nPass;
921
887
nRow=trGet(tr,TR_ROWS);
922
888
nCol=trGet(tr,TR_COLUMNS);
889
if(currentScene->hasOverlays())
894
totalTiles=nRow*nCol*nPass;
924
897
wxProgressDialog *wxD=0;
927
//Only show progress for multiple tiles
928
std::string tmpStr,tmpStrTwo;
929
stream_cast(tmpStrTwo,nRow*nCol);
931
showProgress=showProgress && ( nRow*nCol > 1);
898
showProgress=showProgress && ( totalTiles > 1);
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);
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.
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.
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;
926
const bool IMPORTANT_AXIS[4]={true,false,true,false};
945
929
float oldLightPos[4];
946
currentScene.getLightPos(oldLightPos);
947
const int UNTRANS_AXIS=2;
948
for(size_t ui=0;ui<3;ui++)
950
if(ui == UNTRANS_AXIS)
953
oldLightPos[ui]=-oldLightPos[ui];
932
currentScene->getLightPos(oldLightPos);
933
float newLightPos[4];
934
for(size_t ui=0;ui<4;ui++)
936
if(IMPORTANT_AXIS[ui])
937
newLightPos[ui]=oldLightPos[ui];
939
newLightPos[ui]=-oldLightPos[ui];
942
currentScene->setLightPos(newLightPos);
956
currentScene.setLightPos(oldLightPos);
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)
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
972
wxD->Update(thisTileNum,wxStr(tmpStr));
974
956
//Manually set the camera
986
currentScene.draw(true);
968
currentScene->draw(true);
972
//ending the tile copies
990
974
haveMoreTiles=trEndTile(tr);
977
wxD->Update(thisTileNum);
994
//re-set light coordinates
995
for(size_t ui=0;ui<3;ui++)
997
if (ui == UNTRANS_AXIS)
999
oldLightPos[ui]=-oldLightPos[ui];
983
//re-set light coordinates
984
currentScene->setLightPos(oldLightPos);
1001
currentScene.setLightPos(oldLightPos);
1007
989
//Transfer pointer to image, which will perform free-ing of the buffer
1008
990
image->SetData(imageBuffer);
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);
1014
bool isOK=image->SaveFile(wxCStr(filename),wxBITMAP_TYPE_PNG);
999
if(currentScene->hasOverlays())
1001
//alllocate RGBA (4-channel) image
1002
imageBuffer= (unsigned char*) malloc(4*(width)*height);
1007
tr=generateTileContext(width,height,imageBuffer,true);
1008
trOrtho(tr,0.0f,aspect,
1009
0.0f,1.0f,-1.0f,1.0f);
1015
float rClear,gClear,bClear;
1016
currentScene->getBackgroundColour(rClear,gClear,bClear);
1017
glClearColor( rClear, gClear,
1020
//I am unclear why, but the faces are reversed
1021
glDisable(GL_CULL_FACE);
1022
while(haveMoreTiles)
1027
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
1028
currentScene->drawOverlays(true);
1029
//ending the tile copies
1031
haveMoreTiles=trEndTile(tr);
1034
wxD->Update(thisTileNum);
1036
glEnable(GL_CULL_FACE);
1037
//restore the GL clear colour
1038
updateClearColour();
1040
///unpack the tile buffer into a wx image
1041
wxImage imageOverlay(width,height);
1042
imageOverlay.InitAlpha();
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);
1053
combineWxImage(*image,imageOverlay);
1056
//Free the tile buffer
1060
bool isOK=image->SaveFile(filename,wxBITMAP_TYPE_PNG);
1018
1068
if (needPostPaint) {
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 );
1045
1095
std::string tmpStr,tmpStrTwo;
1046
1096
stream_cast(tmpStrTwo,nFrames);
1048
Camera *origCam=currentScene.getActiveCam()->clone();
1098
Camera *origCam=currentScene->getActiveCam()->clone();
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);
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))
1073
currentScene.setActiveCam(origCam);
1123
currentScene->setActiveCam(origCam);
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))
1087
currentScene.setActiveCam(origCam);
1137
currentScene->setActiveCam(origCam);
1089
1139
//Discard the current temp. cam to return the scene back to normal
1090
currentScene.discardTempCam();
1140
currentScene->discardTempCam();
1091
1141
wxD->Destroy();
1093
1143
wxPaintEvent event;