58

我有一个小的 obj 加载器,它需要两个参数并将它们传递回输入变量。但是这是我第一次这样做,我现在不知道如何打印所述值。这是我测试加载程序是否正常工作的主要功能。我有两个类型glm::vec3的向量来保存顶点和法线数据。

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;   
}

上面评论的那一行是产生无用信息的原因。如果我这样离开它并运行程序,我会收到一堆错误(太无格式且无法在此处粘贴),如果我添加引用运算符,我会得到如下输出:

0x711ea0
0x711eac
0x711eb8
0x711ec4    // etc

知道我做错了什么吗?

4

6 回答 6

130

glm 对此有一个扩展。添加#include "glm/ext.hpp""glm/gtx/string_cast.hpp"

然后打印一个向量,例如:

glm::vec4 test;
std::cout<<glm::to_string(test)<<std::endl;
于 2013-02-23T22:47:26.810 回答
20

我认为最优雅的解决方案可能是已经发布的两个答案的组合,并添加了模板,因此您不必为所有向量/矩阵类型重新实现运算符(但这将函数定义限制为头文件) .

#include <glm/gtx/string_cast.hpp>

template<typename genType>
std::ostream& operator<<(std::ostream& out, const genType& g)
{
    return out << glm::to_string(g);
}
于 2013-12-12T14:09:41.230 回答
15

glm::vec3不会超载operator<<,因此您无法打印矢量本身。但是,您可以做的是打印向量的成员:

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

更好的是,如果你经常使用它,你可以超载operator<<自己:

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

    return out;
}

然后打印,只需使用:

std::cout << vertices[i];
于 2012-07-17T03:13:52.400 回答
8

GLMoperator<<()<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;
}

输出是:

[    1.000,    2.000,    3.000]
于 2020-10-13T14:15:55.963 回答
0

要正确解决重载问题,您可以执行以下操作:

// Writes a generic GLM vector type to a stream.
template <int D, typename T, glm::qualifier P>
std::ostream &operator<<(std::ostream &os, glm::vec<D, T, P> v) {
  return os << glm::to_string(v);
}

于 2020-05-25T05:14:46.793 回答
0

详细说明 JAB 的答案,我使用以下内容来避免'operator <<' is ambiguous错误:

#include <glm/glm.hpp>
#include <glm/gtx/string_cast.hpp>

/**
 * can_cout<T> tells whether there already exists an override of operator<< that
 * supports T.
 */
template <typename, typename = void>
struct can_cout : public std::false_type {};

template <typename T>
struct can_cout<T, std::void_t<decltype(operator<<(std::declval<std::ostream>(), std::declval<T>()))> > : public std::true_type {};

/**
 * Implement operator<< iff GlmType is handled by glm::to_string but there is
 * not already an override of operator<< that hanldes this type.
 */
template<
    typename GlmType,
    typename = std::enable_if_t<!can_cout<GlmType>::value>,
    typename = decltype(glm::to_string(std::declval<GlmType>()))
>
std::ostream& operator<<(std::ostream& out, const GlmType& g)
{
    return out << glm::to_string(g);
}
于 2021-03-13T17:00:34.710 回答