00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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"
00030
00031
00032
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();
00039 gapi = GelatoAPI::CreateRenderer();
00040
00041
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
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
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
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
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
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
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
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
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
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
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
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,
00176 cnv + v1 + 7,
00177 cnv + v2 + 7,
00178 cnv + v0 + 4,
00179 cnv + v1 + 4,
00180 cnv + v2 + 4,
00181 cnv + v0,
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
00192
00193
00194
00195
00196 int strip, t, v = 0;
00197 int stripaddr[2][3] = { {0, 1, 2}, {1, 0, 2} };
00198
00199
00200 for (strip=0; strip < numstrips; strip++) {
00201
00202 for (t = 0; t < (vertsperstrip[strip] - 2); t++) {
00203
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,
00209 cnv + v1 + 7,
00210 cnv + v2 + 7,
00211 cnv + v0 + 4,
00212 cnv + v1 + 4,
00213 cnv + v2 + 4,
00214 cnv + v0,
00215 cnv + v1,
00216 cnv + v2);
00217 v++;
00218 }
00219 v+=2;
00220 }
00221 }
00222
00223
00224
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
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));
00238 memcpy(&norms[6], &norms[0], 3*sizeof(float));
00239 memcpy(&norms[9], &norms[0], 3*sizeof(float));
00240
00241
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
00256 gapi->Output(my_filename, "tiff", "rgba", "camera");
00257
00258
00259
00260
00261 int res[2];
00262 res[0] = xSize;
00263 res[1] = ySize;
00264 gapi->Attribute("int[2] resolution", res);
00265
00266
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
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
00285 gapi->Attribute("float near", &nearClip);
00286 gapi->Attribute("float far", &farClip);
00287
00288
00289 gapi->Translate(-eyePos[0], -eyePos[1], -eyePos[2]);
00290
00291 #if 0
00292
00293 fprintf( outfile, "Declare \"shadows\" \"string\"\n");
00294 fprintf( outfile, "Attribute \"light\" \"shadows\" \"on\"\n" );
00295 #endif
00296
00297
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
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
00330
00331
00332
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();
00344 }
00345
00346
00347 void LibGelatoDisplayDevice::write_materials(int write_color) {
00348
00349
00350 if (write_color) {
00351
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
00360 memcpy(old_color, matData[colorIndex], sizeof(float) * 3);
00361 }
00362 }
00363
00364
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
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