Issue by sstewartgallus
_Wednesday Jul 31, 2013 at 04:38 GMT_
_For earlier discussion, see https://github.com/rust-lang/rust/issues/8144_
_This issue was labelled with: in the Rust repository_
I have the following code at http://gitorious.org/p-x/p-x/blobs/master/src/gl.rs#line465 but it is very ugly. I have to create a data structure so I can calculate the offset from the structure to it's field, and pass it to the low level OpenGL code. To understand the issue better the documentation at http://www.khronos.org/opengles/sdk/docs/man/xhtml/glVertexAttribPointer.xml for the glVertexAttribPointer function may be useful.
impl <'self, S: Zero, T: AttributeValue> DisabledAttribute<'self, T> {
pub fn vertex_pointer<C: Component<S, T>, State>(
&self,
_: &BufferTarget<'self, State, S>, // Not used just needs to be bound
normalized: bool,
component: &C
) {
let handle = self.raw_attribute;
// Compute the stride, and offset
let s = &Zero::zero();
let t = component.access(s);
let offset = borrow::to_uint(t) - borrow::to_uint(s);
do self.linked_program.raw_program.context.send_and_recv {
AttributeValue::vertex_attrib_pointer::<T>(
handle,
normalized,
sys::size_of::<S>(),
offset
)
}
}
}
The definition of Component:
pub trait Component<S, T> {
fn access<'r>(&self, &'r S) -> &'r T;
}
A sample implementation:
struct Positions;
impl Component<assets::Vertex, [f32, ..3]> for Positions {
fn access<'r>(&self, s: &'r assets::Vertex) -> &'r [f32, ..3] {
&s.position
}
}
Somewhat related - https://github.com/Diggsey/rust-field-offset
The workaround:
macro_rules! offset_of {
($ty:ty, $field:ident) => {
unsafe { &(*(0 as *const $ty)).$field as *const _ as usize }
}
}
source: https://stackoverflow.com/questions/40310483/how-to-get-pointer-offset-in-bytes/40310851
@gtors That might be UB. I don't know where the previous discussion was.
For the record @gtors's solution caused segfaults in glium.
I believe using an union / mem::uninitialized + mem::drop could work, but you have to be careful about panicking while you have an uninitialized variable on the stack.
We don't have to deal with Drop impls in this case, but the uninitialized approach appears to work in practice: https://github.com/rust-lang-nursery/unix-socket/blob/master/src/lib.rs#L21. It compiles down to a constant.
Most helpful comment
We don't have to deal with Drop impls in this case, but the
uninitializedapproach appears to work in practice: https://github.com/rust-lang-nursery/unix-socket/blob/master/src/lib.rs#L21. It compiles down to a constant.