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