Оптимизация рейкастера [закрыто]Python

Программы на Python
Anonymous
Оптимизация рейкастера [закрыто]

Сообщение Anonymous »

Я пишу код рейкастера для игры типа Wolfenstein-3D, но когда я реализовал текстуры, моя производительность сильно упала.
Для справки, вот учебник, которому я следовал: https://lodev.org/cgtutor/raycasting.html
И вот мой код рейкастера:

Код: Выделить всё

def blit_3d(self):
import main
cm = main.cm
pl = main.pl
cm.x = pl.x + 0.5
cm.z = pl.y + 0.5

last_color = None
last_color_rgb = None

same_color_x = []
for x in range(self.screen.get_width()):
cam_spc_x = 2 * x / self.screen.get_width() - 1
ray_dir_x = cm.dir_x + cm.plane_x * cam_spc_x
ray_dir_y = cm.dir_y + cm.plane_y * cam_spc_x

map_x = int(cm.x)
map_y = int(cm.z)

delta_dist_x = 1e30 if ray_dir_x == 0 else abs(1/ray_dir_x)
delta_dist_y = 1e30 if ray_dir_y == 0 else abs(1/ray_dir_y)

side_dist_x = 0
side_dist_y = 0

step_x = 0
step_y = 0

hit = False
side = 0

if ray_dir_x < 0:
step_x = -1
side_dist_x = (cm.x - map_x) * delta_dist_x
else:
step_x = 1
side_dist_x = (map_x + 1 - cm.x) * delta_dist_x
if ray_dir_y < 0:
step_y = -1
side_dist_y = (cm.z - map_y) * delta_dist_y
else:
step_y = 1
side_dist_y = (map_y + 1 - cm.z) * delta_dist_y

curr_map = map.levels[map.curr_level]
curr_map_width = map.level_size[map.curr_level][0]
while not hit:
if side_dist_x < side_dist_y:
side = 0
side_dist_x += delta_dist_x
map_x += step_x
else:
side = 1
side_dist_y += delta_dist_y
map_y += step_y

if curr_map[map_x + map_y * curr_map_width] > 0:
hit = True

perp_wall_dist = 0
if side == 0: perp_wall_dist = side_dist_x - delta_dist_x
if side == 1: perp_wall_dist = side_dist_y - delta_dist_y

tex_num = curr_map[map_x + map_y * curr_map_width] - 1

wall_x = 0
if side == 0: wall_x = cm.x + perp_wall_dist * ray_dir_y
if side == 1: wall_x = cm.x + perp_wall_dist * ray_dir_x
wall_x -= np.floor(wall_x)

tex_x = int(wall_x * self.tex_w)
if side == 0 and ray_dir_x > 0: tex_x = self.tex_w - tex_x - 1
if side == 1 and ray_dir_y < 0: tex_x = self.tex_w - tex_x - 1

line_height = self.screen.get_height() / perp_wall_dist
line_y0 = self.screen.get_height() // 2 + line_height // 2
line_y0 = min(self.screen.get_height() - 1, line_y0)
line_y1 = self.screen.get_height() // 2 - line_height // 2
line_y1 = max(0, line_y1)

step = self.tex_h / line_height

tex_pos = (line_y0 - self.screen.get_height() // 2 + line_height // 2) * step

same_color_x.insert(x, {})

last_color_y0 = line_y1
for y in range(int(np.floor(line_y1)), int(np.ceil(line_y0))):
tex_y = int(tex_pos) & (self.tex_h - 1)
tex_pos += step

color = self.arrays[tex_num][tex_x][tex_y]
alpha = self.alpha_mask[tex_num]

if not (color & alpha):
if last_color is not None:
pygame.draw.line(self.screen, last_color_rgb, (x, int(last_color_y0)), (x, y - 1))
last_color = None
last_color_y0 = y + 1
continue

if color != last_color:
last_color_y0 = y
last_color = color
if last_color:
a = (last_color >> 24) & 0xFF
r = (last_color >> 16) & 0xFF
g = (last_color >> 8) & 0xFF
b = last_color &  0xFF
last_color_rgb = (int(r), int(g), int(b))

if y == int(line_y0) - 1:
pygame.draw.line(self.screen, last_color_rgb, (x, int(last_color_y0)), (x, y))

last_color = None
Я немного изменил код, чтобы рисовать линии одного цвета вместо рисования попиксельно на экране, но я все еще думаю, что виноват цикл y foor.
Кроме того, я уже читал, как ускорить рендеринг текстур на моем pygame raycaster?, и я думаю, что это не то, что мне нужно...
Я использую OpenGL для раскраски... Как вы думаете, мне следует что-то сделать с этим?
Есть рекомендации?

Вернуться в «Python»