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