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);
+
}