00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "vp_global.h"
00032
00033 static void InitContext ANSI_ARGS((vpContext *vpc));
00034 #ifdef HAVE_HIRES_TIMER
00035 static void StartHiResTimer ANSI_ARGS((vpContext *vpc));
00036 #endif
00037
00038 #ifdef STATISTICS
00039 int vpResampleCount = 0;
00040 int vpCompositeCount = 0;
00041 int vpERTSkipCount = 0;
00042 int vpERTSkipAgainCount = 0;
00043 int vpERTUpdateCount = 0;
00044 int vpSpecialZeroSkipCount = 0;
00045 int vpRunFragmentCount = 0;
00046 #endif
00047
00048
00049
00050
00051
00052
00053
00054 static void
00055 InitContext(vpc)
00056 vpContext *vpc;
00057 {
00058 extern int read(), write();
00059 int m, l;
00060
00061 vpc->xlen = 0;
00062 vpc->ylen = 0;
00063 vpc->zlen = 0;
00064 vpc->raw_bytes_per_voxel = 0;
00065 vpc->num_voxel_fields = 0;
00066 vpc->num_shade_fields = 0;
00067 vpc->min_opacity = 0.0;
00068 vpc->num_clsfy_params = 0;
00069 vpc->color_channels = 1;
00070 vpc->shading_mode = LOOKUP_SHADER;
00071 vpc->num_materials = 1;
00072 vpc->color_field = 0;
00073 vpc->weight_field = 0;
00074 for (m = 0; m < VP_MAX_MATERIAL; m++) {
00075 vpc->matl_props[m][EXT_SURFACE][MATL_AMB_R] = DEFAULT_AMBIENT;
00076 vpc->matl_props[m][EXT_SURFACE][MATL_DIFF_R] = DEFAULT_DIFFUSE;
00077 vpc->matl_props[m][EXT_SURFACE][MATL_SPEC_R] = DEFAULT_SPECULAR;
00078 vpc->matl_props[m][EXT_SURFACE][MATL_AMB_G] = DEFAULT_AMBIENT;
00079 vpc->matl_props[m][EXT_SURFACE][MATL_DIFF_G] = DEFAULT_DIFFUSE;
00080 vpc->matl_props[m][EXT_SURFACE][MATL_SPEC_G] = DEFAULT_SPECULAR;
00081 vpc->matl_props[m][EXT_SURFACE][MATL_AMB_B] = DEFAULT_AMBIENT;
00082 vpc->matl_props[m][EXT_SURFACE][MATL_DIFF_B] = DEFAULT_DIFFUSE;
00083 vpc->matl_props[m][EXT_SURFACE][MATL_SPEC_B] = DEFAULT_SPECULAR;
00084 vpc->matl_props[m][EXT_SURFACE][MATL_SHINY] = DEFAULT_SHINYNESS;
00085
00086 vpc->matl_props[m][INT_SURFACE][MATL_AMB_R] = DEFAULT_AMBIENT;
00087 vpc->matl_props[m][INT_SURFACE][MATL_DIFF_R] = DEFAULT_DIFFUSE;
00088 vpc->matl_props[m][INT_SURFACE][MATL_SPEC_R] = DEFAULT_SPECULAR;
00089 vpc->matl_props[m][INT_SURFACE][MATL_AMB_G] = DEFAULT_AMBIENT;
00090 vpc->matl_props[m][INT_SURFACE][MATL_DIFF_G] = DEFAULT_DIFFUSE;
00091 vpc->matl_props[m][INT_SURFACE][MATL_SPEC_G] = DEFAULT_SPECULAR;
00092 vpc->matl_props[m][INT_SURFACE][MATL_AMB_B] = DEFAULT_AMBIENT;
00093 vpc->matl_props[m][INT_SURFACE][MATL_DIFF_B] = DEFAULT_DIFFUSE;
00094 vpc->matl_props[m][INT_SURFACE][MATL_SPEC_B] = DEFAULT_SPECULAR;
00095 vpc->matl_props[m][INT_SURFACE][MATL_SHINY] = DEFAULT_SHINYNESS;
00096 }
00097 for (l = 0; l < VP_MAX_LIGHTS; l++) {
00098 vpc->light_enable[l] = 0;
00099 vpSetVector4(vpc->light_vector[l], 0.57735, 0.57735, 0.57735, 1.);
00100 vpSetVector3(vpc->light_color[l], 1., 1., 1.);
00101 }
00102 vpc->light_enable[0] = 1;
00103 vpc->light_both_sides = 0;
00104 vpc->reverse_surface_sides = 0;
00105 vpc->dc_enable = 0;
00106 vpc->dc_front_factor = 1.;
00107 vpc->dc_density = 1.;
00108 vpc->dc_quantization = DEFAULT_DC_QUANTIZATION;
00109 vpIdentity4(vpc->transforms[VP_MODEL]);
00110 vpIdentity4(vpc->transforms[VP_VIEW]);
00111 vpIdentity4(vpc->transforms[VP_PROJECT]);
00112 vpWindow(vpc, VP_PARALLEL, -0.5, 0.5, -0.5, 0.5, -0.5, 0.5);
00113 vpc->current_matrix = VP_MODEL;
00114 vpc->concat_left = 0;
00115 vpc->axis_override = VP_NO_AXIS;
00116 vpc->max_opacity = 1.0;
00117 vpc->factored_view_ready = 0;
00118 vpc->int_image_width_hint = 0;
00119 vpc->int_image_height_hint = 0;
00120 vpc->clamp_shade_table = 1;
00121 vpc->enable_shadows = 0;
00122 vpc->shadow_light_num = VP_LIGHT0;
00123 vpc->shadow_width_hint = 0;
00124 vpc->shadow_height_hint = 0;
00125 vpc->shadow_bias = 4;
00126 vpc->write_func = write;
00127 vpc->read_func = read;
00128 vpc->mmap_func = NULL;
00129 vpc->log_alloc_func = NULL;
00130 vpc->log_free_func = NULL;
00131 vpc->status_func = NULL;
00132 vpc->client_data = NULL;
00133 vpc->error_code = VP_OK;
00134 #ifdef DEBUG
00135 bzero(vpc->debug_enable, VPDEBUG_COUNT * sizeof(short));
00136 vpc->trace_u = -1;
00137 vpc->trace_v = -1;
00138 vpc->trace_shadow_k = 0;
00139 #endif
00140
00141 #ifdef USE_TIMER
00142 bzero(vpc->timer_ticks, VPTIMER_COUNT * sizeof(unsigned));
00143 #ifdef HAVE_LORES_TIMER
00144 vpc->timer_usec_per_tick = 1.0;
00145 #endif
00146 #ifdef HAVE_HIRES_TIMER
00147 StartHiResTimer(vpc);
00148 #endif
00149 #endif
00150 }
00151
00152
00153
00154
00155
00156
00157
00158 vpContext *
00159 vpCreateContext()
00160 {
00161 vpContext *vpc;
00162
00163
00164
00165 if ((vpc = (vpContext *)malloc(sizeof(vpContext))) == NULL)
00166 VPBug("out of memory");
00167 bzero(vpc, sizeof(vpContext));
00168 InitContext(vpc);
00169 return(vpc);
00170 }
00171
00172
00173
00174
00175
00176
00177
00178 void
00179 vpDestroyContext(vpc)
00180 vpContext *vpc;
00181 {
00182 VPResizeDepthCueTable(vpc, 0, 0);
00183 VPResizeRenderBuffers(vpc, 0, 0, 0);
00184 vpDestroyClassifiedVolume(vpc);
00185 vpDestroyMinMaxOctree(vpc);
00186 if (vpc->sum_table != NULL)
00187 Dealloc(vpc, vpc->sum_table);
00188 VPResizeShadowBuffer(vpc, 0, 0);
00189
00190
00191
00192 free((void *)vpc);
00193 }
00194
00195
00196
00197
00198
00199
00200
00201 vpResult
00202 vpSetVolumeSize(vpc, xlen, ylen, zlen)
00203 vpContext *vpc;
00204 int xlen, ylen, zlen;
00205 {
00206 vpc->xlen = xlen;
00207 vpc->ylen = ylen;
00208 vpc->zlen = zlen;
00209 vpc->factored_view_ready = 0;
00210 vpDestroyClassifiedVolume(vpc);
00211 vpDestroyMinMaxOctree(vpc);
00212 return(VP_OK);
00213 }
00214
00215
00216
00217
00218
00219
00220
00221 vpResult
00222 vpSetVoxelSize(vpc, bytes_per_voxel, num_voxel_fields, num_shade_fields,
00223 num_clsfy_fields)
00224 vpContext *vpc;
00225 int bytes_per_voxel;
00226 int num_voxel_fields;
00227 int num_shade_fields;
00228 int num_clsfy_fields;
00229 {
00230 if (num_voxel_fields >= VP_MAX_FIELDS)
00231 return(VPSetError(vpc, VPERROR_LIMIT_EXCEEDED));
00232 if (num_clsfy_fields < 0 || num_clsfy_fields > num_voxel_fields)
00233 return(VPSetError(vpc, VPERROR_BAD_VALUE));
00234 if (num_shade_fields < 0 || num_shade_fields > num_voxel_fields)
00235 return(VPSetError(vpc, VPERROR_BAD_VALUE));
00236 vpc->raw_bytes_per_voxel = bytes_per_voxel;
00237 vpc->num_voxel_fields = num_voxel_fields;
00238 vpc->num_shade_fields = num_shade_fields;
00239 vpc->num_clsfy_params = num_clsfy_fields;
00240 vpDestroyClassifiedVolume(vpc);
00241 vpDestroyMinMaxOctree(vpc);
00242 return(VP_OK);
00243 }
00244
00245
00246
00247
00248
00249
00250
00251 vpResult
00252 vpSetVoxelField(vpc, field_num, field_size, field_offset, field_max)
00253 vpContext *vpc;
00254 int field_num;
00255 int field_size;
00256 int field_offset;
00257 int field_max;
00258 {
00259 if (field_num < 0 || field_num >= vpc->num_voxel_fields)
00260 return(VPSetError(vpc, VPERROR_BAD_VALUE));
00261 if (field_size != 1 && field_size != 2 && field_size != 4)
00262 return(VPSetError(vpc, VPERROR_BAD_VALUE));
00263 if (field_offset < 0 || field_offset >= vpc->raw_bytes_per_voxel)
00264 return(VPSetError(vpc, VPERROR_BAD_VALUE));
00265 vpc->field_size[field_num] = field_size;
00266 vpc->field_offset[field_num] = field_offset;
00267 vpc->field_max[field_num] = field_max;
00268 vpDestroyClassifiedVolume(vpc);
00269 vpDestroyMinMaxOctree(vpc);
00270 return(VP_OK);
00271 }
00272
00273
00274
00275
00276
00277
00278
00279 vpResult
00280 vpSetRawVoxels(vpc, raw_voxels, raw_voxels_size, xstride, ystride, zstride)
00281 vpContext *vpc;
00282 int xstride, ystride, zstride;
00283 void *raw_voxels;
00284 int raw_voxels_size;
00285 {
00286 vpc->raw_voxels = raw_voxels;
00287 vpc->raw_voxels_size = raw_voxels_size;
00288 vpc->xstride = xstride;
00289 vpc->ystride = ystride;
00290 vpc->zstride = zstride;
00291 if (raw_voxels_size != 0)
00292 vpDestroyClassifiedVolume(vpc);
00293 vpDestroyMinMaxOctree(vpc);
00294 return(VP_OK);
00295 }
00296
00297
00298
00299
00300
00301
00302
00303
00304 vpResult
00305 vpSetClassifierTable(vpc, param_num, param_field, table, table_size)
00306 vpContext *vpc;
00307 int param_num;
00308 int param_field;
00309 float *table;
00310 int table_size;
00311 {
00312 if (param_num < 0 || param_num >= vpc->num_clsfy_params)
00313 return(VPSetError(vpc, VPERROR_BAD_VALUE));
00314 if (param_field < 0 || param_field >= vpc->num_voxel_fields)
00315 return(VPSetError(vpc, VPERROR_BAD_VALUE));
00316 vpc->param_field[param_num] = param_field;
00317 vpc->clsfy_table[param_num] = table;
00318 vpc->clsfy_table_size[param_num] = table_size;
00319 return(VP_OK);
00320 }
00321
00322
00323
00324
00325
00326
00327
00328 vpResult
00329 vpSetLookupShader(vpc, color_channels, num_materials,
00330 color_field, color_table, color_table_size,
00331 weight_field, weight_table, weight_table_size)
00332 vpContext *vpc;
00333 int color_channels;
00334 int num_materials;
00335 int color_field;
00336 float *color_table;
00337 int color_table_size;
00338 int weight_field;
00339 float *weight_table;
00340 int weight_table_size;
00341 {
00342 if (color_channels != 1 && color_channels != 3)
00343 return(VPSetError(vpc, VPERROR_BAD_VALUE));
00344 if (num_materials <= 0 || num_materials >= VP_MAX_MATERIAL)
00345 return(VPSetError(vpc, VPERROR_LIMIT_EXCEEDED));
00346 if (color_field < 0 || color_field >= vpc->num_voxel_fields ||
00347 color_table == NULL || color_table_size == 0)
00348 return(VPSetError(vpc, VPERROR_BAD_VALUE));
00349 if (num_materials > 1) {
00350 if (weight_field < 0 || weight_field >= vpc->num_voxel_fields ||
00351 weight_table == NULL || weight_table_size == 0)
00352 return(VPSetError(vpc, VPERROR_BAD_VALUE));
00353 }
00354 vpc->color_channels = color_channels;
00355 vpc->shading_mode = LOOKUP_SHADER;
00356 vpc->shade_color_table = color_table;
00357 vpc->shade_color_table_size = color_table_size;
00358 vpc->shade_weight_table = weight_table;
00359 vpc->shade_weight_table_size = weight_table_size;
00360 vpc->num_materials = num_materials;
00361 vpc->color_field = color_field;
00362 vpc->weight_field = weight_field;
00363 return(VP_OK);
00364 }
00365
00366
00367
00368
00369
00370
00371
00372 vpResult
00373 vpSetShadowLookupShader(vpc, color_channels, num_materials,
00374 color_field, color_table, color_table_size,
00375 weight_field, weight_table, weight_table_size,
00376 shadow_table, shadow_table_size)
00377 vpContext *vpc;
00378 int color_channels;
00379 int num_materials;
00380 int color_field;
00381 float *color_table;
00382 int color_table_size;
00383 int weight_field;
00384 float *weight_table;
00385 int weight_table_size;
00386 float *shadow_table;
00387 int shadow_table_size;
00388 {
00389 if (color_channels != 1 && color_channels != 3)
00390 return(VPSetError(vpc, VPERROR_BAD_VALUE));
00391 if (num_materials <= 0 || num_materials >= VP_MAX_MATERIAL)
00392 return(VPSetError(vpc, VPERROR_LIMIT_EXCEEDED));
00393 if (color_field < 0 || color_field >= vpc->num_voxel_fields ||
00394 color_table == NULL || color_table_size == 0)
00395 return(VPSetError(vpc, VPERROR_BAD_VALUE));
00396 if (num_materials > 1) {
00397 if (weight_field < 0 || weight_field >= vpc->num_voxel_fields ||
00398 weight_table == NULL || weight_table_size == 0)
00399 return(VPSetError(vpc, VPERROR_BAD_VALUE));
00400 }
00401 if (shadow_table_size != color_table_size)
00402 return(VPSetError(vpc, VPERROR_BAD_SIZE));
00403 vpc->color_channels = color_channels;
00404 vpc->shading_mode = LOOKUP_SHADER;
00405 vpc->shade_color_table = color_table;
00406 vpc->shade_color_table_size = color_table_size;
00407 vpc->shade_weight_table = weight_table;
00408 vpc->shade_weight_table_size = weight_table_size;
00409 vpc->num_materials = num_materials;
00410 vpc->color_field = color_field;
00411 vpc->weight_field = weight_field;
00412 vpc->shadow_color_table = shadow_table;
00413 vpc->shadow_color_table_size = shadow_table_size;
00414 return(VP_OK);
00415 }
00416
00417
00418
00419
00420
00421
00422
00423 vpResult
00424 vpSetMaterial(vpc, material, property, surface_side, r, g, b)
00425 vpContext *vpc;
00426 int material;
00427 int property;
00428 int surface_side;
00429 double r, g, b;
00430 {
00431 material -= VP_MATERIAL0;
00432 if (material < 0 || material >= vpc->num_materials)
00433 return(VPSetError(vpc, VPERROR_BAD_VALUE));
00434 if (surface_side == 0 || (surface_side & ~VP_BOTH_SIDES) != 0)
00435 return(VPSetError(vpc, VPERROR_BAD_OPTION));
00436 if (property != VP_SHINYNESS) {
00437 if (r < 0. || g < 0. || b < 0.)
00438 return(VPSetError(vpc, VPERROR_BAD_VALUE));
00439 }
00440 switch (property) {
00441 case VP_AMBIENT:
00442 if (surface_side & VP_EXTERIOR) {
00443 vpc->matl_props[material][EXT_SURFACE][MATL_AMB_R] = r * 255.;
00444 vpc->matl_props[material][EXT_SURFACE][MATL_AMB_G] = g * 255.;
00445 vpc->matl_props[material][EXT_SURFACE][MATL_AMB_B] = b * 255.;
00446 }
00447 if (surface_side & VP_INTERIOR) {
00448 vpc->matl_props[material][INT_SURFACE][MATL_AMB_R] = r * 255.;
00449 vpc->matl_props[material][INT_SURFACE][MATL_AMB_G] = g * 255.;
00450 vpc->matl_props[material][INT_SURFACE][MATL_AMB_B] = b * 255.;
00451 }
00452 break;
00453 case VP_DIFFUSE:
00454 if (surface_side & VP_EXTERIOR) {
00455 vpc->matl_props[material][EXT_SURFACE][MATL_DIFF_R] = r * 255.;
00456 vpc->matl_props[material][EXT_SURFACE][MATL_DIFF_G] = g * 255.;
00457 vpc->matl_props[material][EXT_SURFACE][MATL_DIFF_B] = b * 255.;
00458 }
00459 if (surface_side & VP_INTERIOR) {
00460 vpc->matl_props[material][INT_SURFACE][MATL_DIFF_R] = r * 255.;
00461 vpc->matl_props[material][INT_SURFACE][MATL_DIFF_G] = g * 255.;
00462 vpc->matl_props[material][INT_SURFACE][MATL_DIFF_B] = b * 255.;
00463 }
00464 break;
00465 case VP_SPECULAR:
00466 if (surface_side & VP_EXTERIOR) {
00467 vpc->matl_props[material][EXT_SURFACE][MATL_SPEC_R] = r * 255.;
00468 vpc->matl_props[material][EXT_SURFACE][MATL_SPEC_G] = g * 255.;
00469 vpc->matl_props[material][EXT_SURFACE][MATL_SPEC_B] = b * 255.;
00470 }
00471 if (surface_side & VP_INTERIOR) {
00472 vpc->matl_props[material][INT_SURFACE][MATL_SPEC_R] = r * 255.;
00473 vpc->matl_props[material][INT_SURFACE][MATL_SPEC_G] = g * 255.;
00474 vpc->matl_props[material][INT_SURFACE][MATL_SPEC_B] = b * 255.;
00475 }
00476 break;
00477 case VP_SHINYNESS:
00478 if (surface_side & VP_EXTERIOR)
00479 vpc->matl_props[material][EXT_SURFACE][MATL_SHINY] = r;
00480 if (surface_side & VP_INTERIOR)
00481 vpc->matl_props[material][INT_SURFACE][MATL_SHINY] = r;
00482 break;
00483 default:
00484 return(VPSetError(vpc, VPERROR_BAD_OPTION));
00485 }
00486 return(VP_OK);
00487 }
00488
00489
00490
00491
00492
00493
00494
00495 vpResult
00496 vpSetLight(vpc, light_num, property, n0, n1, n2)
00497 vpContext *vpc;
00498 int light_num;
00499 int property;
00500 double n0, n1, n2;
00501 {
00502 vpVector4 v1, v2;
00503
00504 light_num -= VP_LIGHT0;
00505 if (light_num < 0 || light_num >= VP_MAX_LIGHTS)
00506 return(VPSetError(vpc, VPERROR_LIMIT_EXCEEDED));
00507 switch (property) {
00508 case VP_DIRECTION:
00509 vpSetVector4(v1, n0, n1, n2, 1.);
00510 if (vpNormalize3(v1) != VP_OK)
00511 return(VPSetError(vpc, VPERROR_SINGULAR));
00512 vpMatrixVectorMult4(v2, vpc->transforms[VP_MODEL], v1);
00513 vpc->light_vector[light_num][0] = v2[0];
00514 vpc->light_vector[light_num][1] = v2[1];
00515 vpc->light_vector[light_num][2] = v2[2];
00516 vpc->light_vector[light_num][3] = v2[3];
00517 break;
00518 case VP_COLOR:
00519 if (n0 < 0. || n0 > 1. || n1 < 0. || n1 > 1. || n2 < 0. || n2 > 1.)
00520 return(VPSetError(vpc, VPERROR_BAD_VALUE));
00521 vpc->light_color[light_num][0] = n0;
00522 vpc->light_color[light_num][1] = n1;
00523 vpc->light_color[light_num][2] = n2;
00524 break;
00525 default:
00526 return(VPSetError(vpc, VPERROR_BAD_OPTION));
00527 }
00528 return(VP_OK);
00529 }
00530
00531
00532
00533
00534
00535
00536
00537 vpResult
00538 vpEnable(vpc, option, value)
00539 vpContext *vpc;
00540 int option;
00541 int value;
00542 {
00543 switch (option) {
00544 case VP_LIGHT0:
00545 case VP_LIGHT1:
00546 case VP_LIGHT2:
00547 case VP_LIGHT3:
00548 case VP_LIGHT4:
00549 case VP_LIGHT5:
00550 if (value == 0)
00551 vpc->light_enable[option - VP_LIGHT0] = 0;
00552 else
00553 vpc->light_enable[option - VP_LIGHT0] = 1;
00554 break;
00555 case VP_LIGHT_BOTH_SIDES:
00556 if (value == 0)
00557 vpc->light_both_sides = 0;
00558 else
00559 vpc->light_both_sides = 1;
00560 break;
00561 case VP_REVERSE_SURFACE_SIDES:
00562 if (value == 0)
00563 vpc->reverse_surface_sides = 0;
00564 else
00565 vpc->reverse_surface_sides = 1;
00566 break;
00567 case VP_DEPTH_CUE:
00568 if (value == 0)
00569 vpc->dc_enable = 0;
00570 else
00571 vpc->dc_enable = 1;
00572 break;
00573 case VP_VIEW_X_AXIS:
00574 if (value == 0)
00575 vpc->skip_rle_x = 1;
00576 else
00577 vpc->skip_rle_x = 0;
00578 break;
00579 case VP_VIEW_Y_AXIS:
00580 if (value == 0)
00581 vpc->skip_rle_y = 1;
00582 else
00583 vpc->skip_rle_y = 0;
00584 break;
00585 case VP_VIEW_Z_AXIS:
00586 if (value == 0)
00587 vpc->skip_rle_z = 1;
00588 else
00589 vpc->skip_rle_z = 0;
00590 break;
00591 case VP_SHADOW:
00592 if (value == 0) {
00593 vpc->enable_shadows = 0;
00594 } else {
00595 vpc->enable_shadows = 1;
00596 }
00597 vpc->factored_view_ready = 0;
00598 break;
00599 case VP_CLAMP_SHADE_TABLE:
00600 if (value == 0)
00601 vpc->clamp_shade_table = 0;
00602 else
00603 vpc->clamp_shade_table = 1;
00604 break;
00605 default:
00606 return(VPSetError(vpc, VPERROR_BAD_VALUE));
00607 }
00608 return(VP_OK);
00609 }
00610
00611
00612
00613
00614
00615
00616
00617 vpResult
00618 vpSetDepthCueing(vpc, front_factor, density)
00619 vpContext *vpc;
00620 double front_factor;
00621 double density;
00622 {
00623 if (front_factor <= 0.)
00624 return(VPSetError(vpc, VPERROR_BAD_VALUE));
00625 vpc->dc_front_factor = front_factor;
00626 vpc->dc_density = density;
00627 if (vpc->dc_table_len > 0)
00628 VPComputeDepthCueTable(vpc, 0, vpc->dc_table_len-1);
00629 return(VP_OK);
00630 }
00631
00632
00633
00634
00635
00636
00637
00638 vpResult
00639 vpCurrentMatrix(vpc, option)
00640 vpContext *vpc;
00641 int option;
00642 {
00643 switch (option) {
00644 case VP_MODEL:
00645 case VP_VIEW:
00646 case VP_PROJECT:
00647 vpc->current_matrix = option;
00648 break;
00649 default:
00650 return(VPSetError(vpc, VPERROR_BAD_OPTION));
00651 }
00652 return(VP_OK);
00653 }
00654
00655
00656
00657
00658
00659
00660
00661 vpResult
00662 vpIdentityMatrix(vpc)
00663 vpContext *vpc;
00664 {
00665 vpIdentity4(vpc->transforms[vpc->current_matrix]);
00666 vpc->factored_view_ready = 0;
00667 return(VP_OK);
00668 }
00669
00670
00671
00672
00673
00674
00675
00676 vpResult
00677 vpSetMatrix(vpc, matrix)
00678 vpContext *vpc;
00679 vpMatrix4 matrix;
00680 {
00681 bcopy(matrix, vpc->transforms[vpc->current_matrix], sizeof(vpMatrix4));
00682 vpc->factored_view_ready = 0;
00683 return(VP_OK);
00684 }
00685
00686
00687
00688
00689
00690
00691
00692 vpResult
00693 vpGetMatrix(vpc, matrix_code, matrix)
00694 vpContext *vpc;
00695 int matrix_code;
00696 vpMatrix4 matrix;
00697 {
00698 switch (matrix_code) {
00699 case VP_MODEL:
00700 case VP_VIEW:
00701 case VP_PROJECT:
00702 bcopy(vpc->transforms[matrix_code], matrix, sizeof(vpMatrix4));
00703 break;
00704 case VP_SCREEN:
00705 VPComputeViewTransform(vpc, matrix);
00706 break;
00707 default:
00708 return(VPSetError(vpc, VPERROR_BAD_OPTION));
00709 }
00710 return(VP_OK);
00711 }
00712
00713
00714
00715
00716
00717
00718
00719 vpResult
00720 vpMultMatrix(vpc, matrix)
00721 vpContext *vpc;
00722 vpMatrix4 matrix;
00723 {
00724 vpMatrix4 tmp;
00725
00726 if (vpc->concat_left)
00727 vpMatrixMult4(tmp, matrix, vpc->transforms[vpc->current_matrix]);
00728 else
00729 vpMatrixMult4(tmp, vpc->transforms[vpc->current_matrix], matrix);
00730 bcopy(tmp, vpc->transforms[vpc->current_matrix], sizeof(vpMatrix4));
00731 vpc->factored_view_ready = 0;
00732 return(VP_OK);
00733 }
00734
00735
00736
00737
00738
00739
00740
00741 vpResult
00742 vpTranslate(vpc, tx, ty, tz)
00743 vpContext *vpc;
00744 double tx, ty, tz;
00745 {
00746 vpMatrix4 t, tmp;
00747
00748 VPLoadTranslation(t, tx, ty, tz);
00749 if (vpc->concat_left)
00750 vpMatrixMult4(tmp, t, vpc->transforms[vpc->current_matrix]);
00751 else
00752 vpMatrixMult4(tmp, vpc->transforms[vpc->current_matrix], t);
00753 bcopy(tmp, vpc->transforms[vpc->current_matrix], sizeof(vpMatrix4));
00754 vpc->factored_view_ready = 0;
00755 return(VP_OK);
00756 }
00757
00758
00759
00760
00761
00762
00763
00764 vpResult
00765 vpRotate(vpc, axis, degrees)
00766 vpContext *vpc;
00767 int axis;
00768 double degrees;
00769 {
00770 vpMatrix4 r, tmp;
00771
00772 if (axis != VP_X_AXIS && axis != VP_Y_AXIS && axis != VP_Z_AXIS)
00773 return(VPSetError(vpc, VPERROR_BAD_OPTION));
00774 VPLoadRotation(r, axis, degrees);
00775 if (vpc->concat_left)
00776 vpMatrixMult4(tmp, r, vpc->transforms[vpc->current_matrix]);
00777 else
00778 vpMatrixMult4(tmp, vpc->transforms[vpc->current_matrix], r);
00779 bcopy(tmp, vpc->transforms[vpc->current_matrix], sizeof(vpMatrix4));
00780 vpc->factored_view_ready = 0;
00781 return(VP_OK);
00782 }
00783
00784
00785
00786
00787
00788
00789
00790 vpResult
00791 vpScale(vpc, sx, sy, sz)
00792 vpContext *vpc;
00793 double sx, sy, sz;
00794 {
00795 vpMatrix4 s, tmp;
00796
00797 VPLoadScale(s, sx, sy, sz);
00798 if (vpc->concat_left)
00799 vpMatrixMult4(tmp, s, vpc->transforms[vpc->current_matrix]);
00800 else
00801 vpMatrixMult4(tmp, vpc->transforms[vpc->current_matrix], s);
00802 bcopy(tmp, vpc->transforms[vpc->current_matrix], sizeof(vpMatrix4));
00803 vpc->factored_view_ready = 0;
00804 return(VP_OK);
00805 }
00806
00807
00808
00809
00810
00811
00812
00813
00814 vpResult
00815 vpWindow(vpc, type, left, right, bottom, top, near, far)
00816 vpContext *vpc;
00817 int type;
00818 double left, right, bottom, top, near, far;
00819 {
00820 vpMatrix4 projectm, tmp;
00821
00822 if (left >= right || bottom >= top || near >= far)
00823 return(VPSetError(vpc, VPERROR_BAD_VALUE));
00824 if (type == VP_PERSPECTIVE) {
00825 if (near <= 0 || far <= 0)
00826 return(VPSetError(vpc, VPERROR_BAD_VALUE));
00827 } else if (type != VP_PARALLEL) {
00828 return(VPSetError(vpc, VPERROR_BAD_OPTION));
00829 }
00830
00831 vpIdentity4(projectm);
00832 if (type == VP_PARALLEL) {
00833 projectm[0][0] = 2. / (right - left);
00834 projectm[1][1] = 2. / (top - bottom);
00835 projectm[2][2] = 2. / (far - near);
00836 projectm[0][3] = (left + right) / (left - right);
00837 projectm[1][3] = (bottom + top) / (bottom - top);
00838 projectm[2][3] = (near + far) / (near - far);
00839 } else {
00840
00841 return(VPSetError(vpc, VPERROR_BAD_OPTION));
00842 #ifdef notdef
00843 projectm[0][0] = 2. * near / (right - left);
00844 projectm[1][1] = 2. * near / (top - bottom);
00845 projectm[2][2] = (near + far) / (near - far);
00846 projectm[0][2] = (right + left) / (right - left);
00847 projectm[1][2] = (top + bottom) / (top - bottom);
00848 projectm[3][2] = -1.;
00849 projectm[2][3] = 2. * far * near / (near - far);
00850 #endif
00851 }
00852 if (vpc->concat_left)
00853 vpMatrixMult4(tmp, projectm, vpc->transforms[VP_PROJECT]);
00854 else
00855 vpMatrixMult4(tmp, vpc->transforms[VP_PROJECT], projectm);
00856 bcopy(tmp, vpc->transforms[VP_PROJECT], sizeof(vpMatrix4));
00857 vpc->factored_view_ready = 0;
00858 return(VP_OK);
00859 }
00860
00861
00862
00863
00864
00865
00866
00867 vpResult
00868 vpWindowPHIGS(vpc, vrp, vpn, vup, prp, viewport_umin, viewport_umax,
00869 viewport_vmin, viewport_vmax, viewport_front, viewport_back,
00870 projection_type)
00871 vpContext *vpc;
00872 vpVector3 vrp;
00873 vpVector3 vpn;
00874 vpVector3 vup;
00875 vpVector3 prp;
00876 double viewport_umin;
00877 double viewport_umax;
00878 double viewport_vmin;
00879 double viewport_vmax;
00880 double viewport_front;
00881 double viewport_back;
00882 int projection_type;
00883 {
00884 vpMatrix4 m1, m2, m3;
00885 double cw_x, cw_y;
00886 double newz;
00887
00888 if (viewport_umax <= viewport_umin || viewport_vmax <= viewport_vmin ||
00889 viewport_front <= viewport_back)
00890 return(VPSetError(vpc, VPERROR_BAD_VALUE));
00891 if (projection_type != VP_PARALLEL && projection_type != VP_PERSPECTIVE)
00892 return(VPSetError(vpc, VPERROR_BAD_OPTION));
00893
00894
00895 if (projection_type == VP_PERSPECTIVE)
00896 return(VPSetError(vpc, VPERROR_BAD_OPTION));
00897
00898
00899 VPLoadTranslation(m1, -vrp[0], -vrp[1], -vrp[2]);
00900
00901
00902 vpIdentity4(m2);
00903 m2[2][0] = vpn[0];
00904 m2[2][1] = vpn[1];
00905 m2[2][2] = vpn[2];
00906 if (vpNormalize3(m2[2]) != VP_OK)
00907 return(VPSetError(vpc, VPERROR_SINGULAR));
00908 vpCrossProduct(m2[0], vup, m2[2]);
00909 if (vpNormalize3(m2[0]) != VP_OK)
00910 return(VPSetError(vpc, VPERROR_SINGULAR));
00911 vpCrossProduct(m2[1], m2[2], m2[0]);
00912 vpMatrixMult4(m3, m2, m1);
00913
00914 if (projection_type == VP_PERSPECTIVE) {
00915
00916 VPLoadTranslation(m1, -prp[0], -prp[1], -prp[2]);
00917 vpMatrixMult4(m2, m1, m3);
00918 bcopy(m2, m3, sizeof(vpMatrix4));
00919 }
00920
00921
00922 if (fabs(prp[2]) < VP_EPS)
00923 return(VPSetError(vpc, VPERROR_SINGULAR));
00924 vpIdentity4(m1);
00925 cw_x = 0.5 * (viewport_umin + viewport_umax);
00926 cw_y = 0.5 * (viewport_vmin + viewport_vmax);
00927 m1[0][2] = (cw_x - prp[0]) / prp[2];
00928 m1[1][2] = (cw_y - prp[1]) / prp[2];
00929 vpMatrixMult4(m2, m1, m3);
00930
00931 if (projection_type == VP_PARALLEL) {
00932
00933 VPLoadTranslation(m3, -cw_x, -cw_y, -viewport_back);
00934 vpMatrixMult4(m1, m3, m2);
00935
00936
00937 VPLoadScale(m2, 2. / (viewport_umax - viewport_umin),
00938 2. / (viewport_vmax - viewport_vmin),
00939 1. / (viewport_front - viewport_back));
00940 vpMatrixMult4(m3, m2, m1);
00941 } else {
00942
00943 if (fabs(prp[2] - viewport_back) < VP_EPS)
00944 return(VPSetError(vpc, VPERROR_SINGULAR));
00945 vpIdentity4(m3);
00946 m3[0][0] = 2*prp[2] / ((viewport_umax - viewport_umin) *
00947 (prp[2] - viewport_back));
00948 m3[1][1] = 2*prp[2] / ((viewport_vmax - viewport_vmin) *
00949 (prp[2] - viewport_back));
00950 m3[2][2] = 1. / (prp[2] - viewport_back);
00951 vpMatrixMult4(m1, m3, m2);
00952
00953
00954 vpIdentity4(m2);
00955 newz = (prp[2] - viewport_front) / (viewport_back - prp[2]);
00956 m2[2][2] = 1. / (1. + newz);
00957 m2[2][3] = newz / (-1. - newz);
00958 m2[3][2] = -1.;
00959 m2[3][3] = 0.;
00960 vpMatrixMult4(m3, m2, m1);
00961 }
00962 if (vpc->concat_left)
00963 vpMatrixMult4(m1, m3, vpc->transforms[VP_PROJECT]);
00964 else
00965 vpMatrixMult4(m1, vpc->transforms[VP_PROJECT], m3);
00966 bcopy(m1, vpc->transforms[VP_PROJECT], sizeof(vpMatrix4));
00967 vpc->factored_view_ready = 0;
00968 return(VP_OK);
00969 }
00970
00971
00972
00973
00974
00975
00976
00977 vpResult
00978 vpSetImage(vpc, image, width, height, bytes_per_scan, pixel_type)
00979 vpContext *vpc;
00980 unsigned char *image;
00981 int width, height;
00982 int bytes_per_scan;
00983 int pixel_type;
00984 {
00985 int bytes_per_pixel;
00986
00987
00988 switch (pixel_type) {
00989 case VP_ALPHA:
00990 case VP_LUMINANCE:
00991 bytes_per_pixel = 1;
00992 break;
00993 case VP_LUMINANCEA:
00994 bytes_per_pixel = 2;
00995 break;
00996 case VP_RGB:
00997 case VP_BGR:
00998 bytes_per_pixel = 3;
00999 break;
01000 case VP_RGBA:
01001 case VP_ABGR:
01002 bytes_per_pixel = 4;
01003 break;
01004 default:
01005 return(VPSetError(vpc, VPERROR_BAD_OPTION));
01006 }
01007 if (bytes_per_scan < width * bytes_per_pixel)
01008 return(VPSetError(vpc, VPERROR_BAD_SIZE));
01009
01010
01011 if (width != vpc->image_width || height != vpc->image_height) {
01012 vpc->image_width = width;
01013 vpc->image_height = height;
01014 vpc->factored_view_ready = 0;
01015 }
01016 vpc->image = image;
01017 vpc->image_bytes_per_scan = bytes_per_scan;
01018 vpc->pixel_type = pixel_type;
01019 return(VP_OK);
01020 }
01021
01022
01023
01024
01025
01026
01027
01028 vpResult
01029 vpSeti(vpc, option, value)
01030 vpContext *vpc;
01031 int option;
01032 int value;
01033 {
01034 switch (option) {
01035 case VP_CONCAT_MODE:
01036 if (value == VP_CONCAT_LEFT)
01037 vpc->concat_left = 1;
01038 else if (value == VP_CONCAT_RIGHT)
01039 vpc->concat_left = 0;
01040 else
01041 return(VPSetError(vpc, VPERROR_BAD_OPTION));
01042 break;
01043 case VP_DEPTH_CUE_SIZE_HINT:
01044 if (value < 0)
01045 return(VPSetError(vpc, VPERROR_BAD_VALUE));
01046 vpc->dc_table_len_hint = value;
01047 break;
01048 case VP_INT_WIDTH_HINT:
01049 if (value < 0)
01050 return(VPSetError(vpc, VPERROR_BAD_VALUE));
01051 vpc->int_image_width_hint = value;
01052 break;
01053 case VP_INT_HEIGHT_HINT:
01054 if (value < 0)
01055 return(VPSetError(vpc, VPERROR_BAD_VALUE));
01056 vpc->int_image_height_hint = value;
01057 break;
01058 case VP_SHADOW_LIGHT:
01059 if (value < VP_LIGHT0 || value > VP_LIGHT5)
01060 return(VPSetError(vpc, VPERROR_BAD_OPTION));
01061 vpc->shadow_light_num = value;
01062 break;
01063 case VP_SHADOW_WIDTH_HINT:
01064 if (value < 0)
01065 return(VPSetError(vpc, VPERROR_BAD_VALUE));
01066 vpc->shadow_width_hint = value;
01067 break;
01068 case VP_SHADOW_HEIGHT_HINT:
01069 if (value < 0)
01070 return(VPSetError(vpc, VPERROR_BAD_VALUE));
01071 vpc->shadow_height_hint = value;
01072 break;
01073 case VP_SHADOW_BIAS:
01074 if (value < 0)
01075 return(VPSetError(vpc, VPERROR_BAD_VALUE));
01076 vpc->shadow_bias = value;
01077 vpc->factored_view_ready = 0;
01078 break;
01079 case VP_AXIS_OVERRIDE:
01080 switch (value) {
01081 case VP_X_AXIS:
01082 case VP_Y_AXIS:
01083 case VP_Z_AXIS:
01084 case VP_NO_AXIS:
01085 vpc->axis_override = value;
01086 break;
01087 default:
01088 return(VPSetError(vpc, VPERROR_BAD_OPTION));
01089 break;
01090 }
01091 vpc->factored_view_ready = 0;
01092 break;
01093 case VP_TRACE_SHADOW_K:
01094 #ifdef DEBUG
01095 vpc->trace_shadow_k = value;
01096 #endif
01097 break;
01098 default:
01099 return(VPSetError(vpc, VPERROR_BAD_OPTION));
01100 }
01101 return(VP_OK);
01102 }
01103
01104
01105
01106
01107
01108
01109
01110 vpResult
01111 vpSetd(vpc, option, value)
01112 vpContext *vpc;
01113 int option;
01114 double value;
01115 {
01116 switch (option) {
01117 case VP_DEPTH_CUE_QUANTIZATION:
01118 if (value <= 0. || value >= 1.)
01119 return(VPSetError(vpc, VPERROR_BAD_VALUE));
01120 vpc->dc_quantization = value;
01121 VPResizeDepthCueTable(vpc, 0, 0);
01122 break;
01123 case VP_MAX_RAY_OPACITY:
01124 if (value < 0. || value > 1.)
01125 return(VPSetError(vpc, VPERROR_BAD_VALUE));
01126 vpc->max_opacity = value;
01127 break;
01128 case VP_MIN_VOXEL_OPACITY:
01129 if ((value < 0. || value > 1.) && value != -1.0)
01130 return(VPSetError(vpc, VPERROR_BAD_VALUE));
01131 vpc->min_opacity = value;
01132 break;
01133 default:
01134 return(VPSetError(vpc, VPERROR_BAD_OPTION));
01135 }
01136 return(VP_OK);
01137 }
01138
01139
01140
01141
01142
01143
01144
01145 vpResult
01146 vpMinMaxOctreeThreshold(vpc, param, range)
01147 vpContext *vpc;
01148 int param;
01149 int range;
01150 {
01151 if (param >= vpc->num_clsfy_params)
01152 return(VPSetError(vpc, VPERROR_BAD_VALUE));
01153 vpc->param_maxrange[param] = range;
01154 return(VP_OK);
01155 }
01156
01157
01158
01159
01160
01161
01162
01163 vpResult
01164 vpSetCallback(vpc, option, func)
01165 vpContext *vpc;
01166 int option;
01167 void *func;
01168 {
01169 extern int read(), write();
01170
01171 switch (option) {
01172 case VP_LOG_ALLOC_FUNC:
01173 vpc->log_alloc_func = func;
01174 break;
01175 case VP_LOG_FREE_FUNC:
01176 vpc->log_free_func = func;
01177 break;
01178 case VP_STATUS_FUNC:
01179 vpc->status_func = func;
01180 break;
01181 case VP_READ_FUNC:
01182 if (func == NULL)
01183 vpc->read_func = read;
01184 else
01185 vpc->read_func = func;
01186 break;
01187 case VP_WRITE_FUNC:
01188 if (func == NULL)
01189 vpc->write_func = write;
01190 else
01191 vpc->write_func = func;
01192 break;
01193 case VP_MMAP_FUNC:
01194 vpc->mmap_func = func;
01195 break;
01196 case VP_GRAY_SHADE_FUNC:
01197 if (func == NULL) {
01198 vpc->shading_mode = LOOKUP_SHADER;
01199 } else {
01200 vpc->color_channels = 1;
01201 vpc->shading_mode = CALLBACK_SHADER;
01202 vpc->shade_func = func;
01203 }
01204 break;
01205 case VP_RGB_SHADE_FUNC:
01206 if (func == NULL) {
01207 vpc->shading_mode = LOOKUP_SHADER;
01208 } else {
01209 vpc->color_channels = 3;
01210 vpc->shading_mode = CALLBACK_SHADER;
01211 vpc->shade_func = func;
01212 }
01213 break;
01214 default:
01215 return(VPSetError(vpc, VPERROR_BAD_OPTION));
01216 }
01217 return(VP_OK);
01218 }
01219
01220
01221
01222
01223
01224
01225
01226 vpResult
01227 vpSetClientData(vpc, client_data)
01228 vpContext *vpc;
01229 void *client_data;
01230 {
01231 vpc->client_data = client_data;
01232 return(VP_OK);
01233 }
01234
01235
01236
01237
01238
01239
01240
01241 vpResult
01242 vpSetDebug(vpc, flag, value)
01243 vpContext *vpc;
01244 int flag;
01245 int value;
01246 {
01247 if (flag < 0 || flag >= VPDEBUG_COUNT)
01248 return(VPSetError(vpc, VPERROR_BAD_OPTION));
01249 #ifdef DEBUG
01250 vpc->debug_enable[flag] = value;
01251 #endif
01252 return(VP_OK);
01253 }
01254
01255
01256
01257
01258
01259
01260
01261 vpResult
01262 vpTracePixel(vpc, trace_u, trace_v)
01263 vpContext *vpc;
01264 int trace_u, trace_v;
01265 {
01266 #ifdef DEBUG
01267 vpc->trace_u = trace_u;
01268 vpc->trace_v = trace_v;
01269 #endif
01270 return(VP_OK);
01271 }
01272
01273
01274
01275
01276
01277
01278
01279 vpResult
01280 vpGeti(vpc, option, iptr)
01281 vpContext *vpc;
01282 int option;
01283 int *iptr;
01284 {
01285 int c;
01286 int retcode;
01287
01288 switch (option) {
01289 case VP_XLEN:
01290 *iptr = vpc->xlen;
01291 break;
01292 case VP_YLEN:
01293 *iptr = vpc->ylen;
01294 break;
01295 case VP_ZLEN:
01296 *iptr = vpc->zlen;
01297 break;
01298 case VP_BYTES_PER_VOXEL:
01299 *iptr = vpc->raw_bytes_per_voxel;
01300 break;
01301 case VP_VOXEL_FIELD_COUNT:
01302 *iptr = vpc->num_voxel_fields;
01303 break;
01304 case VP_SHADE_FIELD_COUNT:
01305 *iptr = vpc->num_shade_fields;
01306 break;
01307 case VP_FIELD_SIZES:
01308 for (c = 0; c < vpc->num_voxel_fields; c++)
01309 iptr[c] = vpc->field_size[c];
01310 break;
01311 case VP_FIELD_OFFSETS:
01312 for (c = 0; c < vpc->num_voxel_fields; c++)
01313 iptr[c] = vpc->field_offset[c];
01314 break;
01315 case VP_FIELD_MAXES:
01316 for (c = 0; c < vpc->num_voxel_fields; c++)
01317 iptr[c] = vpc->field_max[c];
01318 break;
01319 case VP_VOXEL_DATA_SIZE:
01320 *iptr = vpc->raw_voxels_size;
01321 break;
01322 case VP_VOXEL_XSTRIDE:
01323 *iptr = vpc->xstride;
01324 break;
01325 case VP_VOXEL_YSTRIDE:
01326 *iptr = vpc->ystride;
01327 break;
01328 case VP_VOXEL_ZSTRIDE:
01329 *iptr = vpc->zstride;
01330 break;
01331 case VP_CLASSIFY_FIELD_COUNT:
01332 *iptr = vpc->num_clsfy_params;
01333 break;
01334 case VP_CLASSIFY_FIELDS:
01335 for (c = 0; c < vpc->num_clsfy_params; c++)
01336 iptr[c] = vpc->param_field[c];
01337 break;
01338 case VP_CLASSIFY_TABLE_SIZES:
01339 for (c = 0; c < vpc->num_clsfy_params; c++)
01340 iptr[c] = vpc->clsfy_table_size[c];
01341 break;
01342 case VP_COLOR_CHANNELS:
01343 *iptr = vpc->color_channels;
01344 break;
01345 case VP_SHADE_COLOR_SIZE:
01346 *iptr = vpc->shade_color_table_size;
01347 break;
01348 case VP_SHADE_WEIGHT_SIZE:
01349 *iptr = vpc->shade_weight_table_size;
01350 break;
01351 case VP_MATERIAL_COUNT:
01352 *iptr = vpc->num_materials;
01353 break;
01354 case VP_SHADE_COLOR_FIELD:
01355 *iptr = vpc->color_field;
01356 break;
01357 case VP_SHADE_WEIGHT_FIELD:
01358 *iptr = vpc->weight_field;
01359 break;
01360 case VP_LIGHT0:
01361 case VP_LIGHT1:
01362 case VP_LIGHT2:
01363 case VP_LIGHT3:
01364 case VP_LIGHT4:
01365 case VP_LIGHT5:
01366 *iptr = vpc->light_enable[option - VP_LIGHT0];
01367 break;
01368 case VP_LIGHT_BOTH_SIDES:
01369 *iptr = vpc->light_both_sides;
01370 break;
01371 case VP_REVERSE_SURFACE_SIDES:
01372 *iptr = vpc->reverse_surface_sides;
01373 break;
01374 case VP_DEPTH_CUE:
01375 *iptr = vpc->dc_enable;
01376 break;
01377 case VP_DEPTH_CUE_TABLE_SIZE:
01378 *iptr = vpc->dc_table_len;
01379 break;
01380 case VP_DEPTH_CUE_SIZE_HINT:
01381 *iptr = vpc->dc_table_len_hint;
01382 break;
01383 case VP_CURRENT_MATRIX:
01384 *iptr = vpc->current_matrix;
01385 break;
01386 case VP_CONCAT_MODE:
01387 if (vpc->concat_left)
01388 *iptr = VP_CONCAT_LEFT;
01389 else
01390 *iptr = VP_CONCAT_RIGHT;
01391 break;
01392 case VP_IMAGE_WIDTH:
01393 *iptr = vpc->image_width;
01394 break;
01395 case VP_IMAGE_HEIGHT:
01396 *iptr = vpc->image_height;
01397 break;
01398 case VP_IMAGE_SCAN_SIZE:
01399 *iptr = vpc->image_bytes_per_scan;
01400 break;
01401 case VP_VIEW_AXIS:
01402 if ((retcode = VPFactorView(vpc)) != VP_OK)
01403 return(retcode);
01404 *iptr = vpc->best_view_axis;
01405 break;
01406 case VP_INTERMEDIATE_WIDTH:
01407 if ((retcode = VPFactorView(vpc)) != VP_OK)
01408 return(retcode);
01409 *iptr = vpc->intermediate_width;
01410 break;
01411 case VP_INTERMEDIATE_HEIGHT:
01412 if ((retcode = VPFactorView(vpc)) != VP_OK)
01413 return(retcode);
01414 *iptr = vpc->intermediate_height;
01415 break;
01416 case VP_INTERMEDIATE_COLOR:
01417 if ((retcode = VPFactorView(vpc)) != VP_OK)
01418 return(retcode);
01419 *iptr = vpc->intermediate_color_channels;
01420 break;
01421 case VP_INT_WIDTH_HINT:
01422 *iptr = vpc->int_image_width_hint;
01423 break;
01424 case VP_INT_HEIGHT_HINT:
01425 *iptr = vpc->int_image_height_hint;
01426 break;
01427 case VP_VIEW_X_AXIS:
01428 *iptr = !vpc->skip_rle_x;
01429 break;
01430 case VP_VIEW_Y_AXIS:
01431 *iptr = !vpc->skip_rle_y;
01432 break;
01433 case VP_VIEW_Z_AXIS:
01434 *iptr = !vpc->skip_rle_z;
01435 break;
01436 case VP_VIEW_X_SIZE:
01437 if (vpc->rle_x == NULL) {
01438 *iptr = 0;
01439 } else {
01440 *iptr = sizeof(RLEVoxels) + vpc->rle_x->run_count +
01441 vpc->rle_x->data_count*vpc->rle_bytes_per_voxel +
01442 vpc->rle_x->klen*vpc->rle_x->scan_offsets_per_slice*
01443 sizeof(ScanOffset);
01444 }
01445 break;
01446 case VP_VIEW_Y_SIZE:
01447 if (vpc->rle_y == NULL) {
01448 *iptr = 0;
01449 } else {
01450 *iptr = sizeof(RLEVoxels) + vpc->rle_y->run_count +
01451 vpc->rle_y->data_count*vpc->rle_bytes_per_voxel +
01452 vpc->rle_y->klen*vpc->rle_y->scan_offsets_per_slice*
01453 sizeof(ScanOffset);
01454 }
01455 break;
01456 case VP_VIEW_Z_SIZE:
01457 if (vpc->rle_z == NULL) {
01458 *iptr = 0;
01459 } else {
01460 *iptr = sizeof(RLEVoxels) + vpc->rle_z->run_count +
01461 vpc->rle_z->data_count*vpc->rle_bytes_per_voxel +
01462 vpc->rle_z->klen*vpc->rle_z->scan_offsets_per_slice*
01463 sizeof(ScanOffset);
01464 }
01465 break;
01466 case VP_MMOCTREE_THRESHOLDS:
01467 for (c = 0; c < vpc->num_clsfy_params; c++)
01468 iptr[c] = vpc->param_maxrange[c];
01469 break;
01470 case VP_MMOCTREE_SIZE:
01471 if (vpc->mm_octree == NULL)
01472 *iptr = 0;
01473 else
01474 *iptr = sizeof(MinMaxOctree) + vpc->mm_octree->octree_bytes;
01475 break;
01476 case VP_SHADOW:
01477 *iptr = vpc->enable_shadows;
01478 break;
01479 case VP_SHADOW_LIGHT:
01480 *iptr = vpc->shadow_light_num;
01481 break;
01482 case VP_SHADOW_WIDTH_HINT:
01483 *iptr = vpc->shadow_width_hint;
01484 break;
01485 case VP_SHADOW_HEIGHT_HINT:
01486 *iptr = vpc->shadow_height_hint;
01487 break;
01488 case VP_SHADOW_WIDTH:
01489 if ((retcode = VPFactorView(vpc)) != VP_OK)
01490 return(retcode);
01491 *iptr = vpc->shadow_width;
01492 break;
01493 case VP_SHADOW_HEIGHT:
01494 if ((retcode = VPFactorView(vpc)) != VP_OK)
01495 return(retcode);
01496 *iptr = vpc->shadow_height;
01497 break;
01498 case VP_SHADOW_COLOR_SIZE:
01499 *iptr = vpc->shadow_color_table_size;
01500 break;
01501 case VP_SHADOW_BIAS:
01502 *iptr = vpc->shadow_bias;
01503 break;
01504 case VP_PIXEL_TYPE:
01505 *iptr = vpc->pixel_type;
01506 break;
01507 case VP_CLAMP_SHADE_TABLE:
01508 *iptr = vpc->clamp_shade_table;
01509 break;
01510 case VP_COMPOSITE_ORDER:
01511 if ((retcode = VPFactorView(vpc)) != VP_OK)
01512 return(retcode);
01513 if (vpc->reverse_slice_order)
01514 *iptr = -1;
01515 else
01516 *iptr = 1;
01517 break;
01518 default:
01519 return(VPSetError(vpc, VPERROR_BAD_OPTION));
01520 }
01521 return(VP_OK);
01522 }
01523
01524
01525
01526
01527
01528
01529
01530 vpResult
01531 vpGetd(vpc, option, dptr)
01532 vpContext *vpc;
01533 int option;
01534 double *dptr;
01535 {
01536 int c;
01537
01538 switch (option) {
01539 case VP_MIN_VOXEL_OPACITY:
01540 *dptr = vpc->min_opacity;
01541 break;
01542 case VP_DEPTH_CUE_FRONT:
01543 *dptr = vpc->dc_front_factor;
01544 break;
01545 case VP_DEPTH_CUE_DENSITY:
01546 *dptr = vpc->dc_density;
01547 break;
01548 case VP_DEPTH_CUE_QUANTIZATION:
01549 *dptr = vpc->dc_quantization;
01550 break;
01551 case VP_MAX_RAY_OPACITY:
01552 *dptr = vpc->max_opacity;
01553 break;
01554 default:
01555 return(VPSetError(vpc, VPERROR_BAD_OPTION));
01556 }
01557 return(VP_OK);
01558 }
01559
01560
01561
01562
01563
01564
01565
01566 vpResult
01567 vpGetp(vpc, option, pptr)
01568 vpContext *vpc;
01569 int option;
01570 void **pptr;
01571 {
01572 int c;
01573
01574 switch (option) {
01575 case VP_VOXEL_DATA:
01576 *pptr = vpc->raw_voxels;
01577 break;
01578 case VP_CLASSIFY_TABLES:
01579 for (c = 0; c < vpc->num_clsfy_params; c++)
01580 pptr[c] = vpc->clsfy_table[c];
01581 break;
01582 case VP_SHADE_FUNC:
01583 *pptr = vpc->shade_func;
01584 break;
01585 case VP_SHADE_COLOR_TABLE:
01586 *pptr = vpc->shade_color_table;
01587 break;
01588 case VP_SHADE_WEIGHT_TABLE:
01589 *pptr = vpc->shade_weight_table;
01590 break;
01591 case VP_SHADOW_COLOR_TABLE:
01592 *pptr = vpc->shadow_color_table;
01593 break;
01594 case VP_IMAGE:
01595 *pptr = vpc->image;
01596 break;
01597 case VP_LOG_ALLOC_FUNC:
01598 *pptr = vpc->log_alloc_func;
01599 break;
01600 case VP_LOG_FREE_FUNC:
01601 *pptr = vpc->log_free_func;
01602 break;
01603 case VP_STATUS_FUNC:
01604 *pptr = vpc->status_func;
01605 break;
01606 case VP_READ_FUNC:
01607 *pptr = vpc->read_func;
01608 break;
01609 case VP_WRITE_FUNC:
01610 *pptr = vpc->write_func;
01611 break;
01612 case VP_MMAP_FUNC:
01613 *pptr = vpc->mmap_func;
01614 break;
01615 case VP_CLIENT_DATA:
01616 *pptr = vpc->client_data;
01617 break;
01618 default:
01619 return(VPSetError(vpc, VPERROR_BAD_OPTION));
01620 }
01621 return(VP_OK);
01622 }
01623
01624
01625
01626
01627
01628
01629
01630 vpResult
01631 vpGetMaterial(vpc, material, property, surface_side, r, g, b)
01632 vpContext *vpc;
01633 int material;
01634 int property;
01635 int surface_side;
01636 double *r, *g, *b;
01637 {
01638 material -= VP_MATERIAL0;
01639 if (material < 0 || material >= vpc->num_materials)
01640 return(VPSetError(vpc, VPERROR_BAD_VALUE));
01641 if (surface_side != VP_EXTERIOR && surface_side != VP_INTERIOR)
01642 return(VPSetError(vpc, VPERROR_BAD_OPTION));
01643 switch (property) {
01644 case VP_AMBIENT:
01645 if (surface_side == VP_EXTERIOR) {
01646 *r = vpc->matl_props[material][EXT_SURFACE][MATL_AMB_R] / 255.;
01647 *g = vpc->matl_props[material][EXT_SURFACE][MATL_AMB_G] / 255.;
01648 *b = vpc->matl_props[material][EXT_SURFACE][MATL_AMB_B] / 255.;
01649 } else {
01650 *r = vpc->matl_props[material][INT_SURFACE][MATL_AMB_R] / 255.;
01651 *g = vpc->matl_props[material][INT_SURFACE][MATL_AMB_G] / 255.;
01652 *b = vpc->matl_props[material][INT_SURFACE][MATL_AMB_B] / 255.;
01653 }
01654 break;
01655 case VP_DIFFUSE:
01656 if (surface_side == VP_EXTERIOR) {
01657 *r = vpc->matl_props[material][EXT_SURFACE][MATL_DIFF_R] / 255.;
01658 *g = vpc->matl_props[material][EXT_SURFACE][MATL_DIFF_G] / 255.;
01659 *b = vpc->matl_props[material][EXT_SURFACE][MATL_DIFF_B] / 255.;
01660 } else {
01661 *r = vpc->matl_props[material][INT_SURFACE][MATL_DIFF_R] / 255.;
01662 *g = vpc->matl_props[material][INT_SURFACE][MATL_DIFF_G] / 255.;
01663 *b = vpc->matl_props[material][INT_SURFACE][MATL_DIFF_B] / 255.;
01664 }
01665 break;
01666 case VP_SPECULAR:
01667 if (surface_side == VP_EXTERIOR) {
01668 *r = vpc->matl_props[material][EXT_SURFACE][MATL_SPEC_R] / 255.;
01669 *g = vpc->matl_props[material][EXT_SURFACE][MATL_SPEC_G] / 255.;
01670 *b = vpc->matl_props[material][EXT_SURFACE][MATL_SPEC_B] / 255.;
01671 } else {
01672 *r = vpc->matl_props[material][INT_SURFACE][MATL_SPEC_R] / 255.;
01673 *g = vpc->matl_props[material][INT_SURFACE][MATL_SPEC_G] / 255.;
01674 *b = vpc->matl_props[material][INT_SURFACE][MATL_SPEC_B] / 255.;
01675 }
01676 break;
01677 case VP_SHINYNESS:
01678 if (surface_side & VP_EXTERIOR)
01679 *r = vpc->matl_props[material][EXT_SURFACE][MATL_SHINY];
01680 else
01681 *r = vpc->matl_props[material][INT_SURFACE][MATL_SHINY];
01682 break;
01683 default:
01684 return(VPSetError(vpc, VPERROR_BAD_OPTION));
01685 }
01686 return(VP_OK);
01687 }
01688
01689
01690
01691
01692
01693
01694
01695 vpResult
01696 vpGetLight(vpc, light_num, property, n0, n1, n2)
01697 vpContext *vpc;
01698 int light_num;
01699 int property;
01700 double *n0, *n1, *n2;
01701 {
01702 light_num -= VP_LIGHT0;
01703 if (light_num < 0 || light_num >= VP_MAX_LIGHTS)
01704 return(VPSetError(vpc, VPERROR_LIMIT_EXCEEDED));
01705 switch (property) {
01706 case VP_DIRECTION:
01707 *n0 = vpc->light_vector[light_num][0];
01708 *n1 = vpc->light_vector[light_num][1];
01709 *n2 = vpc->light_vector[light_num][2];
01710 break;
01711 case VP_COLOR:
01712 *n0 = vpc->light_color[light_num][0];
01713 *n1 = vpc->light_color[light_num][1];
01714 *n2 = vpc->light_color[light_num][2];
01715 break;
01716 default:
01717 return(VPSetError(vpc, VPERROR_BAD_OPTION));
01718 }
01719 return(VP_OK);
01720 }
01721
01722
01723
01724
01725
01726
01727
01728 vpResult
01729 vpGetImage(vpc, image, width, height, scan_bytes, pixel_type, image_type)
01730 vpContext *vpc;
01731 void *image;
01732 int width;
01733 int height;
01734 int scan_bytes;
01735 int pixel_type;
01736 int image_type;
01737
01738 {
01739 int x, y;
01740 unsigned char *dst_ptr;
01741 GrayIntPixel *gray_pixel;
01742 RGBIntPixel *rgb_pixel;
01743 int value;
01744 int color_channels;
01745
01746 switch (image_type) {
01747 case VP_IMAGE_BUFFER:
01748 if (width != vpc->intermediate_width ||
01749 height != vpc->intermediate_height)
01750 return(VPSetError(vpc, VPERROR_BAD_SIZE));
01751 color_channels = vpc->intermediate_color_channels;
01752 dst_ptr = image;
01753 switch (pixel_type) {
01754 case VP_ALPHA:
01755 if (scan_bytes < width)
01756 return(VPSetError(vpc, VPERROR_BAD_SIZE));
01757 if (color_channels == 1) {
01758 for (y = 0; y < height; y++) {
01759 gray_pixel = vpc->int_image.gray_intim +
01760 (vpc->pad_int_to_maxwidth ?
01761 vpc->max_intermediate_width*y :
01762 vpc->intermediate_width*y);
01763 dst_ptr = (unsigned char *)image + y * scan_bytes;
01764 for (x = 0; x < width; x++) {
01765 value = (int)rint(gray_pixel->opcflt * 255.);
01766 if (value > 255)
01767 *dst_ptr = 255;
01768 else
01769 *dst_ptr = value;
01770 dst_ptr++;
01771 gray_pixel++;
01772 }
01773 }
01774 } else {
01775 for (y = 0; y < height; y++) {
01776 rgb_pixel = vpc->int_image.rgb_intim +
01777 (vpc->pad_int_to_maxwidth ?
01778 vpc->max_intermediate_width*y :
01779 vpc->intermediate_width*y);
01780 dst_ptr = (unsigned char *)image + y * scan_bytes;
01781 for (x = 0; x < width; x++) {
01782 value = (int)rint(rgb_pixel->opcflt * 255.);
01783 if (value > 255)
01784 *dst_ptr = 255;
01785 else
01786 *dst_ptr = value;
01787 dst_ptr++;
01788 rgb_pixel++;
01789 }
01790 }
01791 }
01792 break;
01793 case VP_LUMINANCE:
01794 if (color_channels != 1)
01795 return(VPSetError(vpc, VPERROR_BAD_OPTION));
01796 if (scan_bytes < width)
01797 return(VPSetError(vpc, VPERROR_BAD_SIZE));
01798 for (y = 0; y < height; y++) {
01799 gray_pixel = vpc->int_image.gray_intim +
01800 (vpc->pad_int_to_maxwidth ?
01801 vpc->max_intermediate_width*y :
01802 vpc->intermediate_width*y);
01803 dst_ptr = (unsigned char *)image + y * scan_bytes;
01804 for (x = 0; x < width; x++) {
01805 value = (int)rint(gray_pixel->clrflt);
01806 if (value > 255)
01807 *dst_ptr = 255;
01808 else
01809 *dst_ptr = value;
01810 dst_ptr++;
01811 gray_pixel++;
01812 }
01813 }
01814 break;
01815 case VP_LUMINANCEA:
01816 if (color_channels != 1)
01817 return(VPSetError(vpc, VPERROR_BAD_OPTION));
01818 if (scan_bytes < 2*width)
01819 return(VPSetError(vpc, VPERROR_BAD_SIZE));
01820 for (y = 0; y < height; y++) {
01821 gray_pixel = vpc->int_image.gray_intim +
01822 (vpc->pad_int_to_maxwidth ?
01823 vpc->max_intermediate_width*y :
01824 vpc->intermediate_width*y);
01825 dst_ptr = (unsigned char *)image + y * scan_bytes;
01826 for (x = 0; x < width; x++) {
01827 value = (int)rint(gray_pixel->clrflt);
01828 if (value > 255)
01829 *dst_ptr = 255;
01830 else
01831 *dst_ptr = value;
01832 dst_ptr++;
01833 value = (int)rint(gray_pixel->opcflt * 255.);
01834 if (value > 255)
01835 *dst_ptr = 255;
01836 else
01837 *dst_ptr = value;
01838 dst_ptr++;
01839 gray_pixel++;
01840 }
01841 }
01842 break;
01843 case VP_RGB:
01844 if (color_channels != 3)
01845 return(VPSetError(vpc, VPERROR_BAD_OPTION));
01846 if (scan_bytes < 3*width)
01847 return(VPSetError(vpc, VPERROR_BAD_SIZE));
01848 for (y = 0; y < height; y++) {
01849 rgb_pixel = vpc->int_image.rgb_intim +
01850 (vpc->pad_int_to_maxwidth ?
01851 vpc->max_intermediate_width*y :
01852 vpc->intermediate_width*y);
01853 dst_ptr = (unsigned char *)image + y * scan_bytes;
01854 for (x = 0; x < width; x++) {
01855 value = (int)rint(rgb_pixel->rclrflt);
01856 if (value > 255)
01857 *dst_ptr = 255;
01858 else
01859 *dst_ptr = value;
01860 dst_ptr++;
01861 value = (int)rint(rgb_pixel->gclrflt);
01862 if (value > 255)
01863 *dst_ptr = 255;
01864 else
01865 *dst_ptr = value;
01866 dst_ptr++;
01867 value = (int)rint(rgb_pixel->bclrflt);
01868 if (value > 255)
01869 *dst_ptr = 255;
01870 else
01871 *dst_ptr = value;
01872 dst_ptr++;
01873 rgb_pixel++;
01874 }
01875 }
01876 break;
01877 case VP_RGBA:
01878 if (color_channels != 3)
01879 return(VPSetError(vpc, VPERROR_BAD_OPTION));
01880 if (scan_bytes < 4*width)
01881 return(VPSetError(vpc, VPERROR_BAD_SIZE));
01882 for (y = 0; y < height; y++) {
01883 rgb_pixel = vpc->int_image.rgb_intim +
01884 (vpc->pad_int_to_maxwidth ?
01885 vpc->max_intermediate_width*y :
01886 vpc->intermediate_width*y);
01887 dst_ptr = (unsigned char *)image + y * scan_bytes;
01888 for (x = 0; x < width; x++) {
01889 value = (int)rint(rgb_pixel->rclrflt);
01890 if (value > 255)
01891 *dst_ptr = 255;
01892 else
01893 *dst_ptr = value;
01894 dst_ptr++;
01895 value = (int)rint(rgb_pixel->gclrflt);
01896 if (value > 255)
01897 *dst_ptr = 255;
01898 else
01899 *dst_ptr = value;
01900 dst_ptr++;
01901 value = (int)rint(rgb_pixel->bclrflt);
01902 if (value > 255)
01903 *dst_ptr = 255;
01904 else
01905 *dst_ptr = value;
01906 dst_ptr++;
01907 value = (int)rint(rgb_pixel->opcflt*255.);
01908 if (value > 255)
01909 *dst_ptr = 255;
01910 else
01911 *dst_ptr = value;
01912 dst_ptr++;
01913 rgb_pixel++;
01914 }
01915 }
01916 break;
01917 case VP_BGR:
01918 if (color_channels != 3)
01919 return(VPSetError(vpc, VPERROR_BAD_OPTION));
01920 if (scan_bytes < 3*width)
01921 return(VPSetError(vpc, VPERROR_BAD_SIZE));
01922 for (y = 0; y < height; y++) {
01923 rgb_pixel = vpc->int_image.rgb_intim +
01924 (vpc->pad_int_to_maxwidth ?
01925 vpc->max_intermediate_width*y :
01926 vpc->intermediate_width*y);
01927 dst_ptr = (unsigned char *)image + y * scan_bytes;
01928 for (x = 0; x < width; x++) {
01929 value = (int)rint(rgb_pixel->bclrflt);
01930 if (value > 255)
01931 *dst_ptr = 255;
01932 else
01933 *dst_ptr = value;
01934 dst_ptr++;
01935 value = (int)rint(rgb_pixel->gclrflt);
01936 if (value > 255)
01937 *dst_ptr = 255;
01938 else
01939 *dst_ptr = value;
01940 dst_ptr++;
01941 value = (int)rint(rgb_pixel->rclrflt);
01942 if (value > 255)
01943 *dst_ptr = 255;
01944 else
01945 *dst_ptr = value;
01946 dst_ptr++;
01947 rgb_pixel++;
01948 }
01949 }
01950 break;
01951 case VP_ABGR:
01952 if (color_channels != 3)
01953 return(VPSetError(vpc, VPERROR_BAD_OPTION));
01954 if (scan_bytes < 4*width)
01955 return(VPSetError(vpc, VPERROR_BAD_SIZE));
01956 for (y = 0; y < height; y++) {
01957 rgb_pixel = vpc->int_image.rgb_intim +
01958 (vpc->pad_int_to_maxwidth ?
01959 vpc->max_intermediate_width*y :
01960 vpc->intermediate_width*y);
01961 dst_ptr = (unsigned char *)image + y * scan_bytes;
01962 for (x = 0; x < width; x++) {
01963 value = (int)rint(rgb_pixel->opcflt*255.);
01964 if (value > 255)
01965 *dst_ptr = 255;
01966 else
01967 *dst_ptr = value;
01968 dst_ptr++;
01969 value = (int)rint(rgb_pixel->bclrflt);
01970 if (value > 255)
01971 *dst_ptr = 255;
01972 else
01973 *dst_ptr = value;
01974 dst_ptr++;
01975 value = (int)rint(rgb_pixel->gclrflt);
01976 if (value > 255)
01977 *dst_ptr = 255;
01978 else
01979 *dst_ptr = value;
01980 dst_ptr++;
01981 value = (int)rint(rgb_pixel->rclrflt);
01982 if (value > 255)
01983 *dst_ptr = 255;
01984 else
01985 *dst_ptr = value;
01986 dst_ptr++;
01987 rgb_pixel++;
01988 }
01989 }
01990 break;
01991 default:
01992 return(VPSetError(vpc, VPERROR_BAD_OPTION));
01993 }
01994 break;
01995 case VP_SHADOW_BUFFER:
01996 if (pixel_type != VP_ALPHA)
01997 return(VPSetError(vpc, VPERROR_BAD_OPTION));
01998 if (width != vpc->shadow_width || height != vpc->shadow_height)
01999 return(VPSetError(vpc, VPERROR_BAD_SIZE));
02000 if (scan_bytes < width)
02001 return(VPSetError(vpc, VPERROR_BAD_SIZE));
02002 for (y = 0; y < height; y++) {
02003 gray_pixel = vpc->shadow_buffer + (vpc->pad_shadow_to_maxwidth ?
02004 vpc->max_shadow_width*y : vpc->shadow_width*y);
02005 dst_ptr = (unsigned char *)image + y * scan_bytes;
02006 for (x = 0; x < width; x++) {
02007 value = (int)rint(gray_pixel->opcflt * 255.);
02008 if (value > 255)
02009 *dst_ptr = 255;
02010 else
02011 *dst_ptr = value;
02012 dst_ptr++;
02013 gray_pixel++;
02014 }
02015 }
02016 break;
02017 default:
02018 return(VPSetError(vpc, VPERROR_BAD_OPTION));
02019 }
02020 return(VP_OK);
02021 }
02022
02023
02024
02025
02026
02027
02028
02029 vpResult
02030 vpGetTimer(vpc, option, iptr)
02031 vpContext *vpc;
02032 int option;
02033 int *iptr;
02034 {
02035 if (option < 0 || option >= VPTIMER_COUNT)
02036 return(VPSetError(vpc, VPERROR_BAD_OPTION));
02037 #ifdef USE_TIMER
02038 *iptr = (int)(vpc->timer_ticks[option] * vpc->timer_usec_per_tick);
02039 #else
02040 *iptr = 0;
02041 #endif
02042 return(VP_OK);
02043 }
02044
02045
02046
02047
02048
02049
02050
02051 vpResult
02052 vpClearTimer(vpc, option)
02053 vpContext *vpc;
02054 int option;
02055 {
02056 if (option < 0 || option >= VPTIMER_COUNT)
02057 return(VPSetError(vpc, VPERROR_BAD_OPTION));
02058 #ifdef USE_TIMER
02059 vpc->timer_ticks[option] = 0;
02060 #endif
02061 return(VP_OK);
02062 }
02063
02064 #ifdef HAVE_HIRES_TIMER
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074 static void
02075 StartHiResTimer(vpc)
02076 vpContext *vpc;
02077 {
02078 volatile unsigned timer_resolution;
02079 unsigned phys_addr;
02080 unsigned page_addr;
02081 int fd;
02082 volatile unsigned *timer_addr;
02083
02084
02085
02086
02087 vpc->timer_usec_per_tick = 0.;
02088 vpc->timer_addr = &vpc->dummy_timer;
02089 vpc->dummy_timer = 0;
02090
02091 phys_addr = syssgi(SGI_QUERY_CYCLECNTR, &timer_resolution);
02092 if ((int)phys_addr == -1)
02093 return;
02094 if ((fd = open("/dev/mmem", O_RDONLY)) < 0)
02095 return;
02096 page_addr = phys_addr & ~POFFMASK;
02097 timer_addr = (volatile unsigned *)mmap(0, POFFMASK, PROT_READ,
02098 MAP_PRIVATE, fd, (int)page_addr);
02099 close(fd);
02100 if ((int)timer_addr == -1)
02101 return;
02102 vpc->timer_addr = (unsigned *)((unsigned)timer_addr + poff(phys_addr));
02103 #ifdef HAVE_64BIT_TIMER
02104 vpc->timer_addr++;
02105 printf("Timer configured for 64 bits.\n");
02106 #endif
02107 vpc->timer_usec_per_tick = timer_resolution * 1.0e-6;
02108 printf("Timer resolution is %d psec.\n", timer_resolution);
02109 }
02110 #endif