How do I print vector values of type glm::vec3 that have been passed by reference?

I have a small obj loader and it takes two parameters and passes them back to the input variables.. however this is my first time doing this and i'm not sure how to print said values now. Here is my main function to test if the loader is working. I have two vectors of type glm::vec3 to hold the vertex and normal data.

std::vector<glm::vec3> vertices;
std::vector<glm::vec3> normals;    

int main() {
    bool test = loadOBJ("cube.obj", vertices, normals);
    for (int i = 0; i < vertices.size(); i++) {
       std::cout << vertices[i] << std::endl;   // problem line
    }

    return 0;   
}

The line commented above is what is generating useless info. If I leave it like that and run the program I get a bunch of errors spewed at me (too unformatted and long to paste here) and if I add the reference operator I get output like this:

0x711ea0
0x711eac
0x711eb8
0x711ec4    // etc

Any idea what I am doing wrong?


Solution 1:

glm has an extension for this. Add #include "glm/ext.hpp" or "glm/gtx/string_cast.hpp"

Then to print a vector for example:

glm::vec4 test;
std::cout<<glm::to_string(test)<<std::endl;

Solution 2:

I think the most elegant solution might be a combination of the two answers already posted, with the addition of templating so you don't have to reimplement the operator for all vector/matrix types (this restricts the function definition to header files, though).

#include <glm/gtx/string_cast.hpp>

template<typename genType>
std::ostream& operator<<(std::ostream& out, const genType& g)
{
    return out << glm::to_string(g);
}

Solution 3:

glm::vec3 doesn't overload operator<< so you can't print the vector itself. What you can do, though, is print the members of the vector:

std::cout << "{" 
          << vertices[i].x << " " << vertices[i].y << " " << vertices[i].z 
          << "}";

Even better, if you use that a lot, you can overload operator<< yourself:

std::ostream &operator<< (std::ostream &out, const glm::vec3 &vec) {
    out << "{" 
        << vec.x << " " << vec.y << " "<< vec.z 
        << "}";

    return out;
}

Then to print, just use:

std::cout << vertices[i];

Solution 4:

GLM has operator<<() in <glm/gtx/io.hpp>

#include <iostream>
#include <glm/glm.hpp>
#include <glm/gtx/io.hpp>

int main()
{
   glm::vec3 v(1.0f, 2.0f, 3.0f);
   std::cout << v << std::endl;
}

Output is:

[    1.000,    2.000,    3.000]