[ Previous | Next | Contents | Glossary | Home | Search ]
GL3.2 Version 4.1 for AIX: Programming Concepts

Object Editing

This section discusses the following topics

You can change an object by editing it. Editing requires you to identify and locate the drawing routines that you want to change. You use two types of routines when you edit an object:

editobj Subroutine

To open an object for editing, use the editobj subroutine. A pointer acts as a cursor that appends new routines. The pointer is initially set to the end of the object. The system appends graphics routines to the object until either a closeobj subroutine or a pointer positioning routine (the objdelete, objinsert, or objreplace subroutines) executes. The syntax is as follows:

void editobj(Int32 object)

The system interprets the editing routines following the editobj subroutine call. Use the closeobj subroutine to terminate your editing session. If you specify an undefined object, an error message appears.

getopenobj Subroutine

To determine if an object is open for editing, use the getopenobj subroutine. If an object is open, it returns the object's numeric identifier. If no object is open, it returns -1. The syntax is as follows:

Int32 getopenobj()

Identifying Display List Items with Tags

Tags locate display list items you want to edit. Editing routines require tag names as parameters. The STARTTAG value is a predefined tag that goes before the very first item to mark the beginning of the list. The STARTTAG value does not have any effect on drawing or modifying the object; use it only to return to (find) the beginning of the list.

The ENDTAG value is a predefined tag that is positioned after the last item to mark the end of the list. Like STARTTAG, ENDTAG does not have any effect on drawing or modifying the object; use it to find the end of the graphical object. When you call the makeobj subroutine to create a list, STARTTAG and ENDTAG automatically appear. You cannot delete these tags. When an object is opened for editing, a pointer appears at ENDTAG, after the last routine in the object. To perform edits on other items, refer to them by their tags.

maketag Subroutine

Use tags to mark display list items you may want to change. You explicitly tag routines with the maketag subroutine. You specify a signed 32-bit numeric identifier and the system places a marker between two list items. You can use the same tag name in different objects. The syntax is as follows:

void maketag(Int32 tag)

newtag Subroutine

The newtag subroutine also adds tags to an object, but uses an existing tag to determine its relative position within the object. The newtag subroutine creates a new tag that is offset beyond the other tag by the number of lines given in its parameter offset. The syntax is as follows:

void newtag(Int32 newt, Int32 oldtag, Int32 offset)

istag Subroutine

The istag subroutine tells whether a given tag is in use within the current open object. The subroutine returns TRUE if the tag is in use, and FALSE if it is not. The result is undefined if there is no currently open object. The syntax is as follows:

Int32 istag(Int32 tag)

gentag Subroutine

The gentag subroutine generates a unique integer to use as a tag within the current open object. The syntax is as follows:

Int32 gentag()

deltag Subroutine

The deltag subroutine deletes tags from the object currently open for editing. Remember, you cannot delete the special STARTTAG and ENDTAG tags. The syntax is as follows:

void deltag(Int32 tag)

Inserting, Deleting, and Replacing within Objects

The following subroutines allow you to edit an object by moving the subroutines inside the object using tags as markers for inserting or deleting.

objinsert Subroutine

Use the objinsert subroutine to add routines to an object at the location specified in the tag parameter. The objinsert subroutine positions an editing pointer on the tag specified in the tag parameter. The system inserts graphics routines immediately after the tag. To terminate the insertion, use the closeobj subroutine or the objdelete or objreplace editing subroutines. The syntax is as follows:

void objinsert(Int32 tag)

objdelete Subroutine

The objdelete subroutine removes routines from the current open object. It removes everything between the tag1 and tag2 parameters, including routines and other tag names. For example, objdelete(STARTTAG, ENDTAG) would delete every routine. The system ignores the objdelete subroutine if no object is open for editing. This routine leaves the pointer at the tag1 parameter location after it executes. The syntax is as follows:

void objdelete(Int32 tag1, Int32 tag2)

objreplace Subroutine

The objreplace subroutine combines the functions of the objdelete and objinsert subroutines. It provides a quick way to replace one routine with another that occupies the same amount of display list space. Its tag parameter is a single tag. Graphics routines that follow the objreplace subroutine overwrite existing routines until an occurrence of the closeobj or an editing subroutine (objinsert or objdelete) terminates the replacement.

Note: The objreplace subroutine requires that the new routine to be exactly the same length in bytes as the previous one. If it is not, there is a danger that the display list will be scrambled. Use the objdelete and objinsert subroutines for more general replacement.

The syntax is as follows:

void objreplace(Int32 tag)

Object Editing Examples

The following is an example of object editing. The object star is defined.

makeobj(star);
   color(GREEN);
   maketag(BOX);
   recti(1, 1, 9, 9);
   maketag(INNER);
   color(BLUE);
   poly2i(8, Inner);
   maketag(OUTER);
   color(RED);
   poly2i(8, Outer);
   maketag(CENTER);
   color(YELLOW);
   pnt2i(5, 5);
closeobj();

This object is then edited with the following routine to produce a modified object:

editobj(star);
   circi(1, 5, 5);
   objinsert(BOX);
   recti(0, 0, 10, 10);
   objreplace(INNER);
   color(GREEN);
closeobj();

The object resulting from the editing session is equivalent to an object created by the following code.

makeobj(star);
   color(GREEN);
   maketag(BOX);
   recti(0, 0, 10, 10);
   recti(1, 1, 9, 9);
   maketag(INNER);
   color(GREEN);
   poly2i(8, Inner);
   maketag(OUTER);
   color(RED);
   poly2i(8, Outer);
   maketag(CENTER);
   color(YELLOW);
   pnt2i(5, 5);
   circi(1, 5, 5);
closeobj();

Object Memory Management

Editing can require large amounts of memory. The compactify and chunksize subroutines perform memory management tasks.

compactify Subroutine

As memory is modified by the various editing routines, an open object can become fragmented and stored inefficiently. When the amount of wasted space becomes large, the system automatically calls the compactify subroutine during the closeobj operation. The routine allows you to perform the compaction explicitly. Unless new routines are inserted in the middle of an object, compaction is not necessary.

Note: The compactify subroutine uses a significant amount of computing time. Do not call it unless the amount of available storage space is critical; use it sparingly when performance is a consideration.

The syntax is as follows:

void compactify(Int32 object)

chunksize Subroutine

The chunksize subroutine specifies the minimum chunk of memory necessary to accommodate the largest GL command call. Normally, this is a call to the poly or polf subroutine with a very large number of vertices. If there is a memory shortage, use the chunksize subroutine to allocate memory differently to an object.

The chunksize subroutine specifies the minimum amount of memory that the system allocates to an object. The default chunk is 1020 bytes. When a chunk is specified, its size varies according to the needs of the application. As the object grows, more memory is allocated in units of the size specified in the chunk parameter. The chunksize subroutine is called once after the ginit or winopen subroutine, and once before the first makeobj subroutine.

The chunksize subroutine helps use memory economically. For example, when graphical objects require very little memory, the system can be used more efficiently by specifying smaller chunks of memory. There are drawbacks to the use of the chunksize subroutine. There is both memory and execution time overhead associated with each chunk. Many small chunks can be inefficient in both ways. The syntax is as follows:

void chunksize(Int32 chunk)

[ Previous | Next | Contents | Glossary | Home | Search ]