Performance SDL2:如何尽快绘制矩形?

Performance SDL2:如何尽快绘制矩形?,performance,sdl-2,Performance,Sdl 2,背景 我正在开发一个渲染客户端,它可以绘制从服务器接收到的图形信息。服务器以服务器上定义的可变帧速率发送包含不同纯色的非重叠矩形的数据包。我目前已经配置好了它,这样服务器传输的屏幕大小就不同于客户端绘制的窗口大小,所以就可以进行缩放了。我需要客户端尽快绘制这些矩形,以免落后于服务器的流 目前,我正在使用SDL2.0。我正在使用中描述的流纹理技术将矩形绘制到SDL\u曲面上。当显示帧的时间到达时,我调用lSDL\u UpdateTexture()覆盖SDL\u纹理的像素数据,然后使用SDL\u R

背景

我正在开发一个渲染客户端,它可以绘制从服务器接收到的图形信息。服务器以服务器上定义的可变帧速率发送包含不同纯色的非重叠矩形的数据包。我目前已经配置好了它,这样服务器传输的屏幕大小就不同于客户端绘制的窗口大小,所以就可以进行缩放了。我需要客户端尽快绘制这些矩形,以免落后于服务器的流

目前,我正在使用SDL2.0。我正在使用中描述的流纹理技术将矩形绘制到
SDL\u曲面上。当显示帧的时间到达时,我调用l
SDL\u UpdateTexture()
覆盖
SDL\u纹理的像素数据,然后使用
SDL\u RenderCopyEx()
将纹理复制到渲染器。我需要这个函数而不是
SDL\u RenderCopy()
,这样我就可以指定
SDL\u FLIP\u VERTICAL
来说明传递的坐标是位图样式的


问题

我当前的方法渲染矩形的速度不够快。为了让客户端能够跟上服务器,我目前必须将服务器的上传速率从30+FPS降低到15-FPS。即使这样,我也必须将套接字的缓冲区设置得非常大,这样我最终会看到客户端的渲染慢慢落后,最终导致数据包丢失

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

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


技术细节

我在Windows7 64位上使用C++11、MinGW32和SDL2以及EclipseKeplerCDT和GCC4.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
}
intmain(intargc,char**args){
//省略初始化代码
SDL_Init(SDL_Init_视频);
SDL_Window*Window=SDL_CreateWindow(
“RTSC”,
SDL_窗口位置居中,
SDL_窗口位置居中,
窗宽,
窗高,
显示SDL_窗口| SDL_窗口|可调整大小
);
SDL_Renderer*Renderer=SDL_CreateRenderer(窗口,-1,0);
SDL_曲面*曲面=SDL_CreateRGB曲面(
0,
源宽度,
源高度,
24,
0xFF格式,
SDL_纹理访问_流媒体,
源宽度,
源高度
);
bool运行{true};
(跑步时){
SDL_事件;
while(SDL_事件和事件)){
开关(事件类型){
案例SDL_退出:
运行=错误;
打破
案例SDL_WINDOWEVENT:
开关(event.windowevent.event){
案例SDL\u窗口事件\u关闭:
运行=错误;
打破
违约:
打破
}
打破
违约:
打破
}
}
//省略的数据包接收和解释代码
对于(uint32_t i{0};i
这让人尴尬。由于我在服务器上进行了早期检测,我假设所有问题都与SDL渲染客户端有关。但是,结果表明,只有当服务器出现问题时,客户端才会变慢。这与SDL完全无关。抱歉。

您可以使用SDL2\u Gfx进行矩形渲染,使用该库可以绘制矩形直接在SDL_纹理上进行em,无需先创建SDL_曲面。但您需要自己编译,否则我的github配置文件中已经有编译版本。SDL2 Gfx网站:为什么您使用纹理来存储这些矩形而不是直接在屏幕上绘制它们?您可以使用SDL_RenderFillRect()直接渲染。@TalesM我之前尝试过,并假设(可能是错误的)使用纹理可以更快地处理我接收到的反转y坐标。我现在再次尝试,并将使用
SDL\u RenderFillRect()
与复制到纹理然后使用
SDL\u RenderCopyEx()进行比较
。这两种方法有相同的帧速率和延迟问题。不过,感谢您的推荐。@jordsti今晚晚些时候我将尝试使用此API。