Jump to content United States-English
HP.com Home Products and Services Support and Drivers Solutions How to Buy
» Contact HP
More options
HP.com home
Starbase Display List Programmer's Manual: HP 9000 Series 700 Computers > Chapter 5 Displaying and Refreshing

A Display Example

» 

Technical documentation

» Feedback
Content starts here

 » Table of Contents

 » Glossary

 » Index

In Chapter 4 “The Basics of Using a Display List”, the "House.c" example showed examples of refreshing display list segments. Below, the program is modified in two ways:

  • This time, the display list is a device-independent display list. This has a couple of implications:

    • There are two different file descriptors needed: one for the display list (displist) and one for the output device (outdev).

    • The image is drawn using the display- routines rather than the refresh- routines.

  • The segments are displayed one element at a time in the "piecemeal" section. This was implemented through use of a subroutine.

Accessing Elements One at a Time

When a segment is refreshed or displayed, all the elements in it are drawn consecutively and inseparably. If your application would benefit from the ability to access single elements within a segment, Display List has routines to do it. The element-specific routines used in the modified "house" program are as follows:

set_ele_ptr

Set the element pointer to an absolute location in the currently open segment. This is called only once, to initialize the element pointer to the first (null) element in the open segment.

display_element

Draw, on the specified output device, the portion of the image that is represented by the current element in the specified display list.

print_element

Print, on stdout, the function name and the parameters of the current element in the currently open segment. This is merely for the user's information (it is a debugging tool), and is not required for the logic of the program to work.

set_ele_ptr_relative

Set the element pointer to a location relative to the current element in the currently open segment. This is used to step through the elements in the open segment one at a time.

inq_ele_ptr_at_bound

This routine returns two boolean values: the first tells you whether or not the current element is the first element in the segment, and the second tells you whether or not the current element is the last element in the segment. Only the second is used in this program, and it is the loop-control variable.

These routines are used in the subroutine as follows:

ShowElementDisplay(displist, outdev, SegNo, SegName)
int displist; /* file descriptor display list */
int outdev; /* file descriptor output device */
int SegNo; /* the segment number to display */
char *SegName; /* the name of the segment */

int AtTop, AtBottom; /* loop control variables */

printf("%s (segment #%d)...\\n", SegName, SegNo);
open_segment(displist, SegNo, AppendOff, DisplayOff);
set_ele_ptr(displist, 0); /* set ptr. to NULL element */
do { /* for all non-NULL elements */
inq_ele_ptr_at_bound(displist, /* is the current element... */
&AtTop, &AtBottom); /* ...at one of the ends? *
if (AtBottom) /* if so... */
continue; /* skip rest of the loop. */
set_ele_ptr_relative(displist, 1); /* increment element ptr. */
print_element(displist, AbbrevArrays); /* for user's benefit */
fflush(stdout); /* make sure it prints */
display_element(displist, outdev);/* display current element */
sleep(1); /* let user notice */
} while (! AtBottom); /* if not at end, loop */
close_segment(displist);
sleep(1);
}

The identifier AbbrevArrays is a macro defined to be the boolean value TRUE. It tells the print_element function to "abbreviate the arrays," which means to note the fact that there is an array there, but don't print all the values in the array. If AbbrevArrays is FALSE, all values in the array are printed.

Selected segments are drawn by sending the appropriate information to the subroutine:

ShowElementDisplay(displist, outdev, Roof,   "Roof");
ShowElementDisplay(displist, outdev, Window, "Window");
ShowElementDisplay(displist, outdev, Door, "Door");
ShowElementDisplay(displist, outdev, Wall, "Wall");

Note that when segment Wall is drawn, it re-draws Door and Window, since they are sub-segments of Wall. At this point, nothing appears to happen: lines are being drawn over already-existent lines.

And finally, the whole house is drawn at once by sending the file descriptor of the device-independent display list, the segment number, and the file descriptor of the output device to the routine display_segment:

display_segment(displist, House, outdev);

Here is a listing of the modified program, called HouseEle.c. There are several things of note[15]:

  • Notice that there are now two gopen statements: one for the device-independent display list, and one for the output device.

  • The display-list-defining logic is identical to that of program House.c.

  • The initialization statements — those which are not in any segment — are called with the file descriptor outdev, and not displist.

  • There is a one-second wait after each element has been displayed, and an additional one-second wait after each segment has been completed. Thus, there is a two-second wait between segments, so you can identify where one segment ends and another one starts.

#include <starbase.c.h>           /* get Starbase definitions */
#include <dl.c.h> /* get Display List definitions */
#include <stdio.h> /* get standard I/O functions */

#define AppendOff FALSE /* sent to "open_segment" */
#define AppendOn TRUE /* sent to "open_segment" */
#define DisplayOff FALSE /* sent to "open_segment" */
#define DisplayOn TRUE /* sent to "open_segment" */
#define AbbrevArrays TRUE /* sent to "print_element" */
#define AlwaysCurrent FALSE /* sent to "buffer_mode" */
#define Edges TRUE /* sent to "interior_style" */
#define NoFlags FALSE /* sent to "polygon2d" */

