在 SDL2 (C++) 中生成圆的顶点

Generate the vertices of a circle in SDL2 (C++)

有没有办法自动生成圆的顶点?我知道如何渲染它,我只需要一种方法来输入一定数量的顶点,然后根据该数字生成圆的顶点(它们的数量)。

生成顶点以近似圆的一种方法如下:

void GenerateCircle(std::vector<SDL_Vertex> &outCircleVertices, size_t vertexCount, int radius, std::vector<int> &outIndices)
{
    // Size our vector so it can hold all the requested vertices plus our center one
    outCircleVertices.resize(vertexCount + 1);

    // Calculate the angle we'll need to rotate by for each iteration (* (PI / 180) to convert it into radians)
    double segRotationAngle = (360.0 / vertexCount) * (3.14159265 / 180);

    // Here I set a center in the middle of the window as an example. The center point of the circle can be anywhere
    int centerX = WINDOW_WIDTH / 2;
    int centerY = WINDOW_HEIGHT / 2;

    // We need an initial vertex in the center as a point for all of the triangles we'll generate
    outCircleVertices[0].position.x = centerX;
    outCircleVertices[0].position.y = centerY;

    // Set the colour of the center point
    outCircleVertices[0].color.r = 255;
    outCircleVertices[0].color.g = 255;
    outCircleVertices[0].color.b = 255;
    outCircleVertices[0].color.a = 255;

    // Set the starting point for the initial generated vertex. We'll be rotating this point around the origin in the loop
    double startX = 0.0 - radius;
    double startY = 0.0;

    for (int i = 1; i < vertexCount + 1; i++)
    {
        // Calculate the angle to rotate the starting point around the origin
        double finalSegRotationAngle = (i * segRotationAngle);

        // Rotate the start point around the origin (0, 0) by the finalSegRotationAngle (see https://en.wikipedia.org/wiki/Rotation_(mathematics) section on two dimensional rotation)
        outCircleVertices[i].position.x = cos(finalSegRotationAngle) * startX - sin(finalSegRotationAngle) * startY;
        outCircleVertices[i].position.y = cos(finalSegRotationAngle) * startY + sin(finalSegRotationAngle) * startX;

        // Set the point relative to our defined center (in this case the center of the screen)
        outCircleVertices[i].position.x += centerX;
        outCircleVertices[i].position.y += centerY;

        // Set the colour for the vertex
        outCircleVertices[i].color.r = 255;
        outCircleVertices[i].color.g = 255;
        outCircleVertices[i].color.b = 255;
        outCircleVertices[i].color.a = 255;

        // Add centre point index
        outIndices.push_back(0);

        // Add generated point index
        outIndices.push_back(i);

        // Add next point index (with logic to wrap around when we reach the start)
        int index = (i + 1) % vertexCount;
        if (index == 0)
        {
            index = vertexCount;
        }
        outIndices.push_back(index);
    }
}

每个阶段都附有注释以帮助理解。在我这里的示例中,我选择不复制任何顶点,而是使用索引来向绘图函数描述它应该如何使用每个顶点来生成三角形。这是图形编程中的常见做法 - 例如,您会在 OpenGL 中看到它。

要使用此功能只需添加

std::vector<SDL_Vertex> circleVertices;
std::vector<int> indices;

GenerateCircle(circleVertices, 20, 60, indices);

在你的初始化中然后添加

int rc = SDL_RenderGeometry(renderer, NULL, circleVertices.data(), circleVertices.size(), indices.data(), indices.size());
if (rc < 0)
{
    std::cout << SDL_GetError();
}

在 SDL_RenderClear 和 SDL_RenderPresent 调用之间的渲染循环中。请注意,您可以更改传入的 vertexCount 以生成具有更多或更少三角形的圆,以获得更好或更差的近似值。另请注意,如果您按原样使用该功能,您将绘制一个白色圆圈,以防万一您有白色背景并想知道它在哪里!