reorg. fxengine
This commit is contained in:
parent
501a36ec69
commit
1db17f353a
|
@ -3,14 +3,13 @@
|
|||
|
||||
#include <fxengine/space.h>
|
||||
|
||||
struct fe_camera
|
||||
typedef struct
|
||||
{
|
||||
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;
|
||||
} fe_camera;
|
||||
|
||||
/**
|
||||
* @brief Sets up the translation matrices for a new rendering cycle
|
||||
|
|
|
@ -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,16 @@
|
|||
#ifndef FE_MATRIX
|
||||
#define FE_MATRIX
|
||||
|
||||
#include <fxengine/model/vertex.h>
|
||||
|
||||
void fe_vertex_translate(fe_vertex* v);
|
||||
void fe_set_matrix(double dh, double dv, double rot);
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint32_t fe_matrix_type;
|
||||
extern fe_matrix_type fe_matrix[3][3];
|
||||
|
||||
extern fe_point fe_pos_delta;
|
||||
|
||||
#endif
|
|
@ -7,7 +7,7 @@
|
|||
/* bitmap model
|
||||
transparency is in the layout
|
||||
this color type is monochrome only ! */
|
||||
typedef struct fe_bitmap
|
||||
typedef struct
|
||||
{
|
||||
uint32_t size_px_x;
|
||||
uint32_t size_px_y;
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
# Fxengine::Bitmap
|
||||
This is part of the [fxengine](/Milang/fxengine) project.
|
||||
This file refers to [bitmap.h](bitmap.h) header.
|
||||
```c
|
||||
#include <fxengine/model/bitmap.h>
|
||||
```
|
||||
## What is it ?
|
||||
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 fe_bitmap
|
||||
typedef struct
|
||||
{
|
||||
uint32_t size_px_x;
|
||||
uint32_t size_px_y;
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef FE_MODEL_POINT
|
||||
#define FE_MODEL_POINT
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
int32_t z;
|
||||
} fe_point;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
double z;
|
||||
} fe_point_d;
|
||||
|
||||
#endif
|
|
@ -1,28 +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_triangle
|
||||
typedef struct
|
||||
{
|
||||
fe_integer_vertex * s1;
|
||||
fe_integer_vertex * s2;
|
||||
fe_integer_vertex * s3;
|
||||
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
|
||||
#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,12 @@
|
|||
#ifndef FE_MODEL_VERTEX
|
||||
#define FE_MODEL_VERTEX
|
||||
|
||||
#include <fxengine/model/point.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
fe_point real;
|
||||
fe_point translated;
|
||||
} fe_vertex;
|
||||
|
||||
#endif
|
|
@ -8,7 +8,7 @@
|
|||
#include <stdbool.h>
|
||||
|
||||
|
||||
struct fe_object
|
||||
typedef struct
|
||||
{
|
||||
fe_triangle * faces;
|
||||
uint32_t f_size;
|
||||
|
@ -16,8 +16,7 @@ struct fe_object
|
|||
fe_ivertex * points;
|
||||
uint32_t p_size;
|
||||
bool p_owner;
|
||||
};
|
||||
typedef struct fe_object fe_object;
|
||||
} fe_object;
|
||||
|
||||
void fe_object_init(fe_object * object);
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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,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
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef RENDER_BUFFER
|
||||
#define RENDER_BUFFER
|
||||
|
||||
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
|
|
@ -3,17 +3,30 @@
|
|||
|
||||
#include <fxengine/models/vertex.h>
|
||||
#include <fxengine/models/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 */
|
||||
void render_triangle(fe_integer_vertex const s1, fe_integer_vertex const s2, fe_integer_vertex const s3,
|
||||
fe_bitmap const * side_0, fe_bitmap const * side_1);
|
||||
int render_triangle(fe_point const s1, fe_point const s2, fe_point const s3,
|
||||
fe_bitmap const * side_0, fe_bitmap const * side_1, bool const texture_half);
|
||||
|
||||
/* render_triangle_nobfc()
|
||||
renders a face without backface culling */
|
||||
void render_triangle_nobfc(fe_integer_vertex const s1, fe_integer_vertex const s2, fe_integer_vertex const s3,
|
||||
fe_bitmap const * side);
|
||||
|
||||
|
||||
int render_triangle_nobfc(fe_point const s1, fe_point const s2, fe_point const s3,
|
||||
fe_bitmap const * side, bool const texture_half);
|
||||
|
||||
#endif
|
|
@ -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,67 @@
|
|||
#include <fxengine/matrix.h>
|
||||
#include <fxengine/model/point.h>
|
||||
|
||||
fe_matrix_type fe_matrix[3][3]=
|
||||
{
|
||||
{0,0,0},
|
||||
{0,0,0},
|
||||
{0,0,0}
|
||||
};
|
||||
#define fe_unite 1024
|
||||
fe_point fe_pos_delta;
|
||||
|
||||
#define sgn(x) (x>=0?x:-x)
|
||||
|
||||
void fe_vertex_translate(fe_vertex * v)
|
||||
{
|
||||
static fe_point temp;
|
||||
temp.x = v->real.x - fe_translate_delta.x;
|
||||
temp.y = v->real.y - fe_translate_delta.y;
|
||||
temp.z = v->real.z - fe_translate_delta.z;
|
||||
|
||||
v->translated.x = fe_matrix[0][0]temp.x + fe_matrix[0][1]*temp.y + fe_matrix[0][2]*temp.z;
|
||||
v->translated.z = fe_matrix[1][0]temp.x + fe_matrix[1][1]*temp.y + fe_matrix[1][2]*temp.z;
|
||||
v->translated.y = fe_matrix[2][0]temp.x + fe_matrix[2][1]*temp.y + fe_matrix[2][2]*temp.z;
|
||||
|
||||
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+=63;
|
||||
v->translated.y+=31;
|
||||
}
|
||||
|
||||
void fe_set_matrix(double dh, double dv, double rot)
|
||||
{
|
||||
const fe_matrix_type A=fe_unite*fe_cos(dv);
|
||||
const fe_matrix_type B=fe_unite*fe_sin(dv);
|
||||
|
||||
const fe_matrix_type C=fe_unite*fe_cos(roulis);
|
||||
const fe_matrix_type D=fe_unite*fe_sin(roulis);
|
||||
|
||||
const fe_matrix_type E=fe_unite*fe_cos(dh);
|
||||
const fe_matrix_type F=fe_unite*fe_sin(dh);
|
||||
|
||||
// raccourcis
|
||||
const fe_matrix AD=A*D/fe_unite, BD=B*D/fe_unite;
|
||||
|
||||
fe_matrix[0][0]=C*E/fe_unite;
|
||||
fe_matrix[0][1]=-C*F/fe_unite;
|
||||
fe_matrix[0][2]=D;
|
||||
|
||||
fe_matrix[1][0]=(BD*E+A*F)/fe_unite;
|
||||
fe_matrix[1][1]=(-BD*F+A*E)/fe_unite;
|
||||
fe_matrix[1][2]=-B*C/fe_unite;
|
||||
|
||||
fe_matrix[2][0]=(-AD*E+B*F)/fe_unite;
|
||||
fe_matrix[2][1]=(AD*F+B*E)/fe_unite;
|
||||
fe_matrix[2][2]=A*C/fe_unite;
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
#include <render/triangle.h>
|
||||
#include <render/buffer.h>
|
||||
#include <fxengine/model/point.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <gint/display.h>
|
||||
|
||||
|
||||
void render_triangle(fe_point const s1, fe_point const s2, fe_point 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_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 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_point const s1, fe_point const s2, fe_point const s3,
|
||||
fe_bitmap const * side, bool texture_half);
|
||||
{
|
||||
if (!side) return RENDER_NO_BMP;
|
||||
|
||||
// clipping (incomplete)
|
||||
if (face->s1->x < 0 && face->s2->x < 0 && face->s3->x < 0) return RENDER_OUT_OF_SCREEN;
|
||||
if (face->s1->x >= fe_width && face->s2->x >= fe_width && face->s3->x >= fe_width) return RENDER_OUT_OF_SCREEN;
|
||||
if (face->s1->y < 0 && face->s2->y < 0 && face->s3->y < 0) return RENDER_OUT_OF_SCREEN;
|
||||
if (face->s1->y >= fe_height && face->s2->y >= fe_height && face->s3->y >= fe_height) return RENDER_OUT_OF_SCREEN;
|
||||
if (face->s1->z <= 0 && face->s2->z <= 0 && face->s3->z <= 0) return RENDER_OUT_OF_SCREEN;
|
||||
|
||||
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 RENDER_INVISIBLE;
|
||||
|
||||
|
||||
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++)
|
||||
{
|
||||
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);
|
||||
|
||||
// Affichage du point
|
||||
const uint8_t color = fe_texture_get_pixel_r(face->texture, 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;
|
||||
}
|
191
src/triangle.c
191
src/triangle.c
|
@ -1,190 +1,7 @@
|
|||
#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;
|
||||
}
|
||||
|
||||
#include <render/triangle.h>
|
||||
#include <fxengine/model/triangle.h>
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
render_triangle(face->s1->translated, face->s2->translated, face->s3->translated, face->texture1, face->texture2, face->texture_half);
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
#include <fxengine/model/vertex.h>
|
|
@ -1,4 +1,6 @@
|
|||
#include <fxengine/zbuffer.h>
|
||||
#include <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;
|
||||
|
||||
|
@ -37,7 +39,7 @@ void fe_zbuffer_clear()
|
|||
|
||||
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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue