Box Definitions Reference (0010.BoxName)

There are several ways to view into the reference guide:

What follows is the the command reference. If you find errors in the docs, please contact us via email to support@cinegrfx.com.


REFERENCE GUIDE

SHADETREE-BOXES(1)         Cinema Graphics, Inc.            SHADETREE-BOXES(1)

NAME
    shadetree-boxes - The ShadeTree operation box definitions file

DESCRIPTION
    This document describes the commands in the ShadeTree box definitions
    files.

    Each 'box' in the ShadeTree program has an ASCII 'definitions' file
    associated with it, containing commands that describe the size and
    color of the box, the buttons, the icons, the kind of sliders for
    each button, and what code is generated when the box is on the desk.

    ShadeTree's own operation box definitions can be found in the
    directory tree:

        /usr/local/shadetree/{prman,mray}/menu/*

    This directory tree reflects the 'Operation Menu Bar' in the interface;
    subdirectories are found as  'sub menus' in ShadeTree. Any files show
    up as selectable items in these menus.  When selected, each loads its
    file-information as a box definition, or as a stree file.

    When ShadeTree is invoked by a user, the menu directory is recursively
    descended to create the Operation Menu Bar.

    If the user has their own menu directories, ShadeTree can be
    instructed to descend those directories by specifying the following
    command in the ./stree.defs or ~/.stree.defs file:

        menudir.add /your/path/menu
        menudir.add /another/path/menu

    NOTE: The last directory component MUST be called 'menu', for correct
          sorting into the menus.



TABLE OF CONTENTS

  • 1.0.0 FILE NAMING CONVENTIONS
  • 2.0.0 CUSTOM BOXES


    
    
    


    1.0.0 FILE NAMING CONVENTIONS Files and directories should all have names of the form: 0000.name ..where '0000' is a padded number that is used to control the sorting order, to control placement in the menus. ShadeTree strips these numbers away when displaying the menus. Basically, the order that 'ls' shows the files, is the order in which ShadeTree will display the menus' respective items. Consider the following example 'ls' listing of a menu sub directory: 0010.dice 0010.bend 0010.fuzz 0010.slice 0010.zoom 0020._SEPARATOR_ 0021.row 0022.column 0030._SEPARATOR_ Note that 'dice', 'bend', 'fuzz', 'slice' and 'zoom' display alphabetically, because the '0010.' prefix is the same for all of them. However, 'row' and 'column' display non-alphabetically, as the numbers override the sort order. Note too that '_SEPARATOR_' files are used to create menu separators, to allow for visual separation in the menus.


    1.2.0 BOX DEFINITIONS FILE: A REFERENCE GUIDE The operation box description file has several commands that control the physical attributes of the box, such as color, size, icons. It also controls the macro expansion for generating code. It is recommended that you find a box in the ShadeTree menu directory that is closest to your needs, make a copy of the file, and doctor it to your liking. What follows is a brief description of the box defintions commands. This list MAY be incomplete; software evolves more quickly than the tech docs. If you encounter errors, please send mail to support@cinegrfx.com.


    1.2.1 icontext - sets text to appear in place of icon images NAME icontext <text> DESCRIPTION Specifies text to be displayed if icons are disabled from the interface, or if no 'iconimg' is specified. <text> should NOT contain spaces.


    1.2.2 iconimg - sets icon image for the box (.sgi, .rgb) NAME iconimg <filename> DESCRIPTION Specifies the filename of the icon to be displayed. The file must be in either of the machine's native image formats; .sgi or .rgb files. The alpha channel of the image is used to blend the icon into the color of the box. If <filename> does NOT start with a '/' (ie., not an absolute path), the contents of $STREE_LIB is prepended to the pathname. So, if the command is: iconimg icons/foo.sgi and STREE_LIB resolves to '/usr/local/shadetree/prman', then the file loaded will be '/usr/local/shadetree/prman/icons/foo.sgi'. If no 'iconimg' command is specified, the 'icontext' is displayed instead. The icon image can be any size. If the icon is LARGER than could fit in the box, the box's size is enlarged. If the icon is very small, and the box size is large, the icon will center within the box. To save memory, icons are only loaded once (buffered), regardless of the number of times the box is instanced on the desk.


    1.2.3 size - sets the image size NAME size <x> <y> DESCRIPTION Specifies the default size of the box in pixels. If no iconimg is specified, the size is used. If an icon image is specified, size will be effective ONLY if the size of the icon image fits within the specified box. Otherwise a large icon will enlarge the box, overriding the 'size' specification.


    1.2.4 color - sets the color of the box NAME color <r> <g> <b> DESCRIPTION Specifies the overall box color as normalized values; <r> <g> and <b> must all be within the range 0.0 to 1.0. EXAMPLE: color .5 .5 .5 ..yields a 50% gray box. CAVEATS Ignore comments for 'color' in any menus that indicate '0 0 0 = grey'; these comments refer to an old version behavior that is no longer valid.


    1.2.5 boxhelp - set the help text for the box NAME boxhelp { <text> } DESCRIPTION Specifies help text for the box. This text is displayed in the status bar when the mouse is sitting on the icon or box title bar. Text may be free form. Leading white space is ignored. NOTE: Text must be enclosed within braces, as shown above.


    1.2.6 codegen - defines the code macros for the code generator NAME codegen.<section> <operation> <macro-code> .. <<EOT>> EXAMPLES codegen.main-header unique float _STREE_PULSE_low; float _STREE_PULSE_hi; <<EOT>> codegen.main-body append _STREE_PULSE_low = 0.5 - (WID/2); _STREE_PULSE_hi = 0.5 + (WID/2); OUT = (smoothstep(_STREE_PULSE_low-FUZ, _STREE_PULSE_low, EDG) - smoothstep(_STREE_PULSE_hi-FUZ, _STREE_PULSE_hi, EDG)); <<EOT>> DESCRIPTION This is where the real stuff happens. These commands define the macro text that is used by the code generator for creating the program's source code when the box is on the desk. <macro-code> is free-form text that is generated when the macro is expanded. Any words within the macro that match the names of input or output buttons will be expanded to either constants or variable names by the main program's internal code generator. <section> can be any of the following, and basically defines where in the program the <macro-code> should be expanded: global-open - the absolute top of the program global-header - area where '#include' commands should appear main-open - the shader function's declaration area main-args - the shader argument area main-args-close - the argument close area main-header - the top of the function's code body main-body - the function's main code body main-close - the bottom of the function (exit commands) global-close - the absolute end of the program <operation> can be any of the following, and specifies how the macro is expanded: insert - insert the macro code above all code for this <section>. Rarely used. append - append the macro code to the program, in the order specified by program layout. Most commonly used. unique - append each line of <macro-code> only if the section doesn't already have the same line of text. Useful for declaring '#include' commands, which should only appear once, or when defining 'global variables' that should only be declared once. The macro text can contain double quotes. Beware that the macro expander will still expand names, EVEN if they are within double quotes. You may use '\' to escape macro text, to prevent unwanted expansions. <<EOT>> must appear flush left, to terminate the macro-code.


    1.2.7 wwms.argname - set arg editor default 'name' NAME wwms.argname string DESCRIPTION Rarely used, this presets a default argument name to a fixed string. If unspecified, a default name will be created that is a mangled version of the box title and button title. This can only appear WITHIN the declaration of an input or vinput button.


    1.2.8 macro.fixedtext - sets a fixed string for macro expansion NAME macro.fixedtext string DESCRIPTION Useful when you want the default for a button to be a global variable, or unchangeable constant. Rarely used, this forces a button's default macro expansion to be the raw text string specified, whenever the button is unconnected. When defined, NO SLIDER will appear for this button; the default will be the hard coded string defined by macro.fixedtext, and it will not be changable by the user. (If you want it to be changeable, you can abuse the 'string' datatype to allow users to enter raw strings for macro expansion) For use in input or vinput constructs only. EXAMPLE input A { macro.fixedtext P xyz { 0.0 0.0 0.0 -100.0 100.0 0 "point(%g, %g, %g)" } } ..In this example, if the button is unconnected, the macro expansion for the button will be 'P'. If connected to something else, the datatype will be 'xyz', and the code expanded as defined by "point (%g, %g, %g)". Note that the default min/max/value in the xyz command will be effectively ignored, because no slider is created for this button.


    1.2.9 input - define an input button construct NAME input Foo # set the input button's name to 'Foo' { [commands] # described below } DESCRIPTION This command adds an 'input button' to the currently defined opbox. Within this construct, you define the name of the button, the type of data that it represents, the default slider values (if any). The button name is ALSO the variable name that should appear in the codegen macro for this box, to define where the variable appears in the code generated for the box. Possible commands within the 'input' construct are: wwms.argname macro.fixedtext float # the 'input' form only rgb # the 'input' form only rgba # the 'input' form only xyz # the 'input' form only generic:[text] # the 'input' form only string # the 'input' form only help EXAMPLE In this example, we define an input button that can be several different types of value (float, color, point). This is an excerpt from the Renderman version of the 'add' box: input A { float { 0.0 -100.0 100.0 0 "%g" } xyz { 0.0 0.0 0.0 -100.0 100.0 0 "point(%g, %g, %g)" } rgb { 0.5 0.5 0.5 "color(%g, %g, %g)" } help { Value to be added. A can be a float, point, or color. Default is float. } }


    1.2.10 vinput - define a variable input button construct NAME vinput Foo # set the input button's name to 'Foo' { [commands] # described below } DESCRIPTION This command adds a 'variable input button' to the currently defined opbox. 'vinput' buttons differ from 'input' buttons in that they can be duplicated or removed by the user. The 'spline' box, for instance. The button name is ALSO the variable name that should appear in the codegen macro for this box, to define where the variable appears in the code generated for the box. The user can generate multiple instances of the button, either by using the popup menu Copy Above/Below, or by doing a left click on the button, and choosing 'arrow up' or 'arrow down'. When several instances of the button exist, the code generator will expand the variable as several values (one for each instance), using the 'vargseparator' string between each instance. Example: vinput A { float { 0.0 -100.0 100.0 0 "%g" } vargseparator " + " } [..] codegen.main-body append out = A; <<EOT>> ..if the user creates three instances of the button, setting each value to 1.0, 2.0, and 3.0 respectively, the code generator will expand: out = A; ..into: out = 1.0 + 2.0 + 3.0; Within the vinput construct, you define the name of the button, the type of data that it represents, the default slider values (if any). Possible commands within the 'vinput' construct are: vinstances vargseparator wwms.argname macro.fixedtext float # the 'input' form only rgb # the 'input' form only rgba # the 'input' form only xyz # the 'input' form only generic:[text] # the 'input' form only string # the 'input' form only help EXAMPLE In this example, we define a variable input button that can be several different types of value (float, color, point). This is an excerpt from the Renderman version of the 'add' box: vinput B { float { 1.0 -100.0 100.0 0 "%g" } xyz { 0.0 0.0 0.0 -100.0 100.0 0 "point(%g, %g, %g)" } rgb { 0.5 0.5 0.5 "color(%g, %g, %g)" } vargseparator " + " help { Value to be added. B can be a float, point, or color. Default is float. } }


    1.2.11 output - define an output button construct NAME output Foo # set the output button's name to 'Foo' { [commands] # described below } DESCRIPTION This command adds an output button to the currently defined opbox. Within this construct, you define the name of the button, the type of data that it represents, etc. The button name is ALSO the variable name that should appear in the codegen macro for this box, to define where the variable appears in the code generated for the box. Possible commands within the 'output' construct are: float # the 'output' form only rgb # the 'output' form only rgba # the 'output' form only xyz # the 'output' form only generic:[text] # the 'output' form only string # the 'output' form only help EXAMPLE In this example, we define an output button that can be several different types of value (float, color, point). This is an excerpt from the Renderman version of the 'add' box: output OUT { float out xyz out rgb out help { The result is A + B. A and B can be floats, points, or colors. } }


    1.2.12 vargseparator - define the string to separate vinput instances NAME vargseparator "text" DESCRIPTION When several instances of the button exist, the code generator will expand the variable as several values (one for each instance), using the 'vargseparator' string between each instance. For use in 'vinput' constructs only. The text must be quoted. EXAMPLE Define the vargseparator text to be " + ": vinput A { float { 0.0 -100.0 100.0 0 "%g" } vargseparator " + " } [..] codegen.main-body append out = A; <<EOT>> So, if the user creates three instances of the button, setting each value to 1.0, 2.0, and 3.0 respectively, the code generator will expand: out = A; ..into: out = 1.0 + 2.0 + 3.0;


    1.2.13 vinstances - sets default instances for a vinput button NAME vinstances <value> DESCRIPTION Sets the default number of instances of a vinput button. For use in 'vinput' constructs only. If vinstances is unspecified, the default is to create one instance of the vinput button. EXAMPLE vinput A { float { 0.0 -100.0 100.0 0 "%g" } vargseparator " + " vinstances 3 } ..in this example, when the box is dropped on the desk, it will have three instances of the 'A' input button: A1 A2 A3 ..all buttons will default to '0.0', as defined by the 'float {..}' statement.


    1.2.14 float - the float slider datatype NAME float { <value> <minval> <maxval> <intflag> <"fmt string"> } # INPUT float out # OUTPUT <value> - the default value for the slider <minval> - min value for the slider <maxval> - max value for the slider <intflag> - default state of INT button (0=off, 1=on) <"fmt string"> - a printf() style format string, usually "%g" or "%#g" DESCRIPTION This command introduces an 'opbox' button that is to represent a 'float' data element. When the button is unconnected, a slider appears with a text input window; the user can enter a constant floating value either with the slider or via the text window. MIN/MAX values allow the box programmer to constrain the range of values for the slider. Numbers that the user enters directly into text input fields are NOT affected by these constraints. An 'INT' button allows the slider to generate integer-only values. EXAMPLE float { 0.0 -100.0 100.0 0 "%g" }


    1.2.15 rgb - the rgb slider datatype NAME rgb { <r> <g> <b> <intflag> <"fmt string"> } # INPUT rgb out # OUTPUT <r> - default red value for slider <g> - default green value for slider <b> - default blue value for slider <intflag> - default state of INT button (0=off, 1=on) <"fmt string"> - a printf() style format string that defines a constant color value to be specified in the code as three floats. DESCRIPTION This command introduces an 'opbox' button that is to represent an rgb data element. When the button is unconnected, the slider that appears is an assortment of RGB sliders and inputs; the user can enter constant R/G/B values either with sliders or via the text input fields. The sliders are silently constrained to 0.0 - 1.0, although the user may enter any value they want into the text window. EXAMPLES rgb { 0.0 -100.0 100.0 0 "color(%g,%g,%g)" } rgb out


    1.2.16 xyz - the xyz slider datatype NAME xyz { <x> <y> <z> <min> <max> <intflag> <"fmt string"> } # INPUT xyz out # OUTPUT <x> - default x value for slider <y> - default y value for slider <z> - default z value for slider <min> - default minimum value for slider <max> - default maximum value for slider <intflag> - default state of INT button (0=off, 1=on) <"fmt string"> - a printf() style format that defines a constant XYZ value to be specified in the code as three floats. DESCRIPTION This command introduces an 'opbox' button that is to represent an xyz data element. When the button is unconnected, the sliders that appear are three slider inputs (XYZ). The user can enter constant XYZ values either with the sliders or via the text input fields. MIN/MAX values allow the box programmer to constrain the range of values for the sliders. Numbers that the user enters directly into text input fields are NOT affected by these constraints. An 'INT' button allows the sliders to generate integer-only values. EXAMPLE xyz { 0.0 0.0 0.0 -10.0 100.0 0 "point(%g,%g,%g)" } xyz out


    1.2.17 string - the string 'slider' datatype NAME string <qflag> # INPUT { <"text"> <"fmt string"> } string <qflag> out # OUTPUT NOTE: above format is required: open / close braces and the two quoted strings MUST all be on separate lines. <qflag> - state of 'force quote flag'. 1 means text will appear in source code with "" surrounding it. 0 means no quotes will be added; text will appear verbatim in code. <"text"> - a quoted string that represents the default value of the text string. \" escaping can be used to include a quote character as part of the text string. <"fmt string"> - a printf() style format string to define how a constant string value should be specified in the code. DESCRIPTION This command introduces an 'opbox' button that is to represent a string data element. When the button is unconnected, the slider that appears is a 'string input' window. This is where the user can enter a free form constant text string. EXAMPLE string 0 { "This is how you include a quote >\"< within the default text" "%s" } string 1 out


    1.2.18 generic - the generic 'slider' datatype NAME generic:<typename> { <"const value"> } # INPUT generic:<typename> out # OUTPUT <typename> - 'look up' name used by opboxes for this 'data type'. NOTE: TYPENAME MUST NOT CONTAIN WHITESPACE! <"const val"> - the constant value the button should assume (actual source code within quotes) if unconnected. This quoted text MAY contain spaces (see example). EXAMPLES generic:void* { "(void*) NULL" } # input example generic:void* out # output example


    1.2.19 defs - commands affecting the internal button definitions class NAME defs { castlock.clearall # clear all castlocks castlock.add IN_A IN_B # cast lock two input buttons together castlock.add IN_A OUT_A # castlock input and output together maxinstance 1 # maximum instances of box on desk } DESCRIPTION This construct affects operations related to the buttons. Any of the following commands may appear within the construct: maxinstance 1 - Prevents more than one box of this type from being on the desk at the same time. castlock.clearall - This clears any previous castlocks. castlock.add <b1> <b2> - locks the cast of two buttons together, so that if the cast of either button is changed, the other button is changed accordingly. <b1> and <b2> can be input or output buttons, and both must be a 'base name' of the button. In the case of variable input (vinput) buttons, this means VIN_A must be used, and _not_ VIN_A1, VIN_A2. NOTE: When locking variable input buttons, keep in mind all matching buttons will be locked together. Example: castlock.add VIN_A OUT_A ..if VIN_A is a variable input, and has two instances (VIN_A1 and VIN_A2), changing the cast of any of the buttons will interlock them all (VIN_A1, VIN_A2, OUT_A) to the same cast value.


    2.0.0 CUSTOM BOXES For a simple example of making your own ShadeTree boxes, enter the test login directory, and bring up this example: cd /usr/local/shadetree/login st -f shadetree/stree/example.stree Notice that the large box on the right is a 'custom' box, whose definition is in the /usr/local/shadetree/login/shadetree/menus directory. It appears in the Operation Menu Bar under the 'Local' desk submenu. Duplicate the technique used here yourself in your own environment. Study the following files, to see how it all works: /usr/local/shadetree/login/stree.defs ------------------------------------- ShadeTree loads commands from this file because it is in the current working directory. Of particular note, the 'menudir.add' command in this file tells ShadeTree to search the 'menu' directory recursively for box definition files. /usr/local/shadetree/login/shadetree/menus/ ------------------------------------------- This dir contains subdirectories that appear as submenus in the interface; each subdirectory becomes a roll-over menu. Any files in that directory are assumed to be box definition files or stree files. Notice that the files are prefixed with padded numbers to control how the entries sort in the interface. /usr/local/shadetree/login/shadetree/icons/ ------------------------------------------- This is where the icon can be found for the custom box. The filename is referenced by the 'iconimg' command in the box definition file: /usr/local/shadetree/login/shadetree/menus/0000.Local/0000.MyPlastic The icon was created by sgi's own 'snapshot(1)'. However, if you want to get fancy, you may want to render them WITH an alpha channel, so that the icon blends into the color of the box. To understand the layout of the menu directories, take a look at ShadeTree's own internal menu directory layout in: /usr/local/shadetree/prman/menu # RENDERMAN /usr/local/shadetree/mray/menu # MENTAL RAY AUTHOR Greg Ercolano COPYRIGHT (C) Copyright 1996 Cinema Graphics, Inc. All Rights Reserved. SUPPORT If you encounter errors in this document, email support@cinegrfx.com. Please supply the name of the file or manpage, enclose clippings of the erroneous text, and describe the error.


    SOURCE CODE EXAMPLE

    iconimg icons/UserDefined.sgi   # name of icon image
    size  300 150           # default size of Operation Box
    color 0.80 0.80 0.80    # color (.5 .5 .5 = grey)
    icontext TEST           # Text that shows over icon, if any
    
    boxhelp
    {
        This is a box that demonstrates most of the possible techniques when
        making an opbox. It shows:
    
        >   macro.fixedtext     - fixed text in place of sliders
        >   float               - a float button/sliders
        >   xyz                 - an XYZ button/sliders
        >   rgb                 - an RGB button/sliders
        >   rgba                - an RGBA button/sliders
        >   generic             - a 'generic' datatype button
    }
    
    input MACRO_FIXEDTEXT
    {
        macro.fixedtext P
        xyz { 0.0 0.0 0.0 -100.0 100.0 0 "point(%g, %g, %g)" }
        help {
            This input is fixed (macro.fixedtext). It will not have a slider,
            but a button will show up. When the button is unconnected, 'P' will
            be used in the macro expansion. When connected to another box, the
            point value will be used instead of 'P'
        }
    }
    
    input FLOAT
    {
        float { 0.1  -100.0 100.0  0  "%g" }
        #      /      /      |      \   \
        #     /      /       |       \   \
        #    |      |        |        |   \
        #    |      |        |        |    \
        # DEFAULT  MIN      MAX      INT     MACRO
        #                            FLAG    EXPANSION
    
        help {
            A string, which forces enclosing quotes (string 1) around the
            output macro.
        }
    }
    
    input XYZ
    {
        rgb   { 0.1 0.2 0.3 -100.0  100.0 "color(%g, %g, %g)" }
        #        |   |   |    |      |    ___________________
        #        |   |   |    |      |            |
        #        |   |   |    |      |            |
        #        X   Y   Z   MIN    MAX         MACRO
        #                                       EXPANSION
        help {
            An X/Y/Z value. Min/Max affect all three X/Y/Z values.
        }
    }
    
    input RGB
    {
        rgb   { 0.1 0.2 0.3 "color(%g, %g, %g)" }
        #        |   |   |  ___________________
        #        |   |   |          |
        #        |   |   |          |
        #        R   G   B        MACRO
        #                         EXPANSION
        help {
            A red/green/blue value. Values must be from 0.0 to 1.0.
        }
    }
    
    input RGBA
    {
        rgba  { 0.1 0.2 0.3 0.4 "color(%g, %g, %g, %g)" }
        #        |   |   |   |  _______________________
        #        |   |   |   |          |
        #        |   |   |   |          |
        #        R   G   B   A        MACRO
        #                         EXPANSION
        help {
            A red/green/blue value. Values must be from 0.0 to 1.0.
        }
    }
    
    input STRING
    {
        string 1
        {
            "hello world."
            "%s"
        }
    
        help {
            A string, which forces enclosing quotes (string 1) around the
            output macro.
        }
    }
    
    input FLT_XYZ_RGB_RGBA
    {
        #                                    INT
        #       DEFAULTS        MIN/MAX      FLG
        #       --------------- ------------ --- ------------------
        float { 0.1             -100.0 100.0 0   "%g" }
        xyz   { 0.1 0.2 0.3     -100.0 100.0 0   "point(%g, %g, %g)" }
        rgb   { 0.1 0.2 0.3                      "color(%g, %g, %g)" }
        rgba  { 0.1 0.2 0.3 0.4                  "color(%g, %g, %g, %g)" }
    
        # STRING
        #    String is a special case; it must have this 'vertical' format
        #
        string 1
        {
            "hello world."
            "%s"
        }
    
        help {
            This button can be any one of five different data types.. to
            access them, enter the popup for the box, and choose 'Casts':
            >
            >    float
            >    xyz
            >    rgb
            >    rgba
            >    string
            >
        }
    }
    
    vinput VINPUT
    {
        float { 1.0 -100.0 100.0 0 "%g" }
        xyz   { 0.0 0.0 0.0 -100.0 100.0 0 "point(%g, %g, %g)" }
        rgb   { 0.5 0.5 0.5 "color(%g, %g, %g)" }
        vargseparator " + "
        help {
            A variable input button. This button can be replicated by the
            user to create several. The macro variable name (VINPUT) will
            be expanded to all instances of the button, with the string
            for 'vargseparator' separating each instance. For example, if
            there are 3 instances of the button, and they are set to float values
            #1=0.0, #2=1.0, and #3=2.0, and vargseparator is set to " + ", then
            all appearances of 'VINPUT' in the macro text will expand to:
    
            >       0.0 + 1.0 + 2.0
        }
    }
    
    output FLT_XYZ_RGB_OUT
    {
        float out
        xyz out
        rgb out
        help {
            The result is A + B.
            A and B can be floats, points, or colors.
            The result will be a float if both A and B are floats.
            The result will be a point if either A or B is a point.
            The result will be a color if either A or B is a color.
            A type mis-match will result from the addition of points and colors.
        }
    }
    
    # Inline way to define a macro
    codegen.main-body append
        /***********************************************************************
         * THIS 'TestAll' BOX MACRO IS COMMENTED OUT, BECAUSE IT IS NON-SENSICAL
         *
         *    However, for demonstration purposes, the macro will still expand,
         *    even within the comments because the code generator does global
         *    expansion, even within quotes.
         *
         *    These macro values will expand when the shader is created.
         ***********************************************************************
         *
         * FLT_XYZ_RGB_OUT = VINPUT;
         * MACRO_FIXEDTEXT;
         * FLOAT;
         * RGB;
         * RGBA;
         * STRING;
         */
    <<EOT>>