PDA

View Full Version : GLM perspective



sam_thedancer
05-24-2013, 05:42 AM
Greetings:
I see that
float aspect = 1.0;
projMat = glm::perspective(60.0, aspect, 1.0, 50.0);
gives an error in Win7/MS VS 2010 and refuses to compile, while
double aspect = 1.0;
projMat = glm::perspective(60.0, aspect, 1.0, 50.0);
is fine.

However, the GLM manual seems to indicate that both float and double should be acceptable. Is this a known issue with GLM or something to do with VS environment? I know it's no big deal but I use float pretty much throughout so it's a bit annoying to have to use double just as a fix.

Thanks,
Sam

carsten neumann
05-24-2013, 08:16 AM
You are using double literals (60.0 is a double, 60.0f is a float), together with the way template argument deduction works, you get the error when passing in 3 doubles and 1 float argument about the arguments having inconsistent type.

Please use [ code]/[ /code] (no space after '[') tags around source snippets (should keep the forum from greedily placing emoticons into your code ;) ).

thokra
05-24-2013, 08:19 AM
So those :p in your text? Wonder why that is? Please put code in code segments and read the forum posting guidelines. Thank you. BTW, this is a C++ related question .... not related to OpenGL other than the fact that the resulting matrix is used during rendering... Still, I like it and will give this answer:

Look at this code:



float aspect = 1.0;
projMat = glm::perspective(60.0, aspect, 1.0, 50.0);


First of all, let me state something unrelated to the problem:


float aspect = 1.0; introduces an implicit conversion from double to float. Avoid stuff like that. Just write it correctly:


float aspect = 1.0f; // or 1.0F o 1.f, or 1.F

The reason for the actual problem to type dedution, or better put, a lack thereof. Why? Simple: the function template is parameterized by a single type parameter:


template <typename valType> detail::tmat4x4<valType> perspective(valType const & fovy, valType const & aspect, valType const & zNear, valType const & zFar)

As you can see, there is only one possible parameter there: valType. However, the following code puts arguments of float and double type into the args list:



float aspect = 1.0; // FLOAT!!!
projMat = glm::perspective(60.0, aspect, 1.0, 50.0); // 60.0 is DOUBLE, aspect is FLOAT, 1.0 is DOUBLE, 50.0 is DOUBLE !!!


At the time compiler tries to instantiate the template it sees itself confronted with two different types that could be the type if valType. Is it float or double? The compiler cannot make a decision and fails - rightfully so.

The correct way to use the function template is to simply write the following:


projMat = glm::perspective(60.0f, aspect, 1.0f, 50.0f); // aspect is still of type float, and now all the other arguments are too - hooray!

In this case, the compiler will deduce that valType == float and instantiate the corresponding function. Just for completeness' sake: You can still instantiate a template explicitly, even if the types of the arguments differ:



float aspect = 1.f;
projMat = glm::perspective<double>(60.0, aspect, 1.0, 50.0);


This works. You tell the compiler, "don't try to deduce, I know what I'm giving the function, so just assume the arguments are of type double!". This, however, implies that the instantiated function will take all double arguments. Since aspect is of type float, you introduce another implicit conversion. And this fact leads to another implication: the arguments must be implicitly convertible. EDIT: This is not advice on how to use templates. The general consensus is: let the compiler deduce if it can and be explicit only if you must.

You should read up on C++ templates.

sam_thedancer
05-25-2013, 06:59 AM
Thanks, Carsten and Thokra.

Thokra, really appreciate your going out of your way to educate.

thokra
05-25-2013, 07:32 AM
Sam_thedancer: check out C++ Templates by Josuttis and Vandervoorde. That's what you call going out of your way. :)