GLASS models are stored in plaintext files, using the following format.
How GLASS reads a model file
GLASS reads the model file by breaking it into words.
A word is a continuous string of non-whitespace characters surrounded by
whitespace, or a string of characters surrounded by double quotes ("). The double quotes
do not count towards the word. For example if a GLASS model file contained the line:
foo
bar "foo bar"
GLASS would read this as three words, `foo', followed by `bar', and `foo bar'.
Comments are started by the hash character (#), and a terminated by the next newline. Comments are completely ignored by GLASS. For example:
# A comment
begin something # Another comment
# More comments
end
GLASS would read this as:
begin something
end
Options in a GLASS model file
The following fields are read from the file:
An example of a texture component is:
begin texture
name "marble texture"
image "textures/marble.rgb"
end
This defines a new texture with the name "marble texture", that uses the image file
"marble.rgb" which is found in the the subdirectory "textures/" which is in the directory
the GLASS model is in.
Materials
Materials define the lit properties, and the texture used by triangles in the GLASS model.
A material component has seven fields. These are:
An example of a material is:
begin material
name "blue marble"
texture "marble texture"
ambient 0.1 0.1 0.8 1.0
diffuse 0.1 0.1 0.8 1.0
specular 1.0 1.0 1.0 1.0
emission 0.0 0.0 0.0 1.0
shininess 10.0
end
An example of a surface is:
begin surface
name "marble pyramid"
{
material "blue marble"
pos 0 0.0 0.0 -5.0
col 0 1.0 0.0 0.0
nor 0 0.0 -1.0 0.0
tex 0 0.5 0.0
pos 1 4.330127 0.0 2.5
col 1 0.0 1.0 0.0
nor 1 0.0 -1.0 0.0
tex 1 0.9330127 0.75
pos 2 -4.330127 0.0 2.5
col 2 0.0 0.0 1.0
nor 2 0.0 -1.0 0.0
tex 2 0.0669873 0.75
}
{
material "blue marble"
pos 0 4.330127 0.0 2.5
col 0 0.0 1.0 0.0
nor 0 0.774597 0.447214 -0.447214
tex 0 0.9330127 0.75
pos 1 0.0 0.0 -5.0
col 1 1.0 0.0 0.0
nor 1 0.774597 0.447214 -0.447214
tex 1 0.5 0.0
pos 2 0.0 5.0 0.0
col 2 1.0 1.0 0.0
nor 2 0.774597 0.447214 -0.447214
tex 2 0.5 0.5
}
{
material "blue marble"
pos 0 0.0 0.0 -5.0
col 0 1.0 0.0 0.0
nor 0 -0.774597 0.447214 -0.447214
tex 0 0.5 0.0
pos 1 -4.330127 0.0 2.5
col 1 0.0 0.0 1.0
nor 1 -0.774597 0.447214 -0.447214
tex 1 0.0669873 0.75
pos 2 0.0 5.0 0.0
col 2 1.0 1.0 0.0
nor 2 -0.774597 0.447214 -0.447214
tex 2 0.5 0.5
}
{
material "blue marble"
pos 0 -4.330127 0.0 2.5
col 0 0.0 0.0 1.0
nor 0 0.0 0.447214 0.894427
tex 0 0.0669873 0.75
pos 1 4.330127 0.0 2.5
col 1 0.0 1.0 0.0
nor 1 0.0 0.447214 0.894427
tex 1 0.9330127 0.75
pos 2 0.0 5.0 0.0
col 2 1.0 1.0 0.0
nor 2 0.0 0.447214 0.894427
tex 2 0.5 0.5
}
end
This defines a multi-coloured tetrahedron, that when lit has the material "blue marble".
Variables
A variable controls transforms used by the GLASS model. It has four fields.
An example of a variable is:
begin variable
name "size"
min 0.1
max 10.0
value 1.0
end
An example of an active point is:
begin active_point
name "pyramid tip"
initial_dir 0.0 1.0 0.0
end
The type is followed by n parameters, which can be a floating point constant, or a variable. Variables are used by adding "V::" to the front of the variables name.
Examples of transforms are:
transform TRANSLATE 1.2 -2.1 3.9
transform SCALE_EVEN "V::scale factor"
transform SCALE 1.0 "V::y scale factor" 2.8
An example of two nodes are:
begin node
index 0
transform SCALE_EVEN "V::size"
surface "marble pyramid"
end
begin node
index 1
transform TRANSLATE_Y 5.0
active_point "pyramid tip"
end
To draw the structure, convert the indices of the nodes to three character numbers, for example the index 21 would go to 021. Start by writing the index of the root node. If the root has a child, its index would go directly below it. If the root has a sibling, its index would be written to the right of the root index, with 8n-3 dashes (-), between them. (n is the number of rows across you want this index). Continue to do this for each node, building up the tree of how the nodes link together.
This is perhaps hard to explain, but easy to do in practice (see the below examples).
An example of a structure is:
begin structure
000
001
end
This shows that node 000 (index=0), is the root node, and node 001 (index=1), is a child of this node.
An example of a more complicated structure is:
000
001---------------------013-----015
002-----003-----010 014 016
004 005 011 017 019
006 007 012 018 020
008 009 021 023
022 024
As you can see, this way is easier to do by hand, as you can see the "big picture" as
you link the nodes together. If you had used the children field, you would
be more likely to make a mistake.
A complete GLASS model
All the above components can be written into the file in any order, although it is
perhaps a good idea to stick to the above order, to keep the file logical. Collecting
the examples used above, we can create a textured pyramid, with one variable that
changes the size of the pyramid, and a point on the top of the pyramid that allows us to
find out how high it is.
The finished model:
# An example of how to create a GLASS model
# A textured pyramid, with a variable to change the size, and
# an active point to find the height of the pyramid.
#
# See glass.sourceforge.net for details
name "pyramid"
version "1.2.0"
# The texture used by the pyramid
begin texture
name "marble texture"
image "textures/marble.rgb"
end
# The material used by the surfaces of the pyramid,
# uses the above texture
# It's a blue colour
begin material
name "blue marble"
texture "marble texture"
ambient 0.1 0.1 0.8 1.0
diffuse 0.1 0.1 0.8 1.0
specular 1.0 1.0 1.0 1.0
emission 0.0 0.0 0.0 1.0
shininess 10.0
end
# The triangles that make up the pyramid
begin surface
name "marble pyramid"
{
material "blue marble"
pos 0 0.0 0.0 -5.0
col 0 1.0 0.0 0.0
nor 0 0.0 -1.0 0.0
tex 0 0.5 0.0
pos 1 4.330127 0.0 2.5
col 1 0.0 1.0 0.0
nor 1 0.0 -1.0 0.0
tex 1 0.9330127 0.75
pos 2 -4.330127 0.0 2.5
col 2 0.0 0.0 1.0
nor 2 0.0 -1.0 0.0
tex 2 0.0669873 0.75
}
{
material "blue marble"
pos 0 4.330127 0.0 2.5
col 0 0.0 1.0 0.0
nor 0 0.774597 0.447214 -0.447214
tex 0 0.9330127 0.75
pos 1 0.0 0.0 -5.0
col 1 1.0 0.0 0.0
nor 1 0.774597 0.447214 -0.447214
tex 1 0.5 0.0
pos 2 0.0 5.0 0.0
col 2 1.0 1.0 0.0
nor 2 0.774597 0.447214 -0.447214
tex 2 0.5 0.5
}
{
material "blue marble"
pos 0 0.0 0.0 -5.0
col 0 1.0 0.0 0.0
nor 0 -0.774597 0.447214 -0.447214
tex 0 0.5 0.0
pos 1 -4.330127 0.0 2.5
col 1 0.0 0.0 1.0
nor 1 -0.774597 0.447214 -0.447214
tex 1 0.0669873 0.75
pos 2 0.0 5.0 0.0
col 2 1.0 1.0 0.0
nor 2 -0.774597 0.447214 -0.447214
tex 2 0.5 0.5
}
{
material "blue marble"
pos 0 -4.330127 0.0 2.5
col 0 0.0 0.0 1.0
nor 0 0.0 0.447214 0.894427
tex 0 0.0669873 0.75
pos 1 4.330127 0.0 2.5
col 1 0.0 1.0 0.0
nor 1 0.0 0.447214 0.894427
tex 1 0.9330127 0.75
pos 2 0.0 5.0 0.0
col 2 1.0 1.0 0.0
nor 2 0.0 0.447214 0.894427
tex 2 0.5 0.5
}
end
# A variable to control the scale of the pyramid
begin variable
name "size"
min 0.1
max 10.0
value 1.0
end
# An active point to get the height of the pyramid
begin active_point
name "pyramid tip"
initial_dir 0.0 1.0 0.0
end
# The nodes
# Scale the pyramid, and draw it
begin node
index 0
transform SCALE_EVEN "V::size"
surface "marble pyramid"
end
# Translate up to the top of the (unscaled) pyramid, and put
# an active point there. (This node will inherit the
# scale transform from the above one).
begin node
index 1
transform TRANSLATE_Y 5.0
active_point "pyramid tip"
end
# How the nodes link together
# Could have done this in the definitions of each node,
# but since writing this by hand, it's easier this way
begin structure
000
001
end