用三角条围成的圆圈

Circle with Triangle strips

本文关键字:三角      更新时间:2023-10-16

我一直在尝试在OpenGL中创建一个圆,但我不能使用三角扇,因为我已经读到它们在directx中不再可用,我也将进行directx调用。

我真的不明白三角带是怎么工作的。我所有的实现都有漏洞或奇怪的怪癖,有人能帮我吗?我如何以最好的方式实现它?

此外,三角形条和单独的三角形之间确实有任何性能差异,比如说10个圆圈,每个圆圈有1000个三角形。这会有很大的不同吗?

用三角形条指定圆的一种方法如下:

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个三角形需要30000个顶点。对于三角形条带,每个圆需要1002个顶点,因此总共需要10020个顶点。这几乎是它的三倍小,当转移到CPU时应该会快一点。这是否反映在FPS中取决于几件事。

这里是使用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);
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)

而不是像上面显示的伪代码那样在圆圈的一侧上下曲折,这个代码将在圆圈的中心上曲折。这将有一个更完整的圆圈。