Strings in SGO.TXT


Copyright  1993, Silicon Graphics, Inc. All rights reserved.
Silicon Graphics and the Silicon Graphics logo are registered
trademarks, and SGO is a trademark of Silicon Graphics.
Specifications are subject to change without notice.
SGO File Format
SGO = (Silicon Graphics Object)
SGO format is a format slightly more complicated that Spin format,
but still quite simple. It allows lists of quadrilaterals, lists
of triangles and triangle meshes.
The first word in the file is the SGO magic number:
word 1: 0x5424 (4 bytes)
Following next is a set of objects:
<object type 1 token>
<data for object 1>
<object type 2 token>
<data for object 2>
.
.
.
<object type n token>
<data for object n>
<end data token>
Each of the tokens is 4 bytes long. The tokens are:
OBJ_QUADLIST (= 1)
OBJ_TRILIST (= 2)
OBJ_TRIMESH (= 3)
OBJ_END (= 4) the end of data token.
The next word following any of the three object types is the number
of longs in the data for that object.
For OBJ_QUADLIST and OBJ_TRILIST (quadrilateral list and triangle
list), there are 9 floats of data for each vertex. The first three
are the components of the normal vector at the vertex; the next
three are the color components (R, G, B), all between 0.0 and 1.0,
and finally there are the components of the vertex itself.
For the OBJ_QUADLIST, the points are simply taken 4 at a time, so
there are 9*4 = 36 floats of data for each quadrilateral. For the
OBJ_TRILIST, the points are used 3 at a time, making 9*3 = 27
floats per triangle.
The triangle mesh (OBJ_TRIMESH) is the most complicated of the
three. The data consist of a set of vertices followed by a set of
mesh control commands. The data for each vertex is the same as
above -- 9 floats. The mesh controls consist of:
OP_BGNTMESH (= 1)
OP_SWAPTMESH (= 2)
OP_ENDBGNTMESH (= 3)
OP_ENDTMESH (= 4)
Following the number of longs required for the entire triangle mesh
data is the number of floats required for the vertex data (at 9
floats per vertex). Next comes the vertex data, and the rest of
the data are longs containing triangle mesh controls.
For example, a file containing a single triangle mesh object with
four vertices, and nine mesh controls would look like this:
word 1: 0x5424
word 2: OBJ_TRIMESH
word 3: 42 = 4*9 + 1 + 5
word 4: 36 (length of data for 4 vertices)
word 5-40: vertex data
word 41-49: mesh controls
word 50: OBJ_END
When the triangle mesh is drawn, the controls are interpreted one
at a time. The first control is assumed to be an OP_BGNTMESH.
After each control is a long indicating how many vertex indices
will follow. The vertex indices are in byte offsets. For example,
vertex n is offset by n*9*4.
To understand triangle meshes, consider the following example.
Suppose there are 6 points arranged as follows:
0-----2-----4
\ / \ / \
\ / \ / \
1-----3-----5
To draw the triangles 012, 123, 234, and 345, the control sequence
(the mesh controls) would be:
OP_BGTMESH 6 0*9*4 1*9*4 2*9*4 3*9*4 4*9*4 5*9*4 OP_ENDTMESH
Two vertices are recorded in the hardware. As each new vertex is
sent, a triangle is output with the two saved vertices and the new
one. Then the oldest vertex is discarded and is replaced by the
second oldest, and the new vertex replaces the second oldest. For
the sequence above, the state looks like this:
Saveold Savenew Output Triangle
------- ------- ------
OP_BGNTMESH: invalid invalid nothing
point 0: invalid point 0 nothing
point 1: point 0 point 1 nothing
point 2: point 1 point 2 0-1-2
point 3: point 2 point 3 1-2-3
point 4: point 3 point 4 2-3-4
point 5: point 4 point 5 3-4-5
OP_ENDTMESH: invalid invalid nothing
This is great if all you want to do is go down a ribbon outputting
triangles. If you want to turn a corner, or to have multiple
sequences, OP_SWAPTMESH reverses the contents of the Saveold and
Savenew registers, and OP_ENDBGNTMESH is ends the current sequence
and begins a new one.
One final example should illustrate this:
0-----2-----4
\ / \ / \
\ / \ / \
1-----3-----5
14-----13
/ \ / \
/ \ / \
6-----8----10-----12
\ / \ / \ /
\ / \ / \ /
7-----9-----11
To draw the pattern above, use the following mesh control sequence:
OP_BGNTMESH, 6, 0*9*4, 1*9*4, 2*9*4, 3*9*4, 4*9*4, 5*9*4,
OP_ENDBGNTMESH, 6, 6*9*4, 7*9*4, 8*9*4, 9*9*4, 10*9*4, 11*9*4,
OP_SWAPTMESH, 1, 12*9*4, OP_SWAPTMESH, 1, 13*9*4, OP_SWAPTMESH, 2,
14*9*4, 8*9*4, OP_ENDTMESH
Saveold Savenew Output Triangle
------- ------- ------
OP_BGNTMESH:
invalid invalid nothing
point 0: invalid point 0 nothing
point 1: point 0 point 1 nothing
point 2: point 1 point 2 0-1-2
point 3: point 2 point 3 1-2-3
point 4: point 3 point 4 2-3-4
point 5: point 4 point 5 3-4-5
OP_ENDBGNTMESH: invalid invalid nothing
point 6: invalid point 6 nothing
point 7: point 6 point 7 nothing
point 8: point 7 point 8 6-7-8
point 9: point 8 point 9 7-8-9
point A: point 9 point A 8-9-A
point B: point A point B 9-A-B
OP_SWAPTMESH: point B point A nothing
point C: point A point C B-A-C
OP_SWAPTMESH: point C point A nothing
point D: point A point D C-A-D
OP_SWAPTMESH: point D point A nothing
point E: point A point E D-A-E
point 8: point E point 8 A-E-8
OP_ENDTMESH: invalid invalid nothing

#include <stdio.h>
#define OBJ_QUADLIST 1
#define OBJ_TRILIST
2
#define OBJ_TRIMESH 3
#define OBJ_END 4
#define OP_BGNTMESH 1
#define OP_SWAPTMESH 2
#define OP_ENDBGNTMESH 3
#define OP_ENDTMESH 4
FILE *fp;
long meshctl[27] = {
OP_BGNTMESH, 6, 0, 1*9*4, 2*9*4, 3*9*4, 4*9*4, 5*9*4, OP_ENDBGNTMESH,
6, 6*9*4, 7*9*4, 8*9*4, 9*9*4, 10*9*4, 11*9*4, OP_SWAPTMESH,
1, 12*9*4, OP_SWAPTMESH,
1, 13*9*4, OP_SWAPTMESH, 2, 14*9*4, 8*9*4, OP_ENDTMESH };
float meshdata[15][3] = {
{3, 11, 0}, {5, 8, 0}, {7, 11, -1}, {9, 8, 0}, {11, 11, 0}, {13, 8, -1},
{2, 3, 0}, {4, 0, 0}, {6, 3, -1}, {8, 0, 0}, {10, 3, 1}, {12, 0, -1},
{14, 3, 3}, {12, 6, 2}, {8, 6, -2}
float meshnorm[15][3] = {
{0, 0, 1}, {0, 1, 0}, {1, 0, 0}, {0, 0, 1}, {0, 1, 0}, {1, 0, 0},
{0, 0, 1}, {0, 1, 0}, {1, 0, 0}, {0, 0, 1}, {0, 1, 0}, {1, 0, 0},
{0, 0, 1}, {0, 1, 0}, {1, 0, 0}
float cube[8][3] = {
{-1.0, -1.0, -1.0},
{-1.0, -1.0, 1.0},
{-1.0, 1.0, 1.0},
{-1.0, 1.0, -1.0},
{1.0, -1.0, -1.0},
{1.0, -1.0, 1.0},
{1.0, 1.0, 1.0},
{1.0, 1.0, -1.0},
float ncube[6][3] = {
{1.0, 0.0, 0.0},
{-1.0, 0.0, 0.0},
{0.0, 1.0, 0.0},
{0.0, -1.0, 0.0},
{0.0, 0.0, 1.0},
{0.0, 0.0, -1.0},
float nullcolor[3] = { 0.0, 0.0, 0.0 };
writesgomesh()
long typeandcount[3];
long i;
typeandcount[0] = OBJ_TRIMESH;
typeandcount[1] = 15*9 + 1 + 27;
typeandcount[2] = 15*9;
fwrite(&typeandcount[0], 4, 3, fp);
for (i = 0; i < 15; i++) {
fwrite(&meshnorm[i][0], 4, 3, fp);
fwrite(&nullcolor[0], 4, 3, fp);
fwrite(&meshdata[i][0], 4, 3, fp);
}
for (i = 0; i < 27; i++)
fwrite(&meshctl[i], 4, 1, fp);
writesgocube()
long typeandcount[2];
typeandcount[0] = OBJ_QUADLIST;
typeandcount[1] = 6*36;
fwrite(&typeandcount[0], 4, 2, fp);
nw(0); vw(4); nw(0); vw(5); nw(0); vw(6); nw(0); vw(7);
nw(1); vw(0); nw(1); vw(1); nw(1); vw(2); nw(1); vw(3);
nw(2); vw(2); nw(2); vw(3); nw(2); vw(7); nw(2); vw(6);
nw(3); vw(0); nw(3); vw(1); nw(3); vw(5); nw(3); vw(4);
nw(4); vw(1); nw(4); vw(2); nw(4); vw(6); nw(4); vw(5);
nw(5); vw(0); nw(5); vw(3); nw(5); vw(7); nw(5); vw(4);
vw(n)
long n;
fwrite(&cube[n][0], 4, 3, fp);
nw(n)
long n;
fwrite(&ncube[n][0], 4, 3, fp);
fwrite(&nullcolor[0], 4, 3, fp);
octvert(n)
long n;
fwrite(&ncube[n][0], 4, 3, fp);
fwrite(&nullcolor[0], 4, 3, fp);
fwrite(&ncube[n][0], 4, 3, fp);
sgotri(a, b, c)
long a, b, c;
octvert(a); octvert(b); octvert(c);
writesgooct()
long typeandcount[2];
typeandcount[0] = OBJ_TRILIST;
typeandcount[1] = 8*27;
fwrite(&typeandcount[0], 4, 2, fp);
sgotri(0, 2, 5);
sgotri(0, 5, 3);
sgotri(0, 3, 4);
sgotri(0, 4, 2);
sgotri(1, 2, 5);
sgotri(1, 5, 3);
sgotri(1, 3, 4);
sgotri(1, 4, 2);
main()
long end = OBJ_END;
/* comment out all but one of the next three lines */
writesgoheader();
/*writesgocube();*/
/*writesgooct();*/
writesgomesh();
fwrite(&end, 4, 1, fp);
fclose(fp);
writesgoheader(polycount)
long polycount;
long magic;
magic = 0x5424;
fp = fopen("sgoout", "w");
fwrite(&magic, 4, 1, fp);