/* tristrip.c 1.1 */ /* Copyright 1992, 1993 O'Reilly and Associates, Inc. Permission to use, copy, and modify this program is hereby granted, as long as this copyright notice appears in each copy of the program source code. */ #include "book_utils.h" #define WIN_GEOM "500x500+50+50" /* Structure ID */ static PEXStructure struct_id; /* Miscellaneous constants we use. */ #define NUM_TRIANGLES 21 #define NUM_VERTICES (NUM_TRIANGLES + 2) #define X_START 0.2 #define X_END 0.8 #define Y0 0.7 #define Z0 0.5 #define STRIP_HALF_WIDTH 0.15 #define TWIST_ANGLE M_PI static void create_structure( dpy ) Display *dpy; { PEXColor color; PEXCoord vertices[NUM_VERTICES]; PEXVertexRGB vertices_with_color[NUM_VERTICES]; PEXArrayOfVertex verts; PEXArrayOfFacetData dummy; unsigned int i, facet_data_flag, vertex_data_flag; double dx, delta, angle; /* Generate the points for the band. */ dx = (X_END - X_START) / (NUM_VERTICES - 1); delta = TWIST_ANGLE / (NUM_VERTICES - 1); /* The top vertices. */ for ( i = 0; i < NUM_VERTICES; i += 2 ) { vertices[i].x = X_START + i * dx; angle = i * delta; /* Compute the vertices for the hollow strip. */ vertices[i].y = Y0 + STRIP_HALF_WIDTH * cos( angle ); vertices[i].z = Z0 + STRIP_HALF_WIDTH * sin( angle ); /* Set the coordinates and colors for the shaded strip. */ vertices_with_color[i].point = vertices[i]; vertices_with_color[i].point.y -= 0.4; vertices_with_color[i].rgb.red = 1.0; vertices_with_color[i].rgb.green = 0.0; vertices_with_color[i].rgb.blue = 0.0; } /* The bottom vertices. */ for ( i = 1; i < NUM_VERTICES; i += 2 ) { vertices[i].x = X_START + i * dx; angle = i * delta; /* Compute the vertices for the hollow strip. */ vertices[i].y = Y0 - STRIP_HALF_WIDTH * cos( angle ); vertices[i].z = Z0 - STRIP_HALF_WIDTH * sin( angle ); /* Set the coordinates and colors for the shaded strip. */ vertices_with_color[i].point = vertices[i]; vertices_with_color[i].point.y -= 0.4; vertices_with_color[i].rgb.red = 1.0; vertices_with_color[i].rgb.green = 1.0; vertices_with_color[i].rgb.blue = 1.0; } /* Make the ends of the band square. */ vertices[1].x = X_START; vertices[NUM_VERTICES - 2].x = vertices[NUM_VERTICES - 1].x; vertices_with_color[1].point.x = X_START; vertices_with_color[NUM_VERTICES - 2].point.x = vertices[NUM_VERTICES - 1].x; /* Create the structure. */ struct_id = PEXCreateStructure( dpy ); /* Set the interior style and color. */ PEXSetInteriorStyle( dpy, struct_id, PEXOCStore, PEXInteriorStyleHollow ); SET_COLOR( 1, 1, 1, color ); /* white */ PEXSetSurfaceColor( dpy, struct_id, PEXOCStore, PEXColorTypeRGB, &color ); /* Distinguish between front and back faces. */ PEXSetFacetDistinguishFlag( dpy, struct_id, PEXOCStore, True ); /* Set the back interior style and color. */ PEXSetBFInteriorStyle( dpy, struct_id, PEXOCStore, PEXInteriorStyleHollow ); SET_COLOR( 1, 1, 0, color ); /* yellow */ PEXSetBFSurfaceColor( dpy, struct_id, PEXOCStore, PEXColorTypeRGB, &color ); /* Create the hollow triangle strip. */ facet_data_flag = PEXGANone; vertex_data_flag = PEXGANone; verts.no_data = vertices; PEXTriangleStrip( dpy, struct_id, PEXOCStore, facet_data_flag, vertex_data_flag, PEXColorTypeRGB, dummy, NUM_VERTICES, verts ); /* Set the attributes for the shaded strip. */ PEXSetInteriorStyle( dpy, struct_id, PEXOCStore, PEXInteriorStyleSolid ); PEXSetSurfaceInterpMethod( dpy, struct_id, PEXOCStore, PEXSurfaceInterpColor ); /* Stop distinguishing between front and back faces. */ PEXSetFacetDistinguishFlag( dpy, struct_id, PEXOCStore, False ); /* Create the shaded triangle strip. */ vertex_data_flag = PEXGAColor; verts.rgb = vertices_with_color; PEXTriangleStrip( dpy, struct_id, PEXOCStore, facet_data_flag, vertex_data_flag, PEXColorTypeRGB, dummy, NUM_VERTICES, verts ); } static void redraw( dpy, window, renderer ) Display *dpy; Window window; PEXRenderer renderer; { XClearWindow( dpy, window ); PEXRenderNetwork( dpy, window, renderer, struct_id ); XFlush( dpy ); } main( argc, argv ) int argc; char *argv[]; { Display *dpy; Window window; XEvent event; XVisualInfo vis_info; XColor bkgd_color; XStandardColormap cmap_info; PEXColorApproxEntry capx_info; PEXRenderer renderer; PEXRendererAttributes rattrs; PEXExtensionInfo *pexinfo; int done = 0; /* Open a display and initialize PEX. */ dpy = ora_init_pex( argv, &pexinfo ); if ( !dpy ) exit(1); /* Determine the best visual to use. */ ora_find_best_visual( dpy, &vis_info ); /* Get a standard colormap for the visual. */ if ( !ora_get_standard_colormap( dpy, &vis_info, &cmap_info ) ) { fprintf ( stderr, "Cannot find a standard colormap\n" ); exit(1); } ora_set_stdcmap_approx( &vis_info, &cmap_info, &capx_info ); /* Create the window, giving it a gray background. */ bkgd_color.red = bkgd_color.green = bkgd_color.blue = 0x5555; bkgd_color.flags = DoRed | DoGreen | DoBlue; window = ora_create_window( dpy, &vis_info, &cmap_info, WIN_GEOM, &bkgd_color ); /* Create the structure and Set up the PEX renderer. */ if ( STRUCTURE_SPT( pexinfo ) ) { create_structure( dpy ); renderer = ora_setup_renderer( dpy, window, &capx_info, &rattrs ); } else { fprintf( stderr, "Structures not supported.\n" ); exit(1); } /* Read and respond to X events. */ XSelectInput( dpy, window, ExposureMask | ButtonPressMask ); while ( !done ) { XNextEvent( dpy, &event ); switch ( event.type ) { case Expose: /* Flush remaining Expose events, then redraw. */ while ( XCheckTypedWindowEvent( dpy, window, Expose, &event ) ) ; /* empty statement */ redraw( dpy, window, renderer ); break; case ButtonPress: done = 1; break; } } XCloseDisplay( dpy ); return 0; }