SDL3 入门(3):三角形

sdl3 · 浏览次数 : 0

小编点评

本文介绍了使用SDL3库绘制几何图形的基本方法。与OpenGL类似,首先需要定义顶点数据,然后根据这些数据在屏幕上绘制出几何图形。文章给出了一个绘制三角形的示例,并解释了如何通过修改顶点坐标的值来实现三角形的动态移动效果。 1. 文章首先定义了一个包含三个顶点的数组`origin_vertices`,每个顶点包含四个浮点数坐标值和一个归一化颜色值。 2. 在事件循环中,作者修改了渲染的触发方式,从等待用户输入(SDL_WaitEvent)改为轮询获取事件(SDL_PollEvent),以便在空闲时自动进行渲染。 3. 为了实现三角形的动态移动,文章引入了一个时间变量`last_tickets`来记录上次渲染的时间,并定义了`position`和`direction`变量来计算三角形的位置。 4. 在循环内部,文章计算了当前时间与上次渲染时间的差值,以此来确定三角形的移动距离和方向。 5. 为了防止三角形超出窗口边界,文章还检查了三角形的当前位置,并根据需要调整其移动方向。 6. 最后,文章使用新的顶点数据重新绘制了三角形,并在屏幕上显示出来。 通过以上步骤,作者展示了一个简单的动态三角形示例,实现了在窗口上水平往复运动的效果。这种方法对于初学者来说是一个很好的起点,可以进一步扩展和优化以适应更复杂的图形和动画需求。

正文

SDL3 提供了 SDL_RenderGeometry 函数绘制几何图形,用法和 OpenGL 差不多,先定义顶点数据,然后根据顶点数据绘制几何图形。

绘制三角形的代码如下:

std::array<SDL_Vertex, 3> origin_vertices = {
    SDL_Vertex { { 150, 100 }, { 1.0f, 0.0f, 0.0f, 1.0f } }, // top
    SDL_Vertex { { 000, 300 }, { 0.0f, 1.0f, 0.0f, 1.0f } }, // left bottom
    SDL_Vertex { { 300, 300 }, { 0.0f, 0.0f, 1.0f, 1.0f } } // right bottom
};

SDL_RenderGeometry(renderer, nullptr, origin_vertices.data(), origin_vertices.size(), nullptr, 0);

效果如图:

注意上面的顶点定义,坐标虽然是浮点数但表示的是像素值,颜色则做了归一化(取值范围 0.0~1.0)这一点和 SDL2 不同,SDL2 中颜色取值范围是 0~255.

可以通过实时修改顶点坐标实现运动效果。首先修改事件循环,由重绘事件 SDL_EVENT_WINDOW_EXPOSED 触发渲染改成空闲时自动渲染,对应的读取事件的方式也由 SDL_WaitEvent 改为 SDL_PollEvent

SDL_Event event {};
bool keep_going = true;

while (keep_going) {
    while (SDL_PollEvent(&event)) {
        switch (event.type) {
        case SDL_EVENT_QUIT:
            keep_going = false;
            break;

        case SDL_EVENT_KEY_DOWN: {
            keep_going = keep_going && (event.key.keysym.sym != SDLK_ESCAPE);
            break;
        }
        }
    }

    SDL_SetRenderDrawColor(renderer, 16, 0, 16, 255);
    SDL_RenderClear(renderer);
    SDL_RenderGeometry(renderer, nullptr, origin_vertices.data(), origin_vertices.size(), nullptr, 0);
    SDL_RenderPresent(renderer);
}

使用 SDL_GetTicks 获取时间,定义计算三角形位置所需变量:

uint64_t last_tickets = SDL_GetTicks();
float position = 0.0f;
float direction = 1.0f;

while 循环中增加位置计算和修改顶点数据的代码:

while(keep_going) {
    ...

    uint64_t current_ticks = SDL_GetTicks();
    float delta_time = (current_ticks - last_tickets) / 1000.0f;
    last_tickets = current_ticks;
    position += 200.0f * delta_time * direction;

    int width = 0;
    SDL_GetRenderOutputSize(renderer, &width, nullptr);
    float max_position = static_cast<float>(width) - (origin_vertices[2].position.x - origin_vertices[1].position.x);

    if (position > max_position) {
        direction = -1.0f;
    } else if (position < 0.0f) {
        position = 0.0f;
        direction = 1.0f;
    }

    std::vector<SDL_Vertex> vertices;
    for (const auto& vertex : origin_vertices) {
        vertices.push_back(vertex);
        vertices.back().position.x += position;
    }

    ...
    SDL_RenderGeometry(renderer, nullptr, vertices.data(), vertices.size(), nullptr, 0);
    ...
}

这样我们就得到了一个在窗口上水平往复运动的三角形:

与SDL3 入门(3):三角形相似的内容: