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
00112 #if 0
00113
00114 void LibGelatoDisplayDevice::cylinder(float *a, float *b, float r,
00115 int ) {
00116 }
00117
00118
00120 void LibGelatoDisplayDevice::cone(float *a, float *b, float r) {
00121 }
00122 #endif
00123
00124
00125
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
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
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
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
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
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
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
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,
00191 cnv + v1 + 7,
00192 cnv + v2 + 7,
00193 cnv + v0 + 4,
00194 cnv + v1 + 4,
00195 cnv + v2 + 4,
00196 cnv + v0,
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
00207
00208
00209
00210
00211 int strip, t, v = 0;
00212 int stripaddr[2][3] = { {0, 1, 2}, {1, 0, 2} };
00213
00214
00215 for (strip=0; strip < numstrips; strip++) {
00216
00217 for (t = 0; t < (vertsperstrip[strip] - 2); t++) {
00218
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,
00224 cnv + v1 + 7,
00225 cnv + v2 + 7,
00226 cnv + v0 + 4,
00227 cnv + v1 + 4,
00228 cnv + v2 + 4,
00229 cnv + v0,
00230 cnv + v1,
00231 cnv + v2);
00232 v++;
00233 }
00234 v+=2;
00235 }
00236 }
00237
00238
00239
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
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));
00253 memcpy(&norms[6], &norms[0], 3*sizeof(float));
00254 memcpy(&norms[9], &norms[0], 3*sizeof(float));
00255
00256
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
00271 gapi->Output(my_filename, "tiff", "rgba", "camera");
00272
00273
00274
00275
00276 int res[2];
00277 res[0] = xSize;
00278 res[1] = ySize;
00279 gapi->Attribute("int[2] resolution", res);
00280
00281
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
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
00300 gapi->Attribute("float near", &nearClip);
00301 gapi->Attribute("float far", &farClip);
00302
00303
00304 gapi->Translate(-eyePos[0], -eyePos[1], -eyePos[2]);
00305
00306 #if 0
00307
00308 fprintf( outfile, "Declare \"shadows\" \"string\"\n");
00309 fprintf( outfile, "Attribute \"light\" \"shadows\" \"on\"\n" );
00310 #endif
00311
00312
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
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
00345
00346
00347
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();
00359 }
00360
00361
00362 void LibGelatoDisplayDevice::write_materials(int write_color) {
00363
00364
00365 if (write_color) {
00366
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
00375 memcpy(old_color, matData[colorIndex], sizeof(float) * 3);
00376 }
00377 }
00378
00379
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
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