TRIANG2D *triang2d_example_disp (void) /* this method is not optimized in any way. */ { TRIANG2D *self; GRAPHICDEVICE *grdev; MANAGER *mgr; static int own_colors = 0; static CHECKBOX *checkbox = NULL; self = (TRIANG2D *) START_METHOD (G_INSTANCE); ASSURE (self, "", END_METHOD (NULL)); mgr = (MANAGER *) GRAPE (Manager, "get-stdmgr")(); ASSURE (mgr, "triang2d_example_disp: can't get manager", END_METHOD (NULL)); /* we have a switch: "own_colors". * to let the user choose a value we use a Checkbox. */ if (!checkbox) { /* no checkbox yet: create it */ checkbox = (CHECKBOX *) GRAPE (Checkbox, "new-instance") ("example: colors", &own_colors); GRAPE (checkbox, "set-pref-size")(6.0, 1.0); } /* insert the checkbox into menu "opt 0" if not already there. * it will be removed when this method is not used any more */ if (GRAPE (mgr, "new-handle")(triang2d_example_disp, 1)) { GRAPE (mgr, "add-inter")(checkbox); } /* get standard graphic device. * create error message when fail. */ grdev = (GRAPHICDEVICE *) GRAPE (GraphicDevice, "get-stddev")(); ASSURE (grdev, "triang2d_example_disp: can't get GraphicDevice", END_METHOD (NULL)); if (grdev->grid_patch == G_GRID) { /* Device is switched to grid mode. We MUST NOT draw patches * here (it may work on your device, but not on others, e.g. * X11, PostScript ...; to have patch-only and mixed modes * alternatively you have to use patch mode and extra * selfmade switches). */ if (!own_colors) { /* normally use the preset line color */ int i, j; VEC3 point[3]; for (i = 0; i < self->number_of_elements; i++) { for (j = 0; j < 3; j++) { point[j][0] = self->x[self->vertex[i][j]]; point[j][1] = self->y[self->vertex[i][j]]; point[j][2] = self->z[self->vertex[i][j]]; } grdev->move (point[0]); for (j = 0; j < 3; j++) grdev->draw (point[2 - j]); } } else { /* special: we use our own line color: Red */ int i, j; VEC3 point[3], linecolor; static VEC3 Red = { 1.0, 0.0, 0.0}; /* preserve the previously set line color */ grdev->attribute (G_MODE_GET, G_LINE_COLOR, linecolor); grdev->attribute (G_MODE_SET, G_LINE_COLOR, Red); for (i = 0; i < self->number_of_elements; i++) { for (j = 0; j < 3; j++) { point[j][0] = self->x[self->vertex[i][j]]; point[j][1] = self->y[self->vertex[i][j]]; point[j][2] = self->z[self->vertex[i][j]]; } grdev->move (point[0]); for (j = 0; j < 3; j++) grdev->draw (point[2 - j]); } /* set the previously set line color */ grdev->attribute (G_MODE_SET, G_LINE_COLOR, linecolor); } } else /* (grdev->grid_patch == G_PATCH) */ { /* Device is switched to patch mode. We can draw patches or * grids and mix it. */ /* In this example we always use patches here. Normally we * want them to be colored automatically with respect to * the lightsources. * here another type of display is shown as well: selfmade colors */ if (!own_colors) { int i, j; VEC3 point, normal; /* we use the lightsources */ for (i = 0; i < self->number_of_elements; i++) { grdev->begin_patch(); for (j = 0; j < 3; j++) { point[0] = self->x[self->vertex[i][j]]; point[1] = self->y[self->vertex[i][j]]; point[2] = self->z[self->vertex[i][j]]; /* calculate the patch normal in this vertex from your data normal = my_normal (self->vertex[i][j]); the default display method takes the average normal of the triangles using this vertex we take a very stupid formula here */ normal[0] = g_sin (point[2]); normal[1] = g_cos (point[2]); normal[2] = point[2]; g_vec3_normalize (normal); grdev->patch_normal (normal); grdev->patch_vertex (point); } grdev->end_patch(); } } else { int i, j; int light_model, off = 0; VEC3 point, color; /* we use selfmade colors. switch off the light-model, but * save previous state to restore afterwards */ grdev->attribute (G_MODE_GET, G_LIGHT_MODEL, &light_model); grdev->attribute (G_MODE_SET, G_LIGHT_MODEL, &off); for (i = 0; i < self->number_of_elements; i++) { grdev->begin_patch(); for (j = 0; j < 3; j++) { point[0] = self->x[self->vertex[i][j]]; point[1] = self->y[self->vertex[i][j]]; point[2] = self->z[self->vertex[i][j]]; /* calculate the color for this vertex from your data color = my_color (self->vertex[i][j]); we take a very stupid formula here */ color[0] = g_sin (10. * point[2]); color[1] = g_cos (10. * point[1]); color[2] = g_sin (10. * point[0]); grdev->patch_color (color); grdev->patch_vertex (point); } grdev->end_patch(); } grdev->attribute (G_MODE_SET, G_LIGHT_MODEL, &light_model); } } END_METHOD (self); }
Copyright © by the Sonderforschungsbereich 256 at the Institut für Angewandte Mathematik, Universität Bonn.