是什么导致每次渲染新颜色之间出现第二次延迟?
What is causing there to be a second delay between each rendering of a new color?
所以我想深入研究 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}
本程序编译运行没有问题。输出看起来像这样:
我想知道为什么每个新颜色之间会有一秒钟的延迟?
直觉告诉我每次循环都会有新的颜色。这应该是每秒数百次。也许看起来像这样:
https://youtu.be/AjbrmfjJRk0?t=6m3s
造成这种延迟的原因是什么?还是我想念对代码的一些理解,而它正在做它应该做的事情?
伪随机数生成器通过对先前值进行计算来生成可预测的数字序列。
举个简单的例子:
int lastValue;
int rand(void) {
lastValue = (lastValue * 13) / 7;
return lastValue;
}
当然 rand()
的真正实现更复杂。
当没有以前的数字时,您必须使用默认值,并且如果默认值始终相同(例如,当您启动程序时始终为零),它将始终为所有程序生成完全相同的序列.
要解决此问题,您可以设置 "initial previous number" 或种子编号。这就是 srand()
的用途。
现在...
每次绘制矩形并从当前时间获取种子值时,您都在使用 srand()
。如果当前时间不变,则种子相同,所以数字序列与上次相同。
当前时间每秒变化一次。
您正在通过调用 drawRect 中的 srand()
重新播种随机数生成器。您正在提供 time()
的 return 值作为您的新种子,并且它每秒仅更改一次,因为它报告自纪元开始以来的时间(以秒为单位)。然后调用 rand()
来获取矩形颜色的随机 RGB 值。
因为您正在使用 time()
的 return 值重新播种 RNG,即使您的主函数正在调用 drawRect()
,您大约每秒只能看到一种新的随机颜色经常。您可能认为 rand()
仍应为您提供不同的 'random' 值,但这不是大多数 RNG 的工作方式。他们中的许多人为给定的种子值给出了可预测的数字序列,因此术语 'pseudo-random number generator'。这实际上在可测试性方面有好处。
如果您消除对 srand()
的调用,或将其移到 drawRect()
之外(最好是在您的主游戏循环之外),您应该会看到颜色更频繁地变化。
所以我想深入研究 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}
本程序编译运行没有问题。输出看起来像这样:
我想知道为什么每个新颜色之间会有一秒钟的延迟?
直觉告诉我每次循环都会有新的颜色。这应该是每秒数百次。也许看起来像这样:
https://youtu.be/AjbrmfjJRk0?t=6m3s
造成这种延迟的原因是什么?还是我想念对代码的一些理解,而它正在做它应该做的事情?
伪随机数生成器通过对先前值进行计算来生成可预测的数字序列。
举个简单的例子:
int lastValue;
int rand(void) {
lastValue = (lastValue * 13) / 7;
return lastValue;
}
当然 rand()
的真正实现更复杂。
当没有以前的数字时,您必须使用默认值,并且如果默认值始终相同(例如,当您启动程序时始终为零),它将始终为所有程序生成完全相同的序列.
要解决此问题,您可以设置 "initial previous number" 或种子编号。这就是 srand()
的用途。
现在...
每次绘制矩形并从当前时间获取种子值时,您都在使用 srand()
。如果当前时间不变,则种子相同,所以数字序列与上次相同。
当前时间每秒变化一次。
您正在通过调用 drawRect 中的 srand()
重新播种随机数生成器。您正在提供 time()
的 return 值作为您的新种子,并且它每秒仅更改一次,因为它报告自纪元开始以来的时间(以秒为单位)。然后调用 rand()
来获取矩形颜色的随机 RGB 值。
因为您正在使用 time()
的 return 值重新播种 RNG,即使您的主函数正在调用 drawRect()
,您大约每秒只能看到一种新的随机颜色经常。您可能认为 rand()
仍应为您提供不同的 'random' 值,但这不是大多数 RNG 的工作方式。他们中的许多人为给定的种子值给出了可预测的数字序列,因此术语 'pseudo-random number generator'。这实际上在可测试性方面有好处。
如果您消除对 srand()
的调用,或将其移到 drawRect()
之外(最好是在您的主游戏循环之外),您应该会看到颜色更频繁地变化。