From 1274ba29c5ca3f8f8746c6da17a143c0c52b2d7e Mon Sep 17 00:00:00 2001 From: milang Date: Sun, 1 Sep 2019 10:13:17 +0200 Subject: [PATCH] correct some little things on bitmaps --- .gitignore | 3 + doc/html/search/defines_1.html | 30 +++ doc/html/search/defines_1.js | 9 + .../structrender__floating__position.html | 151 ++++++++++++ doc/html/structrender__integer__point.html | 133 +++++++++++ doc/html/structrender__integer__position.html | 151 ++++++++++++ doc/man/man3/render_floating_position.3 | 47 ++++ doc/man/man3/render_integer_point.3 | 40 ++++ doc/man/man3/render_integer_position.3 | 47 ++++ include/fxengine/event/keyboard.h | 27 +++ include/fxengine/render/bitmap.h | 84 +++++++ include/fxengine/render/parameters.h | 17 ++ include/fxengine/render/translate.h | 103 +++++++++ include/fxengine/render/triangle.h | 51 +++++ include/fxengine/render/zbuffer.h | 21 ++ src/keyboard/keyboard.c | 33 +++ src/render/triangle.c | 215 ++++++++++++++++++ 17 files changed, 1162 insertions(+) create mode 100644 doc/html/search/defines_1.html create mode 100644 doc/html/search/defines_1.js create mode 100644 doc/html/structrender__floating__position.html create mode 100644 doc/html/structrender__integer__point.html create mode 100644 doc/html/structrender__integer__position.html create mode 100644 doc/man/man3/render_floating_position.3 create mode 100644 doc/man/man3/render_integer_point.3 create mode 100644 doc/man/man3/render_integer_position.3 create mode 100644 include/fxengine/event/keyboard.h create mode 100644 include/fxengine/render/bitmap.h create mode 100644 include/fxengine/render/parameters.h create mode 100644 include/fxengine/render/translate.h create mode 100644 include/fxengine/render/triangle.h create mode 100644 include/fxengine/render/zbuffer.h create mode 100644 src/keyboard/keyboard.c create mode 100644 src/render/triangle.c diff --git a/.gitignore b/.gitignore index e2646e3..f7576aa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ # Specify filepatterns you want git to ignore. /build/* + +*.c.o +*.c.d diff --git a/doc/html/search/defines_1.html b/doc/html/search/defines_1.html new file mode 100644 index 0000000..7af9324 --- /dev/null +++ b/doc/html/search/defines_1.html @@ -0,0 +1,30 @@ + + + + + + + + + +
+
Loading...
+
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/doc/html/search/defines_1.js b/doc/html/search/defines_1.js new file mode 100644 index 0000000..0b55e10 --- /dev/null +++ b/doc/html/search/defines_1.js @@ -0,0 +1,9 @@ +var searchData= +[ + ['render_5fheight',['render_height',['../parameters_8h.html#a287d41473ee77db859d4d709d66ddb03',1,'parameters.h']]], + ['render_5fmax_5fdist',['render_max_dist',['../parameters_8h.html#a83f9e629cfbf1dcd0de077265b29a1f4',1,'parameters.h']]], + ['render_5fmin_5fdist',['render_min_dist',['../parameters_8h.html#a0ba94ff36e6c2a548735e40012f7ccbd',1,'parameters.h']]], + ['render_5fwidth',['render_width',['../parameters_8h.html#a791a4a111886d2cab059ebc5ab6aa722',1,'parameters.h']]], + ['render_5fx_5fmid',['render_x_mid',['../parameters_8h.html#a887e6ccc340beb6774eb95667d3bfe05',1,'parameters.h']]], + ['render_5fy_5fmid',['render_y_mid',['../parameters_8h.html#ab67f355ab6184dcd911f0bf9380196c4',1,'parameters.h']]] +]; diff --git a/doc/html/structrender__floating__position.html b/doc/html/structrender__floating__position.html new file mode 100644 index 0000000..1d11a46 --- /dev/null +++ b/doc/html/structrender__floating__position.html @@ -0,0 +1,151 @@ + + + + + + + +FxEngine: render_floating_position Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
FxEngine +  0.0.1 +
+
3d engine for fx9860G calculators
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
render_floating_position Struct Reference
+
+
+ +

