/* view-cyl.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" /* Globals. */ static PEXStructure model; static Display *dpy; static Window window; static PEXRenderer renderer; static unsigned int view_num = 1; /* Constants */ #define NUM_SEGS 32 #define CYL_RADIUS 1.0 #define CYL_HEIGHT 1.0 #define AXIS_LENGTH 0.3 static void initialize_view( view_table ) PEXLookupTable view_table; { PEXCoord view_ref_pt, prp; PEXVector view_up_vec, view_plane_normal; PEXCoord2D view_window[2]; double view_plane, front_plane, back_plane; PEXNPCSubVolume viewport; PEXViewEntry view; int err, perspective; /* Compute the view orientation transform. */ view_ref_pt.x = 0; view_ref_pt.y = 0; view_ref_pt.z = 0; view_up_vec.x = 0; view_up_vec.y = 1; view_up_vec.z = 0; view_plane_normal.x = 1; view_plane_normal.y = 1; view_plane_normal.z = 1; err = PEXViewOrientationMatrix( &view_ref_pt, &view_plane_normal, &view_up_vec, view.orientation ); /* The view mapping parameters. */ perspective = False; view_plane = 0; prp.x = 0; prp.y = 0; prp.z = 10; view_window[0].x = -1.5; view_window[1].x = 1.5; view_window[0].y = -1.5; view_window[1].y = 1.5; back_plane = -1.5; front_plane = 1.5; viewport.min.x = 0; viewport.max.x = 1; viewport.min.y = 0; viewport.max.y = 1; viewport.min.z = 0; viewport.max.z = 1; /* Compute the view mapping transform. */ err = PEXViewMappingMatrix( view_window, &viewport, perspective, &prp, view_plane, back_plane, front_plane, view.mapping ); /* The view clipping parameters. */ view.clip_flags = PEXClippingAll; view.clip_limits = viewport; /* Set the view. */ PEXSetTableEntries( dpy, view_table, view_num, 1, PEXLUTView, (PEXPointer) &view ); } void create_model() { PEXCoord vertices[4*(NUM_SEGS+1)]; PEXCoord *top, *bot, *sides; PEXListOfVertex lines[NUM_SEGS+3]; PEXCoord center; PEXStructure axes, cylinder; PEXColor color; double angle, delta; int i; /* Create the axes structure. */ center.x = center.y = center.z = 0; axes = ora_build_axes_struct( dpy, ¢er, AXIS_LENGTH ); /* Create the cylinder structure. */ cylinder = PEXCreateStructure( dpy ); /* Build the cylinder, a polyline set with data primitive. */ top = vertices; lines[0].count = NUM_SEGS + 1; lines[0].vertices.no_data = top; bot = top + NUM_SEGS + 1; lines[1].count = NUM_SEGS + 1; lines[1].vertices.no_data = bot; sides = bot + NUM_SEGS + 1; /* Calculate the vertices for the polylines. */ angle = 0; delta = (2 * M_PI) / NUM_SEGS; for ( i = 0; i < NUM_SEGS + 1; i++, angle += delta ) { /* The top circle. */ top[i].x = center.x + CYL_RADIUS * cos( angle ); top[i].y = center.y + 0.5 * CYL_HEIGHT; top[i].z = center.z + CYL_RADIUS * sin( angle ); /* The bottom circle. */ bot[i].x = top[i].x; bot[i].y = center.y - 0.5 * CYL_HEIGHT; bot[i].z = top[i].z; /* The side polylines. */ if ( i <= NUM_SEGS ) { lines[i+2].count = 2; lines[i+2].vertices.no_data = sides; sides[0] = top[i]; sides[1] = bot[i]; /* Move the vertex pointer two vertices forward. */ sides += 2; } } /* Create the cylinder. */ SET_COLOR( 1, 1, 1, color ); PEXSetLineColor( dpy, cylinder, PEXOCStore, PEXColorTypeRGB, &color ); PEXPolylineSetWithData( dpy, cylinder, PEXOCStore, PEXGANone, PEXColorTypeRGB, NUM_SEGS+2, lines ); /* Create the top-level structure. */ model = PEXCreateStructure( dpy ); /* Make all following primitives use the selected view. */ PEXSetViewIndex( dpy, model, PEXOCStore, view_num ); /* Execute the structures containing the primitives. */ PEXExecuteStructure( dpy, model, PEXOCStore, cylinder ); PEXExecuteStructure( dpy, model, PEXOCStore, axes ); } static void redraw() { XClearWindow( dpy, window ); PEXRenderNetwork( dpy, window, renderer, model ); XFlush( dpy ); } #define WIN_GEOM "500x500+50+50" main( argc, argv ) int argc; char *argv[]; { XEvent event; XVisualInfo vis_info; XStandardColormap cmap_info; PEXColorApproxEntry capx_info; PEXRendererAttributes rattrs; PEXExtensionInfo *pexinfo; XColor bkgd_color; 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. */ bkgd_color.red = bkgd_color.green = bkgd_color.blue = 0; bkgd_color.flags = DoRed | DoGreen | DoBlue; window = ora_create_window( dpy, &vis_info, &cmap_info, WIN_GEOM, &bkgd_color ); /* Create the model and set up the PEX renderer. */ if ( STRUCTURE_SPT( pexinfo ) ) { create_model(); renderer = ora_setup_renderer( dpy, window, &capx_info, &rattrs ); } else { fprintf( stderr, "Structures not supported.\n" ); exit(1); } /* Initialize the view. */ initialize_view( rattrs.view_table ); /* Read and respond to X events. */ XSelectInput( dpy, window, ButtonPressMask | ExposureMask ); while ( !done ) { XNextEvent( dpy, &event ); switch ( event.type ) { case ButtonPress: done = 1; break; case Expose: /* Flush remaining Expose events, then redraw. */ while ( XCheckTypedWindowEvent( dpy, window, Expose, &event ) ) ; /* empty statement */ redraw(); break; } } XCloseDisplay( dpy ); return 0; }