SDL2:如何尽快绘制矩形?

时间:2014-03-05 16:02:38

标签: performance sdl-2

背景

我正在处理一个渲染客户端,它绘制从服务器接收的图形信息。服务器以在服务器上可变地定义的帧速率发送包含具有不同纯色的非重叠矩形的分组。我目前配置它,以便服务器传输的屏幕大小不同于客户端绘制的窗口大小,因此缩放完成。我需要客户端尽快绘制这些矩形,以免落后于服务器的流。

目前,我正在使用SDL 2.0。我正在使用SDL 2 Migration Guide中描述的流纹理技术将矩形绘制到SDL_Surface上。当显示帧的时间到来时,我调用SDL_UpdateTexture()来覆盖SDL_Texture的像素数据,然后使用SDL_RenderCopyEx()将纹理复制到渲染器。我需要此函数而不是SDL_RenderCopy(),因此我可以指定SDL_FLIP_VERTICAL来说明传递的坐标是位图样式的事实。


问题

我当前的方法不能足够快地渲染矩形。为了让客户端能够跟上服务器的步伐,我目前必须将服务器的上传速率从30+ FPS降低到15-FPS。即便如此,我还是要使socket的缓冲区变得非常大,最后我会看到客户端的渲染慢慢落后并最终导致数据包丢失。

让SDL渲染这些矩形的最快方法是什么?如果我目前正在使用最快的方法,那么其他人会推荐哪些API来建立一个可以跟上的客户端?

我已经包含了我的源代码的精简版本,以便其他人可以寻找改进/错误。


技术细节

我在64位Window 7上使用C ++ 11,MinGW32和SDL2与Eclipse Kepler CDT和GCC 4.8.2。


剥离代码

int main(int argc, char** args) {
    // omitted initialization code

    SDL_Init(SDL_INIT_VIDEO);
    SDL_Window* window = SDL_CreateWindow(
        "RTSC",
        SDL_WINDOWPOS_CENTERED,
        SDL_WINDOWPOS_CENTERED,
        windowWidth,
        windowHeight,
        SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE
    );
    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 0);
    SDL_Surface* surface = SDL_CreateRGBSurface(
        0,
        sourceWidth,
        sourceHeight,
        24,
        0xFF << 16,
        0xFF << 8,
        0xFF,
        0
    );
    SDL_FillRect(surface, nullptr, 0);
    SDL_Texture* texture = SDL_CreateTexture(
        renderer,
        surface->format->format,
        SDL_TEXTUREACCESS_STREAMING,
        sourceWidth,
        sourceHeight
    );

    bool running {true};
    while (running) {
        SDL_Event event;
        while (SDL_PollEvent(&event)) {
            switch (event.type) {
                case SDL_QUIT:
                    running = false;
                    break;
                case SDL_WINDOWEVENT:
                    switch (event.windowevent.event) {
                        case SDL_WINDOWEVENT_CLOSE:
                            running = false;
                            break;
                        default:
                            break;
                    }
                    break;
                default:
                    break;
            }
        }

        // omitted packet reception and interpretation code

        for (uint32_t i {0}; i < receivedRegions; ++i) {
            Region& region = regions[i];
            SDL_Rect rect {
                (int) region.x,
                (int) region.y,
                (int) region.width,
                (int) region.height
            };
            uint32_t color =
                (region.red << 16) +
                (region.green << 8) +
                region.blue;
            SDL_FillRect(surface, &rect, color);
        }

        // omitted logic for determining whether to present the frame

        SDL_RenderClear(renderer);
        SDL_UpdateTexture(texture, nullptr, surface->pixels, surface->pitch);
        SDL_RenderCopyEx(
            renderer,
            texture,
            nullptr,
            nullptr,
            0,
            nullptr,
            SDL_FLIP_VERTICAL
        );
        SDL_RenderPresent(renderer);
        SDL_FillRect(surface, nullptr, 0);
    }

    // omitted clean-up and return code
}

1 个答案:

答案 0 :(得分:-1)

这很令人尴尬。由于我在服务器上完成的早期检测,我认为所有问题都与SDL渲染客户端有关。但是,结果表明客户端只在服务器运行时才会变慢。它根本与SDL无关。遗憾。