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

时间:2018-06-23 00:18:00

标签: c++ sdl

我正在使用SDL 2.0.8和SDL_image 2.0.3。我编写了一个小程序,可以在屏幕2上渲染纹理。

启动程序时,我的计算机滞后很多,无法关闭程序窗口。我把这个程序交给了我的朋友,当他打开它时,他和我一样滞后。我们认为我的代码中的某些内容不好。我们分析了代码,发现没有错误。然后我想起我去年写过类似的代码,并且一切运行良好。我下载它是因为我将其存储在云中,然后我们运行了它。这个程序也很落后。这对我们来说是完全奇怪的。我们的显卡利用率为100%,因为我没有设置帧率锁定或垂直同步。

我的电脑:

  • AMD Ryzen 7 2700x @ 4.3GHz
  • AMD Radeon R9 390
  • 16 GB RAM DDR4 3000MHz

我朋友的计算机:

  • AMD锐龙7 1700 @ 3.6GHz
  • NVidia GTX 770
  • 16 GB RAM DDR4 3200MHz

我可以在循环中添加注释渲染功能以消除延迟。

编辑:

仅在图形卡利用率为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;
};

1 个答案:

答案 0 :(得分:1)

更新到最新的Windows 10版本后,没有出现问题。