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

LibGelatoDisplayDevice.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: LibGelatoDisplayDevice.C
00013 *      $Author: johns $      $Locker:  $               $State: Exp $
00014 *      $Revision: 1.17 $         $Date: 2019/01/17 21:20:59 $
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 
00110 // draw a triangle
00111 void LibGelatoDisplayDevice::triangle(const float *a, const float *b, const float *c, const float *n1, const float *n2, const float *n3) {
00112   int nverts = 3;
00113   int verts[] = {0, 1, 2};
00114   float points[9];
00115   float norms[9];
00116 
00117   // Transform the world coordinates
00118   (transMat.top()).multpoint3d(a, &points[0]);
00119   (transMat.top()).multpoint3d(b, &points[3]);
00120   (transMat.top()).multpoint3d(c, &points[6]);
00121   (transMat.top()).multnorm3d(n1, &norms[0]);
00122   (transMat.top()).multnorm3d(n2, &norms[3]);
00123   (transMat.top()).multnorm3d(n3, &norms[6]);
00124 
00125   // Write the triangle
00126   write_materials(1);
00127 
00128   gapi->Parameter("vertex point P", (float *) &points);
00129   gapi->Parameter("vertex normal P", (float *) &norms);
00130   gapi->Mesh("linear", 1, &nverts, verts);
00131 }
00132 
00133 
00134 // draw a tricolor
00135 void LibGelatoDisplayDevice::tricolor(const float *a, const float *b, const float *c,
00136                       const float *n1, const float *n2, const float *n3,
00137                       const float *c1, const float *c2, const float *c3) {
00138   int nverts = 3;
00139   int verts[] = {0, 1, 2};
00140   float points[9];
00141   float norms[9];
00142   float colors[9];
00143 
00144   // Transform the world coordinates
00145   (transMat.top()).multpoint3d(a, &points[0]);
00146   (transMat.top()).multpoint3d(b, &points[3]);
00147   (transMat.top()).multpoint3d(c, &points[6]);
00148   (transMat.top()).multnorm3d(n1, &norms[0]);
00149   (transMat.top()).multnorm3d(n2, &norms[3]);
00150   (transMat.top()).multnorm3d(n3, &norms[6]);
00151 
00152   // copy colors
00153   memcpy(&colors[0], c1, 3*sizeof(float));
00154   memcpy(&colors[3], c2, 3*sizeof(float));
00155   memcpy(&colors[6], c3, 3*sizeof(float));
00156  
00157   // Write the triangle
00158   write_materials(0);
00159 
00160   gapi->Parameter("vertex point P", (float *) &points);
00161   gapi->Parameter("vertex normal P", (float *) &norms);
00162   gapi->Parameter("vertex color C", (float *) &colors);
00163   gapi->Mesh("linear", 1, &nverts, verts);
00164 }
00165 
00166 void LibGelatoDisplayDevice::trimesh_c4n3v3(int numverts, float * cnv,
00167                                             int numfacets, int * facets) {
00168   // XXX replace this with real mesh code asap
00169   int i;
00170   for (i=0; i<numfacets; i++) {
00171     int ind = i * 3;
00172     int v0 = facets[ind    ] * 10;
00173     int v1 = facets[ind + 1] * 10;
00174     int v2 = facets[ind + 2] * 10;
00175     tricolor(cnv + v0 + 7, // vertices 0, 1, 2
00176              cnv + v1 + 7,
00177              cnv + v2 + 7,
00178              cnv + v0 + 4, // normals 0, 1, 2
00179              cnv + v1 + 4,
00180              cnv + v2 + 4,
00181              cnv + v0,     // colors 0, 1, 2
00182              cnv + v1,
00183              cnv + v2);
00184   }
00185 }
00186 
00187 
00188 void LibGelatoDisplayDevice::tristrip(int numverts, const float * cnv,
00189                                    int numstrips, const int *vertsperstrip,
00190                                    const int *facets) {
00191   // XXX replace this with real mesh code asap
00192 
00193   // render triangle strips one triangle at a time
00194   // triangle winding order is:
00195   //   v0, v1, v2, then v2, v1, v3, then v2, v3, v4, etc.
00196   int strip, t, v = 0;
00197   int stripaddr[2][3] = { {0, 1, 2}, {1, 0, 2} };
00198 
00199   // loop over all of the triangle strips
00200   for (strip=0; strip < numstrips; strip++) {
00201     // loop over all triangles in this triangle strip
00202     for (t = 0; t < (vertsperstrip[strip] - 2); t++) {
00203       // render one triangle, using lookup table to fix winding order
00204       int v0 = facets[v + (stripaddr[t & 0x01][0])] * 10;
00205       int v1 = facets[v + (stripaddr[t & 0x01][1])] * 10;
00206       int v2 = facets[v + (stripaddr[t & 0x01][2])] * 10;
00207 
00208       tricolor(cnv + v0 + 7, // vertices 0, 1, 2
00209                cnv + v1 + 7,
00210                cnv + v2 + 7,
00211                cnv + v0 + 4, // normals 0, 1, 2
00212                cnv + v1 + 4,
00213                cnv + v2 + 4,
00214                cnv + v0,     // colors 0, 1, 2
00215                cnv + v1,
00216                cnv + v2);
00217       v++; // move on to next vertex
00218     }
00219     v+=2; // last two vertices are already used by last triangle
00220   }
00221 }
00222 
00223 
00224 // draw a square
00225 void LibGelatoDisplayDevice::square(float *n, float *a, float *b, float *c, float *d) {
00226   int nverts = 4;
00227   int verts[] = {0, 1, 2, 4};
00228   float points[12];
00229   float norms[12];
00230 
00231   // Transform the world coordinates
00232   (transMat.top()).multpoint3d(a, &points[0]);
00233   (transMat.top()).multpoint3d(b, &points[3]);
00234   (transMat.top()).multpoint3d(c, &points[6]);
00235   (transMat.top()).multpoint3d(d, &points[9]);
00236   (transMat.top()).multnorm3d(n, &norms[0]);
00237   memcpy(&norms[3], &norms[0], 3*sizeof(float)); // all verts use same normal
00238   memcpy(&norms[6], &norms[0], 3*sizeof(float));
00239   memcpy(&norms[9], &norms[0], 3*sizeof(float));
00240 
00241   // Write the triangle
00242   write_materials(1);
00243 
00244   gapi->Parameter("vertex point P", (float *) &points);
00245   gapi->Parameter("vertex normal P", (float *) &norms);
00246   gapi->Mesh("linear", 1, &nverts, verts);
00247 }
00248 
00249 
00251 
00252 void LibGelatoDisplayDevice::write_header() {
00253   int i, n;
00254 
00255   // Initialize the Gelato output, lighting, and camera information
00256   gapi->Output(my_filename, "tiff", "rgba", "camera");
00257 
00258 // XXX these are assumed default for now, may set them later
00259 // "float gain", 1, "float gamma", 1, "string filter", "gaussian", "float[2] filterwidth", (2, 2)));
00260 
00261   int res[2];
00262   res[0] = xSize;
00263   res[1] = ySize;
00264   gapi->Attribute("int[2] resolution",  res);
00265 
00266   // Make coordinate system right-handed
00267   gapi->Scale(1, 1, -1);
00268 
00269   if (projection() == PERSPECTIVE) {
00270     gapi->Attribute("string projection",  "perspective");
00271     float fov=360.0*atan2((double)0.5*vSize, (double)eyePos[2]-zDist)*VMD_1_PI;
00272     gapi->Attribute("float fov", &fov);
00273   } else {
00274     gapi->Attribute("string projection",  "orthographic");
00275     // scaling necessary to equalize sizes of vmd screen and image 
00276     float screen[4];
00277     screen[0] = -Aspect*vSize/4;
00278     screen[1] =  Aspect*vSize/4;
00279     screen[2] = -vSize/4;
00280     screen[3] =  vSize/4;
00281     gapi->Attribute("float[4] screen", &screen);
00282   }
00283 
00284   // set near/far clipping planes
00285   gapi->Attribute("float near", &nearClip);
00286   gapi->Attribute("float far", &farClip);
00287 
00288   // Set up the camera position
00289   gapi->Translate(-eyePos[0], -eyePos[1], -eyePos[2]);
00290 
00291 #if 0
00292   // shadows on, comment out for no shadows
00293   fprintf( outfile, "Declare \"shadows\" \"string\"\n");
00294   fprintf( outfile, "Attribute \"light\" \"shadows\" \"on\"\n" );
00295 #endif
00296 
00297   // ambient light source
00298   char lightname[1024];
00299   sprintf(lightname, "light0");
00300   float intensity = 1.0;
00301   float ambcolor[3], lightorigin[3];
00302   ambcolor[0] = 1.0;
00303   ambcolor[1] = 1.0;
00304   ambcolor[2] = 1.0;
00305   lightorigin[0] = 0.0;
00306   lightorigin[1] = 0.0;
00307   lightorigin[2] = 0.0;
00308 
00309   gapi->Parameter("float intensity", &intensity);
00310   gapi->Parameter("color lightcolor", ambcolor);
00311   gapi->Light("light0", "ambientlight");
00312 
00313   // Write out all the light sources as point lights
00314   n = 1;
00315   for (i = 0; i < DISP_LIGHTS; i++) {
00316     if (lightState[i].on) {
00317       gapi->Parameter("float intensity", &intensity);
00318       gapi->Parameter("color lightcolor", lightState[i].color);
00319       gapi->Parameter("point from", lightState[i].pos);
00320       gapi->Parameter("point to", lightorigin);
00321       sprintf(lightname, "light%d", n);
00322       n++,
00323       gapi->Light(lightname, "distantlight");
00324     }
00325   }
00326 
00327   gapi->World();
00328 
00329   // Gelato background color shader
00330   // Background colors slow down rendering,\n");
00331   // but this is what VMD users expect.\n");
00332   // Comment these lines for a transparent background.\n");
00333   gapi->PushAttributes();
00334   gapi->Shader("surface", "constant");
00335   gapi->Attribute("color C", backColor);
00336   gapi->Input("backplane.pyg");
00337   gapi->PopAttributes();
00338 }
00339 
00340 
00341 void LibGelatoDisplayDevice::write_trailer(void){
00342   gapi->Render("camera");
00343   reset_vars(); // reinitialize material cache
00344 }
00345 
00346 
00347 void LibGelatoDisplayDevice::write_materials(int write_color) {
00348   // keep track of what the last written material properties
00349   // are, that way we can avoid writing redundant def's
00350   if (write_color) {
00351     // the color has changed since last write, emit an update 
00352     if ((matData[colorIndex][0] != old_color[0]) ||
00353         (matData[colorIndex][1] != old_color[1]) ||
00354         (matData[colorIndex][2] != old_color[2])) {
00355       fprintf(outfile, "Attribute(\"color C\",  (%g, %g, %g))\n",
00356               matData[colorIndex][0], 
00357               matData[colorIndex][1],
00358               matData[colorIndex][2]);
00359       // save the last color
00360       memcpy(old_color, matData[colorIndex], sizeof(float) * 3);
00361     }
00362   }
00363 
00364   // now check opacity
00365   if (mat_opacity != old_opacity) {
00366     float opacity[3];
00367     opacity[0] = mat_opacity;
00368     opacity[1] = mat_opacity;
00369     opacity[2] = mat_opacity;
00370 
00371     gapi->Attribute("color opacity", opacity);
00372     old_opacity = mat_opacity;
00373   }
00374 
00375   // and the lighting and roughness coefficients
00376   if ((mat_ambient != old_ambient) || 
00377       (mat_diffuse != old_diffuse) ||
00378       (mat_specular != old_specular)) {
00379     float roughness=10000.0;
00380     if (mat_shininess > 0.00001) {
00381       roughness = 1.0 / mat_shininess;
00382     }
00383     gapi->Parameter("float Ka", &mat_ambient);
00384     gapi->Parameter("float Kd", &mat_diffuse);
00385     gapi->Parameter("float Ks", &mat_specular);
00386     gapi->Parameter("float roughness", &roughness);
00387     gapi->Shader("surface", "plastic");
00388     old_ambient = mat_ambient;
00389     old_specular = mat_specular;
00390     old_diffuse = mat_diffuse;
00391   }
00392 }
00393 
00394 
00395 

Generated on Thu Apr 25 02:42:45 2024 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002