/* quadmesh.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_X_INTERVALS 20 #define NUM_Z_INTERVALS 20 #define NUM_X_POINTS (NUM_X_INTERVALS + 1) #define NUM_Z_POINTS (NUM_Z_INTERVALS + 1) #define X0 0.5 #define Z0 0.5 static void create_structure( dpy ) Display *dpy; { PEXColor color; PEXCoord vertices[NUM_X_POINTS * NUM_Z_POINTS]; PEXCoord origin; PEXArrayOfVertex verts; PEXStructure axes; PEXArrayOfFacetData dummy; unsigned int facet_data_flag, vertex_data_flag; int i, j, index; double x, dx, z, dz; /* Generate the points for the surface. */ dx = 1.0 / (NUM_X_INTERVALS); dz = 1.0 / (NUM_Z_INTERVALS); for ( j = 0, z = 0.0; j < NUM_Z_POINTS; j++, z += dz ) { for ( i = 0, x = 0.0; i < NUM_X_POINTS; i++, x += dx ) { index = j * NUM_X_POINTS + i; vertices[index].x = x; vertices[index].y = (x - X0) * (x - X0) + (z - Z0) * (z - Z0); vertices[index].z = z; } } /* Create the structure. */ struct_id = PEXCreateStructure( dpy ); /* Set the view index. */ PEXSetViewIndex( dpy, struct_id, PEXOCStore, 1 ); /* Build the axes. */ origin.x = origin.y = origin.z = 0; axes = ora_build_axes_struct( dpy, &origin, 0.6 ); PEXExecuteStructure( dpy, struct_id, PEXOCStore, axes ); /* Distinguish between front and back faces. */ PEXSetFacetDistinguishFlag( dpy, struct_id, PEXOCStore, True ); /* Set the interior style and color for front faces. */ PEXSetInteriorStyle( dpy, struct_id, PEXOCStore, PEXInteriorStyleHollow ); SET_COLOR( 1, 1, 1, color ); /* white */ PEXSetSurfaceColor( dpy, struct_id, PEXOCStore, PEXColorTypeRGB, &color ); /* Set the back interior style and color for back faces. */ PEXSetBFInteriorStyle( dpy, struct_id, PEXOCStore, PEXInteriorStyleSolid ); PEXSetBFSurfaceColor( dpy, struct_id, PEXOCStore, PEXColorTypeRGB, &color ); /* Create the quadrilateral mesh. */ facet_data_flag = PEXGANone; vertex_data_flag = PEXGANone; verts.no_data = vertices; PEXQuadrilateralMesh( dpy, struct_id, PEXOCStore, PEXShapeConvex, facet_data_flag, vertex_data_flag, PEXColorTypeRGB, dummy, NUM_Z_POINTS, NUM_X_POINTS, verts ); } static void redraw( dpy, window, renderer ) Display *dpy; Window window; PEXRenderer renderer; { XClearWindow( dpy, window ); PEXRenderNetwork( dpy, window, renderer, struct_id ); XFlush( dpy ); } extern void set_view(); 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); } set_view( dpy, rattrs.view_table ); /* 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; } static void set_view( dpy, view_table ) Display *dpy; PEXLookupTable view_table; { PEXViewEntry view; PEXCoord2D window[2]; double view_plane, front_plane, back_plane; PEXCoord prp; PEXNPCSubVolume viewport; /* The view orientation parameters. */ static PEXCoord view_ref_pt = {0.5, 0.5, 0.5}; static PEXVector view_plane_normal = {-0.5, 0.5, 1}; static PEXVector view_up_vec = {0,1,0}; /* Compute the view orientation transform. */ (void)PEXViewOrientationMatrix( &view_ref_pt, &view_plane_normal, &view_up_vec, view.orientation ); /* The view mapping parameters. */ prp.x = 1; prp.y = 0.5; prp.z = 10; window[0].x = -0.8; window[1].x = 0.8; window[0].y = -0.9; window[1].y = 0.7; front_plane = 5; view_plane = 0; back_plane = -1; 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. */ (void)PEXViewMappingMatrix( window, &viewport, True, &prp, view_plane, back_plane, front_plane, view.mapping ); /* The view clipping parameters. */ view.clip_flags = PEXClippingAll; view.clip_limits = viewport; /* Set view 1. */ PEXSetTableEntries( dpy, view_table, 1, 1, PEXLUTView, (PEXPointer) &view ); }