static void fill_buffer_with_table(lua_State* L, bufferobject* b, int idx, int offset) { int count = lua_objlen(L, idx); void* data = NULL; #define _FILL(type) \ b->element_size = sizeof(type); \ data = malloc(count * sizeof(type)); \ if (NULL == data) \ luaL_error(L, "Out of memory"); \ for (int i = 1; i <= count; ++i) { \ lua_rawgeti(L, idx, i); \ lua_Number v = lua_tonumber(L, -1); \ ((type*)data)[i-1] = (type)v; \ } \ lua_pop(L, count) switch (b->element_type) { case GL_BYTE: _FILL(GLbyte); break; case GL_UNSIGNED_BYTE: _FILL(GLubyte); break; case GL_SHORT: _FILL(GLshort); break; case GL_UNSIGNED_SHORT: _FILL(GLushort); break; case GL_INT: _FILL(GLint); break; case GL_UNSIGNED_INT: _FILL(GLuint); break; case GL_FLOAT: _FILL(GLfloat); break; case GL_DOUBLE: _FILL(GLdouble); break; default: luaL_error(L, "Invalid data type"); }; #undef _FILL int size_old = b->count * b->element_size; int size_new = count * b->element_size; offset = b->element_size; glBindBuffer(b->target, b->id); if (size_old >= size_new + offset) { // reuse old buffer glBufferSubData(b->target, offset, size_new, data); } else if (b->count == 0) { // this is a new buffer glBufferData(b->target, size_new, data, b->usage); b->count = count; } else { // new data extends buffer. bollux. void* new_data = malloc(size_new + offset); if (NULL == new_data) { free(data); luaL_error(L, "Out of memory"); } // merge unchanged with new part void* old_data = NULL; glGetBufferSubData(b->target, 0, offset, old_data); memcpy(new_data, old_data, offset); memcpy((void*)((char*)new_data + offset), data, size_new); glBufferData(b->target, size_new + offset, new_data, b->usage); free(new_data); b->count = count; } free(data); }
/** * oil_randize_array_default: * * The default randomize-array function. */ void oil_randize_array_default ( GRand *r, guint8 *array, OilType type, gint pre_n, gint stride, gint post_n) { #define _FILL(c_type, rfunc) \ G_STMT_START { \ gint i; \ for (i = 0; i < post_n; i++) { \ gint j; \ guint8 *ptr = array + i * stride; \ \ for (j = 0; j < pre_n; j++) { \ c_type *_e = (c_type *) ptr + j; \ *_e = (c_type) rfunc (r); \ } \ } \ } G_STMT_END switch (type) { case OIL_TYPE_s8p: _FILL (gint8, oil_rand_s8); break; case OIL_TYPE_u8p: _FILL (guint8, oil_rand_u8); break; case OIL_TYPE_s16p: _FILL (gint16, oil_rand_s16); break; case OIL_TYPE_u16p: _FILL (guint16, oil_rand_u16); break; case OIL_TYPE_s32p: _FILL (gint32, oil_rand_s32); break; case OIL_TYPE_u32p: _FILL (guint32, oil_rand_u32); break; case OIL_TYPE_s64p: _FILL (gint64, oil_rand_s64); break; case OIL_TYPE_u64p: _FILL (guint64, oil_rand_u64); break; case OIL_TYPE_f32p: _FILL (gfloat, oil_rand_f32); break; case OIL_TYPE_f64p: _FILL (gdouble, oil_rand_f64); break; default: g_error ("Unknow OilType %d", type); /* should abort*/ break; }; #undef _FILL }