pub fn element_count(comptime T : type) comptime_int { const info = @typeInfo(T); return switch (info) { .Float => { 1; }, .Int => { 1; }, .Struct => blk: { const count = T.component_count; if (count < 1 or count > 4) { @compileError("element count for vector types must be 1, 2, 3, or 4 (not " ++ count ++ ")"); } break :blk count; }, else => @compileError("unsupported type " ++ @typeName(T)), }; } pub fn element_type(comptime T : type) c_uint { const info = @typeInfo(T); return switch (info) { .Float => |float| switch (float.bits) { 16 => GL_HALF_FLOAT, 32 => GL_FLOAT, 64 => GL_DOUBLE, else => @compileError("unsupported float type " ++ @typeName(T)), }, .Int => |int| switch (int.signedness) { .signed => switch (int.bits) { 8 => GL_BYTE, 16 => GL_SHORT, 32 => GL_INT, else => @compileError("unsupported signed int type " ++ @typeName(T)), }, .unsigned => switch (int.bits) { 8 => GL_UNSIGNED_BYTE, 16 => GL_UNSIGNED_SHORT, 32 => GL_UNSIGNED_INT, else => @compileError("unsupported unsigned int type " ++ @typeName(T)), }, }, .Struct => element_type(T.Component), // vector types store their componenet types in their Component declaration else => @compileError("unsupported type " ++ @typeName(T)), }; } pub fn attrib_pointers(self : Self, comptime T : type, start_attrib : comptime_int) void { const info = @typeInfo(T); switch (info) { .Struct => { if (info.Struct.layout == .Extern) { const stride = @sizeOf(T); // std.log.info("struct {s}: stride {d} bytes", .{@typeName(T), @sizeOf(T)}); const fields = info.Struct.fields; inline for (fields) |field, i| { const ftype = field.field_type; const elem_count = element_count(ftype); const elem_type = element_type(ftype); const offset = @byteOffsetOf(T, field.name); glVertexAttribPointer(start_attrib + i, elem_count, elem_type, 0, stride, @intToPtr(?*c_void, offset)); glEnableVertexAttribArray(start_attrib + i); // std.log.info("glAttribPointer({d}, {d}, {d}, 0, {d}, @intToPtr(?*c_void, {d}));", .{start_attrib + i, elem_count, elem_type, stride, offset}); } } else { @compileError("cannot read layout of non-extern struct " ++ @typeName(T)); } }, else => @compileError("cannot read layout of non-struct " ++ @typeName(T)), } }