github to gitea
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
// render.c
|
||||
#include "cub3d.h"
|
||||
|
||||
static int is_wall(t_app *a, int mx, int my) {
|
||||
if (mx < 0 || my < 0 || mx >= a->map_w || my >= a->map_h) return 1;
|
||||
return (a->map[my][mx] == '1');
|
||||
}
|
||||
|
||||
static void move_player(t_app *a) {
|
||||
double ms = a->move_speed;
|
||||
double rs = a->rot_speed;
|
||||
|
||||
// forward/back
|
||||
if (a->keys.w) {
|
||||
double nx = a->px + a->dirx * ms;
|
||||
double ny = a->py + a->diry * ms;
|
||||
if (!is_wall(a, (int)nx, (int)a->py)) a->px = nx;
|
||||
if (!is_wall(a, (int)a->px, (int)ny)) a->py = ny;
|
||||
}
|
||||
if (a->keys.s) {
|
||||
double nx = a->px - a->dirx * ms;
|
||||
double ny = a->py - a->diry * ms;
|
||||
if (!is_wall(a, (int)nx, (int)a->py)) a->px = nx;
|
||||
if (!is_wall(a, (int)a->px, (int)ny)) a->py = ny;
|
||||
}
|
||||
// strafe
|
||||
if (a->keys.a) {
|
||||
double nx = a->px - a->diry * ms;
|
||||
double ny = a->py + a->dirx * ms;
|
||||
if (!is_wall(a, (int)nx, (int)a->py)) a->px = nx;
|
||||
if (!is_wall(a, (int)a->px, (int)ny)) a->py = ny;
|
||||
}
|
||||
if (a->keys.d) {
|
||||
double nx = a->px + a->diry * ms;
|
||||
double ny = a->py - a->dirx * ms;
|
||||
if (!is_wall(a, (int)nx, (int)a->py)) a->px = nx;
|
||||
if (!is_wall(a, (int)a->px, (int)ny)) a->py = ny;
|
||||
}
|
||||
// rotation
|
||||
if (a->keys.left || a->keys.right) {
|
||||
double angle = (a->keys.left ? -rs : rs);
|
||||
double olddirx = a->dirx;
|
||||
a->dirx = a->dirx * cos(angle) - a->diry * sin(angle);
|
||||
a->diry = olddirx * sin(angle) + a->diry * cos(angle);
|
||||
double oldplanex = a->planex;
|
||||
a->planex = a->planex * cos(angle) - a->planey * sin(angle);
|
||||
a->planey = oldplanex * sin(angle) + a->planey * cos(angle);
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_vertical_line_tex(t_app *a, int x, int drawStart, int drawEnd,
|
||||
t_tex *tex, int texX, double step, double texPos) {
|
||||
if (drawStart < 0) drawStart = 0;
|
||||
if (drawEnd >= WIN_H) drawEnd = WIN_H - 1;
|
||||
|
||||
// plafond (optionnel: couleur unie)
|
||||
for (int y = 0; y < drawStart; ++y)
|
||||
put_pixel(&a->frame, x, y, 0x0080A0); // bleu doux
|
||||
|
||||
for (int y = drawStart; y <= drawEnd; ++y) {
|
||||
int texY = (int)texPos & (tex->h - 1); // textures power-of-two → masque ok
|
||||
texPos += step;
|
||||
int color = get_tex_color(tex, texX, texY);
|
||||
put_pixel(&a->frame, x, y, color);
|
||||
}
|
||||
// sol
|
||||
for (int y = drawEnd + 1; y < WIN_H; ++y)
|
||||
put_pixel(&a->frame, x, y, 0x404040);
|
||||
}
|
||||
|
||||
void render_frame(t_app *a) {
|
||||
// clear: pas nécessaire si on redraw tout (plafond/sol + murs)
|
||||
for (int x = 0; x < WIN_W; ++x) {
|
||||
// camX dans [-1, 1]
|
||||
double cameraX = 2.0 * x / (double)WIN_W - 1.0;
|
||||
double rayDirX = a->dirx + a->planex * cameraX;
|
||||
double rayDirY = a->diry + a->planey * cameraX;
|
||||
|
||||
int mapX = (int)a->px;
|
||||
int mapY = (int)a->py;
|
||||
|
||||
double deltaDistX = (rayDirX == 0) ? 1e30 : fabs(1.0 / rayDirX);
|
||||
double deltaDistY = (rayDirY == 0) ? 1e30 : fabs(1.0 / rayDirY);
|
||||
double sideDistX, sideDistY;
|
||||
int stepX, stepY;
|
||||
|
||||
if (rayDirX < 0) { stepX = -1; sideDistX = (a->px - mapX) * deltaDistX; }
|
||||
else { stepX = 1; sideDistX = (mapX + 1.0 - a->px) * deltaDistX; }
|
||||
if (rayDirY < 0) { stepY = -1; sideDistY = (a->py - mapY) * deltaDistY; }
|
||||
else { stepY = 1; sideDistY = (mapY + 1.0 - a->py) * deltaDistY; }
|
||||
|
||||
int hit = 0, side = 0;
|
||||
while (!hit) {
|
||||
if (sideDistX < sideDistY) { sideDistX += deltaDistX; mapX += stepX; side = 0; }
|
||||
else { sideDistY += deltaDistY; mapY += stepY; side = 1; }
|
||||
if (is_wall(a, mapX, mapY)) hit = 1;
|
||||
}
|
||||
|
||||
double perpWallDist = (side == 0)
|
||||
? (mapX - a->px + (1 - stepX) / 2.0) / rayDirX
|
||||
: (mapY - a->py + (1 - stepY) / 2.0) / rayDirY;
|
||||
if (perpWallDist < 1e-6) perpWallDist = 1e-6;
|
||||
|
||||
int lineHeight = (int)(WIN_H / perpWallDist);
|
||||
int drawStart = -lineHeight / 2 + WIN_H / 2;
|
||||
int drawEnd = lineHeight / 2 + WIN_H / 2;
|
||||
|
||||
// texture selection: 0=N,1=E,2=S,3=W (à adapter selon ta map)
|
||||
int tex_id;
|
||||
if (side == 0 && rayDirX > 0) tex_id = 3; // W
|
||||
else if (side == 0 && rayDirX < 0) tex_id = 1; // E
|
||||
else if (side == 1 && rayDirY > 0) tex_id = 0; // N
|
||||
else tex_id = 2; // S
|
||||
t_tex *tex = &a->tex[tex_id];
|
||||
|
||||
// point d'impact sur le mur
|
||||
double wallX = (side == 0) ? (a->py + perpWallDist * rayDirY)
|
||||
: (a->px + perpWallDist * rayDirX);
|
||||
wallX -= floor(wallX);
|
||||
|
||||
int texX = (int)(wallX * (double)tex->w);
|
||||
if (side == 0 && rayDirX > 0) texX = tex->w - texX - 1;
|
||||
if (side == 1 && rayDirY < 0) texX = tex->w - texX - 1;
|
||||
|
||||
double step = (double)tex->h / (double)lineHeight;
|
||||
double texPos = (drawStart - WIN_H / 2 + lineHeight / 2) * step;
|
||||
|
||||
draw_vertical_line_tex(a, x, drawStart, drawEnd, tex, texX, step, texPos);
|
||||
|
||||
a->zbuf[x] = perpWallDist;
|
||||
}
|
||||
|
||||
mlx_put_image_to_window(a->mlx, a->win, a->frame.ptr, 0, 0);
|
||||
}
|
||||
|
||||
int update(t_app *a) {
|
||||
move_player(a);
|
||||
render_frame(a);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user