From: H. H. <hen...@gm...> - 2008-08-24 01:04:55
|
Does anyone have anything to say on this, please? I am currently working hard on the GLM and I think we should resolve the issue of how we actually define the math types. On Sun, Aug 24, 2008 at 1:43 AM, Henri Häkkinen <hen...@gm...> wrote: > Okay, lets discuss on this matter. I have written the library with the > implementation of using struct/union approach as I thought this was the > implementation we decided on in the forums. > > We have multiple approaches: > > Proposal #1: the array approach > > typedef GLfloat GLMvec2f[2]; > > void glmVecSet2f (GLMvec2f out, GLfloat x, GLfloat y); > void glmVecAdd2f (GLMvec2f out, const GLMvec2f v1, const GLMvec2f v2); > > This allows the user code to call like this: > > GLMvec2f a, b, c; > glmVecSet2f (a, 1.0f, 1.0f); > glmVecSet2f (b, 2.0f, 2.0f); > glmVecAdd2f (c, a, b); > > However GCC will generate warnings on args 2 and 3 for glmVecAdd2f. > > We cannot define glmVecSet2f like this: > > GLMvec2f glmVecSet2f (GLMvec2f out, GLfloat x, GLfloat y); > > This is impossible because functions cannot return arrays. The bad side of > this approach is that function calls cannot be nested like this: > > glmVecAdd2f (c, glmVecSet2f (a, 1.0f, 1.0f), glmVecSet2f (b, 2.0f, 2.0f)); > > > Proposal #2: struct/union approach (the current implementation) > > typedef struct GLMvec2f_s { > union { > GLfloat v[2]; > struct GLMvec2f_data_s { > GLfloat x, y; > }; > }; > } GLMvec2f; > > GLMvec2f *glmVecSet2f (GLMvec2f *out, GLfloat x, GLfloat y); > GLMvec2f *glmVecAdd2f (GLMvec2f *out, const GLMvec2f *v1, const GLMvec2f > *v2); > > This allows function calls to be nested: > > GLMvec2f a, b, c; > glmVecAdd2f (&c, glmVecSet2f (&a, 1.0f, 1.0f), glmVecSet2f (&b, 2.0f, > 2.0f)); > > Data can be also passed directly to OpenGL functions: > > GLMmat4f mat; > glmMatIdentity4f (&mat); > glLoadMatrixf (mat.m); > (or some equivalent GL3 API call) > > Member can also be accessed by a moniker: > > mat.m11 = 1.0f; > vec.x = 2.0f; > col.r = 0.5f; > > As a sidenote, this is also how they do this in D3DX (the util library of > D3D). > > The only con is the use of union, but I don't see this as a problem. They > are not particularly complicated either IMO. > > > Proposal #3: the struct-only approach > > struct GLMvec2f_s { > GLfloat x, y; > } GLMvec2f; > > GLMvec2f *glmVecSet2f (GLMvec2f *out, GLfloat x, GLfloat y); > GLMvec2f *glmVecAdd2f (GLMvec2f *out, const GLMvec2f *v1, const GLMvec2f > *v2); > > This is almost the same as #2 except that avoidance of unions. > > I would go with the struct/union. > > > > On Sun, Aug 24, 2008 at 1:22 AM, Jason McKesson <ko...@gm...> wrote: > >> Henri Häkkinen wrote: >> >> No no... We had this conversation already in the forums few days ago. >> >> The struct approach is superior over typedef GLfloat GLMmat2f[4]; for the >> following reason: >> >> - it allows matrix data to be accessed as either using index or members. >> You can see the memory layout of the matrix from the ordering of the mXX >> members. >> >> - the following piece of code: >> >> typedef float FOO[2]; >> >> FOO *test (FOO *out, const FOO *f) >> { >> (*out)[0] = (*f)[0]; >> (*out)[1] = (*f)[1]; >> return out; >> } >> >> The function "test" should not take pointers. Objects of type "FOO" >> already are pointers, so it does not need to take FOO*'s. >> >> > >> int main () >> { >> FOO a, b; >> test (&a, &b); >> return 0; >> } >> >> >> Produces the following warning on GCC 4.2.3: >> warning: passing argument 2 of 'test' from incompatible pointer type >> >> Which is why virtually every book on programming tells you *not* to >> define multiple variables on the same line. >> > > > This has nothing to do how the variables are declared, but how the function > test is called. > > > >> >> Compare this: >> >> typedef struct { >> union { >> float f[2]; >> struct { >> float x, y; >> }; >> }; >> } FOO; >> >> FOO *test (FOO *out, const FOO *f) >> { >> out->x = f->x; >> out->y = f->y; >> return out; >> } >> >> I don't like the idea of these functions all taking pointers to the types >> rather than the types themselves. I know C doesn't have an equivalent to the >> & reference in C++, but the user code would be a lot cleaner if you only >> passed pointers for parameters that are outputs (or large objects). That's >> the general convention for most C libraries I've seen. >> > > > But it is also a lot more efficient to pass them as pointers. > > > >> >> This code is a lot more clear and usable than the previous one. Also: >> >> vec[0] = -vec[0]; >> >> You cannot be sure if this vec is an array of vectors or are you accessing >> the first element of a 2D vector. >> >> Implementing math datatypes as structure is a lot more cleaner approach >> than the array approach. Perhaps we should think if the union there is >> redundant but typedef GLfloat GLMvec2f[2]; is not a good idea. And I don't >> think we should hinder our design by the assumed ignorance of the >> afromentioned newbies. Besides, I have already implemented the library by >> the struct approach design. See the OpenGL forums for the discussion we >> underwent there fore more points. >> >> If you feel that the math types should be structs, then let them be >> struct. But they should *not* be structs containing a union of an array >> and a struct. That violates principle #2: simplicity. A principle you agreed >> on, as you previously stated. Simplicity means you pick one side: struct or >> array. >> >> ------------------------------------------------------------------------- >> This SF.Net email is sponsored by the Moblin Your Move Developer's >> challenge >> Build the coolest Linux based applications with Moblin SDK & win great >> prizes >> Grand prize is a trip for two to an Open Source event anywhere in the >> world >> http://moblin-contest.org/redirect.php?banner_id=100&url=/ >> _______________________________________________ >> Glsdk-devel mailing list >> Gls...@li... >> https://lists.sourceforge.net/lists/listinfo/glsdk-devel >> >> > > > -- > Henri 'henux' Häkkinen > > -- Henri 'henux' Häkkinen |