我正在编写一个 2.5d 游戏,我注意到每当我靠近并面对墙壁时,游戏速度就会大大减慢。当我添加纹理时,这种情况更加严重。我正在使用一种低效的渲染方法,并研究了如何改进它,所以这个问题不是关于如何使其更快。我最初的想法是,这只是因为屏幕上有更多内容。这是部分正确的,但是我确保渲染器会剪掉屏幕上没有的任何内容。我还添加了一个检查来查看每帧绘制了多少像素(矩形)。当我这样做时,我注意到随着我越来越近,即使矩形数量完全相同,我仍然会变得越来越慢。为什么即使绘制相同数量的矩形,此代码也会变慢?
int drawStart = y_offset > 0 ? y_offset : 0;
int drawEnd = (y_offset + bar_height) < 480 ? y_offset + bar_height : 480;
int texNum = map[cell_y][cell_x] - 49;
//calculate value of wallX
double wallX; //where exactly the wall was hit
if (side == 0) wallX = player->y + distance * ray_angle_y;
else wallX = player->x + distance * ray_angle_x;
wallX -= floor(wallX);
//x coordinate on the texture
int texX = wallX * TEXTURE_WIDTH;
if (side == 0 && ray_angle_x > 0) texX = TEXTURE_WIDTH - texX - 1;
if (side == 1 && ray_angle_y < 0) texX = TEXTURE_WIDTH - texX - 1;
// How much to increase the texture coordinate per screen pixel
double step = 1.0 * TEXTURE_HEIGHT / bar_height;
double pixel_size = bar_height / TEXTURE_HEIGHT;
// Starting texture coordinate
double texPos = bar_height > 480 ? (-y_offset * step) : 0;
for(int y = drawStart; y < drawEnd; y++) {
// Cast the texture coordinate to integer, and mask with (TEXTURE_HEIGHT - 1) in case of overflow
int texY = (int)texPos & (TEXTURE_HEIGHT - 1);
texPos += step;
Uint32 color = textures[texNum].array[texY][texX];
if(side == 1) color = (color >> 1) & 8355711;
SDL_Rect rect = {i * rect_width, y, rect_width, pixel_size};
/* even when this is called the same amount of times, it will be slower depending on how close to the wall the player is*/
SDL_FillRect( screenSurface, &rect, color );
}
我按照@Ry-的建议尝试在程序上使用分析器。通过这样做,我能够追踪到有问题的代码:
double pixel_size = bar_height / TEXTURE_HEIGHT;
// ...
SDL_Rect rect = {i * rect_width, y, rect_width, pixel_size};
我将 Pixel_size 计算为常量值,这是不正确的。它需要根据距墙壁的距离而增大或缩小。离墙越近,纹理的每个“像素”就应该越大,但这使它们超出了预期的长度。