this struct is a point in 3d, which has coords save as double it is not recommended to use it for high performances rendering, because of the sh3eb-elf architecture, which does not support natively floating calculation + More...

+ +

#include <translate.h>

+ + + + + + + + +

+Data Fields

double x
 
double y
 
double z
 
+

Detailed Description

+

this struct is a point in 3d, which has coords save as double it is not recommended to use it for high performances rendering, because of the sh3eb-elf architecture, which does not support natively floating calculation

+ +

Definition at line 23 of file translate.h.

+

Field Documentation

+ +

◆ x

+ +
+
+ + + + +
double x
+
+ +

Definition at line 25 of file translate.h.

+ +
+
+ +

◆ y

+ +
+
+ + + + +
double y
+
+ +

Definition at line 25 of file translate.h.

+ +
+
+ +

◆ z

+ +
+
+ + + + +
double z
+
+ +

Definition at line 25 of file translate.h.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + diff --git a/doc/html/structrender__integer__point.html b/doc/html/structrender__integer__point.html new file mode 100644 index 0000000..d088dd2 --- /dev/null +++ b/doc/html/structrender__integer__point.html @@ -0,0 +1,133 @@ + + + + + + + +FxEngine: render_integer_point Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
FxEngine +  0.0.1 +
+
3d engine for fx9860G calculators
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
render_integer_point Struct Reference
+
+
+ +

This is a point which is used for 3d translations and rendering integer mode is the best solution to increase perfs, and that's why I didn't have implemented te floating_points yet. + More...

+ +

#include <translate.h>

+ + + + + + +

+Data Fields

render_integer_position real
 
render_integer_position translated
 
+

Detailed Description

+

This is a point which is used for 3d translations and rendering integer mode is the best solution to increase perfs, and that's why I didn't have implemented te floating_points yet.

+ +

Definition at line 36 of file translate.h.

+

Field Documentation

+ +

◆ real

+ +
+
+ + + + +
render_integer_position real
+
+ +

Definition at line 38 of file translate.h.

+ +
+
+ +

◆ translated

+ +
+
+ + + + +
render_integer_position translated
+
+ +

Definition at line 38 of file translate.h.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + diff --git a/doc/html/structrender__integer__position.html b/doc/html/structrender__integer__position.html new file mode 100644 index 0000000..f7d220e --- /dev/null +++ b/doc/html/structrender__integer__position.html @@ -0,0 +1,151 @@ + + + + + + + +FxEngine: render_integer_position Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
FxEngine +  0.0.1 +
+
3d engine for fx9860G calculators
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
render_integer_position Struct Reference
+
+
+ +

this struct is a point in 3d, which has coords save as uint32_t this is the recommended type for high performance rendering, because the sh3eb-elf architecture is 32 bits + More...

+ +

#include <translate.h>

+ + + + + + + + +

+Data Fields

int32_t x
 
int32_t y
 
int32_t z
 
+

Detailed Description

+

this struct is a point in 3d, which has coords save as uint32_t this is the recommended type for high performance rendering, because the sh3eb-elf architecture is 32 bits

+ +

Definition at line 11 of file translate.h.

+

Field Documentation

+ +

◆ x

+ +
+
+ + + + +
int32_t x
+
+ +

Definition at line 13 of file translate.h.

+ +
+
+ +

◆ y

+ +
+
+ + + + +
int32_t y
+
+ +

Definition at line 13 of file translate.h.

+ +
+
+ +

◆ z

+ +
+
+ + + + +
int32_t z
+
+ +

