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

SDLOpenGLDisplayDevice.C

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: SDLOpenGLDisplayDevice.C,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.36 $       $Date: 2011/02/25 18:15:55 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *
00019  * Subclass of DisplayDevice, this object has routines used by all the
00020  * different display devices that are OpenGL-specific.  Will render drawing
00021  * commands into a single X window.
00022  *
00023  ***************************************************************************/
00024 
00025 #include <stdlib.h>
00026 #include <math.h>
00027 #if defined(__APPLE__)
00028 #include <OpenGL/gl.h>
00029 #else
00030 #include <GL/gl.h>
00031 #endif
00032 #include <SDL.h>
00033 
00034 #include "OpenGLDisplayDevice.h"
00035 #include "Inform.h"
00036 #include "utilities.h"
00037 #include "config.h"   // VMD version strings etc
00038 
00039 // static data for this object
00040 static const char *glStereoNameStr[OPENGL_STEREO_MODES] = 
00041  { "Off", 
00042    "QuadBuffered", 
00043    "DTI SideBySide",
00044    "Checkerboard",
00045    "ColumnInterleaved",
00046    "RowInterleaved",
00047    "Anaglyph", 
00048    "SideBySide", 
00049    "AboveBelow",
00050    "Left", 
00051    "Right" };
00052 
00053 static const char *glRenderNameStr[OPENGL_RENDER_MODES] =
00054 { "Normal",
00055   "GLSL",
00056   "Acrobat3D" };
00057 
00058 static const char *glCacheNameStr[OPENGL_CACHE_MODES] =
00059 { "Off",
00060   "On" };
00061 
00062 
00064 
00065 OpenGLDisplayDevice::OpenGLDisplayDevice()
00066 : OpenGLRenderer((char *) "VMD " VMDVERSION " OpenGL Display") {
00067 
00068   // set up data possible before opening window
00069   stereoNames = glStereoNameStr;
00070   stereoModes = OPENGL_STEREO_MODES;
00071 
00072   renderNames = glRenderNameStr;
00073   renderModes = OPENGL_RENDER_MODES;
00074 
00075   cacheNames = glCacheNameStr;
00076   cacheModes = OPENGL_CACHE_MODES;
00077 
00078   memset(&sdlsrv, 0, sizeof(sdlsrv));
00079   have_window = FALSE;
00080   screenX = screenY = 0;
00081   vmdapp = NULL;
00082 }
00083 
00084 int OpenGLDisplayDevice::init(int argc, char **argv, VMDApp* app, int *size, int *loc) {
00085 
00086   // open the window
00087   sdlsrv.windowID = open_window(name, size, loc, argc, argv);
00088   if (!have_window) return FALSE;
00089 
00090   // set flags for the capabilities of this display
00091   // whether we can do antialiasing or not.
00092   if (ext->hasmultisample) 
00093     aaAvailable = TRUE;  // we use multisampling over other methods
00094   else
00095     aaAvailable = FALSE; // no non-multisample implementation yet
00096 
00097   // set default settings
00098   if (ext->hasmultisample) {
00099     aa_on();  // enable fast multisample based antialiasing by default
00100               // other antialiasing techniques are slow, so only multisample
00101               // makes sense to enable by default.
00102   } 
00103 
00104   cueingAvailable = TRUE;
00105   cueing_on(); // leave depth cueing on by default, despite the speed hit.
00106 
00107   cullingAvailable = TRUE;
00108   culling_off();
00109 
00110   set_sphere_mode(sphereMode);
00111   set_sphere_res(sphereRes);
00112   set_line_width(lineWidth);
00113   set_line_style(lineStyle);
00114 
00115   // reshape and clear the display, which initializes some other variables
00116   reshape();
00117   normal();
00118   clear();
00119   update();
00120 
00121   // successfully opened window.
00122   return TRUE;
00123 }
00124 
00125 // destructor ... close the window
00126 OpenGLDisplayDevice::~OpenGLDisplayDevice(void) {
00127   if (have_window) {
00128     free_opengl_ctx(); // free display lists, textures, etc
00129   }
00130 
00131   SDL_Quit();
00132 }
00133 
00134 
00136 
00137 
00138 // create a new window and set it's characteristics
00139 int OpenGLDisplayDevice::open_window(char *nm, int *size, int *loc,
00140                                      int argc, char** argv) {
00141   int SX = 100, SY = 100, W, H;
00142  
00143   char *dispname = NULL;
00144   if ((dispname = getenv("VMDGDISPLAY")) == NULL)
00145     dispname = getenv("DISPLAY");
00146 
00147   if (SDL_Init(SDL_INIT_VIDEO) < 0) {
00148     msgErr << "Exiting due to SDL window creation failure." << sendmsg;
00149     SDL_Quit();
00150     return -1;
00151   }
00152   // get info about root window
00153   screenX = 1280; // XXX hack
00154   screenY = 1024;
00155   W = size[0];
00156   H = size[1];
00157   if (loc) {
00158     SX = loc[0];
00159     // The X11 screen uses Y increasing from upper-left corner down; this is
00160     // opposite to what GL does, which is the way VMD was set up originally
00161     SY = (screenY - loc[1]) - H;
00162   }
00163   ext->hasstereo = FALSE;        // stereo is off until we find out otherwise.
00164   ext->stereodrawforced = FALSE; // don't force stereo draws initially.
00165   ext->hasmultisample = FALSE;   // multisample is off until we find out otherwise.
00166   
00167   if (SDL_SetVideoMode(W, H, 32, SDL_OPENGL) == NULL) {
00168     msgInfo << "Tried 32 bit color and failed..." << sendmsg;
00169     if (SDL_SetVideoMode(W, H, 24, SDL_OPENGL) == NULL) { 
00170       msgInfo << "Tried 24 bit color and failed..." << sendmsg;
00171       if (SDL_SetVideoMode(W, H, 16, SDL_OPENGL) == NULL) {
00172         msgInfo << "Tried 16 bit color and failed..." << sendmsg;
00173         msgErr << "Cannot open display.  Exiting ..." << sendmsg;
00174         SDL_Quit();
00175         return -1;
00176       }
00177     }
00178   } 
00179 
00180   SDL_WM_SetCaption("VMD " VMDVERSION " OpenGL Display", NULL);
00181 
00182   // (9) configure the rendering properly
00183   setup_initial_opengl_state();  // setup initial OpenGL state
00184 
00185   // Tell init that we successfully created a window.
00186   have_window = TRUE;
00187 
00188   return 0; // return window id
00189 }
00190 
00191 
00193 
00194 void OpenGLDisplayDevice::do_resize_window(int width, int height) {
00195   // not implemented yet
00196 }
00197 
00198 void OpenGLDisplayDevice::do_reposition_window(int xpos, int ypos) {
00199   // not implemented yet
00200 }
00201 
00202 //
00203 // get the current state of the device's pointer (i.e. cursor if it has one)
00204 //
00205 
00206 // abs pos of cursor from lower-left corner of display
00207 int OpenGLDisplayDevice::x(void) {
00208   int rx;
00209 
00210   rx = 0;
00211 
00212   return rx;
00213 }
00214 
00215 
00216 // same, for y direction
00217 int OpenGLDisplayDevice::y(void) {
00218   int ry;
00219 
00220   ry = 0;
00221 
00222   return ry;
00223 }
00224 
00225 // return the current state of the shift, control, and alt keys
00226 int OpenGLDisplayDevice::shift_state(void) {
00227   int retval = 0;
00228 
00229   // return the result
00230   return retval;
00231 }
00232 
00233 // return the spaceball state, if any
00234 int OpenGLDisplayDevice::spaceball(int *rx, int *ry, int *rz, int *tx, int *ty,
00235 int *tz, int *buttons) {
00236   // not implemented yet
00237   return 0;
00238 }
00239 
00240 
00241 // set the Nth cursor shape as the current one.  If no arg given, the
00242 // default shape (n=0) is used.
00243 void OpenGLDisplayDevice::set_cursor(int n) {
00244   // unimplemented
00245 }
00246 
00247 
00248 //
00249 // event handling routines
00250 //
00251 
00252 // queue the standard events (need only be called once ... but this is
00253 // not done automatically by the window because it may not be necessary or
00254 // even wanted)
00255 void OpenGLDisplayDevice::queue_events(void) {
00256 }
00257 
00258 // read the next event ... returns an event type (one of the above ones),
00259 // and a value.  Returns success, and sets arguments.
00260 int OpenGLDisplayDevice::read_event(long &retdev, long &retval) {
00261   int done = 0;
00262   SDL_Event event;
00263 
00264   SDL_PollEvent(&event);
00265 
00266   if ( event.type == SDL_KEYDOWN ) {
00267     if ( event.key.keysym.sym == SDLK_ESCAPE ) {
00268 printf("ESC pressed!!\n");
00269       done = 1;
00270     }
00271   }
00272 
00273   return FALSE;
00274 }
00275 
00276 
00277 //
00278 // virtual routines for preparing to draw, drawing, and finishing drawing
00279 //
00280 
00281 // reshape the display after a shape change
00282 void OpenGLDisplayDevice::reshape(void) {
00283   xSize = 512;
00284   ySize = 512;
00285   xOrig = 0;
00286   yOrig = 0;
00287 
00288   switch (inStereo) {
00289     case OPENGL_STEREO_SIDE:
00290       set_screen_pos(0.5f * (float)xSize / (float)ySize);
00291       break;
00292 
00293     case OPENGL_STEREO_ABOVEBELOW:
00294       set_screen_pos(2.0f * (float)xSize / (float)ySize);
00295       break;
00296 
00297     case OPENGL_STEREO_STENCIL_CHECKERBOARD:
00298     case OPENGL_STEREO_STENCIL_COLUMNS:
00299     case OPENGL_STEREO_STENCIL_ROWS:
00300       enable_stencil_stereo(inStereo);
00301       set_screen_pos((float)xSize / (float)ySize);
00302       break;
00303  
00304     default:
00305       set_screen_pos((float)xSize / (float)ySize);
00306       break;
00307   }
00308 }
00309 
00310 unsigned char * OpenGLDisplayDevice::readpixels(int &x, int &y) {
00311   unsigned char * img;
00312 
00313   x = xSize;
00314   y = ySize;
00315 
00316   if ((img = (unsigned char *) malloc(x * y * 3)) != NULL) {
00317     glPixelStorei(GL_PACK_ALIGNMENT, 1);
00318     glReadPixels(0, 0, x, y, GL_RGB, GL_UNSIGNED_BYTE, img);
00319   } else {
00320     x = 0;
00321     y = 0;
00322   } 
00323 
00324   return img; 
00325 }
00326 
00327 
00328 // update after drawing
00329 void OpenGLDisplayDevice::update(int do_update) {
00330   if(do_update)
00331     SDL_GL_SwapBuffers();
00332 
00333   glDrawBuffer(GL_BACK);
00334 }
00335 
00336 

Generated on Tue May 22 01:48:11 2012 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002