#define House 1 /* \\ */
#define Wall 11 /* \\ */
#define WallSurface 111 /* \\ These mnemonic tokens*/
#define Door 112 /* \\ are associated with */
#define Window 113 /* \\ segment numbers that */
#define Frame 1131 /* / indicate the house's */
#define Panes 1132 /* / hierarchical */
#define Roof 12 /* / structure. */
#define RoofSurface 121 /* / */
#define Chimney 122 /* / */main() /* program "HouseEle.c" */
{
int displist, outdev; /* file descriptors */

if ((displist = gopen("&<dev>/null", OUTDEV, "display_list", INIT)) == -1) {
fprintf(stderr, "Open of outdev-independent display list failed.\\n");
exit(-1);
}
if ((outdev = gopen(getenv("SB_OUTDEV"), OUTDEV, NULL,
INIT)) == -1) {
fprintf(stderr, "%s %s\\n", "Error: gopen failed using environment",
"variable SB_OUTDEV.");
exit(-2);
}
buffer_mode(outdev, AlwaysCurrent);
vdc_extent(outdev, 0.0, 0.0, 0.0, 1.25, 1.0, 0.0);
view_window(outdev, 0.0, 0.0, 10.0, 8.0);
interior_style(outdev, INT_HOLLOW, Edges);
/*=== define the display list segments comprising the house =======*/
/*- Section 1: Define the house's structure */
open_segment(displist, House, AppendOff, DisplayOff);
call_segment(displist, Wall);
call_segment(displist, Roof);
close_segment(displist);
/*- Section 1.1: Define the wall's structure -*/
open_segment(displist, Wall, AppendOff, DisplayOff);
call_segment(displist, WallSurface);
call_segment(displist, Door);
call_segment(displist, Window);
close_segment(displist);
/*- Section 1.1.1: Define the wall surface's structure -*/
open_segment(displist, WallSurface, AppendOff, DisplayOff);
rectangle(displist, 2.0, 1.0, 8.0, 5.0);
close_segment(displist);
/*- Section 1.1.2: Define the door's structure -*/
open_segment(displist, Door, AppendOff, DisplayOff);
rectangle(displist, 2.5, 1.0, 4.2, 4.2);
ellipse(displist, 0.06, 0.06, 2.65, 2.3);
close_segment(displist);
/*- Section 1.1.3: Define the window's structure -*/
open_segment(displist, Window, AppendOff, DisplayOff);
call_segment(displist, Frame);
call_segment(displist, Panes);
close_segment(displist);
/*- Section 1.1.3.1: Define the window frame's structure -*/
open_segment(displist, Frame, AppendOff, DisplayOff);
rectangle(displist, 5.0, 2.0, 7.0, 4.0);
close_segment(displist);
/*- Section 1.1.3.2: Define the window panes' structure */
open_segment(displist, Panes, AppendOff, DisplayOff);
rectangle(displist, 5.1, 2.1, 5.95, 2.95);
rectangle(displist, 6.05, 2.1, 6.9, 2.95);
rectangle(displist, 6.05, 3.05, 6.9, 3.9);
rectangle(displist, 5.1, 3.05, 5.95, 3.9);
close_segment(displist);
/*- Section 1.2: Define the roof's structure -*/
open_segment(displist, Roof, AppendOff, DisplayOff);
call_segment(displist, RoofSurface);
call_segment(displist, Chimney);
close_segment(displist);
/*- Section 1.2.1: Define the roof surface's structure -*/
open_segment(displist, RoofSurface, AppendOff, DisplayOff);
{
static float RoofStructure[3][2] = {
1.0, 5.0, 9.0, 5.0, 5.0, 7.0};

polygon2d(displist, RoofStructure, 3, NoFlags);
}
close_segment(displist);
/*- Section 1.2.2: Define the chimney's structure */
open_segment(displist, Chimney, AppendOff, DisplayOff);
{
static float ChimneyStructure[4][2] = {
6.0, 6.5, 7.0, 6.0, 7.0, 7.5, 6.0, 7.5};

polygon2d(displist, ChimneyStructure, 4, NoFlags);
}
close_segment(displist);
/*=== draw the house piecemeal ==================================*/
ShowElementDisplay(displist, outdev, Roof, "Roof");
ShowElementDisplay(displist, outdev, Window, "Window");
ShowElementDisplay(displist, outdev, Door, "Door");
ShowElementDisplay(displist, outdev, Wall, "Wall");
/*=== draw the house all at once ================================*/
clear_view_surface(outdev); sleep(1);
printf("House...\\n"); fflush(stdout);
display_segment(displist, House, outdev);
gclose(displist);
gclose(outdev);
}/********************************************************************/
ShowElementDisplay(displist, outdev, SegNo, SegName)
int displist; /* file descriptor of display list */
int outdev; /* file descriptor of output outdev */
int SegNo; /* the segment number to display */
char *SegName; /* the name of the segment */
{
int AtTop, AtBottom; /* loop control variables */

printf("%s (segment #%d)...\\n", SegName, SegNo);
open_segment(displist, SegNo, AppendOff, DisplayOff);
set_ele_ptr(displist, 0); /* set ptr. to NULL element */
do { /* for all non-NULL elements */
inq_ele_ptr_at_bound(displist, /* is the current element... */
&AtTop, &AtBottom); /* ...at one of the ends? */
if (AtBottom) /* if so... */
continue; /* skip the rest of the loop. */
set_ele_ptr_relative(displist, 1); /* increment element ptr. */
print_element(displist, AbbrevArrays); /* for user's benefit */
fflush(stdout); /* make sure it prints */
display_element(displist, outdev); /* display current element */
sleep(1); /* let user notice */
} while (! AtBottom); /* if not at end, loop */
close_segment(displist);
sleep(1);
}

The graphical output of this program is visually identical to that of the program House.c that appeared in Chapter 4 “The Basics of Using a Display List” Here is the output:

Figure 5-1 House Drawn with Device-Independent Display List

House Drawn with Device-Independent Display List


[15] The actual path names of directories in angle brackets depend on the file system structure. See the Graphics Administration Guide for details.

Printable version
Privacy statement Using this site means you accept its terms Feedback to webmaster
© 1995 Hewlett-Packard Development Company, L.P.