static VALUE ray_drawable_init_copy(VALUE self, VALUE orig) { if (rb_obj_is_kind_of(self, rb_path2class("Ray::Text")) || rb_obj_is_kind_of(self, rb_path2class("Ray::Sprite")) || rb_obj_is_kind_of(self, rb_path2class("Ray::Polygon"))) { rb_raise(rb_eTypeError, "can't get drawable pointer from %s", RAY_OBJ_CLASSNAME(self)); } ray_drawable *obj = NULL; Data_Get_Struct(self, ray_drawable, obj); ray_drawable *other = ray_rb2full_drawable(orig); size_t vid = say_drawable_get_vertex_type(other->drawable); obj->drawable = say_drawable_create(vid); say_drawable_set_custom_data(obj->drawable, obj); say_drawable_set_other_data(obj->drawable, (void*)self); say_drawable_copy(obj->drawable, other->drawable); say_drawable_set_changed(obj->drawable); rb_iv_set(self, "@vertex_type_class", rb_iv_get(orig, "@vertex_type_class")); obj->vsize = other->vsize; ray_drawable_copy_attr(self, orig); return self; }
/* @overload initialize(vertex_class = Ray::Vertex) @param [Class] vertex_class Class of the vertices. */ static VALUE ray_drawable_init(int argc, VALUE *argv, VALUE self) { if (rb_obj_is_kind_of(self, rb_path2class("Ray::Text")) || rb_obj_is_kind_of(self, rb_path2class("Ray::Sprite")) || rb_obj_is_kind_of(self, rb_path2class("Ray::Polygon"))) { rb_raise(rb_eTypeError, "can't get drawable pointer from %s", RAY_OBJ_CLASSNAME(self)); } ray_drawable *obj = NULL; Data_Get_Struct(self, ray_drawable, obj); VALUE arg = Qnil; rb_scan_args(argc, argv, "01", &arg); size_t id = NIL_P(arg) ? 0 : ray_get_vtype(arg); obj->drawable = say_drawable_create(id); say_drawable_set_custom_data(obj->drawable, obj); say_drawable_set_other_data(obj->drawable, (void*)self); say_drawable_set_fill_proc(obj->drawable, ray_drawable_fill_proc); say_drawable_set_shader_proc(obj->drawable, ray_drawable_shader_proc); say_drawable_set_render_proc(obj->drawable, ray_drawable_render_proc); say_drawable_set_index_fill_proc(obj->drawable, ray_drawable_indices_fill_proc); say_drawable_set_changed(obj->drawable); rb_iv_set(self, "@vertex_type_class", NIL_P(arg) ? rb_path2class("Ray::Vertex") : arg); obj->vsize = say_vertex_type_get_size(say_get_vertex_type(id)); return self; }
/* * @overload set_intance(id, value) * @param [Integer] id * @param [Ray::GL::Vertex::Instance] value The instance to set the given * index. */ static VALUE ray_gl_buffer_set_instance(VALUE self, VALUE i, VALUE vertex) { rb_check_frozen(self); say_buffer *buf = ray_rb2buffer(self); if (!say_buffer_has_instance(buf)) rb_raise(rb_eRuntimeError, "buffer has no instance data"); VALUE klass = rb_const_get(rb_iv_get(self, "@vertex_type"), rb_intern("Instance")); if (!RAY_IS_A(vertex, klass)) { rb_raise(rb_eTypeError, "Can't convert %s into %s", RAY_OBJ_CLASSNAME(vertex), rb_class2name(klass)); } size_t size = say_buffer_get_instance_size(buf); size_t index = NUM2ULONG(i); if (index >= size) { rb_raise(rb_eRangeError, "%zu is outside of range 0...%zu", size, index); } size_t byte_size = NUM2INT(rb_iv_get(klass, "@vertex_instance_size")); void *ptr = NULL; Data_Get_Struct(vertex, void, ptr); memcpy(say_buffer_get_instance(buf, index), ptr, byte_size); return vertex; }
say_image_target *ray_rb2image_target(VALUE obj) { if (!RAY_IS_A(obj, rb_path2class("Ray::ImageTarget"))) { rb_raise(rb_eTypeError, "Can't convert %s into Ray::ImageTarget", RAY_OBJ_CLASSNAME(obj)); } say_image_target *ret = NULL; Data_Get_Struct(obj, say_image_target, ret); return ret; }
say_sprite *ray_rb2sprite(VALUE obj) { if (!RAY_IS_A(obj, rb_path2class("Ray::Sprite"))) { rb_raise(rb_eTypeError, "Can't convert %s into Ray::Sprite", RAY_OBJ_CLASSNAME(obj)); } say_sprite *sprite; Data_Get_Struct(obj, say_sprite, sprite); return sprite; }
say_array *ray_rb2int_array(VALUE obj) { if (!rb_obj_is_kind_of(obj, rb_path2class("Ray::GL::IntArray"))) { rb_raise(rb_eTypeError, "can't convert %s into Ray::GL::IntArray", RAY_OBJ_CLASSNAME(obj)); } say_array *ptr = NULL; Data_Get_Struct(obj, say_array, ptr); return ptr; }
say_input *ray_rb2input(VALUE obj) { if (!RAY_IS_A(obj, rb_path2class("Ray::Input"))) { rb_raise(rb_eTypeError, "Can't convert %s into Ray::Input", RAY_OBJ_CLASSNAME(obj)); } say_input *input = NULL; Data_Get_Struct(obj, say_input, input); return input; }
say_audio_source *ray_rb2audio_source(VALUE obj) { if (RAY_IS_A(obj, rb_path2class("Ray::Sound"))) return ray_rb2sound(obj)->src; if (RAY_IS_A(obj, rb_path2class("Ray::Music"))) return ray_rb2music(obj)->src; else { rb_raise(rb_eTypeError, "can't get audio source pointer from %s", RAY_OBJ_CLASSNAME(obj)); } return NULL; }
say_buffer *ray_rb2buffer(VALUE obj) { if (!RAY_IS_A(obj, rb_path2class("Ray::GL::Buffer"))) { rb_raise(rb_eTypeError, "Can't convert %s into Ray::GL::Buffer", RAY_OBJ_CLASSNAME(obj)); } say_buffer * *ptr = NULL; Data_Get_Struct(obj, say_buffer*, ptr); if (!*ptr) rb_raise(rb_eRuntimeError, "trying to use un-initialized buffer"); return *ptr; }
ray_drawable *ray_rb2full_drawable(VALUE obj) { if (rb_obj_is_kind_of(obj, rb_path2class("Ray::Text")) || rb_obj_is_kind_of(obj, rb_path2class("Ray::Sprite")) || rb_obj_is_kind_of(obj, rb_path2class("Ray::Polygon")) || !rb_obj_is_kind_of(obj, rb_path2class("Ray::Drawable"))) { rb_raise(rb_eTypeError, "can't get drawable pointer from %s", RAY_OBJ_CLASSNAME(obj)); } ray_drawable *ptr = NULL; Data_Get_Struct(obj, ray_drawable, ptr); if (!ptr->drawable) { rb_raise(rb_eRuntimeError, "trying to use an uninitialized drawable"); } return ptr; }
static void ray_drawable_fill_proc(void *drawable_ptr, void *vertex_ptr) { ray_drawable *drawable = drawable_ptr; uint8_t *vertices = vertex_ptr; VALUE ary = rb_funcall(drawable->obj, RAY_METH("fill_vertices"), 0); VALUE klass = rb_iv_get(drawable->obj, "@vertex_type_class"); size_t size = say_drawable_get_vertex_count(drawable->drawable); for (size_t i = 0; i < size; i++) { VALUE vertex = RAY_ARRAY_AT(ary, i); if (!RAY_IS_A(vertex, klass)) { rb_raise(rb_eTypeError, "Can't convert %s into %s", RAY_OBJ_CLASSNAME(vertex), rb_class2name(klass)); } uint8_t *data = NULL; Data_Get_Struct(vertex, uint8_t, data); memcpy(vertices, data, drawable->vsize); vertices += drawable->vsize; } }