SDL 导致整个计算机图形冻结

SDL causes graphic freezes in entire computer

我使用的是 SDL 2.0.8 和 SDL_image 2.0.3。我写了一个小程序,可以在屏幕上呈现 2 个纹理。

当我启动该程序时,我的计算机非常滞后,以至于我无法关闭该程序 window。我把这个程序给了我的朋友,当他打开它时,他遇到了和我一样的延迟。我们认为我的代码中有问题。我们分析了代码,没有发现任何错误。然后我想起去年我写过类似的代码,一切都很好 运行ning 。我下载它是因为我把它放在云端,我们 运行 它。该计划也很滞后。这对我们来说太奇怪了。我们的显卡有 100% 的利用率,因为我没有设置 framerate lock 或 vsync。

我的电脑:

我朋友的电脑:

我可以补充一点,在循环中注释渲染函数可以消除延迟。

编辑:

只有当显卡利用率在100%左右时才会出现。可能是处理器太弱,运行速度太快,显卡满载,问题就不会出现了。

代码如下:

Main.cpp

#define _CRT_SECURE_NO_WARNINGS
#include "Client.h"

int main(int argc, char** argv)
{
    // Redict strerr to file
    freopen("ErrorFile.log", "w", stderr);
    Client * c = new Client();
    c->start(40);
    system("pause");
    return 0;
}

Client.h

#pragma once
#include "Graphics.h"
#include <time.h>

class Client
{
public:
    Client()
    {
        gptr = new Graphics();
    }
    ~Client()
    {
        delete gptr;
        gptr = NULL;
    }
    // -Triggers needed components and starts client
    void start(int tickrate)
    {
        gptr->init();
        loop(tickrate);
    }
private:
    void loop(int tickrate)
    {
        clock_t start;
        clock_t timer;
        start = clock();
        while (!quit)
        {
            timer = clock();
            while (start + tickrate <= timer)
            {
                //TODO Mechanics update
                start += tickrate;
            }
            while (SDL_PollEvent(&gptr->e) != 0)
            {
                if (gptr->e.type == SDL_QUIT)
                    quit = true;
            }
            gptr->render();
        }
    }
private:
    Graphics * gptr;
    bool quit = false;
};

Graphics.h

#pragma once
#include "Texture.h"

class Graphics
{
public:
    void init()
    {
        if (SDL_Init(SDL_INIT_VIDEO) < 0)
        {
            fprintf(stderr, "Cannot init SDL. Error: %s\n", SDL_GetError());
            exit(-1);
        }
        //Set texture filtering to linear
        if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"))
        {
            printf("Warning: Linear texture filtering not enabled!");
        }
        window = SDL_CreateWindow("Client", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, SDL_WINDOW_SHOWN);
        if (window == NULL)
        {
            fprintf(stderr, "Cannot create window. Error: %s\n", SDL_GetError());
            exit(-1);
        }
        renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
        if (renderer == NULL)
        {
            fprintf(stderr, "Cannot create renderer. Error: %s\n", SDL_GetError());
            exit(-1);
        }
        SDL_RenderClear(renderer);
        //Init PNG loading
        int imgFlags = IMG_INIT_PNG;
        if (!(IMG_Init(imgFlags) & imgFlags))
        {
            fprintf(stderr, "Cannot init PNG loading. Error: %s\n", IMG_GetError());
            exit(-1);
        }
        loadMedia();
    }
    void render()
    {
        SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
        SDL_RenderClear(renderer);
        textures[MAP].render(renderer, 0, 0);
        textures[CHARACTER].render(renderer, 0, 0);
        SDL_RenderPresent(renderer);
    }
private:
    bool loadMedia()
    {
        bool success = true;

        if (!textures[MAP].loadTexture("res/map.png", renderer))
            success = false;
        if (!textures[CHARACTER].loadTexture("res/link.png", renderer))
            success = false;

        return success;
    }
public:
    SDL_Event e;
private:
    SDL_Renderer * renderer;
    Texture textures[TOTAL_TEXTURES];
    SDL_Window * window;
};

Texture.h

#pragma once
#include <SDL.h>
#include <SDL_image.h>
#include <cstdio>

enum TextureEnum
{
    MAP,
    CHARACTER,
    TOTAL_TEXTURES
};

class Texture
{
public:
    Texture()
    {
        texture = NULL;
        width = 0;
        height = 0;
    }
    bool loadTexture(const char* path, SDL_Renderer * renderer)
    {
        bool success = true;
        free();
        SDL_Surface* loadedSurface = IMG_Load(path);
        if (loadedSurface == NULL)
        {
            fprintf(stderr, "Cannot load image %s. SDL_image Error: %s\n", path, IMG_GetError());
            printf("Cannot load image %s. SDL_image Error: %s\n", path, IMG_GetError());
            SDL_FreeSurface(loadedSurface);
            success = false;
        }
        else
        {
            SDL_SetColorKey(loadedSurface, SDL_TRUE, SDL_MapRGB(loadedSurface->format, 0, 0xFF, 0xFF));
            texture = SDL_CreateTextureFromSurface(renderer, loadedSurface);
            width = loadedSurface->w;
            height = loadedSurface->h;
            if (texture == NULL)
            {
                fprintf(stderr, "Cannot create texture from %s. SDL Error: %s\n", path, SDL_GetError());
                printf("Cannot create texture from %s. SDL Error: %s\n", path, SDL_GetError());
                success = false;
            }
        }
        SDL_FreeSurface(loadedSurface);
        return success;
    }
    void free()
    {
        if (texture != NULL)
        {
            SDL_DestroyTexture(texture);
            texture == NULL;
            width = 0;
            height = 0;
        }
    }
    void render(SDL_Renderer * renderer, int x, int y)
    {
        SDL_Rect quad = { x, y, width, height };
        SDL_RenderCopy(renderer, texture, NULL, &quad);
    }
private:
    SDL_Texture * texture;
    int width;
    int height;
};

更新到最新后Windows10版本问题没有出现