ext/gl_vertex.c in ray-0.1.1 vs ext/gl_vertex.c in ray-0.2.0

- old
+ new

@@ -1,8 +1,10 @@ #include "ray.h" -VALUE ray_cGLVertex = Qnil; +VALUE ray_cGLVertex = Qnil; +VALUE ray_cGLInstance = Qnil; + static VALUE ray_gl_vertex_types = Qnil; VALUE ray_get_vertex_class(size_t id) { VALUE vclass = rb_path2class("Ray::GL::Vertex"); return rb_hash_aref(rb_iv_get(vclass, "@vertex_classes"), INT2FIX(id)); @@ -17,17 +19,73 @@ rb_raise(rb_eRuntimeError, "expected class to be a vertex class"); return 0; } } +VALUE ray_get_vertex_element(void *data, VALUE type) { + switch (NUM2INT(rb_hash_aref(ray_gl_vertex_types, type))) { + case SAY_FLOAT: + return rb_float_new(*(GLfloat*)data); + case SAY_INT: + return INT2FIX(*(GLint*)data); + case SAY_UBYTE: + return INT2FIX(*(GLubyte*)data); + case SAY_BOOL: + return (*(GLint*)data) ? Qtrue : Qfalse; + + case SAY_COLOR: + return ray_col2rb(*(say_color*)data); + case SAY_VECTOR2: + return ray_vector2_to_rb(*(say_vector2*)data); + case SAY_VECTOR3: + return ray_vector3_to_rb(*(say_vector3*)data); + } + + return Qnil; +} + +void ray_set_vertex_element(void *data, VALUE type, VALUE val) { + switch (NUM2INT(rb_hash_aref(ray_gl_vertex_types, type))) { + case SAY_FLOAT: + *(GLfloat*)data = NUM2DBL(val); + break; + case SAY_INT: + *(GLint*)data = NUM2INT(val); + break; + case SAY_UBYTE: + *(GLubyte*)data = ray_byte_clamp(NUM2INT(val)); + break; + case SAY_BOOL: + (*(GLint*)data) = RTEST(val); + break; + + case SAY_COLOR: + *(say_color*)data = ray_rb2col(val); + break; + case SAY_VECTOR2: + *(say_vector2*)data = ray_convert_to_vector2(val); + break; + case SAY_VECTOR3: + *(say_vector3*)data = ray_convert_to_vector3(val); + break; + } +} + VALUE ray_gl_vertex_alloc(VALUE self) { size_t size = NUM2ULONG(rb_iv_get(self, "@vertex_type_size")); void *vertex = malloc(size); return Data_Wrap_Struct(self, NULL, free, vertex); } +VALUE ray_gl_instance_alloc(VALUE self) { + size_t size = NUM2ULONG(rb_iv_get(self, "@vertex_instance_size")); + + void *instance = malloc(size); + return Data_Wrap_Struct(self, NULL, free, instance); +} + static VALUE ray_gl_vertex_make_type(VALUE self, VALUE types) { size_t size = RARRAY_LEN(types); if (size == 0) { rb_raise(rb_eArgError, "can't create empty vertex type"); @@ -40,15 +98,17 @@ VALUE element = RAY_ARRAY_AT(types, i); VALUE name = RAY_ARRAY_AT(element, 0); VALUE type = RAY_ARRAY_AT(element, 1); - char *c_name = StringValuePtr(name); + VALUE per_instance = RAY_ARRAY_AT(element, 2); + + char *c_name = say_strdup(StringValuePtr(name)); say_vertex_elem_type c_type = NUM2INT(rb_hash_aref(ray_gl_vertex_types, type)); - say_vertex_elem c_elem = {c_type, c_name}; + say_vertex_elem c_elem = {c_type, c_name, RTEST(per_instance)}; say_vertex_type_push(vtype, c_elem); } return INT2FIX(vtype_id); } @@ -63,70 +123,33 @@ VALUE ray_gl_vertex_size(VALUE self, VALUE vtype) { say_vertex_type *type = say_get_vertex_type(NUM2ULONG(vtype)); return INT2FIX(say_vertex_type_get_size(type)); } +static +VALUE ray_gl_vertex_instance_size(VALUE self, VALUE vtype) { + say_vertex_type *type = say_get_vertex_type(NUM2ULONG(vtype)); + return INT2FIX(say_vertex_type_get_instance_size(type)); +} + VALUE ray_gl_vertex_element(VALUE self, VALUE offset, VALUE type) { uint8_t *data = NULL; Data_Get_Struct(self, uint8_t, data); data += NUM2ULONG(offset); - - switch (NUM2INT(rb_hash_aref(ray_gl_vertex_types, type))) { - case SAY_FLOAT: - return rb_float_new(*(GLfloat*)data); - case SAY_INT: - return INT2FIX((*(GLint*)data)); - case SAY_UBYTE: - return INT2FIX((*(GLubyte*)data)); - case SAY_BOOL: - return (*(GLint*)data) ? Qtrue : Qfalse; - - case SAY_COLOR: - return ray_col2rb(*(say_color*)data); - case SAY_VECTOR2: - return ray_vector2_to_rb(*(say_vector2*)data); - case SAY_VECTOR3: - return ray_vector3_to_rb(*(say_vector3*)data); - } - - return Qnil; + return ray_get_vertex_element(data, type); } VALUE ray_gl_vertex_set_element(VALUE self, VALUE offset, VALUE type, VALUE val) { uint8_t *data = NULL; Data_Get_Struct(self, uint8_t, data); data += NUM2ULONG(offset); + ray_set_vertex_element(data, type, val); - switch (NUM2INT(rb_hash_aref(ray_gl_vertex_types, type))) { - case SAY_FLOAT: - (*(GLfloat*)data) = NUM2DBL(val); - break; - case SAY_INT: - ((*(GLint*)data)) = NUM2INT(val); - break; - case SAY_UBYTE: - ((*(GLubyte*)data)) = ray_byte_clamp(NUM2INT(val)); - break; - case SAY_BOOL: - (*(GLint*)data) = RTEST(val); - break; - - case SAY_COLOR: - ((*(say_color*)data)) = ray_rb2col(val); - break; - case SAY_VECTOR2: - ((*(say_vector2*)data)) = ray_convert_to_vector2(val); - break; - case SAY_VECTOR3: - ((*(say_vector3*)data)) = ray_convert_to_vector3(val); - break; - } - - return type; + return val; } void Init_ray_gl_vertex() { ray_cGLVertex = rb_define_class_under(ray_mGL, "Vertex", rb_cObject); rb_define_alloc_func(ray_cGLVertex, ray_gl_vertex_alloc); @@ -135,10 +158,12 @@ ray_gl_vertex_make_type, 1); rb_define_singleton_method(ray_cGLVertex, "offset_of", ray_gl_vertex_offset_of, 2); rb_define_singleton_method(ray_cGLVertex, "size", ray_gl_vertex_size, 1); + rb_define_singleton_method(ray_cGLVertex, "instance_size", + ray_gl_vertex_instance_size, 1); rb_define_private_method(ray_cGLVertex, "element", ray_gl_vertex_element, 2); rb_define_private_method(ray_cGLVertex, "set_element", ray_gl_vertex_set_element, 3); @@ -152,6 +177,16 @@ rb_hash_aset(ray_gl_vertex_types, RAY_SYM("color"), INT2FIX(SAY_COLOR)); rb_hash_aset(ray_gl_vertex_types, RAY_SYM("vector2"), INT2FIX(SAY_VECTOR2)); rb_hash_aset(ray_gl_vertex_types, RAY_SYM("vector3"), INT2FIX(SAY_VECTOR3)); rb_define_const(ray_cGLVertex, "TypeMap", ray_gl_vertex_types); + + ray_cGLInstance = rb_define_class_under(ray_cGLVertex, "Instance", + rb_cObject); + rb_define_alloc_func(ray_cGLInstance, ray_gl_instance_alloc); + + rb_define_private_method(ray_cGLInstance, "element", ray_gl_vertex_element, + 2); + rb_define_private_method(ray_cGLInstance, "set_element", + ray_gl_vertex_set_element, 3); + }