// set up the graphics on the seperate CAVE displays void CaveDisplayDevice::cave_gl_init_fn(void) { setup_initial_opengl_state(); // do all OpenGL setup/initialization now // follow up with mode settings aaAvailable = TRUE; // enable antialiasing cueingAvailable = FALSE; // disable depth cueing cullingAvailable = FALSE; // disable culling // XXX need to test this still // ext->hasstereo = CAVEInStereo(); // stereo availability test ext->hasstereo = TRUE; // stereo is on initially ext->stereodrawforced = FALSE; // no need for forced stereo draws glClearColor(0.0, 0.0, 0.0, 0.0); // set clear color to black aa_on(); // force antialiasing on if possible cueing_off(); // force depth cueing off // set default settings set_sphere_mode(sphereMode); set_sphere_res(sphereRes); set_line_width(lineWidth); set_line_style(lineStyle); clear(); // clear screen update(); // swap buffers // we want the CAVE to be centered at the origin, and in the range -1, +1 (transMat.top()).translate(0.0, 3.0, -2.0); (transMat.top()).scale(VMD_PI); doneGLInit = TRUE; // only do this once }
// create a new window and set it's characteristics int OpenGLDisplayDevice::open_window(char *nm, int *size, int *loc, int argc, char** argv ) { int SX = 100, SY = 100, W, H; char *dispname; if ((dispname = getenv("VMDGDISPLAY")) == NULL) dispname = getenv("DISPLAY"); if (SDL_Init(SDL_INIT_VIDEO) < 0) { msgErr << "Exiting due to SDL window creation failure." << sendmsg; SDL_Quit(); return -1; } // get info about root window screenX = 1280; // XXX hack screenY = 1024; W = size[0]; H = size[1]; if (loc) { SX = loc[0]; // The X11 screen uses Y increasing from upper-left corner down; this is // opposite to what GL does, which is the way VMD was set up originally SY = (screenY - loc[1]) - H; } ext->hasstereo = FALSE; // stereo is off until we find out otherwise. ext->stereodrawforce = FALSE; // don't force stereo draws initially. ext->hasmultisample = FALSE; // multisample is off until we find out otherwise. if (SDL_SetVideoMode(W, H, 32, SDL_OPENGL) == NULL) { msgInfo << "Tried 32 bit color and failed..." << sendmsg; if (SDL_SetVideoMode(W, H, 24, SDL_OPENGL) == NULL) { msgInfo << "Tried 24 bit color and failed..." << sendmsg; if (SDL_SetVideoMode(W, H, 16, SDL_OPENGL) == NULL) { msgInfo << "Tried 16 bit color and failed..." << sendmsg; msgErr << "Cannot open display. Exiting ..." << sendmsg; SDL_Quit(); return -1; } } } SDL_WM_SetCaption("VMD " VMDVERSION " OpenGL Display", NULL); // (9) configure the rendering properly setup_initial_opengl_state(); // setup initial OpenGL state // Tell init that we successfully created a window. have_window = TRUE; return 0; // return window id }
// create a new window and set it's characteristics int OpenGLDisplayDevice::open_window(char *nm, int *size, int *loc, int argc, char** argv) { int SX = 596, SY = 190; if (loc) { SX = loc[0]; // X screen uses Y increasing from upper-left corner down; this is // opposite to what GL does, which is the way VMD was set up originally SY = screenY - loc[1] - size[1]; } glwsrv.cursornum = 0; // initialize cursor number // window opening stuff goes here int rc = OpenWin32Connection(&glwsrv); if (rc != 0) { return -1; } xOrig = 0; yOrig = 0; xSize = size[0]; ySize = size[1]; glwsrv.width = xSize; glwsrv.height = ySize; rc = myCreateWindow(this, 0, 0, glwsrv.width, glwsrv.height); if (rc != 0) { return -1; } // Determine if stereo is available if (glwsrv.PFDisStereo == 0) { ext->hasstereo = FALSE; } else { ext->hasstereo = TRUE; } ext->stereodrawforced = FALSE; // don't force stereo draws initially setup_initial_opengl_state(); #ifdef VMDSPACEWARE vmd_setupwin32spaceball(&glwsrv); #endif // normal return: window was successfully created have_window = TRUE; // return window id return 0; }
// constructor ... open a window and set initial default values FltkOpenGLDisplayDevice::FltkOpenGLDisplayDevice(int argc, char **argv, VMDApp *vmdapp_p, int *size, int *loc) : OpenGLRenderer((char *) "VMD " VMDVERSION " OpenGL Display") { vmdapp = vmdapp_p; // save VMDApp handle for use by drag-and-drop handlers, // and GPU memory management routines // set up data possible before opening window stereoNames = glStereoNameStr; stereoModes = OPENGL_STEREO_MODES; // GLSL is only available on MacOS X 10.4 and later. renderNames = glRenderNameStr; renderModes = OPENGL_RENDER_MODES; cacheNames = glCacheNameStr; cacheModes = OPENGL_CACHE_MODES; // open the window int SX = 100, SY = 100, W, H; W = size[0]; H = size[1]; if (loc) { SX = loc[0]; SY = loc[1]; } window = new myglwindow(SX, SY, W, H, name, this, vmdapp_p); ext->hasstereo = FALSE; // stereo is off initially ext->stereodrawforced = FALSE; // stereo not forced initially ext->hasmultisample = FALSE; // multisample is off initially int rc=0; // FLTK stereo support only started working for MacOS X at around version 1.1.7 #if (FL_MAJOR_VERSION >= 1) && (((FL_MINOR_VERSION >= 1) && (FL_PATCH_VERSION >= 7)) || ((FL_MINOR_VERSION >= 1) && (FL_PATCH_VERSION >= 7))) // find an appropriate visual and colormap ... if (getenv("VMDPREFERSTEREO") != NULL) { // Stereo limps along with FLTK 1.1.7 on MacOS X rc = window->mode(FL_RGB8 | FL_DOUBLE | FL_STENCIL | FL_STEREO); ext->hasstereo = TRUE; #if defined(__APPLE__) ext->stereodrawforced = TRUE; // forced draw in stereo all the time when on #endif // FLTK multisample antialiasing still doesn't actually work in // MacOS X as of FLTK 1.1.10... #if !defined(__APPLE__) // } else if (getenv("VMDPREFERMULTISAMPLE") != NULL) { } else if (rc != 0) { rc = window->mode(FL_RGB8 | FL_DOUBLE | FL_STENCIL | FL_MULTISAMPLE); ext->hasmultisample = TRUE; // FLTK only does SGI multisample, no ARB yet #endif } else { rc = window->mode(FL_RGB8 | FL_DOUBLE | FL_STENCIL); } #else // find an appropriate visual and colormap ... rc = window->mode(FL_RGB8 | FL_DOUBLE | FL_STENCIL); #endif window->show(); // (7) bind the rendering context to the window window->make_current(); // (8) actually request the window to be displayed screenX = Fl::w(); screenY = Fl::h(); // (9) configure the rendering properly setup_initial_opengl_state(); // setup initial OpenGL state // set flags for the capabilities of this display // whether we can do antialiasing or not. if (ext->hasmultisample) aaAvailable = TRUE; // we use multisampling over other methods else aaAvailable = FALSE; // no non-multisample implementation yet // set default settings if (ext->hasmultisample) { aa_on(); // enable fast multisample based antialiasing by default // other antialiasing techniques are slow, so only multisample // makes sense to enable by default. } cueingAvailable = TRUE; cueing_on(); // leave depth cueing on by default, despite the speed hit. cullingAvailable = TRUE; culling_off(); set_sphere_mode(sphereMode); set_sphere_res(sphereRes); set_line_width(lineWidth); set_line_style(lineStyle); // reshape and clear the display, which initializes some other variables reshape(); normal(); clear(); update(); }
// create a new window and set it's characteristics Window OpenGLPbufferDisplayDevice::open_window(char *nm, int *size, int *loc, int argc, char** argv ) { char *dispname; if ((dispname = getenv("VMDGDISPLAY")) == NULL) dispname = getenv("DISPLAY"); if(!(glxsrv.dpy = XOpenDisplay(dispname))) { msgErr << "Exiting due to X-Windows GLX/OpenGL Pbuffer creation failure." << sendmsg; if (dispname != NULL) { msgErr << "Failed to open display: " << dispname << sendmsg; } return (Window)0; } // // Check for "Composite" extension and any others that might cause // stability issues and warn the user about any potential problems... // char **xextensionlist; int nextensions, xtn; int warncompositeext=0; xextensionlist = XListExtensions(glxsrv.dpy, &nextensions); for (xtn=0; xtn<nextensions; xtn++) { // printf("xtn[%d]: '%s'\n", xtn, xextensionlist[xtn]); if (xextensionlist[xtn] && !strcmp(xextensionlist[xtn], "Composite")) { warncompositeext=1; } } if (warncompositeext) { msgWarn << "Detected X11 'Composite' extension: if incorrect display occurs" << sendmsg; msgWarn << "try disabling this X server option. Most OpenGL drivers" << sendmsg; msgWarn << "disable stereoscopic display when 'Composite' is enabled." << sendmsg; } XFreeExtensionList(xextensionlist); // // get info about root window // glxsrv.dpyScreen = DefaultScreen(glxsrv.dpy); glxsrv.rootWindowID = RootWindow(glxsrv.dpy, glxsrv.dpyScreen); screenX = DisplayWidth(glxsrv.dpy, glxsrv.dpyScreen); screenY = DisplayHeight(glxsrv.dpy, glxsrv.dpyScreen); // (3) make sure the GLX extension is available if (!glXQueryExtension(glxsrv.dpy, NULL, NULL)) { msgErr << "The X server does not support the OpenGL GLX extension." << " Exiting ..." << sendmsg; XCloseDisplay(glxsrv.dpy); return (Window)0; } ext->hasstereo = TRUE; // stereo on until we find out otherwise. ext->stereodrawforced = FALSE; // no need for force stereo draws initially ext->hasmultisample = TRUE; // multisample on until we find out otherwise. // Find the best matching OpenGL framebuffer config for our purposes GLXFBConfig *fbc; fbc = vmd_get_fbconfig(&glxsrv, &ext->hasstereo, &ext->hasmultisample, &ext->nummultisamples); if (fbc == NULL) { msgErr << "No OpenGL Pbuffer configurations available" << sendmsg; return (Window)0; } // Create the OpenGL Pbuffer and associated GLX context const int pbconf[] = {GLX_PBUFFER_WIDTH, DEF_PBUFFER_XRES, GLX_PBUFFER_HEIGHT, DEF_PBUFFER_YRES, GLX_LARGEST_PBUFFER, 1, GLX_PRESERVED_CONTENTS, 1, None}; GLXPbuffer PBuffer = glXCreatePbuffer(glxsrv.dpy, fbc[0], pbconf); glxsrv.cx = glXCreateNewContext(glxsrv.dpy, fbc[0], GLX_RGBA_TYPE, 0, GL_TRUE); if (PBuffer == 0 || glxsrv.cx == NULL) { msgErr << "A TrueColor OpenGL Pbuffer is required, but not available." << sendmsg; msgErr << "The X server is not capable of displaying double-buffered," << sendmsg; msgErr << "RGB images with a Z buffer. Exiting ..." << sendmsg; XCloseDisplay(glxsrv.dpy); return (Window)0; } // set maximum allowable rendered image size for the Pbuffer // that was actually allocated, which may be smaller than we hoped... PbufferMaxXsz = DEF_PBUFFER_XRES; PbufferMaxYsz = DEF_PBUFFER_YRES; glXQueryDrawable(glxsrv.dpy, PBuffer, GLX_WIDTH, &PbufferMaxXsz); glXQueryDrawable(glxsrv.dpy, PBuffer, GLX_HEIGHT, &PbufferMaxYsz); msgInfo << "OpenGL Pbuffer size: " << PbufferMaxXsz << "x" << PbufferMaxYsz << sendmsg; // set default image size to incoming values, when possible. xSize = size[0]; ySize = size[1]; if (xSize < 0 || xSize > PbufferMaxXsz || ySize < 0 || ySize > PbufferMaxYsz) { msgWarn << "Ignored out-of-range OpenGL Pbuffer image dimension request: " << xSize << "x" << ySize << " (max: " << PbufferMaxXsz << "x" << PbufferMaxYsz << ")" << sendmsg; xSize = PbufferMaxXsz; ySize = PbufferMaxYsz; } // make the Pbuffer active glXMakeContextCurrent(glxsrv.dpy, PBuffer, PBuffer, glxsrv.cx); glXMakeCurrent(glxsrv.dpy, PBuffer, glxsrv.cx); // If we have acquired a multisample buffer with GLX, we // still need to test to see if we can actually use it. if (ext->hasmultisample) { int msampeext = 0; // check for ARB multisampling if (ext->vmdQueryExtension("GL_ARB_multisample")) { msampeext = 1; } if (!msampeext) { ext->hasmultisample = FALSE; ext->nummultisamples = 0; } } // (9) configure the rendering properly setup_initial_opengl_state(); // setup initial OpenGL state // normal return: window was successfully created have_window = TRUE; // return window id return PBuffer; }