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