Files
mips/src/jman/ri.c
T
jens a655e1c5d9 - use build in data types
git-svn-id: http://moon:8086/svn/mips@35 a8ebac50-d88d-4704-bea3-6648445a41b3
2015-05-28 19:19:01 +00:00

1039 lines
24 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <math.h>
#include "ri.h"
#include "types.h"
#include "matrix.h"
#include "stack.h"
#include "graph_state.h"
#include "object.h"
#include "vars.h"
#include "engine.h"
#include "linklist.h"
#include "ribgen.h"
// Globals
engine_t engine = {0};
graph_state_t *pG;
scene_t *pW;
scene_t *pL;
RtToken RI_FRAMEBUFFER = "framebuffer";
RtToken RI_FILE = "file";
RtToken RI_RGB = "rgb";
RtToken RI_RGBA = "rgba";
RtToken RI_RGBZ = "rgbz";
RtToken RI_RGBAZ = "rgbaz";
RtToken RI_A = "a";
RtToken RI_Z = "z";
RtToken RI_AZ = "az";
RtToken RI_PERSPECTIVE = "perspective";
RtToken RI_ORTHOGRAPHIC = "orthographic";
RtToken RI_FOV = "fov";
RtToken RI_BILINEAR = "bilinear";
RtToken RI_BICUBIC = "bicubic";
RtToken RI_LINEAR = "linear";
RtToken RI_CUBIC = "cubic";
RtToken RI_PERIODIC = "periodic";
RtToken RI_NONPERIODIC = "nonperiodic";
RtBasis RiBezierBasis = { {-1, 3, -3, 1},
{3, -6, 3, 0},
{-3, 3, 0, 0},
{1, 0, 0, 0}};
RtBasis RiBSplineBasis = {{-(RtFloat)1/6, (RtFloat)3/6, -(RtFloat)3/6, (RtFloat)1/6}
,{(RtFloat)3/6, -(RtFloat)6/6, (RtFloat)3/6, 0},
{-(RtFloat)3/6, 0, (RtFloat)3/6, 0},
{(RtFloat)1/6, (RtFloat)4/6, (RtFloat)1/6, 0}};
RtBasis RiCatmullRomBasis = { {-(RtFloat)1/2, (RtFloat)3/2, -(RtFloat)3/2, (RtFloat)1/2},
{(RtFloat)2/2, -(RtFloat)5/2, (RtFloat)4/2, -(RtFloat)1/2},
{-(RtFloat)1/2, 0, (RtFloat)1/2, 0},
{0, (RtFloat)2/2, 0, 0}};
RtBasis RiHermiteBasis = { {2, 1, -2, 1},
{-3, -2, 3, -1},
{0, 1, 0, 0},
{1, 0, 0, 0}};
RtBasis RiPowerBasis = { {1, 0, 0, 0},
{0, 1, 0, 0},
{0, 0, 1, 0},
{0, 0, 0, 1}};
// --------------------------------------------------------------
// RenderMan interface
// --------------------------------------------------------------
/* Basic control flow, scoping, stacks */
RtVoid RiBegin (RtToken name)
{
if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) != ENGINE_CONTEXT_INVALID)
{
fprintf(stderr, "RiBegin() cannot be nested!\n");
return;
}
Engine_init(&engine, name);
pG = &engine.gs;
pW = &engine.geometry;
pL = &engine.lights;
GS_init(pG);
// Init scene
pW->pObjs = NULL;
pL->pObjs = NULL;
// Set camera as current coordinate system
GS_xform_set(pG, camera_space);
Engine_context_set(&engine, ENGINE_CONTEXT_MAIN, ENGINE_CONTEXT_LEVEL_MAIN);
}
// --------------------------------------------------------------
RtVoid RiEnd (void)
{
if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) == ENGINE_CONTEXT_INVALID)
{
fprintf(stderr, "RiBegin() not declared previously!\n");
return;
}
Engine_DeleteScene(&engine);
GS_free(pG);
Engine_free(&engine);
}
// --------------------------------------------------------------
RtVoid RiFrameBegin (RtInt number)
{
uint32_t i;
if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) == ENGINE_CONTEXT_INVALID)
{
fprintf(stderr, "RiBegin() not declared previously!\n");
return;
}
if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) == ENGINE_CONTEXT_FRAME)
{
fprintf(stderr, "RiFrameBegin() cannot be nested!\n");
return;
}
if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) == ENGINE_CONTEXT_WORLD)
{
fprintf(stderr, "RiFrameBegin() is invalid within world block!\n");
return;
}
pG->frame = number;
// Initialize coordinate systems
for (i=0; i < NUM_COORD_SYSTEMS; i++)
{
IdentityMatrix(&pG->pXform->space[i]);
}
Engine_context_push(&engine);
Engine_context_set(&engine, ENGINE_CONTEXT_FRAME, ENGINE_CONTEXT_LEVEL_MAIN);
Ribgen_FrameBegin(&engine, number);
}
// --------------------------------------------------------------
RtVoid RiFrameEnd (void)
{
if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) < ENGINE_CONTEXT_FRAME)
{
fprintf(stderr, "RiFrameBegin() not declared previously!\n");
return;
}
Engine_DeleteScene(&engine);
Engine_context_pop(&engine);
Ribgen_FrameEnd(&engine);
}
// --------------------------------------------------------------
RtVoid RiWorldBegin (void)
{
if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) == ENGINE_CONTEXT_INVALID)
{
fprintf(stderr, "RiBegin() not declared previously!\n");
return;
}
if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) == ENGINE_CONTEXT_WORLD)
{
fprintf(stderr, "RiWorldBegin() cannot be nested!\n");
return;
}
// Set world as current coordinate system
GS_xform_set(pG, world_space);
Engine_context_push(&engine);
Engine_context_set(&engine, ENGINE_CONTEXT_WORLD, ENGINE_CONTEXT_LEVEL_MAIN);
GS_opt_push(pG);
GS_attr_push(pG);
GS_xform_push(pG);
Ribgen_WorldBegin(&engine);
}
// --------------------------------------------------------------
RtVoid RiWorldEnd (void)
{
if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) < ENGINE_CONTEXT_WORLD)
{
fprintf(stderr, "RiWorldBegin() not declared previously!\n");
return;
}
// Set camera as current coordinate system
GS_xform_set(pG, camera_space);
Engine_Render(&engine);
Engine_SceneInfo(&engine);
Engine_DeleteScene(&engine);
Engine_context_pop(&engine);
GS_opt_pop(pG);
GS_attr_pop(pG);
GS_xform_pop(pG);
Ribgen_WorldEnd(&engine);
}
// --------------------------------------------------------------
RtVoid RiAttributeBegin (void)
{
if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) == ENGINE_CONTEXT_INVALID)
{
fprintf(stderr, "RiBegin() not declared previously!\n");
return;
}
GS_attr_push(pG);
GS_xform_push(pG);
Engine_context_push(&engine);
Engine_context_set(&engine, ENGINE_CONTEXT_ATTRIBUTE, ENGINE_CONTEXT_LEVEL_SUB);
Ribgen_AttributeBegin(&engine);
}
// --------------------------------------------------------------
RtVoid RiAttributeEnd (void)
{
if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) == ENGINE_CONTEXT_INVALID)
{
fprintf(stderr, "RiWorldBegin() not declared previously!\n");
return;
}
if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_SUB) != ENGINE_CONTEXT_ATTRIBUTE)
{
fprintf(stderr, "RiAttributeBegin() not declared previously!\n");
return;
}
GS_attr_pop(pG);
GS_xform_pop(pG);
Engine_context_pop(&engine);
Ribgen_AttributeEnd(&engine);
}
// --------------------------------------------------------------
RtVoid RiTransformBegin (void)
{
if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) == ENGINE_CONTEXT_INVALID)
{
fprintf(stderr, "RiBegin() not declared previously!\n");
return;
}
GS_xform_push(pG);
Engine_context_push(&engine);
Engine_context_set(&engine, ENGINE_CONTEXT_TRANSFORM, ENGINE_CONTEXT_LEVEL_SUB);
Ribgen_TransformBegin(&engine);
}
// --------------------------------------------------------------
RtVoid RiTransformEnd (void)
{
if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) == ENGINE_CONTEXT_INVALID)
{
fprintf(stderr, "RiWorldBegin() not declared previously!\n");
return;
}
if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_SUB) != ENGINE_CONTEXT_TRANSFORM)
{
fprintf(stderr, "RiTransformBegin() not declared previously!\n");
return;
}
GS_xform_pop(pG);
Engine_context_pop(&engine);
Ribgen_TransformEnd(&engine);
}
// --------------------------------------------------------------
RtToken RiDeclare (char *name, char *declaration)
{
uint32_t i, len;
RtToken pVar;
char *pClass;
char *pType;
len = strlen(declaration);
pClass = jmalloc(len);
memset(pClass, 0, len);
pType = jmalloc(len);
memset(pType, 0, len);
i=0;
while(*declaration != ' ')
pClass[i++] = *declaration++;
declaration++;
i=0;
while(*declaration)
pType[i++] = *declaration++;
pVar = (RtToken)VarListDeclare(&engine.varList, name, pClass, pType);
jfree(pClass);
jfree(pType);
return pVar;
}
// --------------------------------------------------------------
/* Transformations */
RtVoid RiConcatTransform (RtMatrix transform)
{
RtMatrix T;
GS_xform_push(pG);
memcpy(T, *pG->pXform_curr, sizeof(RtMatrix));
MultiplyMatrices(T, transform, pG->pXform_curr);
Ribgen_ConcatTransform(&engine, transform);
}
// --------------------------------------------------------------
RtVoid RiCoordinateSystem (RtToken space)
{
}
// --------------------------------------------------------------
RtVoid RiCoordSysTransform (RtToken space)
{
}
// --------------------------------------------------------------
RtVoid RiIdentity (void)
{
GS_xform_push(pG);
IdentityMatrix(pG->pXform_curr);
Ribgen_Identity(&engine);
}
// --------------------------------------------------------------
RtVoid RiPerspective (RtFloat fov)
{
pG->pOpt->projection.fov = fov;
Ribgen_Perspective(&engine, fov);
}
// --------------------------------------------------------------
RtVoid RiRotate (RtFloat angle, RtFloat dx, RtFloat dy, RtFloat dz)
{
RtFloat v[3];
RtMatrix R, T;
RtFloat c, s, n, x, y, z;
RtFloat a;
GS_xform_push(pG);
v[0] = dx;
v[1] = dy;
v[2] = dz;
n = Norm(v, 3);
x = v[0]/n;
y = v[1]/n;
z = v[2]/n;
a = (RtFloat)(PI*angle/180.0);
c = (RtFloat)(1.0 - cos(a));
s = (RtFloat)-sin(a);
IdentityMatrix(&R);
R[0][0] = 1 + c*(x*x-1);
R[0][1] = z*s + c*x*y;
R[0][2] = -y*s + c*x*z;
R[1][0] = -z*s + c*x*y;
R[1][1] = 1 + c*(y*y-1);
R[1][2] = x*s + c*y*z;
R[2][0] = y*s + c*x*z;
R[2][1] = -x*s + c*y*z;
R[2][2] = 1 + c*(z*z-1);
memcpy(T, *pG->pXform_curr, sizeof(RtMatrix));
MultiplyMatrices(T, R, pG->pXform_curr);
Ribgen_Rotate(&engine, angle, dx, dy, dz);
}
// --------------------------------------------------------------
RtVoid RiScale (RtFloat dx, RtFloat dy, RtFloat dz)
{
RtMatrix R, T;
GS_xform_push(pG);
IdentityMatrix(&R);
R[0][0] = dx;
R[1][1] = dy;
R[2][2] = dz;
memcpy(T, *pG->pXform_curr, sizeof(RtMatrix));
MultiplyMatrices(T, R, pG->pXform_curr);
Ribgen_Scale(&engine, dx, dy, dz);
}
// --------------------------------------------------------------
RtVoid RiSkew (RtFloat angle, RtFloat dx1, RtFloat dy1, RtFloat dz1,
RtFloat dx2, RtFloat dy2, RtFloat dz2)
{
}
// --------------------------------------------------------------
RtVoid RiTransform (RtMatrix transform)
{
uint32_t i, j;
GS_xform_push(pG);
for (i=0; i < 4; i++)
for (j=0; j < 4; j++)
*pG->pXform_curr[i][j] = transform[i][j];
Ribgen_Transform(&engine, transform);
}
// --------------------------------------------------------------
RtVoid RiTranslate (RtFloat dx, RtFloat dy, RtFloat dz)
{
RtMatrix R, T;
GS_xform_push(pG);
IdentityMatrix(&R);
R[0][3] = dx;
R[1][3] = dy;
R[2][3] = dz;
memcpy(T, *pG->pXform_curr, sizeof(RtMatrix));
MultiplyMatrices(T, R, pG->pXform_curr);
Ribgen_Translate(&engine, dx, dy, dz);
}
// --------------------------------------------------------------
RtPoint *RiTransformPoints (RtToken fromspace, RtToken tospace,
RtInt npoints, RtPoint *points)
{
return RI_NULL;
}
// --------------------------------------------------------------
/* Options */
RtVoid RiCropWindow (RtFloat xmin, RtFloat xmax, RtFloat ymin, RtFloat ymax)
{
GS_opt_push(pG);
pG->pOpt->crop[0] = xmin;
pG->pOpt->crop[1] = xmax;
pG->pOpt->crop[2] = ymin;
pG->pOpt->crop[3] = ymax;
Ribgen_CropWindow(&engine, xmin, xmax, ymin, ymax);
}
// --------------------------------------------------------------
RtVoid RiDisplay (char *name, RtToken type, RtToken mode, ...)
{
RtToken token;
RtPointer arg;
va_list args;
va_start(args, mode);
GS_opt_push(pG);
pG->pOpt->display.name = name;
pG->pOpt->display.type = type;
pG->pOpt->display.mode = mode;
while((token = va_arg(args, RtToken)) != RI_NULL)
{
arg = va_arg(args, RtPointer);
}
va_start(args, mode);
Ribgen_Display(&engine, name, type, mode, args);
va_end(args);
}
// --------------------------------------------------------------
RtVoid RiFormat (RtInt xres, RtInt yres, RtFloat aspect)
{
GS_opt_push(pG);
pG->pOpt->format.xres = xres;
pG->pOpt->format.yres = yres;
if (aspect > 0)
pG->pOpt->format.ar_p = (RtFloat)aspect;
pG->pOpt->format.ar_f = pG->pOpt->format.ar_p*xres/yres;
Ribgen_Format(&engine, xres, yres, aspect);
}
// --------------------------------------------------------------
RtVoid RiFrameAspectRatio (RtFloat aspect)
{
GS_opt_push(pG);
pG->pOpt->format.ar_f = aspect;
Ribgen_FrameAspectRatio(&engine, aspect);
}
// --------------------------------------------------------------
RtVoid RiProjection (char *name, ...)
{
RtToken token;
RtPointer arg;
va_list args;
va_start(args, name);
GS_opt_push(pG);
pG->pOpt->projection.type = name;
while((token = va_arg(args, RtToken)) != RI_NULL)
{
if (token == RI_FOV)
{
arg = va_arg(args, RtPointer);
pG->pOpt->projection.fov = *((RtFloat*)arg);
}
}
va_start(args, name);
Ribgen_Projection(&engine, name, args);
va_end(args);
}
// --------------------------------------------------------------
RtVoid RiScreenWindow (RtFloat left, RtFloat right, RtFloat bot, RtFloat top)
{
GS_opt_push(pG);
pG->pOpt->screen[0] = left;
pG->pOpt->screen[1] = right;
pG->pOpt->screen[2] = bot;
pG->pOpt->screen[3] = top;
Ribgen_ScreenWindow(&engine, left, right, bot, top);
}
// --------------------------------------------------------------
RtVoid RiClipping (RtFloat hither, RtFloat yon)
{
pG->pOpt->clipping[0] = hither;
pG->pOpt->clipping[1] = yon;
Ribgen_Clipping(&engine, hither, yon);
}
// --------------------------------------------------------------
/* Attributes */
RtVoid RiColor (RtColor Cs)
{
GS_attr_push(pG);
pG->pAttr->cs[0] = Cs[0];
pG->pAttr->cs[1] = Cs[1];
pG->pAttr->cs[2] = Cs[2];
Ribgen_Color(&engine, Cs);
}
// --------------------------------------------------------------
RtVoid RiShadingRate (RtFloat size)
{
GS_attr_push(pG);
pG->pAttr->shadingrate = size;
Ribgen_ShadingRate(&engine, size);
}
// --------------------------------------------------------------
RtVoid RiIlluminate (RtLightHandle light, RtBoolean onoff)
{
light_t *pLight;
pLight = (light_t*)light;
pLight->onoff = onoff;
Ribgen_Illuminate(&engine, pLight->id, onoff);
}
// --------------------------------------------------------------
RtVoid RiSides (RtInt nsides)
{
pG->pAttr->nsides = nsides;
Ribgen_Sides(&engine, nsides);
}
// --------------------------------------------------------------
/* Geometric Primitives (and a couple gprim-specific attributes) */
RtVoid RiPointsPolygons (RtInt npolys, RtInt *nverts, RtInt *verts, ...)
{
uint32_t j, v, n, k;
object_t *pObj;
RtToken token;
RtPoint *pPoint, *pVert;
ri_var_t *pVar;
va_list args;
va_start(args, verts);
if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) < ENGINE_CONTEXT_WORLD)
{
fprintf(stderr, "RiPolygon(): Invalid context!\n");
return;
}
pObj = (object_t*)jmalloc(npolys*sizeof(object_t));
for (n=0; n < (uint32_t)npolys; n++)
{
Polygon_init(&pObj[n], ++pW->stat.num_polygons, nverts[n]);
}
while((token = va_arg(args, RtToken)) != RI_NULL)
{
if (token == RI_P)
{
pPoint = (RtPoint*)va_arg(args, RtPointer);
v = 0;
for (n=0; n < (uint32_t)npolys; n++)
{
pVar = VarListFindByName(&engine.varList, token);
if (!pVar)
{
fprintf(stderr, "RiPointsPolygons(): Variable \"%s\" not found!\n", token);
return;
}
pVar = VarListAdd(&pObj[n].vars, pVar);
pVert = (RtPoint*)VarSet(pVar, NULL, nverts[n]);
for (j=0; j < (uint32_t)nverts[n]; j++)
{
k = verts[v++];
pVert[j][0] = pPoint[k][0];
pVert[j][1] = pPoint[k][1];
pVert[j][2] = pPoint[k][2];
}
}
}
};
for (n=0; n < (uint32_t)npolys; n++)
{
Object_set_xform(&pObj[n], pG->pXform_curr);
Object_set_attr(&pObj[n], pG->pAttr);
Scene_Add(pW, &pObj[n]);
}
jfree(pObj);
va_start(args, verts);
Ribgen_PointsPolygons(&engine, npolys, nverts, verts, args);
va_end(args);
}
// --------------------------------------------------------------
RtVoid RiPolygon (RtInt nvertices, ...)
{
object_t obj = {0};
RtToken token;
RtPointer arg;
ri_var_t *pVar;
va_list args;
va_start(args, nvertices);
if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) < ENGINE_CONTEXT_WORLD)
{
fprintf(stderr, "RiPolygon(): Invalid context!\n");
return;
}
Polygon_init(&obj, ++pW->stat.num_polygons, nvertices);
while((token = va_arg(args, RtToken)) != RI_NULL)
{
arg = va_arg(args, RtPointer);
pVar = VarListFindByName(&engine.varList, token);
if (!pVar)
{
fprintf(stderr, "RiPolygon(): Variable \"%s\" not found!\n", token);
return;
}
pVar = VarListAdd(&obj.vars, pVar);
VarSet(pVar, arg, nvertices);
};
Object_set_xform(&obj, pG->pXform_curr);
Object_set_attr(&obj, pG->pAttr);
Scene_Add(pW, &obj);
va_start(args, nvertices);
Ribgen_Polygon(&engine, &obj, args);
va_end(args);
}
// --------------------------------------------------------------
RtVoid RiBasis (RtBasis ubasis, RtInt ustep, RtBasis vbasis, RtInt vstep)
{
if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) < ENGINE_CONTEXT_WORLD)
{
fprintf(stderr, "RiBasis(): Invalid context!\n");
return;
}
GS_attr_push(pG);
pG->pAttr->ubasis = (RtPointer)ubasis;
pG->pAttr->vbasis = (RtPointer)vbasis;
pG->pAttr->ustep = ustep;
pG->pAttr->vstep = vstep;
Ribgen_Basis(&engine, ubasis, ustep, vbasis, vstep);
}
RtVoid RiCurves (RtToken degree, RtInt ncurves, RtInt nverts[], RtToken wrap, ...)
{
uint32_t n;
object_t *pObj;
RtToken token;
RtPointer arg;
ri_var_t *pVar, *pKnownVar;
va_list args;
va_start(args, wrap);
if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) < ENGINE_CONTEXT_WORLD)
{
fprintf(stderr, "RiCurves(): Invalid context!\n");
return;
}
pObj = (object_t*)jmalloc(ncurves*sizeof(object_t));
for (n=0; n < ncurves; n++)
{
Curve_init(&pObj[n], ++pW->stat.num_curves, degree, nverts[n], wrap);
}
while((token = va_arg(args, RtToken)) != RI_NULL)
{
arg = va_arg(args, RtPointer);
pKnownVar = VarListFindByName(&engine.varList, token);
if (!pKnownVar)
{
fprintf(stderr, "RiCurves(): Variable \"%s\" not found!\n", token);
return;
}
for (n=0; n < ncurves; n++)
{
pVar = VarListAdd(&pObj[n].vars, pKnownVar);
VarSet(pVar, arg, nverts[n]);
}
};
for (n=0; n < ncurves; n++)
{
Object_set_xform(&pObj[n], pG->pXform_curr);
Object_set_attr(&pObj[n], pG->pAttr);
Scene_Add(pW, &pObj[n]);
}
va_start(args, wrap);
Ribgen_Curves(&engine, pObj, degree, ncurves, nverts, wrap, args);
va_end(args);
jfree(pObj);
}
// --------------------------------------------------------------
RtVoid RiPatch (RtToken type, ...)
{
RtInt npoints;
object_t obj;
RtToken token;
RtPointer arg;
ri_var_t *pVar;
va_list args;
va_start(args, type);
if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) < ENGINE_CONTEXT_WORLD)
{
fprintf(stderr, "RiPatch(): Invalid context!\n");
return;
}
Patch_init(&obj, ++pW->stat.num_patches, type);
npoints = 4;
if (type == RI_BICUBIC)
npoints = 16;
while((token = va_arg(args, RtToken)) != RI_NULL)
{
arg = va_arg(args, RtPointer);
pVar = VarListFindByName(&engine.varList, token);
if (!pVar)
{
fprintf(stderr, "RiPatch(): Variable \"%s\" not found!\n", token);
return;
}
pVar = VarListAdd(&obj.vars, pVar);
VarSet(pVar, arg, npoints);
};
Object_set_xform(&obj, pG->pXform_curr);
Object_set_attr(&obj, pG->pAttr);
Scene_Add(pW, &obj);
va_start(args, type);
Ribgen_Patch(&engine, &obj, type, args);
va_end(args);
}
// --------------------------------------------------------------
RtVoid RiPatchMesh (RtToken type, RtInt nu, RtToken uwrap, RtInt nv, RtToken vwrap, ...)
{
object_t obj;
RtToken token;
RtPointer arg;
ri_var_t *pVar;
va_list args;
va_start(args, vwrap);
if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) < ENGINE_CONTEXT_WORLD)
{
fprintf(stderr, "RiPatchMesh(): Invalid context!\n");
return;
}
Patchmesh_init(&obj, ++pW->stat.num_patchmeshes, type, nu, uwrap, nv, vwrap, NULL);
while((token = va_arg(args, RtToken)) != RI_NULL)
{
arg = va_arg(args, RtPointer);
pVar = VarListFindByName(&engine.varList, token);
if (!pVar)
{
fprintf(stderr, "RiPatch(): Variable \"%s\" not found!\n", token);
return;
}
pVar = VarListAdd(&obj.vars, pVar);
VarSet(pVar, arg, nu*nv);
};
Object_set_xform(&obj, pG->pXform_curr);
Object_set_attr(&obj, pG->pAttr);
Scene_Add(pW, &obj);
va_start(args, vwrap);
Ribgen_Patchmesh(&engine, &obj, type, nu, uwrap, nv, vwrap, args);
va_end(args);
}
// --------------------------------------------------------------
RtVoid RiSphere (RtFloat radius, RtFloat zmin, RtFloat zmax, RtFloat thetamax, ...)
{
object_t obj = {0};
RtToken token;
RtPointer arg;
ri_var_t *pVar;
va_list args;
va_start(args, thetamax);
if (Engine_context_get(&engine, ENGINE_CONTEXT_LEVEL_MAIN) < ENGINE_CONTEXT_WORLD)
{
fprintf(stderr, "RiSphere(): Invalid context!\n");
return;
}
Sphere_init(&obj, ++pW->stat.num_spheres, radius, zmin, zmax, thetamax);
while((token = va_arg(args, RtToken)) != RI_NULL)
{
arg = va_arg(args, RtPointer);
pVar = VarListFindByName(&engine.varList, token);
if (!pVar)
{
fprintf(stderr, "RiSphere(): Variable \"%s\" not found!\n", token);
return;
}
pVar = VarListAdd(&obj.vars, pVar);
VarSet(pVar, arg, 1);
};
Object_set_xform(&obj, pG->pXform_curr);
Object_set_attr(&obj, pG->pAttr);
Scene_Add(pW, &obj);
va_start(args, thetamax);
Ribgen_Sphere(&engine, &obj, radius, zmin, zmax, thetamax, args);
va_end(args);
}
/* Shaders */
RtLightHandle RiLightSource (char *name, ...)
{
light_t *pLight ;
object_t obj = {0};
RtToken token;
RtPointer arg;
ri_var_t *pVar;
va_list args;
va_start(args, name);
Light_init(&obj, ++pL->stat.num_lights);
while((token = va_arg(args, RtToken)) != RI_NULL)
{
arg = va_arg(args, RtPointer);
pVar = VarListFindByName(&engine.varList, token);
if (!pVar)
{
fprintf(stderr, "RiLightSource(): Variable \"%s\" not found!\n", token);
return NULL;
}
pVar = VarListAdd(&obj.vars, pVar);
VarSet(pVar, arg, 1);
}
Object_set_xform(&obj, pG->pXform_curr);
Object_set_attr(&obj, pG->pAttr);
Scene_Add(pL, &obj);
pLight = (light_t*)obj.pObjData;
va_start(args, name);
Ribgen_LightSource(&engine, &obj, name, pLight->id, args);
va_end(args);
return (RtLightHandle)pLight;
}
RtVoid RiSurface (char *name, ...)
{
RtToken token;
RtPointer arg;
ri_var_t *pVar;
va_list args;
va_start(args, name);
while((token = va_arg(args, RtToken)) != RI_NULL)
{
arg = va_arg(args, RtPointer);
pVar = VarListFindByName(&engine.varList, token);
if (!pVar)
{
fprintf(stderr, "RiSurface(): Variable \"%s\" not found!\n", token);
return;
}
// pVar = VarListAdd(&obj.vars, pVar);
// VarSet(pVar, arg, 1);
}
va_start(args, name);
Ribgen_Surface(&engine, name, args);
va_end(args);
}
RtVoid RiDisplacement (char *name, ...)
{
RtToken token;
RtPointer arg;
ri_var_t *pVar;
va_list args;
va_start(args, name);
while((token = va_arg(args, RtToken)) != RI_NULL)
{
arg = va_arg(args, RtPointer);
pVar = VarListFindByName(&engine.varList, token);
if (!pVar)
{
fprintf(stderr, "RiSurface(): Variable \"%s\" not found!\n", token);
return;
}
// pVar = VarListAdd(&obj.vars, pVar);
// VarSet(pVar, arg, 1);
}
va_start(args, name);
Ribgen_Displacement(&engine, name, args);
va_end(args);
}