pick the wall texture The chosen texture depends on DDA side and ray direction sign.
side == 0 && ray_dir_x > 0 WE side == 0 && ray_dir_x < 0 EA side == 1 && ray_dir_y > 0 SO side == 1 && ray_dir_y < 0 NO Texture mapping is the step that transforms a projected wall slice into actual surface pixels. After DDA has found the hit and projection has computed the slice height, the renderer turns geometry into texture coordinates.
Per-column mapping
Texture mapping happens after wall projection. For each screen column, the renderer chooses a texture, computes `tex_x`, advances `tex_y`, then samples the image buffer into the frame buffer.
pick the wall texture The chosen texture depends on DDA side and ray direction sign.
side == 0 && ray_dir_x > 0 WE side == 0 && ray_dir_x < 0 EA side == 1 && ray_dir_y > 0 SO side == 1 && ray_dir_y < 0 NO compute `wall_x` then `tex_x` The renderer keeps only the fractional hit part on the wall face.
// hit fraction on the wall plane
if (side == 0)
wall_x = player.y + perp_dist * ray_dir_y;
else
wall_x = player.x + perp_dist * ray_dir_x;
wall_x -= floor(wall_x);
tex_x = (int)(wall_x * tex_width);
if (side == 0 && ray_dir_x > 0)
tex_x = tex_width - tex_x - 1;
if (side == 1 && ray_dir_y < 0)
tex_x = tex_width - tex_x - 1; advance `tex_y` across the slice The vertical sampler converts projected wall height into texture rows.
step = (double)tex_height / line_height;
tex_pos = (draw_start - screen_h / 2 + line_height / 2) * step;
for (y = draw_start; y < draw_end; y++)
{
tex_y = (int)tex_pos;
tex_pos += step;
// sample + write pixel
} fractional hit position on the wall face after removing the integer tile coordinate
horizontal texel column derived from `wall_x * tex_width`, then flipped if needed
vertical sampling stride for the projected slice from `draw_start` to `draw_end`
current texture row sampled for the current screen pixel
interactive column preview Move across the wall to inspect `wall_x`, `tex_x`, and the selected texture stripe.
move over the preview sample texture, write frame pixel Each wall pixel now uses a valid texture address and writes a consistent wall color into the frame buffer.
Per screen column, the mapper uses:
side, ray direction, hit tile, perp_dist)draw_start, draw_end, line_height)These values are enough to choose the correct wall texture and the exact texel to sample at each pixel.
Texture mapping
Raycasting gives a hit side, a distance, and an impact point. Mapping turns those values into tex_x and tex_y before writing pixels into frame.addr.
`NO`, `SO`, `WE`, or `EA` depending on the hit face.
`wall_x` becomes `tex_x`.
`tex_pos` advances vertically while drawing.
NO: ray travels south, north face, tex_no texture if (ray.side == 0 && ray.ray_dir_x > 0)
return (&app->tex_we);
if (ray.side == 0)
return (&app->tex_ea);
if (ray.ray_dir_y > 0)
return (&app->tex_no);
return (&app->tex_so); wall_x=0.32 -> tex_x=20 / 64 tex->addr + tex_y * line_len + tex_x * bpp/8 x = ray.x, y = draw_start..draw_end tex_x = (int)(wall_x * (double)tex->width);
step = (double)tex->height / (double)ray.line_height;
tex_pos = (ray.draw_start - app->frame.height / 2
+ ray.line_height / 2) * step;
color = sample_texel(tex, tex_x, (int)tex_pos);
put_pixel(&app->frame, ray.x, y, color); The first decision is which texture family to use.
Base mandatory logic selects directional wall textures:
NOSOWEEABonus mode can replace that with additional wall, door, symbol, or animated texture sources, but the decision still depends on the tile hit and the side reported by DDA.
wall_x represents where the ray hit the wall face, expressed as a fractional
position in [0, 1).
That fraction becomes:
tex_x = (int)(wall_x * tex_width)Then the code flips the result on some faces so opposite directions do not show mirrored textures incorrectly.
Vertical sampling uses the projected wall height:
step = tex_height / line_heighttex_pos starts at the first visible pixel of the slicetex_postex_y comes from the current integer part of that valueThis keeps texture sampling stable even when walls are very tall, clipped, or far away.
For each wall pixel:
At the end of the loop, the wall column is fully resolved and ready for the final image present call.
After texture mapping:
srcs/render/raycast_draw.csrcs/render/raycast.csrcs/core/init_mlx.csrcs_bonus/retro/walls_*.c