The first step is to decide what type of data your module will need. To do this, you need to know that Alias already has some standard data items that it maintains. Each type of object (light/shader/texture) has a certain number of standard, Alias-defined data items that are parsed, evaluated and initialized automatically. These standard data items are available to you in the CALC routines in the data structures: AR_LightInfo, AR_ShaderData or AR_TextureData (depending, of course, on which type of ALIAS OpenRender C module you are writing).
Note: It cannot be stressed enough that the values in the Alias supplied AR_ structures should not be changed by you at any time, unless explicitly requested in the prototypes.
The following tables contain the fields in the various data structures that are available for you to use in the CALC routines. These types are defined in ALIAS OCR_types.h. Any fields not described below are for Alias internal use only.
Normal and the crosspt have already been bump mapped and displacement mapped if such textures were applied.The only field in AR_ShadeData that can (and must) be modified by you is the
transcol field. This field must hold the result of the shading computation when the shader returns.
AR_LightData Structure
TDcolor field of the AR_TextureData structure before returning successfully. Upon a successful texturing, the textures must place values in each of the red, green, blue and alpha channels. If the texturing is unsuccessful, then the value in the TDcolor field should not be modified.
Note: The following lists are reserved SDL keywords. You cannot use these keywords for your SDL extensions because the Alias field will take precedence. For example, if you have a NODE field that you link to the SDL keyword "
color," your field will never have anything put into it since the Alias shader keyword "color" is already linked to an Alias defined NODE structure.
Briefly examine the file simple_shader.c. It uses its own definition for "color." This is not necessary, since this field is also maintained by Alias in the AR_ShadeData structure. The "color" field is defined here for clarity. Although you are free to use the information passed into your shader(s) in the AR_ShadeData structure, it is clearer if you define all the parameters you are going to use in your own data structures (as you have done with "color" in the simple_shader.c example).
Copy the file simple_shader.c to a file called new_shader.c, and read new_shader.c into your favorite editor.
The first thing to change is the data structures. Locate the
NODE_TYPE and INFO_TYPE data structures in the file and add "glow," an AR_Rgb, to both data structures. The structures should now look like:
typedef struct NODE_TYPE {
RR_ExpNode *diffuse_node;
RR_ExpNode *color_node;
RR_ExpNode *glow_node;
} NODE_TYPE;
typedef struct INFO_TYPE {
float diffuse;
AR_Rgb color;
AR_Rgb glow;
} INFO_TYPE;
MODULE_NAME define-it should be only a few lines below the data structure definitions that you just changed. Now change the MODULE_NAME to "new_shader" (or whatever you choose to call it). This allows Alias-defined functions in OCR_predef_routines.h to print out meaningful warning and error messages.You want your new "glow" parameter to have a default. Let's say that the default is a nice red (200, 20, 10). Locate the line that reads:
static const int diffuse_default = 0.8;
static const AR_Rgb glow_default = (200.0, 20.0, 10.0);
static const OcrCtlParamTabType PARAM_TAB[]={
/*
PARAM_TAB[], the Alias Renderer knows that when it sees the keyword "glow" in the SDL file, the Renderer must place whatever "glow" is assigned into the NODE field "glow_node," and that at evaluate time, the NODE field "glow_node" must be evaluated into the INFO field "glow." You have also told the renderer that "glow" must be a TRIPLE (in this case, red, green, and blue) and that if there is no keyword "glow" in the SDL file, the values you placed in "glow_default" are to be used (see the next section, Notes on the PARAM_TAB Array, for more information).Note: The SDL keyword for your "color" field is defined to be
lcolor to avoid conflict with the Alias defined keyword color. See the note at the top of Standard SDL Parameters for more explanation.The final change to make in order to add our new "glow" parameter to the simple shader is to modify the CALC routine. Locate the line:
/* Calculate Transparency */
result.r += pUserInfo->glow.r;
result.g += pUserInfo->glow.g;
result.b += pUserInfo->glow.b;
create shader ( model = new_shader, filename = "new_shader.o" );
shader my_shader(
model = new_shader,
lcolor = (150, 150, 150), /* grey */
ldiffuse = 0.8,
glow = (20, 20, 180) /* blue */
);
PARAM_TAB[] array is interpreted by the Parse and Evaluate routines. In the following example array, the first row is an example of how an SDL parameter keyword corresponds to a field in the NODE struct called fieldNODE and a field in the INFO structure called fieldINFO.
typedef struct NODE_TYPE {
RR_ExpNode *fieldNODE;
RR_ExpNode *fieldColn;
} NODE_TYPE;
typedef struct INFO_TYPE{
int fieldINFO;
AR_Rgb fieldColi;
}INFO_TYPE;
static const OcrCtlParamTabType PARAM_TAB[]={
/*
*SDL param Node Field Info Field Info Type Default
*------- ---------- ---------- --------- -------
*/
"paramSDL", NODE(fieldNODE), INFO(fieldINFO), SCALAR, NULL,
"mcolour", NODE(fieldColn), INFO(fieldColi), TRIPLE,
(void*)&ColDef,
"mcolor", NODE(fieldColn), INFO(fieldColi), DO_NOT_EVAL, NULL,
NULL, 0, 0, 0, NULL
};
create light (model=example, filename="example.o");
.
.
.
light (model=example, paramSDL=1.0);
paramSDL in the above PARAM_TAB array associates the NODE field fieldNODE with paramSDL for the purposes of SDL parsing and with the INFO struct field fieldINFO for the purposes of evaluation. In this case, by the time the INIT() routine is called, the field fieldINFO has the value 1.0 in it.The next two lines of the above PARAM_TAB array assume that there is a color field (
fieldColn in the NODE struct and fieldColi in the INFO struct) that you want to be associated with two synonymous SDL parameters ("mcolour" and "mcolor"). Since you only want to evaluate the information in the NODE_TYPE structure once, the second binding of an SDL keyword to a field must have the Info Type set to DO_NOT_EVAL. All INFO fields that should not be evaluated, but can be parsed, should have DO_NOT_EVAL in the type field.
Info Type field of the PARAM_TAB[] array.
Info Types in the example ALIAS OpenRender modules. Changing Glow to a Texturable Parameter
In this section, you will change the glow parameter you just added to new_shader.c into a texturable parameter. The first thing to do is edit new_shader.c. Locate the INFO_TYPE data structure. Change the definition of glow from AR_Rgb to AR_TextureType.typedef struct INFO_TYPE{
float diffuse;
AR_Rgb color;
AR_TextureType glow;
}INFO_TYPE;
Note that its type remains RR_ExpNode in the NODE_TYPE structure.glow_default. All textures are 4 channel textures, so the default for a texture must be an AR_Rgba. Therefore, you must change its definition, and add a scalar to the default value:static const AR_Rgba glow_default = (200.0, 20.0, 10.0, 0.0);
Next, locate the PARAM_TAB[] array. You must change the Info Type field from TRIPLE to TEXTURE."glow", NODE(glow_node), INFO(glow), TEXTURE,
(void*)&glow_default,
Textures require initialization in the INIT() routine, so locate the OCR_Init() routine. Currently it is an empty function. Add the following line to initialize the texture:static AR_Boolean
OCR_Init(
INFO_TYPE *pUserInfo
)
{
OCR_initialize_texture( pUserInfo->glow.map );
return TRUE;
}
Finally, the last change required is in the CALC routine. You must now call the CALC routine for the texture before you add glow to the result. To do this, you need some extra variables defined at the top of the CALC routine:AR_TextureData tx; /* Texture mapping variables */
AR_Rgba rgba;
Then, you need to set up the AR_TextureData structure so that the texture can evaluate the value at the current location properly. Locate the code you put in to add the glow to the result (it should look like:) result.r += pUserInfo->glow.r;
result.g += pUserInfo->glow.g;
result.b += pUserInfo->glow.b;
Delete the above code (it will no longer work for textures) and replace it with: /* Set up AR_TextureData structure. */
tx.TDgeom = pGeometry;
tx.TDray = &ray;
tx.TDnormal = &(pShadeData->Normal);
/* Set up location for result of texture. */
tx.TDcolor = &rgba;
/* Call the texture (this will work even if a literal or the */
/* default value was assigned to this parameter in SDL). */
OCR_INVOKE_MAPPING( tx, pInfo->reflectivity, pShadeData->Sight );
/* Add the textured glow to the result. */
result.r += rgba.r;
result.g += rgba.g;
result.b += rgba.b;
Notice how you added the values in rgba to the result after the texture had been invoked. You could have taken the values out of tx.TDcolor as well, since it also points to rgba.shader my_shader(
model = new_shader,
lcolor = (150, 150, 150), /* grey */
ldiffuse = 0.8,
glow = texture(
procedure = Checker,
urepeat = 20,
vrepeat = 20,
rgbout = (0, 150, 255),
contrast = 1.0,
color1 = (255, 255, 255),
color2 = (0, 0, 0)
)
);
Try rendering this modified SDL file. Notice how the object appears to be checkered. Congratulations-you have just added a texturable attribute to your ALIAS OpenRender shader. Modifying SDL files
The Alias Scene Description Language (SDL) has a new extension to allow you to specify the ALIAS OpenRender shaders, lights and textures. The new keyword is create. The syntax for this keyword is as follows:create [light|shader|texture] ( model = <model name>, filename =
"<filename.o>" );
After the create statement is placed in the SDL file, the ALIAS OpenRender model you have created can be used just like an Alias model. (Look at the simple_shader SDL file in the ALIAS OpenRender sdl directory for an example.) create shader ( model = glossy, filename = glossy.o );
and subsequent uses of the shader would look like: shader (model = glossy, ...... );
Of course, the remaining arguments to the shader "glossy" depend on what parameters you have defined in the ALIAS OpenRender Template file. You must create an ALIAS OpenRender code module in the SDL higher up in the file than where it is used (that is, the ALIAS OpenRender code module must be defined before it is used).