Definition at line 13 of file translate.h.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + diff --git a/doc/man/man3/render_floating_position.3 b/doc/man/man3/render_floating_position.3 new file mode 100644 index 0000000..0bc1e9f --- /dev/null +++ b/doc/man/man3/render_floating_position.3 @@ -0,0 +1,47 @@ +.TH "render_floating_position" 3 "Fri Aug 30 2019" "Version 0.0.1" "FxEngine" \" -*- nroff -*- +.ad l +.nh +.SH NAME +render_floating_position \- this struct is a point in 3d, which has coords save as double it is not recommended to use it for high performances rendering, because of the sh3eb-elf architecture, which does not support natively floating calculation + +.SH SYNOPSIS +.br +.PP +.PP +\fC#include \fP +.SS "Data Fields" + +.in +1c +.ti -1c +.RI "double \fBx\fP" +.br +.ti -1c +.RI "double \fBy\fP" +.br +.ti -1c +.RI "double \fBz\fP" +.br +.in -1c +.SH "Detailed Description" +.PP +this struct is a point in 3d, which has coords save as double it is not recommended to use it for high performances rendering, because of the sh3eb-elf architecture, which does not support natively floating calculation +.PP +Definition at line 23 of file translate\&.h\&. +.SH "Field Documentation" +.PP +.SS "double x" + +.PP +Definition at line 25 of file translate\&.h\&. +.SS "double y" + +.PP +Definition at line 25 of file translate\&.h\&. +.SS "double z" + +.PP +Definition at line 25 of file translate\&.h\&. + +.SH "Author" +.PP +Generated automatically by Doxygen for FxEngine from the source code\&. diff --git a/doc/man/man3/render_integer_point.3 b/doc/man/man3/render_integer_point.3 new file mode 100644 index 0000000..96e136e --- /dev/null +++ b/doc/man/man3/render_integer_point.3 @@ -0,0 +1,40 @@ +.TH "render_integer_point" 3 "Fri Aug 30 2019" "Version 0.0.1" "FxEngine" \" -*- nroff -*- +.ad l +.nh +.SH NAME +render_integer_point \- This is a point which is used for 3d translations and rendering integer mode is the best solution to increase perfs, and that's why I didn't have implemented te floating_points yet\&. + +.SH SYNOPSIS +.br +.PP +.PP +\fC#include \fP +.SS "Data Fields" + +.in +1c +.ti -1c +.RI "\fBrender_integer_position\fP \fBreal\fP" +.br +.ti -1c +.RI "\fBrender_integer_position\fP \fBtranslated\fP" +.br +.in -1c +.SH "Detailed Description" +.PP +This is a point which is used for 3d translations and rendering integer mode is the best solution to increase perfs, and that's why I didn't have implemented te floating_points yet\&. +.PP +Definition at line 36 of file translate\&.h\&. +.SH "Field Documentation" +.PP +.SS "\fBrender_integer_position\fP real" + +.PP +Definition at line 38 of file translate\&.h\&. +.SS "\fBrender_integer_position\fP translated" + +.PP +Definition at line 38 of file translate\&.h\&. + +.SH "Author" +.PP +Generated automatically by Doxygen for FxEngine from the source code\&. diff --git a/doc/man/man3/render_integer_position.3 b/doc/man/man3/render_integer_position.3 new file mode 100644 index 0000000..223b31b --- /dev/null +++ b/doc/man/man3/render_integer_position.3 @@ -0,0 +1,47 @@ +.TH "render_integer_position" 3 "Fri Aug 30 2019" "Version 0.0.1" "FxEngine" \" -*- nroff -*- +.ad l +.nh +.SH NAME +render_integer_position \- this struct is a point in 3d, which has coords save as uint32_t this is the recommended type for high performance rendering, because the sh3eb-elf architecture is 32 bits + +.SH SYNOPSIS +.br +.PP +.PP +\fC#include \fP +.SS "Data Fields" + +.in +1c +.ti -1c +.RI "int32_t \fBx\fP" +.br +.ti -1c +.RI "int32_t \fBy\fP" +.br +.ti -1c +.RI "int32_t \fBz\fP" +.br +.in -1c +.SH "Detailed Description" +.PP +this struct is a point in 3d, which has coords save as uint32_t this is the recommended type for high performance rendering, because the sh3eb-elf architecture is 32 bits +.PP +Definition at line 11 of file translate\&.h\&. +.SH "Field Documentation" +.PP +.SS "int32_t x" + +.PP +Definition at line 13 of file translate\&.h\&. +.SS "int32_t y" + +.PP +Definition at line 13 of file translate\&.h\&. +.SS "int32_t z" + +.PP +Definition at line 13 of file translate\&.h\&. + +.SH "Author" +.PP +Generated automatically by Doxygen for FxEngine from the source code\&. diff --git a/include/fxengine/event/keyboard.h b/include/fxengine/event/keyboard.h new file mode 100644 index 0000000..e910d92 --- /dev/null +++ b/include/fxengine/event/keyboard.h @@ -0,0 +1,27 @@ +#ifndef FE_KEYBOARD +#define FE_KEYBOARD + +#include +#include +#include + +/* FE_keyboard: gestion evenementielle du clavier + on peut assigner des callbacks à certains evènements définis dans gint + les arguments envoyés sont le code de la touche en question (event.key) + le type d'evenement (event.type) + void (*callback)(void) + la fonction à exécuter en cas de pression sur une touche + la fonction reload est appelée à la demande de l'utilisateur et appelle tous les callbacks dans l'ordre */ + +typedef void (*callback)(void); + +void event_keyboard_set_key(uint32_t matrix_code, uint32_t ev_type, callback function); + +// reload all key events and call callbacks +void event_keyboard_reload(); + +//void event_keyboard_start(); + +//void event_keyboard_stop(); + +#endif \ No newline at end of file diff --git a/include/fxengine/render/bitmap.h b/include/fxengine/render/bitmap.h new file mode 100644 index 0000000..6dd8b89 --- /dev/null +++ b/include/fxengine/render/bitmap.h @@ -0,0 +1,84 @@ +#ifndef RENDER_BITMAP +#define RENDER_BITMAP + +#include +#include + +/** + * @brief bitmap rich type + * transparency is in the layout + * @warning Monochrome only ! + */ +struct bitmap_rich +{ + uint32_t size_px_x; + uint32_t size_px_y; + uint32_t size_o_y; + + uint32_t * color; + bool color_dynamic; + uint32_t * layout; + bool layout_dynamic; +}; +typedef struct bitmap_rich bitmap_rich; + + +/** + * @brief { function_description } + * + * @param[in] size_px_x The width in px + * @param[in] size_px_y The height in px + * @param color color origin + * @param[in] copy_color if you want to make a copy, or only to make a link + * @param layout layout origin -> can be set as 0 if it isn't needed + * @param[in] copy_layout if you want to make a copy, or to make a link + * + * @return a rich bitmap, ready to use ! + */ +bitmap_rich* bitmap_new_rich(uint32_t size_px_x, uint32_t size_px_y, uint32_t* color, bool copy_color, + uint32_t *layout, bool copy_layout); + +/** + * @brief delete a rich bitmap created with bitmap_new_rich() + * + * @param bmp The bitmap to delete + */ +void bitmap_delete_rich(bitmap_rich* bmp); + + +/** + * @brief get the color of pixel from rich bitmap + * + * @param[in] bmp The bitmap + * @param[in] x The bitmap x coordinate (in pixels) + * @param[in] y The bitmap y coordinate (in pixels) + * + * @return the color coded in a unsigned char : + * if (color >> 1) + * switch (color%2) + * { + * case 0: + * // WHITE + * break; + * case 1: + * // BLACK + * } + * else + */ +uint8_t bitmap_get_pixel_r(const bitmap_rich * bmp, uint32_t x, uint32_t y); + + +/** + * @brief display a specific rich bitmap pixel on the screen + * + * @param[in] bmp The bitmap + * @param[in] bmp_x The bitmap x coordinate (in pixels) + * @param[in] bmp_y The bitmap y coordinate (in pixels) + * @param[in] x screen : x coordinate + * @param[in] y screen : y coordinate + */ +void bitmap_display_pixel_r(const bitmap_rich * bmp, uint32_t bmp_x, uint32_t bmp_y, uint32_t x, uint32_t y); + + + +#endif diff --git a/include/fxengine/render/parameters.h b/include/fxengine/render/parameters.h new file mode 100644 index 0000000..02cb5bd --- /dev/null +++ b/include/fxengine/render/parameters.h @@ -0,0 +1,17 @@ +#ifndef RENDER_PARAM +#define RENDER_PARAM + + +// Render param + +#define render_width 128 +#define render_height 64 +#define render_x_mid ((render_width - 1) / 2) // depends on screen width +#define render_y_mid ((render_height - 1) / 2) + +#define render_max_dist 3000 +#define render_min_dist 1 + + + +#endif \ No newline at end of file diff --git a/include/fxengine/render/translate.h b/include/fxengine/render/translate.h new file mode 100644 index 0000000..3533e1b --- /dev/null +++ b/include/fxengine/render/translate.h @@ -0,0 +1,103 @@ +#ifndef RENDER_TRANSLATE_H +#define RENDER_TRANSLATE_H + +#include +#include + +/** + * @brief this struct is a point in 3d, which has coords save as uint32_t + * this is the recommended type for high performance rendering, because the sh3eb-elf architecture is 32 bits + */ +struct render_integer_position +{ + int32_t x, + y, + z; +}; +typedef struct render_integer_position render_integer_position; + +/** + * @brief this struct is a point in 3d, which has coords save as double + * it is not recommended to use it for high performances rendering, because of the sh3eb-elf architecture, which does not support natively floating calculation + */ +struct render_floating_position +{ + double x, + y, + z; +}; +typedef struct render_floating_position render_floating_position; + + +/** + * @brief This is a point which is used for 3d translations and rendering + * integer mode is the best solution to increase perfs, and that's why I didn't have implemented te floating_points yet. + */ +struct render_integer_point +{ + render_integer_position real; + render_integer_position translated; +}; + +typedef struct render_integer_point render_integer_point; + + +// applique la matrice de rotation et les deltas sur les coordonnées d'un point + +/** + * @brief This function rotates and applies perspective on an integer point + * + * @param point The point which needs to be translated + */ +void render_translate(render_integer_point * point); + + + +/** + * @brief Sets up the translation matrices for a new rendering cycle + * There is no need to call this function if you have already called render_update() + * + * @param[in] dh Camera's horizontal direction (rad) + * @param[in] dv Camera's vertical direction (rad) + * @param[in] roulis Optionnal rotation around the middle of the screen + * @param[in] camera The camera's coordinates, as an integer position + */ +void render_set(const double dh, const double dv, const double roulis, const render_integer_position * camera); + + + +/** + * mathematics constants + */ +extern const double pi, pi2, pi_sur_2; + + +/** + * @brief Sets up an angle mesure between -pi and +pi + * + * @param[in] a the angle (rad) + * + * @return angle mesure which respect the following contraint : + * -pi <= angle <= pi + */ +double modulo_2pi(double a); + +/** + * @brief Homemade cosinus implementation, which is faster than casio provided cosinus function + * + * @param[in] angle The angle (rad) + * + * @return cos angle + */ +double cos(double angle); + +/** + * @brief Homemade sinus implementation, which is faster than casio provided sinus function + * + * @param[in] angle The angle (rad) + * + * @return sin angle + */ +double sin(const double angle); + +#endif diff --git a/include/fxengine/render/triangle.h b/include/fxengine/render/triangle.h new file mode 100644 index 0000000..dc97bf7 --- /dev/null +++ b/include/fxengine/render/triangle.h @@ -0,0 +1,51 @@ +#ifndef RENDER_TRIANGLE_H +#define RENDER_TRIANGLE_H + +#include +#include +#include + +/** + * @brief Regulates the maximum fps count to 30 fps + */ +#define MINIMUM_FRAME_DELAY 3333 + +/** + * @brief Triangle struct used to render fonctions + * @param[out] part choose the used texture half + * @param[out] clockwised choose the visible side of the face + * @param[out] s1,s2,s3 three points + * @param[out] texture used texture + */ +struct render_triangle +{ + render_integer_position * s1; + render_integer_position * s2; + render_integer_position * s3; + + bitmap_rich * texture; + + bool part; + bool clockwised; +}; +typedef struct render_triangle render_triangle; + +/** + * @brief Renders a triangle with perspective deformation + * + * @param[in] face pointer to the face to draw + */ +void render_display_triangle(const render_triangle * face); + +/** + * @brief Clears vram, zbuffer + * + * @param[in] libprof_channel The libprof channel to be used to count_fps + * @param[in] dh Horizontal direction (rad) + * @param[in] dv Vertical direction (rad) + * @param[in] roulis The roulis (rad) + * @param[in] camera Pointer to the camera + */ +void render_update(const uint32_t libprof_channel); + +#endif diff --git a/include/fxengine/render/zbuffer.h b/include/fxengine/render/zbuffer.h new file mode 100644 index 0000000..47371f9 --- /dev/null +++ b/include/fxengine/render/zbuffer.h @@ -0,0 +1,21 @@ +#ifndef RENDER_ZBUFFER +#define RENDER_ZBUFFER + +#include +#include + +/** FE_zbuffer_clear + * effacer le z buffer pour un nouveau cycle de dessin + * TODO : ajouter effacement avec le DMA Controller pour les modèles ayant un processeur SH4-A +**/ +void render_zbuffer_clear(); + +#include +/** FE_zbuffer_set_dist + * change la distance d'un pixel du zbuffer + * retourne true si il faut dessiner le pixel + * retourne false si le pixel est déjà existant +**/ +bool render_zbuffer_set_px(uint32_t x, uint32_t y, uint32_t dist); // if you are allowed to draw the pixel on vram + +#endif diff --git a/src/keyboard/keyboard.c b/src/keyboard/keyboard.c new file mode 100644 index 0000000..a9b773d --- /dev/null +++ b/src/keyboard/keyboard.c @@ -0,0 +1,33 @@ +#include + +static callback callbacks[3][6][10]={0}; + +static inline uint32_t get_x(const uint32_t matrix_code) +{ + return (matrix_code-1) % 0x10; +} + +static inline uint32_t get_y(const uint32_t matrix_code) +{ + return (matrix_code-1) / 0x10; +} + +void FE_keyboard_reload() +{ + key_event_t event; + while (1) + { + event=pollevent(); + event.type--; + if (event.type==-1) + break; + callback action = callbacks[event.type][get_x(event.key)][get_y(event.key)]; + if (action) + action(); + } +} + +void FE_keyboard_set_key(uint32_t matrix_code, uint32_t ev_type, callback function) +{ + callbacks[ev_type-1][get_x(matrix_code)][get_y(matrix_code)]=function; +} diff --git a/src/render/triangle.c b/src/render/triangle.c new file mode 100644 index 0000000..7820c6d --- /dev/null +++ b/src/render/triangle.c @@ -0,0 +1,215 @@ +#include +#include +#include +#include + +#include + +#include +#include + +static uint32_t frame_interval_min; +static uint32_t frame_interval_max; + +void render_update(const uint32_t libprof_channel) +{ + //dupdate(); + + // gestion du temps avec libprof + if (prof_elapsed) + { + prof_leave(0); + uint32_t frame_interval = prof_time(0); + //sleep_us(0, MINIMUM_FRAME_DELAY-frame_interval); + if (frame_intervalframe_interval_max) + frame_interval_max = frame_interval; + } + else + { + prof_init(libprof_channel+1, 0); + } + //dupdate(); + prof_clear(0); + prof_enter(0); + + render_zbuffer_clear(); + + ///render_set(dh, dv, roulis, camera); + + dclear(C_WHITE); +} + +/** + * @brief Orientation of the face + * + * @param face The face + * + * @return if it is true the it is clockwised else it isn't clockwised + */ +static bool is_colckwised(render_triangle const * face) +{ + int32_t area = 0; + + area += face->s1->x * face->s2->y; + area -= face->s2->x * face->s1->y; + + area += face->s2->x * face->s3->y; + area -= face->s3->x * face->s2->y; + + area += face->s3->x * face->s1->y; + area -= face->s1->x * face->s3->y; + + return (area < 0); +} + + +// gestion locale des arètes +typedef struct line line; +struct line +{ + int32_t x,y,z; + int32_t dx,dy,dz; + int32_t no_line; // si les deux points sont confondus (se comporte comme un bool) +}; + +/** + * @brief Sets up a line with 2 points + * + * @param l The line + * @param s1 The s 1 + * @param s2 The s 2 + */ +static void line_set(line* l,render_integer_position const * s1, render_integer_position const * s2) +{ + l->x = s1->x; + l->y = s1->y; + l->z = s1->z; + l->dx = s2->x - s1->x; + l->dy = s2->y - s1->y; + l->dz = s2->z - s1->z; + l->no_line = (l->dx==0 && l->dy==0); +} + +static int32_t max(int32_t x, int32_t y) +{ + return (x>y ? x : y); +} + +static int32_t min(int32_t x, int32_t y) +{ + return (xy; + if (y < 0 && l->dy > 0) + return false; + if (y > 0 && l->dy < 0) + return false; + if (abs(y) > abs(l->dy)) + return false; + + if (l->dy != 0) + *x = l->x + (y * l->dx) / l->dy; + else if (y==0) + *x = l->x + l->dx; + else + return false; + return true; +} + + +void render_display_triangle(const render_triangle * face) +{ + // backface culling + if (is_colckwised(face) != face->clockwised) + return; + + // incomplete clipping + if (face->s1->x < 0 && face->s2->x < 0 && face->s3->x < 0) + return; + if (face->s1->x >= render_width && face->s2->x >= render_width && face->s3->x >= render_width) + return; + if (face->s1->y < 0 && face->s2->y < 0 && face->s3->y < 0) + return; + if (face->s1->y >= render_height && face->s2->y >= render_height && face->s3->y >= render_height) + return; + if (face->s1->z <= 0 && face->s2->z <= 0 && face->s3->z <= 0) + return; + + line cotes[3]; + line_set(&cotes[0], face->s1, face->s2); + line_set(&cotes[1], face->s1, face->s3); + line_set(&cotes[2], face->s2, face->s3); + + if (cotes[0].no_line || cotes[1].no_line || cotes[2].no_line) + return; + + const int32_t ymin = max(min(face->s1->y, min(face->s2->y, face->s3->y)), 0); + const int32_t ymax = min(max(face->s1->y, max(face->s2->y, face->s3->y)), 63); + + const int32_t xAB = face->s2->x - face->s1->x, yAB = face->s2->y - face->s1->y, zAB=face->s2->z-face->s1->z; + const int32_t xAC = face->s3->x - face->s1->x, yAC = face->s3->y - face->s1->y, zAC=face->s3->z-face->s1->z; + const int32_t diviseur_commun = (xAB * yAC - yAB * xAC); + + const int32_t fact_1= (32768 * yAC) / diviseur_commun, fact_2 = (32768 * xAC) / diviseur_commun; + const int32_t fact_3= (32768 * xAB) / diviseur_commun, fact_4 = (32768 * yAB) / diviseur_commun; + + for (int32_t y = ymin; y <= ymax; y++) + { + // xmin and xmax determination + int32_t tx1,tx2; + + for (int t=0;t<3;t++) + { + if (line_get_x(y,&cotes[t],&tx1)) + break; + } + for (int32_t t=0;t<3;t++) + { + if (line_get_x(y,&cotes[t],&tx2)&&tx1!=tx2) + break; + } + + const int32_t txmin=max(min(tx1,tx2),0), txmax=min(max(tx1,tx2),127); + + for (int32_t x=txmin; x<=txmax; x++) + { + double vx, vy, z; + const double xcalc = x - face->s1->x, ycalc = y - face->s1->y; + // calcul de vx, vy + vx=(xcalc*fact_1-ycalc*fact_2); // 0 s1->z + (vx * zAB + vy * zAC) / 32768; + vx /= 32768; + vy /= 32768; + + vx /= (double) face->s2->z / ((1 - vx) / face->s1->z + vx / (double) face->s2->z); + vy /= (double) face->s3->z / ((1 - vy) / face->s1->z + vy / (double) face->s3->z); + + // Affichage du point + const uint8_t color = bitmap_get_pixel_r(face->texture, 8*vx, 8*vy); + + if (color) + if (render_zbuffer_set_px(x,y,z)) + dpixel(x, y, 3 * (color % 2)); // 3* means cast to black and white, and vx,and vy casted between 0 and 7 + } + } +}