Max 5 API Reference
00001 /* 00002 * jit.gl.cache.h 00003 * 00004 * Copyright 2001-2005 - Cycling '74 00005 * Derek Gerstmann - derek@cycling74.com 00006 * 00007 * Internal data structure for storing cached geometric data. 00008 * 00009 */ 00010 00011 #include "jit.math.h" 00012 #include "jit.gl.mesh.h" 00013 #include "jit.gl.cache.h" 00014 #include "jit.gl.cache.dl.h" 00015 #include "jit.gl.cache.var.h" 00016 #include "jit.gl.cache.vbo.h" 00017 00018 // -------------------------------------------------------------------------------- 00019 00020 t_symbol *ps_jit_gl_cache_none; 00021 t_symbol *ps_jit_gl_cache_auto; 00022 t_symbol *ps_jit_gl_cache_var; 00023 t_symbol *ps_jit_gl_cache_vbo; 00024 t_symbol *ps_jit_gl_cache_dl; 00025 t_symbol *ps_jit_gl_cache_vertexarray; 00026 t_symbol *ps_jit_gl_cache_vertexbuffer; 00027 t_symbol *ps_jit_gl_cache_displaylist; 00028 00029 // -------------------------------------------------------------------------------- 00030 00031 t_jit_err jit_gl_cache_init(void) 00032 { 00033 // generate symbols 00034 ps_jit_gl_cache_none = gensym("none"); 00035 ps_jit_gl_cache_auto = gensym("auto"); 00036 ps_jit_gl_cache_var = gensym("var"); 00037 ps_jit_gl_cache_vbo = gensym("vbo"); 00038 ps_jit_gl_cache_dl = gensym("dl"); 00039 ps_jit_gl_cache_vertexarray = gensym("vertexarray"); 00040 ps_jit_gl_cache_vertexbuffer = gensym("vertexbuffer"); 00041 ps_jit_gl_cache_displaylist = gensym("displaylist"); 00042 return JIT_ERR_NONE; 00043 } 00044 00045 t_jit_gl_cache * jit_gl_cache_new(long count, long coords, long datatype) 00046 { 00047 long i; 00048 t_jit_gl_cache *x; 00049 00050 if (x = (t_jit_gl_cache *)jit_getbytes(sizeof(t_jit_gl_cache))) 00051 { 00052 x->id = -1; 00053 x->data = NULL; 00054 x->used = FALSE; 00055 00056 jit_gl_cache_reset(x); 00057 jit_gl_cache_resize(x, count, coords, datatype, FALSE); 00058 return x; 00059 } 00060 return NULL; 00061 } 00062 00063 void jit_gl_cache_free(t_jit_gl_cache *x) 00064 { 00065 if (!x) 00066 return ; 00067 00068 jit_gl_cache_destroy(x); 00069 } 00070 00071 t_jit_err jit_gl_cache_clear(t_jit_gl_cache *x) 00072 { 00073 t_jit_err err = JIT_ERR_NONE; 00074 00075 if (!x) 00076 return JIT_ERR_INVALID_PTR; 00077 00078 // destroy data managed by cache 00079 if (x->manage && x->data && x->bytes) 00080 jit_freebytes(x->data, x->bytes); 00081 00082 // reset attributes 00083 x->data = NULL; 00084 x->bytes = 0; 00085 x->capacity = 0; 00086 x->count = 0; 00087 x->manage = FALSE; 00088 return JIT_ERR_NONE; 00089 } 00090 00091 t_jit_err jit_gl_cache_buffer_destroy(t_jit_gl_cache *x) 00092 { 00093 if (!x) 00094 return JIT_ERR_INVALID_PTR; 00095 00096 // delete the internal state for the cache type 00097 switch (x->type) 00098 { 00099 case JIT_GL_MESH_CACHE_DISPLAYLIST: 00100 { 00101 // destroy the entire display list 00102 return jit_gl_cache_delete_dl(x); 00103 break; 00104 } 00105 case JIT_GL_MESH_CACHE_VERTEXBUFFER: 00106 { 00107 // destroy just the vbo for this cache 00108 return jit_gl_cache_delete_vbo(x); 00109 break; 00110 } 00111 }; 00112 return JIT_ERR_GENERIC; 00113 } 00114 00115 t_jit_err jit_gl_cache_destroy(t_jit_gl_cache *x) 00116 { 00117 if (!x) 00118 return JIT_ERR_INVALID_PTR; 00119 00120 // destroy data managed by hardware 00121 jit_gl_cache_buffer_destroy(x); 00122 00123 // destroy data managed by cache 00124 jit_gl_cache_clear(x); 00125 return JIT_ERR_NONE; 00126 } 00127 00128 t_jit_err jit_gl_cache_reset(t_jit_gl_cache *x) 00129 { 00130 t_jit_err err = JIT_ERR_NONE; 00131 00132 // safety 00133 if (!x) 00134 return JIT_ERR_INVALID_PTR; 00135 00136 // destroy data managed by cache 00137 err = jit_gl_cache_destroy(x); 00138 00139 // reset attributes 00140 x->data = NULL; 00141 x->bytes = 0; 00142 x->manage = FALSE; 00143 x->type = -1; 00144 x->buffertype = -1; 00145 x->buffersize = 0; 00146 x->datatype = -1; 00147 x->datasize = 0; 00148 x->capacity = 0; 00149 x->drawcount = 0; 00150 x->drawsize = 0; 00151 x->grow = JIT_GL_MESH_CACHE_DEFAULT_GROW; 00152 x->enumtype = -1; 00153 x->geomsize = 0; 00154 x->elements = 0; 00155 x->count = 0; 00156 x->coords = 0; 00157 x->stride = 0; 00158 x->start = 0; 00159 x->end = 0; 00160 x->mode = GL_STATIC_DRAW_ARB; 00161 x->used = FALSE; 00162 x->update = FALSE; 00163 x->id = -1; 00164 return err; 00165 } 00166 00167 t_jit_err jit_gl_cache_grow(t_jit_gl_cache *x, long bytes, long copy) 00168 { 00169 long i; 00170 char *data = 0; 00171 00172 if (x) 00173 { 00174 bytes = x->bytes + bytes; 00175 data = (char *)jit_getbytes(bytes); 00176 if (!bytes) 00177 return JIT_ERR_INVALID_PTR; 00178 00179 // copy 00180 if (copy) 00181 { 00182 for (i = 0; i < x->bytes && i < bytes; i++) 00183 data[i] = ((char*)x->data)[i]; 00184 } 00185 00186 // destroy 00187 jit_gl_cache_clear(x); 00188 00189 // assign 00190 x->bytes = bytes; 00191 x->data = data; 00192 x->manage = TRUE; 00193 x->used = TRUE; 00194 x->update = TRUE; 00195 } 00196 return JIT_ERR_NONE; 00197 } 00198 00199 t_jit_err jit_gl_cache_resize(t_jit_gl_cache *x, long count, long coords, long datatype, long copy) 00200 { 00201 long i; 00202 t_jit_err err = JIT_ERR_NONE; 00203 long bytes = 0; 00204 long datasize = 0; 00205 00206 if (x) 00207 { 00208 datasize = jit_gl_cache_datasize_from_datatype(datatype); 00209 if (!datasize) 00210 return JIT_ERR_MISMATCH_TYPE; 00211 00212 // resize 00213 bytes = coords * count * datasize; 00214 err = jit_gl_cache_grow(x, bytes, copy); 00215 if (err) 00216 return err; 00217 00218 // assign 00219 x->count = count; 00220 x->coords = coords; 00221 x->elements = x->count * x->coords; 00222 x->datatype = datatype; 00223 x->datasize = datasize; 00224 x->manage = TRUE; 00225 x->used = TRUE; 00226 x->update = TRUE; 00227 } 00228 return JIT_ERR_NONE; 00229 } 00230 00231 t_jit_err jit_gl_cache_append(t_jit_gl_cache *x, char *data, long count, long coords, long datatype) 00232 { 00233 long i = 0; 00234 long d = 0; 00235 long index; 00236 t_jit_err err = JIT_ERR_NONE; 00237 long datasize = jit_gl_cache_datasize_from_datatype(datatype); 00238 00239 if (x) 00240 { 00241 if (x->datasize != datasize) 00242 return JIT_ERR_GENERIC; 00243 00244 // resize 00245 index = x->count; 00246 if (x->bytes - (x->count * x->datasize) < (datasize * count)) 00247 { 00248 err = jit_gl_cache_grow(x, datasize * count * x->grow, TRUE); 00249 if (err) 00250 return err; 00251 } 00252 00253 // copy 00254 switch (datatype) 00255 { 00256 case GL_UNSIGNED_BYTE: 00257 { 00258 for (i = index; i < index + count; i++) 00259 { 00260 for (d = 0; d < coords; d++) 00261 { 00262 ((GLubyte*)x->data)[i * coords + d] = ((GLubyte*)data)[d]; 00263 } 00264 } 00265 break; 00266 } 00267 case GL_UNSIGNED_INT: 00268 { 00269 for (i = index; i < index + count; i++) 00270 { 00271 for (d = 0; d < coords; d++) 00272 { 00273 ((GLuint*)x->data)[i * coords + d] = ((GLuint*)data)[d]; 00274 } 00275 } 00276 break; 00277 } 00278 case GL_INT: 00279 { 00280 for (i = index; i < index + count; i++) 00281 { 00282 for (d = 0; d < coords; d++) 00283 { 00284 ((GLint*)x->data)[i * coords + d] = ((GLint*)data)[d]; 00285 } 00286 } 00287 break; 00288 } 00289 case GL_FLOAT: 00290 { 00291 for (i = index; i < index + count; i++) 00292 { 00293 for (d = 0; d < coords; d++) 00294 { 00295 ((GLfloat*)x->data)[i * coords + d] = ((GLfloat*)data)[d]; 00296 } 00297 } 00298 break; 00299 } 00300 case GL_DOUBLE: 00301 { 00302 for (i = index; i < index + count; i++) 00303 { 00304 for (d = 0; d < coords; d++) 00305 { 00306 ((GLdouble*)x->data)[i * coords + d] = ((GLdouble*)data)[d]; 00307 } 00308 } 00309 break; 00310 } 00311 default: 00312 err = JIT_ERR_MISMATCH_TYPE; 00313 break; 00314 } 00315 } 00316 return err; 00317 } 00318 00319 t_jit_err jit_gl_cache_replace(t_jit_gl_cache *x, long index, char *data, long count, long coords, long datatype) 00320 { 00321 long i, d; 00322 t_jit_err err = JIT_ERR_NONE; 00323 long datasize = jit_gl_cache_datasize_from_datatype(datatype); 00324 long newsize = (index * coords * count); 00325 00326 if (x) 00327 { 00328 if (x->datasize != datasize) 00329 return JIT_ERR_GENERIC; 00330 00331 // resize 00332 if (newsize > x->count || newsize > x->capacity) 00333 { 00334 err = jit_gl_cache_grow(x, datasize * count * coords * x->grow, TRUE); 00335 if (err) 00336 return err; 00337 } 00338 00339 switch (datatype) 00340 { 00341 case GL_UNSIGNED_BYTE: 00342 { 00343 for (i = index; i < index + count; i++) 00344 { 00345 for (d = 0; d < coords; d++) 00346 { 00347 ((GLubyte*)x->data)[i * coords + d] = ((GLubyte*)data)[d]; 00348 } 00349 } 00350 break; 00351 } 00352 case GL_UNSIGNED_INT: 00353 { 00354 for (i = index; i < index + count; i++) 00355 { 00356 for (d = 0; d < coords; d++) 00357 { 00358 ((GLuint*)x->data)[i * coords + d] = ((GLuint*)data)[d]; 00359 } 00360 } 00361 break; 00362 } 00363 case GL_INT: 00364 { 00365 for (i = index; i < index + count; i++) 00366 { 00367 for (d = 0; d < coords; d++) 00368 { 00369 ((GLint*)x->data)[i * coords + d] = ((GLint*)data)[d]; 00370 } 00371 } 00372 break; 00373 } 00374 case GL_FLOAT: 00375 { 00376 for (i = index; i < index + count; i++) 00377 { 00378 for (d = 0; d < coords; d++) 00379 { 00380 ((GLfloat*)x->data)[i * coords + d] = ((GLfloat*)data)[d]; 00381 } 00382 } 00383 break; 00384 } 00385 case GL_DOUBLE: 00386 { 00387 for (i = index; i < index + count; i++) 00388 { 00389 for (d = 0; d < coords; d++) 00390 { 00391 ((GLdouble*)x->data)[i * coords + d] = ((GLdouble*)data)[d]; 00392 } 00393 } 00394 break; 00395 } 00396 default: 00397 err = JIT_ERR_MISMATCH_TYPE; 00398 break; 00399 } 00400 } 00401 return err; 00402 } 00403 00404 #define COMP(A,B,EPSILON) (((A)>((B)-EPSILON)) && ((A)<((B)+EPSILON))) 00405 00406 long jit_gl_cache_compare(t_jit_gl_cache *x, long a, long b, double epsilon) 00407 { 00408 long i; 00409 long dupe = FALSE; 00410 GLubyte *glub, glubeps; 00411 GLuint *glui, gluieps; 00412 GLint *gli, glieps; 00413 GLfloat *glf, glfeps; 00414 GLdouble *gld, gldeps; 00415 00416 if (!x || !x->data) 00417 return FALSE; 00418 00419 switch (x->datatype) 00420 { 00421 case GL_UNSIGNED_BYTE: 00422 { 00423 glub = (GLubyte*)x->data; 00424 glubeps = (GLubyte)epsilon; 00425 for (i = 0; i < x->coords; i++) 00426 { 00427 dupe = COMP(glub[a * x->coords + i], glub[b * x->coords + i], glubeps); 00428 if (!dupe) 00429 break; 00430 } 00431 break; 00432 } 00433 case GL_UNSIGNED_INT: 00434 { 00435 glui = (GLuint*)x->data; 00436 gluieps = (GLuint)epsilon; 00437 for (i = 0; i < x->coords; i++) 00438 { 00439 dupe = COMP(glui[a * x->coords + i], glui[b * x->coords + i], gluieps); 00440 if (!dupe) 00441 break; 00442 } 00443 break; 00444 } 00445 case GL_INT: 00446 { 00447 gli = (GLint*)x->data; 00448 glieps = (GLint)epsilon; 00449 for (i = 0; i < x->coords; i++) 00450 { 00451 dupe = COMP(gli[a * x->coords + i], gli[b * x->coords + i], glieps); 00452 if (!dupe) 00453 break; 00454 } 00455 break; 00456 } 00457 case GL_FLOAT: 00458 { 00459 glf = (GLfloat*)x->data; 00460 glfeps = (GLfloat)epsilon; 00461 for (i = 0; i < x->coords; i++) 00462 { 00463 dupe = COMP(glf[a * x->coords + i], glf[b * x->coords + i], glfeps); 00464 if (!dupe) 00465 break; 00466 } 00467 break; 00468 } 00469 case GL_DOUBLE: 00470 { 00471 gld = (GLdouble*)x->data; 00472 gldeps = (GLdouble)epsilon; 00473 for (i = 0; i < x->coords; i++) 00474 { 00475 dupe = COMP(gld[a * x->coords + i], gld[b * x->coords + i], gldeps); 00476 if (!dupe) 00477 break; 00478 } 00479 break; 00480 } 00481 default: 00482 dupe = FALSE; 00483 break; 00484 }; 00485 00486 return dupe; 00487 } 00488 00489 t_jit_err jit_gl_cache_weld(t_jit_gl_cache *x, double epsilon) 00490 { 00491 long i, j, k; 00492 long unique = 1; 00493 long dupe = FALSE; 00494 t_jit_err err = JIT_ERR_NONE; 00495 t_jit_gl_cache welded; 00496 t_jit_gl_cache index; 00497 00498 GLubyte *glub, glubeps = (GLubyte)epsilon; 00499 GLuint *glui, gluieps = (GLuint)epsilon; 00500 GLfloat *glf, glfeps = (GLfloat)epsilon; 00501 GLdouble *gld, gldeps = (GLdouble)epsilon; 00502 00503 // resize and copy into temp cache 00504 err = jit_gl_cache_resize(&welded, x->count, x->coords, x->datatype, TRUE); 00505 if (err) 00506 return err; 00507 00508 // find unique members 00509 switch (x->datatype) 00510 { 00511 case GL_FLOAT: 00512 { 00513 glf = (GLfloat*)x->data; 00514 for (i = 0; i < x->count; i++) 00515 { 00516 for (j = 1; j <= unique; j++) 00517 { 00518 dupe = TRUE; 00519 for (k = 0; k < x->coords; k++) 00520 { 00521 dupe = dupe && (glf[x->coords * i + k] - glf[x->coords * j + k] < epsilon); 00522 } 00523 if (dupe) 00524 { 00525 goto glfdupe; 00526 } 00527 } 00528 00529 for (k = 0; k < x->coords; k++) 00530 ((GLfloat*)welded.data)[x->coords * unique + 0] = glf[x->coords * i + 0]; 00531 00532 j = unique; 00533 unique++; 00534 00535 glfdupe: 00536 continue; 00537 } 00538 break; 00539 } 00540 } 00541 00542 // resize and copy back into cache 00543 err = jit_gl_cache_resize(x, unique, x->coords, x->datatype, TRUE); 00544 if (err) 00545 return err; 00546 00547 return JIT_ERR_NONE; 00548 } 00549 00550 // -------------------------------------------------------------------------------- 00551 00552 00553 GLenum jit_gl_cache_datatype_from_symbol(t_symbol *s) 00554 { 00555 if (s == _jit_sym_char) 00556 { 00557 return GL_UNSIGNED_BYTE; 00558 } 00559 else if (s == _jit_sym_long) 00560 { 00561 return GL_UNSIGNED_INT; 00562 } 00563 else if (s == _jit_sym_float32) 00564 { 00565 return GL_FLOAT; 00566 } 00567 else if (s == _jit_sym_float64) 00568 { 00569 return GL_DOUBLE; 00570 } 00571 return GL_FLOAT; 00572 } 00573 00574 long jit_gl_cache_datasize_from_datatype(GLenum e) 00575 { 00576 switch (e) 00577 { 00578 case GL_UNSIGNED_BYTE: 00579 { 00580 return sizeof(GLubyte); 00581 } 00582 case GL_UNSIGNED_INT: 00583 { 00584 return sizeof(GLuint); 00585 } 00586 case GL_INT: 00587 { 00588 return sizeof(GLint); 00589 } 00590 case GL_FLOAT: 00591 { 00592 return sizeof(GLfloat); 00593 } 00594 case GL_DOUBLE: 00595 { 00596 return sizeof(GLdouble); 00597 } 00598 }; 00599 return sizeof(GLfloat); 00600 }
Copyright © 2008, Cycling '74