带三角形带的圆圈

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 的正弦和余弦调用。

以上是关于带三角形带的圆圈的主要内容,如果未能解决你的问题,请参考以下文章

重叠圆的组合面积

三角带三角剖分

红旗h5 仪表盘上出现两个圆圈中间一个点下面一个三角

得到三角形带内的三角形?

带背景图像的三角形

绘制三角形带时,啥控制 OpenGL 的行为?