Compare commits
53 Commits
Author | SHA1 | Date |
---|---|---|
Milang | f8da258442 | |
Milang | fc77fef9a7 | |
Milang | 0fc0adac49 | |
Milang | 6d745d454a | |
Milang | 51d65485ac | |
Milang | 3c66554835 | |
Milang | fc0071f83e | |
Milang | f8129c8b18 | |
Milang | 84e656d30a | |
Milang | 8b8f8d511a | |
Milang | a413ec89a9 | |
Milang | cf9e329580 | |
Milang | 6911776aca | |
Milang | 1730d98911 | |
Milang | 4c534571fd | |
Milang | 33396b4af2 | |
Milang | 1f6ba41298 | |
Milang | 2c8e7cb263 | |
Milang | f69227192d | |
Milang | c01a6cd9c0 | |
Milang | 7a621ae56b | |
Milang | e882cfbfee | |
Milang | 05b98c77e3 | |
Milang | e21d481b78 | |
Milang | 4dd7b142c4 | |
Milang | f2e3c92f65 | |
Milang | 06a4bf2fc8 | |
Milang | 771524e4eb | |
Milang | 53c5489da6 | |
Milang | b9c84f7823 | |
Milang | 9731133706 | |
Milang | be6214a41e | |
Milang | 371251f049 | |
Milang | 8a49bb2c9a | |
Milang | 83ef2c7465 | |
Milang | c806ee9c07 | |
Milang | 54a31fdbca | |
Milang | 69c2f79095 | |
Milang | f11d89d4cf | |
Milang | 33c45d0718 | |
Milang | f32a2bc7b6 | |
Milang | 419b74c5d0 | |
Milang | 29d85cd5a9 | |
Milang | e59dac5b8d | |
Milang | b9620fdebc | |
Milang | fc2389d605 | |
Milang | 8c48f584f0 | |
Milang | f18ebfd828 | |
Milang | 1db17f353a | |
Milang | 501a36ec69 | |
Milang | 25534c69af | |
Milang | 39e25c13e5 | |
Milang | da72997a6e |
|
@ -9,3 +9,4 @@ Doxyfile
|
|||
|
||||
*.tar.xz
|
||||
*.cfg
|
||||
*.directory
|
|
@ -1,30 +0,0 @@
|
|||
#ifndef FE_CAMERA
|
||||
#define FE_CAMERA
|
||||
|
||||
#include <fxengine/space.h>
|
||||
|
||||
struct fe_camera
|
||||
{
|
||||
fe_ipoint pos; // point of view
|
||||
fe_fpoint pos_temp; // floating copy used while moving
|
||||
|
||||
double dh, dv, roll;
|
||||
};
|
||||
typedef struct fe_camera fe_camera;
|
||||
|
||||
/**
|
||||
* @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 fe_view_set_param(const double dh, const double dv, const double roulis, const fe_ipoint * camera);
|
||||
|
||||
void fe_view_set(const fe_camera * cam);
|
||||
|
||||
|
||||
|
||||
#endif
|
|
@ -1,20 +1,19 @@
|
|||
#ifndef FE_FXENGINE
|
||||
#define FE_FXENGINE
|
||||
|
||||
#include <stdint.h>
|
||||
#include <fxengine/model/object.h>
|
||||
|
||||
/**
|
||||
* @brief Clears zbuffer, counts fps and log settings
|
||||
*
|
||||
* @param[in] libprof_channel The libprof channel to be used to count_fps
|
||||
* if you don't use libprof channel, (default), you send what you want,
|
||||
* it doesn't matters ;)
|
||||
*/
|
||||
void fe_update(const uint32_t libprof_channel);
|
||||
void fe_add_object(fe_object * const o);
|
||||
void fe_del_object(fe_object * const o);
|
||||
|
||||
/* updates and clears vram, than calls fe_update */
|
||||
void fe_display(const uint32_t libprof_channel);
|
||||
void fe_load(); // Lance le thread de rendering
|
||||
void fe_quit(); // Appelee depuis un timer, cette fonction rend la main au programme à la fin de la frame
|
||||
|
||||
void fe_custom_panic();
|
||||
// Callbacks (a executer au début et à la fin d'une interruption intervenant sur l'affichage)
|
||||
void fe_callback_start();
|
||||
void fe_callback_end();
|
||||
void fe_draw(); // draw image, mais pour le rendu 3D
|
||||
|
||||
uint32_t fe_get_fps(); // Pas la fréquence d'affichage, mais la fréquence de rendu
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef FE_MATH
|
||||
#define FE_MATH
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Custom calculation depth for trigonometric functions
|
||||
void fe_set_trigo(uint32_t p);
|
||||
|
||||
uint32_t fe_get_trigo(void);
|
||||
|
||||
|
||||
double fe_modulo_2pi(double a);
|
||||
|
||||
double fe_cos(double angle);
|
||||
|
||||
double fe_sin(const double angle);
|
||||
|
||||
/**
|
||||
* mathematics constants
|
||||
* TODO déplacer dans caméra
|
||||
*/
|
||||
#define pi 3.14159265358
|
||||
#define pi2 6.28318530718
|
||||
#define pi_sur_2 1.57079632679
|
||||
|
||||
#endif
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef FE_MATRIX
|
||||
#define FE_MATRIX
|
||||
|
||||
#include <fxengine/model/vertex.h>
|
||||
#include <fxengine/model/camera.h>
|
||||
|
||||
void fe_vertex_translate(fe_vertex const * const source, fe_vertex * target);
|
||||
void fe_set_matrix(fe_camera const cam);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef FE_MODEL_BITMAP
|
||||
#define FE_MODEL_BITMAP
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/* bitmap model
|
||||
transparency is in the layout
|
||||
this color type is monochrome only ! */
|
||||
typedef struct
|
||||
{
|
||||
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;
|
||||
} fe_bitmap;
|
||||
|
||||
|
||||
fe_bitmap* fe_bitmap_new(uint32_t size_px_x, uint32_t size_px_y, uint32_t* color, bool copy_color, uint32_t *layout, bool copy_layout);
|
||||
|
||||
void fe_bitmap_del(fe_bitmap * bmp);
|
||||
|
||||
|
||||
/* fe_bitmap_get_pixel()
|
||||
returns the color of a pixel in the gint's type*/
|
||||
uint8_t fe_bitmap_get_px(const fe_bitmap * bmp, uint32_t x, uint32_t y);
|
||||
|
||||
|
||||
/* fe_bitmap_display_pixel()
|
||||
display a specific rich bitmap pixel on the screen (on vram) */
|
||||
void fe_bitmap_display_px(const fe_bitmap * bmp, uint32_t bmp_x, uint32_t bmp_y, uint32_t scr_x, uint32_t scr_y);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,60 @@
|
|||
# Fxengine::Bitmap
|
||||
This is part of the [fxengine](/Milang/fxengine) project.
|
||||
This file refers to [fxengine/model/bitmap.h](bitmap.h) header.
|
||||
|
||||
## Dependencies
|
||||
<none>
|
||||
|
||||
## Presentation
|
||||
The `fe_bitmap` data structure is a way to use pictures in fxengine. These pictures are saved with a format which is near to the `*.bmp` type.
|
||||
|
||||
## Detail
|
||||
```c
|
||||
typedef struct
|
||||
{
|
||||
uint32_t size_px_x;
|
||||
uint32_t size_px_y;
|
||||
|
||||
uint32_t * color;
|
||||
uint32_t * layout;
|
||||
|
||||
bool color_dynamic;
|
||||
bool layout_dynamic;
|
||||
uint16_t size_o_y;
|
||||
} fe_bitmap;
|
||||
```
|
||||
Here are the most used parameters, the others are used internally by the machine, so they do not need to be initialized.
|
||||
### Size
|
||||
`size_px_x` and `size_px_y` are the bitmap's height and width, in pixels.
|
||||
### Color and layout encoding
|
||||
- `*color` is a pointer to a monochrome bitmap.
|
||||
The format is the following : one bit per pixel: 1 = black, 0 = white.
|
||||
- `*layout` is a pointer to a layout for the previous bitmap.
|
||||
It is one bit per pixel too, and then, 1=visible, 0=invisible.
|
||||
|
||||
## Use
|
||||
### Create
|
||||
It is not recommended to create a bitmap as this :
|
||||
```c
|
||||
fe_bitmap bmp
|
||||
{...};
|
||||
```
|
||||
Please use the function
|
||||
```c
|
||||
fe_bitmap_rich* fe_bitmap_new(
|
||||
uint32_t size_px_x, uint32_t size_px_y, // bitmap size
|
||||
uint32_t* color, bool copy_color, // color table address and type (static | dynamic)
|
||||
uint32_t *layout, bool copy_layout // layout table address and type (static | dynamic)
|
||||
);
|
||||
```
|
||||
The `bool copy_<...>` lets you choose:
|
||||
- if the bitmap header takes data from the pointer you have given.
|
||||
- if the bitmap header needs to copy data itself.
|
||||
|
||||
### Delete
|
||||
The bitmap is dynamically allocated, so it should be deleted by using `free()` method. However, it contains some complex data, which is itself dynamically allocated, so you need to call that method: `fe_bitmap_del()`.
|
||||
The only argument to pass is the bitmap's address.
|
||||
|
||||
### Display
|
||||
You cannot display the bitmap yet, but in fxengine, it is not a priority.
|
||||
However, you can display a specific pixel with `fe_bitmap_display_px()`, or you can get its color with `fe_bitmap_get_px`.
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef FE_CAMERA
|
||||
#define FE_CAMERA
|
||||
|
||||
#include <fxengine/model/vertex.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
fe_vertex pos; // point of view
|
||||
double dh, dv, roll;
|
||||
} fe_camera;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef FE_MODEL_OBJECT
|
||||
#define FE_MODEL_OBJECT
|
||||
|
||||
#include <fxengine/model/vertex.h>
|
||||
#include <fxengine/model/triangle.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
fe_vertex centre; // Emplacement de l'objet
|
||||
|
||||
fe_vertex * vertex_table; // Coordonnées du modèle
|
||||
uint32_t vt_size;
|
||||
bool vt_own;
|
||||
|
||||
fe_triangle * face_table;
|
||||
uint32_t ft_size;
|
||||
bool ft_own;
|
||||
|
||||
// Plage de travail privée
|
||||
fe_vertex * vertex_t0; // vertex_table[x]+centre
|
||||
fe_vertex * vertex_t1; // fe_translate(vertex_t0)
|
||||
fe_vertex old_centre; // Avoid changes during one frame :E
|
||||
} fe_object;
|
||||
|
||||
void fe_object_init(fe_object * object); // Create the object on the zone you allocated
|
||||
|
||||
void fe_object_set_vertex(fe_object * object, fe_vertex * points, uint32_t n, bool copy);
|
||||
|
||||
void fe_object_set_faces(fe_object * object, fe_triangle * faces, uint32_t n, bool copy);
|
||||
|
||||
void fe_object_delete(fe_object * object);
|
||||
|
||||
void fe_object_display(fe_object * object);
|
||||
|
||||
fe_vertex* fe_object_getvx(const fe_object * object, const int n);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef FE_MODEL_TRIANGLE
|
||||
#define FE_MODEL_TRIANGLE
|
||||
|
||||
#include <fxengine/model/vertex.h>
|
||||
#include <fxengine/model/bitmap.h>
|
||||
#include <stdbool.h>
|
||||
/* fe_triangle model
|
||||
this struct makes 3d displaying easier */
|
||||
typedef struct
|
||||
{
|
||||
fe_vertex * s1;
|
||||
fe_vertex * s2;
|
||||
fe_vertex * s3;
|
||||
|
||||
fe_bitmap * texture1;
|
||||
fe_bitmap * texture2;
|
||||
|
||||
bool texture_half;
|
||||
} fe_triangle;
|
||||
|
||||
/* fe_display_triangle()
|
||||
displays a triangle from the previous model */
|
||||
void fe_display_triangle(const fe_triangle * face);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,25 @@
|
|||
# Fxengine::Bitmap
|
||||
This is part of the [fxengine](/Milang/fxengine) project.
|
||||
This file refers to [fxengine/model/triangle.h](triangle.h) header.
|
||||
|
||||
## Dependencies
|
||||
[bitmap.h](bitmap.h) ([doc](bitmap.md))
|
||||
[vertex.h](vertex.h) ([doc](vertex.md))
|
||||
|
||||
## Presentation
|
||||
The `fe_triangle` data structure is a way to display easily faces in fxengine. It helps while you are creating models, or just if you want to reduce code size.
|
||||
|
||||
## Detail
|
||||
```c
|
||||
typedef struct
|
||||
{
|
||||
fe_vertex * s1; // The 3 vertexes
|
||||
fe_vertex * s2;
|
||||
fe_vertex * s3;
|
||||
|
||||
fe_bitmap * texture1; // side 1
|
||||
fe_bitmap * texture2; // side 2
|
||||
|
||||
bool texture_half; // the half used for the textures
|
||||
} fe_triangle;
|
||||
```
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef FE_MODEL_VERTEX
|
||||
#define FE_MODEL_VERTEX
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
int32_t z;
|
||||
} fe_vertex;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
double z;
|
||||
} fe_vertex_d;
|
||||
|
||||
#endif
|
|
@ -1,36 +0,0 @@
|
|||
#ifndef FE_OBJECT
|
||||
#define FE_OBJECT
|
||||
|
||||
#include <fxengine/space.h>
|
||||
#include <fxengine/triangle.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
struct fe_object
|
||||
{
|
||||
fe_triangle * faces;
|
||||
uint32_t f_size;
|
||||
bool f_owner;
|
||||
fe_ivertex * points;
|
||||
uint32_t p_size;
|
||||
bool p_owner;
|
||||
};
|
||||
typedef struct fe_object fe_object;
|
||||
|
||||
void fe_object_init(fe_object * object);
|
||||
|
||||
void fe_object_set_points(fe_object * object, fe_ivertex * points, uint32_t n, bool copy);
|
||||
|
||||
void fe_object_set_faces(fe_object * object, fe_triangle * faces, uint32_t n, bool copy);
|
||||
|
||||
void fe_object_delete(fe_object * object);
|
||||
|
||||
void fe_object_display(fe_object * object);
|
||||
|
||||
void fe_object_debug(const fe_object * object);
|
||||
|
||||
fe_ipoint* fe_object_get_vertex(const fe_object * object, const int n);
|
||||
|
||||
#endif
|
|
@ -1,18 +0,0 @@
|
|||
#ifndef FE_RENDER_PARAM
|
||||
#define FE_RENDER_PARAM
|
||||
|
||||
|
||||
// Render param
|
||||
// You change it as you want before compiling ;)
|
||||
|
||||
#define fe_width 128
|
||||
#define fe_height 64
|
||||
#define fe_x_mid ((fe_width - 1) / 2) // depends on screen width
|
||||
#define fe_y_mid ((fe_height - 1) / 2)
|
||||
|
||||
#define fe_max_dist 3000
|
||||
#define fe_min_dist 1
|
||||
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef RENDER_BUFFER
|
||||
#define RENDER_BUFFER
|
||||
|
||||
#define fe_width 128
|
||||
#define fe_height 64
|
||||
|
||||
void fe_clear_zbuffer();
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
bool fe_zbuffer_set_px(const uint32_t x, const uint32_t y, const uint32_t dist); // true if you are allowed to draw the pixel on vram
|
||||
|
||||
#endif
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef RENDER_TRIANGLE
|
||||
#define RENDER_TRIANGLE
|
||||
|
||||
#include <fxengine/model/vertex.h>
|
||||
#include <fxengine/model/bitmap.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
// ERR CODES
|
||||
#define RENDER_SUCCESSFULLY_RENDERED 0
|
||||
#define RENDER_NOBMP -1
|
||||
#define RENDER_OUT_OF_SCREEN -2
|
||||
#define RENDER_INVISIBLE -3
|
||||
|
||||
#define RENDER_DEBUG_MODE
|
||||
|
||||
|
||||
/* render_triangle()
|
||||
renders a face supporting backface culling, or dual textures */
|
||||
int render_triangle(fe_vertex const s1, fe_vertex const s2, fe_vertex const s3,
|
||||
fe_bitmap const * side_0, fe_bitmap const * side_1, bool texture_half);
|
||||
|
||||
/* render_triangle_nobfc()
|
||||
renders a face without backface culling */
|
||||
int render_triangle_nobfc(fe_vertex const s1, fe_vertex const s2, fe_vertex const s3,
|
||||
fe_bitmap const * side, bool texture_half);
|
||||
|
||||
// Object overlay
|
||||
#include <fxengine/render/triangle.h>
|
||||
#include <fxengine/model/triangle.h>
|
||||
|
||||
void fe_display_triangle(const fe_triangle * face);
|
||||
#endif
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef FR_RENDERLIST
|
||||
#define FR_RENDERLIST
|
||||
|
||||
#include <fxengine/model/object.h>
|
||||
|
||||
// Returns object ID or -1 if it fails
|
||||
int fe_renderlist_add(fe_object * const object);
|
||||
|
||||
// Returns object ID
|
||||
int fe_renderlist_remove(fe_object * const object);
|
||||
|
||||
// Returns object address
|
||||
fe_object * fe_renderlist_remove_id(int id);
|
||||
|
||||
void fe_renderlist_clear(void);
|
||||
|
||||
void fe_render(void);
|
||||
|
||||
#endif
|
|
@ -1,103 +0,0 @@
|
|||
#ifndef FE_SPACE
|
||||
#define FE_SPACE
|
||||
|
||||
// Diverses representations de points dans l'espace
|
||||
|
||||
#include <stdint.h>
|
||||
#include <fxengine/parameters.h>
|
||||
|
||||
|
||||
/**
|
||||
* @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
|
||||
* This is also the type used by the rendering triangles.
|
||||
*/
|
||||
struct fe_ipoint
|
||||
{
|
||||
int32_t x,
|
||||
y,
|
||||
z;
|
||||
};
|
||||
typedef struct fe_ipoint fe_ipoint;
|
||||
|
||||
/**
|
||||
* @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 fe_fpoint
|
||||
{
|
||||
double x,
|
||||
y,
|
||||
z;
|
||||
};
|
||||
typedef struct fe_fpoint fe_fpoint;
|
||||
|
||||
|
||||
/**
|
||||
* @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
|
||||
* the floating_points yet. (Maybe I will never add them)
|
||||
* To render a triangle, you have to set &point.translated as s1, s2 or even s3
|
||||
*/
|
||||
struct fe_ivertex
|
||||
{
|
||||
fe_ipoint real,
|
||||
translated;
|
||||
};
|
||||
typedef struct fe_ivertex fe_ivertex;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Translate a point with camera settings
|
||||
*
|
||||
* @param point The point to translate
|
||||
*/
|
||||
void fe_vertex_translate(fe_ivertex * v);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @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 fe_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 fe_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 fe_sin(const double angle);
|
||||
|
||||
/**
|
||||
* mathematics constants
|
||||
* TODO déplacer dans caméra
|
||||
*/
|
||||
#define pi 3.14159265358
|
||||
#define pi2 6.28318530718
|
||||
#define pi_sur_2 1.57079632679
|
||||
|
||||
// translate matrix
|
||||
extern double fe_matrix[3][3];
|
||||
extern fe_ipoint fe_translate_delta;
|
||||
|
||||
#endif
|
|
@ -1,84 +0,0 @@
|
|||
#ifndef FE_TEXTURE
|
||||
#define FE_TEXTURE
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* @brief texture rich type
|
||||
* transparency is in the layout
|
||||
* @warning Monochrome only !
|
||||
*/
|
||||
struct fe_texture_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 fe_texture_rich fe_texture_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 texture, ready to use !
|
||||
*/
|
||||
fe_texture_rich* fe_texture_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 texture created with texture_new_rich()
|
||||
*
|
||||
* @param txtr The texture to delete
|
||||
*/
|
||||
void fe_texture_delete_rich(fe_texture_rich * txtr);
|
||||
|
||||
|
||||
/**
|
||||
* @brief get the color of pixel from rich texture
|
||||
*
|
||||
* @param[in] txtr The texture
|
||||
* @param[in] x The texture x coordinate (in pixels)
|
||||
* @param[in] y The texture 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 fe_texture_get_pixel_r(const fe_texture_rich * txtr, uint32_t x, uint32_t y);
|
||||
|
||||
|
||||
/**
|
||||
* @brief display a specific rich texture pixel on the screen (on vram)
|
||||
*
|
||||
* @param[in] txtr The texture
|
||||
* @param[in] txtr_x The texture x coordinate (in pixels)
|
||||
* @param[in] txtr_y The texture y coordinate (in pixels)
|
||||
* @param[in] x screen : x coordinate
|
||||
* @param[in] y screen : y coordinate
|
||||
*/
|
||||
void fe_texture_display_pixel_r(const fe_texture_rich * txtr, uint32_t txtr_x, uint32_t txtr_y, uint32_t x, uint32_t y);
|
||||
|
||||
void fe_texture_debug(fe_texture_rich * txtr);
|
||||
|
||||
#endif
|
|
@ -1,42 +0,0 @@
|
|||
#ifndef FE_TRIANGLE
|
||||
#define FE_TRIANGLE
|
||||
|
||||
#include <fxengine/space.h>
|
||||
#include <fxengine/texture.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* @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 fe_triangle
|
||||
{
|
||||
fe_ipoint * s1;
|
||||
fe_ipoint * s2;
|
||||
fe_ipoint * s3;
|
||||
|
||||
fe_texture_rich * texture;
|
||||
|
||||
bool part;
|
||||
bool clockwised;
|
||||
};
|
||||
typedef struct fe_triangle fe_triangle;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Renders a triangle with perspective deformation
|
||||
*
|
||||
* @param[in] face pointer to the face to draw
|
||||
*/
|
||||
void fe_display_triangle(const fe_triangle * face);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
|
@ -1,21 +0,0 @@
|
|||
#ifndef RENDER_ZBUFFER
|
||||
#define RENDER_ZBUFFER
|
||||
|
||||
#include <fxengine/parameters.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/** 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 fe_zbuffer_clear();
|
||||
|
||||
#include <stdbool.h>
|
||||
/** 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 fe_zbuffer_set_px(const uint32_t x, const uint32_t y, const uint32_t dist); // if you are allowed to draw the pixel on vram
|
||||
|
||||
#endif
|
BIN
libfxengine.a
BIN
libfxengine.a
Binary file not shown.
39
src/camera.c
39
src/camera.c
|
@ -1,39 +0,0 @@
|
|||
#include <fxengine/camera.h>
|
||||
#include <gint/std/string.h>
|
||||
|
||||
|
||||
void fe_view_set(const fe_camera * cam)
|
||||
{
|
||||
fe_view_set_param(cam->dh, cam->dv, cam->roll, &cam->pos);
|
||||
}
|
||||
|
||||
|
||||
void fe_view_set_param(const double dh, const double dv, const double roulis, const fe_ipoint * camera)
|
||||
{
|
||||
const double A=fe_cos(dv);
|
||||
const double B=fe_sin(dv);
|
||||
|
||||
const double C=fe_cos(roulis);
|
||||
const double D=fe_sin(roulis);
|
||||
|
||||
const double E=fe_cos(dh);
|
||||
const double F=fe_sin(dh);
|
||||
|
||||
// raccourcis
|
||||
const double AD=A*D, BD=B*D;
|
||||
|
||||
fe_matrix[0][0]=C*E;
|
||||
fe_matrix[0][1]=-C*F;
|
||||
fe_matrix[0][2]=D;
|
||||
|
||||
fe_matrix[1][0]=BD*E+A*F;
|
||||
fe_matrix[1][1]=-BD*F+A*E;
|
||||
fe_matrix[1][2]=-B*C;
|
||||
|
||||
fe_matrix[2][0]=-AD*E+B*F;
|
||||
fe_matrix[2][1]=AD*F+B*E;
|
||||
fe_matrix[2][2]=A*C;
|
||||
|
||||
// assigner delta
|
||||
memcpy(&fe_translate_delta, camera, sizeof(fe_ipoint));
|
||||
}
|
175
src/fxengine.c
175
src/fxengine.c
|
@ -1,112 +1,111 @@
|
|||
#include <fxengine/fxengine.h>
|
||||
#include <fxengine/zbuffer.h>
|
||||
#define GINT_NEED_VRAM
|
||||
|
||||
#include <gint/std/stdio.h>
|
||||
#include <gint/display.h>
|
||||
|
||||
#include <gint/exc.h>
|
||||
#include <gint/defs/attributes.h>
|
||||
#include <stdint.h>
|
||||
#include <fxengine/fxengine.h>
|
||||
#include <gint/std/stdlib.h>
|
||||
#include <gint/std/string.h>
|
||||
#include <stdbool.h>
|
||||
#include <fxengine/renderlist.h>
|
||||
#include <fxengine/render/buffer.h>
|
||||
#ifdef USE_LIBLOG
|
||||
#include <liblog.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_LIBPROF
|
||||
// FPS count
|
||||
#ifdef USE_LIBPROF
|
||||
|
||||
#include <libprof.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_LIBLOG
|
||||
|
||||
#include <liblog.h>
|
||||
|
||||
GNORETURN void system_error(uint32_t code)
|
||||
{
|
||||
ll_display();
|
||||
while(1)
|
||||
getkey();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void fe_custom_panic()
|
||||
{
|
||||
|
||||
#ifdef USE_LIBLOG
|
||||
gint_panic_set(system_error);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_LIBPROF
|
||||
static uint32_t frame_interval_min=1000000;
|
||||
|
||||
static uint32_t frame_interval_max=1;
|
||||
|
||||
static uint32_t fps=0;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
int32_t fe_get_fps()
|
||||
uint32_t fe_get_fps()
|
||||
{
|
||||
#ifdef USE_LIBPROF
|
||||
return fps;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void fe_display(const uint32_t libprof_channel)
|
||||
{
|
||||
fe_update(libprof_channel);
|
||||
|
||||
dupdate();
|
||||
|
||||
#ifdef USE_LIBLOG
|
||||
ll_send("VRAM contents sent.");
|
||||
#endif
|
||||
|
||||
|
||||
// Triple buffering
|
||||
#define BUFFER_SIZE 256
|
||||
static uint32_t triple_buffering_area[2*BUFFER_SIZE]; // 2 buffers supplémentaires
|
||||
static uint32_t * const temp_buffers[2] = {&triple_buffering_area[0], &triple_buffering_area[BUFFER_SIZE]};
|
||||
static uint32_t * gint_vram=0;
|
||||
static uint32_t working_buffer=0;
|
||||
|
||||
static void check_vram()
|
||||
{
|
||||
if (gint_vram==0)
|
||||
gint_vram=vram;
|
||||
}
|
||||
|
||||
void fe_callback_start()
|
||||
{
|
||||
vram=gint_vram;
|
||||
}
|
||||
|
||||
void fe_callback_end()
|
||||
{
|
||||
vram=temp_buffers[working_buffer];
|
||||
}
|
||||
|
||||
void fe_draw()
|
||||
{
|
||||
memcpy(gint_vram, temp_buffers[1-working_buffer], sizeof(uint32_t)*BUFFER_SIZE);
|
||||
}
|
||||
|
||||
void switch_frame()
|
||||
{
|
||||
working_buffer=1-working_buffer;
|
||||
vram=temp_buffers[working_buffer];
|
||||
dclear(C_WHITE);
|
||||
|
||||
#ifdef USE_LIBLOG
|
||||
ll_send("VRAM cleared.");
|
||||
#endif
|
||||
}
|
||||
|
||||
static volatile bool quit=true;
|
||||
|
||||
void fe_update(const uint32_t libprof_channel)
|
||||
void fe_load()
|
||||
{
|
||||
///dupdate();
|
||||
#ifdef USE_LIBPROF
|
||||
// gestion du temps avec libprof
|
||||
if (prof_elapsed)
|
||||
{
|
||||
prof_leave(libprof_channel);
|
||||
uint32_t frame_interval = prof_time(libprof_channel);
|
||||
//sleep_us(0, MINIMUM_FRAME_DELAY-frame_interval);
|
||||
if (frame_interval<frame_interval_min)
|
||||
frame_interval_min = frame_interval;
|
||||
if (frame_interval>frame_interval_max)
|
||||
frame_interval_max = frame_interval;
|
||||
fps=1000000/frame_interval;
|
||||
}
|
||||
else
|
||||
{
|
||||
prof_init(libprof_channel+1, 0);
|
||||
}
|
||||
//dupdate();
|
||||
prof_clear(libprof_channel);
|
||||
prof_enter(libprof_channel);
|
||||
#endif
|
||||
fe_zbuffer_clear();
|
||||
#ifdef USE_LIBLOG
|
||||
ll_send("fxEngine loader :\n");
|
||||
#endif
|
||||
check_vram();
|
||||
#ifdef USE_LIBLOG
|
||||
ll_send(">> Got vram\n");
|
||||
#endif
|
||||
fe_callback_end();
|
||||
#ifdef USE_LIBLOG
|
||||
ll_send(">> Started triple \n buffering\n");
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIBLOG
|
||||
char fps_str[10];
|
||||
sprintf(fps_str, ">> FPS = %d", fps);
|
||||
ll_send(fps_str);
|
||||
#else
|
||||
ll_send(">> FPS not available");
|
||||
#endif
|
||||
//dclear(C_WHITE);
|
||||
quit=false;
|
||||
#ifdef USE_LIBLOG
|
||||
ll_send("run fxEng. thread\n");
|
||||
#endif
|
||||
while (1)
|
||||
{
|
||||
fe_clear_zbuffer();
|
||||
fe_render();
|
||||
#ifdef USE_LIBLOG
|
||||
ll_send("Frame rendered.\n");
|
||||
#endif
|
||||
switch_frame();
|
||||
if (quit)
|
||||
break;
|
||||
}
|
||||
#ifdef USE_LIBLOG
|
||||
ll_send("ended fxEngine.\n");
|
||||
#endif
|
||||
// Free some malloc
|
||||
//// as object list
|
||||
}
|
||||
|
||||
void fe_quit()
|
||||
{
|
||||
quit=1;
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
#include <fxengine/math.h>
|
||||
|
||||
static double reducted_cos(const double a)
|
||||
{
|
||||
double u= 1.0;
|
||||
const double a2 = a * a;
|
||||
for(int32_t p = 17; p>=1; p -= 2)
|
||||
u = 1 - a2 / (p * p + p) * u;
|
||||
return u;
|
||||
}
|
||||
|
||||
// return a with -pi<=a<pi
|
||||
double fe_modulo_2pi(double a)
|
||||
{
|
||||
while (a<=-pi)
|
||||
a += pi2;
|
||||
while (a>pi)
|
||||
a -= pi2;
|
||||
return a;
|
||||
}
|
||||
|
||||
double fe_cos(double angle)
|
||||
{
|
||||
angle = fe_modulo_2pi(angle);
|
||||
if (angle<0)
|
||||
angle=-angle;
|
||||
if (angle>=pi_sur_2)
|
||||
return -reducted_cos(angle - pi);
|
||||
else
|
||||
return reducted_cos(angle);
|
||||
}
|
||||
|
||||
double fe_sin(double angle)
|
||||
{
|
||||
return fe_cos(angle - pi_sur_2);
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
#include <fxengine/matrix.h>
|
||||
#include <fxengine/model/vertex.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef int32_t matrix_type;
|
||||
static matrix_type matrix[3][3]=
|
||||
{
|
||||
{0,0,0},
|
||||
{0,0,0},
|
||||
{0,0,0}
|
||||
};
|
||||
#define matrix_unit 1024
|
||||
static fe_vertex pos_delta;
|
||||
|
||||
#define sgn(x) (x>=0?x:-x)
|
||||
|
||||
void fe_vertex_translate(fe_vertex const * const source, fe_vertex * target)
|
||||
{
|
||||
static fe_vertex temp;
|
||||
temp.x = source->x - pos_delta.x;
|
||||
temp.y = source->y - pos_delta.y;
|
||||
temp.z = source->z - pos_delta.z;
|
||||
|
||||
target->x = matrix[0][0]*temp.x*matrix_unit + matrix[0][1]*temp.y + matrix[0][2]*temp.z;
|
||||
target->z = matrix[1][0]*temp.x*matrix_unit + matrix[1][1]*temp.y + matrix[1][2]*temp.z;
|
||||
target->y = matrix[2][0]*temp.x*matrix_unit + matrix[2][1]*temp.y + matrix[2][2]*temp.z;
|
||||
|
||||
target->z/=(matrix_unit/8);
|
||||
if (target->z>0)
|
||||
{
|
||||
target->x/=target->z;
|
||||
target->y/=target->z;
|
||||
}
|
||||
else
|
||||
{
|
||||
target->x*=256*sgn(target->z);
|
||||
target->y*=256*sgn(target->z);
|
||||
}
|
||||
|
||||
target->x+=63;
|
||||
target->y+=31;
|
||||
}
|
||||
|
||||
void fe_set_matrix(fe_camera const cam)
|
||||
{
|
||||
pos_delta.x = cam.pos.x;
|
||||
pos_delta.y = cam.pos.y;
|
||||
pos_delta.z = cam.pos.z;
|
||||
|
||||
const matrix_type A=matrix_unit*fe_cos(cam.dv);
|
||||
const matrix_type B=matrix_unit*fe_sin(cam.dv);
|
||||
|
||||
const matrix_type C=matrix_unit*fe_cos(cam.roll);
|
||||
const matrix_type D=matrix_unit*fe_sin(cam.roll);
|
||||
|
||||
const matrix_type E=matrix_unit*fe_cos(cam.dh);
|
||||
const matrix_type F=matrix_unit*fe_sin(cam.dh);
|
||||
|
||||
// raccourcis
|
||||
const matrix_type AD=A*D/matrix_unit, BD=B*D/matrix_unit;
|
||||
|
||||
matrix[0][0]=C*E/matrix_unit;
|
||||
matrix[0][1]=-C*F/matrix_unit;
|
||||
matrix[0][2]=D;
|
||||
|
||||
matrix[1][0]=(BD*E+A*F)/matrix_unit;
|
||||
matrix[1][1]=(-BD*F+A*E)/matrix_unit;
|
||||
matrix[1][2]=-B*C/matrix_unit;
|
||||
|
||||
matrix[2][0]=(-AD*E+B*F)/matrix_unit;
|
||||
matrix[2][1]=(AD*F+B*E)/matrix_unit;
|
||||
matrix[2][2]=A*C/matrix_unit;
|
||||
}
|
108
src/object.c
108
src/object.c
|
@ -1,35 +1,55 @@
|
|||
#include <fxengine/object.h>
|
||||
#include <fxengine/model/object.h>
|
||||
|
||||
#include <gint/std/stdlib.h>
|
||||
#include <gint/std/stdio.h>
|
||||
#include <gint/std/string.h>
|
||||
#include <gint/display.h>
|
||||
#include <gint/keyboard.h>
|
||||
#include <gint/std/stdlib.h>
|
||||
|
||||
void fe_object_init(fe_object * object)
|
||||
{
|
||||
memset(object, 0, sizeof(fe_object));
|
||||
}
|
||||
|
||||
|
||||
void fe_object_set_points(fe_object * object, fe_ivertex * points, uint32_t n, bool copy)
|
||||
static void fe_object_delete_vertex(fe_object * object)
|
||||
{
|
||||
if (object->vertex_table==0 && object->vertex_t0==0 && object->vertex_t1==0 && object->vt_size==0)
|
||||
return;
|
||||
|
||||
if (object->vt_own)
|
||||
free(object->vertex_table);
|
||||
else
|
||||
free(object->vertex_t0);
|
||||
|
||||
object->vertex_table=0;
|
||||
object->vertex_t0=0;
|
||||
object->vertex_t1=0;
|
||||
object->vt_size=0;
|
||||
object->vt_own=0;
|
||||
|
||||
}
|
||||
|
||||
void fe_object_set_vertex(fe_object * object, fe_vertex * points, uint32_t n, bool copy)
|
||||
{
|
||||
fe_object_delete_vertex(object);
|
||||
|
||||
if (copy)
|
||||
{
|
||||
object->points = malloc(n*sizeof(fe_ipoint));
|
||||
if (!object->points)
|
||||
object->vertex_table = malloc(3*n*sizeof(fe_vertex)); // Centraliser les données de copie
|
||||
if (!object->vertex_table)
|
||||
return;
|
||||
memcpy(object->points, points, n*sizeof(fe_ipoint));
|
||||
//memcpy()
|
||||
memcpy(object->vertex_table, points, n*sizeof(fe_vertex));
|
||||
object->vertex_t0 = &object->vertex_table[n];
|
||||
object->vertex_t1 = &object->vertex_table[2*n];
|
||||
}
|
||||
else
|
||||
{
|
||||
object->points = points;
|
||||
object->vertex_t0 = malloc(2*n*sizeof(fe_vertex));
|
||||
if (!object->vertex_t0)
|
||||
return;
|
||||
object->vertex_t1 = &object->vertex_t0[n];
|
||||
object->vertex_table = points;
|
||||
}
|
||||
|
||||
object->p_owner = copy;
|
||||
object->p_size = n;
|
||||
object->vt_own = copy;
|
||||
object->vt_size = n;
|
||||
}
|
||||
|
||||
|
||||
|
@ -37,46 +57,68 @@ void fe_object_set_faces(fe_object * object, fe_triangle * faces, uint32_t n, bo
|
|||
{
|
||||
if (copy)
|
||||
{
|
||||
object->faces = malloc(n*sizeof(fe_ipoint));
|
||||
if (!object->faces)
|
||||
object->face_table = malloc(n*sizeof(fe_vertex));
|
||||
if (!object->face_table)
|
||||
return;
|
||||
memcpy(object->faces, faces, n*sizeof(fe_ipoint));
|
||||
memcpy(object->face_table, faces, n*sizeof(fe_vertex));
|
||||
}
|
||||
else
|
||||
{
|
||||
object->faces = faces;
|
||||
object->face_table = faces;
|
||||
}
|
||||
|
||||
|
||||
object->f_owner = copy;
|
||||
object->f_size = n;
|
||||
object->ft_own = copy;
|
||||
object->ft_size = n;
|
||||
}
|
||||
|
||||
static void fe_object_delete_faces(fe_object * object)
|
||||
{
|
||||
if (object->face_table && object->ft_own && object->ft_size)
|
||||
free(object->face_table);
|
||||
object->face_table=0;
|
||||
object->ft_size=0;
|
||||
object->ft_own=0;
|
||||
}
|
||||
|
||||
void fe_object_delete(fe_object * object)
|
||||
{
|
||||
if (object->points && object->p_owner)
|
||||
free(object->points);
|
||||
fe_object_delete_vertex(object);
|
||||
|
||||
if (object->faces && object->f_owner)
|
||||
free(object->faces);
|
||||
fe_object_delete_faces(object);
|
||||
|
||||
fe_object_init(object);
|
||||
}
|
||||
|
||||
fe_vertex* fe_object_getvx(const fe_object * object, const int n)
|
||||
{
|
||||
return &object->vertex_t1[n];
|
||||
}
|
||||
|
||||
|
||||
void fe_object_display(fe_object * object)
|
||||
{
|
||||
for (int i = 0; i < object->p_size; i++)
|
||||
fe_vertex_translate(&object->points[i]);
|
||||
object->old_centre.x=object->centre.x;
|
||||
object->old_centre.y=object->centre.y;
|
||||
object->old_centre.z=object->centre.z;
|
||||
|
||||
for (int i = 0; i < object->f_size; i++)
|
||||
fe_display_triangle(&object->faces[i]);
|
||||
for (int i = 0; i < object->vt_size; i++)
|
||||
{
|
||||
object->vertex_t0[i].x = object->old_centre.x + object->vertex_table[i].x;
|
||||
object->vertex_t0[i].y = object->old_centre.y + object->vertex_table[i].y;
|
||||
object->vertex_t0[i].z = object->old_centre.z + object->vertex_table[i].z;
|
||||
fe_vertex_translate(&object->vertex_t0[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < object->p_size; i++)
|
||||
dpixel(object->points[i].translated.x, object->points[i].translated.y, C_BLACK);
|
||||
for (int i = 0; i < object->ft_size; i++)
|
||||
fe_display_triangle(&object->face_table[i]);
|
||||
|
||||
// for (int i = 0; i < object->p_size; i++)
|
||||
// dpixel(object->points[i].translated.x, object->points[i].translated.y, C_BLACK);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
void fe_object_debug(const fe_object * object)
|
||||
{
|
||||
dclear(C_WHITE);
|
||||
|
@ -105,9 +147,5 @@ void fe_object_debug(const fe_object * object)
|
|||
dupdate();
|
||||
getkey();
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
fe_ipoint* fe_object_get_vertex(const fe_object * object, const int n)
|
||||
{
|
||||
return &object->points[n].translated;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
#include <fxengine/render/triangle.h>
|
||||
#include <fxengine/render/buffer.h>
|
||||
#include <fxengine/model/vertex.h>
|
||||
#include <fxengine/model/bitmap.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <gint/display.h>
|
||||
|
||||
void fe_display_triangle(const fe_triangle * face)
|
||||
{
|
||||
render_triangle(*face->s1, *face->s2, *face->s3, face->texture1, face->texture2, face->texture_half);
|
||||
}
|
||||
|
||||
int render_triangle(fe_vertex const s1, fe_vertex const s2, fe_vertex const s3,
|
||||
fe_bitmap const * side_0, fe_bitmap const * side_1, bool texture_half)
|
||||
{
|
||||
// Backface culling
|
||||
const int32_t area = s1.x * s2.y
|
||||
- s2.x * s1.y
|
||||
+ s2.x * s3.y
|
||||
- s3.x * s2.y
|
||||
+ s3.x * s1.y
|
||||
- s1.x * s3.y;
|
||||
|
||||
if (area < 0)
|
||||
return render_triangle_nobfc(s1,s2,s3,side_0,texture_half);
|
||||
else
|
||||
return render_triangle_nobfc(s1,s2,s3,side_1,texture_half);
|
||||
}
|
||||
|
||||
// Render Core
|
||||
|
||||
// Macros
|
||||
#define min(x,y) (x<y?x:y)
|
||||
#define max(x,y) (x>y?x:y)
|
||||
#define abs(x) (x<0?-x:x)
|
||||
|
||||
// gestion des arètes
|
||||
typedef struct
|
||||
{
|
||||
int32_t x,y,z;
|
||||
int32_t dx,dy,dz;
|
||||
int8_t no_line; // si les deux points sont confondus (se comporte comme un bool)
|
||||
} line;
|
||||
static void line_set(line* l,fe_vertex const * s1, fe_vertex 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 bool line_get_x(int32_t y, line const * l, int32_t * x) // retourne false si impossible, ou alors écrit dans x
|
||||
{
|
||||
y -= l->y;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
int render_triangle_nobfc(fe_vertex const s1, fe_vertex const s2, fe_vertex const s3,
|
||||
fe_bitmap const * side, bool texture_half)
|
||||
{
|
||||
if (!side) return RENDER_NOBMP;
|
||||
|
||||
// clipping (incomplete)
|
||||
if (s1.x < 0 && s2.x < 0 && s3.x < 0) return RENDER_OUT_OF_SCREEN;
|
||||
if (s1.x >= fe_width && s2.x >= fe_width && s3.x >= fe_width) return RENDER_OUT_OF_SCREEN;
|
||||
if (s1.y < 0 && s2.y < 0 && s3.y < 0) return RENDER_OUT_OF_SCREEN;
|
||||
if (s1.y >= fe_height && s2.y >= fe_height && s3.y >= fe_height) return RENDER_OUT_OF_SCREEN;
|
||||
if (s1.z <= 0 && s2.z <= 0 && s3.z <= 0) return RENDER_OUT_OF_SCREEN;
|
||||
|
||||
line cotes[3];
|
||||
line_set(&cotes[0], &s1, &s2);
|
||||
line_set(&cotes[1], &s1, &s3);
|
||||
line_set(&cotes[2], &s2, &s3);
|
||||
if (cotes[0].no_line || cotes[1].no_line || cotes[2].no_line) return RENDER_INVISIBLE;
|
||||
|
||||
|
||||
const int32_t ymin = max(min(s1.y, min(s2.y, s3.y)), 0);
|
||||
const int32_t ymax = min(max(s1.y, max(s2.y, s3.y)), 63);
|
||||
|
||||
const int32_t xAB = s2.x - s1.x, yAB = s2.y - s1.y, zAB=s2.z-s1.z;
|
||||
const int32_t xAC = s3.x - s1.x, yAC = s3.y - s1.y, zAC=s3.z-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++)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
int32_t vx, vy, z;
|
||||
|
||||
const int32_t xcalc = x - s1.x, ycalc = y - s1.y;
|
||||
// calcul de vx, vy
|
||||
vx = (xcalc*fact_1 - ycalc*fact_2);
|
||||
vy = (ycalc*fact_3 - xcalc*fact_4);
|
||||
z = s1.z + (vx * zAB + vy * zAC)/32768;
|
||||
if (z>0)
|
||||
{
|
||||
int32_t vx2= ( vx*side->size_px_x/s2.z ) / ((32768-vx)/s1.z + vx/s2.z);
|
||||
int32_t vy2= ( vy*side->size_px_y/s3.z ) / ((32768-vy)/s1.z + vy/s3.z);
|
||||
|
||||
// Affichage du point
|
||||
const uint8_t color = fe_bitmap_get_px(side, vx2, vy2);
|
||||
|
||||
if (color >> 1)
|
||||
{
|
||||
#ifdef RENDER_DEBUG_MODE
|
||||
dpixel(x,y, C_BLACK);
|
||||
#else
|
||||
if (fe_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
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return RENDER_SUCCESSFULLY_RENDERED;
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
#include <fxengine/zbuffer.h>
|
||||
#include <fxengine/render/buffer.h>
|
||||
|
||||
/*
|
||||
#include <fxengine/parameters.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
|
@ -9,7 +11,7 @@
|
|||
#include <gint/keyboard.h>
|
||||
#include <gint/defs/attributes.h>
|
||||
#include <gint/hardware.h>
|
||||
|
||||
*/
|
||||
|
||||
static const int size_uint32 = fe_width * fe_height;
|
||||
|
||||
|
@ -20,26 +22,18 @@ static const int size_char = size_uint32 * sizeof(uint32_t);
|
|||
static int32_t *zbuffer = (void *)0x88080000 - (((size_char >> 5) << 5) + 1);
|
||||
|
||||
|
||||
// gint doesn't provide any prototype for that function which is implemented
|
||||
// AND THE DMA STILL DON'T WOOORK :(
|
||||
extern void dma_memset(void *dst, uint32_t l, size_t size);
|
||||
|
||||
|
||||
void fe_zbuffer_clear()
|
||||
void fe_clear_zbuffer()
|
||||
{
|
||||
uint32_t indice = 0;
|
||||
for (indice = 0; indice < size_uint32; indice ++)
|
||||
zbuffer[indice] = fe_max_dist;
|
||||
#ifdef USE_LIBLOG
|
||||
ll_send(">> ZBuffer cleared.");
|
||||
#endif
|
||||
zbuffer[indice] = 20000000;
|
||||
}
|
||||
|
||||
bool fe_zbuffer_set_px(const uint32_t x, const uint32_t y, const uint32_t dist)
|
||||
{
|
||||
const int indice = x * fe_height + y;
|
||||
const uint32_t indice = x * fe_height + y;
|
||||
|
||||
if (zbuffer[indice]>dist && dist>=fe_min_dist && dist<=fe_max_dist)
|
||||
if (zbuffer[indice]>dist && dist)
|
||||
{
|
||||
zbuffer[indice] = dist;
|
||||
return true;
|
|
@ -0,0 +1,75 @@
|
|||
#include <fxengine/renderlist.h>
|
||||
#include <fxengine/model/object.h>
|
||||
#include <gint/std/stdlib.h>
|
||||
|
||||
static fe_object ** list = 0;
|
||||
static int list_size = 0;
|
||||
|
||||
int fe_renderlist_add(fe_object * const object)
|
||||
{
|
||||
if (object==0)
|
||||
return -1;
|
||||
for (int i=0; i<list_size; i++)
|
||||
if (list[i]==object)
|
||||
return -1;
|
||||
for (int i=0; i<list_size; i++)
|
||||
{
|
||||
if (list[i]==0)
|
||||
{
|
||||
list[i]=object;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
if (list==0)
|
||||
{
|
||||
list_size++;
|
||||
list=malloc(sizeof(fe_object*));
|
||||
list[0]=object;
|
||||
}
|
||||
else
|
||||
{
|
||||
list_size++;
|
||||
list=realloc(list, list_size*sizeof(fe_object*));
|
||||
list[list_size-1]=object;
|
||||
}
|
||||
}
|
||||
|
||||
int fe_renderlist_remove(fe_object * const object)
|
||||
{
|
||||
if (object==0)
|
||||
return -1;
|
||||
for (int i=0; i<list_size; i++)
|
||||
if (list[i]==object)
|
||||
{
|
||||
list[i]=0;
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
fe_object * fe_renderlist_remove_id(int id)
|
||||
{
|
||||
if (id>=list_size)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
fe_object * tmp = list[id];
|
||||
list[id]=0;
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
||||
void fe_renderlist_clear(void)
|
||||
{
|
||||
free(list);
|
||||
list_size=0;
|
||||
return;
|
||||
}
|
||||
|
||||
void fe_render(void)
|
||||
{
|
||||
for (int i=0; i<list_size; i++)
|
||||
if (list[i])
|
||||
fe_object_display(list[i]);
|
||||
}
|
98
src/space.c
98
src/space.c
|
@ -1,98 +0,0 @@
|
|||
#include <fxengine/space.h>
|
||||
#include <fxengine/camera.h>
|
||||
|
||||
#include <gint/std/stdlib.h>
|
||||
#include <gint/std/stdio.h>
|
||||
#include <gint/std/string.h>
|
||||
|
||||
#ifdef USE_LIBLOG
|
||||
#include <liblog.h>
|
||||
#endif
|
||||
|
||||
double fe_matrix[3][3]=
|
||||
{
|
||||
{0,0,0},
|
||||
{0,0,0},
|
||||
{0,0,0}
|
||||
};
|
||||
fe_ipoint fe_translate_delta;
|
||||
|
||||
static double reducted_cos(const double a)
|
||||
{
|
||||
double u= 1.0;
|
||||
const double a2 = a * a;
|
||||
for(int32_t p = 17; p>=1; p -= 2)
|
||||
u = 1 - a2 / (p * p + p) * u;
|
||||
return u;
|
||||
}
|
||||
|
||||
// return a with -pi<=a<pi
|
||||
double fe_modulo_2pi(double a)
|
||||
{
|
||||
while (a<=-pi)
|
||||
a += pi2;
|
||||
while (a>pi)
|
||||
a -= pi2;
|
||||
return a;
|
||||
}
|
||||
|
||||
double fe_cos(double angle)
|
||||
{
|
||||
angle = fe_modulo_2pi(angle);
|
||||
if (angle<0)
|
||||
angle=-angle;
|
||||
if (angle>=pi_sur_2)
|
||||
return -reducted_cos(angle - pi);
|
||||
return reducted_cos(angle);
|
||||
}
|
||||
|
||||
double fe_sin(double angle)
|
||||
{
|
||||
return fe_cos(angle - pi_sur_2);
|
||||
}
|
||||
|
||||
|
||||
#define sgn(x) (x>=0?x:-x)
|
||||
|
||||
void fe_vertex_translate(fe_ivertex * v)
|
||||
{
|
||||
static fe_ipoint temp;
|
||||
temp.x = 64*(v->real.x - fe_translate_delta.x);
|
||||
temp.y = 64*(v->real.y - fe_translate_delta.y);
|
||||
temp.z = 64*(v->real.z - fe_translate_delta.z);
|
||||
|
||||
v->translated.x = (double)(fe_matrix[0][0]*(double)temp.x + fe_matrix[0][1]*(double)temp.y + fe_matrix[0][2]*(double)temp.z);
|
||||
v->translated.z = (double)(fe_matrix[1][0]*(double)temp.x + fe_matrix[1][1]*(double)temp.y + fe_matrix[1][2]*(double)temp.z);
|
||||
v->translated.y = (double)(fe_matrix[2][0]*(double)temp.x + fe_matrix[2][1]*(double)temp.y + fe_matrix[2][2]*(double)temp.z);
|
||||
|
||||
//v->translated.x*=10;
|
||||
//v->translated.y*=10;
|
||||
v->translated.z/=64;
|
||||
if (v->translated.z>0)
|
||||
{
|
||||
v->translated.x/=v->translated.z;
|
||||
v->translated.y/=v->translated.z;
|
||||
}
|
||||
else
|
||||
{
|
||||
v->translated.x*=256*sgn(v->translated.z);
|
||||
v->translated.y*=256*sgn(v->translated.z);
|
||||
}
|
||||
//(v->translated.x*1024)/v->translated.z;
|
||||
//(v->translated.y*1024)/v->translated.z;
|
||||
|
||||
v->translated.x+=fe_x_mid;
|
||||
v->translated.y+=fe_y_mid;
|
||||
|
||||
#ifdef USE_LIBLOG
|
||||
char str[50];
|
||||
sprintf(str, "Vrtx %p\n >> X:%d Y:%d Z:%d\n",
|
||||
v,
|
||||
v->translated.x,
|
||||
v->translated.y,
|
||||
v->translated.z);
|
||||
ll_send(str);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
#include <fxengine/texture.h>
|
||||
#include <fxengine/model/bitmap.h>
|
||||
|
||||
#include <gint/display.h>
|
||||
#include <gint/std/string.h>
|
||||
#include <gint/std/stdlib.h>
|
||||
|
||||
fe_texture_rich* fe_texture_new_rich(uint32_t size_px_x, uint32_t size_px_y, uint32_t* color, bool copy_color, uint32_t *layout, bool copy_layout)
|
||||
fe_bitmap* fe_bitmap_new(uint32_t size_px_x, uint32_t size_px_y, uint32_t* color, bool copy_color, uint32_t *layout, bool copy_layout)
|
||||
{
|
||||
fe_texture_rich* bmp = malloc(sizeof(fe_texture_rich));
|
||||
fe_bitmap* bmp = malloc(sizeof(fe_bitmap));
|
||||
if (!bmp)
|
||||
return 0;
|
||||
|
||||
|
@ -52,33 +52,7 @@ fe_texture_rich* fe_texture_new_rich(uint32_t size_px_x, uint32_t size_px_y, uin
|
|||
return bmp;
|
||||
}
|
||||
|
||||
void fe_texture_debug(fe_texture_rich * txtr)
|
||||
{
|
||||
dclear(C_WHITE);
|
||||
if (txtr)
|
||||
{
|
||||
char text[21];
|
||||
sprintf(text, "ADDRESS : %p", txtr);
|
||||
dtext(1,1, text, C_BLACK, C_NONE);
|
||||
|
||||
sprintf(text, "size %d %d", txtr->size_px_x, txtr->size_px_y);
|
||||
dtext(1,9, text, C_BLACK, C_NONE);
|
||||
|
||||
sprintf(text, "color %p %d", txtr->color, txtr->color_dynamic);
|
||||
dtext(1,17, text, C_BLACK, C_NONE);
|
||||
|
||||
sprintf(text, "layout %p %d", txtr->layout, txtr->layout_dynamic);
|
||||
dtext(1,25, text, C_BLACK, C_NONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
dtext(1,1, "Texture set as NULL", C_BLACK, C_NONE);
|
||||
}
|
||||
dupdate();
|
||||
getkey();
|
||||
}
|
||||
|
||||
void fe_texture_delete_rich(fe_texture_rich * bmp)
|
||||
void fe_bitmap_del(fe_bitmap * bmp)
|
||||
{
|
||||
if (!bmp)
|
||||
return;
|
||||
|
@ -92,7 +66,7 @@ void fe_texture_delete_rich(fe_texture_rich * bmp)
|
|||
free(bmp);
|
||||
}
|
||||
|
||||
uint8_t fe_texture_get_pixel_r(const fe_texture_rich * bmp, uint32_t x, uint32_t y)
|
||||
uint8_t fe_bitmap_get_px(const fe_bitmap * bmp, uint32_t x, uint32_t y)
|
||||
{
|
||||
if (x >= bmp->size_px_x || y >= bmp->size_px_y)
|
||||
return 0;
|
||||
|
@ -108,9 +82,9 @@ uint8_t fe_texture_get_pixel_r(const fe_texture_rich * bmp, uint32_t x, uint32_t
|
|||
}
|
||||
|
||||
|
||||
void fe_texture_display_pixel_r(const fe_texture_rich * bmp, uint32_t bmp_x, uint32_t bmp_y, uint32_t x, uint32_t y)
|
||||
void fe_bitmap_display_px(const fe_bitmap * bmp, uint32_t bmp_x, uint32_t bmp_y, uint32_t scr_x, uint32_t scr_y)
|
||||
{
|
||||
uint8_t color = fe_texture_get_pixel_r(bmp, bmp_x, bmp_y);
|
||||
uint8_t color = fe_bitmap_get_px(bmp, bmp_x, bmp_y);
|
||||
if (color)
|
||||
dpixel(x, y, 3 * (color % 2));
|
||||
dpixel(scr_x, scr_y, 3 * (color % 2));
|
||||
}
|
||||
|
|
190
src/triangle.c
190
src/triangle.c
|
@ -1,190 +0,0 @@
|
|||
#include <fxengine/triangle.h>
|
||||
#include <fxengine/texture.h>
|
||||
#include <fxengine/space.h>
|
||||
#include <fxengine/zbuffer.h>
|
||||
|
||||
#ifdef USE_LIBPROF
|
||||
#include <libprof.h>
|
||||
#endif
|
||||
|
||||
#include <gint/display.h>
|
||||
#include <gint/clock.h>
|
||||
|
||||
/**
|
||||
* @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(fe_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,fe_ipoint const * s1, fe_ipoint 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 (x<y ? x : y);
|
||||
}
|
||||
|
||||
static int32_t abs(int32_t x)
|
||||
{
|
||||
return(x<0 ? -x : x);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get the corresponding x from the y coordinate
|
||||
*
|
||||
* @param[in] y the y coordinate
|
||||
* @param l the line
|
||||
* @param x address where x is written
|
||||
*
|
||||
* @return if given point coordinate belongs to the l
|
||||
*/
|
||||
static bool line_get_x(int32_t y, line const * l, int32_t * x)
|
||||
{
|
||||
y -= l->y;
|
||||
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 fe_display_triangle(const fe_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 >= fe_width && face->s2->x >= fe_width && face->s3->x >= fe_width)
|
||||
return;
|
||||
if (face->s1->y < 0 && face->s2->y < 0 && face->s3->y < 0)
|
||||
return;
|
||||
if (face->s1->y >= fe_height && face->s2->y >= fe_height && face->s3->y >= fe_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++)
|
||||
{
|
||||
int32_t vx, vy, z;
|
||||
|
||||
const int32_t xcalc = x - face->s1->x, ycalc = y - face->s1->y;
|
||||
// calcul de vx, vy
|
||||
vx = (xcalc*fact_1 - ycalc*fact_2);
|
||||
vy = (ycalc*fact_3 - xcalc*fact_4);
|
||||
z = face->s1->z + (vx * zAB + vy * zAC)/32768;
|
||||
|
||||
|
||||
int32_t vx2= ( vx*face->texture->size_px_x/face->s2->z ) / ((32768-vx)/face->s1->z + vx/face->s2->z);
|
||||
int32_t vy2= ( vy*face->texture->size_px_y/face->s3->z ) / ((32768-vy)/face->s1->z + vy/face->s3->z);
|
||||
/* Perspective correction
|
||||
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 = fe_texture_get_pixel_r(face->texture, vx2, vy2);
|
||||
|
||||
if (color >> 1)
|
||||
{
|
||||
//dpixel(x,y, C_BLACK);
|
||||
if (fe_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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue