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

DisplayDevice.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr                                                                       
00003  *cr            (C) Copyright 1995-2011 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.134 $      $Date: 2012/03/13 18:41:55 $
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 
00037 public:
00038   char *name; 
00039 
00041   enum DisplayEye { NOSTEREO, LEFTEYE, RIGHTEYE };
00042 
00044   enum Buttons { B_LEFT, B_MIDDLE, B_RIGHT, B2_LEFT, B2_MIDDLE, B2_RIGHT,
00045                  B_F1, B_F2, B_F3, B_F4,  B_F5,  B_F6,
00046                  B_F7, B_F8, B_F9, B_F10, B_F11, B_F12,
00047                  B_ESC, TOTAL_BUTTONS };
00048   
00050   enum EventCodes  { WIN_REDRAW, WIN_LEFT, WIN_MIDDLE, WIN_RIGHT,
00051                      WIN_WHEELUP, WIN_WHEELDOWN, WIN_MOUSEX, WIN_MOUSEY, 
00052                      WIN_KBD, 
00053                      WIN_KBD_ESCAPE,
00054                      WIN_KBD_UP, 
00055                      WIN_KBD_DOWN, 
00056                      WIN_KBD_LEFT, 
00057                      WIN_KBD_RIGHT, 
00058                      WIN_KBD_PAGE_UP, 
00059                      WIN_KBD_PAGE_DOWN, 
00060                      WIN_KBD_HOME, 
00061                      WIN_KBD_END, 
00062                      WIN_KBD_INSERT,
00063                      WIN_KBD_DELETE,
00064                      WIN_KBD_F1,  WIN_KBD_F2,  WIN_KBD_F3,  WIN_KBD_F4,
00065                      WIN_KBD_F5,  WIN_KBD_F6,  WIN_KBD_F7,  WIN_KBD_F8,
00066                      WIN_KBD_F9,  WIN_KBD_F10, WIN_KBD_F11, WIN_KBD_F12,
00067                      WIN_NOEVENT };
00068 
00070   enum CursorCodes { NORMAL_CURSOR, TRANS_CURSOR, SCALE_CURSOR, 
00071                      PICK_CURSOR, WAIT_CURSOR };
00072 
00074   int needRedraw(void) const { return _needRedraw; }
00075   int _needRedraw; 
00076 
00077   int num_display_processes;   
00078   int renderer_process;        
00079 
00081   virtual int get_num_processes()   { return num_display_processes; } 
00082   virtual int is_renderer_process() { return renderer_process; }
00083  
00084 protected:
00086 
00087   int aaAvailable, cueingAvailable, cullingAvailable;
00088   int aaEnabled,   cueingEnabled,   cullingEnabled;
00089   int aoEnabled,   shadowEnabled;
00090   int aaPrevious;
00092 
00094   int my_depth_sort;
00095 
00097   //displays.
00098   const float *colorData;
00099   virtual void do_use_colors() {}
00100 
00102   enum CueMode { CUE_LINEAR, CUE_EXP, CUE_EXP2, NUM_CUE_MODES };
00103   CueMode cueMode;              
00104   float cueStart, cueEnd;       
00105   float cueDensity;             
00106 
00108   enum ShadowMode { SHADOWS_OFF, SHADOWS_ON };
00109 
00110   // ambient occlusion
00111   float aoAmbient;              
00112   float aoDirect;               
00113 
00114 public:
00116   enum Projection {PERSPECTIVE, ORTHOGRAPHIC, NUM_PROJECTIONS};
00117   Projection projection() const { return my_projection; }
00118 
00120   long xOrig, yOrig, xSize, ySize;
00121 
00122 protected:
00124   Stack<Matrix4> transMat;
00125 
00127   int backgroundmode; 
00128 
00130 
00131   int lineStyle, lineWidth;
00132   int sphereRes, sphereMode;
00133   int cylinderRes;
00135 
00136 
00137   //
00138   // eye position, clipping planes, and viewing geometry data
00139   //
00140   float eyePos[3];              
00141   DisplayEye whichEye;          
00142   float nearClip, farClip;      
00143 
00144   float vSize;                  
00145   float zDist;                  
00146 
00147   float Aspect;                 
00148 
00149 
00150 
00151 
00152 
00154 
00155   float cpUp, cpDown, cpLeft, cpRight;  
00157 
00158 
00159   // stereo display data
00160   int inStereo;                 
00161   int stereoSwap;               
00162   int stereoModes;              
00163   const char **stereoNames;     
00164 
00165   // display list caching data
00166   int cacheMode;                
00167   int cacheModes;               
00168   const char **cacheNames;      
00169 
00170   // rendering mode data
00171   int renderMode;               
00172   int renderModes;              
00173   const char **renderNames;     
00174 
00175   // display camera/eye parameters
00176   float eyeSep;                 
00177   float eyeDist;                
00178   float eyeDir[3];              
00179   float upDir[3];               
00180   float eyeSepDir[3];           
00181 
00182 
00183 public:  
00185   virtual int do_define_light(int, float *, float *) { return TRUE; } 
00186   virtual int do_activate_light(int, int) { return TRUE; } 
00187 
00188 #if 0
00189   // XXX need to implement advanced lights still
00190 #endif
00191 
00193   void use_colors(const float *c) {
00194     colorData = c;
00195     do_use_colors();
00196   }
00197 
00198 protected:
00199   int mouseX;                   
00200   int mouseY;                   
00201 
00206   void calc_frustum(void);
00207 
00212   void calc_eyedir(void);
00213 
00217   virtual void do_resize_window(int w, int h);
00218   virtual void do_reposition_window(int xpos, int ypos) {}
00219 
00221   int screenX, screenY;
00222 
00226   void find_pbc_images(const VMDDisplayList *, ResizeArray<Matrix4> &);
00227 
00231   void find_pbc_cells(const VMDDisplayList *, ResizeArray<int> &);
00232 
00233 public:
00234   DisplayDevice(const char *);
00235   virtual ~DisplayDevice(void);
00236   
00238   DisplayDevice& operator=(DisplayDevice &);
00239 
00242   virtual int init(int argc, char **argv, VMDApp *app, int *size, int *loc) {
00243     return TRUE;
00244   }
00245 
00248   virtual int supports_gui() { return FALSE; }
00249 
00250 
00251   //
00252   // event handling routines
00253   //
00254 
00260   virtual void queue_events(void);
00261 
00268   virtual int read_event(long &, long &);
00269 
00270   // get the current state of the device's pointer (i.e. cursor if it has one)
00271   virtual int x(void); 
00272   virtual int y(void); 
00273 
00275   enum { 
00276     SHIFT = 1, 
00277     CONTROL = 2, 
00278     ALT = 4, 
00279     AUX = 8
00280   }; 
00281 
00282   virtual int shift_state(void); 
00283 
00288   virtual int spaceball(int *, int *, int *, int *, int *, int *, int *) { return 0; }
00289 
00294   virtual void set_cursor(int);
00295 
00296 private:
00298   int old_cursor;
00299 
00300   Projection my_projection;     
00301   static const char *projNames[NUM_PROJECTIONS];
00302   static const char *cueModeNames[NUM_CUE_MODES];
00303 
00304 public:
00306 
00307   float aspect(void) { return Aspect; }
00308   float near_clip(void) const { return nearClip; }
00309   float far_clip(void) const { return farClip; }
00310   float clip_width(void) const { return (farClip - nearClip); }
00311   float addto_near_clip(float ac) { return set_near_clip(nearClip + ac); }
00312   float addto_far_clip(float ac) { return set_far_clip(farClip + ac); }
00313   float set_near_clip(float nc) {
00314     // near clip plane must be > 0.0, and less than far clip plane
00315     if (nc < farClip && nc > 0.0) {
00316       nearClip = nc;
00317       calc_frustum();
00318       _needRedraw = 1;
00319     } 
00320     return nearClip;
00321   }
00322 
00323   float set_far_clip(float fc) {
00324     if(fc > nearClip) {
00325       farClip = fc;
00326       _needRedraw = 1;
00327     }
00328     return farClip;
00329   }
00331 
00332 
00334 
00335   virtual void cueing_on(void);
00336   virtual void cueing_off(void);
00337   int cueing_available(void) { return cueingAvailable; }
00338   int cueing_enabled(void) { return cueingEnabled; }
00339 
00340   const char *get_cue_mode() const { return cueModeNames[cueMode]; }
00341   int num_cue_modes() const { return NUM_CUE_MODES; }
00342   const char *cue_mode_name(int i) const {
00343     if (i < 0 || i >= NUM_CUE_MODES) return NULL;
00344     return cueModeNames[i];
00345   }
00346   int set_cue_mode(const char *mode) { 
00347     for (int i=0; i<NUM_CUE_MODES; i++) {
00348       if (!strupcmp(mode, cueModeNames[i])) {
00349         cueMode = (CueMode)i;
00350         _needRedraw = 1;
00351         return TRUE;
00352       }
00353     }
00354     return FALSE; // no match
00355   }
00356 
00357   float get_cue_start() const { return cueStart; }
00358   float set_cue_start(float s) { 
00359     if (s < cueEnd && s >= 0.0) { 
00360       cueStart = s; 
00361       _needRedraw = 1;
00362       return TRUE;
00363     } 
00364     return FALSE;
00365   }   
00366 
00367   float get_cue_end() const { return cueEnd; }
00368   float set_cue_end(float e) { 
00369     if (e > cueStart) { 
00370       cueEnd = e; 
00371       _needRedraw = 1;
00372       return TRUE;
00373     } 
00374     return FALSE;
00375   }   
00376   
00377   float get_cue_density() const { return cueDensity; }
00378   int set_cue_density(float d) {
00379     // XXX check for legal value here
00380     cueDensity = d;
00381     _needRedraw = 1;
00382     return TRUE;
00383   }
00385 
00386 
00388 
00389   virtual void aa_on(void);
00390   virtual void aa_off(void);
00391   int aa_available(void) { return aaAvailable; }
00392   int aa_enabled(void) { return aaEnabled; }
00394 
00395 
00397 
00398   virtual void culling_on(void);
00399   virtual void culling_off(void);
00400   int culling_available(void) { return cullingAvailable; }
00401   int culling_enabled(void) { return cullingEnabled; }
00403 
00404 
00406 
00407   int set_shadow_mode(int onoff) {
00408     if (onoff)
00409       shadowEnabled=1;
00410     else
00411       shadowEnabled=0;
00412     _needRedraw = 1;
00413     return TRUE;
00414   }  
00415   int shadows_enabled(void) { return shadowEnabled; }
00417 
00418 
00420 
00421   int set_ao_mode(int onoff) {
00422     if (onoff)
00423       aoEnabled=1;
00424     else
00425       aoEnabled=0;
00426     _needRedraw = 1;
00427     return TRUE;
00428   }  
00429   int ao_enabled(void) { return aoEnabled; }
00430 
00431   float get_ao_ambient() const { return aoAmbient; }
00432   int set_ao_ambient(float a) {
00433     aoAmbient = a;
00434     _needRedraw = 1;
00435     return TRUE;
00436   }
00437 
00438   float get_ao_direct() const { return aoDirect; }
00439   int set_ao_direct(float d) {
00440     aoDirect = d;
00441     _needRedraw = 1;
00442     return TRUE;
00443   }
00445 
00446 
00447 
00448 
00449   //
00450   // camera and view frustum parameters 
00451   //
00452 
00454   float distance_to_screen(void) { return zDist; }
00455   void distance_to_screen(float zd) {
00456     zDist = zd;
00457     calc_frustum();
00458     _needRedraw = 1;
00459   }
00460   
00462   float screen_height(void) { return vSize; }
00463   void screen_height(float vs) {
00464     if(vs > 0.0) {
00465       vSize = vs;
00466       calc_frustum();
00467       _needRedraw = 1;
00468     }
00469   }
00470 
00472   void set_screen_pos(float vsize, float zdist, float asp) {
00473     Aspect = asp;  vSize = vsize;  zDist = zdist;
00474     calc_frustum();    
00475   }
00476   
00478   void set_screen_pos(float vs, float zd) { set_screen_pos(vs, zd, aspect()); }
00479   
00481   void set_screen_pos(float asp) { set_screen_pos(vSize, zDist, asp); }
00482   
00484   void set_screen_pos(void) { set_screen_pos(vSize, zDist); }
00485 
00487   void resize_window(int w, int h) {
00488     if (w > 0 && h > 0) {
00489       do_resize_window(w, h);
00490     }
00491   }
00493   void reposition_window(int xpos, int ypos) {
00494     if (xpos >= 0 && xpos < screenX && ypos >= 0 && ypos < screenY) {
00495       do_reposition_window(xpos, -1+screenY-ypos);
00496     }
00497   } 
00498 #if 0
00499   // XXX This doesn't work...
00500   void window_position(int *xpos, int *ypos) {
00501     *xpos = xOrig;
00502     //*ypos = screenY - 1 - yOrig;
00503     *ypos = yOrig + screenY - 1;
00504   }
00505 #endif
00506 
00507   //
00508   // routines to deal with stereo display
00509   //
00510   
00512   virtual void set_stereo_mode(int = 0);
00513 
00515   int stereo_mode(void) { return inStereo; }
00516 
00518   void set_stereo_swap(int onoff) { 
00519      stereoSwap = (!(onoff == 0)); 
00520     _needRedraw = 1;
00521   }
00522 
00524   int stereo_swap(void) { return stereoSwap; };
00525  
00527   virtual int forced_stereo_draws(void) { return 0; }
00528  
00530   int num_stereo_modes(void) { return stereoModes; }
00531   
00533   const char *stereo_name(int n) {
00534     const char *retval = stereoNames[0];
00535     if(n >= 0 && n < stereoModes)
00536       retval = stereoNames[n];
00537     return retval;
00538   }
00539 
00540   //
00541   // routines to deal with special rendering modes/features
00542   //
00543   
00545   virtual void set_cache_mode(int = 0);
00546 
00548   int cache_mode(void) { return cacheMode; }
00549 
00551   int num_cache_modes(void) { return cacheModes; }
00552   
00554   const char *cache_name(int n) {
00555     const char *retval = cacheNames[0];
00556     if(n >= 0 && n < cacheModes)
00557       retval = cacheNames[n];
00558     return retval;
00559   }
00560   
00561 
00563   virtual void set_render_mode(int = 0);
00564 
00566   int render_mode(void) { return renderMode; }
00567   
00569   int num_render_modes(void) { return renderModes; }
00570   
00572   const char *render_name(int n) {
00573     const char *retval = renderNames[0];
00574     if(n >= 0 && n < renderModes)
00575       retval = renderNames[n];
00576     return retval;
00577   }
00578 
00579 
00581   int set_eye_defaults(void);
00582 
00584   int set_eye_pos(float * pos) {
00585     if (!pos) return FALSE;
00586     vec_copy(&eyePos[0], pos); 
00587     _needRedraw = 1;
00588     return TRUE; 
00589   }
00590 
00592   int get_eye_pos(float * pos) {
00593     if (!pos) return FALSE;
00594     vec_copy(pos, &eyePos[0]); 
00595     return TRUE; 
00596   }
00597  
00599   int set_eye_dir(float * dir) {
00600     if (!dir) return FALSE;
00601     vec_copy(&eyeDir[0], dir); 
00602     _needRedraw = 1;
00603     return TRUE; 
00604   }
00605 
00607   int get_eye_dir(float * dir) {
00608     if (!dir) return FALSE;
00609     vec_copy(dir, &eyeDir[0]); 
00610     return TRUE; 
00611   }
00612  
00614   int set_eye_up(float *updir) {
00615     if (!updir) return FALSE;
00616     vec_copy(&upDir[0], updir); 
00617     calc_eyedir(); // recalculate related eye parameters
00618     _needRedraw = 1;
00619     return TRUE; 
00620   }
00621 
00623   int get_eye_up(float *updir) {
00624     if (!updir) return FALSE;
00625     vec_copy(updir, &upDir[0]); 
00626     return TRUE; 
00627   }
00628 
00630   float eye_dist(void) const { return eyeDist; }
00631 
00634   int set_eye_dist(float flen) {
00635     if (!eyeDist) return FALSE; // XXX is this possible?
00636     float fl = flen/eyeDist;
00637     for (int i=0; i<3; i++) eyeDir[i] *= fl;
00638     eyeDist = flen; 
00639     calc_eyedir(); // XXX should really be called calc_eyesep 
00640     _needRedraw = 1;
00641     return TRUE;
00642   }
00643    
00645   float eyesep(void) const { return eyeSep; }
00646 
00648   float set_eyesep(float newsep) {
00649     if(newsep >= 0.0) {
00650       eyeSep = newsep;
00651       calc_eyedir();
00652     }
00653     _needRedraw = 1;
00654     return eyeSep;
00655   }
00656 
00658   void right_eye_dir(float& x, float& y, float& z) const {
00659     x = eyeSepDir[0];  y = eyeSepDir[1];  z = eyeSepDir[2];
00660   }  
00661 
00663   int num_projections() const { return NUM_PROJECTIONS; }
00664   const char *projection_name(int i) const {
00665     if (i < 0 || i >= NUM_PROJECTIONS) return NULL;
00666     return projNames[i];
00667   }
00668   const char *get_projection() const { return projNames[my_projection]; }
00669   int set_projection(const char *proj) {
00670     if (!proj) return FALSE;
00671     for (int i=0; i<NUM_PROJECTIONS; i++) {
00672       if (!strupcmp(proj, projNames[i])) {
00673         my_projection = (Projection)i;
00674         _needRedraw = 1;
00675         return TRUE;
00676       }
00677     }
00678     return FALSE;
00679   }
00680 
00681   //
00682   // virtual routines to find characteristics of display itself
00683   //
00684 
00687   virtual void abs_screen_loc_3D(float *, float *);
00688 
00690   virtual void abs_screen_loc_2D(float *, float *);
00691 
00693   virtual void rel_screen_pos(float &x, float &y) {
00694     x = (x - (float)xOrig) / ((float)xSize);
00695     y = (y - (float)yOrig) / ((float)ySize);
00696   }
00697 
00699   void abs_screen_pos(float &x, float &y) {
00700     x = x * (float)xSize + (float)xOrig;
00701     y = y * (float)ySize + (float)yOrig;
00702   }
00703 
00704   // Given a 3D point (pos A),
00705   // and a 2D rel screen pos point (for pos B), computes the 3D point
00706   // which goes with the second 2D point at pos B.  Result returned in 3rd arg.
00707   virtual void find_3D_from_2D(const float *, const float *, float *) {}
00708 
00709 
00710   //
00711   // virtual routines to affect the device's transformation matrix
00712   //
00713   virtual void loadmatrix(const Matrix4 &); 
00714   virtual void multmatrix(const Matrix4 &); 
00715 
00716 
00717   //
00718   // set the background colors
00719   //
00720   void set_background_mode(int newmode) { backgroundmode = newmode; } 
00721   int background_mode(void) { return backgroundmode; } 
00722   virtual void set_background(const float *) {} 
00723   virtual void set_backgradient(const float *, const float *) {} 
00724 
00725  
00726   //
00727   // virtual routines for preparing to draw, drawing, and finishing drawing
00728   //
00729   virtual int prepare3D(int = TRUE);    
00730   virtual int prepareOpaque(void) { return 1; } 
00731   virtual int prepareTrans(void){ return 0; }   
00732   virtual void clear(void);             
00733   virtual void left(void);              
00734   virtual void right(void);             
00735   virtual void normal(void);            
00736   virtual void update(int = TRUE);      
00737   virtual void reshape(void);           
00738 
00740   virtual unsigned char * readpixels(int &x, int &y);
00741   
00743   virtual void render(const VMDDisplayList *) { _needRedraw = 0; } 
00744                                           
00745   virtual void render_done() {}
00746   
00747   // pick objects based on given list of draw commands.
00748   // arguments are dimension of picking (2 or 3), position of pointer,
00749   // draw command list, and returned distance from object to eye position.
00750   // Returns ID code ('tag') for item closest to pointer, or (-1) if no pick.
00751   // If an object is picked, the eye distance argument is set to the distance
00752   // from the display's eye position to the object (after its position has been
00753   // found from the transformation matrix).  If the value of the argument when
00754   // 'pick' is called is <= 0, a pick will be generated if any item is near the
00755   // pointer.  If the value of the argument is > 0, a pick will be generated
00756   // only if an item is closer to the eye position than the value of the
00757   // argument.
00758   // For 2D picking, coordinates are relative position in window from
00759   //    lower-left corner (both in range 0 ... 1)
00760   // For 3D picking, coordinates are the world coords of the pointer.  They
00761   //    are the coords of the pointer after its transformation matrix has been
00762   //    applied, and these coordinates are compared to the coords of the objects
00763   //    when their transformation matrices are applied.
00764   // The window_size argument tells pick how close the picked item must be.
00765   virtual int pick(int, const float *, const VMDDisplayList *, float &, int *,
00766                    float window_size); 
00767 
00768 };
00769 
00770 #endif
00771 

Generated on Sat May 26 01:47:53 2012 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002