Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

DisplayDevice.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr                                                                       
00003  *cr            (C) Copyright 1995-2019 The Board of Trustees of the           
00004  *cr                        University of Illinois                       
00005  *cr                         All Rights Reserved                        
00006  *cr                                                                   
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  * RCS INFORMATION:
00011  *
00012  *      $RCSfile: DisplayDevice.h,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.144 $      $Date: 2021/03/09 15:55:17 $
00015  *
00016  ***************************************************************************/
00017 #ifndef DISPLAYDEVICE_H
00018 #define DISPLAYDEVICE_H
00019 
00020 #include <stdio.h>
00021 #include <math.h>
00022 
00023 #include "Matrix4.h"
00024 #include "Stack.h"
00025 #include "ResizeArray.h"
00026 #include "utilities.h"
00027 
00028 class VMDApp;
00029 class VMDDisplayList;
00030 
00035 class DisplayDevice {
00036 public:
00037   VMDApp *vmdapp; 
00038 
00039 
00040 
00041 
00042 
00043   char *name; 
00044 
00046   enum DisplayEye { NOSTEREO, LEFTEYE, RIGHTEYE };
00047 
00049   enum Buttons { B_LEFT, B_MIDDLE, B_RIGHT, B2_LEFT, B2_MIDDLE, B2_RIGHT,
00050                  B_F1, B_F2, B_F3, B_F4,  B_F5,  B_F6,
00051                  B_F7, B_F8, B_F9, B_F10, B_F11, B_F12,
00052                  B_ESC, TOTAL_BUTTONS };
00053   
00055   enum EventCodes  { WIN_REDRAW, WIN_LEFT, WIN_MIDDLE, WIN_RIGHT,
00056                      WIN_WHEELUP, WIN_WHEELDOWN, WIN_MOUSEX, WIN_MOUSEY, 
00057                      WIN_KBD, 
00058                      WIN_KBD_ESCAPE,
00059                      WIN_KBD_UP, 
00060                      WIN_KBD_DOWN, 
00061                      WIN_KBD_LEFT, 
00062                      WIN_KBD_RIGHT, 
00063                      WIN_KBD_PAGE_UP, 
00064                      WIN_KBD_PAGE_DOWN, 
00065                      WIN_KBD_HOME, 
00066                      WIN_KBD_END, 
00067                      WIN_KBD_INSERT,
00068                      WIN_KBD_DELETE,
00069                      WIN_KBD_F1,  WIN_KBD_F2,  WIN_KBD_F3,  WIN_KBD_F4,
00070                      WIN_KBD_F5,  WIN_KBD_F6,  WIN_KBD_F7,  WIN_KBD_F8,
00071                      WIN_KBD_F9,  WIN_KBD_F10, WIN_KBD_F11, WIN_KBD_F12,
00072                      WIN_NOEVENT };
00073 
00075   enum CursorCodes { NORMAL_CURSOR, TRANS_CURSOR, SCALE_CURSOR, 
00076                      PICK_CURSOR, WAIT_CURSOR };
00077 
00079   int needRedraw(void) const { return _needRedraw; }
00080   int _needRedraw; 
00081 
00082   int num_display_processes;   
00083   int renderer_process;        
00084 
00086   virtual int get_num_processes()   { return num_display_processes; } 
00087   virtual int is_renderer_process() { return renderer_process; }
00088  
00089 protected:
00091 
00092 
00093   int aaAvailable, cueingAvailable, cullingAvailable;
00094   int aaEnabled,   cueingEnabled,   cullingEnabled;
00095   int aoEnabled,   shadowEnabled,   dofEnabled;
00096   int aaPrevious;
00098 
00100   int my_depth_sort;
00101 
00103   //displays.
00104   const float *colorData;
00105   virtual void do_use_colors() {}
00106 
00108   enum CueMode { CUE_LINEAR, CUE_EXP, CUE_EXP2, NUM_CUE_MODES };
00109   CueMode cueMode;              
00110   float cueStart, cueEnd;       
00111   float cueDensity;             
00112 
00114   enum ShadowMode { SHADOWS_OFF, SHADOWS_ON };
00115 
00116   // ambient occlusion
00117   float aoAmbient;              
00118   float aoDirect;               
00119 
00120   // depth of field
00121   float dofFNumber;             
00122   float dofFocalDist;           
00123 
00124 public:
00126   enum Projection {PERSPECTIVE, ORTHOGRAPHIC, NUM_PROJECTIONS};
00127   Projection projection() const { return my_projection; }
00128 
00130   long xOrig, yOrig, xSize, ySize;
00131 
00132 protected:
00134   Stack<Matrix4> transMat;
00135 
00137   int backgroundmode; 
00138 
00140 
00141   int lineStyle, lineWidth;
00142   int sphereRes, sphereMode;
00143   int cylinderRes;
00145 
00146 
00147   //
00148   // eye position, clipping planes, and viewing geometry data
00149   //
00150   float eyePos[3];              
00151   DisplayEye whichEye;          
00152   float nearClip, farClip;      
00153 
00154   float vSize;                  
00155   float zDist;                  
00156 
00157   float Aspect;                 
00158 
00159 
00160 
00161 
00162 
00164 
00165   float cpUp, cpDown, cpLeft, cpRight;  
00167 
00168 
00169   // stereo display data
00170   int inStereo;                 
00171   int stereoSwap;               
00172   int stereoModes;              
00173   const char **stereoNames;     
00174 
00175   // display list caching data
00176   int cacheMode;                
00177   int cacheModes;               
00178   const char **cacheNames;      
00179 
00180   // rendering mode data
00181   int renderMode;               
00182   int renderModes;              
00183   const char **renderNames;     
00184 
00185   // display camera/eye parameters
00186   float eyeSep;                 
00187   float eyeDist;                
00188   float eyeDir[3];              
00189   float upDir[3];               
00190   float eyeSepDir[3];           
00191 
00192 
00193 public:  
00195   virtual int do_define_light(int, float *, float *) { return TRUE; } 
00196   virtual int do_activate_light(int, int) { return TRUE; } 
00197 
00198 #if 0
00199   // XXX need to implement advanced lights still
00200 #endif
00201 
00203   void use_colors(const float *c) {
00204     colorData = c;
00205     do_use_colors();
00206   }
00207 
00208 protected:
00209   int mouseX;                   
00210   int mouseY;                   
00211 
00216   void calc_frustum(void);
00217 
00222   void calc_eyedir(void);
00223 
00227   virtual void do_resize_window(int w, int h);
00228   virtual void do_reposition_window(int xpos, int ypos) {}
00229 
00231   int screenX, screenY;
00232 
00236   void find_pbc_images(const VMDDisplayList *, ResizeArray<Matrix4> &);
00237 
00241   void find_pbc_cells(const VMDDisplayList *, ResizeArray<int> &);
00242 
00246   void find_instance_images(const VMDDisplayList *, ResizeArray<Matrix4> &);
00247 
00248 public:
00249   DisplayDevice(const char *);
00250   virtual ~DisplayDevice(void);
00251   
00253   DisplayDevice& operator=(DisplayDevice &);
00254 
00257   virtual int init(int argc, char **argv, VMDApp *app, int *size, int *loc) {
00258     if (size != NULL)
00259       resize_window(size[0], size[1]);
00260 
00261     vmdapp=app; // set VMDApp ptr to allow DisplayDevice control over use of
00262                 // GPU memory resources during ray tracing, etc.
00263 
00264     return TRUE;
00265   }
00266 
00269   virtual int supports_gui() { return FALSE; }
00270 
00271 
00272   //
00273   // event handling routines
00274   //
00275 
00281   virtual void queue_events(void);
00282 
00289   virtual int read_event(long &, long &);
00290 
00291   // get the current state of the device's pointer (i.e. cursor if it has one)
00292   virtual int x(void); 
00293   virtual int y(void); 
00294 
00296   enum { 
00297     SHIFT = 1, 
00298     CONTROL = 2, 
00299     ALT = 4, 
00300     AUX = 8
00301   }; 
00302 
00303   virtual int shift_state(void); 
00304 
00309   virtual int spaceball(int *, int *, int *, int *, int *, int *, int *) { return 0; }
00310 
00315   virtual void set_cursor(int);
00316 
00317 private:
00318   Projection my_projection;     
00319   static const char *projNames[NUM_PROJECTIONS];
00320   static const char *cueModeNames[NUM_CUE_MODES];
00321 
00322 public:
00324 
00325   float aspect(void) { return Aspect; }
00326   float near_clip(void) const { return nearClip; }
00327   float far_clip(void) const { return farClip; }
00328   float clip_width(void) const { return (farClip - nearClip); }
00329   float addto_near_clip(float ac) { return set_near_clip(nearClip + ac); }
00330   float addto_far_clip(float ac) { return set_far_clip(farClip + ac); }
00331   float set_near_clip(float nc) {
00332     // near clip plane must be > 0.0, and less than far clip plane
00333     if (nc < farClip && nc > 0.0) {
00334       nearClip = nc;
00335       calc_frustum();
00336       _needRedraw = 1;
00337     } 
00338     return nearClip;
00339   }
00340 
00341   float set_far_clip(float fc) {
00342     if(fc > nearClip) {
00343       farClip = fc;
00344       _needRedraw = 1;
00345     }
00346     return farClip;
00347   }
00349 
00350 
00352 
00353 
00354   // turn on hardware depth-cueing
00355   virtual void cueing_on(void) {
00356     if (cueingAvailable && !cueingEnabled) {
00357       cueingEnabled = TRUE;
00358       _needRedraw = 1;
00359     }
00360   }
00361 
00362   // turn off hardware depth-cueing
00363   virtual void cueing_off(void) {
00364     if (cueingAvailable && cueingEnabled) {
00365       cueingEnabled = FALSE;
00366       _needRedraw = 1;
00367     }
00368   }
00369 
00370   int cueing_available(void) { return cueingAvailable; }
00371   int cueing_enabled(void) { return cueingEnabled; }
00372 
00373   const char *get_cue_mode() const { return cueModeNames[cueMode]; }
00374   int num_cue_modes() const { return NUM_CUE_MODES; }
00375   const char *cue_mode_name(int i) const {
00376     if (i < 0 || i >= NUM_CUE_MODES) return NULL;
00377     return cueModeNames[i];
00378   }
00379   int set_cue_mode(const char *mode) { 
00380     for (int i=0; i<NUM_CUE_MODES; i++) {
00381       if (!strupcmp(mode, cueModeNames[i])) {
00382         cueMode = (CueMode)i;
00383         _needRedraw = 1;
00384         return TRUE;
00385       }
00386     }
00387     return FALSE; // no match
00388   }
00389 
00390   float get_cue_start() const { return cueStart; }
00391   float set_cue_start(float s) { 
00392     if (s < cueEnd && s >= 0.0) { 
00393       cueStart = s; 
00394       _needRedraw = 1;
00395       return TRUE;
00396     } 
00397     return FALSE;
00398   }   
00399 
00400   float get_cue_end() const { return cueEnd; }
00401   float set_cue_end(float e) { 
00402     if (e > cueStart) { 
00403       cueEnd = e; 
00404       _needRedraw = 1;
00405       return TRUE;
00406     } 
00407     return FALSE;
00408   }   
00409   
00410   float get_cue_density() const { return cueDensity; }
00411   int set_cue_density(float d) {
00412     // XXX check for legal value here
00413     cueDensity = d;
00414     _needRedraw = 1;
00415     return TRUE;
00416   }
00418 
00419 
00421 
00422   virtual void aa_on(void);
00423   virtual void aa_off(void);
00424   int aa_available(void) { return aaAvailable; }
00425   int aa_enabled(void) { return aaEnabled; }
00427 
00428 
00430 
00431   virtual void culling_on(void);
00432   virtual void culling_off(void);
00433   int culling_available(void) { return cullingAvailable; }
00434   int culling_enabled(void) { return cullingEnabled; }
00436 
00437 
00439 
00440   int set_shadow_mode(int onoff) {
00441     if (onoff)
00442       shadowEnabled=1;
00443     else
00444       shadowEnabled=0;
00445     _needRedraw = 1;
00446     return TRUE;
00447   }  
00448   int shadows_enabled(void) { return shadowEnabled; }
00450 
00451 
00453 
00454   int set_ao_mode(int onoff) {
00455     if (onoff)
00456       aoEnabled=1;
00457     else
00458       aoEnabled=0;
00459     _needRedraw = 1;
00460     return TRUE;
00461   }  
00462   int ao_enabled(void) { return aoEnabled; }
00463 
00464   float get_ao_ambient() const { return aoAmbient; }
00465   int set_ao_ambient(float a) {
00466     aoAmbient = a;
00467     _needRedraw = 1;
00468     return TRUE;
00469   }
00470 
00471   float get_ao_direct() const { return aoDirect; }
00472   int set_ao_direct(float d) {
00473     aoDirect = d;
00474     _needRedraw = 1;
00475     return TRUE;
00476   }
00478 
00479 
00481 
00482   int set_dof_mode(int onoff) {
00483     if (onoff)
00484       dofEnabled=1;
00485     else
00486       dofEnabled=0;
00487     _needRedraw = 1;
00488     return TRUE;
00489   }  
00490   int dof_enabled(void) { return dofEnabled; }
00491 
00492   float get_dof_fnumber() const { return dofFNumber; }
00493   int set_dof_fnumber(float f) {
00494     dofFNumber = f;
00495     _needRedraw = 1;
00496     return TRUE;
00497   }
00498 
00499   float get_dof_focal_dist() const { return dofFocalDist; }
00500   int set_dof_focal_dist(float d) {
00501     dofFocalDist = d;
00502     _needRedraw = 1;
00503     return TRUE;
00504   }
00506 
00507 
00508   //
00509   // camera and view frustum parameters 
00510   //
00511 
00513   float distance_to_screen(void) { return zDist; }
00514   void distance_to_screen(float zd) {
00515     zDist = zd;
00516     calc_frustum();
00517     _needRedraw = 1;
00518   }
00519   
00521   float screen_height(void) { return vSize; }
00522   void screen_height(float vs) {
00523     if(vs > 0.0) {
00524       vSize = vs;
00525       calc_frustum();
00526       _needRedraw = 1;
00527     }
00528   }
00529 
00531   void set_screen_pos(float vsize, float zdist, float asp) {
00532     Aspect = asp;  vSize = vsize;  zDist = zdist;
00533     calc_frustum();    
00534   }
00535   
00537   void set_screen_pos(float vs, float zd) { set_screen_pos(vs, zd, aspect()); }
00538   
00540   void set_screen_pos(float asp) { set_screen_pos(vSize, zDist, asp); }
00541   
00543   void set_screen_pos(void) { set_screen_pos(vSize, zDist); }
00544 
00546   void resize_window(int w, int h) {
00547     if (w > 0 && h > 0) {
00548       do_resize_window(w, h);
00549     }
00550   }
00552   void reposition_window(int xpos, int ypos) {
00553     if (xpos >= 0 && xpos < screenX && ypos >= 0 && ypos < screenY) {
00554       do_reposition_window(xpos, -1+screenY-ypos);
00555     }
00556   } 
00557 #if 0
00558   // XXX This doesn't work...
00559   void window_position(int *xpos, int *ypos) {
00560     *xpos = xOrig;
00561     //*ypos = screenY - 1 - yOrig;
00562     *ypos = yOrig + screenY - 1;
00563   }
00564 #endif
00565 
00566   //
00567   // routines to deal with stereo display
00568   //
00569   
00571   virtual void set_stereo_mode(int = 0);
00572 
00574   int stereo_mode(void) { return inStereo; }
00575 
00577   void set_stereo_swap(int onoff) { 
00578      stereoSwap = (!(onoff == 0)); 
00579     _needRedraw = 1;
00580   }
00581 
00583   int stereo_swap(void) { return stereoSwap; };
00584  
00586   virtual int forced_stereo_draws(void) { return 0; }
00587  
00589   int num_stereo_modes(void) { return stereoModes; }
00590   
00592   const char *stereo_name(int n) {
00593     const char *retval = stereoNames[0];
00594     if(n >= 0 && n < stereoModes)
00595       retval = stereoNames[n];
00596     return retval;
00597   }
00598 
00599   //
00600   // routines to deal with special rendering modes/features
00601   //
00602   
00604   virtual void set_cache_mode(int = 0);
00605 
00607   int cache_mode(void) { return cacheMode; }
00608 
00610   int num_cache_modes(void) { return cacheModes; }
00611   
00613   const char *cache_name(int n) {
00614     const char *retval = cacheNames[0];
00615     if(n >= 0 && n < cacheModes)
00616       retval = cacheNames[n];
00617     return retval;
00618   }
00619   
00620 
00622   virtual void set_render_mode(int = 0);
00623 
00625   int render_mode(void) { return renderMode; }
00626   
00628   int num_render_modes(void) { return renderModes; }
00629   
00631   const char *render_name(int n) {
00632     const char *retval = renderNames[0];
00633     if(n >= 0 && n < renderModes)
00634       retval = renderNames[n];
00635     return retval;
00636   }
00637 
00638 
00640   int set_eye_defaults(void);
00641 
00643   int set_eye_pos(float * pos) {
00644     if (!pos) return FALSE;
00645     vec_copy(&eyePos[0], pos); 
00646     _needRedraw = 1;
00647     return TRUE; 
00648   }
00649 
00651   int get_eye_pos(float * pos) {
00652     if (!pos) return FALSE;
00653     vec_copy(pos, &eyePos[0]); 
00654     return TRUE; 
00655   }
00656  
00658   int set_eye_dir(float * dir) {
00659     if (!dir) return FALSE;
00660     vec_copy(&eyeDir[0], dir); 
00661     _needRedraw = 1;
00662     return TRUE; 
00663   }
00664 
00666   int get_eye_dir(float * dir) {
00667     if (!dir) return FALSE;
00668     vec_copy(dir, &eyeDir[0]); 
00669     return TRUE; 
00670   }
00671  
00673   int set_eye_up(float *updir) {
00674     if (!updir) return FALSE;
00675     vec_copy(&upDir[0], updir); 
00676     calc_eyedir(); // recalculate related eye parameters
00677     _needRedraw = 1;
00678     return TRUE; 
00679   }
00680 
00682   int get_eye_up(float *updir) {
00683     if (!updir) return FALSE;
00684     vec_copy(updir, &upDir[0]); 
00685     return TRUE; 
00686   }
00687 
00689   float eye_dist(void) const { return eyeDist; }
00690 
00693   int set_eye_dist(float flen) {
00694     if (!eyeDist) return FALSE; // XXX is this possible?
00695     float fl = flen/eyeDist;
00696     for (int i=0; i<3; i++) eyeDir[i] *= fl;
00697     eyeDist = flen; 
00698     calc_eyedir(); // XXX should really be called calc_eyesep 
00699     _needRedraw = 1;
00700     return TRUE;
00701   }
00702    
00704   float eyesep(void) const { return eyeSep; }
00705 
00707   float set_eyesep(float newsep) {
00708     if(newsep >= 0.0) {
00709       eyeSep = newsep;
00710       calc_eyedir();
00711     }
00712     _needRedraw = 1;
00713     return eyeSep;
00714   }
00715 
00717   void right_eye_dir(float& x, float& y, float& z) const {
00718     x = eyeSepDir[0];  y = eyeSepDir[1];  z = eyeSepDir[2];
00719   }  
00720 
00722   int num_projections() const { return NUM_PROJECTIONS; }
00723   const char *projection_name(int i) const {
00724     if (i < 0 || i >= NUM_PROJECTIONS) return NULL;
00725     return projNames[i];
00726   }
00727   const char *get_projection() const { return projNames[my_projection]; }
00728   int set_projection(const char *proj) {
00729     if (!proj) return FALSE;
00730     for (int i=0; i<NUM_PROJECTIONS; i++) {
00731       if (!strupcmp(proj, projNames[i])) {
00732         my_projection = (Projection)i;
00733         _needRedraw = 1;
00734         return TRUE;
00735       }
00736     }
00737     return FALSE;
00738   }
00739 
00740   //
00741   // virtual routines to find characteristics of display itself
00742   //
00743 
00746   virtual void abs_screen_loc_3D(float *, float *);
00747 
00749   virtual void abs_screen_loc_2D(float *, float *);
00750 
00752   virtual void rel_screen_pos(float &x, float &y) {
00753     x = (x - (float)xOrig) / ((float)xSize);
00754     y = (y - (float)yOrig) / ((float)ySize);
00755   }
00756 
00758   void abs_screen_pos(float &x, float &y) {
00759     x = x * (float)xSize + (float)xOrig;
00760     y = y * (float)ySize + (float)yOrig;
00761   }
00762 
00763   // Given a 3D point (pos A),
00764   // and a 2D rel screen pos point (for pos B), computes the 3D point
00765   // which goes with the second 2D point at pos B.  Result returned in 3rd arg.
00766   virtual void find_3D_from_2D(const float *, const float *, float *) {}
00767 
00768 
00769   //
00770   // virtual routines to affect the device's transformation matrix
00771   //
00772   virtual void loadmatrix(const Matrix4 &); 
00773   virtual void multmatrix(const Matrix4 &); 
00774 
00775 
00776   //
00777   // set the background colors
00778   //
00779   void set_background_mode(int newmode) { backgroundmode = newmode; } 
00780   int background_mode(void) { return backgroundmode; } 
00781   virtual void set_background(const float *) {} 
00782   virtual void set_backgradient(const float *, const float *) {} 
00783 
00784  
00785   //
00786   // virtual routines for preparing to draw, drawing, and finishing drawing
00787   //
00788   virtual int prepare3D(int = TRUE);    
00789   virtual int prepareOpaque(void) { return 1; } 
00790   virtual int prepareTrans(void){ return 0; }   
00791   virtual void clear(void);             
00792   virtual void left(void);              
00793   virtual void right(void);             
00794   virtual void normal(void);            
00795   virtual void update(int = TRUE);      
00796   virtual void reshape(void);           
00797 
00799   virtual unsigned char * readpixels_rgb3u(int &x, int &y);
00800 
00802   virtual unsigned char * readpixels_rgba4u(int &x, int &y);
00803 
00805   virtual int drawpixels_rgba4u(unsigned char *rgba, int &x, int &y) { return -1; };
00806   
00807   
00809   virtual void render(const VMDDisplayList *) { _needRedraw = 0; } 
00810                                           
00811   virtual void render_done() {}
00812   
00813   // pick objects based on given list of draw commands.
00814   // arguments are dimension of picking (2 or 3), position of pointer,
00815   // draw command list, and returned distance from object to eye position.
00816   // Returns ID code ('tag') for item closest to pointer, or (-1) if no pick.
00817   // If an object is picked, the eye distance argument is set to the distance
00818   // from the display's eye position to the object (after its position has been
00819   // found from the transformation matrix).  If the value of the argument when
00820   // 'pick' is called is <= 0, a pick will be generated if any item is near the
00821   // pointer.  If the value of the argument is > 0, a pick will be generated
00822   // only if an item is closer to the eye position than the value of the
00823   // argument.
00824   // For 2D picking, coordinates are relative position in window from
00825   //    lower-left corner (both in range 0 ... 1)
00826   // For 3D picking, coordinates are the world coords of the pointer.  They
00827   //    are the coords of the pointer after its transformation matrix has been
00828   //    applied, and these coordinates are compared to the coords of the objects
00829   //    when their transformation matrices are applied.
00830   // The window_size argument tells pick how close the picked item must be.
00831   virtual int pick(int, const float *, const VMDDisplayList *, float &, int *,
00832                    float window_size); 
00833 
00834 };
00835 
00836 #endif
00837 

Generated on Fri Nov 8 02:44:29 2024 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002