【问题标题】:SDL_RENDERER_PRESENTVSYNC Inconsistently DisplaysSDL_RENDERER_PRESENTVSYNC 显示不一致
【发布时间】:2015-09-10 11:20:06
【问题描述】:

我最近决定开始使用 SDL 作为我的库之一来编写 C++ 游戏。在我编写程序和学习 SDL 的过程中,我偶然发现了我的程序中的一个特殊错误,并决定在 SSCCE 中复制它以确保我没有发疯。

问题似乎是当我将 SDL_RENDERER_PRESENTVSYNC 作为标志传递给 SDL_CreateRenderer 时,我得到不一致的渲染。为了比较,我运行了 50 次带有标志的程序,50 次没有标志,并且在每种情况下对我的程序进行了唯一的更改。没有标志,显示器工作 100% 的时间。开启标志后,它在 50 次中仅成功渲染了 13 次。

这是程序:

#include <SDL2/SDL.h>
#include <iostream>

int main(int argc, char** argv)
{
    if(SDL_Init(SDL_INIT_VIDEO) != 0)
    {
        std::cerr << "Unable to initialize SDL: " << SDL_GetError() << std::endl;
        return -1;
    }
    SDL_Window* win = SDL_CreateWindow("Testing", 
                                       SDL_WINDOWPOS_UNDEFINED, 
                                       SDL_WINDOWPOS_UNDEFINED,
                                       640, 480, SDL_WINDOW_SHOWN);
    SDL_Renderer* renderer = SDL_CreateRenderer(win, -1, 
                                                SDL_RENDERER_ACCELERATED | 
                                                SDL_RENDERER_PRESENTVSYNC);
    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    SDL_RenderClear(renderer);
    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
    for(int x = 0; x < 640; x+=32)
    {
        for(int y = 0; y < 480; y+=32)
        {
            SDL_Rect rect = {x+1, y+1, 31, 31};
            SDL_RenderFillRect(renderer, &rect);
        }
    }
    SDL_RenderPresent(renderer);
    SDL_Delay(500);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(win);
    SDL_Quit();
    return 0;
}

如果有所作为,我将在 Ubuntu 15.04、GCC/G++ 4.9.2 上编译和测试该程序,并针对 SDL 2.0.2 进行编译和链接。

对 SDL 如此陌生,并且对 C++ 和 C 来说仍然相对较新(我来自 Java 背景),我认为我很可能犯了一个我没有发现的简单错误,但我可以不要想我可能做了什么。

【问题讨论】:

  • 无法复制。当它“失败”时,你究竟看到了什么?
  • @keltar 当它失败时,窗口确实出现了,但它应该呈现的区域只是窗口弹出之前背景中的任何内容的副本,这与我得到的行为相同没有应用渲染/绘图。
  • 你的显卡驱动是什么?是否启用合成?如果您要求驱动程序强制 vsync 会发生什么?
  • @keltar 我在笔记本电脑上使用板载英特尔显卡。作为笔记本电脑,没有单独安装的显卡。 lshw 显示我的驱动程序是 i915。根据 compiz 的说法,启用了合成。 OpenGL 被设置为同步到 VBLANK,由同一个工具。不太清楚如何要求驱动程序强制 vsync。应该注意,图形不是(还)我的专业领域。
  • 我的意思是,在您的情况下,将环境变量 vblank_mode 设置为 0(禁用 vsync)或 1(即使应用程序没有请求它也强制 vsync)。不幸的是,我从未遇到过您的问题,因此无法告诉您确切的原因或解决方案,但有人多次告诉我,GPU vsync 和 compiz vsync 的组合纯粹是疯狂。我建议在不合成的情况下尝试它。在快速更新的应用程序中这不是问题,但是如果您只想绘制一帧 - 它会变得很棘手;可能由于某种原因,当 compiz 还没有准备好获取图像时,您的翻转发生得太早了。

标签: c++ sdl-2


【解决方案1】:

对于那些以后看到这个问题的人来说,问题似乎在一年多之后就自行解决了,因为我无法再复制我自己的 SSCCE。这可能是环境的变化,因为我没有使用相同的系统,现在使用的是 Nvidia 显卡。尽管我无法再验证这一点,但几乎可以肯定,问题出在环境或硬件上。仅仅一两个月后,同一台笔记本电脑就出现了故障(主板问题),所以你可以从中吸取教训。如果您遇到同样的问题,请考虑检查您的硬件运行状况并尝试一个完全干净的环境。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-22
    • 2010-10-20
    • 1970-01-01
    • 1970-01-01
    • 2012-07-02
    • 2021-03-31
    • 2015-01-31
    • 1970-01-01
    相关资源
    最近更新 更多