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

LibGelatoDisplayDevice.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: LibGelatoDisplayDevice.C
00013 *      $Author: johns $      $Locker:  $               $State: Exp $
00014 *      $Revision: 1.14 $         $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 "LibGelatoDisplayDevice.h"
00028 #include "gelatoapi.h"
00029 #include "config.h"     // needed for default image viewer
00030 
00031 // The default radius for points and lines (which are displayed
00032 // as small spheres or cylinders, respectively)
00033 #define DEFAULT_RADIUS  0.0025f
00034 
00036 LibGelatoDisplayDevice::LibGelatoDisplayDevice() 
00037 : FileRenderer("GelatoInternal", "NVIDIA Gelato 2.1 (internal, in-memory rendering)", "vmdscene.tif", DEF_VMDIMAGEVIEWER) {
00038   reset_vars(); // initialize material cache
00039   gapi = GelatoAPI::CreateRenderer(); // create gelato rendering context
00040 
00041   // check for valid Gelato handle
00042   if (gapi == NULL) {
00043     msgErr << "Failed to initialize Gelato rendering library" << sendmsg;
00044   }
00045 }
00046         
00048 LibGelatoDisplayDevice::~LibGelatoDisplayDevice(void) {
00049   delete gapi;
00050 }
00051 
00052 
00054 void LibGelatoDisplayDevice::reset_vars(void) {
00055   old_color[0] = -1;
00056   old_color[1] = -1;
00057   old_color[2] = -1;
00058   old_ambient = -1;
00059   old_specular = -1;
00060   old_opacity = -1;
00061   old_diffuse = -1;
00062 }
00063 
00064 
00066 void LibGelatoDisplayDevice::point(float * spdata) {
00067   float vec[3];
00068   // Transform the world coordinates
00069   (transMat.top()).multpoint3d(spdata, vec);
00070 
00071   gapi->PushTransform();
00072   write_materials(1);
00073   gapi->Translate(vec[0], vec[1], vec[2]);
00074   gapi->Sphere((float)  lineWidth * DEFAULT_RADIUS,
00075                (float) -lineWidth * DEFAULT_RADIUS,
00076                (float)  lineWidth * DEFAULT_RADIUS,
00077                360);
00078   gapi->PopTransform();
00079 }
00080 
00081 
00083 void LibGelatoDisplayDevice::sphere(float * spdata) {
00084   float vec[3];
00085   float radius;
00086 
00087   // Transform the world coordinates
00088   (transMat.top()).multpoint3d(spdata, vec);
00089   radius = scale_radius(spdata[3]);
00090   if (radius < DEFAULT_RADIUS) {
00091     radius = (float) DEFAULT_RADIUS;
00092   }
00093 
00094   // Draw the sphere
00095   gapi->PushTransform();
00096   write_materials(1);
00097   gapi->Translate(vec[0], vec[1], vec[2]);
00098   gapi->Sphere(radius, -radius, radius, 360);
00099   gapi->PopTransform();
00100 }
00101 
00102 
00103 
00105 void LibGelatoDisplayDevice::line(float *a, float *b) {
00106   cylinder(a, b, (float) (lineWidth * DEFAULT_RADIUS), 0);
00107 }
00108 
00109 
00112 #if 0
00113 
00114 void LibGelatoDisplayDevice::cylinder(float *a, float *b, float r, 
00115                               int /* filled */ ) {
00116 }
00117 
00118 
00120 void LibGelatoDisplayDevice::cone(float *a, float *b, float r) {
00121 }
00122 #endif  
00123 
00124 
00125 // draw a triangle
00126 void LibGelatoDisplayDevice::triangle(const float *a, const float *b, const float *c, const float *n1, const float *n2, const float *n3) {
00127   int nverts = 3;
00128   int verts[] = {0, 1, 2};
00129   float points[9];
00130   float norms[9];
00131 
00132   // Transform the world coordinates
00133   (transMat.top()).multpoint3d(a, &points[0]);
00134   (transMat.top()).multpoint3d(b, &points[3]);
00135   (transMat.top()).multpoint3d(c, &points[6]);
00136   (transMat.top()).multnorm3d(n1, &norms[0]);
00137   (transMat.top()).multnorm3d(n2, &norms[3]);
00138   (transMat.top()).multnorm3d(n3, &norms[6]);
00139 
00140   // Write the triangle
00141   write_materials(1);
00142 
00143   gapi->Parameter("vertex point P", (float *) &points);
00144   gapi->Parameter("vertex normal P", (float *) &norms);
00145   gapi->Mesh("linear", 1, &nverts, verts);
00146 }
00147 
00148 
00149 // draw a tricolor
00150 void LibGelatoDisplayDevice::tricolor(const float *a, const float *b, const float *c,
00151                       const float *n1, const float *n2, const float *n3,
00152                       const float *c1, const float *c2, const float *c3) {
00153   int nverts = 3;
00154   int verts[] = {0, 1, 2};
00155   float points[9];
00156   float norms[9];
00157   float colors[9];
00158 
00159   // Transform the world coordinates
00160   (transMat.top()).multpoint3d(a, &points[0]);
00161   (transMat.top()).multpoint3d(b, &points[3]);
00162   (transMat.top()).multpoint3d(c, &points[6]);
00163   (transMat.top()).multnorm3d(n1, &norms[0]);
00164   (transMat.top()).multnorm3d(n2, &norms[3]);
00165   (transMat.top()).multnorm3d(n3, &norms[6]);
00166 
00167   // copy colors
00168   memcpy(&colors[0], c1, 3*sizeof(float));
00169   memcpy(&colors[3], c2, 3*sizeof(float));
00170   memcpy(&colors[6], c3, 3*sizeof(float));
00171  
00172   // Write the triangle
00173   write_materials(0);
00174 
00175   gapi->Parameter("vertex point P", (float *) &points);
00176   gapi->Parameter("vertex normal P", (float *) &norms);
00177   gapi->Parameter("vertex color C", (float *) &colors);
00178   gapi->Mesh("linear", 1, &nverts, verts);
00179 }
00180 
00181 void LibGelatoDisplayDevice::trimesh_c4n3v3(int numverts, float * cnv,
00182                                             int numfacets, int * facets) {
00183   // XXX replace this with real mesh code asap
00184   int i;
00185   for (i=0; i<numfacets; i++) {
00186     int ind = i * 3;
00187     int v0 = facets[ind    ] * 10;
00188     int v1 = facets[ind + 1] * 10;
00189     int v2 = facets[ind + 2] * 10;
00190     tricolor(cnv + v0 + 7, // vertices 0, 1, 2
00191              cnv + v1 + 7,
00192              cnv + v2 + 7,
00193              cnv + v0 + 4, // normals 0, 1, 2
00194              cnv + v1 + 4,
00195              cnv + v2 + 4,
00196              cnv + v0,     // colors 0, 1, 2
00197              cnv + v1,
00198              cnv + v2);
00199   }
00200 }
00201 
00202 
00203 void LibGelatoDisplayDevice::tristrip(int numverts, const float * cnv,
00204                                    int numstrips, const int *vertsperstrip,
00205                                    const int *facets) {
00206   // XXX replace this with real mesh code asap
00207 
00208   // render triangle strips one triangle at a time
00209   // triangle winding order is:
00210   //   v0, v1, v2, then v2, v1, v3, then v2, v3, v4, etc.
00211   int strip, t, v = 0;
00212   int stripaddr[2][3] = { {0, 1, 2}, {1, 0, 2} };
00213 
00214   // loop over all of the triangle strips
00215   for (strip=0; strip < numstrips; strip++) {
00216     // loop over all triangles in this triangle strip
00217     for (t = 0; t < (vertsperstrip[strip] - 2); t++) {
00218       // render one triangle, using lookup table to fix winding order
00219       int v0 = facets[v + (stripaddr[t & 0x01][0])] * 10;
00220       int v1 = facets[v + (stripaddr[t & 0x01][1])] * 10;
00221       int v2 = facets[v + (stripaddr[t & 0x01][2])] * 10;
00222 
00223       tricolor(cnv + v0 + 7, // vertices 0, 1, 2
00224                cnv + v1 + 7,
00225                cnv + v2 + 7,
00226                cnv + v0 + 4, // normals 0, 1, 2
00227                cnv + v1 + 4,
00228                cnv + v2 + 4,
00229                cnv + v0,     // colors 0, 1, 2
00230                cnv + v1,
00231                cnv + v2);
00232       v++; // move on to next vertex
00233     }
00234     v+=2; // last two vertices are already used by last triangle
00235   }
00236 }
00237 
00238 
00239 // draw a square
00240 void LibGelatoDisplayDevice::square(float *n, float *a, float *b, float *c, float *d) {
00241   int nverts = 4;
00242   int verts[] = {0, 1, 2, 4};
00243   float points[12];
00244   float norms[12];
00245 
00246   // Transform the world coordinates
00247   (transMat.top()).multpoint3d(a, &points[0]);
00248   (transMat.top()).multpoint3d(b, &points[3]);
00249   (transMat.top()).multpoint3d(c, &points[6]);
00250   (transMat.top()).multpoint3d(d, &points[9]);
00251   (transMat.top()).multnorm3d(n, &norms[0]);
00252   memcpy(&norms[3], &norms[0], 3*sizeof(float)); // all verts use same normal
00253   memcpy(&norms[6], &norms[0], 3*sizeof(float));
00254   memcpy(&norms[9], &norms[0], 3*sizeof(float));
00255 
00256   // Write the triangle
00257   write_materials(1);
00258 
00259   gapi->Parameter("vertex point P", (float *) &points);
00260   gapi->Parameter("vertex normal P", (float *) &norms);
00261   gapi->Mesh("linear", 1, &nverts, verts);
00262 }
00263 
00264 
00266 
00267 void LibGelatoDisplayDevice::write_header() {
00268   int i, n;
00269 
00270   // Initialize the Gelato output, lighting, and camera information
00271   gapi->Output(my_filename, "tiff", "rgba", "camera");
00272 
00273 // XXX these are assumed default for now, may set them later
00274 // "float gain", 1, "float gamma", 1, "string filter", "gaussian", "float[2] filterwidth", (2, 2)));
00275 
00276   int res[2];
00277   res[0] = xSize;
00278   res[1] = ySize;
00279   gapi->Attribute("int[2] resolution",  res);
00280 
00281   // Make coordinate system right-handed
00282   gapi->Scale(1, 1, -1);
00283 
00284   if (projection() == PERSPECTIVE) {
00285     gapi->Attribute("string projection",  "perspective");
00286     float fov=360.0*atan2((double)0.5*vSize, (double)eyePos[2]-zDist)*VMD_1_PI;
00287     gapi->Attribute("float fov", &fov);
00288   } else {
00289     gapi->Attribute("string projection",  "orthographic");
00290     // scaling necessary to equalize sizes of vmd screen and image 
00291     float screen[4];
00292     screen[0] = -Aspect*vSize/4;
00293     screen[1] =  Aspect*vSize/4;
00294     screen[2] = -vSize/4;
00295     screen[3] =  vSize/4;
00296     gapi->Attribute("float[4] screen", &screen);
00297   }
00298 
00299   // set near/far clipping planes
00300   gapi->Attribute("float near", &nearClip);
00301   gapi->Attribute("float far", &farClip);
00302 
00303   // Set up the camera position
00304   gapi->Translate(-eyePos[0], -eyePos[1], -eyePos[2]);
00305 
00306 #if 0
00307   // shadows on, comment out for no shadows
00308   fprintf( outfile, "Declare \"shadows\" \"string\"\n");
00309   fprintf( outfile, "Attribute \"light\" \"shadows\" \"on\"\n" );
00310 #endif
00311 
00312   // ambient light source
00313   char lightname[1024];
00314   sprintf(lightname, "light0");
00315   float intensity = 1.0;
00316   float ambcolor[3], lightorigin[3];
00317   ambcolor[0] = 1.0;
00318   ambcolor[1] = 1.0;
00319   ambcolor[2] = 1.0;
00320   lightorigin[0] = 0.0;
00321   lightorigin[1] = 0.0;
00322   lightorigin[2] = 0.0;
00323 
00324   gapi->Parameter("float intensity", &intensity);
00325   gapi->Parameter("color lightcolor", ambcolor);
00326   gapi->Light("light0", "ambientlight");
00327 
00328   // Write out all the light sources as point lights
00329   n = 1;
00330   for (i = 0; i < DISP_LIGHTS; i++) {
00331     if (lightState[i].on) {
00332       gapi->Parameter("float intensity", &intensity);
00333       gapi->Parameter("color lightcolor", lightState[i].color);
00334       gapi->Parameter("point from", lightState[i].pos);
00335       gapi->Parameter("point to", lightorigin);
00336       sprintf(lightname, "light%d", n);
00337       n++,
00338       gapi->Light(lightname, "distantlight");
00339     }
00340   }
00341 
00342   gapi->World();
00343 
00344   // Gelato background color shader
00345   // Background colors slow down rendering,\n");
00346   // but this is what VMD users expect.\n");
00347   // Comment these lines for a transparent background.\n");
00348   gapi->PushAttributes();
00349   gapi->Shader("surface", "constant");
00350   gapi->Attribute("color C", backColor);
00351   gapi->Input("backplane.pyg");
00352   gapi->PopAttributes();
00353 }
00354 
00355 
00356 void LibGelatoDisplayDevice::write_trailer(void){
00357   gapi->Render("camera");
00358   reset_vars(); // reinitialize material cache
00359 }
00360 
00361 
00362 void LibGelatoDisplayDevice::write_materials(int write_color) {
00363   // keep track of what the last written material properties
00364   // are, that way we can avoid writing redundant def's
00365   if (write_color) {
00366     // the color has changed since last write, emit an update 
00367     if ((matData[colorIndex][0] != old_color[0]) ||
00368         (matData[colorIndex][1] != old_color[1]) ||
00369         (matData[colorIndex][2] != old_color[2])) {
00370       fprintf(outfile, "Attribute(\"color C\",  (%g, %g, %g))\n",
00371               matData[colorIndex][0], 
00372               matData[colorIndex][1],
00373               matData[colorIndex][2]);
00374       // save the last color
00375       memcpy(old_color, matData[colorIndex], sizeof(float) * 3);
00376     }
00377   }
00378 
00379   // now check opacity
00380   if (mat_opacity != old_opacity) {
00381     float opacity[3];
00382     opacity[0] = mat_opacity;
00383     opacity[1] = mat_opacity;
00384     opacity[2] = mat_opacity;
00385 
00386     gapi->Attribute("color opacity", opacity);
00387     old_opacity = mat_opacity;
00388   }
00389 
00390   // and the lighting and roughness coefficients
00391   if ((mat_ambient != old_ambient) || 
00392       (mat_diffuse != old_diffuse) ||
00393       (mat_specular != old_specular)) {
00394     float roughness=10000.0;
00395     if (mat_shininess > 0.00001) {
00396       roughness = 1.0 / mat_shininess;
00397     }
00398     gapi->Parameter("float Ka", &mat_ambient);
00399     gapi->Parameter("float Kd", &mat_diffuse);
00400     gapi->Parameter("float Ks", &mat_specular);
00401     gapi->Parameter("float roughness", &roughness);
00402     gapi->Shader("surface", "plastic");
00403     old_ambient = mat_ambient;
00404     old_specular = mat_specular;
00405     old_diffuse = mat_diffuse;
00406   }
00407 }
00408 
00409 
00410 

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