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

GelatoDisplayDevice.C

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

Generated on Thu Mar 28 02:43:14 2024 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002