Max 5 API Reference
00001 #include "jit.gl.mesh.h" 00002 #include "jit.gl.cache.h" 00003 #include "jit.gl.cache.dl.h" 00004 #include "jit.gl.cache.var.h" 00005 #include "jit.gl.cache.vbo.h" 00006 #include "jit.gl.mesh.index.h" 00007 #include "jit.gl.mesh.colors.h" 00008 #include "jit.gl.mesh.normals.h" 00009 #include "jit.gl.mesh.tangents.h" 00010 00011 // -------------------------------------------------------------------------- 00012 00013 t_symbol *ps_jit_gl_mesh_index; 00014 t_symbol *ps_jit_gl_mesh_vertex; 00015 t_symbol *ps_jit_gl_mesh_position; 00016 t_symbol *ps_jit_gl_mesh_normal; 00017 t_symbol *ps_jit_gl_mesh_texcoord; 00018 t_symbol *ps_jit_gl_mesh_color; 00019 t_symbol *ps_jit_gl_mesh_diffuse; 00020 t_symbol *ps_jit_gl_mesh_specular; 00021 t_symbol *ps_jit_gl_mesh_edgeflag; 00022 t_symbol *ps_jit_gl_mesh_tangent; 00023 t_symbol *ps_jit_gl_mesh_bitangent; 00024 t_symbol *ps_jit_gl_mesh_index_matrix; 00025 t_symbol *ps_jit_gl_mesh_vertex_matrix; 00026 t_symbol *ps_jit_gl_mesh_normal_matrix; 00027 t_symbol *ps_jit_gl_mesh_texcoord_matrix; 00028 t_symbol *ps_jit_gl_mesh_color_matrix; 00029 t_symbol *ps_jit_gl_mesh_specular_matrix; 00030 t_symbol *ps_jit_gl_mesh_edgeflag_matrix; 00031 t_symbol *ps_jit_gl_mesh_tangent_matrix; 00032 t_symbol *ps_jit_gl_mesh_bitangent_matrix; 00033 t_symbol *ps_jit_gl_mesh_vertex_attr_matrix; 00034 t_symbol *ps_jit_gl_mesh_none; 00035 00036 t_symbol *ps_jit_gl_mesh_shader_attribute_position; 00037 t_symbol *ps_jit_gl_mesh_shader_attribute_normal; 00038 t_symbol *ps_jit_gl_mesh_shader_attribute_tangent; 00039 t_symbol *ps_jit_gl_mesh_shader_attribute_bitangent; 00040 t_symbol *ps_jit_gl_mesh_shader_attribute_texcoord; 00041 t_symbol *ps_jit_gl_mesh_shader_attribute_vertex_attr; 00042 00043 t_symbol *ps_jit_gl_mesh_lines_adjacency; 00044 t_symbol *ps_jit_gl_mesh_line_strip_adjacency; 00045 t_symbol *ps_jit_gl_mesh_triangles_adjacency; 00046 t_symbol *ps_jit_gl_mesh_triangle_strip_adjacency; 00047 00048 // -------------------------------------------------------------------------- 00049 00050 void *_jit_gl_mesh_class; 00051 00052 // -------------------------------------------------------------------------- 00053 00054 t_jit_err jit_gl_mesh_init(void) 00055 { 00056 long attrflags = 0; 00057 long ob3d_flags = 0; 00058 void *mop, *attr; 00059 void *ob3d; 00060 00061 // create class 00062 _jit_gl_mesh_class = jit_class_new("jit_gl_mesh",(method)jit_gl_mesh_new, (method)jit_gl_mesh_free, 00063 sizeof(t_jit_gl_mesh), A_DEFSYM, 0L); 00064 00065 // set up object extension for 3d object, customized with flags 00066 ob3d = jit_ob3d_setup(_jit_gl_mesh_class, 00067 calcoffset(t_jit_gl_mesh, ob3d), ob3d_flags); 00068 00069 // user transparent attributes 00070 attrflags = JIT_ATTR_GET_DEFER_LOW | JIT_ATTR_SET_USURP_LOW; 00071 attr = jit_object_new(_jit_sym_jit_attr_offset, "cache_mode", _jit_sym_symbol, attrflags, 00072 (method)0L, (method)jit_gl_mesh_setattr_cache_mode, calcoffset(t_jit_gl_mesh, cache_mode)); 00073 jit_class_addattr(_jit_gl_mesh_class, (t_jit_object*)attr); 00074 attr = jit_object_new(_jit_sym_jit_attr_offset, "draw_mode", _jit_sym_symbol, attrflags, 00075 (method)0L, (method)jit_gl_mesh_setattr_draw_mode, calcoffset(t_jit_gl_mesh, draw_mode)); 00076 jit_class_addattr(_jit_gl_mesh_class, (t_jit_object*)attr); 00077 attr = jit_object_new(_jit_sym_jit_attr_offset, "auto_normals", _jit_sym_long, attrflags, 00078 (method)0L, (method)jit_gl_mesh_setattr_auto_normals, calcoffset(t_jit_gl_mesh, auto_normals)); 00079 jit_class_addattr(_jit_gl_mesh_class, (t_jit_object*)attr); 00080 attr = jit_object_new(_jit_sym_jit_attr_offset, "auto_colors", _jit_sym_long, attrflags, 00081 (method)0L, (method)jit_gl_mesh_setattr_auto_colors, calcoffset(t_jit_gl_mesh, auto_colors)); 00082 jit_class_addattr(_jit_gl_mesh_class, (t_jit_object*)attr); 00083 attr = jit_object_new(_jit_sym_jit_attr_offset, "color_mode", _jit_sym_symbol, attrflags, 00084 (method)0L, (method)jit_gl_mesh_setattr_color_mode, calcoffset(t_jit_gl_mesh, color_mode)); 00085 jit_class_addattr(_jit_gl_mesh_class, (t_jit_object*)attr); 00086 attr = jit_object_new(_jit_sym_jit_attr_offset, "auto_tangents", _jit_sym_long, attrflags, 00087 (method)0L, (method)jit_gl_mesh_setattr_auto_tangents, calcoffset(t_jit_gl_mesh, auto_tangents)); 00088 jit_class_addattr(_jit_gl_mesh_class, (t_jit_object*)attr); 00089 attr = jit_object_new(_jit_sym_jit_attr_offset, "auto_bitangents", _jit_sym_long, attrflags, 00090 (method)0L, (method)jit_gl_mesh_setattr_auto_bitangents, calcoffset(t_jit_gl_mesh, auto_bitangents)); 00091 jit_class_addattr(_jit_gl_mesh_class, (t_jit_object*)attr); 00092 00093 00094 // ... 00095 00096 // user opaque attributes 00097 attrflags = JIT_ATTR_GET_OPAQUE_USER | JIT_ATTR_SET_OPAQUE_USER; 00098 attr = jit_object_new(_jit_sym_jit_attr_offset, "input_type", _jit_sym_long, attrflags, 00099 (method)0L, (method)jit_gl_mesh_setattr_input_type, calcoffset(t_jit_gl_mesh, input_type)); 00100 jit_class_addattr(_jit_gl_mesh_class, (t_jit_object*)attr); 00101 00102 // add ob3d methods 00103 jit_class_addmethod(_jit_gl_mesh_class, 00104 (method)jit_object_register, "register", A_CANT, 0L); 00105 jit_class_addmethod(_jit_gl_mesh_class, 00106 (method)jit_gl_mesh_draw, "ob3d_draw", A_CANT, 0L); 00107 jit_class_addmethod(_jit_gl_mesh_class, 00108 (method)jit_gl_mesh_dest_changed, "dest_changed", A_CANT, 0L); 00109 jit_class_addmethod(_jit_gl_mesh_class, 00110 (method)jit_gl_mesh_dest_closing, "dest_closing", A_CANT, 0L); 00111 00112 // add matrix methods 00113 jit_class_addmethod(_jit_gl_mesh_class, 00114 (method)jit_gl_mesh_jit_matrix, "jit_matrix", A_GIMME, 0L); 00115 jit_class_addmethod(_jit_gl_mesh_class, 00116 (method)jit_gl_mesh_jit_matrix, "index_matrix", A_GIMME, 0L); 00117 jit_class_addmethod(_jit_gl_mesh_class, 00118 (method)jit_gl_mesh_jit_matrix, "vertex_matrix", A_GIMME, 0L); 00119 jit_class_addmethod(_jit_gl_mesh_class, 00120 (method)jit_gl_mesh_jit_matrix, "normal_matrix", A_GIMME, 0L); 00121 jit_class_addmethod(_jit_gl_mesh_class, 00122 (method)jit_gl_mesh_jit_matrix, "texcoord_matrix", A_GIMME, 0L); 00123 jit_class_addmethod(_jit_gl_mesh_class, 00124 (method)jit_gl_mesh_jit_matrix, "color_matrix", A_GIMME, 0L); 00125 jit_class_addmethod(_jit_gl_mesh_class, 00126 (method)jit_gl_mesh_jit_matrix, "specular_matrix", A_GIMME, 0L); 00127 jit_class_addmethod(_jit_gl_mesh_class, 00128 (method)jit_gl_mesh_jit_matrix, "edgeflag_matrix", A_GIMME, 0L); 00129 jit_class_addmethod(_jit_gl_mesh_class, 00130 (method)jit_gl_mesh_jit_matrix, "tangent_matrix", A_GIMME, 0L); 00131 jit_class_addmethod(_jit_gl_mesh_class, 00132 (method)jit_gl_mesh_jit_matrix, "bitangent_matrix", A_GIMME, 0L); 00133 jit_class_addmethod(_jit_gl_mesh_class, 00134 (method)jit_gl_mesh_jit_matrix, "vertex_attr_matrix", A_GIMME, 0L); 00135 00136 // add geometry methods 00137 jit_class_addmethod(_jit_gl_mesh_class, 00138 (method)jit_gl_mesh_reset, "reset", A_DEFER_LOW, 0L); 00139 jit_class_addmethod(_jit_gl_mesh_class, 00140 (method)jit_gl_mesh_bind, "bind", A_DEFER_LOW, 0L); 00141 jit_class_addmethod(_jit_gl_mesh_class, 00142 (method)jit_gl_mesh_unbind, "unbind", A_DEFER_LOW, 0L); 00143 jit_class_addmethod(_jit_gl_mesh_class, 00144 (method)jit_gl_mesh_get_cache_by_name, "get_cache", A_DEFER_LOW, 0L); 00145 00146 jit_class_addmethod(_jit_gl_mesh_class, 00147 (method)jit_gl_mesh_rebuild, "rebuild", A_CANT, 0L); 00148 00149 // register class 00150 jit_class_register(_jit_gl_mesh_class); 00151 00152 // init cache 00153 jit_gl_cache_init(); 00154 00155 // generate symbols 00156 ps_jit_gl_mesh_index = gensym("index"); 00157 ps_jit_gl_mesh_position = gensym("position"); 00158 ps_jit_gl_mesh_vertex = gensym("vertex"); 00159 ps_jit_gl_mesh_normal = gensym("normal"); 00160 ps_jit_gl_mesh_texcoord = gensym("texcoord"); 00161 ps_jit_gl_mesh_color = gensym("color"); 00162 ps_jit_gl_mesh_diffuse = gensym("diffuse"); 00163 ps_jit_gl_mesh_specular = gensym("specular"); 00164 ps_jit_gl_mesh_edgeflag = gensym("edgeflag"); 00165 ps_jit_gl_mesh_tangent = gensym("tangent"); 00166 ps_jit_gl_mesh_bitangent = gensym("bitangent"); 00167 ps_jit_gl_mesh_index_matrix = gensym("index_matrix"); 00168 ps_jit_gl_mesh_vertex_matrix = gensym("vertex_matrix"); 00169 ps_jit_gl_mesh_normal_matrix = gensym("normal_matrix"); 00170 ps_jit_gl_mesh_texcoord_matrix = gensym("texcoord_matrix"); 00171 ps_jit_gl_mesh_color_matrix = gensym("color_matrix"); 00172 ps_jit_gl_mesh_specular_matrix = gensym("specular_matrix"); 00173 ps_jit_gl_mesh_edgeflag_matrix = gensym("edgeflag_matrix"); 00174 ps_jit_gl_mesh_tangent_matrix = gensym("tangent_matrix"); 00175 ps_jit_gl_mesh_bitangent_matrix = gensym("bitangent_matrix"); 00176 ps_jit_gl_mesh_vertex_attr_matrix = gensym("vertex_attr_matrix"); 00177 ps_jit_gl_mesh_none = gensym("none"); 00178 00179 ps_jit_gl_mesh_shader_attribute_position = gensym("POSITION"); 00180 ps_jit_gl_mesh_shader_attribute_normal = gensym("NORMAL"); 00181 ps_jit_gl_mesh_shader_attribute_tangent = gensym("TANGENT"); 00182 ps_jit_gl_mesh_shader_attribute_bitangent = gensym("BITANGENT"); 00183 ps_jit_gl_mesh_shader_attribute_texcoord = gensym("TEXCOORD"); 00184 ps_jit_gl_mesh_shader_attribute_vertex_attr = gensym("VERTEX_ATTR"); 00185 00186 ps_jit_gl_mesh_lines_adjacency = gensym("lines_adjacency"); 00187 ps_jit_gl_mesh_line_strip_adjacency = gensym("line_strip_adjacency"); 00188 ps_jit_gl_mesh_triangles_adjacency = gensym("triangles_adjacency"); 00189 ps_jit_gl_mesh_triangle_strip_adjacency = gensym("triangle_strip_adjacency"); 00190 00191 return JIT_ERR_NONE; 00192 } 00193 00194 t_jit_gl_mesh *jit_gl_mesh_new(t_symbol * dest_name) 00195 { 00196 long i; 00197 t_jit_gl_mesh *x; 00198 00199 if (x = (t_jit_gl_mesh *)jit_object_alloc(_jit_gl_mesh_class)) 00200 { 00201 00202 // create and attach ob3d 00203 jit_ob3d_new(x, dest_name); 00204 00205 x->update = TRUE; 00206 x->mode = JIT_GL_MESH_CACHE_NONE; 00207 x->cache_mode = ps_jit_gl_cache_auto; 00208 x->draw_mode = _jit_sym_gl_tri_grid; 00209 x->optimize = FALSE; 00210 x->id = -1; 00211 x->epsilon = 0.0001; 00212 00213 x->input_type = JIT_GL_MESH_VERTEX; 00214 00215 x->auto_index = FALSE; 00216 x->auto_normals = FALSE; 00217 x->auto_tangents = FALSE; 00218 x->auto_bitangents = FALSE; 00219 x->auto_colors = FALSE; 00220 x->color_mode = _jit_sym_nothing; 00221 00222 // allocate cache 00223 x->cache = (t_jit_gl_cache**)jit_getbytes(JIT_GL_MESH_MAX_INPUTCOUNT * sizeof(t_jit_gl_cache*)); 00224 if (!x->cache) 00225 return NULL; 00226 00227 // init cache 00228 for (i = 0; i < JIT_GL_MESH_MAX_INPUTCOUNT; i++) 00229 { 00230 x->cache[i] = jit_gl_cache_new(0, 0, 0); 00231 if (!x->cache[i]) 00232 return NULL; 00233 } 00234 00235 // allocate matrices 00236 x->input = (t_jit_object **)jit_getbytes(JIT_GL_MESH_MAX_INPUTCOUNT * sizeof(t_jit_object*)); 00237 if (!x->input) 00238 return NULL; 00239 00240 // init matrices 00241 for (i = 0; i < JIT_GL_MESH_MAX_INPUTCOUNT; i++) 00242 { 00243 x->input[i] = NULL; 00244 } 00245 00246 } 00247 else 00248 { 00249 x = NULL; 00250 } 00251 return x; 00252 } 00253 00254 void jit_gl_mesh_free(t_jit_gl_mesh *x) 00255 { 00256 long i; 00257 00258 if (jit_ob3d_set_context(x) == JIT_ERR_NONE) 00259 { 00260 // jit_gl_mesh_destroy(x); 00261 } 00262 00263 if (x->cache) 00264 { 00265 for (i = 0; i < JIT_GL_MESH_MAX_INPUTCOUNT; i++) 00266 { 00267 jit_gl_cache_free(x->cache[i]); 00268 } 00269 jit_freebytes(x->cache, JIT_GL_MESH_MAX_INPUTCOUNT * sizeof(t_jit_gl_cache*)); 00270 x->cache = NULL; 00271 } 00272 00273 if (x->input) 00274 { 00275 for (i = 0; i < JIT_GL_MESH_MAX_INPUTCOUNT; i++) 00276 { 00277 jit_object_free(x->input[i]); 00278 x->input[i] = NULL; 00279 } 00280 jit_freebytes(x->input, JIT_GL_MESH_MAX_INPUTCOUNT * sizeof(t_jit_object*)); 00281 x->input = NULL; 00282 } 00283 00284 jit_ob3d_free(x); 00285 } 00286 00287 // -------------------------------------------------------------------------- 00288 00289 00290 t_jit_err jit_gl_mesh_dest_closing(t_jit_gl_mesh *x) 00291 { 00292 long i; 00293 00294 // destroy buffer, keep cache data 00295 for (i = 0; i < JIT_GL_MESH_MAX_INPUTCOUNT; i++) 00296 { 00297 jit_gl_cache_buffer_destroy(x->cache[i]); 00298 } 00299 00300 return JIT_ERR_NONE; 00301 } 00302 00303 00304 t_jit_err jit_gl_mesh_draw(t_jit_gl_mesh *x) 00305 { 00306 t_jit_err result = JIT_ERR_NONE; 00307 00308 if (x->update) 00309 { 00310 jit_gl_mesh_recalc(x); 00311 } 00312 00313 if (!jit_attr_getlong(x, gensym("matrixoutput"))) 00314 { 00315 jit_gl_mesh_draw_cache(x); 00316 } 00317 else 00318 { 00319 // setup output matrix 00320 00321 //result = jit_ob3d_draw_chunk(x->ob3d, x->chunk); //output matrix 00322 } 00323 00324 return result; 00325 } 00326 00327 t_jit_err jit_gl_mesh_dest_changed(t_jit_gl_mesh *x) 00328 { 00329 x->update = TRUE; 00330 return JIT_ERR_NONE; 00331 } 00332 00333 t_jit_gl_cache *jit_gl_mesh_get_cache_by_name(t_jit_gl_mesh *x, t_symbol *name) 00334 { 00335 long i; 00336 t_jit_err err = JIT_ERR_NONE; 00337 00338 if (x) 00339 { 00340 if (name == ps_jit_gl_mesh_vertex || 00341 name == ps_jit_gl_mesh_position || 00342 name == ps_jit_gl_mesh_shader_attribute_position) 00343 { 00344 return x->cache[JIT_GL_MESH_VERTEX]; 00345 } 00346 else if(name == ps_jit_gl_mesh_texcoord || 00347 name == ps_jit_gl_mesh_shader_attribute_texcoord) 00348 { 00349 return x->cache[JIT_GL_MESH_TEXCOORD]; 00350 } 00351 else if(name == ps_jit_gl_mesh_normal || 00352 name == ps_jit_gl_mesh_shader_attribute_normal) 00353 { 00354 return x->cache[JIT_GL_MESH_NORMAL]; 00355 } 00356 else if(name == ps_jit_gl_mesh_tangent || 00357 name == ps_jit_gl_mesh_shader_attribute_tangent) 00358 { 00359 return x->cache[JIT_GL_MESH_TANGENT]; 00360 } 00361 else if(name == ps_jit_gl_mesh_bitangent || 00362 name == ps_jit_gl_mesh_shader_attribute_bitangent) 00363 { 00364 return x->cache[JIT_GL_MESH_BITANGENT]; 00365 } 00366 else if(name == ps_jit_gl_mesh_edgeflag) 00367 { 00368 return x->cache[JIT_GL_MESH_EDGEFLAG]; 00369 } 00370 else if(name == ps_jit_gl_mesh_vertex_attr_matrix || 00371 name == ps_jit_gl_mesh_shader_attribute_vertex_attr) 00372 { 00373 return x->cache[JIT_GL_MESH_VERTEX_ATTR]; 00374 } 00375 } 00376 00377 return NULL; 00378 } 00379 00380 // -------------------------------------------------------------------------- 00381 00382 t_jit_err jit_gl_mesh_recalc(t_jit_gl_mesh *x) 00383 { 00384 t_jit_err err; 00385 00386 x->enumtype = jit_gl_mesh_enumtype_from_sym(x->draw_mode); 00387 x->grid = (x->draw_mode == _jit_sym_gl_tri_grid) || (x->draw_mode == _jit_sym_gl_quad_grid); 00388 00389 err = jit_gl_mesh_rebuild(x); 00390 if (err) 00391 return err; 00392 00393 if (x->optimize) 00394 { 00395 err = jit_gl_mesh_optimize(x); 00396 if (err) 00397 return err; 00398 } 00399 00400 x->update = FALSE; 00401 return JIT_ERR_NONE; 00402 } 00403 00404 t_jit_err jit_gl_mesh_setattr_input_type(t_jit_gl_mesh *x, void *attr, long argc, t_atom *argv) 00405 { 00406 long i; 00407 long v; 00408 00409 if (x) 00410 { 00411 v = jit_atom_getlong(argv); 00412 if (x->input_type != v) 00413 { 00414 x->input_type = v; 00415 } 00416 return JIT_ERR_NONE; 00417 } 00418 return JIT_ERR_INVALID_PTR; 00419 } 00420 00421 t_jit_err jit_gl_mesh_setattr_cache_mode(t_jit_gl_mesh *x, void *attr, long argc, t_atom *argv) 00422 { 00423 long i; 00424 t_symbol *v; 00425 t_symbol *old; 00426 t_jit_err err = JIT_ERR_NONE; 00427 00428 if (x) 00429 { 00430 v = jit_atom_getsym(argv); 00431 if (x->cache_mode != v) 00432 { 00433 x->cache_mode = v; 00434 00435 // reset cache 00436 for (i = 0; i < JIT_GL_MESH_MAX_INPUTCOUNT; i++) 00437 { 00438 err = jit_gl_cache_reset(x->cache[i]); 00439 if (err) 00440 return err; 00441 } 00442 jit_gl_mesh_recalc(x); 00443 } 00444 return err; 00445 } 00446 return JIT_ERR_INVALID_PTR; 00447 } 00448 00449 t_jit_err jit_gl_mesh_setattr_color_mode(t_jit_gl_mesh *x, void *attr, long argc, t_atom *argv) 00450 { 00451 long i; 00452 t_symbol *v; 00453 t_symbol *old; 00454 t_jit_err err = JIT_ERR_NONE; 00455 00456 if (x) 00457 { 00458 v = jit_atom_getsym(argv); 00459 if (x->color_mode != v) 00460 { 00461 if ( v == ps_jit_gl_mesh_vertex || 00462 v == ps_jit_gl_mesh_position || 00463 v == ps_jit_gl_mesh_texcoord || 00464 v == ps_jit_gl_mesh_normal || 00465 v == ps_jit_gl_mesh_tangent || 00466 v == ps_jit_gl_mesh_bitangent || 00467 v == ps_jit_gl_mesh_edgeflag ) 00468 { 00469 x->color_mode = v; 00470 jit_gl_mesh_recalc(x); 00471 } 00472 else 00473 { 00474 jit_object_error((t_object *)x,"jit.gl.mesh: invalid color mode: '%s'", JIT_SYM_SAFECSTR(v)); 00475 } 00476 } 00477 return err; 00478 } 00479 return JIT_ERR_INVALID_PTR; 00480 } 00481 00482 t_jit_err jit_gl_mesh_setattr_draw_mode(t_jit_gl_mesh *x, void *attr, long argc, t_atom *argv) 00483 { 00484 long i; 00485 t_symbol *v; 00486 t_symbol *old; 00487 t_jit_err err = JIT_ERR_NONE; 00488 00489 if (x) 00490 { 00491 v = jit_atom_getsym(argv); 00492 if (x->draw_mode != v) 00493 { 00494 x->draw_mode = v; 00495 x->grid = (x->draw_mode == _jit_sym_gl_tri_grid) || (x->draw_mode == _jit_sym_gl_quad_grid); 00496 jit_gl_mesh_recalc(x); 00497 } 00498 return err; 00499 } 00500 return JIT_ERR_INVALID_PTR; 00501 } 00502 00503 t_jit_err jit_gl_mesh_setattr_auto_index(t_jit_gl_mesh *x, void *attr, long argc, t_atom *argv) 00504 { 00505 long i; 00506 long v; 00507 t_jit_err err = JIT_ERR_NONE; 00508 00509 if (x) 00510 { 00511 v = jit_atom_getlong(argv); 00512 if (x->auto_index != v) 00513 { 00514 x->auto_index = v; 00515 jit_gl_mesh_recalc(x); 00516 } 00517 return err; 00518 } 00519 return JIT_ERR_INVALID_PTR; 00520 } 00521 00522 t_jit_err jit_gl_mesh_setattr_auto_colors(t_jit_gl_mesh *x, void *attr, long argc, t_atom *argv) 00523 { 00524 long i; 00525 long v; 00526 t_jit_err err = JIT_ERR_NONE; 00527 00528 if (x) 00529 { 00530 v = jit_atom_getlong(argv); 00531 if (x->auto_colors != v) 00532 { 00533 x->auto_colors = v; 00534 jit_gl_mesh_recalc(x); 00535 } 00536 return err; 00537 } 00538 return JIT_ERR_INVALID_PTR; 00539 } 00540 00541 t_jit_err jit_gl_mesh_setattr_auto_normals(t_jit_gl_mesh *x, void *attr, long argc, t_atom *argv) 00542 { 00543 long i; 00544 long v; 00545 t_jit_err err = JIT_ERR_NONE; 00546 00547 if (x) 00548 { 00549 v = jit_atom_getlong(argv); 00550 if (x->auto_normals != v) 00551 { 00552 x->auto_normals = v; 00553 jit_gl_mesh_recalc(x); 00554 } 00555 return err; 00556 } 00557 return JIT_ERR_INVALID_PTR; 00558 } 00559 00560 t_jit_err jit_gl_mesh_setattr_auto_tangents(t_jit_gl_mesh *x, void *attr, long argc, t_atom *argv) 00561 { 00562 long i; 00563 long v; 00564 t_jit_err err = JIT_ERR_NONE; 00565 00566 if (x) 00567 { 00568 v = jit_atom_getlong(argv); 00569 if (x->auto_tangents != v) 00570 { 00571 x->auto_tangents = v; 00572 jit_gl_mesh_recalc(x); 00573 } 00574 return err; 00575 } 00576 return JIT_ERR_INVALID_PTR; 00577 } 00578 00579 t_jit_err jit_gl_mesh_setattr_auto_bitangents(t_jit_gl_mesh *x, void *attr, long argc, t_atom *argv) 00580 { 00581 long i; 00582 long v; 00583 t_jit_err err = JIT_ERR_NONE; 00584 00585 if (x) 00586 { 00587 v = jit_atom_getlong(argv); 00588 if (x->auto_bitangents != v) 00589 { 00590 x->auto_bitangents = v; 00591 jit_gl_mesh_recalc(x); 00592 } 00593 return err; 00594 } 00595 return JIT_ERR_INVALID_PTR; 00596 } 00597 00598 // -------------------------------------------------------------------------- 00599 00600 t_jit_err jit_gl_mesh_reset(t_jit_gl_mesh *x, t_symbol *s, int argc, t_atom *argv) 00601 { 00602 return JIT_ERR_NONE; 00603 } 00604 00605 t_jit_err jit_gl_mesh_jit_matrix(t_jit_gl_mesh *x, t_symbol *s, int argc, t_atom *argv) 00606 { 00607 t_jit_object *matrix; 00608 t_jit_err err = JIT_ERR_NONE; 00609 t_jit_matrix_info info; 00610 char *bp = NULL; 00611 t_jit_gl_cache *cache = NULL; 00612 t_symbol *matrix_name = jit_atom_getsym(argv); 00613 00614 00615 if (s != _jit_sym_jit_matrix) { 00616 if (s == ps_jit_gl_mesh_vertex_matrix) { 00617 x->input_type = JIT_GL_MESH_VERTEX; 00618 } else if (s == ps_jit_gl_mesh_texcoord_matrix) { 00619 x->input_type = JIT_GL_MESH_TEXCOORD; 00620 } else if (s == ps_jit_gl_mesh_normal_matrix) { 00621 x->input_type = JIT_GL_MESH_NORMAL; 00622 } else if (s == ps_jit_gl_mesh_color_matrix) { 00623 x->input_type = JIT_GL_MESH_COLOR; 00624 } else if (s == ps_jit_gl_mesh_specular_matrix) { 00625 x->input_type = JIT_GL_MESH_SPECULAR; 00626 } else if (s == ps_jit_gl_mesh_edgeflag_matrix) { 00627 x->input_type = JIT_GL_MESH_EDGEFLAG; 00628 } else if (s == ps_jit_gl_mesh_tangent_matrix) { 00629 x->input_type = JIT_GL_MESH_TANGENT; 00630 } else if (s == ps_jit_gl_mesh_bitangent_matrix) { 00631 x->input_type = JIT_GL_MESH_BITANGENT; 00632 } else if (s == ps_jit_gl_mesh_index_matrix) { 00633 x->input_type = JIT_GL_MESH_INDEX; 00634 } else if (s == ps_jit_gl_mesh_vertex_attr_matrix) { 00635 x->input_type = JIT_GL_MESH_VERTEX_ATTR; 00636 } 00637 // strip if user passes extra "jit_matrix" symbol 00638 if ((matrix_name == _jit_sym_jit_matrix) && (argc > 1)) { 00639 matrix_name = jit_atom_getsym(argv+1); 00640 } 00641 } 00642 00643 if (matrix_name) 00644 { 00645 matrix = (t_jit_object*)jit_object_findregistered(matrix_name); 00646 if (!matrix) 00647 { 00648 post ("jit.gl.mesh: couldn't get matrix object!"); 00649 return JIT_ERR_GENERIC; 00650 } 00651 00652 // get matrix info 00653 jit_object_method(matrix, _jit_sym_getinfo, &info); 00654 00655 if (x->input_type == JIT_GL_MESH_VERTEX && info.planecount >= 4 ) 00656 { 00657 // handle combined matrix formats on next recalc 00658 info.type = _jit_sym_float32; 00659 x->update = TRUE; 00660 } 00661 else 00662 { 00663 // get associated cache 00664 cache = jit_gl_mesh_get_cache_for_input(x, x->input_type); 00665 if (!cache) 00666 return JIT_ERR_INVALID_PTR; 00667 00668 // reset the cache 00669 err = jit_gl_cache_reset(cache); 00670 if (err) 00671 return err; 00672 00673 // convert input to conform to cache datatypes 00674 switch (x->input_type) 00675 { 00676 case JIT_GL_MESH_INDEX: 00677 { 00678 // supports datatypes: ubyte/ushort/uint 00679 if (info.type == _jit_sym_char) 00680 { 00681 cache->datatype = GL_UNSIGNED_BYTE; 00682 } 00683 else if (info.type == _jit_sym_long) 00684 { 00685 cache->datatype = GL_UNSIGNED_INT; 00686 } 00687 else if (info.type == _jit_sym_float32) 00688 { 00689 cache->datatype = GL_UNSIGNED_INT; 00690 info.type = _jit_sym_long; 00691 } 00692 else if (info.type == _jit_sym_float64) 00693 { 00694 cache->datatype = GL_UNSIGNED_INT; 00695 info.type = _jit_sym_long; 00696 } 00697 00698 // supports planes/coords: 1 00699 info.planecount = 1; 00700 break; 00701 } 00702 case JIT_GL_MESH_VERTEX: 00703 { 00704 // supports datatypes: short/int/float/double 00705 if (info.type == _jit_sym_char) 00706 { 00707 cache->datatype = GL_INT; 00708 info.type = _jit_sym_long; 00709 } 00710 else if (info.type == _jit_sym_long) 00711 { 00712 cache->datatype = GL_INT; 00713 } 00714 else if (info.type == _jit_sym_float32) 00715 { 00716 cache->datatype = GL_FLOAT; 00717 } 00718 else if (info.type == _jit_sym_float64) 00719 { 00720 cache->datatype = GL_DOUBLE; 00721 } 00722 00723 // supports planes/coords: 2/3/4 00724 info.planecount = JIT_MATH_CLAMP(info.planecount, 2, 3); 00725 break; 00726 } 00727 case JIT_GL_MESH_TEXCOORD: 00728 { 00729 // supports datatypes: short/int/float/double 00730 if (info.type == _jit_sym_char) 00731 { 00732 cache->datatype = GL_INT; 00733 info.type = _jit_sym_long; 00734 } 00735 else if (info.type == _jit_sym_long) 00736 { 00737 cache->datatype = GL_INT; 00738 } 00739 else if (info.type == _jit_sym_float32) 00740 { 00741 cache->datatype = GL_FLOAT; 00742 } 00743 else if (info.type == _jit_sym_float64) 00744 { 00745 cache->datatype = GL_DOUBLE; 00746 } 00747 00748 // supports planes/coords: 1/2/3/4 00749 info.planecount = JIT_MATH_CLAMP(info.planecount, 1, 4); 00750 break; 00751 } 00752 case JIT_GL_MESH_NORMAL: 00753 { 00754 // supports datatypes: byte/short/int/float/double 00755 if (info.type == _jit_sym_char) 00756 { 00757 // jitter chars are always unsigned which won't fit in a GL_BYTE -- convert to long 00758 cache->datatype = GL_INT; 00759 info.type = _jit_sym_long; 00760 } 00761 else if (info.type == _jit_sym_long) 00762 { 00763 cache->datatype = GL_INT; 00764 } 00765 else if (info.type == _jit_sym_float32) 00766 { 00767 cache->datatype = GL_FLOAT; 00768 } 00769 else if (info.type == _jit_sym_float64) 00770 { 00771 cache->datatype = GL_DOUBLE; 00772 } 00773 00774 // supports planes/coords: 3 00775 info.planecount = 3; 00776 break; 00777 } 00778 case JIT_GL_MESH_COLOR: 00779 { 00780 // supports datatypes: byte/ubyte/short/ushort/int/uint/float/double 00781 if (info.type == _jit_sym_char) 00782 { 00783 cache->datatype = GL_UNSIGNED_BYTE; 00784 } 00785 else if (info.type == _jit_sym_long) 00786 { 00787 cache->datatype = GL_INT; 00788 } 00789 else if (info.type == _jit_sym_float32) 00790 { 00791 cache->datatype = GL_FLOAT; 00792 } 00793 else if (info.type == _jit_sym_float64) 00794 { 00795 cache->datatype = GL_DOUBLE; 00796 } 00797 00798 // supports planes/coords: 3/4 00799 info.planecount = JIT_MATH_CLAMP(info.planecount, 3, 4); 00800 break; 00801 } 00802 case JIT_GL_MESH_EDGEFLAG: 00803 { 00804 // supports datatypes: bool 00805 cache->datatype = GL_BOOLEAN; 00806 info.type = _jit_sym_long; // convert to bool later 00807 00808 // supports planes/coords: 1 00809 info.planecount = 1; 00810 break; 00811 } 00812 case JIT_GL_MESH_TANGENT: 00813 { 00814 // supports datatypes: float/double 00815 if (info.type == _jit_sym_char) 00816 { 00817 cache->datatype = GL_FLOAT; 00818 info.type = _jit_sym_float32; 00819 } 00820 else if (info.type == _jit_sym_long) 00821 { 00822 cache->datatype = GL_FLOAT; 00823 info.type = _jit_sym_float32; 00824 } 00825 else if (info.type == _jit_sym_float32) 00826 { 00827 cache->datatype = GL_FLOAT; 00828 } 00829 else if (info.type == _jit_sym_float64) 00830 { 00831 cache->datatype = GL_DOUBLE; 00832 } 00833 00834 // supports planes/coords: 4 00835 info.planecount = 4; 00836 break; 00837 } 00838 case JIT_GL_MESH_BITANGENT: 00839 { 00840 // supports datatypes: float/double 00841 if (info.type == _jit_sym_char) 00842 { 00843 cache->datatype = GL_FLOAT; 00844 info.type = _jit_sym_float32; 00845 } 00846 else if (info.type == _jit_sym_long) 00847 { 00848 cache->datatype = GL_FLOAT; 00849 info.type = _jit_sym_float32; 00850 } 00851 else if (info.type == _jit_sym_float32) 00852 { 00853 cache->datatype = GL_FLOAT; 00854 } 00855 else if (info.type == _jit_sym_float64) 00856 { 00857 cache->datatype = GL_DOUBLE; 00858 } 00859 00860 // supports planes/coords: 4 00861 info.planecount = 4; 00862 break; 00863 } 00864 case JIT_GL_MESH_VERTEX_ATTR: 00865 { 00866 // supports datatypes: byte/ubyte/short/ushort/int/uint/float/double 00867 if (info.type == _jit_sym_char) 00868 { 00869 cache->datatype = GL_UNSIGNED_BYTE; 00870 } 00871 else if (info.type == _jit_sym_long) 00872 { 00873 cache->datatype = GL_INT; 00874 } 00875 else if (info.type == _jit_sym_float32) 00876 { 00877 cache->datatype = GL_FLOAT; 00878 } 00879 else if (info.type == _jit_sym_float64) 00880 { 00881 cache->datatype = GL_DOUBLE; 00882 } 00883 00884 // supports any planecount 00885 break; 00886 } 00887 default: 00888 jit_object_error((t_object *)x,"jit.gl.mesh: invalid input type"); 00889 err = JIT_ERR_GENERIC; 00890 break; 00891 }; 00892 } 00893 00894 if (!err) 00895 { 00896 // restrict dimcount 00897 if (info.dimcount > 2) 00898 info.dimcount = 2; 00899 00900 if (!x->input[x->input_type]) 00901 { 00902 x->input[x->input_type] = (t_jit_object*)jit_object_new(gensym("jit_matrix"), NULL); 00903 if (!x->input[x->input_type]) 00904 return JIT_ERR_INVALID_PTR; 00905 } 00906 00907 // copy incoming matrix to local input cache 00908 jit_object_method(x->input[x->input_type], _jit_sym_setinfo, &info); 00909 jit_object_method(x->input[x->input_type], _jit_sym_frommatrix, matrix, NULL); 00910 00911 // toggle update and used flags for cache 00912 if (cache) 00913 { 00914 cache->update = TRUE; 00915 cache->used = TRUE; 00916 } 00917 x->update = TRUE; 00918 } 00919 } 00920 return JIT_ERR_NONE; 00921 } 00922 00923 t_jit_err jit_gl_mesh_determine_mode(t_jit_gl_mesh *x) 00924 { 00925 t_jit_err err = JIT_ERR_NONE; 00926 00927 if (!x) 00928 return JIT_ERR_INVALID_PTR; 00929 00930 // get cache type from symbol 00931 x->mode = jit_gl_mesh_mode_from_sym(x->cache_mode); 00932 00933 // test system support for indicated cache type 00934 switch (x->mode) 00935 { 00936 case JIT_GL_MESH_CACHE_AUTO: 00937 case JIT_GL_MESH_CACHE_VERTEXBUFFER: 00938 { 00939 // verify system support for vertex buffer objects 00940 err = jit_gl_mesh_verify_extensions(x, pb_jit_gl_cache_vbo_required_ext); 00941 if (!err) 00942 { 00943 // use vertex buffer objects 00944 x->mode = JIT_GL_MESH_CACHE_VERTEXBUFFER; 00945 } 00946 else 00947 { 00948 // fallback to uncached vertex arrays 00949 x->mode = JIT_GL_MESH_CACHE_VERTEXARRAY; 00950 } 00951 break; 00952 } 00953 case JIT_GL_MESH_CACHE_VERTEXARRAY: 00954 case JIT_GL_MESH_CACHE_NONE: 00955 { 00956 // use uncached vertex arrays 00957 x->mode = JIT_GL_MESH_CACHE_VERTEXARRAY; 00958 break; 00959 } 00960 case JIT_GL_MESH_CACHE_DISPLAYLIST: 00961 { 00962 // use uncached vertex arrays 00963 x->mode = JIT_GL_MESH_CACHE_DISPLAYLIST; 00964 break; 00965 } 00966 default: 00967 { 00968 jit_object_error((t_object *)x,"jit.gl.mesh: invalid cache type"); 00969 err = JIT_ERR_GENERIC; 00970 } 00971 } 00972 00973 00974 if(jit_gl_get_context()) 00975 err = jit_gl_mesh_init_cache(x); 00976 00977 return err; 00978 } 00979 00980 t_jit_err jit_gl_mesh_draw_cache(t_jit_gl_mesh *x) 00981 { 00982 long i; 00983 long mode = 0; 00984 t_jit_err error = JIT_ERR_NONE; 00985 00986 if (!x->cache[JIT_GL_MESH_VERTEX]->used) 00987 return JIT_ERR_NONE; 00988 00989 /* 00990 // debug drawing in immediate mode 00991 glBegin(x->enumtype); 00992 for(i = 0; i < x->cache[JIT_GL_MESH_VERTEX]->elements; i++) 00993 glVertex3fv(&((float*)x->cache[JIT_GL_MESH_VERTEX]->data)[i * 3]); 00994 glEnd(); 00995 return JIT_ERR_NONE; 00996 */ 00997 00998 switch (x->mode) 00999 { 01000 case JIT_GL_MESH_CACHE_AUTO: 01001 { 01002 // get best mode for system 01003 error = jit_gl_mesh_determine_mode(x); 01004 if (error) 01005 return error; 01006 01007 // try again 01008 return jit_gl_mesh_draw(x); 01009 } 01010 case JIT_GL_MESH_CACHE_DISPLAYLIST: 01011 error = jit_gl_cache_draw_dl(x); 01012 break; 01013 case JIT_GL_MESH_CACHE_VERTEXBUFFER: 01014 error = jit_gl_cache_draw_vbo(x); 01015 break; 01016 case JIT_GL_MESH_CACHE_VERTEXARRAY: 01017 case JIT_GL_MESH_CACHE_NONE: 01018 default: 01019 error = jit_gl_cache_draw_var(x); 01020 break; 01021 }; 01022 01023 jit_gl_report_error("jit.gl.mesh: drawing geometry"); 01024 return error; 01025 } 01026 01027 t_jit_err jit_gl_mesh_init_cache(t_jit_gl_mesh *x) 01028 { 01029 long i; 01030 long mode = 0; 01031 t_jit_err error = JIT_ERR_NONE; 01032 01033 switch (x->mode) 01034 { 01035 case JIT_GL_MESH_CACHE_AUTO: 01036 { 01037 // get best mode for system 01038 error = jit_gl_mesh_determine_mode(x); 01039 if (error) 01040 return error; 01041 01042 // try again 01043 return jit_gl_mesh_init_cache(x); 01044 } 01045 case JIT_GL_MESH_CACHE_DISPLAYLIST: 01046 error = jit_gl_cache_init_dl(x); 01047 break; 01048 case JIT_GL_MESH_CACHE_VERTEXBUFFER: 01049 error = jit_gl_cache_init_vbo(x); 01050 break; 01051 case JIT_GL_MESH_CACHE_VERTEXARRAY: 01052 case JIT_GL_MESH_CACHE_NONE: 01053 default: 01054 error = jit_gl_cache_init_var(x); 01055 break; 01056 }; 01057 01058 jit_gl_report_error("jit.gl.mesh: initializing geometry cache"); 01059 return error; 01060 } 01061 01062 t_jit_err jit_gl_mesh_bind(t_jit_gl_mesh *x, t_symbol *s, int argc, t_atom *argv) 01063 { 01064 long i; 01065 long mode = 0; 01066 t_jit_err error = JIT_ERR_NONE; 01067 01068 switch (x->mode) 01069 { 01070 case JIT_GL_MESH_CACHE_AUTO: 01071 { 01072 // get best mode for system 01073 error = jit_gl_mesh_determine_mode(x); 01074 if (error) 01075 return error; 01076 01077 // try again 01078 return jit_gl_mesh_bind(x, s, argc, argv); 01079 } 01080 case JIT_GL_MESH_CACHE_DISPLAYLIST: 01081 error = jit_gl_cache_bind_dl(x); 01082 break; 01083 case JIT_GL_MESH_CACHE_VERTEXBUFFER: 01084 error = jit_gl_cache_bind_vbo(x); 01085 break; 01086 case JIT_GL_MESH_CACHE_VERTEXARRAY: 01087 case JIT_GL_MESH_CACHE_NONE: 01088 default: 01089 error = jit_gl_cache_bind_var(x); 01090 break; 01091 }; 01092 01093 jit_gl_report_error("jit.gl.mesh: binding geometry"); 01094 return error; 01095 } 01096 01097 t_jit_err jit_gl_mesh_unbind(t_jit_gl_mesh *x, t_symbol *s, int argc, t_atom *argv) 01098 { 01099 long i; 01100 t_jit_err error = JIT_ERR_NONE; 01101 01102 switch (x->mode) 01103 { 01104 case JIT_GL_MESH_CACHE_AUTO: 01105 { 01106 // get best mode for system 01107 error = jit_gl_mesh_determine_mode(x); 01108 if (error) 01109 return error; 01110 01111 // try again 01112 return jit_gl_mesh_unbind(x, s, argc, argv); 01113 } 01114 case JIT_GL_MESH_CACHE_DISPLAYLIST: 01115 error = jit_gl_cache_unbind_dl(x); 01116 break; 01117 case JIT_GL_MESH_CACHE_VERTEXBUFFER: 01118 error = jit_gl_cache_unbind_vbo(x); 01119 break; 01120 case JIT_GL_MESH_CACHE_VERTEXARRAY: 01121 case JIT_GL_MESH_CACHE_NONE: 01122 default: 01123 error = jit_gl_cache_unbind_var(x); 01124 break; 01125 }; 01126 01127 jit_gl_report_error("jit.gl.mesh: unbinding geometry"); 01128 return error; 01129 } 01130 01131 t_jit_gl_cache* jit_gl_mesh_get_cache_for_input(t_jit_gl_mesh *x, long input) 01132 { 01133 switch (input) 01134 { 01135 case JIT_GL_MESH_INDEX: 01136 case JIT_GL_MESH_VERTEX: 01137 case JIT_GL_MESH_TEXCOORD: 01138 case JIT_GL_MESH_NORMAL: 01139 case JIT_GL_MESH_DIFFUSE: 01140 case JIT_GL_MESH_SPECULAR: 01141 case JIT_GL_MESH_EDGEFLAG: 01142 case JIT_GL_MESH_TANGENT: 01143 case JIT_GL_MESH_BITANGENT: 01144 case JIT_GL_MESH_VERTEX_ATTR: 01145 { 01146 return x->cache[input]; 01147 } 01148 default: 01149 { 01150 jit_object_error((t_object *)x,"jit.gl.mesh: no cache associated with given input type!"); 01151 return NULL; 01152 } 01153 }; 01154 01155 return NULL; 01156 } 01157 01158 t_jit_err jit_gl_mesh_destroy(t_jit_gl_mesh *x) 01159 { 01160 return JIT_ERR_NONE; 01161 } 01162 01163 t_jit_err jit_gl_mesh_rebuild(t_jit_gl_mesh *x) 01164 { 01165 long i; 01166 GLuint id, s, e; 01167 char *bp = NULL; 01168 t_jit_gl_cache *vertexcache = NULL; 01169 t_jit_gl_cache *cache = NULL; 01170 long buffer, buffertype, type, typesize; 01171 long offset, stride, width, height, coords, count; 01172 long colstride, rowstride, iters, size; 01173 01174 01175 GLubyte *glub; 01176 GLuint *glui; 01177 01178 t_jit_err err = JIT_ERR_NONE; 01179 01180 t_jit_object *matrix; 01181 t_jit_matrix_info info; 01182 01183 if (!x) 01184 return JIT_ERR_GENERIC; 01185 01186 for (i = 0; i < JIT_GL_MESH_MAX_INPUTCOUNT; i++) 01187 { 01188 // set the buffer index 01189 buffer = i; 01190 01191 // get the next input matrix 01192 matrix = x->input[i]; 01193 if (!matrix) 01194 continue; 01195 01196 x->enumtype = jit_gl_mesh_enumtype_from_sym(x->draw_mode); 01197 x->grid = (x->draw_mode == _jit_sym_gl_tri_grid) || (x->draw_mode == _jit_sym_gl_quad_grid); 01198 01199 // get the matrix data and info 01200 jit_object_method(matrix, _jit_sym_getinfo, &info); 01201 jit_object_method(matrix, _jit_sym_getdata, &bp); 01202 01203 // skip any invalid data 01204 if (!bp) 01205 return JIT_ERR_INVALID_PTR; 01206 01207 // process each cache 01208 if (i == JIT_GL_MESH_VERTEX && info.planecount >= 4 ) 01209 { 01210 // handle combined matrix formats 01211 err = jit_gl_mesh_from_matrix(x, matrix); 01212 if (err) 01213 return err; 01214 } 01215 else 01216 { 01217 // get the cache for this input 01218 cache = x->cache[i]; 01219 01220 // skip any unused cache 01221 if (!cache->used) 01222 continue; 01223 01224 // init from matrix info 01225 err = jit_gl_mesh_init_cache_from_matrix_info(x, cache, &info); 01226 if (err) 01227 return err; 01228 01229 // fill cache 01230 err = jit_gl_mesh_fill_cache(x, cache, &info, bp, 0, info.planecount, TRUE); 01231 if (err) 01232 return err; 01233 } 01234 } 01235 01236 // generate requested data 01237 if (!x->optimize && x->cache[JIT_GL_MESH_VERTEX]->used && x->cache[JIT_GL_MESH_VERTEX]->elements) 01238 { 01239 if (x->auto_index) 01240 { 01241 // err = jit_gl_mesh_generate_indices(x); 01242 if (err) 01243 { 01244 jit_object_error((t_object *)x,"jit.gl.mesh: failed to auto generate indices!"); 01245 } 01246 } 01247 if(x->auto_normals) 01248 { 01249 err = jit_gl_mesh_generate_normals(x); 01250 if (err) 01251 { 01252 jit_object_error((t_object *)x,"jit.gl.mesh: failed to auto generate normals!"); 01253 } 01254 } 01255 if (x->auto_tangents || x->auto_bitangents) 01256 { 01257 err = jit_gl_mesh_generate_tangentspace(x, x->auto_tangents, x->auto_bitangents, FALSE); 01258 if (err) 01259 { 01260 jit_object_error((t_object *)x,"jit.gl.mesh: failed to auto generate tangents!"); 01261 } 01262 } 01263 if (x->auto_colors) 01264 { 01265 err = jit_gl_mesh_generate_colors(x); 01266 if (err) 01267 { 01268 jit_object_error((t_object *)x,"jit.gl.mesh: failed to auto generate colors!"); 01269 } 01270 } 01271 } 01272 x->update = FALSE; 01273 return JIT_ERR_NONE; 01274 } 01275 01276 t_jit_err jit_gl_mesh_optimize(t_jit_gl_mesh *x) 01277 { 01278 /* 01279 long grid = 0; 01280 t_jit_err err = JIT_ERR_NONE; 01281 01282 long nvcount = 0; 01283 unsigned short nvprimcount = 0; 01284 unsigned short *nvindex = NULL; 01285 PrimitiveGroup *nvprims = NULL; 01286 01287 t_jit_gl_cache *indexcache = x->cache[JIT_GL_MESH_INDEX]; 01288 t_jit_gl_cache *vertexcache = x->cache[JIT_GL_MESH_VERTEX]; 01289 t_jit_gl_cache *normalcache = x->cache[JIT_GL_MESH_NORMAL]; 01290 t_jit_gl_cache *texcoordcache = x->cache[JIT_GL_MESH_TEXCOORD]; 01291 t_jit_gl_cache *tangentcache = x->cache[JIT_GL_MESH_TANGENT]; 01292 t_jit_gl_cache *bitangentcache = x->cache[JIT_GL_MESH_BITANGENT]; 01293 01294 // determine grid mode 01295 if ((x->draw_mode == _jit_sym_gl_tri_grid) || (x->draw_mode == _jit_sym_gl_quad_grid)) 01296 { 01297 grid = 1; 01298 } 01299 else 01300 { 01301 grid = 0; 01302 } 01303 01304 // do optimization 01305 if( vertexcache->used && vertexcache->data && texcoordcache->used && texcoordcache->data) 01306 { 01307 // generate indices 01308 if(!indexcache || !indexcache->used) 01309 jit_gl_mesh_generate_indices(x); 01310 01311 // create a new mesh object 01312 t_jit_gl_mesh *mesh = jit_gl_mesh_new(); 01313 if(!mesh) return JIT_ERR_GENERIC; 01314 01315 // generate connectivity 01316 jit_gl_mesh_build(mesh, (float*)vertexcache->data, vertexcache->count, (long*)indexcache->data, indexcache->count); 01317 01318 // reorder index cache 01319 for (long i = 0; i < indexcache->count / 3; i++) 01320 { 01321 if (indexcache->datatype == GL_UNSIGNED_BYTE) 01322 { 01323 ((GLubyte*)indexcache->data)[i + 0] = mesh->triangle[i].v[0]; 01324 ((GLubyte*)indexcache->data)[i + 1] = mesh->triangle[i].v[1]; 01325 ((GLubyte*)indexcache->data)[i + 2] = mesh->triangle[i].v[2]; 01326 } 01327 else if (indexcache->datatype == GL_UNSIGNED_INT) 01328 { 01329 ((GLuint*)indexcache->data)[i + 0] = mesh->triangle[i].v[0]; 01330 ((GLuint*)indexcache->data)[i + 1] = mesh->triangle[i].v[1]; 01331 ((GLuint*)indexcache->data)[i + 2] = mesh->triangle[i].v[2]; 01332 } 01333 01334 } 01335 01336 // generate the tristrip index 01337 nvcount = indexcache->count; 01338 nvindex = (unsigned short*)jit_getbytes(indexcache->count * sizeof(unsigned short)); 01339 if (!nvindex) 01340 { 01341 jit_object_error((t_object *)x,"jit.gl.mesh: optimization failed -- out of memory!"); 01342 return JIT_ERR_INVALID_PTR; 01343 } 01344 01345 for (long i = 0; i < indexcache->count; i++) 01346 { 01347 unsigned short index = 0; 01348 if (indexcache->datatype == GL_UNSIGNED_BYTE) 01349 { 01350 index = ((GLubyte*)indexcache->data)[i]; 01351 } 01352 else if (indexcache->datatype == GL_UNSIGNED_INT) 01353 { 01354 index = ((GLuint*)indexcache->data)[i]; 01355 } 01356 01357 // clamp the index 01358 index = JIT_MATH_CLAMP(index, 0, vertexcache->count); 01359 nvindex[i] = index; 01360 } 01361 01362 // generate tri stips 01363 bool status = GenerateStrips(nvindex, nvcount, &nvprims, &nvprimcount, true); 01364 if (!status) 01365 { 01366 jit_object_error((t_object *)x,"jit.gl.mesh: optimization failed -- unable to generate tri strips!"); 01367 return JIT_ERR_GENERIC; 01368 } 01369 01370 // fill optimizer 01371 MeshMender optimizer; 01372 std::vector< MeshMender::Vertex > vertices; 01373 std::vector< unsigned int > indices; 01374 std::vector< unsigned int > results; 01375 01376 for (long i = 0; i < vertexcache->count; i++) 01377 { 01378 MeshMender::Vertex v; 01379 01380 // get the vertex position 01381 if (vertexcache->datatype == GL_INT) 01382 { 01383 for (long d = 0; d < 3 && d < vertexcache->coords; d++) 01384 v.pos[d] = ((GLint*)vertexcache->data)[i * vertexcache->coords + d]; 01385 } 01386 else if (vertexcache->datatype == GL_FLOAT) 01387 { 01388 for (long d = 0; d < 3 && d < vertexcache->coords; d++) 01389 v.pos[d] = ((GLfloat*)vertexcache->data)[i * vertexcache->coords + d]; 01390 } 01391 else if (vertexcache->datatype == GL_DOUBLE) 01392 { 01393 for (long d = 0; d < 3 && d < vertexcache->coords; d++) 01394 v.pos[d] = ((GLdouble*)vertexcache->data)[i * vertexcache->coords + d]; 01395 } 01396 01397 // get the texture coordinates 01398 if (texcoordcache && texcoordcache->used && i < texcoordcache->count) 01399 { 01400 if (texcoordcache->datatype == GL_INT) 01401 { 01402 v.s = ((GLint*)texcoordcache->data)[i * texcoordcache->coords + 0]; 01403 v.t = ((GLint*)texcoordcache->data)[i * texcoordcache->coords + 1]; 01404 } 01405 else if (texcoordcache->datatype == GL_FLOAT) 01406 { 01407 v.s = ((GLfloat*)texcoordcache->data)[i * texcoordcache->coords + 0]; 01408 v.t = ((GLfloat*)texcoordcache->data)[i * texcoordcache->coords + 1]; 01409 } 01410 else if (texcoordcache->datatype == GL_DOUBLE) 01411 { 01412 v.s = ((GLdouble*)texcoordcache->data)[i * texcoordcache->coords + 0]; 01413 v.t = ((GLdouble*)texcoordcache->data)[i * texcoordcache->coords + 1]; 01414 } 01415 } 01416 01417 // get the vertex position 01418 if (normalcache && normalcache->used && i < normalcache->count) 01419 { 01420 if (normalcache->datatype == GL_INT) 01421 { 01422 for (long d = 0; d < 3 && d < normalcache->coords; d++) 01423 v.normal[d] = ((GLint*)normalcache->data)[i * normalcache->coords + d]; 01424 } 01425 else if (normalcache->datatype == GL_FLOAT) 01426 { 01427 for (long d = 0; d < 3 && d < normalcache->coords; d++) 01428 v.normal[d] = ((GLfloat*)normalcache->data)[i * normalcache->coords + d]; 01429 } 01430 else if (normalcache->datatype == GL_DOUBLE) 01431 { 01432 for (long d = 0; d < 3 && d < normalcache->coords; d++) 01433 v.normal[d] = ((GLdouble*)normalcache->data)[i * normalcache->coords + d]; 01434 } 01435 } 01436 01437 // add vertex to list 01438 vertices.push_back(v); 01439 01440 } 01441 01442 for (unsigned short i = 0; i < nvprimcount; i++) 01443 { 01444 for (unsigned short j = 0; j < nvprims[i].numIndices; j++) 01445 { 01446 indices.push_back(nvprims[i].indices[j]); 01447 } 01448 } 01449 // get the index if specified 01450 if(indexcache && indexcache->used) 01451 { 01452 for(long i = 0; i < vertexcache->count; i++) 01453 { 01454 long index = i; 01455 if(indexcache->datatype == GL_UNSIGNED_BYTE) 01456 { 01457 index = ((GLubyte*)indexcache->data)[i]; 01458 } 01459 else if(indexcache->datatype == GL_UNSIGNED_INT) 01460 { 01461 index = ((GLuint*)indexcache->data)[i]; 01462 } 01463 01464 // clamp the index 01465 index = JIT_MATH_CLAMP(index, 0, vertexcache->count); 01466 indices.push_back(index); 01467 } 01468 01469 } 01470 else 01471 { 01472 for(long i = 0; i < vertexcache->count - 2; i++) 01473 { 01474 if(grid && (i & 0x1)) 01475 { 01476 indices.push_back(i + 0); 01477 indices.push_back(i + 2); 01478 indices.push_back(i + 1); 01479 } 01480 else 01481 { 01482 indices.push_back(i + 0); 01483 indices.push_back(i + 1); 01484 indices.push_back(i + 2); 01485 } 01486 } 01487 } 01488 01489 // perform the optimization 01490 optimizer.Mend( vertices, indices, results, x->smooth_normals, x->smooth_tangents, x->smooth_bitangents, x->weight_normals, 01491 x->auto_normals ? MeshMender::CALCULATE_NORMALS : MeshMender::DONT_CALCULATE_NORMALS, 01492 x->auto_split ? MeshMender::DONT_RESPECT_SPLITS : MeshMender::RESPECT_SPLITS, 01493 x->fix_cylindrical ? MeshMender::FIX_CYLINDRICAL : MeshMender::DONT_FIX_CYLINDRICAL); 01494 01495 // destroy all existing cache data 01496 for (long i = 0; i < JIT_GL_MESH_MAX_INPUTCOUNT; i++) 01497 { 01498 if (i != JIT_GL_MESH_COLOR) 01499 { 01500 jit_gl_cache_buffer_destroy(x->cache[i]); 01501 } 01502 01503 // get the buffer type 01504 if (i == JIT_GL_MESH_INDEX) 01505 { 01506 x->cache[i]->buffertype = GL_ELEMENT_ARRAY_BUFFER_ARB; 01507 } 01508 else 01509 { 01510 x->cache[i]->buffertype = GL_ARRAY_BUFFER_ARB; 01511 } 01512 } 01513 01514 // vertices 01515 err = jit_gl_cache_resize(vertexcache, vertices.size() * 3, 01516 vertexcache->coords, vertexcache->datatype, FALSE); 01517 if(err) return err; 01518 01519 // texcoords 01520 err = jit_gl_cache_resize(texcoordcache, vertices.size() * 2, 2, GL_FLOAT, FALSE); 01521 if(err) return err; 01522 01523 // indices 01524 if(x->auto_index) 01525 { 01526 err = jit_gl_cache_resize(indexcache, results.size() * 1, 1, 01527 (results.size() < 255) ? GL_UNSIGNED_BYTE : GL_UNSIGNED_INT, FALSE); 01528 if(err) return err; 01529 } 01530 01531 // normals 01532 if(x->auto_normals) 01533 { 01534 err = jit_gl_cache_resize(normalcache, vertices.size() * 3, 3, GL_FLOAT, FALSE); 01535 if(err) return err; 01536 } 01537 01538 // tangents 01539 if(x->auto_tangents) 01540 { 01541 err = jit_gl_cache_resize(tangentcache, vertices.size() * 3, 3, GL_FLOAT, FALSE); 01542 if(err) return err; 01543 } 01544 01545 // bitangents 01546 if(x->auto_bitangents) 01547 { 01548 err = jit_gl_cache_resize(bitangentcache, vertices.size() * 3, 3, GL_FLOAT, FALSE); 01549 if(err) return err; 01550 } 01551 01552 // reorder vertex positions 01553 for (unsigned long i = 0; i < results.size(); i++) 01554 { 01555 long index = results[i]; 01556 MeshMender::Vertex v = vertices[index]; 01557 01558 // indices 01559 if (indexcache->used) 01560 { 01561 if (indexcache->datatype == GL_UNSIGNED_BYTE) 01562 { 01563 ((GLubyte*)indexcache->data)[i] = index % 255; 01564 } 01565 else if (indexcache->datatype == GL_UNSIGNED_INT) 01566 { 01567 ((GLuint*)indexcache->data)[i] = index; 01568 } 01569 } 01570 01571 // vertex positions 01572 if (vertexcache->used) 01573 { 01574 if (vertexcache->datatype == GL_INT) 01575 { 01576 for (long d = 0; d < 3 && d < vertexcache->coords; d++) 01577 ((GLint*)vertexcache->data)[i * vertexcache->coords + d] = (GLint)v.pos[d]; 01578 } 01579 else if (vertexcache->datatype == GL_FLOAT) 01580 { 01581 for (long d = 0; d < 3 && d < vertexcache->coords; d++) 01582 ((GLfloat*)vertexcache->data)[i * vertexcache->coords + d] = (GLfloat)v.pos[d]; 01583 } 01584 else if (vertexcache->datatype == GL_DOUBLE) 01585 { 01586 for (long d = 0; d < 3 && d < vertexcache->coords; d++) 01587 ((GLdouble*)vertexcache->data)[i * vertexcache->coords + d] = (GLdouble)v.pos[d]; 01588 } 01589 } 01590 01591 // texcoord 01592 if (texcoordcache->used) 01593 { 01594 if (texcoordcache->datatype == GL_INT) 01595 { 01596 for (long d = 0; d < 2 && d < texcoordcache->coords; d++) 01597 ((GLint*)texcoordcache->data)[i * texcoordcache->coords + d] = (GLint)((d == 0) ? v.s : v.t); 01598 } 01599 else if (texcoordcache->datatype == GL_FLOAT) 01600 { 01601 for (long d = 0; d < 2 && d < texcoordcache->coords; d++) 01602 ((GLfloat*)texcoordcache->data)[i * texcoordcache->coords + d] = (GLfloat)((d == 0) ? v.s : v.t); 01603 } 01604 else if (texcoordcache->datatype == GL_DOUBLE) 01605 { 01606 for (long d = 0; d < 2 && d < texcoordcache->coords; d++) 01607 ((GLdouble*)texcoordcache->data)[i * texcoordcache->coords + d] = (GLdouble)((d == 0) ? v.s : v.t); 01608 } 01609 } 01610 01611 // normals 01612 if (normalcache->used) 01613 { 01614 if (normalcache->datatype == GL_INT) 01615 { 01616 for (long d = 0; d < 3 && d < normalcache->coords; d++) 01617 ((GLint*)normalcache->data)[i * normalcache->coords + d] = (GLint)v.normal[d]; 01618 } 01619 else if (normalcache->datatype == GL_FLOAT) 01620 { 01621 for (long d = 0; d < 3 && d < normalcache->coords; d++) 01622 ((GLfloat*)normalcache->data)[i * normalcache->coords + d] = (GLfloat)v.normal[d]; 01623 } 01624 else if (normalcache->datatype == GL_DOUBLE) 01625 { 01626 for (long d = 0; d < 3 && d < normalcache->coords; d++) 01627 ((GLdouble*)normalcache->data)[i * normalcache->coords + d] = (GLdouble)v.normal[d]; 01628 } 01629 } 01630 01631 // tangents 01632 if (tangentcache->used) 01633 { 01634 if (tangentcache->datatype == GL_FLOAT) 01635 { 01636 for (long d = 0; d < 3 && d < tangentcache->coords; d++) 01637 ((GLfloat*)tangentcache->data)[i * tangentcache->coords + d] = (GLfloat)v.tangent[d]; 01638 } 01639 else if (tangentcache->datatype == GL_DOUBLE) 01640 { 01641 for (long d = 0; d < 3 && d < tangentcache->coords; d++) 01642 ((GLdouble*)tangentcache->data)[i * tangentcache->coords + d] = (GLdouble)v.tangent[d]; 01643 } 01644 } 01645 01646 // bitangents 01647 if (bitangentcache->used) 01648 { 01649 if (bitangentcache->datatype == GL_FLOAT) 01650 { 01651 for (long d = 0; d < 3 && d < bitangentcache->coords; d++) 01652 ((GLfloat*)bitangentcache->data)[i * bitangentcache->coords + d] = (GLfloat)v.bitangent[d]; 01653 } 01654 else if (bitangentcache->datatype == GL_DOUBLE) 01655 { 01656 for (long d = 0; d < 3 && d < bitangentcache->coords; d++) 01657 ((GLdouble*)bitangentcache->data)[i * bitangentcache->coords + d] = (GLdouble)v.bitangent[d]; 01658 } 01659 } 01660 } 01661 } 01662 */ 01663 return JIT_ERR_NONE; 01664 } 01665 01666 // -------------------------------------------------------------------------- 01667 01668 t_jit_err jit_gl_mesh_init_cache_from_matrix_info( 01669 t_jit_gl_mesh *x, t_jit_gl_cache *cache, t_jit_matrix_info *info) 01670 { 01671 long orient = 0; 01672 01673 t_jit_gl_cache *vertexcache = x->cache[JIT_GL_MESH_VERTEX]; 01674 01675 if (!cache || !info) 01676 return JIT_ERR_INVALID_PTR; 01677 01678 // get matrix info 01679 cache->coords = cache->coords ? cache->coords : info->planecount; 01680 cache->elements = 0; 01681 cache->used = FALSE; 01682 01683 // get the buffer type 01684 if (cache->type == JIT_GL_MESH_INDEX) 01685 { 01686 cache->buffertype = GL_ELEMENT_ARRAY_BUFFER_ARB; 01687 } 01688 else 01689 { 01690 cache->buffertype = GL_ARRAY_BUFFER_ARB; 01691 } 01692 01693 cache->datatype = jit_gl_cache_datatype_from_symbol(info->type); 01694 cache->datasize = jit_gl_cache_datasize_from_datatype(cache->datatype); 01695 01696 // set geometry dependent values 01697 cache->enumtype = x->enumtype; 01698 cache->geomsize = jit_gl_mesh_geomsize_from_enumtype(x->enumtype); 01699 cache->stride = 0; 01700 cache->start = 0; 01701 cache->end = cache->count; 01702 01703 if (cache->data && cache->bytes) 01704 jit_freebytes(cache->data, cache->bytes); 01705 cache->data = NULL; 01706 cache->bytes = 0; 01707 01708 // set byte count for grid and non-grid modes 01709 if ((x->draw_mode == _jit_sym_gl_tri_grid) || (x->draw_mode == _jit_sym_gl_quad_grid)) 01710 { 01711 // for degenerate triangles connecting each row 01712 // cache->count = 2 * (JIT_MATH_MAX(info->dim[1], info->dim[0]) + 1) * (JIT_MATH_MIN(info->dim[1], info->dim[0]) - 1); 01713 //cache->count = cache->coords * 2 * (JIT_MATH_MAX(info->dim[1], info->dim[0])) * (JIT_MATH_MIN(info->dim[1], info->dim[0]) - 1); 01714 cache->count = cache->coords * 2 * (info->dim[0] * info->dim[1]); //should be able to elinate 1 from height, btu let's just pad a tad extra 01715 } 01716 else 01717 { 01718 cache->count = cache->coords * info->dim[0] * info->dim[1]; 01719 } 01720 01721 // force the same size on all cache objects 01722 if(cache != vertexcache) 01723 { 01724 if(cache->count < vertexcache->count) 01725 cache->count = vertexcache->count; 01726 } 01727 01728 cache->bytes = cache->count * cache->datasize; 01729 cache->data = jit_getbytes(cache->bytes); 01730 if (!cache->data) 01731 { 01732 jit_object_error((t_object *)x,"jit.gl.mesh: unable to initialize cache -- out of memory!"); 01733 cache->bytes = 0; 01734 return JIT_ERR_INVALID_PTR; 01735 } 01736 01737 01738 01739 return JIT_ERR_NONE; 01740 } 01741 01742 #define _I_X 0 01743 #define _I_Y 1 01744 #define _I_Z 2 01745 #define _I_S 3 01746 #define _I_T 4 01747 #define _I_NX 5 01748 #define _I_NY 6 01749 #define _I_NZ 7 01750 #define _I_R 8 01751 #define _I_G 9 01752 #define _I_B 10 01753 #define _I_A 11 01754 #define _I_E 12 01755 01756 t_jit_err jit_gl_mesh_from_matrix(t_jit_gl_mesh *x, t_jit_object *matrix) 01757 { 01758 float *p, *p2; 01759 char *bp = NULL; 01760 long size, type, datatype, datasize, planestart, planeend; 01761 long i, j, rowstride, width, height, planecount, up = 0; 01762 t_jit_matrix_info info; 01763 t_jit_err err; 01764 01765 GLfloat *gledgeflag = NULL; 01766 GLfloat *glnormal = NULL; 01767 GLfloat *glcolor = NULL; 01768 GLfloat *gltexcoord = NULL; 01769 GLfloat *glvertex = NULL; 01770 01771 t_jit_gl_cache *edgeflagcache = x->cache[JIT_GL_MESH_EDGEFLAG]; 01772 t_jit_gl_cache *normalcache = x->cache[JIT_GL_MESH_NORMAL]; 01773 t_jit_gl_cache *colorcache = x->cache[JIT_GL_MESH_COLOR]; 01774 t_jit_gl_cache *texcoordcache = x->cache[JIT_GL_MESH_TEXCOORD]; 01775 t_jit_gl_cache *vertexcache = x->cache[JIT_GL_MESH_VERTEX]; 01776 01777 if (!matrix) 01778 return JIT_ERR_INVALID_PTR; 01779 01780 jit_object_method(matrix, _jit_sym_getinfo, &info); 01781 jit_object_method(matrix, _jit_sym_getdata, &bp); 01782 01783 if (!bp) 01784 return JIT_ERR_INVALID_PTR; 01785 01786 // later add support for other types 01787 if (info.type != _jit_sym_float32) 01788 return JIT_ERR_MISMATCH_TYPE; 01789 01790 planecount = info.planecount; 01791 rowstride = info.dimstride[1]; 01792 height = info.dim[1] - 1; 01793 width = info.dim[0]; 01794 size = width * height * 3; 01795 datatype = GL_FLOAT; 01796 datasize = sizeof(GLfloat); 01797 01798 // destroy all existing cache data 01799 for (i = 0; i < JIT_GL_MESH_MAX_INPUTCOUNT; i++) 01800 { 01801 err = jit_gl_cache_reset(x->cache[i]); 01802 if (err) 01803 return err; 01804 } 01805 01806 // init cache size 01807 switch (planecount) 01808 { 01809 case 16: 01810 case 15: 01811 case 14: 01812 case 13: 01813 { 01814 // vertex 01815 vertexcache->coords = 3; 01816 err = jit_gl_mesh_fill_cache(x, vertexcache, &info, bp, _I_X, _I_Z + 1, TRUE); 01817 if (err) 01818 return err; 01819 glvertex = (GLfloat*)vertexcache->data; 01820 01821 // texcoord 01822 texcoordcache->coords = 2; 01823 err = jit_gl_mesh_fill_cache(x, texcoordcache, &info, bp, _I_S, _I_T + 1, TRUE); 01824 if (err) 01825 return err; 01826 gltexcoord = (GLfloat*)texcoordcache->data; 01827 01828 // normal 01829 normalcache->coords = 3; 01830 err = jit_gl_mesh_fill_cache(x, normalcache, &info, bp, _I_NX, _I_NZ + 1, TRUE); 01831 if (err) 01832 return err; 01833 glnormal = (GLfloat*)normalcache->data; 01834 01835 // color 01836 colorcache->coords = 4; 01837 err = jit_gl_mesh_fill_cache(x, colorcache, &info, bp, _I_R, _I_A + 1, TRUE); 01838 if (err) 01839 return err; 01840 glcolor = (GLfloat*)colorcache->data; 01841 01842 // edgeflag 01843 edgeflagcache->coords = 1; 01844 err = jit_gl_mesh_fill_cache(x, edgeflagcache, &info, bp, _I_E, _I_E + 1, TRUE); 01845 if (err) 01846 return err; 01847 gledgeflag = (GLfloat*)edgeflagcache->data; 01848 break; 01849 } 01850 case 12: 01851 { 01852 //vertex 01853 vertexcache->coords = 3; 01854 err = jit_gl_mesh_fill_cache(x, vertexcache, &info, bp, _I_X, _I_Z + 1, TRUE); 01855 if (err) 01856 return err; 01857 glvertex = (GLfloat*)vertexcache->data; 01858 01859 // texcoord 01860 texcoordcache->coords = 2; 01861 err = jit_gl_mesh_fill_cache(x, texcoordcache, &info, bp, _I_S, _I_T + 1, TRUE); 01862 if (err) 01863 return err; 01864 gltexcoord = (GLfloat*)texcoordcache->data; 01865 01866 // normal 01867 normalcache->coords = 3; 01868 err = jit_gl_mesh_fill_cache(x, normalcache, &info, bp, _I_NX, _I_NZ + 1, TRUE); 01869 if (err) 01870 return err; 01871 glnormal = (GLfloat*)normalcache->data; 01872 01873 // color 01874 colorcache->coords = 4; 01875 err = jit_gl_mesh_fill_cache(x, colorcache, &info, bp, _I_R, _I_A + 1, TRUE); 01876 if (err) 01877 return err; 01878 glcolor = (GLfloat*)colorcache->data; 01879 break; 01880 } 01881 case 11: 01882 case 10: 01883 case 9: 01884 case 8: 01885 { 01886 // vertex 01887 vertexcache->coords = 3; 01888 err = jit_gl_mesh_fill_cache(x, vertexcache, &info, bp, _I_X, _I_Z + 1, TRUE); 01889 if (err) 01890 return err; 01891 glvertex = (GLfloat*)vertexcache->data; 01892 01893 // texcoord 01894 texcoordcache->coords = 2; 01895 err = jit_gl_mesh_fill_cache(x, texcoordcache, &info, bp, _I_S, _I_T + 1, TRUE); 01896 if (err) 01897 return err; 01898 gltexcoord = (GLfloat*)texcoordcache->data; 01899 01900 // normal 01901 normalcache->coords = 3; 01902 err = jit_gl_mesh_fill_cache(x, normalcache, &info, bp, _I_NX, _I_NZ + 1, TRUE); 01903 if (err) 01904 return err; 01905 glnormal = (GLfloat*)normalcache->data; 01906 break; 01907 } 01908 case 7: 01909 case 6: 01910 case 5: 01911 { 01912 // vertex 01913 vertexcache->coords = 3; 01914 err = jit_gl_mesh_fill_cache(x, vertexcache, &info, bp, _I_X, _I_Z + 1, TRUE); 01915 if (err) 01916 return err; 01917 glvertex = (GLfloat*)vertexcache->data; 01918 01919 // texcoord 01920 texcoordcache->coords = 2; 01921 err = jit_gl_mesh_fill_cache(x, texcoordcache, &info, bp, _I_S, _I_T + 1, TRUE); 01922 if (err) 01923 return err; 01924 gltexcoord = (GLfloat*)texcoordcache->data; 01925 break; 01926 } 01927 case 4: 01928 case 3: 01929 { 01930 // vertex 01931 vertexcache->coords = 3; 01932 err = jit_gl_mesh_fill_cache(x, vertexcache, &info, bp, _I_X, _I_Z + 1, TRUE); 01933 if (err) 01934 return err; 01935 glvertex = (GLfloat*)vertexcache->data; 01936 break; 01937 } 01938 }; 01939 01940 return JIT_ERR_NONE; 01941 } 01942 01943 t_jit_err jit_gl_mesh_fill_cache( 01944 t_jit_gl_mesh *x, t_jit_gl_cache *cache, 01945 t_jit_matrix_info *info, char *bp, 01946 long planestart, long planeend, long allocate) 01947 { 01948 t_jit_err err; 01949 long i, j, k, c; 01950 long grid = 0; 01951 long orient = 0; 01952 long planejump; 01953 long planecount; 01954 long rowstride; 01955 long height; 01956 long width; 01957 01958 GLboolean *glb; 01959 GLubyte *glub; 01960 GLuint *glui; 01961 GLint *gli; 01962 GLfloat *glf; 01963 GLdouble *gld; 01964 01965 if (!x || !cache || !info || !bp) 01966 return JIT_ERR_INVALID_PTR; 01967 01968 // allocate 01969 if (allocate) 01970 { 01971 err = jit_gl_mesh_init_cache_from_matrix_info(x, cache, info); 01972 if (err) 01973 return err; 01974 } 01975 01976 if (!cache->data) 01977 { 01978 cache->data = NULL; 01979 cache->bytes = 0; 01980 01981 jit_object_error((t_object *)x,"jit.gl.mesh: unable to fill geometry cache -- out of memory!"); 01982 return JIT_ERR_INVALID_PTR; 01983 } 01984 cache->manage = TRUE; 01985 cache->elements = 0; 01986 cache->used = FALSE; 01987 01988 // clear cache 01989 setmem(cache->data, 0, cache->bytes); 01990 01991 // check to see if we are in grid mode 01992 if ((x->draw_mode == _jit_sym_gl_tri_grid) || (x->draw_mode == _jit_sym_gl_quad_grid)) 01993 { 01994 grid = 1; 01995 } 01996 else 01997 { 01998 grid = 0; 01999 } 02000 02001 // check for the current orientation based on dims 02002 if ((info->dim[1] <= 1 ) && (info->dim[0] > info->dim[1])) 02003 { 02004 // force row major 02005 orient = 0; 02006 } 02007 else if (( info->dim[0] <= 1 ) && (info->dim[1] > info->dim[0])) 02008 { 02009 // force column major 02010 orient = 1; 02011 } 02012 02013 if (grid) 02014 { 02015 planejump = info->planecount; 02016 planecount = info->planecount; 02017 rowstride = info->dimstride[1]; 02018 height = info->dim[1] - 1; 02019 width = info->dim[0]; 02020 // jit_object_post((t_object *)x,"jit.gl.geom: grid"); 02021 02022 if (width <= 1 && height <= 0) 02023 { 02024 return JIT_ERR_GENERIC; 02025 } 02026 } 02027 else 02028 { 02029 if (orient) 02030 { 02031 // column major 02032 planejump = info->dimstride[1] / jit_matrix_info_typesize(info); 02033 planecount = info->planecount; 02034 rowstride = info->dimstride[0]; 02035 height = info->dim[0]; 02036 width = info->dim[1]; 02037 } 02038 else 02039 { 02040 // row major 02041 planejump = info->planecount; 02042 planecount = info->planecount; 02043 rowstride = info->dimstride[1]; 02044 height = info->dim[1]; 02045 width = info->dim[0]; 02046 } 02047 } 02048 02049 cache->drawcount = height; 02050 cache->drawsize = grid ? width * 2 : width; 02051 planestart = JIT_MATH_CLAMP(planestart, 0, planecount); 02052 planeend = JIT_MATH_CLAMP(planeend, planestart, planecount); 02053 02054 // jit_object_post((t_object *)x,"jit.gl.geom: w[%d] h[%d] p[%d][%d][%d] j[%d] rst[%d]", 02055 // width, height, planestart, planeend, planecount, planejump, rowstride); 02056 02057 // convert to gl native datatypes 02058 if (info->type == _jit_sym_long && cache->datatype == GL_BOOLEAN) 02059 { 02060 long *p, *p2; 02061 glb = (GLboolean*)cache->data; 02062 02063 for (i = 0; i < height; i++) 02064 { 02065 // get current row and next row 02066 p = (long *)(bp + i * rowstride); 02067 p2 = (long *)(bp + (i + 1) * rowstride); 02068 02069 // iterate across the current data row adding vertex positions 02070 for (j = 0; j < width; j++) 02071 { 02072 for (k = planestart; k < planeend; k++) 02073 { 02074 *glb = p[k] > 0 ? TRUE : FALSE; 02075 glb++; 02076 } 02077 cache->elements++; 02078 p += planejump; 02079 02080 // grids: skip to next row and add lower vertex 02081 if (grid) 02082 { 02083 for (k = planestart; k < planeend; k++) 02084 { 02085 *glb = p[k] > 0 ? TRUE : FALSE; 02086 glb++; 02087 } 02088 cache->elements++; 02089 p2 += planejump; 02090 } 02091 } 02092 } 02093 } 02094 else if (info->type == _jit_sym_char && cache->datatype == GL_UNSIGNED_BYTE) 02095 { 02096 unsigned char *p, *p2; 02097 glub = (GLubyte*)cache->data; 02098 02099 for (i = 0; i < height; i++) 02100 { 02101 // get current row and next row 02102 p = (unsigned char *)(bp + i * rowstride); 02103 p2 = (unsigned char *)(bp + (i + 1) * rowstride); 02104 02105 // iterate across the current data row adding vertex positions 02106 for (j = 0; j < width; j++) 02107 { 02108 for (k = planestart; k < planeend; k++) 02109 { 02110 *glub = p[k]; 02111 glub++; 02112 } 02113 cache->elements++; 02114 p += planejump; 02115 02116 // grids: skip to next row and add lower vertex 02117 if (grid) 02118 { 02119 for (k = planestart; k < planeend; k++) 02120 { 02121 *glub = p2[k]; 02122 glub++; 02123 } 02124 cache->elements++; 02125 p2 += planejump; 02126 } 02127 } 02128 } 02129 } 02130 else if (info->type == _jit_sym_long && cache->datatype == GL_UNSIGNED_INT) 02131 { 02132 long *p, *p2; 02133 glui = (GLuint*)cache->data; 02134 02135 for (i = 0; i < height; i++) 02136 { 02137 // get current row and next row 02138 p = (long *)(bp + i * rowstride); 02139 p2 = (long *)(bp + (i + 1) * rowstride); 02140 02141 // iterate across the current data row adding vertex positions 02142 for (j = 0; j < width; j++) 02143 { 02144 for (k = planestart; k < planeend; k++) 02145 { 02146 *glui = p[k]; 02147 glui++; 02148 } 02149 cache->elements++; 02150 p += planejump; 02151 02152 // grids: skip to next row and add lower vertex 02153 if (grid) 02154 { 02155 for (k = planestart; k < planeend; k++) 02156 { 02157 *glui = p2[k]; 02158 glui++; 02159 } 02160 cache->elements++; 02161 p2 += planejump; 02162 } 02163 } 02164 } 02165 } 02166 else if (info->type == _jit_sym_long && cache->datatype == GL_INT) 02167 { 02168 long *p, *p2; 02169 gli = (GLint*)cache->data; 02170 02171 for (i = 0; i < height; i++) 02172 { 02173 // get current row and next row 02174 p = (long *)(bp + i * rowstride); 02175 p2 = (long *)(bp + (i + 1) * rowstride); 02176 02177 // iterate across the current data row adding vertex positions 02178 for (j = 0; j < width; j++) 02179 { 02180 for (k = planestart; k < planeend; k++) 02181 { 02182 *gli = p[k]; 02183 gli++; 02184 } 02185 cache->elements++; 02186 p += planejump; 02187 02188 // grids: skip to next row and add lower vertex 02189 if (grid) 02190 { 02191 for (k = planestart; k < planeend; k++) 02192 { 02193 *gli = p2[k]; 02194 gli++; 02195 } 02196 cache->elements++; 02197 p2 += planejump; 02198 } 02199 } 02200 } 02201 } 02202 else if (info->type == _jit_sym_float32 && cache->datatype == GL_FLOAT) 02203 { 02204 float *p, *p2; 02205 float v; 02206 glf = (GLfloat*)cache->data; 02207 02208 for (i = 0; i < height; i++) 02209 { 02210 // get current row and next row 02211 p = (float *)(bp + i * rowstride); 02212 p2 = (float *)(bp + (i + 1) * rowstride); 02213 02214 // iterate across the current data row adding vertex positions 02215 for (j = 0; j < width; j++) 02216 { 02217 for (k = planestart; k < planeend; k++) 02218 { 02219 *glf = p[k]; 02220 glf++; 02221 } 02222 cache->elements++; 02223 p += planejump; 02224 02225 // grids: skip to next row and add lower vertex 02226 if (grid) 02227 { 02228 for (k = planestart; k < planeend; k++) 02229 { 02230 *glf = p2[k]; 02231 glf++; 02232 } 02233 cache->elements++; 02234 p2 += planejump; 02235 } 02236 } 02237 } 02238 } 02239 else if (info->type == _jit_sym_float64 && cache->datatype == GL_DOUBLE) 02240 { 02241 double *p, *p2; 02242 gld = (GLdouble*)cache->data; 02243 02244 for (i = 0; i < height; i++) 02245 { 02246 // get current row and next row 02247 p = (double *)(bp + i * rowstride); 02248 p2 = (double *)(bp + (i + 1) * rowstride); 02249 02250 // iterate across the current data row adding vertex positions 02251 for (j = 0; j < width; j++) 02252 { 02253 for (k = planestart; k < planeend; k++) 02254 { 02255 *gld = p[k]; 02256 gld++; 02257 } 02258 cache->elements++; 02259 p += planejump; 02260 02261 // grids: skip to next row and add lower vertex 02262 if (grid) 02263 { 02264 for (k = planestart; k < planeend; k++) 02265 { 02266 *gld = p2[k]; 02267 gld++; 02268 } 02269 cache->elements++; 02270 p2 += planejump; 02271 } 02272 } 02273 } 02274 } 02275 else 02276 { 02277 jit_object_error((t_object *)x,"jit.gl.mesh: unable to fill cache -- cannot convert data!"); 02278 return JIT_ERR_GENERIC; 02279 } 02280 02281 if(cache->elements > 0) 02282 cache->used = TRUE; 02283 02284 return JIT_ERR_NONE; 02285 } 02286 02287 // -------------------------------------------------------------------------- 02288 02289 t_jit_err jit_gl_mesh_verify_extensions(t_jit_gl_mesh *x, const char **extensions) 02290 { 02291 long i = 0; 02292 const char *ext = 0; 02293 char supported = TRUE; 02294 02295 // check for system support for glsl 02296 while ((ext = extensions[i++]) != 0) 02297 { 02298 if (jit_gl_is_extension_supported(jit_gl_get_context(), ext) == GL_FALSE) 02299 { 02300 supported = FALSE; 02301 } 02302 } 02303 02304 if (!supported) 02305 { 02306 return JIT_ERR_HW_UNAVAILABLE; 02307 } 02308 02309 return JIT_ERR_NONE; 02310 } 02311 02312 // -------------------------------------------------------------------------- 02313 02314 long jit_gl_mesh_elements_from_enumtype(long enumtype, long count) 02315 { 02316 switch (enumtype) 02317 { 02318 case GL_POINTS: 02319 { 02320 return count; 02321 } 02322 case GL_LINES: 02323 { 02324 return count / 2; 02325 } 02326 case GL_LINE_STRIP: 02327 { 02328 return count - 1; 02329 } 02330 case GL_LINE_LOOP: 02331 { 02332 return count; 02333 } 02334 case GL_TRIANGLES: 02335 { 02336 return count / 3; 02337 } 02338 case GL_TRIANGLE_STRIP: 02339 { 02340 return count - 2; 02341 } 02342 case GL_TRIANGLE_FAN: 02343 { 02344 return count - 2; 02345 } 02346 case GL_QUADS: 02347 { 02348 return count / 4; 02349 } 02350 case GL_QUAD_STRIP: 02351 { 02352 return count / 2 - 1; 02353 } 02354 case GL_POLYGON: 02355 { 02356 return 1; 02357 } 02358 default: 02359 { 02360 return 1; 02361 } 02362 } 02363 return 1; 02364 } 02365 02366 long jit_gl_mesh_geomsize_from_enumtype(long enumtype) 02367 { 02368 switch (enumtype) 02369 { 02370 case GL_POINTS: 02371 { 02372 return 1; 02373 } 02374 case GL_LINES: 02375 { 02376 return 2; 02377 } 02378 case GL_LINE_STRIP: 02379 { 02380 return 1; 02381 } 02382 case GL_LINE_LOOP: 02383 { 02384 return 1; 02385 } 02386 case GL_TRIANGLES: 02387 { 02388 return 3; 02389 } 02390 case GL_TRIANGLE_STRIP: 02391 { 02392 return 1; 02393 } 02394 case GL_TRIANGLE_FAN: 02395 { 02396 return 1; 02397 } 02398 case GL_QUADS: 02399 { 02400 return 3; 02401 } 02402 case GL_QUAD_STRIP: 02403 { 02404 return 2; 02405 } 02406 case GL_POLYGON: 02407 { 02408 return 1; 02409 } 02410 default: 02411 { 02412 return 1; 02413 } 02414 } 02415 return 1; 02416 } 02417 02418 GLenum jit_gl_mesh_enumtype_from_sym(t_symbol *s) 02419 { 02420 if (s == _jit_sym_gl_quad_grid) 02421 { 02422 return GL_QUAD_STRIP; 02423 } 02424 else if (s == _jit_sym_gl_tri_grid) 02425 { 02426 return GL_TRIANGLE_STRIP; 02427 } 02428 else if (s == _jit_sym_gl_points) 02429 { 02430 return GL_POINTS; 02431 } 02432 else if (s == _jit_sym_gl_lines) 02433 { 02434 return GL_LINES; 02435 } 02436 else if (s == _jit_sym_gl_line_strip) 02437 { 02438 return GL_LINE_STRIP; 02439 } 02440 else if (s == _jit_sym_gl_line_loop) 02441 { 02442 return GL_LINE_LOOP; 02443 } 02444 else if (s == _jit_sym_gl_triangles) 02445 { 02446 return GL_TRIANGLES; 02447 } 02448 else if (s == _jit_sym_gl_tri_strip) 02449 { 02450 return GL_TRIANGLE_STRIP; 02451 } 02452 else if (s == _jit_sym_gl_tri_fan) 02453 { 02454 return GL_TRIANGLE_FAN; 02455 } 02456 else if (s == _jit_sym_gl_quads) 02457 { 02458 return GL_QUADS; 02459 } 02460 else if (s == _jit_sym_gl_quad_strip) 02461 { 02462 return GL_QUAD_STRIP; 02463 } 02464 else if (s == _jit_sym_gl_polygon) 02465 { 02466 return GL_POLYGON; 02467 } 02468 else if (s == ps_jit_gl_mesh_lines_adjacency) 02469 { 02470 return GL_LINES_ADJACENCY_EXT; 02471 } 02472 else if (s == ps_jit_gl_mesh_line_strip_adjacency) 02473 { 02474 return GL_LINE_STRIP_ADJACENCY_EXT; 02475 } 02476 else if (s == ps_jit_gl_mesh_triangles_adjacency) 02477 { 02478 return GL_TRIANGLES_ADJACENCY_EXT; 02479 } 02480 else if (s == ps_jit_gl_mesh_triangle_strip_adjacency) 02481 { 02482 return GL_TRIANGLE_STRIP_ADJACENCY_EXT; 02483 } 02484 else 02485 { 02486 return GL_LINES; 02487 } 02488 } 02489 02490 long jit_gl_mesh_mode_from_sym(t_symbol *s) 02491 { 02492 if (s == ps_jit_gl_cache_auto) 02493 { 02494 return JIT_GL_MESH_CACHE_AUTO; 02495 } 02496 else if (s == ps_jit_gl_cache_none) 02497 { 02498 // draw via uncached vertex arrays 02499 return JIT_GL_MESH_CACHE_VERTEXARRAY; 02500 } 02501 else if (s == ps_jit_gl_cache_displaylist) 02502 { 02503 return JIT_GL_MESH_CACHE_DISPLAYLIST; 02504 } 02505 else if (s == ps_jit_gl_cache_dl) 02506 { 02507 return JIT_GL_MESH_CACHE_DISPLAYLIST; 02508 } 02509 else if (s == ps_jit_gl_cache_vertexbuffer) 02510 { 02511 return JIT_GL_MESH_CACHE_VERTEXBUFFER; 02512 } 02513 else if (s == ps_jit_gl_cache_vbo) 02514 { 02515 return JIT_GL_MESH_CACHE_VERTEXBUFFER; 02516 } 02517 else if (s == ps_jit_gl_cache_vertexarray) 02518 { 02519 return JIT_GL_MESH_CACHE_VERTEXARRAY; 02520 } 02521 else if (s == ps_jit_gl_cache_var) 02522 { 02523 return JIT_GL_MESH_CACHE_VERTEXARRAY; 02524 } 02525 else 02526 { 02527 return JIT_GL_MESH_CACHE_AUTO; 02528 } 02529 } 02530 02531 // --------------------------------------------------------------------------
Copyright © 2008, Cycling '74