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