带三角形带的圆圈
Posted
技术标签:
【中文标题】带三角形带的圆圈【英文标题】:Circle with Triangle strips 【发布时间】:2013-03-08 02:59:24 【问题描述】:我一直在尝试在 OpenGL 中创建一个圆,但我不能使用三角扇,因为我已经读过它们在 directx 中不再可用,我还将进行 directx 调用。
我无法真正理解三角条的工作原理。我所有的实现都有漏洞或奇怪的怪癖,任何人都可以在这里帮助我,我怎样才能以最好的方式实现它?
三角形带和单独的三角形之间确实存在任何性能差异,例如 10 个圆形,每个圆形有 1000 个三角形。会有很大的不同吗?
【问题讨论】:
您应该指定您所针对的 Direct3D 版本。 @sion sheevok 我在问如何在 opengl 中用三角条画一个实心圆。 你也有一个directx标签,你只针对OpenGL吗?如果是这样,请删除 directx 标记。 【参考方案1】:用三角带指定圆的一种方法如下:
for each step
add next position on circle
add circle center
这将包括圆的中心位置。不包括中心的另一种方法是:
add left most vertex
for each phi in (-PI/2, Pi/2) //ommit the first and last one
x = r * sin(phi)
y = r * cos(phi)
add (x, y)
add (x, -y)
add right most vertex
您可能需要根据您的背面剔除设置调整循环
拓扑需要不同数量的顶点。对于一个三角形列表,10 个圆 á 1000 个三角形需要 30,000 个顶点。使用三角形条带,每个圆需要 1002 个顶点,因此总共需要 10,020 个顶点。这几乎小了三倍,在传输到 CPU 时应该会快一点。这是否反映在 FPS 中取决于几件事。
【讨论】:
不错的一个。第二种方法比三角扇少一个顶点。 :-)【参考方案2】:这是使用 VAO/VBO 的代码,以及最小点数。与迄今为止发布的其他答案不同,它只需要一个cos()
和一个sin()
调用。
设置:
// Number of points used for half circle.
const unsigned HALF_PREC = 10;
const float angInc = M_PI / static_cast<float>(HALF_PREC);
const float cosInc = cos(angInc);
const float sinInc = sin(angInc);
GLfloat* coordA = new GLfloat[2 * HALF_PREC * 2];
unsigned coordIdx = 0;
coordA[coordIdx++] = 1.0f;
coordA[coordIdx++] = 0.0f;
float xc = 1.0f;
float yc = 0.0f;
for (unsigned iAng = 1; iAng < HALF_PREC; ++iAng)
float xcNew = cosInc * xc - sinInc * yc;
yc = sinInc * xc + cosInc * yc;
xc = xcNew;
coordA[coordIdx++] = xc;
coordA[coordIdx++] = yc;
coordA[coordIdx++] = xc;
coordA[coordIdx++] = -yc;
coordA[coordIdx++] = -1.0f;
coordA[coordIdx++] = 0.0f;
GLuint vaoId = 0;
glGenVertexArrays(1, &vaoId);
glBindVertexArray(vaoId);
GLuint vboId = 0;
glGenBuffers(1, &vboId);
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, 2 * HALF_PREC * 2 * sizeof(GLfloat),
coordA, GL_STATIC_DRAW);
delete[] coordA;
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
画:
glBindVertexArray(vaoId);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 2 * HALF_PREC);
glBindVertexArray(0);
【讨论】:
【参考方案3】:for each phi in (-PI, Pi) //ommit the first and last one
x1 = r * sin(phi)
y1 = r * cos(phi)
x2 = r * sin(phi + Pi)
y2 = r * cos(phi + Pi)
add (x1, y1)
add (x2, y2)
而不是像上面伪代码所示的那样在圆的一侧上下曲折,这个曲折穿过圆的中心。这将有更完整的循环。
【讨论】:
请注意sin(x+Pi)
与-sin(x)
相同。与余弦相同。因此,您可以消除对 x2 和 y2 的正弦和余弦调用。以上是关于带三角形带的圆圈的主要内容,如果未能解决你的问题,请参考以下文章