Documentation for Vrml2OGL.exe V1.0
Copyright 1999 by Alexander Rohra. All rights Reserved.
(See ReadMe.txt for a text version of this file.)
Contents:
I. Introduction
II. Archive Contents
III. Disclaimer and Distribution Notice
IV. Contact Infomation
V. Limitations and Notes
General Information about the Source Code
Terminology
Header Files and Definition Order
VRML Worlds and Camera & Light Definitions
Model Correction/Appearance
Major Shortcomings
Data Precision
Status/Error Codes
Suggested Speed Improvements
Recognized Nodes
Unsupported Nodes
Various Notes
I. Introduction
Vrml2OGL converts a VRML V1.0 file to OpenGL C source code and stores it
in the following three output files:
1) an OpenGL file holding the object drawing code contained in a C-callable
function
2) a header file containing the function prototype for the object drawing
function contained in the OpenGL C file, a few #define statements and
extern variable definitions
3) a data file containing matrix as well material/color arrays (which are
made public by the header file)
The order of the OpenGL file will correspond to the order of the input
.WRL file as closely as possible. The resulting code can be included in any
source code project. In order to view a converted model, at least a light
source and camera transformations need to be set up, prior to calling the
object drawing function contained in the OpenGL file.
The following is a list of command line switches recognized by Vrml2OGL
and their explanations:
-? : show this list of command line switches and their descriptions
-it : include transformations such as translations, rotations, etc. if
present in the input file (by DEFAULT xfrms are not included)
-c : compute the object center and subtract it from all object coordinates
-cxV : subract a value from each x coordinate, where V is any real number
(0.0 by DEFAULT)
-cyV : subract a value from each y coordinate, where V is any real number
(0.0 by DEFAULT)
-czV : subract a value from each z coordinate, where V is any real number
(0.0 by DEFAULT)
-rf : invert the contents of the glFrontFace() statement; this inverts
either the default face order or the face order specified by the
input file for the current vertecis
-rn : revert all normals (generated or retrieved from the input file)
-fV : for each logical indentation use V amount of spaces, where 0<=V<8
-ft : for each logical indentation use one TAB (DEFAULT)
-bV : precede each line with an identation base of V amount of spaces,
where 0<=V<8
-bt : precede each line with an identation base of one TAB (DEFAULT)
-d : prints progress info to stdout (helpful for debugging)
Note: The -d option is only available if the program was compiled with
_V_DEBUGMODE_ defined. The -? option will show if this was the case for the
version of Vrml2OGL.exe that you are using.
The -fV, -ft, -bV and -bt options only affect the appearance of the
generated source code in the OpenGL file. The effect is purely "cosmetic"
and has no influence on the code's functionality or performance.
For additional information on some of the options listed above, please
view the notes under "V. Limitations and Notes" below.
The first command line argument not recognized by Vrml2OGL is considered
the end of the list of command line switches (if any) and the name of the
input file. The following three parameters (if present) are considered the
file names of the OGL.c, Hdr.h and Dat.c files - in this order.
Note: If there are less than 3 arguments left after the name of the input
file, Vrml2OGL ignores these arguments and creates 3 default file names
(name of input file (without any non-aplha numeric characters)followed by
OGL.c, Hdr.h and Dat.c).
II. Archive Contents
The archive containing this file and Vrml2OGL.exe also contains the entire
source code needed to compile Vrml2OGL.exe. Please read the Disclaimer and
Distribution Notice below prior to using ANY of the supplied files.
The following list shows the file names of all files supplied:
ReadMe.html (this file)
ReadMe.txt (essentially the same as this file but in ASCII text)
Vrml2OGL.exe
src\FindNodes.cpp
src\FindNodes.h
src\GeometryUtils.cpp
src\GeometryUtils.h
src\MakeDebug.bat
src\MakeRelease.bat
src\SharedDefs.h
src\Vrml2OGL.cpp
src\Vrml2OGL.h
src\Vrml2OGL.mak
src\Vrml2OGLUtils.cpp
src\Vrml2OGLUtils.h
III. Disclaimer and Distribution Notice
This program, Vrml2OGL.exe and its accompanying source files, are
distributed in the hope that they will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY, COMPLETENESS or
FITNESS FOR ANY PARTICULAR PURPOSE.
The author, Alexander Rohra, accepts no responsibility for any loss or
damage to any person(s) and/or hardware or software, as a result of using
the program Vrml2OGL.exe or its source code.
Vrml2OGL.exe is released into public domain as "FREEWARE" and may be
freely copied and modified provided the disclaimer mentioned above is
maintained in effect for any released versions.
IV. Contact & Download Information
For comments, questions and/or problems write to arohra@geocities.com.
Please be aware that I might not be able to help you and/or publish any
further versions of this program.
In case you are missing any of the files listed under
"II. Archive Contents" you can download the complete archive from
http://www.geocities.com/SiliconValley/Program/3830 (updates will be posted
here first), ftp://ftp.cdrom.com/pub/simtelnet/win95/graphics/vr2ogl10.zip
or ftp://avalon.viewpoint.com/pub/utils/converters/vr2ogl10.zip.
V. Limitations and Notes
* General Information about the Source Code
Vrml2OGL.exe is compiled of multiple .cpp files. However, you will
notice that the code contained in these source code modules is almost 100%
C code. The only C++ feature used that required the .cpp file extension is
"the free store" (new/delete). I prefered this over malloc() due to its
ease of use and its flexibilty.
The source code can be easily compiled, either by using the included
MakeRelease.bat or MakeDebug.bat batch files, or by creating a "Win32
Console" project, including all supplied .cpp files in it and compiling it
from the IDE. If you decide to use the batch files, you should ensure that
that the directory paths specified in them, match the paths on your PC. By
default, they assume a standard base path of
C:\Program Files\DevStudio\VC.
Many functions are very similar to one another (even by name). This was
done to cut down complexity in each function, thereby improving execution
speed.
Coordinate3 and Normal data is read into memory as doubles. Considering
that each of these numbers are rounded to 4 digits after the decimal point
when output, floats should actually be sufficient (this would have a
slightly negative impact for Coordintate3 data when it is being used to
calculate corresponding normals).
Note: Please be aware that there are probably a number of more complete
and efficient converters of this kind (such as VRML2GL.exe by Leigh McRae
(C) 1997 by Now Enterprises) in existence. Also - as I discovered when I
was 75% done with this project - there are professional code libraries
available that can greatly assist in parsing and interpreting VRML files
(see http://www.sdsc.edu/vrml/dvsoftware.html for more information on such
libraries).
* Terminology
When you view the supplied source code you will notice the word
"indentation" or "indent". I used this term to describe what is actually
considered a parent node. In other words instead of using "parentNode" I
used the far more generic and visually inspired term "indentation". You
will see this term in context with the following nodes: Separator, Group,
Switch, LOD and TransformSeparator.
The term "stack" is used conceptually and refers to indentArray[]. This
array is used in adherence to the FIFO (first in, first out) feature of a
stack.
* Header Files and Definition Order
All shared definitions (that do not exactly belong to one source code
module and/or are shared by at least two source code modules) are stored
in SharedDefs.h. Define statements only needed within a specific source
code module are stored in the source code module's header file.
Extern variable definitions are contained in their source code modules'
header files.
Function prototypes are either contained in the source code module in
which they are implemented, or if they need to be public to other
functions, they are contained in their source code modules' header files.
* VRML Worlds and Camera & Light Definitions
Vrml2OGL was written to allow the user to easily import 3D models into
OpenGL. However, it was NOT written to convert whole VRML worlds.
Since camera and light defintions are not truly part of an object but
rather describe how the object is viewed, all commands pertaining to
cameras and lights are ignored and will not appear in the output OpenGL
file. In this way, the code prior to calling the generated object drawing
function has total freedom to determine how the object is viewed.
* Model Correction/Appearance
In an attempt to fix some of the problems that I noticed during testing
of Vrml2OGL, I added the -c, -cx, -cy, -cz, -rf and -rn options.
Use any of the -cx, -cy or -cz options to manually adjust the center of
an object. Otherwise, using the -c option, Vrml2OGL auto adjusts the
center by calculating the middle of the object's bounding box and
subtracting these coordinates from all vertex coordinates making up the
object.
Please note that the -c* options do not have an effect on coordinate
transformations (see -it option) and vice-versa.
If your model appears transparent or polygons faced opposite to the
light source are lit, try the -rf and/or the -rn options.
For more information on any of these options, please see their
respective descriptions under "I. Introduction" above.
Since I was unable to properly view models with transparency or face
ordering problems in a regular VRML viewer, I assume that these problems
are contained in these VRML files and possibly stem from one or more
conversions the models might have undergone, prior to arriving in VRML
format.
Note: Vrml2OGL auto-inserts a few lines of code (calls to glCullFace(),
glBlend(), glEnable() and glDisable()) at the beginning and end of the
each OpenGL file (*OGL.c). While this code generally improves the
appearance of the model and its rendering performance, it can in certain
situations cause exactly the opposite.
GL_NORMALIZE will unnecessarily slow down rendering performance if neither
glScale() nor glMultMatrix() are being used (either contained in the
model's code through the -it option or applied by your own code prior to
drawing the model).
glCullFace() can make parts of a model disappear if the normals of those
parts are set incorrectly.
If you notice any of the negative effects just described, or know that for
this model the above default settings are unnecessary/undesirable, you
should manually uncomment or erase the respective lines of code from the
OpenGL file.
* Major Shortcomings
DEF tags are converted to comments instead of function names (provided
the actual tag is located in between the DEF and the node specifier within
_one_ line). Therefore, USE statements are ignored.
Files actually referencing DEF tags via USE will not be converted
properly. Depending on what kind of resources the USE statement refers
to, Vrml2OGL might or might not issue an error message.
Texture coordinates, indecis and bitmaps are not supported. Vrml2OGL
will simply ignore any commands pertaining to textures.
Most error messages issued by Vrml2OGL are specific to the kind of
problem that occurred; however, unfortunately no line number is given
indicating the position in the input file where the problem occurred.
The -d option offers some help in this regard by outputting generic
statements describing what Vrml2OGL is currently doing. However, only by
carefully tracking down those statements and comparing them to the VRML
code (in the input file,) can an approximate fault position be located.
I did not implement line numbers since I felt that debug statements were
sufficient for my use. They might, however, be highly insufficient with
large VRML files. I don't think that it would be too difficult to modifiy
the program in order to add line numbers and might do so for a future
version.
Vrml2OGL expects the beginning and ending ("}") of node specifiers to be
contained in separate lines. Once the handling function for a given node
returns, after finding the end of the node it handled, the next node
specifier or close brace is expected to be found in one of the following
lines. Most files will adhere to this order; there might, however, be
some files that do not adhere to this in which case, Vrml2OGL might
produce incorrect results or terminate due to an incorrectly detected
error (since the error most likely resulted from Vrml2OGL's inability to
deal with node specifiers and node endings within one line).
Examples of such problem lines would be "} Coordinate3" (Coordinate3 might
not be registered causing the whole node to be ignored) or "}}" (the
second close brace might not be registered causing a parent node not to be
closed).
This could be _fairly_ easily fixed by making each handling function blank
out part of the line containing the end of the node up to and including
the last character belonging to that node. In addition, the node specifier
find function (findNodes()) would have to be adjusted so that it continues
scanning the lines returned from handling functions for the next node
specifier.
* Data Precision
Data read from the input VRML file is stored with its full precision in
doubles. Any calculations necessary (such as the calculation of polygon
normal vectors) are, therefore, performed at double precision.
However, when output (to the 3 output files (OGL.c Dat.c & Hdr.c)) all
data is rounded to a precision of 4 digits after the decimal point.
* Status/Error Codes
All status code defines end with the letters "ERR" indicating a certain
error condition; an exception to this are "NOERR" and "SUCCESS". "NOERR"
indicates that no error occurred, while "SUCCESS" not only indicates that
no error occurred, but also that an operation succeeded.
Most functions will return "NOERR" to indicate success; in some cases,
however, where more than 3 general outcome stati (aborted due to an error,
a request could not be fulfilled but is not considered an error, the
request was fulfilled) can occurr, "SUCCESS" is returned (see
readToBegOfNum() in Vrml2GLUtils.cpp.)
Generic error code defines are preceded by the letters "GEN" and are
indicated through a generic error message (see outputGenericErrorMsgs()
in Vrml2GLUtils.cpp.)
All error code defines NOT preceded by "GEN" are indicated by individual
error messages (always written to stderr) following the source code that
detected them.
The following list shows all status and error codes used by Vrml2OGL.
Also shown are the values associated with each code, and their
descriptions. Depending on the outcome of the conversion, Vrml2OGL will
return one of these values to the invocation environment.
NOERR 0 no error was detected - the operation/conversion was
successful (see above)
SUCCESS 1 internal use only - should not be returned to the
invocation environment (see above)
OPENERR 2 open error - the indicated input or output file could
not be opened in the appropriate access mode
SYNTAXERR 3 syntax error - this error code is used generically; it
is issued whenever Vrml2OGL cannot interpret part of
the input file as expected; it can only be understood
in the context of the displayed error message
VERSIONERR 4 version error - the first line of the input file did
not contain the string "#VRML V1.0 ascii"
NESTEDLODERR 5 nested LOD error - an LOD node was found within another
LOD
OUTOFWARRAYERR 6 out of work array error - the size of the internal work
array (double workArray[MAXWORKARRAY]) was insufficient
in order to store a Coordinate3 or Normal array in it
GENINPREADERR 7 generic input error - a read error was detected when
reading from the input file
GENOUTPWRITEERR 8 generic output error - a write error was detected when
writing to the OGL.c file
GENDATWRITEERR 9 generic Dat output error - a write error was detected
when writing to the Dat.c file
GENHDRWRITEERR 10 generic Hdr output error - a write error was detected
when writing to the Hdr.h file
GENALLOCERR 11 generic memory allocation error - a certain amount of
memory could not be allocated
GENUNEXPEOFERR 12 generic unexpected end of file error - the end of the
input file was found at an invalid point (relative to
its context)
GENFTELLERR 13 generic ftell() error - the file position in the input
file could not be retrieved
GENFSEEKERR 14 generic fseek() error - could not adjust the file
position for one of the file pointers used for reading
the input file
* Suggested Speed Improvements
Currently Vrml2OGL (V1.0) uses 3 file pointers once it finds the
beginning of an IndexedFaceSet node. It does this in order to read and
output the material, normal and coordinate data for each vertex
simultenously. All three file pointers start out at the beginning of the
IndexedFaceSet node and read through the node, each looking for either the
coordIndex, normalIndex or materialIndex specifiers prior to starting to
read any of the indecis. Most of the time, the materialIndex specifier
appears last, in which case, the file pointer that is looking for this
node also has to read through all the indecis belonging to the normalIndex
and coordIndex specifiers. Similarly, most of the time, the file pointer
used for retrieving the normalIndex array has to read through the entire
coordIndex array. This redundant reading of lines just read by another
one of the 3 file pointers, costs a fair amount of time (particularly if
the input file is a few MB big) and could be eliminated.
The file could be read in larger chunks to minimize file access
(instead of line by line.) The iostream C++ class might also provide a
speed improvement over stdio functions such as fread() and fprintf().
Vrml2OGL currently tries to read as little data into memory as possible
(only Coordinate3, Normal and Material data). Though considering the
memory capacity of most PCs nowadays, more data could be read into memory
which could (if done correctly,) in turn, increase processing time.
* Recognized Nodes
The following nodes are recognized by Vrml2OGL:
Separator (see note below)
Group (see note below)
Switch (see note below)
TransformSeparator (see note below)
LOD (see note below)
Coordinate3
ShapeHints (see note below)
IndexedFaceSet
IndexedLineSet
Normal
Material
Transform (see note below)
Translation (see note below)
Rotation (see note below)
Scale (see note below)
MatrixTransform
Info (see note below)
* Unsupported Nodes
The following nodes are ignored:
NormalBinding (see note below)
MaterialBinding (see note below)
Cone
Cube
Cylinder
Sphere
PointSet
Texture2 (see note above under "Major Shortcomings")
TextureCoordinate2 (see note above under "Major Shortcomings")
Texture2Transform (see note above under "Major Shortcomings")
DirectionalLight
SpotLight
PointLight
OrhtographicCamera
PerspectiveCamera
FontStyle
AsciiText
WWWInline
WWWAnchor
* Various Notes
The following notes give insight into how Vrml2OGL interprets .WRL files
and indicate some of its shortcomings.
* Separator
- The renderCulling statement is ignored.
- All attributes and the current transfrom matrix are pushed onto the
stack when a separator node is found. These states are popped off the
stack when the end of the node is found.
* LOD
- LODs are essentially ignored. Only the data defining the first
(/highest) level of detail is retrieved while the data defining all
remaining levels of detail is ignored.
Each Separator that is a direct child to an LOD node is considered
the beginning of a new level of detail. Therefore, the first Separator
after the LOD node is considered the beginning of the first level of
detail. Once this Separator's close brace is found, the next Separator
is considered the beginning of the next level of detail and so on,
until the close brace of the parent LOD node is found.
Even when pre-scanning the input file, in order to find the bounding
box (see findBoundingBox(),) only the first (/highest) level of detail
of every LOD is included besides all coordinates outside of LOD nodes.
* Switch
- The Switch node can contain any type of child nodes. However, Vrml2OGL
does not consider it as having any effect on its child nodes and
therefore, only recognizes it in order to keep track of its open and
close braces. Unlike the Separator node it does not cause a new stack
entry or have any other effect.
- The whichChild statment is ignored.
* TransformSeparator
- The TransformSeparator node can contain any type of child nodes. It is
important to note that Vrml2OGL ignores its CTM saving effect and only
keeps track of its open and close braces. Unlike the Separator node,
it does not cause a new stack entry or have any other effect.
This node is used seldomly.
* Group
- The Group node can contain any type of child nodes. However, Vrml2OGL
does not consider it as having any effect on its child nodes and
therefore, only recognizes it in order to keep track of its open and
close braces. Unlike the Separator node, it does not cause a new stack
entry or have any other effect.
* ShapeHints
- The vertexOrdering statement is recognized by Vrml2OGL and is output
as glFrontFace(). If no vertexOrdering statement was found, the
vertecis are assumed to be in counter clockwise order.
Vrml2OGL generates default normals accordingly;
Note: The -rf option only affects the contents of the glFrontFace()
statement. Default normals will still be calculated according to
the vertex order retrieved from the input file (or according to
the default vertex order, if the input file did not specify a
vertexOrder for the vertecis being processed.)
However, in order to reverse ALL normals (this includes
default normals generated by Vrml2OGL as well as normals
retrieved from the input file,) use the -rn option.
- All faces are assumed to be convex ,therefore, the faceType specifier
is ignored.
- The creaseAngle statement is ignored. It could be implemented by
computing vertex normals (=average of all polygon normals of the
polygons that contain this vertex (use vertex indecis in coordIndex
array to find all polygons that contain this vertex)) for each vertex.
Ignoring the creaseAngle statement causes some objects to look
flat-shaded instead of smooth-shaded.
* NormalBinding & MaterialBinding
- Only PER_VERTEX_INDEXED and PER_FACE bindings are implemented and are
figured depending on whether or not a current IndexedFacesSet node
containing coordIndex data also contains normalIndex/materialIndex
data. In absence of normalIndex/materialIndex data, NormalBinding/
MaterialBinding (respectively) is assumed to be PER_FACE.
* Transform
- Only center, rotation, scaleFactor and translation statements have
been implemented.
- The scaleOrientation statement is ignored.
- By default transformations are excluded from the OpenGL file, since
in many cases, they position the model in an undesirable location in
world space. Use the -it option in order to include all
transformations.
* Rotation, Scale and Translation
- These nodes have been implemented and perform the same way as the
respective commands for Transform nodes.
- By default transformations are excluded from the OpenGL file, since
in many cases, they position the model in an undesirable location in
world space. Use the -it option in order to include all
transformations.
* # Comments
- # comments are stripped off and dropped.
* Info Nodes
- These nodes are inserted into the OpenGL file as comments relative to
the same location as in the VRML file.
Copyright 1999 by Alexander Rohra. All rights reserved.
End of Document