c-是什么导致每次渲染新颜色之间出现第二次延迟



所以我正试图深入研究SDL2。到目前为止,我已经构建了以下简单的程序。它所做的只是在屏幕上渲染一个矩形,并让它快速改变颜色。

game.h

#include<SDL2/SDL.h>
#include<stdbool.h>
typedef struct Game {
bool finished;
SDL_Event curevent;
SDL_Window* mainwin;
SDL_Renderer* mainren;
}Game;
Game *initGame();
void destoryGame(Game*);
void drawRect(Game*);
void handleEvents(Game*);

game.c

#include<SDL2/SDL.h>
#include<malloc.h>
#include<stdlib.h>
#include<stdio.h>
#include<time.h>
#include"game.h"
Game *initGame() {
    Game *game = NULL;
    if(SDL_Init(SDL_INIT_VIDEO) < 0) {
        fprintf(stderr,"Error: %s",SDL_GetError());
    } else {
        game = malloc(sizeof(Game));
        game->finished = false;
        game->mainwin = SDL_CreateWindow("Main Window",
                                         SDL_WINDOWPOS_UNDEFINED,
                                         SDL_WINDOWPOS_UNDEFINED,
                                         800, 640,
                                         SDL_WINDOW_RESIZABLE);
        if(game->mainwin == NULL) {
            fprintf(stderr,"Error: %s",SDL_GetError());
        } else {
            game->mainren = SDL_CreateRenderer(game->mainwin, -1,
                                               SDL_RENDERER_ACCELERATED);
            if(game->mainren == NULL) {
                fprintf(stderr,"Error: %s",SDL_GetError());
            } else {
                SDL_SetRenderDrawColor(game->mainren,0,0,0,0xFF);
                SDL_RenderClear(game->mainren);
            }
        }
    }
    return game;
}
void destoryGame(Game *game) {
    free(game);
    SDL_Quit();
    printf("Exiting ...n");
}
void handleEvents(Game *game) {
    while(SDL_PollEvent(&(game->curevent)) != 0) {
        if(game->curevent.type == SDL_QUIT) {
            game->finished = true;
        }
    }
}
void drawRect(Game *game) {
    int r, b, g, h, w;
    srand(time(NULL));
    r = rand() % 0xFF + 1;
    b = rand() % 0xFF + 1;
    g = rand() % 0xFF + 1;
    SDL_GetWindowSize(game->mainwin,&h,&w);
    SDL_Rect rect = {h/4,w/4,h/2,h/2};
    SDL_SetRenderDrawColor(game->mainren,r,b,g,0xFF);
    SDL_RenderFillRect(game->mainren, &rect);
    SDL_RenderPresent(game->mainren);
}

main.c

#include"game.h"
int main() {
    Game* game = initGame();
    do {
        handleEvents(game);
        drawRect(game);
    } while((game->finished != true));
    destoryGame(game);
    return 0;
}

我使用的是Linux系统。Ubuntu 16.04。我用编译

SRC_FILES = ./src/main.c ./src/game.c
CC_FLAGS = -Wall -Wextra -Os -g -lSDL2 -std=gnu11
CC = gcc
all:
    ${CC} ${SRC_FILES} -o game ${CC_FLAGS}

这个程序编译和运行都没有问题。输出看起来像这样:

http://imgur.com/U5B6hB0

我想知道为什么每种新颜色之间都会有第二次延迟?

直觉会告诉我,每次循环迭代时都会有一种新的颜色。应该是每秒数百次。也许看起来像这样:

https://youtu.be/AjbrmfjJRk0?t=6m3s

是什么原因造成了这种延误?还是我错过了对代码的理解,而它正按照它应该做的那样做?

伪随机数生成器通过对前一个值进行计算来生成可预测的数字序列。

举个简单的例子:

int lastValue;
int rand(void) {
    lastValue = (lastValue * 13) / 7;
    return lastValue;
}

当然,rand()的实际实现更为复杂。

当没有以前的数字时,你必须使用默认值,如果默认值总是相同的(例如,当你启动一个程序时总是零),它总是为所有程序生成完全相同的序列。

要解决此问题,您可以设置"以前的初始编号"或种子编号。这就是srand()的作用。

现在。。。

每次绘制矩形时都使用srand(),并从当前时间获取种子值。如果当前时间不变,则种子是相同的,因此数字序列与上次相同。

当前时间每秒更改一次。

您正在drawRect中用对srand()的调用重新设定随机数生成器的种子。您将提供time()的返回值作为新种子,由于它报告自epoch开始以来的时间(以秒为单位),因此每秒只更改一次。然后调用rand()来获得矩形颜色的随机RGB值。

因为您使用返回值time()重新播种RNG,所以即使您的主函数经常调用drawRect(),您也只能大约每秒看到一个新的随机颜色。你可能认为rand()仍然应该给你一个不同的"随机"值,但这不是大多数RNG的工作方式。它们中的许多给出了给定种子值的可预测数字序列,因此被称为"伪随机数生成器"。这实际上在可测试性方面有好处。

如果您取消了对srand()的调用,或者将其移动到drawRect()之外(最好是移动到主游戏循环之外),您应该会看到颜色更频繁地变化。

相关内容

  • 没有找到相关文章

最新更新