c++ - this_thread::sleep_for/SDL 渲染跳过指令

标签 c++ sdl sleep

我正在尝试使用 SDL2 制作一个排序可视化工具,除了等待时间之外,一切正常。

排序可视化工具有延迟,我可以将其更改为我想要的任何内容,但是当我将其设置为 1 毫秒左右时,它会跳过一些指令。

这是 10 毫秒与 1 毫秒:

10ms delay

1ms delay

视频显示了 1 毫秒的延迟实际上并未完成排序: Picture of 1ms delay algorithm completion.

我怀疑问题出在我使用的等待函数上,我正在尝试使这个程序成为多平台,所以几乎没有选择。

这是代码片段:

选择排序代码(在视频中显示):

void selectionSort(void)  
{  
    int minimum;  
  
    // One by one move boundary of unsorted subarray  
    for (int i = 0; i < totalValue-1; i++)  
    {  
        // Find the minimum element in unsorted array  
        minimum = i;  
        for (int j = i+1; j < totalValue; j++){
            if (randArray[j] < randArray[minimum]){
                minimum = j;
                lineColoration[j] = 2;
                render();
            }
        }
        lineColoration[i] = 1;
  
        // Swap the found minimum element with the first element  
        swap(randArray[minimum], randArray[i]);
        this_thread::sleep_for(waitTime);
        render();
        
    }
}  

一些变量需要解释:

  • totalValue 是要排序的值的数量(用户输入)
  • randArray 是一个存储所有值的 vector
  • waitTime 是计算机每次等待的毫秒数(用户输入)

我已经削减了代码,并删除了其他算法来制作一个可重现的示例,不渲染并使用 cout 似乎可以工作,但我仍然无法确定问题是否是 渲染等待函数:

#include <algorithm>
#include <chrono>
#include <iostream>
#include <random>
#include <thread>
#include <vector>
#include <math.h>

SDL_Window* window;
SDL_Renderer* renderer;

using namespace std;

vector<int> randArray;
int totalValue= 100;
auto waitTime= 1ms;
vector<int> lineColoration;
int lineSize;
int lineHeight;
Uint32 ticks= 0;

void OrganizeVariables()
{
    randArray.clear();
    for(int i= 0; i < totalValue; i++)
        randArray.push_back(i + 1);
    auto rng= default_random_engine{};
    shuffle(begin(randArray), end(randArray), rng);

    lineColoration.assign(totalValue,0);
}

int create_window(void)
{
    window= SDL_CreateWindow("Sorting Visualizer", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1800, 900, SDL_WINDOW_SHOWN);
    return window != NULL;
}

int create_renderer(void)
{
    renderer= SDL_CreateRenderer(
                  window, -1, SDL_RENDERER_PRESENTVSYNC); // Change SDL_RENDERER_PRESENTVSYNC to SDL_RENDERER_ACCELERATED
    return renderer != NULL;
}


int init(void)
{

    if(SDL_Init(SDL_INIT_VIDEO) != 0)
        goto bad_exit;
    if(create_window() == 0)
        goto quit_sdl;
    if(create_renderer() == 0)
        goto destroy_window;

    cout << "All safety checks passed succesfully" << endl;
    return 1;


destroy_window:
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
quit_sdl:
    SDL_Quit();
bad_exit:
    return 0;
}

void cleanup(void)
{
    SDL_DestroyWindow(window);
    SDL_Quit();
}

void render(void)
{

    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    SDL_RenderClear(renderer);

    //This is used to only render when 16ms hits (60fps), if true, will set the ticks variable to GetTicks() + 16
    if(SDL_GetTicks() > ticks) {
        for(int i= 0; i < totalValue - 1; i++) {
            // SDL_Rect image_pos = {i*4, 100, 3, randArray[i]*2};
            SDL_Rect fill_pos= {i * (1 + lineSize), 100, lineSize,randArray[i] * lineHeight};
            switch(lineColoration[i]) {
            case 0:
                SDL_SetRenderDrawColor(renderer,255,255,255,255);
                break;
            case 1:
                SDL_SetRenderDrawColor(renderer,255,0,0,255);
                break;
            case 2:
                SDL_SetRenderDrawColor(renderer,0,255,255,255);
                break;
            default:
                cout << "Error, drawing color not defined, exting...";
                cout << "Unkown Color ID: " << lineColoration[i];
                cleanup();
                abort();
                break;
            }
            SDL_RenderFillRect(renderer, &fill_pos);
        }
        SDL_RenderPresent(renderer);
        lineColoration.assign(totalValue,0);
        ticks= SDL_GetTicks() + 16;
    }
}
void selectionSort(void)
{
    int minimum;

    // One by one move boundary of unsorted subarray
    for (int i = 0; i < totalValue-1; i++) {
        // Find the minimum element in unsorted array
        minimum = i;
        for (int j = i+1; j < totalValue; j++) {
            if (randArray[j] < randArray[minimum]) {
                minimum = j;
                lineColoration[j] = 2;
                render();
            }
        }
        lineColoration[i] = 1;

        // Swap the found minimum element with the first element
        swap(randArray[minimum], randArray[i]);
        this_thread::sleep_for(waitTime);
        render();

    }
}
int main(int argc, char** argv)
{
    //Rough estimate of screen size
    lineSize= 1100 / totalValue;
    lineHeight= 700 / totalValue;


    create_window();
    create_renderer();
    OrganizeVariables();
    selectionSort();
    this_thread::sleep_for(5000ms);
    cleanup();
}

最佳答案

问题在于 ticks= S​​DL_GetTicks() + 16;,因为对于毫秒等待和 if(SDL_GetTicks() >ticks) 条件来说,这些刻度数太多大多数时候都是假的。

如果您等待1ms并且ticks= S​​DL_GetTicks() + 5它将起作用。

selectionSort 循环中,如果在最后(例如,八次)迭代中,if(SDL_GetTicks() >ticks) 跳过绘图,则循环可能会完成并让一些待处理的图纸。

并不是算法没有完成,而是在 ticks 达到足够高的数字以允许绘图之前完成。

关于c++ - this_thread::sleep_for/SDL 渲染跳过指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65050910/

相关文章:

c++ - 与 Mergesort 相比,为什么 GNU 并行快速排序这么慢?

c++ - 无法使用 SDL_LoadBMP 加载图像

c - 此 SDL_gfx 代码是否涉及竞争条件?

macos - 当我的 Mac 进入休眠状态时,我的应用程序会发生什么?

python - 在 Windows 上使用 Python 时 time.sleep() 出现 "Interrupted function call"异常?

c++ - 随机 float 生成

c++ - 远程编程和调试

java - 当计算机从 sleep 模式或待机状态唤醒时,基于图像的 jframe 变为白色

c++ - 使用 int 计算并输出 float?

c++ - SDL_PollEvent 未拾取所有事件