【发布时间】:2020-12-04 17:31:18
【问题描述】:
我有一个项目,我使用点绘制一个三角形,它被称为 Sierpinski Gasket。为了实现这一点,我使用了一个包含 x 和 y 值的类 Vx。问题是如果任何方法是虚拟的,它会抛出不同的值,我想知道为什么。 虚函数如何影响以下 OpenGL 代码中点的生成方式?
我的向量类有以下声明:
class Vx {
public:
float x;
float y;
Vx();
Vx(const float& value);
Vx(const float& x, const float& y);
Vx(const Vx& v);
float getX() const;
void setX(const float& x);
float getY() const;
void setY(const float& y);
const float operator [] (int i) const;
operator const float* () const;
operator float* ();
float& operator [] (int i);
};
std::ostream& operator<<(std::ostream& os, const Vx v);
Vx operator+(const Vx& p1, const Vx& p2);
Vx operator/(const Vx& p1, const Vx& p2);
它的实现是:
Vectors::Vx::Vx() : x(0), y(0)
{
}
Vectors::Vx::Vx(const float& value) : x(value), y(value)
{
}
Vectors::Vx::Vx(const float& x, const float& y) : x(x), y(y)
{
}
Vectors::Vx::Vx(const Vx& v) : x(v.x), y(v.y)
{
}
float Vectors::Vx::getX() const
{
return this->x;
}
void Vectors::Vx::setX(const float& x)
{
this->x = x;
}
float Vectors::Vx::getY() const
{
return this->y;
}
void Vectors::Vx::setY(const float& y)
{
this->y = y;
}
float& Vectors::Vx::operator[](int i)
{
return *(&x + i);
}
const float Vectors::Vx::operator[](int i) const
{
return *(&x + i);
}
Vectors::Vx::operator const float* () const
{
return static_cast<const float*>(&x);
}
Vectors::Vx::operator float* ()
{
return static_cast<float*>(&x);
}
std::ostream& Vectors::operator<<(std::ostream& os, const Vx v)
{
os << "Vx: " << "x = " << v.x << ", y = " << v.y << std::endl;
return os;
}
Vx Vectors::operator+(const Vx& p1, const Vx& p2)
{
return Vx(p1.x + p2.x, p1.y + p2.y);
}
Vx Vectors::operator/(const Vx& p1, const Vx& p2)
{
return Vx(p1.x / p2.x, p1.y / p2.y);
}
我的主类开始设置 OpenGL 以准备绘制,并且在某些时候我创建了一个包含以下数据的缓冲区:
void sierpinskiGasket() {
using namespace Vectors;
/*
Creamos la informacion para el triangulo
*/
const int numPoints = 5000;
Vx points[numPoints];
points[0] = Vx(0.0f, 0.0f);
Vx vertices[] = {
Vx(-0.50f, -0.50f),
Vx(0.50f, -0.50f),
Vx(0.0f, 0.50f)
};
for (int i = 1; i < numPoints;i++) {
int j = rand() % 3;
points[i] = (points[i - 1] + vertices[j]) / 2;
}
/*
Generamos el buffer para el triangulo
*/
unsigned int triangle_vbo;
glGenBuffers(1, &triangle_vbo);
glBindBuffer(GL_ARRAY_BUFFER, triangle_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
}
我得到的结果是下一个三角形(没关系):
但是,如果我将 Vx 类的任何方法更改为 virtual,接下来的事情就会发生:
【问题讨论】:
-
virtual函数不太可能是问题,鉴于您显示的代码,因为您似乎没有使用任何间接(例如,通过指针或引用调用派生类的函数)基地)。更可能的问题是您将x和y成员视为数组的一部分,而它们不是数组的一部分,这将导致未定义的行为。我建议完全摆脱operator[]和operator float*,或者用float xy[2];这样的实际数组替换x和y -
看看Accessing struct data members via pointer arithmetic,这似乎几乎是这个问题的重复
-
请参阅_vec2,了解如何合并类似数组和
.x,.y访问类