#include "shader.h" #include "miaux.h" #define RAMPSIZE 1024 typedef struct { int r_size, g_size, b_size; miScalar r[RAMPSIZE]; miScalar g[RAMPSIZE]; miScalar b[RAMPSIZE]; } channel_ramp_table; struct channel_ramp { int i_keys; int n_keys; miScalar keys[1]; int i_r; int n_r; miScalar r[1]; int i_g; int n_g; miScalar g[1]; int i_b; int n_b; miScalar b[1]; }; DLLEXPORT int channel_ramp_version(void) { return 1; } DLLEXPORT miBoolean channel_ramp_init( miState *state, struct channel_ramp *params, miBoolean *instance_init_required) { if (params == NULL) { /* Main shader init (not an instance) */ *instance_init_required = miTRUE; } else { /* Instance initialization */ int n_keys, n_r, n_g, n_b; miScalar *keys, *red, *green, *blue; channel_ramp_table *ramp; n_keys = *mi_eval_integer(¶ms->n_keys); keys = mi_eval_scalar(params->keys) + *mi_eval_integer(¶ms->i_keys); if ((n_r = *mi_eval_integer(¶ms->n_r)) != n_keys) mi_fatal("Incorrect number of red values: %d", n_r); red = mi_eval_scalar(params->r) + *mi_eval_integer(¶ms->i_r); if ((n_g = *mi_eval_integer(¶ms->n_g)) != n_keys) mi_fatal("Incorrect number of green values: %d", n_g); green = mi_eval_scalar(params->g) + *mi_eval_integer(¶ms->i_g); if ((n_b = *mi_eval_integer(¶ms->n_b)) != n_keys) mi_fatal("Incorrect number of blue values: %d", n_b); blue = mi_eval_scalar(params->b) + *mi_eval_integer(¶ms->i_b); ramp = miaux_user_memory_pointer(state, sizeof(channel_ramp_table)); miaux_piecewise_sinusoid(ramp->r, RAMPSIZE, n_keys, keys, red); miaux_piecewise_sinusoid(ramp->g, RAMPSIZE, n_keys, keys, green); miaux_piecewise_sinusoid(ramp->b, RAMPSIZE, n_keys, keys, blue); } return miTRUE; } DLLEXPORT miBoolean channel_ramp_exit(miState *state, void *params) { return miaux_release_user_memory("channel_ramp", state, params); } DLLEXPORT miBoolean channel_ramp ( miColor *result, miState *state, struct channel_ramp *params ) { miScalar altitude = miaux_altitude(state); channel_ramp_table *ramp = miaux_user_memory_pointer(state, 0); result->r = miaux_interpolated_lookup(ramp->r, RAMPSIZE, altitude); result->g = miaux_interpolated_lookup(ramp->g, RAMPSIZE, altitude); result->b = miaux_interpolated_lookup(ramp->b, RAMPSIZE, altitude); return miTRUE; }