【问题标题】:Create and Iterate through an array of templated objects创建并遍历模板化对象数组
【发布时间】:2016-04-20 12:38:06
【问题描述】:

我创建了一个 C++ 模板,定义了不同的数据类型 2D 点,作为在 OpenGL 程序中重新学习 C++ 的任务。

template <typename T>
class Point2D {
public:
    Point2D(const T& x, const T& y) {
        _data[0] = x;
        _data[1] = y;
    }
    const T & x() { return _data[0]; }
    const T & y() { return _data[1]; }
private:
    T _data[2];
};

我可以创建 Point2D 的多个命名实例并存储值并使用它们来绘制基本形状

Point2D <GLdouble> c0( 0.5,  0.5);
Point2D <GLdouble> c1(-0.5,  0.5);

然后画一个喜欢我访问点中的值。

glBegin(GL_LINES);
    glVertex2d(c0.x(), c0.y());
    glVertex2d(c1.x(), c1.y());
glEnd();

但是,我想创建一个相同模板类型(例如双精度)的 Points2D 对象数组来表示形状。

如何创建模板化 Point2D 数组并表示更复杂的对象,我可以在 for loop 模板化对象数组中绘制这些对象。

glBegin(GL_POLYGON);
for (k = 0; k < 4; k++) {
    glVertex2d( ????? [i].x(), ????? [i].x());
}
glEnd();

有人可以建议我这样做的方法吗?

谢谢

斯图尔特

【问题讨论】:

  • Point2D&lt;GLDouble&gt; points[20]; /* ... */ points[1] = foobar(); ?

标签: c++ arrays templates


【解决方案1】:

要存储多个点,请使用 C 数组甚至更好的 std::vector 容器,然后在循环中枚举点并为每个点调用 glVertex2d

#include <vector>

std::vector< Point2D <GLdouble> > points = {Point2D<GLdouble>(0.5, 0.5),
                                            Point2D<GLdouble>(-0.5, 0.5)};

size_t size = points.size();
glBegin(GL_LINES);
for (size_t i = 0; i < size; ++i)
{
    glVertex2d( points[i].x(), points[i].x());
}
glEnd();

但如果您使用 OpenGL 1.1 或更高版本,最好使用顶点数组缓冲区而不是单独的 glVertex 调用。尝试通过添加将 ponter 返回到第一个数组元素的方法来修改您的点类

template <typename T>
class Point2D {
public:
    Point2D(const T& x, const T& y) {
        _data[0] = x;
        _data[1] = y;
    }
    const T & x() { return _data[0]; }
    const T & y() { return _data[1]; }

    T* data() const { return &_data[0]; }
private:
    T _data[2];
};

然后将点添加到容器中,创建一次顶点缓冲区,然后绑定它并调用函数 glVertexPointer。绘制元素使用 glDrawArrays

GLuint bufferId;
glGenBuffers(1, &bufferId);

std::vector< Point2D <GLdouble> > points = {Point2D<GLdouble>(0.5, 0.5),
                                            Point2D<GLdouble>(-0.5, 0.5)};

size_t size = points.size();

glBindBuffer(GL_ARRAY_BUFFER, bufferId);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_DOUBLE, 0, (const GLvoid *)points[0].data()); // <= 2 - X and Y

glDrawArrays(GL_LINES, 0, points.size());

【讨论】:

    【解决方案2】:

    你为什么不使用 std::vector ?类似的东西:

    #include <iostream>
    #include <vector>
    using namespace std;
    
    template <typename T>
    class Point2D {
    public:
      Point2D(const T& x = T(), const T& y = T()) {
        _data[0] = x; _data[1] = y;
     }
     const T & x() { return _data[0]; }
     const T & y() { return _data[1]; }
     private:
         T _data[2];
    };
    
    int main()
    {
      vector<Point2D<double> > polygon(4);
      for(int i=0;i < polygon.size(); ++i)
        cout << "Point " << i << " = (" << polygon[i].x() << "," << polygon[i].y() << ")" << endl;
    
    return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-15
      • 2016-01-12
      • 1970-01-01
      • 2014-07-15
      • 2016-05-13
      • 2022-11-08
      相关资源
      最近更新 更多