Last active
January 7, 2020 10:27
-
-
Save cchudant/890fe198ba295039b686203c054a158b to your computer and use it in GitHub Desktop.
Cub3d / MiniRT save first frame to .BMP file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* ************************************************************************** */ | |
/* */ | |
/* ::: :::::::: */ | |
/* cube3d.h :+: :+: :+: */ | |
/* +:+ +:+ +:+ */ | |
/* By: cchudant <[email protected]> +#+ +:+ +#+ */ | |
/* +#+#+#+#+#+ +#+ */ | |
/* Created: 2019/10/19 15:14:01 by cchudant #+# #+# */ | |
/* Updated: 2019/11/21 15:09:43 by cchudant ### ########.fr */ | |
/* */ | |
/* ************************************************************************** */ | |
#ifndef CUBE3D_H | |
# define CUBE3D_H | |
# include <stdlib.h> | |
# include <fcntl.h> | |
# include <unistd.h> | |
/* | |
** -- snip -- | |
*/ | |
/* | |
** screenshot | |
*/ | |
typedef struct s_frame_saver | |
{ | |
unsigned char *buf; | |
size_t index; | |
size_t size; | |
} t_frame_saver; | |
t_err save_first_frame(t_state *s, char *filename); | |
/* | |
** -- snip -- | |
*/ | |
#endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* ************************************************************************** */ | |
/* */ | |
/* ::: :::::::: */ | |
/* save_frame.c :+: :+: :+: */ | |
/* +:+ +:+ +:+ */ | |
/* By: cchudant <[email protected]> +#+ +:+ +#+ */ | |
/* +#+#+#+#+#+ +#+ */ | |
/* Created: 2019/11/18 17:23:25 by cchudant #+# #+# */ | |
/* Updated: 2019/11/21 15:28:38 by cchudant ### ########.fr */ | |
/* */ | |
/* ************************************************************************** */ | |
#include "cube3d.h" | |
/* | |
** see https://stackoverflow.com/questions/2654480/writing-bmp-image-in-pure-c-c-without-other-libraries | |
*/ | |
/* | |
** note: little endian | |
*/ | |
static void write_int(t_frame_saver *sv, unsigned int val) | |
{ | |
sv->buf[sv->index++] = val >> 0; | |
sv->buf[sv->index++] = val >> 8; | |
sv->buf[sv->index++] = val >> 16; | |
sv->buf[sv->index++] = val >> 24; | |
} | |
/* | |
** file header | |
** | |
** "BM" (2o) | |
** file size (4o) | |
** null (2o) | |
** null (2o) | |
** 54,0,0,0 (4o) | |
*/ | |
static void write_file_header(t_state *s, t_frame_saver *sv) | |
{ | |
sv->buf[sv->index++] = 'B'; | |
sv->buf[sv->index++] = 'M'; | |
write_int(sv, sv->size); | |
write_int(sv, 0x00000000); | |
sv->buf[sv->index++] = 54; | |
sv->buf[sv->index++] = 0; | |
sv->buf[sv->index++] = 0; | |
sv->buf[sv->index++] = 0; | |
} | |
/* | |
** file info | |
** | |
** 40,0,0,0 (4o) | |
** width (4o) | |
** height (4o) | |
** 1,0 (2o) | |
** 24,0 (2o) | |
** null (24o) | |
*/ | |
static void write_file_info(t_state *s, t_frame_saver *sv) | |
{ | |
int i; | |
sv->buf[sv->index++] = 40; | |
sv->buf[sv->index++] = 0; | |
sv->buf[sv->index++] = 0; | |
sv->buf[sv->index++] = 0; | |
write_int(sv, s->screen_sz.x); | |
write_int(sv, s->screen_sz.y); | |
sv->buf[sv->index++] = 1; | |
sv->buf[sv->index++] = 0; | |
sv->buf[sv->index++] = 24; | |
sv->buf[sv->index++] = 0; | |
i = 0; | |
while (i < 24) | |
{ | |
sv->buf[sv->index++] = 0; | |
i++; | |
} | |
} | |
/* | |
** body | |
** | |
** 1 pixel = 3o (0xBBGGRR) | |
** 1 row = w pixels + padding (0, 1, 2 or 3 for alignement) | |
*/ | |
static void write_body(t_state *s, t_frame_saver *sv) | |
{ | |
int x; | |
int y; | |
y = s->screen_sz.y - 1; | |
while (y >= 0) | |
{ | |
x = 0; | |
while (x < s->screen_sz.x) | |
{ | |
sv->buf[sv->index++] = s->screen[y * s->screen_sz.x + x] >> 0; | |
sv->buf[sv->index++] = s->screen[y * s->screen_sz.x + x] >> 8; | |
sv->buf[sv->index++] = s->screen[y * s->screen_sz.x + x] >> 16; | |
x++; | |
} | |
x = 0; | |
while (x < (4 - (s->screen_sz.x * 3) % 4) % 4) | |
{ | |
sv->buf[sv->index++] = 0; | |
x++; | |
} | |
y--; | |
} | |
} | |
/* | |
** batch write | |
*/ | |
t_err save_first_frame(t_state *s, char *filename) | |
{ | |
int fd; | |
t_frame_saver sv; | |
render(s); | |
sv = (t_frame_saver) { 0 }; | |
sv.size = 54 + 3 * s->screen_sz.x * s->screen_sz.y + | |
((4 - (s->screen_sz.x * 3) % 4) % 4) * s->screen_sz.y; | |
sv.buf = malloc(sv.size); | |
if ((fd = open(filename, O_WRONLY | O_CREAT)) < 0) | |
return (ERR_IO); | |
write_file_header(s, &sv); | |
write_file_info(s, &sv); | |
write_body(s, &sv); | |
write(fd, sv.buf, sv.size); | |
close(fd); | |
return (NULL); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment