1 /******************************************************************************** 2 * * 3 * O p e n G L V i e w e r W i d g e t * 4 * * 5 ********************************************************************************* 6 * Copyright (C) 1997,2005 by Jeroen van der Zijp. All Rights Reserved. * 7 ********************************************************************************* 8 * This library is free software; you can redistribute it and/or * 9 * modify it under the terms of the GNU Lesser General Public * 10 * License as published by the Free Software Foundation; either * 11 * version 2.1 of the License, or (at your option) any later version. * 12 * * 13 * This library is distributed in the hope that it will be useful, * 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 16 * Lesser General Public License for more details. * 17 * * 18 * You should have received a copy of the GNU Lesser General Public * 19 * License along with this library; if not, write to the Free Software * 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * 21 ********************************************************************************* 22 * $Id: FXGLViewer.h,v 1.73 2005/01/16 16:06:06 fox Exp $ * 23 ********************************************************************************/ 24 #ifndef FXGLVIEWER_H 25 #define FXGLVIEWER_H 26 27 #ifndef FXGLCANVAS_H 28 #include "FXGLCanvas.h" 29 #endif 30 31 namespace FX { 32 33 34 class FXDCPrint; 35 class FXGLObject; 36 class FXGLVisual; 37 38 39 // GL Viewer options 40 enum { 41 VIEWER_LIGHTING = 0x00008000, /// Lighting is on 42 VIEWER_FOG = 0x00010000, /// Fog mode on 43 VIEWER_DITHER = 0x00020000 /// Dithering 44 }; 45 46 47 /******************************* Viewer Structs *****************************/ 48 49 50 /// OpenGL Viewer Viewport 51 struct FXViewport { 52 FXint w,h; // Viewport dimensions 53 FXdouble left,right; // World box 54 FXdouble bottom,top; 55 FXdouble hither,yon; 56 }; 57 58 59 // OpenGL Light Source 60 struct FXAPI FXLight { 61 FXVec4f ambient; // Ambient light color 62 FXVec4f diffuse; // Diffuse light color 63 FXVec4f specular; // Specular light color 64 FXVec4f position; // Light position 65 FXVec3f direction; // Spot direction 66 FXfloat exponent; // Spotlight exponent 67 FXfloat cutoff; // Spotlight cutoff angle 68 FXfloat c_attn; // Constant attenuation factor 69 FXfloat l_attn; // Linear attenuation factor 70 FXfloat q_attn; // Quadratic attenuation factor 71 }; 72 73 74 // OpenGL Material Description 75 struct FXAPI FXMaterial { 76 FXVec4f ambient; // Ambient material color 77 FXVec4f diffuse; // Diffuse material color 78 FXVec4f specular; // Specular material color 79 FXVec4f emission; // Emissive material color 80 FXfloat shininess; // Specular shininess 81 }; 82 83 84 // Feedback buffer sort routine 85 typedef FXbool (*FXZSortFunc)(FXfloat*& buffer,FXint& used,FXint& size); 86 87 88 /******************************** Viewer Class ******************************/ 89 90 91 /// OpenGL viewer widget 92 class FXAPI FXGLViewer : public FXGLCanvas { 93 FXDECLARE(FXGLViewer) 94 friend class FXGLObject; 95 protected: 96 FXViewport wvt; // Window viewport transform 97 FXMat4f transform; // Current transformation matrix 98 FXMat4f itransform; // Inverse of current transformation matrix 99 FXuint projection; // Projection mode 100 FXQuatf rotation; // Viewer orientation 101 FXdouble fov; // Field of view 102 FXdouble zoom; // Zoom factor 103 FXVec3f center; // Model center 104 FXVec3f scale; // Model scale 105 FXdouble worldpx; // Pixel size in world 106 FXdouble modelpx; // Pixel size in model 107 FXint maxhits; // Maximum number of hits 108 FXdouble ax,ay; // Quick view->world coordinate mapping 109 FXdouble diameter; // Size of model diameter ( always > 0) 110 FXdouble distance; // Distance of PRP to target 111 FXVec4f background[2]; // Background colors 112 FXVec4f ambient; // Global ambient light 113 FXLight light; // Light source 114 FXMaterial material; // Base material properties 115 FXint dial[3]; // Dial positions 116 FXString help; // Status help 117 FXString tip; // Tooltip for background 118 FXGLObject *dropped; // Object being dropped on 119 FXGLObject *selection; // Current object 120 FXZSortFunc zsortfunc; // Routine to sort feedback buffer 121 FXGLObject *scene; // What we're looking at 122 FXbool doesturbo; // Doing turbo mode 123 FXbool turbomode; // Turbo mode 124 FXuchar mode; // Mode the widget is in 125 public: 126 127 // Common DND types 128 static FXDragType objectType; // GL Object type 129 130 protected: 131 132 // Mouse actions when in viewing window 133 enum { 134 HOVERING, // Hovering mouse w/o doing anything 135 PICKING, // Pick mode 136 ROTATING, // Rotating camera around target 137 POSTING, // Posting right-mouse menu 138 TRANSLATING, // Translating camera 139 ZOOMING, // Zooming 140 FOVING, // Change field-of-view 141 DRAGGING, // Dragging objects 142 TRUCKING, // Trucking camera 143 GYRATING, // Rotation of camera around eye 144 DO_LASSOSELECT, // Lasso select when mouse pressed 145 LASSOSELECT, // Anchor of lasso rectangle 146 DO_LASSOZOOM, // Zoom when mouse pressed 147 LASSOZOOM // Zoom rectangle 148 }; 149 150 protected: 151 FXGLViewer(); 152 void glsetup(); 153 virtual void updateProjection(); 154 virtual void updateTransform(); 155 FXVec3f spherePoint(FXint px,FXint py); 156 FXQuatf turn(FXint fx,FXint fy,FXint tx,FXint ty); 157 void drawWorld(FXViewport& wv); 158 void drawAnti(FXViewport& wv); 159 void drawLasso(FXint x0,FXint y0,FXint x1,FXint y1); 160 FXint selectHits(FXuint*& hits,FXint& nhits,FXint x,FXint y,FXint w,FXint h); 161 FXint renderFeedback(FXfloat *buffer,FXint x,FXint y,FXint w,FXint h,FXint maxbuffer); 162 void drawFeedback(FXDCPrint& pdc,const FXfloat* buffer,FXint used); 163 virtual FXGLObject* processHits(FXuint *pickbuffer,FXint nhits); 164 void setOp(FXuint o); 165 private: 166 FXGLViewer(const FXGLViewer&); 167 FXGLViewer &operator=(const FXGLViewer&); 168 void initialize(); 169 public: 170 171 // Events 172 long onPaint(FXObject*,FXSelector,void*); 173 long onEnter(FXObject*,FXSelector,void*); 174 long onLeave(FXObject*,FXSelector,void*); 175 long onMotion(FXObject*,FXSelector,void*); 176 long onMouseWheel(FXObject*,FXSelector,void*); 177 long onChanged(FXObject*,FXSelector,void*); 178 long onPick(FXObject*,FXSelector,void*); 179 long onClicked(FXObject*,FXSelector,void*); 180 long onDoubleClicked(FXObject*,FXSelector,void*); 181 long onTripleClicked(FXObject*,FXSelector,void*); 182 long onLassoed(FXObject*,FXSelector,void*); 183 long onSelected(FXObject*,FXSelector,void*); 184 long onDeselected(FXObject*,FXSelector,void*); 185 long onInserted(FXObject*,FXSelector,void*); 186 long onDeleted(FXObject*,FXSelector,void*); 187 long onLeftBtnPress(FXObject*,FXSelector,void*); 188 long onLeftBtnRelease(FXObject*,FXSelector,void*); 189 long onMiddleBtnPress(FXObject*,FXSelector,void*); 190 long onMiddleBtnRelease(FXObject*,FXSelector,void*); 191 long onRightBtnPress(FXObject*,FXSelector,void*); 192 long onRightBtnRelease(FXObject*,FXSelector,void*); 193 long onUngrabbed(FXObject*,FXSelector,void*); 194 long onKeyPress(FXObject*,FXSelector,void*); 195 long onKeyRelease(FXObject*,FXSelector,void*); 196 long onFocusIn(FXObject*,FXSelector,void*); 197 long onFocusOut(FXObject*,FXSelector,void*); 198 long onClipboardLost(FXObject*,FXSelector,void*); 199 long onClipboardGained(FXObject*,FXSelector,void*); 200 long onClipboardRequest(FXObject*,FXSelector,void*); 201 202 // Commands 203 long onCmdPerspective(FXObject*,FXSelector,void*); 204 long onUpdPerspective(FXObject*,FXSelector,void*); 205 long onCmdParallel(FXObject*,FXSelector,void*); 206 long onUpdParallel(FXObject*,FXSelector,void*); 207 long onCmdFront(FXObject*,FXSelector,void*); 208 long onUpdFront(FXObject*,FXSelector,void*); 209 long onCmdBack(FXObject*,FXSelector,void*); 210 long onUpdBack(FXObject*,FXSelector,void*); 211 long onCmdLeft(FXObject*,FXSelector,void*); 212 long onUpdLeft(FXObject*,FXSelector,void*); 213 long onCmdRight(FXObject*,FXSelector,void*); 214 long onUpdRight(FXObject*,FXSelector,void*); 215 long onCmdTop(FXObject*,FXSelector,void*); 216 long onUpdTop(FXObject*,FXSelector,void*); 217 long onCmdBottom(FXObject*,FXSelector,void*); 218 long onUpdBottom(FXObject*,FXSelector,void*); 219 long onCmdResetView(FXObject*,FXSelector,void*); 220 long onCmdFitView(FXObject*,FXSelector,void*); 221 long onDNDEnter(FXObject*,FXSelector,void*); 222 long onDNDLeave(FXObject*,FXSelector,void*); 223 long onDNDMotion(FXObject*,FXSelector,void*); 224 long onDNDDrop(FXObject*,FXSelector,void*); 225 long onTipTimer(FXObject*,FXSelector,void*); 226 long onCmdXYZDial(FXObject*,FXSelector,void*); 227 long onUpdXYZDial(FXObject*,FXSelector,void*); 228 long onCmdRollPitchYaw(FXObject*,FXSelector,void*); 229 long onUpdRollPitchYaw(FXObject*,FXSelector,void*); 230 long onCmdXYZScale(FXObject*,FXSelector,void*); 231 long onUpdXYZScale(FXObject*,FXSelector,void*); 232 long onUpdCurrent(FXObject*,FXSelector,void*); 233 long onCmdCutSel(FXObject*,FXSelector,void*); 234 long onCmdCopySel(FXObject*,FXSelector,void*); 235 long onCmdPasteSel(FXObject*,FXSelector,void*); 236 long onCmdDeleteSel(FXObject*,FXSelector,void*); 237 long onUpdDeleteSel(FXObject*,FXSelector,void*); 238 long onCmdBackColor(FXObject*,FXSelector,void*); 239 long onUpdBackColor(FXObject*,FXSelector,void*); 240 long onCmdGradientBackColor(FXObject*,FXSelector,void*); 241 long onUpdGradientBackColor(FXObject*,FXSelector,void*); 242 long onCmdAmbientColor(FXObject*,FXSelector,void*); 243 long onUpdAmbientColor(FXObject*,FXSelector,void*); 244 long onCmdLighting(FXObject*,FXSelector,void*); 245 long onUpdLighting(FXObject*,FXSelector,void*); 246 long onCmdFog(FXObject*,FXSelector,void*); 247 long onUpdFog(FXObject*,FXSelector,void*); 248 long onCmdDither(FXObject*,FXSelector,void*); 249 long onUpdDither(FXObject*,FXSelector,void*); 250 long onCmdFov(FXObject*,FXSelector,void*); 251 long onUpdFov(FXObject*,FXSelector,void*); 252 long onCmdZoom(FXObject*,FXSelector,void*); 253 long onUpdZoom(FXObject*,FXSelector,void*); 254 long onCmdLightAmbient(FXObject*,FXSelector,void*); 255 long onUpdLightAmbient(FXObject*,FXSelector,void*); 256 long onCmdLightDiffuse(FXObject*,FXSelector,void*); 257 long onUpdLightDiffuse(FXObject*,FXSelector,void*); 258 long onCmdLightSpecular(FXObject*,FXSelector,void*); 259 long onUpdLightSpecular(FXObject*,FXSelector,void*); 260 long onCmdTurbo(FXObject*,FXSelector,void*); 261 long onUpdTurbo(FXObject*,FXSelector,void*); 262 long onCmdPrintImage(FXObject*,FXSelector,void*); 263 long onCmdPrintVector(FXObject*,FXSelector,void*); 264 long onCmdLassoZoom(FXObject*,FXSelector,void*); 265 long onCmdLassoSelect(FXObject*,FXSelector,void*); 266 long onQueryHelp(FXObject*,FXSelector,void*); 267 long onQueryTip(FXObject*,FXSelector,void*); 268 virtual long onDefault(FXObject*,FXSelector,void*); 269 270 public: 271 272 // Projection modes 273 enum { 274 PARALLEL, // Parallel projection 275 PERSPECTIVE // Perspective projection 276 }; 277 278 // Messages 279 enum { 280 ID_PERSPECTIVE=FXGLCanvas::ID_LAST, 281 ID_PARALLEL, 282 ID_FRONT, 283 ID_BACK, 284 ID_LEFT, 285 ID_RIGHT, 286 ID_TOP, 287 ID_BOTTOM, 288 ID_RESETVIEW, 289 ID_FITVIEW, 290 ID_TOP_COLOR, 291 ID_BOTTOM_COLOR, 292 ID_BACK_COLOR, 293 ID_AMBIENT_COLOR, 294 ID_LIGHT_AMBIENT, 295 ID_LIGHT_DIFFUSE, 296 ID_LIGHT_SPECULAR, 297 ID_LIGHTING, 298 ID_TURBO, 299 ID_FOG, 300 ID_DITHER, 301 ID_SCALE_X, 302 ID_SCALE_Y, 303 ID_SCALE_Z, 304 ID_DIAL_X, 305 ID_DIAL_Y, 306 ID_DIAL_Z, 307 ID_ROLL, 308 ID_PITCH, 309 ID_YAW, 310 ID_FOV, 311 ID_ZOOM, 312 ID_CUT_SEL, 313 ID_COPY_SEL, 314 ID_PASTE_SEL, 315 ID_DELETE_SEL, 316 ID_PRINT_IMAGE, 317 ID_PRINT_VECTOR, 318 ID_LASSO_ZOOM, 319 ID_LASSO_SELECT, 320 ID_LAST 321 }; 322 323 public: 324 325 // Common DND type names 326 static const FXchar objectTypeName[]; 327 328 public: 329 330 /// Construct GL viewer widget 331 FXGLViewer(FXComposite* p,FXGLVisual *vis,FXObject* tgt=NULL,FXSelector sel=0,FXuint opts=0,FXint x=0,FXint y=0,FXint w=0,FXint h=0); 332 333 /// Construct GL viewer widget sharing display list with another GL viewer 334 FXGLViewer(FXComposite* p,FXGLVisual *vis,FXGLViewer* sharegroup,FXObject* tgt=NULL,FXSelector sel=0,FXuint opts=0,FXint x=0,FXint y=0,FXint w=0,FXint h=0); 335 336 /// Create all of the server-side resources for this window 337 virtual void create(); 338 339 /// Detach server-side resources 340 virtual void detach(); 341 342 /// Perform layout 343 virtual void layout(); 344 345 /// Return size of pixel in world coordinates worldPix()346 FXdouble worldPix() const { return worldpx; } 347 348 /// Return size of pixel in model coordinates modelPix()349 FXdouble modelPix() const { return modelpx; } 350 351 /// Return a NULL-terminated list of all objects in the given rectangle, or NULL 352 FXGLObject** lasso(FXint x1,FXint y1,FXint x2,FXint y2); 353 354 /// Return a NULL-terminated list of all objects in the given rectangle, or NULL 355 virtual FXGLObject** select(FXint x,FXint y,FXint w,FXint h); 356 357 /// Perform a pick operation, returning the object at the given x,y position, or NULL 358 virtual FXGLObject* pick(FXint x,FXint y); 359 360 /// Change the model bounding box; this adjusts the viewer 361 virtual FXbool setBounds(const FXRangef& box); 362 363 /// Fit viewer to the given bounding box 364 FXbool fitToBounds(const FXRangef& box); 365 366 /// Return the viewer's viewport 367 void getViewport(FXViewport& v) const; 368 369 /// Translate eye-coordinate to screen coordinate 370 void eyeToScreen(FXint& sx,FXint& sy,FXVec3f e); 371 372 /// Translate screen coordinate to eye coordinate at the given depth 373 FXVec3f screenToEye(FXint sx,FXint sy,FXfloat eyez=0.0); 374 375 /// Translate screen coordinate to eye coordinate at the target point depth 376 FXVec3f screenToTarget(FXint sx,FXint sy); 377 378 /// Translate world coordinate to eye coordinate 379 FXVec3f worldToEye(FXVec3f w); 380 381 /// Translate world coordinate to eye coordinate depth 382 FXfloat worldToEyeZ(FXVec3f w); 383 384 /// Translate eye coordinate to eye coordinate 385 FXVec3f eyeToWorld(FXVec3f e); 386 387 /// Calculate world coordinate vector from screen movement 388 FXVec3f worldVector(FXint fx,FXint fy,FXint tx,FXint ty); 389 390 /// Change default object material setting 391 void setMaterial(const FXMaterial &mtl); 392 393 /// Return default object material setting 394 void getMaterial(FXMaterial &mtl) const; 395 396 /// Change camera field of view angle (in degrees) 397 void setFieldOfView(FXdouble fv); 398 399 /// Return camera field of view angle getFieldOfView()400 FXdouble getFieldOfView() const { return fov; } 401 402 /// Change camera zoom factor 403 void setZoom(FXdouble zm); 404 405 /// Return camera zoom factor getZoom()406 FXdouble getZoom() const { return zoom; } 407 408 /// Change target point distance 409 void setDistance(FXdouble ed); 410 411 /// Return target point distance getDistance()412 FXdouble getDistance() const { return distance; } 413 414 /// Change unequal model scaling factors 415 void setScale(FXVec3f s); 416 417 /// Return current scaling factors getScale()418 const FXVec3f& getScale() const { return scale; } 419 420 /// Change camera orientation from quaternion 421 void setOrientation(FXQuatf rot); 422 423 /// Return current camera orientation quaternion getOrientation()424 const FXQuatf& getOrientation() const { return rotation; } 425 426 /// Change object center (tranlation) 427 void setCenter(FXVec3f cntr); 428 429 /// Return object center getCenter()430 const FXVec3f& getCenter() const { return center; } 431 432 /// Translate object center 433 void translate(FXVec3f vec); 434 435 /// Return boresight vector 436 FXbool getBoreVector(FXint sx,FXint sy,FXVec3f& point,FXVec3f& dir); 437 438 /// Return eyesight vector 439 FXVec3f getEyeVector() const; 440 441 /// Return eye position 442 FXVec3f getEyePosition() const; 443 444 /// Change help text 445 void setHelpText(const FXString& text); 446 447 /// Return help text getHelpText()448 const FXString& getHelpText() const { return help; } 449 450 /// Change tip text 451 void setTipText(const FXString& text); 452 453 /// Return tip text getTipText()454 const FXString& getTipText() const { return tip; } 455 456 /// Return the current transformation matrix getTransform()457 const FXMat4f& getTransform() const { return transform; } 458 459 /// Return the inverse of the current transformation matrix getInvTransform()460 const FXMat4f& getInvTransform() const { return itransform; } 461 462 /// Change the scene, i.e. the object being displayed. 463 void setScene(FXGLObject* sc); 464 465 /// Return the current scene object getScene()466 FXGLObject* getScene() const { return scene; } 467 468 /// Change selection 469 void setSelection(FXGLObject* sel); 470 471 /// Return selection getSelection()472 FXGLObject* getSelection() const { return selection; } 473 474 /// Change the projection mode, PERSPECTIVE or PARALLEL 475 void setProjection(FXuint proj); 476 477 /// Return the projection mode getProjection()478 FXuint getProjection() const { return projection; } 479 480 /// Change top or bottom or both background colors 481 void setBackgroundColor(const FXVec4f& clr,FXbool bottom=MAYBE); 482 483 /// Return top or bottom window background color. 484 const FXVec4f& getBackgroundColor(FXbool bottom=FALSE) const { return background[bottom]; } 485 486 /// Change global ambient light color 487 void setAmbientColor(const FXVec4f& clr); 488 489 /// Return global ambient light color getAmbientColor()490 const FXVec4f& getAmbientColor() const { return ambient; } 491 492 /** 493 * Read the pixels off the screen as array of FXColor; 494 * this array can be directly passed to fxsaveBMP and other image 495 * output routines. 496 */ 497 FXbool readPixels(FXColor*& buffer,FXint x,FXint y,FXint w,FXint h); 498 499 /** 500 * Read the feedback buffer containing the current scene, returning used 501 * and allocated size. 502 */ 503 FXbool readFeedback(FXfloat*& buffer,FXint& used,FXint& size,FXint x,FXint y,FXint w,FXint h); 504 505 /** 506 * Change hidden-surface feedback buffer sorting algorithm. 507 * This can be used for move/draw printed output depth sorting. 508 */ setZSortFunc(FXZSortFunc func)509 void setZSortFunc(FXZSortFunc func){ zsortfunc=func; } 510 511 /// Return hidden surface sorting function. getZSortFunc()512 FXZSortFunc getZSortFunc() const { return zsortfunc; } 513 514 /** 515 * Change the maximum hits, i.e. the maximum size of the pick buffer. 516 * When set to less than or equal to zero, picking is essentially turned off. 517 */ setMaxHits(FXint maxh)518 void setMaxHits(FXint maxh) { maxhits=maxh; } 519 520 /// Return maximum pickbuffer size getMaxHits()521 FXint getMaxHits() const { return maxhits; } 522 523 /** 524 * When drawing a GL object, if doesTurbo() is true, the object 525 * may choose to perform a reduced complexity drawing as the user is 526 * interactively manipulating; another update will be done later when 527 * the full complexity drawing can be performed again. 528 */ doesTurbo()529 FXbool doesTurbo() const { return doesturbo; } 530 531 /// Return turbo mode setting getTurboMode()532 FXbool getTurboMode() const { return turbomode; } 533 534 /// Set turbo mode 535 void setTurboMode(FXbool turbo=TRUE); 536 537 /// Return light source settings 538 void getLight(FXLight& lite) const; 539 540 /// Change light source settings 541 void setLight(const FXLight& lite); 542 543 /// Save viewer to a stream 544 virtual void save(FXStream& store) const; 545 546 /// Load viewer from a stream 547 virtual void load(FXStream& store); 548 549 /// Destructor 550 virtual ~FXGLViewer(); 551 }; 552 553 } 554 555 #endif 556 557