nuclear@13: #include nuclear@13: #include nuclear@13: #include "unistate.h" nuclear@13: #include "shader.h" nuclear@13: #include "logger.h" nuclear@13: nuclear@13: struct StateItem { nuclear@13: StType type; nuclear@13: nuclear@13: union { nuclear@13: int ival[4]; nuclear@13: float fval[16]; nuclear@13: }; nuclear@13: int transpose; // for matrices nuclear@13: }; nuclear@13: nuclear@13: static const char *typestr(StType type); nuclear@13: static int type_nelem(StType type); nuclear@13: static StType float_type(int elem); nuclear@13: static StType int_type(int elem); nuclear@13: nuclear@13: std::vector state; nuclear@13: std::map stateidx; nuclear@13: nuclear@13: nuclear@13: int add_unistate(const char *name, StType type) nuclear@13: { nuclear@13: static const float ident3[] = {1, 0, 0, 0, 1, 0, 0, 0, 1}; nuclear@13: static const float ident4[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; nuclear@13: nuclear@13: if(stateidx.find(name) != stateidx.end()) { nuclear@13: return stateidx[name]; nuclear@13: } nuclear@13: nuclear@13: StateItem sitem; nuclear@13: memset(&sitem, 0, sizeof sitem); nuclear@13: sitem.type = type; nuclear@13: nuclear@13: // initialize to a reasonable default value nuclear@13: switch(type) { nuclear@13: case ST_MATRIX3: nuclear@13: memcpy(sitem.fval, ident3, sizeof ident3); nuclear@13: break; nuclear@13: nuclear@13: case ST_MATRIX4: nuclear@13: memcpy(sitem.fval, ident4, sizeof ident4); nuclear@13: break; nuclear@13: nuclear@13: default: nuclear@13: break; // in all other cases leave it zero (see memset above) nuclear@13: } nuclear@13: nuclear@13: int sidx = state.size(); nuclear@13: state.push_back(sitem); nuclear@13: stateidx[name] = sidx; nuclear@13: nuclear@13: debug_log("adding uniform state [%d]: %s %s\n", sidx, typestr(sitem.type), name); nuclear@13: nuclear@13: return sidx; nuclear@13: } nuclear@13: nuclear@13: int get_unistate_index(const char *name) nuclear@13: { nuclear@13: std::map::const_iterator it = stateidx.find(name); nuclear@13: if(it != stateidx.end()) { nuclear@13: return it->second; nuclear@13: } nuclear@13: return -1; nuclear@13: } nuclear@13: nuclear@13: #define CHECK_INDEX(i) \ nuclear@13: if(i < 0 || i >= (int)state.size()) return nuclear@13: nuclear@13: #define CHECK_COUNT(count, type) \ nuclear@13: do { \ nuclear@13: int max_elem = type_nelem(type); \ nuclear@13: if(!(count) || (count) > max_elem) { \ nuclear@13: count = max_elem; \ nuclear@13: } \ nuclear@13: } while(0) nuclear@13: nuclear@13: void set_unistate(int sidx, const int *val, int count) nuclear@13: { nuclear@13: CHECK_INDEX(sidx); nuclear@13: CHECK_COUNT(count, state[sidx].type); nuclear@13: nuclear@13: memcpy(state[sidx].ival, val, count * sizeof *state[sidx].ival); nuclear@13: } nuclear@13: nuclear@13: void set_unistate(int sidx, const float *val, int count) nuclear@13: { nuclear@13: CHECK_INDEX(sidx); nuclear@13: CHECK_COUNT(count, state[sidx].type); nuclear@13: nuclear@13: memcpy(state[sidx].fval, val, count * sizeof *state[sidx].fval); nuclear@13: state[sidx].transpose = 0; nuclear@13: } nuclear@13: nuclear@13: void get_unistate(int sidx, int *val, int count) nuclear@13: { nuclear@13: CHECK_INDEX(sidx); nuclear@13: CHECK_COUNT(count, state[sidx].type); nuclear@13: nuclear@13: memcpy(val, state[sidx].ival, count * sizeof *val); nuclear@13: } nuclear@13: nuclear@13: void get_unistate(int sidx, float *val, int count) nuclear@13: { nuclear@13: CHECK_INDEX(sidx); nuclear@13: CHECK_COUNT(count, state[sidx].type); nuclear@13: nuclear@13: memcpy(val, state[sidx].fval, count * sizeof *val); nuclear@13: } nuclear@13: nuclear@13: void set_unistate(int sidx, int val) nuclear@13: { nuclear@13: set_unistate(sidx, &val, 1); nuclear@13: } nuclear@13: nuclear@13: void set_unistate(int sidx, float val) nuclear@13: { nuclear@13: set_unistate(sidx, &val, 1); nuclear@13: } nuclear@13: nuclear@13: void set_unistate(int sidx, const Vector2 &vec) nuclear@13: { nuclear@13: set_unistate(sidx, &vec.x, 2); nuclear@13: } nuclear@13: nuclear@13: void set_unistate(int sidx, const Vector3 &vec) nuclear@13: { nuclear@13: set_unistate(sidx, &vec.x, 3); nuclear@13: } nuclear@13: nuclear@13: void set_unistate(int sidx, const Vector4 &vec) nuclear@13: { nuclear@13: set_unistate(sidx, &vec.x, 4); nuclear@13: } nuclear@13: nuclear@13: void set_unistate(int sidx, const Matrix3x3 &mat) nuclear@13: { nuclear@13: set_unistate(sidx, mat[0], 9); nuclear@13: state[sidx].transpose = 1; nuclear@13: } nuclear@13: nuclear@13: void set_unistate(int sidx, const Matrix4x4 &mat) nuclear@13: { nuclear@13: set_unistate(sidx, mat[0], 16); nuclear@13: state[sidx].transpose = 1; nuclear@13: } nuclear@13: nuclear@13: nuclear@13: int set_unistate(const char *name, int *val, int count) nuclear@13: { nuclear@13: int sidx = get_unistate_index(name); nuclear@13: if(sidx < 0) { nuclear@13: StType type = int_type(count); nuclear@13: if(type == ST_UNKNOWN) { nuclear@13: error_log("invalid element count (%d) while setting previously unknown unistate item \"%s\"\n", nuclear@13: count, name); nuclear@13: return -1; nuclear@13: } nuclear@13: nuclear@13: sidx = add_unistate(name, type); nuclear@13: } nuclear@13: set_unistate(sidx, val); nuclear@13: return sidx; nuclear@13: } nuclear@13: nuclear@13: int set_unistate(const char *name, float *val, int count) nuclear@13: { nuclear@13: int sidx = get_unistate_index(name); nuclear@13: if(sidx < 0) { nuclear@13: StType type = float_type(count); nuclear@13: if(type == ST_UNKNOWN) { nuclear@13: error_log("invalid element count (%d) while setting previously unknown unistate item \"%s\"\n", nuclear@13: count, name); nuclear@13: return -1; nuclear@13: } nuclear@13: nuclear@13: sidx = add_unistate(name, type); nuclear@13: } nuclear@13: set_unistate(sidx, val); nuclear@13: return sidx; nuclear@13: } nuclear@13: nuclear@13: int set_unistate(const char *name, int val) nuclear@13: { nuclear@13: int sidx = get_unistate_index(name); nuclear@13: if(sidx < 0) { nuclear@13: sidx = add_unistate(name, ST_INT); nuclear@13: } nuclear@13: set_unistate(sidx, val); nuclear@13: return sidx; nuclear@13: } nuclear@13: nuclear@13: int set_unistate(const char *name, float val) nuclear@13: { nuclear@13: int sidx = get_unistate_index(name); nuclear@13: if(sidx < 0) { nuclear@13: sidx = add_unistate(name, ST_FLOAT); nuclear@13: } nuclear@13: set_unistate(sidx, val); nuclear@13: return sidx; nuclear@13: } nuclear@13: nuclear@13: int set_unistate(const char *name, const Vector2 &vec) nuclear@13: { nuclear@13: int sidx = get_unistate_index(name); nuclear@13: if(sidx < 0) { nuclear@13: sidx = add_unistate(name, ST_FLOAT2); nuclear@13: } nuclear@13: set_unistate(sidx, vec); nuclear@13: return sidx; nuclear@13: } nuclear@13: nuclear@13: int set_unistate(const char *name, const Vector3 &vec) nuclear@13: { nuclear@13: int sidx = get_unistate_index(name); nuclear@13: if(sidx < 0) { nuclear@13: sidx = add_unistate(name, ST_FLOAT3); nuclear@13: } nuclear@13: set_unistate(sidx, vec); nuclear@13: return sidx; nuclear@13: } nuclear@13: nuclear@13: int set_unistate(const char *name, const Vector4 &vec) nuclear@13: { nuclear@13: int sidx = get_unistate_index(name); nuclear@13: if(sidx < 0) { nuclear@13: sidx = add_unistate(name, ST_FLOAT4); nuclear@13: } nuclear@13: set_unistate(sidx, vec); nuclear@13: return sidx; nuclear@13: } nuclear@13: nuclear@13: int set_unistate(const char *name, const Matrix3x3 &mat) nuclear@13: { nuclear@13: int sidx = get_unistate_index(name); nuclear@13: if(sidx < 0) { nuclear@13: sidx = add_unistate(name, ST_MATRIX3); nuclear@13: } nuclear@13: set_unistate(sidx, mat); nuclear@13: return sidx; nuclear@13: } nuclear@13: nuclear@13: int set_unistate(const char *name, const Matrix4x4 &mat) nuclear@13: { nuclear@13: int sidx = get_unistate_index(name); nuclear@13: if(sidx < 0) { nuclear@13: sidx = add_unistate(name, ST_MATRIX4); nuclear@13: } nuclear@13: set_unistate(sidx, mat); nuclear@13: return sidx; nuclear@13: } nuclear@13: nuclear@13: nuclear@13: int get_unistate_int(int sidx) nuclear@13: { nuclear@13: int val = 0; nuclear@13: get_unistate(sidx, &val, 1); nuclear@13: return val; nuclear@13: } nuclear@13: nuclear@13: float get_unistate_float(int sidx) nuclear@13: { nuclear@13: float val = 0.0f; nuclear@13: get_unistate(sidx, &val, 1); nuclear@13: return val; nuclear@13: } nuclear@13: nuclear@13: Vector2 get_unistate_vec2(int sidx) nuclear@13: { nuclear@13: float val[2] = {0.0f, 0.0f}; nuclear@13: get_unistate(sidx, val, 2); nuclear@13: return Vector2(val[0], val[1]); nuclear@13: } nuclear@13: nuclear@13: Vector3 get_unistate_vec3(int sidx) nuclear@13: { nuclear@13: float val[3] = {0.0f, 0.0f, 0.0f}; nuclear@13: get_unistate(sidx, val, 3); nuclear@13: return Vector3(val[0], val[1], val[2]); nuclear@13: } nuclear@13: nuclear@13: Vector4 get_unistate_vec4(int sidx) nuclear@13: { nuclear@13: float val[4] = {0.0f, 0.0f, 0.0f}; nuclear@13: get_unistate(sidx, val, 4); nuclear@13: return Vector4(val[0], val[1], val[2], val[3]); nuclear@13: } nuclear@13: nuclear@13: Matrix3x3 get_unistate_mat3(int sidx) nuclear@13: { nuclear@13: Matrix3x3 res; nuclear@13: get_unistate(sidx, res.m[0], 9); nuclear@13: return res; nuclear@13: } nuclear@13: nuclear@13: Matrix4x4 get_unistate_mat4(int sidx) nuclear@13: { nuclear@13: Matrix4x4 res; nuclear@13: get_unistate(sidx, res.m[0], 16); nuclear@13: return res; nuclear@13: } nuclear@13: nuclear@13: nuclear@13: int get_unistate_int(const char *name) nuclear@13: { nuclear@13: int sidx = get_unistate_index(name); nuclear@13: if(sidx == -1) { nuclear@13: return 0; nuclear@13: } nuclear@13: return get_unistate_int(sidx); nuclear@13: } nuclear@13: nuclear@13: float get_unistate_float(const char *name) nuclear@13: { nuclear@13: int sidx = get_unistate_index(name); nuclear@13: if(sidx == -1) { nuclear@13: return 0.0f; nuclear@13: } nuclear@13: return get_unistate_float(sidx); nuclear@13: } nuclear@13: nuclear@13: Vector2 get_unistate_vec2(const char *name) nuclear@13: { nuclear@13: int sidx = get_unistate_index(name); nuclear@13: if(sidx == -1) { nuclear@13: return Vector2(); nuclear@13: } nuclear@13: return get_unistate_vec2(sidx); nuclear@13: } nuclear@13: nuclear@13: Vector3 get_unistate_vec3(const char *name) nuclear@13: { nuclear@13: int sidx = get_unistate_index(name); nuclear@13: if(sidx == -1) { nuclear@13: return Vector3(); nuclear@13: } nuclear@13: return get_unistate_vec3(sidx); nuclear@13: } nuclear@13: nuclear@13: Vector4 get_unistate_vec4(const char *name) nuclear@13: { nuclear@13: int sidx = get_unistate_index(name); nuclear@13: if(sidx == -1) { nuclear@13: return Vector4(); nuclear@13: } nuclear@13: return get_unistate_vec4(sidx); nuclear@13: } nuclear@13: nuclear@13: Matrix3x3 get_unistate_mat3(const char *name) nuclear@13: { nuclear@13: int sidx = get_unistate_index(name); nuclear@13: if(sidx == -1) { nuclear@13: return Matrix3x3(); nuclear@13: } nuclear@13: return get_unistate_mat3(sidx); nuclear@13: } nuclear@13: nuclear@13: Matrix4x4 get_unistate_mat4(const char *name) nuclear@13: { nuclear@13: int sidx = get_unistate_index(name); nuclear@13: if(sidx == -1) { nuclear@13: return Matrix4x4(); nuclear@13: } nuclear@13: return get_unistate_mat4(sidx); nuclear@13: } nuclear@13: nuclear@13: nuclear@13: void setup_unistate(const ShaderProg *sdr) nuclear@13: { nuclear@13: if(!sdr) { nuclear@13: if(!(sdr = ShaderProg::current)) { nuclear@13: return; nuclear@13: } nuclear@13: } nuclear@13: nuclear@13: sdr->setup_state_uniforms(); nuclear@13: } nuclear@13: nuclear@13: bool setup_unistate(int sidx, const ShaderProg *sdr, int loc) nuclear@13: { nuclear@13: if(loc < 0 || sidx < 0 || sidx >= (int)state.size()) { nuclear@13: return false; nuclear@13: } nuclear@13: nuclear@13: CHECKGLERR; nuclear@13: glUseProgram(sdr->get_id()); nuclear@13: CHECKGLERR; nuclear@13: nuclear@13: switch(state[sidx].type) { nuclear@13: case ST_INT: nuclear@13: glUniform1iv(loc, 1, state[sidx].ival); nuclear@13: break; nuclear@13: case ST_INT2: nuclear@13: glUniform2iv(loc, 1, state[sidx].ival); nuclear@13: break; nuclear@13: case ST_INT3: nuclear@13: glUniform3iv(loc, 1, state[sidx].ival); nuclear@13: break; nuclear@13: case ST_INT4: nuclear@13: glUniform4iv(loc, 1, state[sidx].ival); nuclear@13: break; nuclear@13: nuclear@13: case ST_FLOAT: nuclear@13: glUniform1fv(loc, 1, state[sidx].fval); nuclear@13: break; nuclear@13: case ST_FLOAT2: nuclear@13: glUniform2fv(loc, 1, state[sidx].fval); nuclear@13: break; nuclear@13: case ST_FLOAT3: nuclear@13: glUniform3fv(loc, 1, state[sidx].fval); nuclear@13: break; nuclear@13: case ST_FLOAT4: nuclear@13: glUniform4fv(loc, 1, state[sidx].fval); nuclear@13: break; nuclear@13: nuclear@13: case ST_MATRIX3: nuclear@13: #ifdef GL_ES_VERSION_2_0 nuclear@13: { nuclear@13: float tmat[9], *ptr = tmat; nuclear@13: for(int i=0; i<3; i++) { nuclear@13: for(int j=0; j<3; j++) { nuclear@13: *ptr++ = state[sidx].fval[j * 3 + i]; nuclear@13: } nuclear@13: } nuclear@13: glUniformMatrix3fv(loc, 1, GL_FALSE, tmat); nuclear@13: } nuclear@13: #else nuclear@13: glUniformMatrix3fv(loc, 1, state[sidx].transpose, state[sidx].fval); nuclear@13: #endif nuclear@13: break; nuclear@13: nuclear@13: case ST_MATRIX4: nuclear@13: #ifdef GL_ES_VERSION_2_0 nuclear@13: { nuclear@13: float tmat[16], *ptr = tmat; nuclear@13: for(int i=0; i<4; i++) { nuclear@13: for(int j=0; j<4; j++) { nuclear@13: *ptr++ = state[sidx].fval[j * 4 + i]; nuclear@13: } nuclear@13: } nuclear@13: glUniformMatrix4fv(loc, 1, GL_FALSE, tmat); nuclear@13: } nuclear@13: #else nuclear@13: glUniformMatrix4fv(loc, 1, state[sidx].transpose, state[sidx].fval); nuclear@13: #endif nuclear@13: break; nuclear@13: nuclear@13: default: nuclear@13: return false; nuclear@13: } nuclear@13: nuclear@13: CHECKGLERR; nuclear@13: return true; nuclear@13: } nuclear@13: nuclear@13: bool setup_unistate(const char *name, const ShaderProg *sdr) nuclear@13: { nuclear@13: int loc = sdr->get_uniform_location(name); nuclear@13: if(loc == -1) { nuclear@13: return false; nuclear@13: } nuclear@13: return setup_unistate(get_unistate_index(name), sdr, loc); nuclear@13: } nuclear@13: nuclear@13: void set_world_matrix(const Matrix4x4 &mat) nuclear@13: { nuclear@13: static int sidx = -1, sidx_transp, sidx_mat3; nuclear@13: nuclear@13: if(sidx == -1) { nuclear@13: sidx = add_unistate("st_world_matrix", ST_MATRIX4); nuclear@13: sidx_mat3 = add_unistate("st_world_matrix3", ST_MATRIX3); nuclear@13: sidx_transp = add_unistate("st_world_matrix_transpose", ST_MATRIX4); nuclear@13: } nuclear@13: nuclear@13: set_unistate(sidx, mat); nuclear@13: set_unistate(sidx_mat3, Matrix3x3(mat)); nuclear@13: set_unistate(sidx_transp, mat[0]); // by using the float* variant, we unset the transpose flag nuclear@13: } nuclear@13: nuclear@13: void set_view_matrix(const Matrix4x4 &mat) nuclear@13: { nuclear@13: static int sidx = -1, sidx_transp, sidx_mat3; nuclear@13: nuclear@13: if(sidx == -1) { nuclear@13: sidx = add_unistate("st_view_matrix", ST_MATRIX4); nuclear@13: sidx_mat3 = add_unistate("st_view_matrix3", ST_MATRIX3); nuclear@13: sidx_transp = add_unistate("st_view_matrix_transpose", ST_MATRIX4); nuclear@13: } nuclear@13: nuclear@13: set_unistate(sidx, mat); nuclear@13: set_unistate(sidx_mat3, Matrix3x3(mat)); nuclear@13: set_unistate(sidx_transp, mat[0]); // by using the float* variant, we unset the transpose flag nuclear@13: } nuclear@13: nuclear@13: void set_projection_matrix(const Matrix4x4 &mat) nuclear@13: { nuclear@13: static int sidx = -1; nuclear@13: nuclear@13: if(sidx == -1) { nuclear@13: sidx = add_unistate("st_proj_matrix", ST_MATRIX4); nuclear@13: } nuclear@13: nuclear@13: set_unistate(sidx, mat); nuclear@13: } nuclear@13: nuclear@13: void set_texture_matrix(const Matrix4x4 &mat) nuclear@13: { nuclear@13: static int sidx = -1; nuclear@13: nuclear@13: if(sidx == -1) { nuclear@13: sidx = add_unistate("st_tex_matrix", ST_MATRIX4); nuclear@13: } nuclear@13: nuclear@13: set_unistate(sidx, mat); nuclear@13: } nuclear@13: nuclear@13: Matrix4x4 get_world_matrix() nuclear@13: { nuclear@13: static int sidx = -1; nuclear@13: nuclear@13: if(sidx == -1) { nuclear@13: if((sidx = get_unistate_index("st_world_matrix")) == -1) { nuclear@13: return Matrix4x4(); nuclear@13: } nuclear@13: } nuclear@13: return get_unistate_mat4(sidx); nuclear@13: } nuclear@13: nuclear@13: Matrix4x4 get_view_matrix() nuclear@13: { nuclear@13: static int sidx = -1; nuclear@13: nuclear@13: if(sidx == -1) { nuclear@13: if((sidx = get_unistate_index("st_view_matrix")) == -1) { nuclear@13: return Matrix4x4(); nuclear@13: } nuclear@13: } nuclear@13: return get_unistate_mat4(sidx); nuclear@13: } nuclear@13: nuclear@13: Matrix4x4 get_projection_matrix() nuclear@13: { nuclear@13: static int sidx = -1; nuclear@13: nuclear@13: if(sidx == -1) { nuclear@13: if((sidx = get_unistate_index("st_proj_matrix")) == -1) { nuclear@13: return Matrix4x4(); nuclear@13: } nuclear@13: } nuclear@13: return get_unistate_mat4(sidx); nuclear@13: } nuclear@13: nuclear@13: Matrix4x4 get_texture_matrix() nuclear@13: { nuclear@13: static int sidx = -1; nuclear@13: nuclear@13: if(sidx == -1) { nuclear@13: if((sidx = get_unistate_index("st_tex_matrix")) == -1) { nuclear@13: return Matrix4x4(); nuclear@13: } nuclear@13: } nuclear@13: return get_unistate_mat4(sidx); nuclear@13: } nuclear@13: nuclear@13: void setup_gl_matrices() nuclear@13: { nuclear@13: #ifdef USE_OLDGL nuclear@13: Matrix4x4 modelview = get_world_matrix() * get_view_matrix(); nuclear@13: Matrix4x4 proj = get_projection_matrix(); nuclear@13: Matrix4x4 tex = get_texture_matrix(); nuclear@13: nuclear@13: glMatrixMode(GL_TEXTURE); nuclear@13: glLoadTransposeMatrixf(tex[0]); nuclear@13: glMatrixMode(GL_PROJECTION); nuclear@13: glLoadTransposeMatrixf(proj[0]); nuclear@13: glMatrixMode(GL_MODELVIEW); nuclear@13: glLoadTransposeMatrixf(modelview[0]); nuclear@13: #endif nuclear@13: } nuclear@13: nuclear@13: static const char *typestr(StType type) nuclear@13: { nuclear@13: switch(type) { nuclear@13: case ST_INT: nuclear@13: return "int"; nuclear@13: case ST_INT2: nuclear@13: return "ivec2"; nuclear@13: case ST_INT3: nuclear@13: return "ivec3"; nuclear@13: case ST_INT4: nuclear@13: return "ivec4"; nuclear@13: case ST_FLOAT: nuclear@13: return "float"; nuclear@13: case ST_FLOAT2: nuclear@13: return "vec2"; nuclear@13: case ST_FLOAT3: nuclear@13: return "vec3"; nuclear@13: case ST_FLOAT4: nuclear@13: return "vec4"; nuclear@13: case ST_MATRIX3: nuclear@13: return "mat3"; nuclear@13: case ST_MATRIX4: nuclear@13: return "mat4"; nuclear@13: nuclear@13: default: nuclear@13: break; nuclear@13: } nuclear@13: return ""; nuclear@13: } nuclear@13: nuclear@13: static int type_nelem(StType type) nuclear@13: { nuclear@13: switch(type) { nuclear@13: case ST_INT: nuclear@13: case ST_FLOAT: nuclear@13: return 1; nuclear@13: case ST_INT2: nuclear@13: case ST_FLOAT2: nuclear@13: return 2; nuclear@13: case ST_INT3: nuclear@13: case ST_FLOAT3: nuclear@13: return 3; nuclear@13: case ST_INT4: nuclear@13: case ST_FLOAT4: nuclear@13: return 4; nuclear@13: case ST_MATRIX3: nuclear@13: return 9; nuclear@13: case ST_MATRIX4: nuclear@13: return 16; nuclear@13: nuclear@13: default: nuclear@13: break; nuclear@13: } nuclear@13: nuclear@13: return 0; nuclear@13: } nuclear@13: nuclear@13: static StType float_type(int elem) nuclear@13: { nuclear@13: switch(elem) { nuclear@13: case 1: nuclear@13: return ST_FLOAT; nuclear@13: case 2: nuclear@13: return ST_FLOAT2; nuclear@13: case 3: nuclear@13: return ST_FLOAT3; nuclear@13: case 4: nuclear@13: return ST_FLOAT4; nuclear@13: case 9: nuclear@13: return ST_MATRIX3; nuclear@13: case 16: nuclear@13: return ST_MATRIX4; nuclear@13: default: nuclear@13: break; nuclear@13: } nuclear@13: return ST_UNKNOWN; nuclear@13: } nuclear@13: nuclear@13: static StType int_type(int elem) nuclear@13: { nuclear@13: switch(elem) { nuclear@13: case 1: nuclear@13: return ST_INT; nuclear@13: case 2: nuclear@13: return ST_INT2; nuclear@13: case 3: nuclear@13: return ST_INT3; nuclear@13: case 4: nuclear@13: return ST_INT4; nuclear@13: default: nuclear@13: break; nuclear@13: } nuclear@13: return ST_UNKNOWN; nuclear@13: }