// 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 }
// init ... open a window and set initial default values int OpenGLDisplayDevice::init(int argc, char **argv, VMDApp *app, int *size, int *loc) { vmdapp = app; // save VMDApp handle for use by drag-and-drop handlers // open the window if (open_window(name, size, loc, argc, argv) != 0) return FALSE; if (!have_window) return FALSE; // get screen size // XXX There's no Win32 API to get the full multi-monitor desktop, // so this code doesn't correctly handle multi-monitor systems yet. // To correctly handle multiple monitors, we'd have to // walk the device tree, take into account monitor layout/positioning, // and compute the desktop dimensions from that. Since these values // are currently only used by do_reposition_window() method, we can // live with primary-monitor values for the time being. screenX = GetSystemMetrics(SM_CXSCREEN); screenY = GetSystemMetrics(SM_CYSCREEN); // set flags for the capabilities of this display ext->hasmultisample = FALSE; // no code for this extension yet ext->nummultisamples = 0; aaAvailable = FALSE; // 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(); // successfully created window return TRUE; }
int OpenGLPbufferDisplayDevice::init(int argc, char **argv, VMDApp *app, int *size, int *loc) { vmdapp = app; // save VMDApp handle for use by drag-and-drop handlers // and GPU memory management routines // open the window glxsrv.windowID = open_window(name, size, loc, argc, argv); if (!have_window) return FALSE; // 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(); // We have a window, return success. return TRUE; }
int OpenGLDisplayDevice::init(int argc, char **argv, VMDApp* app, int *size, int *loc) { // open the window sdlsrv.windowID = open_window(name, size, loc, argc, argv); if (!have_window) return FALSE; // 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 cueingAvailable = TRUE; cullingAvailable = TRUE; cullingEnabled = FALSE; // 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. } cueing_off(); // leave depth cueing off by default, since its a speed hit. 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(); // successfully opened window. return TRUE; }
void PSDisplayDevice::render(const VMDDisplayList *display_list) { DepthSortObject depth_obj; char *cmd_ptr; int draw; int tok; int nc; float a[3], b[3], c[3], d[3]; float cent[3]; float r; Matrix4 ident; float textsize=1.0f; // default text size // first we want to clear the transformation matrix stack while (transMat.num()) transMat.pop(); // push on the identity matrix transMat.push(ident); // load the display list's transformation matrix super_multmatrix(display_list->mat.mat); // Now we need to calculate the normalized position of the light // so we can compute angles of surfaces to that light for shading norm_light[0] = lightState[0].pos[0]; norm_light[1] = lightState[0].pos[1]; norm_light[2] = lightState[0].pos[2]; if (norm_light[0] || norm_light[1] || norm_light[2]) vec_normalize(norm_light); // Computer periodic images ResizeArray<Matrix4> pbcImages; find_pbc_images(display_list, pbcImages); int nimages = pbcImages.num(); for (int pbcimage = 0; pbcimage < nimages; pbcimage++) { transMat.dup(); super_multmatrix(pbcImages[pbcimage].mat); // Loop through the display list and add each object to our // depth-sort list for final rendering. VMDDisplayList::VMDLinkIter cmditer; display_list->first(&cmditer); while ((tok = display_list->next(&cmditer, cmd_ptr)) != DLASTCOMMAND) { draw = 0; nc = -1; switch (tok) { case DPOINT: // allocate memory depth_obj.points = (float *) malloc(sizeof(float) * 2); if (!depth_obj.points) { // memory error if (!memerror) { memerror = 1; msgErr << "PSDisplayDevice: Out of memory. Some " << "objects were not drawn." << sendmsg; } break; } // copy data depth_obj.npoints = 1; depth_obj.color = colorIndex; (transMat.top()).multpoint3d(((DispCmdPoint *) cmd_ptr)->pos, a); memcpy(depth_obj.points, a, sizeof(float) * 2); // compute the distance to the eye depth_obj.dist = compute_dist(a); // valid object to depth sort draw = 1; break; case DSPHERE: { (transMat.top()).multpoint3d(((DispCmdSphere *) cmd_ptr)->pos_r, c); r = scale_radius(((DispCmdSphere *) cmd_ptr)->pos_r[3]); sphere_approx(c, r); break; } case DSPHEREARRAY: { DispCmdSphereArray *sa = (DispCmdSphereArray *) cmd_ptr; int cIndex, rIndex; // cIndex: index of colors & centers // rIndex: index of radii. float * centers; float * radii; float * colors; sa->getpointers(centers, radii, colors); set_sphere_res(sa->sphereres); for (cIndex = 0, rIndex=0; rIndex < sa->numspheres; cIndex+=3, rIndex++) { colorIndex = nearest_index(colors[cIndex], colors[cIndex+1], colors[cIndex+2]); (transMat.top()).multpoint3d(¢ers[cIndex] , c); r = scale_radius(radii[rIndex]); sphere_approx(c, r); } break; } case DLINE: // check for zero-length line (degenerate) if (!memcmp(((DispCmdLine *) cmd_ptr)->pos1, ((DispCmdLine *) cmd_ptr)->pos2, sizeof(float) * 3)) { // degenerate line break; } // allocate memory depth_obj.points = (float *) malloc(sizeof(float) * 4); if (!depth_obj.points) { // memory error if (!memerror) { memerror = 1; msgErr << "PSDisplayDevice: Out of memory. Some " << "objects were not drawn." << sendmsg; } break; } // copy data depth_obj.npoints = 2; depth_obj.color = colorIndex; (transMat.top()).multpoint3d(((DispCmdLine *) cmd_ptr)->pos1, a); (transMat.top()).multpoint3d(((DispCmdLine *) cmd_ptr)->pos2, b); memcpy(depth_obj.points, a, sizeof(float) * 2); memcpy(&depth_obj.points[2], b, sizeof(float) * 2); // compute the centerpoint of the object cent[0] = (a[0] + b[0]) / 2; cent[1] = (a[1] + b[1]) / 2; cent[2] = (a[2] + b[2]) / 2; // compute the distance to the eye depth_obj.dist = compute_dist(cent); // valid object to depth sort draw = 1; break; case DLINEARRAY: { // XXX much replicated code from DLINE float *v = (float *)cmd_ptr; int nlines = (int)v[0]; v++; for (int i=0; i<nlines; i++) { // check for degenerate line if (!memcmp(v,v+3,3*sizeof(float))) break; // allocate memory depth_obj.points = (float *) malloc(sizeof(float) * 4); if (!depth_obj.points) { // memory error if (!memerror) { memerror = 1; msgErr << "PSDisplayDevice: Out of memory. Some " << "objects were not drawn." << sendmsg; } break; } // copy data depth_obj.npoints = 2; depth_obj.color = colorIndex; (transMat.top()).multpoint3d(v, a); (transMat.top()).multpoint3d(v+3, b); memcpy(depth_obj.points, a, sizeof(float) * 2); memcpy(&depth_obj.points[2], b, sizeof(float) * 2); // compute the centerpoint of the object cent[0] = (a[0] + b[0]) / 2; cent[1] = (a[1] + b[1]) / 2; cent[2] = (a[2] + b[2]) / 2; // compute the distance to the eye depth_obj.dist = compute_dist(cent); // we'll add the object here, since we have multiple objects draw = 0; memusage += sizeof(float) * 2 * depth_obj.npoints; points += depth_obj.npoints; objects++; depth_list.append(depth_obj); v += 6; } } break; case DPOLYLINEARRAY: { // XXX much replicated code from DLINE / DLINEARRAY float *v = (float *)cmd_ptr; int nverts = (int)v[0]; v++; for (int i=0; i<nverts-1; i++) { // check for degenerate line if (!memcmp(v,v+3,3*sizeof(float))) break; // allocate memory depth_obj.points = (float *) malloc(sizeof(float) * 4); if (!depth_obj.points) { // memory error if (!memerror) { memerror = 1; msgErr << "PSDisplayDevice: Out of memory. Some " << "objects were not drawn." << sendmsg; } break; } // copy data depth_obj.npoints = 2; depth_obj.color = colorIndex; (transMat.top()).multpoint3d(v, a); (transMat.top()).multpoint3d(v+3, b); memcpy(depth_obj.points, a, sizeof(float) * 2); memcpy(&depth_obj.points[2], b, sizeof(float) * 2); // compute the centerpoint of the object cent[0] = (a[0] + b[0]) / 2; cent[1] = (a[1] + b[1]) / 2; cent[2] = (a[2] + b[2]) / 2; // compute the distance to the eye depth_obj.dist = compute_dist(cent); // we'll add the object here, since we have multiple objects draw = 0; memusage += sizeof(float) * 2 * depth_obj.npoints; points += depth_obj.npoints; objects++; depth_list.append(depth_obj); v += 3; } } break; case DCYLINDER: { int res; (transMat.top()).multpoint3d((float *) cmd_ptr, a); (transMat.top()).multpoint3d(&((float *) cmd_ptr)[3], b); r = scale_radius(((float *) cmd_ptr)[6]); res = (int) ((float *) cmd_ptr)[7]; cylinder_approx(a, b, r, res, (int) ((float *) cmd_ptr)[8]); break; } case DCONE: { (transMat.top()).multpoint3d(((DispCmdCone *) cmd_ptr)->pos1, a); (transMat.top()).multpoint3d(((DispCmdCone *) cmd_ptr)->pos2, b); float r1 = scale_radius(((DispCmdCone *) cmd_ptr)->radius); float r2 = scale_radius(((DispCmdCone *) cmd_ptr)->radius2); // XXX current implementation can't draw truncated cones. if (r2 > 0.0f) { msgWarn << "PSDisplayDevice) can't draw truncated cones" << sendmsg; } cone_approx(a, b, r1); break; } case DTEXTSIZE: textsize = ((DispCmdTextSize *)cmd_ptr)->size; break; case DTEXT: { float* pos = (float *)cmd_ptr; #if 0 // thickness not implemented yet float thickness = pos[3]; // thickness is stored in 4th slot #endif char* txt = (char *)(pos+4); int txtlen = strlen(txt); // allocate memory depth_obj.points = (float *) malloc(sizeof(float) * 2); depth_obj.text = (char *) malloc(sizeof(char) * (txtlen+1)); if ( !(depth_obj.points || depth_obj.text) ) { // memory error if (!memerror) { memerror = 1; msgErr << "PSDisplayDevice: Out of memory. Some " << "objects were not drawn." << sendmsg; } break; } // copy data depth_obj.npoints = 1; depth_obj.color = colorIndex; (transMat.top()).multpoint3d(((DispCmdPoint *) cmd_ptr)->pos, a); memcpy(depth_obj.points, a, sizeof(float) * 2); strcpy(depth_obj.text , txt); // note scale factor, stored into "light_scale", so we didn't // have to add a new structure member just for this. depth_obj.light_scale = textsize * 15; // compute the distance to the eye depth_obj.dist = compute_dist(a); // valid object to depth sort draw = 1; break; } case DTRIANGLE: // check for degenerate triangle if (!memcmp(((DispCmdTriangle *) cmd_ptr)->pos1, ((DispCmdTriangle *) cmd_ptr)->pos2, sizeof(float) * 3) || !memcmp(((DispCmdTriangle *) cmd_ptr)->pos2, ((DispCmdTriangle *) cmd_ptr)->pos3, sizeof(float) * 3) || !memcmp(((DispCmdTriangle *) cmd_ptr)->pos2, ((DispCmdTriangle *) cmd_ptr)->pos3, sizeof(float) * 3)) { // degenerate triangle break; } // allocate memory depth_obj.points = (float *) malloc(sizeof(float) * 6); if (!depth_obj.points) { // memory error if (!memerror) { memerror = 1; msgErr << "PSDisplayDevice: Out of memory. Some " << "objects were not drawn." << sendmsg; } break; } // copy data depth_obj.npoints = 3; depth_obj.color = (nc >= 0) ? nc : colorIndex; (transMat.top()).multpoint3d(((DispCmdTriangle *) cmd_ptr)->pos1, a); (transMat.top()).multpoint3d(((DispCmdTriangle *) cmd_ptr)->pos2, b); (transMat.top()).multpoint3d(((DispCmdTriangle *) cmd_ptr)->pos3, c); memcpy(depth_obj.points, a, sizeof(float) * 2); memcpy(&depth_obj.points[2], b, sizeof(float) * 2); memcpy(&depth_obj.points[4], c, sizeof(float) * 2); // compute the centerpoint of the object cent[0] = (a[0] + b[0] + c[0]) / 3; cent[1] = (a[1] + b[1] + c[1]) / 3; cent[2] = (a[2] + b[2] + c[2]) / 3; // compute the distance to the eye for depth sorting depth_obj.dist = compute_dist(cent); // compute a light shading factor depth_obj.light_scale = compute_light(a, b, c); // valid object to depth sort draw = 1; break; case DTRIMESH_C4F_N3F_V3F: // call a separate routine to break up the mesh into // its component triangles decompose_mesh((DispCmdTriMesh *) cmd_ptr); break; case DTRISTRIP: // call a separate routine to break up the strip into // its component triangles decompose_tristrip((DispCmdTriStrips *) cmd_ptr); break; case DSQUARE: // check for degenerate quadrilateral if (!memcmp(((DispCmdSquare *) cmd_ptr)->pos1, ((DispCmdSquare *) cmd_ptr)->pos2, sizeof(float) * 3) || !memcmp(((DispCmdSquare *) cmd_ptr)->pos1, ((DispCmdSquare *) cmd_ptr)->pos3, sizeof(float) * 3) || !memcmp(((DispCmdSquare *) cmd_ptr)->pos1, ((DispCmdSquare *) cmd_ptr)->pos4, sizeof(float) * 3) || !memcmp(((DispCmdSquare *) cmd_ptr)->pos2, ((DispCmdSquare *) cmd_ptr)->pos3, sizeof(float) * 3) || !memcmp(((DispCmdSquare *) cmd_ptr)->pos2, ((DispCmdSquare *) cmd_ptr)->pos4, sizeof(float) * 3) || !memcmp(((DispCmdSquare *) cmd_ptr)->pos3, ((DispCmdSquare *) cmd_ptr)->pos4, sizeof(float) * 3)) { // degenerate quadrilateral break; } // allocate memory depth_obj.points = (float *) malloc(sizeof(float) * 8); if (!depth_obj.points) { // memory error if (!memerror) { memerror = 1; msgErr << "PSDisplayDevice: Out of memory. Some " << "objects were not drawn." << sendmsg; } break; } // copy data depth_obj.npoints = 4; depth_obj.color = colorIndex; (transMat.top()).multpoint3d(((DispCmdSquare *) cmd_ptr)->pos1, a); (transMat.top()).multpoint3d(((DispCmdSquare *) cmd_ptr)->pos2, b); (transMat.top()).multpoint3d(((DispCmdSquare *) cmd_ptr)->pos3, c); (transMat.top()).multpoint3d(((DispCmdSquare *) cmd_ptr)->pos4, d); memcpy(depth_obj.points, a, sizeof(float) * 2); memcpy(&depth_obj.points[2], b, sizeof(float) * 2); memcpy(&depth_obj.points[4], c, sizeof(float) * 2); memcpy(&depth_obj.points[6], d, sizeof(float) * 2); // compute the centerpoint of the object cent[0] = (a[0] + b[0] + c[0] + d[0]) / 4; cent[1] = (a[1] + b[1] + c[1] + d[1]) / 4; cent[2] = (a[2] + b[2] + c[2] + d[2]) / 4; // compute the distance to the eye for depth sorting depth_obj.dist = compute_dist(cent); // compute a light shading factor depth_obj.light_scale = compute_light(a, b, c); // valid object to depth sort draw = 1; break; case DCOLORINDEX: colorIndex = ((DispCmdColorIndex *) cmd_ptr)->color; break; case DSPHERERES: set_sphere_res(((int *) cmd_ptr)[0]); break; default: // unknown object, so just skip it break; } // if we have a valid object to add to the depth sort list if (draw && depth_obj.npoints) { memusage += sizeof(float) * 2 * depth_obj.npoints; if ( depth_obj.text ) memusage += sizeof(char) * (1+strlen(depth_obj.text)); points += depth_obj.npoints; objects++; depth_list.append(depth_obj); } depth_obj.npoints = 0; depth_obj.points = NULL; } // while (tok != DLASTCOMMAND) transMat.pop(); } // end for() [periodic images] }
// 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(); }