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

GelatoDisplayDevice.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: GelatoDisplayDevice.C
00013 *      $Author: johns $      $Locker:  $               $State: Exp $
00014 *      $Revision: 1.31 $         $Date: 2011/11/10 17:05:34 $
00015 *
00016 ***************************************************************************
00017 * DESCRIPTION:
00018 *
00019 * FileRenderer type for the Gelato interface.
00020 *
00021 ***************************************************************************/
00022 
00023 #include <math.h>
00024 #include <stdlib.h>
00025 #include <stdio.h>
00026 #include <string.h>
00027 #include "GelatoDisplayDevice.h"
00028 #include "DispCmds.h"  // needed for line styles
00029 #include "config.h"    // for VMDVERSION string
00030 #include "Hershey.h"   // needed for Hershey font rendering fctns
00031 
00032 // The default radius for points and lines (which are displayed
00033 // as small spheres or cylinders, respectively)
00034 #define DEFAULT_RADIUS  0.0025f
00035 #define DASH_LENGTH 0.02f
00036 
00041 static int intersectlines2D(float *p1, float *t1, float *p2, float *t2, 
00042                             float *p) {
00043   float ua, ub, den, nomua, nomub;
00044 
00045   den = t2[1]*t1[0] - t2[0]*t1[1];
00046 
00047   if(fabs(den) < 1.0e-6)
00048     return 0;
00049 
00050   nomua = (t2[0]*(p1[1]-p2[1]) - t2[1]*(p1[0]-p2[0]));
00051   nomub = (t1[0]*(p1[1]-p2[1]) - t1[1]*(p1[0]-p2[0]));
00052 
00053   if((fabs(den) < 1.0e-6) &&
00054      (fabs(nomua) < 1.0e-6) &&
00055      (fabs(nomub) < 1.0e-6))
00056     return 0;
00057 
00058   ua = nomua/den;
00059   ub = nomub/den;
00060 
00061   p[0] = p1[0] + ua*t1[0];
00062   p[1] = p1[1] + ua*t1[1];
00063 
00064  return 1;
00065 } // intersectlines2D
00066 
00067 
00069 static int fullcirclearc(float r, float *U, float *Pw) {
00070   float P0[4] = {0};
00071   float P1[4] = {0};
00072   float P2[4] = {0};
00073   float T0[2] = {0};
00074   float T2[2] = {0};
00075   float theta = (float) VMD_TWOPI;
00076   float dtheta = theta/4.0f;
00077   float w1 = cosf(dtheta/2.0f); // dtheta/2 == base angle
00078 
00079 
00080   P0[0] = r;
00081   P0[1] = 0;
00082   P0[3] = 1.0;
00083   T0[0] = 0;
00084   T0[1] = 1;
00085   Pw[0] = P0[0];
00086   Pw[1] = P0[1];
00087   Pw[3] = 1.0;
00088   int index = 0; 
00089 
00090   float angle = 0.0;
00091   int i;
00092   for(i = 1; i <= 4; i++) {
00093     angle += dtheta;
00094 
00095     P2[0] = r * cosf(angle);
00096     P2[1] = r * sinf(angle);
00097     P2[3] = 1.0;
00098     T2[0] = -sinf(angle);
00099     T2[1] = cosf(angle);
00100 
00101     //memset(P1,0,4*sizeof(float));
00102     intersectlines2D(P0, T0, P2, T2, P1);
00103 
00104     Pw[ (index+1)*4   ] = w1*P1[0];
00105     Pw[((index+1)*4)+1] = w1*P1[1];
00106     Pw[((index+1)*4)+3] = w1;
00107 
00108     memcpy(&Pw[(index+2)*4], P2, 4*sizeof(float));
00109 
00110     index += 2;
00111     if(i < index) {
00112       memcpy(P0, P2, 4*sizeof(float));
00113       memcpy(T0, T2, 2*sizeof(float));
00114     }
00115   }
00116 
00117   for(i = 0; i < 3; i++) {
00118     U[i  ] = 0.0;
00119     U[i+9] = 1.0;
00120   }
00121 
00122   U[3] = 0.25;
00123   U[4] = 0.25;
00124   U[5] = 0.5;
00125   U[6] = 0.5;
00126   U[7] = 0.75;
00127   U[8] = 0.75;
00128 
00129   return 1;
00130 } // fullcirclearc
00131 
00132 
00133 
00135 
00136 GelatoDisplayDevice::GelatoDisplayDevice() 
00137 : FileRenderer("Gelato", "NVIDIA Gelato 2.1", "vmdscene.pyg", "gelato %s") {
00138   reset_vars(); // initialize material cache
00139 }
00140         
00142 GelatoDisplayDevice::~GelatoDisplayDevice(void) { }
00143 
00144 
00146 void GelatoDisplayDevice::reset_vars(void) {
00147   old_color[0] = -1;
00148   old_color[1] = -1;
00149   old_color[2] = -1;
00150   old_ambient = -1;
00151   old_specular = -1;
00152   old_opacity = -1;
00153   old_diffuse = -1;
00154 }
00155 
00156 void GelatoDisplayDevice::text(float *pos, float size, float thickness,
00157                                const char *str) {
00158   float textpos[3];
00159   float textsize, textthickness;
00160   hersheyhandle hh;
00161 
00162   // transform the world coordinates
00163   (transMat.top()).multpoint3d(pos, textpos);
00164   textsize = size * 1.5f;
00165   textthickness = thickness*DEFAULT_RADIUS;
00166 
00167   while (*str != '\0') {
00168     float lm, rm, x, y, ox, oy;
00169     int draw, odraw;
00170     ox=oy=x=y=0.0f;
00171     draw=odraw=0;
00172 
00173     hersheyDrawInitLetter(&hh, *str, &lm, &rm);
00174     textpos[0] -= lm * textsize;
00175 
00176     while (!hersheyDrawNextLine(&hh, &draw, &x, &y)) {
00177       float oldpt[3], newpt[3];
00178       if (draw) {
00179         newpt[0] = textpos[0] + textsize * x;
00180         newpt[1] = textpos[1] + textsize * y;
00181         newpt[2] = textpos[2];
00182 
00183         if (odraw) {
00184           // if we have both previous and next points, connect them...
00185           oldpt[0] = textpos[0] + textsize * ox;
00186           oldpt[1] = textpos[1] + textsize * oy;
00187           oldpt[2] = textpos[2];
00188 
00189           cylinder_nurb_noxfrm(oldpt, newpt, textthickness, 0); 
00190 
00191           fprintf(outfile, "PushTransform()\n");
00192           write_materials(1);
00193           fprintf(outfile, "Translate(%g, %g, %g)\n", 
00194                   newpt[0], newpt[1], newpt[2]);
00195           fprintf(outfile, "Sphere(%g, %g, %g, 360)\n", 
00196                   textthickness, -textthickness, textthickness);
00197           fprintf(outfile, "PopTransform()\n");
00198         } else {
00199           // ...otherwise, just draw the next point
00200           fprintf(outfile, "PushTransform()\n");
00201           write_materials(1);
00202           fprintf(outfile, "Translate(%g, %g, %g)\n", 
00203                   newpt[0], newpt[1], newpt[2]);
00204           fprintf(outfile, "Sphere(%g, %g, %g, 360)\n", 
00205                   textthickness, -textthickness, textthickness);
00206           fprintf(outfile, "PopTransform()\n");
00207         }
00208       }
00209 
00210       ox=x;
00211       oy=y;
00212       odraw=draw;
00213     }
00214     textpos[0] += rm * textsize;
00215 
00216     str++;
00217   }
00218 }
00219 
00220 
00222 void GelatoDisplayDevice::point(float * spdata) {
00223   float vec[3];
00224   // Transform the world coordinates
00225   (transMat.top()).multpoint3d(spdata, vec);
00226 
00227   fprintf(outfile, "PushTransform()\n");
00228   write_materials(1);
00229   fprintf(outfile, "Translate(%g, %g, %g)\n", vec[0], vec[1], vec[2]);
00230   fprintf(outfile, "Sphere(%g, %g, %g, 360)\n",
00231     (float)  lineWidth * DEFAULT_RADIUS,
00232     (float) -lineWidth * DEFAULT_RADIUS,
00233     (float)  lineWidth * DEFAULT_RADIUS);
00234   fprintf(outfile, "PopTransform()\n");
00235 }
00236 
00237 
00239 void GelatoDisplayDevice::sphere(float * spdata) {
00240   float vec[3];
00241   float radius;
00242 
00243   // Transform the world coordinates
00244   (transMat.top()).multpoint3d(spdata, vec);
00245   radius = scale_radius(spdata[3]);
00246   if (radius < DEFAULT_RADIUS) {
00247     radius = (float) DEFAULT_RADIUS;
00248   }
00249 
00250   // Draw the sphere
00251   fprintf(outfile, "PushTransform()\n");
00252   write_materials(1);
00253   fprintf(outfile, "Translate(%g, %g, %g)\n", vec[0], vec[1], vec[2]);
00254   fprintf(outfile, "Sphere(%g, %g, %g, 360)\n", radius, -radius, radius);
00255   fprintf(outfile, "PopTransform()\n");
00256 }
00257 
00258 
00260 void GelatoDisplayDevice::line(float *a, float *b) {
00261   int i, j, test;
00262   float dirvec[3], unitdirvec[3];
00263   float from[3], to[3], tmp1[3], tmp2[3];
00264    
00265   if (lineStyle == ::SOLIDLINE) {
00266     // transform the world coordinates
00267     (transMat.top()).multpoint3d(a, from);
00268     (transMat.top()).multpoint3d(b, to);
00269    
00270     cylinder_nurb_noxfrm(from, to, (float) (lineWidth * DEFAULT_RADIUS), 0);
00271   } else if (lineStyle == ::DASHEDLINE) {
00272      // transform the world coordinates
00273     (transMat.top()).multpoint3d(a, tmp1);
00274     (transMat.top()).multpoint3d(b, tmp2);
00275 
00276     // how to create a dashed line
00277     vec_sub(dirvec, tmp2, tmp1);  // vector from a to b
00278     vec_copy(unitdirvec, dirvec);
00279     vec_normalize(unitdirvec);    // unit vector from a to b
00280     test = 1;
00281     i = 0;
00282     while (test == 1) {
00283       for (j=0; j<3; j++) {
00284         from[j] = (float) (tmp1[j] + (2*i    )*DASH_LENGTH*unitdirvec[j]);
00285           to[j] = (float) (tmp1[j] + (2*i + 1)*DASH_LENGTH*unitdirvec[j]);
00286       }
00287       if (fabsf(tmp1[0] - to[0]) >= fabsf(dirvec[0])) {
00288         vec_copy(to, tmp2);
00289         test = 0;
00290       }
00291    
00292       cylinder_nurb_noxfrm(from, to, (float) (lineWidth * DEFAULT_RADIUS), 0);
00293       i++;
00294     }
00295   } else {
00296     msgErr << "GelatoDisplayDevice: Unknown line style "
00297            << lineStyle << sendmsg;
00298   }
00299 }
00300 
00302 void GelatoDisplayDevice::cylinder(float *a, float *b, float r, int filled) {
00303   float vec1[3], vec2[3], radius;
00304    
00305   if (filled) {
00306     FileRenderer::cylinder(a, b, r, filled);
00307     return;
00308   }
00309 
00310   // Transform the world coordinates
00311   (transMat.top()).multpoint3d(a, vec1);
00312   (transMat.top()).multpoint3d(b, vec2);
00313   radius = scale_radius(r);
00314 
00315   cylinder_nurb_noxfrm(vec1, vec2, radius, filled);
00316 }
00317 
00319 void GelatoDisplayDevice::cylinder_nurb_noxfrm(float *vec1, float *vec2, 
00320                                                float radius, int filled) {
00321   float axis[3];
00322   float R, phi, rxy, theta;
00323 
00324   // safety check to prevent overly-tiny cylinders
00325   if (radius < DEFAULT_RADIUS) {
00326     radius = (float) DEFAULT_RADIUS;
00327   }
00328 
00329   // Gelato's cylinders always run along the z axis, and must
00330   // be transformed to the proper position and rotation. This
00331   // code is taken from OpenGLRenderer.C.
00332   axis[0] = vec2[0] - vec1[0];
00333   axis[1] = vec2[1] - vec1[1];
00334   axis[2] = vec2[2] - vec1[2];
00335 
00336   R = axis[0] * axis[0] + axis[1] * axis[1] + axis[2] * axis[2];
00337   if (R <= 0) return;
00338 
00339   R = sqrtf(R); // evaluation of sqrt() _after_ early exit
00340 
00341   // determine phi rotation angle, amount to rotate about y
00342   phi = acosf(axis[2] / R);
00343 
00344   // determine theta rotation, amount to rotate about z
00345   rxy = sqrtf(axis[0] * axis[0] + axis[1] * axis[1]);
00346   if (rxy <= 0) {
00347     theta = 0;
00348   } else {
00349     theta = acosf(axis[0] / rxy);
00350     if (axis[1] < 0) theta = (float) (2.0 * VMD_PI) - theta;
00351   }
00352 
00353   // Write the cylinder, reorienting and translating it to the correct location
00354   fprintf(outfile, "PushTransform()\n");
00355   write_materials(1);
00356   fprintf(outfile, "Translate(%g,%g,%g)\n", vec1[0], vec1[1], vec1[2]);
00357   if (theta) 
00358     fprintf(outfile, "Rotate(%g,0,0,1)\n", (theta / VMD_PI) * 180);
00359   if (phi) 
00360     fprintf(outfile, "Rotate(%g,0,1,0)\n", (phi / VMD_PI) * 180);
00361 
00362   // Calculate the NURBS parameters for Cylinder(radius, 0, R, 360) 
00363   // on the Z axis.  This is mostly hard-coded for speed.
00364   int A, i;
00365   float zmin = 0.0;
00366   float zmax = R;
00367   float circcv[9*4];
00368   float uknotv[9+4]; 
00369   float vknotv[4] = {0.0f,0.0f,1.0f,1.0f};
00370   float controlv[9*2*4];
00371 
00372   fullcirclearc(radius, uknotv, circcv); // generate full circle arc
00373   memcpy(controlv, circcv, 9*4*sizeof(float));
00374   A=0;
00375   for(i=0; i<9; i++) {
00376     controlv[A+2] = zmin * controlv[A+3];
00377     A+=4;
00378   }
00379   A=9*4;
00380   memcpy(&(controlv[A]), circcv, 9*4*sizeof(float));
00381   for(i = 0; i < 9; i++) {
00382     controlv[A+2] = zmax * controlv[A+3];
00383     A += 4;
00384   }
00385 
00386   // draw the NURBS Cylinder using the Gelato Patch primitive
00387   fprintf(outfile, "Patch(%d,3,(", 9);
00388   for (i=0; i<9+3; i++) {
00389     fprintf(outfile, "%g,", uknotv[i]);
00390   }
00391   fprintf(outfile, "),0,1,2,2,(");
00392   for (i=0; i<4; i++) {
00393     fprintf(outfile, "%g,", vknotv[i]);
00394   }
00395   fprintf(outfile, "),0,1,\"vertex hpoint Pw\", (");
00396   for (i=0; i<9*2*4; i++) {
00397     fprintf(outfile, "%g,", controlv[i]);
00398   }
00399   fprintf(outfile, "))\n");
00400 
00401   fprintf(outfile, "PopTransform()\n");
00402 }
00403 
00404 
00405 // draw a triangle
00406 void GelatoDisplayDevice::triangle(const float *a, const float *b, const float *c, const float *n1, const float *n2, const float *n3) {
00407   float vec1[3], vec2[3], vec3[3];
00408   float norm1[3], norm2[3], norm3[3];
00409 
00410   // Transform the world coordinates
00411   (transMat.top()).multpoint3d(a, vec1);
00412   (transMat.top()).multpoint3d(b, vec2);
00413   (transMat.top()).multpoint3d(c, vec3);
00414   (transMat.top()).multnorm3d(n1, norm1);
00415   (transMat.top()).multnorm3d(n2, norm2);
00416   (transMat.top()).multnorm3d(n3, norm3);
00417 
00418   // Write the triangle
00419   write_materials(1);
00420   fprintf(outfile, "Mesh(\"linear\", (3,), (0, 1, 2), "
00421           "\"vertex point P\", (%g, %g, %g, %g, %g, %g, %g, %g, %g), "
00422           "\"vertex normal N\", (%g, %g, %g, %g, %g, %g, %g, %g, %g))\n",
00423           vec1[0], vec1[1], vec1[2],
00424           vec2[0], vec2[1], vec2[2],
00425           vec3[0], vec3[1], vec3[2],
00426           norm1[0], norm1[1], norm1[2],
00427           norm2[0], norm2[1], norm2[2],
00428           norm3[0], norm3[1], norm3[2]);
00429 }
00430 
00431 
00432 // draw a tricolor
00433 void GelatoDisplayDevice::tricolor(const float *a, const float *b, const float *c,
00434                       const float *n1, const float *n2, const float *n3,
00435                       const float *c1, const float *c2, const float *c3) {
00436   float vec1[3], vec2[3], vec3[3];
00437   float norm1[3], norm2[3], norm3[3];
00438 
00439   // Transform the world coordinates
00440   (transMat.top()).multpoint3d(a, vec1);
00441   (transMat.top()).multpoint3d(b, vec2);
00442   (transMat.top()).multpoint3d(c, vec3);
00443   (transMat.top()).multnorm3d(n1, norm1);
00444   (transMat.top()).multnorm3d(n2, norm2);
00445   (transMat.top()).multnorm3d(n3, norm3);
00446 
00447   // Write the triangle
00448   write_materials(0);
00449   fprintf(outfile, "Mesh(\"linear\", (3,), (0, 1, 2), "
00450           "\"vertex point P\", (%g, %g, %g, %g, %g, %g, %g, %g, %g), "
00451           "\"vertex normal N\", (%g, %g, %g, %g, %g, %g, %g, %g, %g), "
00452           "\"vertex color C\", (%g, %g, %g, %g, %g, %g, %g, %g, %g))\n",
00453           vec1[0], vec1[1], vec1[2],
00454           vec2[0], vec2[1], vec2[2],
00455           vec3[0], vec3[1], vec3[2],
00456           norm1[0], norm1[1], norm1[2],
00457           norm2[0], norm2[1], norm2[2],
00458           norm3[0], norm3[1], norm3[2],
00459           c1[0], c1[1], c1[2],
00460           c2[0], c2[1], c2[2],
00461           c3[0], c3[1], c3[2]);
00462 }
00463 
00464 void GelatoDisplayDevice::trimesh_c4n3v3(int numverts, float * cnv,
00465                                          int numfacets, int * facets) {
00466   float vec1[3];
00467   float norm1[3];
00468   int i;
00469 
00470   write_materials(0);
00471   fprintf(outfile, "Mesh(\"linear\", (");
00472  
00473   for (i=0; i<numfacets; i++) {
00474     fprintf(outfile, "3,");
00475   }
00476   fprintf(outfile, "), (");
00477 
00478   for (i=0; i<numfacets; i++) {
00479     fprintf(outfile, "%d, %d, %d,", facets[i*3], facets[i*3+1], facets[i*3+2]);
00480   }
00481   fprintf(outfile, "), ");
00482 
00483   fprintf(outfile, "\n\"vertex point P\", (");
00484   for (i=0; i<numverts; i++) {
00485     (transMat.top()).multpoint3d(cnv + i*10 + 7, vec1);
00486     fprintf(outfile, "%g, %g, %g,", vec1[0], vec1[1], vec1[2]);
00487   }
00488   fprintf(outfile, "), ");
00489   
00490   fprintf(outfile,  "\n\"vertex normal N\", (");
00491   for (i=0; i<numverts; i++) {
00492     (transMat.top()).multnorm3d(cnv + i*10 + 4, norm1);
00493     fprintf(outfile, "%g, %g, %g,", norm1[0], norm1[1], norm1[2]);
00494   }
00495   fprintf(outfile, "), ");
00496 
00497   fprintf(outfile,  "\n\"vertex color C\", (");
00498   for (i=0; i<numverts; i++) {
00499     float *c = cnv + i*10;
00500     fprintf(outfile, "%g, %g, %g,", c[0], c[1], c[2]);
00501   }
00502   fprintf(outfile, "))\n");
00503 }
00504 
00505 
00506 void GelatoDisplayDevice::tristrip(int numverts, const float * cnv,
00507                                    int numstrips, const int *vertsperstrip,
00508                                    const int *facets) {
00509   float vec1[3];
00510   float norm1[3];
00511   int i;
00512   // render triangle strips one triangle at a time
00513   // triangle winding order is:
00514   //   v0, v1, v2, then v2, v1, v3, then v2, v3, v4, etc.
00515   int strip, v = 0;
00516   int stripaddr[2][3] = { {0, 1, 2}, {1, 0, 2} };
00517 
00518   write_materials(0);
00519 
00520   fprintf(outfile, "Mesh(\"linear\", (");
00521 
00522   // loop over all of the triangle strips
00523   for (strip=0; strip < numstrips; strip++) {
00524     for (i=0; i<(vertsperstrip[strip] - 2); i++) {
00525       fprintf(outfile, "3,");
00526     }
00527   }
00528   fprintf(outfile, "), (");
00529 
00530   for (strip=0; strip < numstrips; strip++) {
00531     for (i=0; i<(vertsperstrip[strip] - 2); i++) {
00532       // render one triangle, using lookup table to fix winding order
00533       fprintf(outfile, "%d, %d, %d,", 
00534               facets[v + (stripaddr[i & 0x01][0])],
00535               facets[v + (stripaddr[i & 0x01][1])],
00536               facets[v + (stripaddr[i & 0x01][2])]);
00537       v++; // move on to next vertex
00538     }
00539     v+=2; // last two vertices are already used by last triangle
00540   }
00541   fprintf(outfile, "), ");
00542 
00543   fprintf(outfile, "\n\"vertex point P\", (");
00544   for (i=0; i<numverts; i++) {
00545     (transMat.top()).multpoint3d(cnv + i*10 + 7, vec1);
00546     fprintf(outfile, "%g, %g, %g,", vec1[0], vec1[1], vec1[2]);
00547   }
00548   fprintf(outfile, "), ");
00549   
00550   fprintf(outfile,  "\n\"vertex normal N\", (");
00551   for (i=0; i<numverts; i++) {
00552     (transMat.top()).multnorm3d(cnv + i*10 + 4, norm1);
00553     fprintf(outfile, "%g, %g, %g,", norm1[0], norm1[1], norm1[2]);
00554   }
00555   fprintf(outfile, "), ");
00556 
00557   fprintf(outfile,  "\n\"vertex color C\", (");
00558   for (i=0; i<numverts; i++) {
00559     const float *c = cnv + i*10;
00560     fprintf(outfile, "%g, %g, %g,", c[0], c[1], c[2]);
00561   }
00562   fprintf(outfile, "))\n");
00563 }
00564 
00565 
00566 // draw a square
00567 void GelatoDisplayDevice::square(float *n, float *a, float *b, float *c, float *d) {
00568   float vec1[3], vec2[3], vec3[3], vec4[3];
00569   float norm[3];
00570 
00571   // Transform the world coordinates
00572   (transMat.top()).multpoint3d(a, vec1);
00573   (transMat.top()).multpoint3d(b, vec2);
00574   (transMat.top()).multpoint3d(c, vec3);
00575   (transMat.top()).multpoint3d(d, vec4);
00576   (transMat.top()).multnorm3d(n, norm);
00577 
00578   // Write the square
00579   write_materials(1);
00580   fprintf(outfile, "Mesh(\"linear\", (4,), (0, 1, 2, 3), "
00581           "\"vertex point P\", "
00582           "(%g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g), "
00583           "\"vertex normal N\", "
00584           "(%g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g))\n",
00585           vec1[0], vec1[1], vec1[2],
00586           vec2[0], vec2[1], vec2[2],
00587           vec3[0], vec3[1], vec3[2],
00588           vec4[0], vec4[1], vec4[2],
00589           norm[0], norm[1], norm[2],
00590           norm[0], norm[1], norm[2],
00591           norm[0], norm[1], norm[2],
00592           norm[0], norm[1], norm[2]);
00593 }
00594 
00595 
00596 // display a comment
00597 void GelatoDisplayDevice::comment(const char *s) {
00598   fprintf(outfile, "# %s\n", s);
00599 }
00600 
00602 
00603 void GelatoDisplayDevice::write_header() {
00604   int i, n;
00605 
00606   // Initialize the Gelato interface
00607   fprintf(outfile, "# \n");
00608   fprintf(outfile, "# Molecular graphics export from VMD %s\n", VMDVERSION);
00609   fprintf(outfile, "# http://www.ks.uiuc.edu/Research/vmd/\n");
00610   fprintf(outfile, "# Requires NVIDIA Gelato 2.1, PYG format\n");
00611   fprintf(outfile, "# \n");
00612 
00613   fprintf(outfile, "Output(\"%s.tif\", \"tiff\", \"rgba\", \"camera\", \"float gain\", 1, \"float gamma\", 1, \"string filter\", \"gaussian\", \"float[2] filterwidth\", (2, 2))\n", my_filename);
00614   fprintf(outfile, "Attribute(\"int[2] resolution\",  (%ld, %ld))\n", xSize, ySize);
00615 #if 0
00616   fprintf(outfile, "Attribute(\"float pixelaspect\", %g)\n", 1.0);
00617   // XXX auto calculated by Gelato, seems to match correctly already
00618   fprintf(outfile, "FrameAspectRatio %g\n", Aspect);
00619 #endif
00620 
00621   // Make coordinate system right-handed
00622   fprintf(outfile, "Scale(1, 1, -1)\n");
00623 
00624   if (projection() == PERSPECTIVE) {
00625     fprintf(outfile, "Attribute(\"string projection\",  \"perspective\")\n");
00626     fprintf(outfile, "Attribute(\"float fov\", %g)\n",
00627             360.0*atan2((double) 0.5*vSize, (double) eyePos[2]-zDist)*VMD_1_PI);
00628   } else {
00629     fprintf(outfile, "Attribute(\"string projection\",  \"orthographic\")\n");
00630     // scaling necessary to equalize sizes of vmd screen and image 
00631     fprintf(outfile, "Attribute(\"float[4] screen\", (%g, %g, %g, %g))\n",
00632             -Aspect*vSize/4, Aspect*vSize/4, -vSize/4, vSize/4);
00633   }
00634 
00635   // Set up the camera position
00636   fprintf(outfile, "Attribute (\"float near\", %g)\n", nearClip);
00637   fprintf(outfile, "Attribute (\"float far\", %g)\n", farClip); 
00638   fprintf(outfile, "# translate for camera position\n");
00639   fprintf(outfile, "Translate(%g, %g, %g)\n", 
00640           -eyePos[0], -eyePos[1], -eyePos[2]);
00641 
00642 #if 0
00643   // shadows on, comment out for no shadows
00644   fprintf( outfile, "Declare \"shadows\" \"string\"\n");
00645   fprintf( outfile, "Attribute \"light\" \"shadows\" \"on\"\n" );
00646 #endif
00647 
00648   // ambient light source
00649   fprintf(outfile, "Light(\"light0\", \"ambientlight\", \"float intensity\", 1.0, \"color lightcolor\", (1, 1, 1))\n");
00650   
00651   n = 1;
00652   // Write out all the light sources as point lights
00653   for (i = 0; i < DISP_LIGHTS; i++) {
00654     if (lightState[i].on) {
00655 //      fprintf(outfile, "Light(\"light%d\", \"pointlight\", \"float intensity\", 1.0, \"color lightcolor\", (%g, %g, %g), \"point from\", (%g, %g, %g))\n",
00656         fprintf(outfile, "Light(\"light%d\", \"distantlight\", \"float intensity\", 1, \"color lightcolor\", (%g, %g, %g), \"point from\", (%g, %g, %g), \"point to\", (0, 0, 0))\n",
00657       n++,
00658       lightState[i].color[0], lightState[i].color[1], lightState[i].color[2],
00659       lightState[i].pos[0], lightState[i].pos[1], lightState[i].pos[2]);
00660     }
00661   }
00662 
00663 
00664   fprintf(outfile, "World()\n");
00665 
00666   // Gelato background color shader
00667   fprintf(outfile, "# Background colors slow down rendering,\n");
00668   fprintf(outfile, "# but this is what VMD users expect.\n");
00669   fprintf(outfile, "# Comment these lines for a transparent background.\n");
00670   fprintf(outfile, "PushAttributes()\n");
00671   fprintf(outfile, "Shader(\"surface\", \"constant\")\n");
00672   fprintf(outfile, "Attribute(\"color C\", (%g, %g, %g))\n",
00673           backColor[0], backColor[1], backColor[2]);
00674   fprintf(outfile, "Input(\"backplane.pyg\")\n");
00675   fprintf(outfile, "PopAttributes()\n");
00676 
00677 }
00678 
00679 
00680 void GelatoDisplayDevice::write_trailer(void){
00681   fprintf(outfile, "Render (\"camera\")\n");
00682   fprintf(outfile, "# End Input\n");
00683   reset_vars(); // reinitialize material cache
00684 }
00685 
00686 
00687 void GelatoDisplayDevice::write_materials(int write_color) {
00688   // keep track of what the last written material properties
00689   // are, that way we can avoid writing redundant def's
00690   if (write_color) {
00691     // the color has changed since last write, emit an update 
00692     if ((matData[colorIndex][0] != old_color[0]) ||
00693         (matData[colorIndex][1] != old_color[1]) ||
00694         (matData[colorIndex][2] != old_color[2])) {
00695       fprintf(outfile, "Attribute(\"color C\",  (%g, %g, %g))\n",
00696               matData[colorIndex][0], 
00697               matData[colorIndex][1],
00698               matData[colorIndex][2]);
00699       // save the last color
00700       memcpy(old_color, matData[colorIndex], sizeof(float) * 3);
00701     }
00702   }
00703 
00704   // now check opacity
00705   if (mat_opacity != old_opacity) {
00706     fprintf(outfile, "Attribute(\"color opacity\", (%g, %g, %g))\n", 
00707             mat_opacity, mat_opacity, mat_opacity);
00708     old_opacity = mat_opacity;
00709   }
00710 
00711   // and the lighting and roughness coefficients
00712   if ((mat_ambient != old_ambient) || 
00713       (mat_diffuse != old_diffuse) ||
00714       (mat_specular != old_specular)) {
00715     float roughness=10000.0f;
00716     if (mat_shininess > 0.00001f) {
00717       roughness = 1.0f / mat_shininess;
00718     }
00719     fprintf(outfile, "Shader(\"surface\", \"plastic\", " 
00720             "\"float Ka\", %g, \"float Kd\", %g, "
00721             "\"float Ks\", %g, \"float roughness\", %g)\n",
00722             mat_ambient, mat_diffuse, mat_specular, roughness);
00723     old_ambient = mat_ambient;
00724     old_specular = mat_specular;
00725     old_diffuse = mat_diffuse;
00726   }
00727 }
00728 
00729 
00730 

Generated on Wed May 16 01:49:17 2012 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002