Compare commits

...

19 Commits

Author SHA1 Message Date
milang 308cb408a2 correct zbuffer clearing ( thanks @lephenixnoir) 2019-08-19 12:58:50 +02:00
Milang 4ccf324e48 rename some static variables 2019-08-19 12:10:06 +02:00
Milang 891921fd39 f*ck dma again 2019-08-17 20:07:59 +02:00
Milang 42cd1bb580 f*ck dma 2019-08-17 20:07:04 +02:00
Milang a8360f10dc dma again (I hate it) 2019-08-17 19:59:56 +02:00
Milang 869a762637 align zbuffer on 32Bytes blocks 2019-08-17 19:48:41 +02:00
Milang 45ec1a4a35 correct bug in DMA using
-> copied value was not set on 32 bytes, but on 4 bytes
2019-08-17 19:37:27 +02:00
Milang 94b7f6e7c6 still debugging direct memory access controller (I gonna suicide) 2019-08-17 19:25:16 +02:00
Milang e9c5f9935d debugging DMA 2019-08-17 19:13:28 +02:00
Milang 5b99d60eff align the buffer 2 2019-08-17 18:25:30 +02:00
Milang bfe73f1886 align the buffer 2019-08-17 18:23:41 +02:00
Milang 6f36dd1966 test to align zbuffer on 32 2019-08-17 18:14:36 +02:00
Milang d9abe48615 DMA, finished ? 2019-08-17 17:57:44 +02:00
Milang 3b62636d30 potatoes 2019-08-17 17:50:53 +02:00
Milang 84d31c7783 add DMA >> experimental 2019-08-17 17:47:05 +02:00
Milang 9900f70201 inchallah ça passe 2019-08-17 17:28:27 +02:00
milang d45020336e continue to remake rendering 2019-08-17 14:42:59 +02:00
milang e4f86a3c3e implementing texture rendering 2019-08-17 14:30:18 +02:00
milang 263e8543c6 changing triangle rendering 2019-08-17 14:09:45 +02:00
21 changed files with 775 additions and 868 deletions

BIN
1v13D.g1a

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

BIN
build-fx/src/1v13D.elf Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,5 +1,6 @@
build-fx/src/controls.o: src/controls.c src/controls.h \
src/FxEngine/FxEngine.h src/FxEngine/coord.h src/FxEngine/zbuffer.h
src/FxEngine/FxEngine.h src/FxEngine/coord.h src/FxEngine/FxEngine.h \
src/FxEngine/zbuffer.h
src/controls.h:
@ -7,4 +8,6 @@ src/FxEngine/FxEngine.h:
src/FxEngine/coord.h:
src/FxEngine/FxEngine.h:
src/FxEngine/zbuffer.h:

Binary file not shown.

View File

@ -1,15 +1,15 @@
build-fx/src/main.o: src/main.c src/FxEngine/FxEngine.h \
src/FxEngine/coord.h src/FxEngine/zbuffer.h src/FxEngine/face.h \
src/FxEngine/FxEngine.h src/controls.h
src/FxEngine/coord.h src/FxEngine/FxEngine.h src/FxEngine/zbuffer.h \
src/FxEngine/face.h src/controls.h
src/FxEngine/FxEngine.h:
src/FxEngine/coord.h:
src/FxEngine/FxEngine.h:
src/FxEngine/zbuffer.h:
src/FxEngine/face.h:
src/FxEngine/FxEngine.h:
src/controls.h:

View File

@ -41,18 +41,18 @@ static void FE_move()
}
if (event.key==KEY_5)
{
py += FE_cos(FE_dh + pi);
px += FE_sin(FE_dh + pi);
py += FE_cos(FE_dh + FE_PI);
px += FE_sin(FE_dh + FE_PI);
}
if (event.key==KEY_4)
{
py += FE_cos(FE_dh - pi_sur2);
px += FE_sin(FE_dh - pi_sur2);
py += FE_cos(FE_dh - FE_PI_SUR_2);
px += FE_sin(FE_dh - FE_PI_SUR_2);
}
if (event.key==KEY_6)
{
py += FE_cos(FE_dh + pi_sur2);
px += FE_sin(FE_dh + pi_sur2);
py += FE_cos(FE_dh + FE_PI_SUR_2);
px += FE_sin(FE_dh + FE_PI_SUR_2);
}
@ -99,17 +99,17 @@ void FE_new_frame()
#define MICROSECOND 1000000
unsigned uint32_t FE_get_fps_current()
uint32_t FE_get_fps_current()
{
return MICROSECOND / frame_interval;
}
unsigned uint32_t FE_get_fps_min()
uint32_t FE_get_fps_min()
{
return MICROSECOND / frame_interval_max;
}
unsigned uint32_t FE_get_fps_max()
uint32_t FE_get_fps_max()
{
return MICROSECOND / frame_interval_min;
}
@ -121,4 +121,4 @@ char* FE_get_fps_history()
{
sprintf(fps_history, "%d/%d/%d", FE_get_fps_min(), FE_get_fps_current(), FE_get_fps_max());
return fps_history;
}
}

View File

@ -1,6 +1,7 @@
#ifndef FENG_H
#define FENG_H
#include <stdint.h>
#include "coord.h"
#include "zbuffer.h"
#include <libprof.h>
@ -36,15 +37,15 @@ void FE_new_frame(void); // calls move function
/* FE_get_fps_current():
obtient le nombre d'Images Par Seconde (IPS) calculé à partir du dernier cycle */
unsigned int FE_get_fps_current(void);
uint32_t FE_get_fps_current(void);
/* FE_get_fps_min():
obtient le nombre d'images par seconde le plus bas ayant existé depuis le démarrage du moteur 3d */
unsigned int FE_get_fps_min(void);
uint32_t FE_get_fps_min(void);
/* FE_get_fps_max():
obtient le nombre d'images par seconde le plus haut ayant existé depuis le démarrage du moteur 3d */
unsigned int FE_get_fps_max(void);
uint32_t FE_get_fps_max(void);
/* FE_get_fps_history():
renvoie, dans une version compactée, les nombres minimum, actuel et maximum d'images par seconde
@ -59,4 +60,4 @@ unsigned int FE_get_fps_max(void);
char* FE_get_fps_history(void);
#endif
#endif

View File

@ -19,10 +19,10 @@ static double reducted_cos(const double a)
// return a with -pi<=a<pi
double FE_modulo_2pi(double a)
{
while (a<=-pi)
a += pi2;
while (a>pi)
a -= pi2;
while (a<=-FE_PI)
a += FE_2_PI;
while (a>FE_PI)
a -= FE_2_PI;
return a;
}
@ -31,7 +31,7 @@ static double cos_recursive(double angle)
if (angle<0)
return cos_recursive(-angle);
if (angle>=FE_PI_SUR_2)
return -reducted_cos(angle - pi);
return -reducted_cos(angle - FE_PI);
return reducted_cos(angle); // OK
}
@ -43,7 +43,7 @@ double FE_cos(double angle)
double FE_sin(double angle)
{
return FE_cos(angle - pi_sur2);
return FE_cos(angle - FE_PI_SUR_2);
}
@ -69,21 +69,21 @@ void FE_calc(FE_point* point)
//point->translated.x*=10;
//point->translated.y*=10;
point->rotated.x*=64;
point->rotated.y*=64;
point->translated.z=point->rotated.z;
point->rotated.x *= 64;
point->rotated.y *= 64;
point->translated.z = point->rotated.z;
if (point->translated.z>0)
{
point->translated.x=point->rotated.x/point->translated.z;
point->translated.y=point->rotated.y/point->translated.z;
point->translated.x = point->rotated.x / point->translated.z;
point->translated.y = point->rotated.y / point->translated.z;
}
else
{
point->translated.x=point->rotated.x*10000*sgn(point->translated.z);
point->translated.y=point->rotated.y*10000*sgn(point->translated.z);
point->translated.x = point->rotated.x * 10000 * sgn(point->translated.z);
point->translated.y = point->rotated.y * 10000 * sgn(point->translated.z);
}
(point->translated.x*1000)/point->translated.z;
(point->translated.y*1000)/point->translated.z;
// (point->translated.x*1000)/point->translated.z;
// (point->translated.y*1000)/point->translated.z;
point->translated.x+=63;
point->translated.y+=31;
@ -111,4 +111,4 @@ void FE_set_matrice(void)
matrice[2][1]=AD*F+B*E;
matrice[2][2]=A*C;
}
}

View File

@ -1,13 +1,11 @@
#ifndef FE_COORD_H
#define FE_COORD_H
#include "FxEngine.h"
/* FE_position:
notion de point dans l'espace simple */
typedef struct FE_position FE_position;
struct FE_position
{int32_t x,y,z;};
{int x,y,z;};
/* FE_point:
notion de point dans l'espace destiné à etre utilisé dans l'affichage
@ -18,6 +16,8 @@ typedef struct FE_point FE_point;
struct FE_point
{FE_position real,translated,rotated};
#include "FxEngine.h"
/* FE_calc():
applique la matrice de rotation sur les coordonnées d'un point
@ -58,4 +58,4 @@ double FE_cos(double angle);
double FE_sin(const double angle);
#endif
#endif

View File

@ -1,25 +1,22 @@
#include "face.h"
#include "texture.h"
#include "zbuffer.h"
#include <stdbool.h>
#include <gint/display.h>
#define min(x,y) (x<y?x:y)
#define max(x,y) (x>y?x:y)
#define abs(x) (x>0?x:-x)
#include <stdbool.h>
static bool sens_horaire(FE_face const * face)
{
int area = 0;
area+=face->s1->translated.x*face->s2->translated.y;
area-=face->s2->translated.x*face->s1->translated.y;
area += face->s1->translated.x * face->s2->translated.y;
area -= face->s2->translated.x * face->s1->translated.y;
area+=face->s2->translated.x*face->s3->translated.y;
area-=face->s3->translated.x*face->s2->translated.y;
area += face->s2->translated.x * face->s3->translated.y;
area -= face->s3->translated.x * face->s2->translated.y;
area+=face->s3->translated.x*face->s1->translated.y;
area-=face->s1->translated.x*face->s3->translated.y;
area += face->s3->translated.x * face->s1->translated.y;
area -= face->s1->translated.x * face->s3->translated.y;
return (area < 0);
}
@ -32,6 +29,7 @@ struct line
int dx,dy,dz;
bool no_line; // si les deux points sont confondus
};
static void set_line(line* segment,FE_point const * s1, FE_point const * s2)
{
segment->x=s1->translated.x;
@ -42,6 +40,7 @@ static void set_line(line* segment,FE_point const * s1, FE_point const * s2)
segment->dz=s2->translated.z-s1->translated.z;
segment->no_line=(segment->dx==0&&segment->dy==0);
}
static bool get_x(int y, line const * segment, int * x)
{
y-=segment->y;
@ -61,11 +60,16 @@ static bool get_x(int y, line const * segment, int * x)
return true;
}
#include "texture.h"
#include "zbuffer.h"
#include <gint/display.h>
void FE_draw_face(FE_face const * face)
{
// élimination des faces cachées
if (sens_horaire(face)!=face->visible)
return;
// cas particuliers où la face n'est pas dans l'écran
if (face->s1->translated.x<0 && face->s2->translated.x<0 && face->s3->translated.x<0)
return;
if (face->s1->translated.x>127 && face->s2->translated.x>127 && face->s3->translated.x>127)
@ -77,50 +81,65 @@ void FE_draw_face(FE_face const * face)
if (face->s1->translated.z<=0 && face->s2->translated.z<=0 && face->s3->translated.z<=0)
return;
// cas où un côté est nul
line cotes[3];
set_line(&cotes[0],face->s1,face->s2);
set_line(&cotes[1],face->s1,face->s3);
set_line(&cotes[2],face->s2,face->s3);
if (cotes[0].no_line||cotes[1].no_line||cotes[2].no_line)
set_line(&cotes[0], face->s1,face->s2);
set_line(&cotes[1], face->s1,face->s3);
set_line(&cotes[2], face->s2,face->s3);
if (cotes[0].no_line || cotes[1].no_line || cotes[2].no_line)
return;
const int ymin=max(min(face->s1->translated.y,min(face->s2->translated.y,face->s3->translated.y)),0);
const int ymax=min(max(face->s1->translated.y,max(face->s2->translated.y,face->s3->translated.y)),63);
const int32_t y1 = max(min(face->s1->translated.y, min(face->s2->translated.y, face->s3->translated.y)), 0);
const int32_t y2 = min(max(face->s1->translated.y, max(face->s2->translated.y, face->s3->translated.y)), 63);
const int xAB=face->s2->translated.x-face->s1->translated.x, yAB=face->s2->translated.y-face->s1->translated.y, zAB=face->s2->translated.z-face->s1->translated.z;
const int xAC=face->s3->translated.x-face->s1->translated.x, yAC=face->s3->translated.y-face->s1->translated.y, zAC=face->s3->translated.z-face->s1->translated.z;
const int diviseur_commun=(xAB*yAC-yAB*xAC); //(multiplier par 10000)
const int fact_1=(10000*yAC)/diviseur_commun, fact_2=(10000*xAC)/diviseur_commun;
const int fact_3=(10000*xAB)/diviseur_commun, fact_4=(10000*yAB)/diviseur_commun;
// ressources pour déformer les textures
const int32_t xAB = face->s2->translated.x-face->s1->translated.x,
yAB = face->s2->translated.y-face->s1->translated.y,
zAB=face->s2->translated.z-face->s1->translated.z;
const int32_t xAC = face->s3->translated.x-face->s1->translated.x,
yAC = face->s3->translated.y-face->s1->translated.y,
zAC=face->s3->translated.z-face->s1->translated.z;
const int32_t diviseur_commun=(xAB*yAC-yAB*xAC);
const int fact_1=(1024*yAC)/diviseur_commun, fact_2=(1024*xAC)/diviseur_commun;
const int fact_3=(1024*xAB)/diviseur_commun, fact_4=(1024*yAB)/diviseur_commun;
for (int y=ymin; y<=ymax; y++)
for (int y=y1; y<=y2; y++)
{
// détermination du xmin et du xmax de la ligne
int tx1,tx2;
int tx1, tx2;
for (int t=0;t<3;t++)
{if (get_x(y,&cotes[t],&tx1)) break;}
if (get_x(y,&cotes[t],&tx1))
break;
for (int t=0;t<3;t++)
{if (get_x(y,&cotes[t],&tx2)&&tx1!=tx2) break;}
if (get_x(y,&cotes[t],&tx2)&&tx1!=tx2)
break;
const int txmin=max(min(tx1,tx2),0), txmax=min(max(tx1,tx2),127);
for (int x=txmin; x<=txmax; x++)
{
double vx, vy, z;
// vx et vy coordonnées transformées pour l'accès à la texture
// z distance du point visible (distance non transformée)
int32_t vx, vy, z;
// calcul de vx, vy
vx=(xcalc*fact_1-ycalc*fact_2); // 0 <vx< 10_000
const int32_t xcalc = x-face->s1->translated.x, ycalc = y-face->s1->translated.y;
vx=(xcalc*fact_1-ycalc*fact_2); // 0 <vx< 10_000
vy=(ycalc*fact_3-xcalc*fact_4); // idem
z=face->s1->translated.z + (vx*zAB+vy*zAC)/10000;
vx/=10000;
vy/=10000;
vx /= (double)face->s2->translated.z / ((1-vx) / face->s1->translated.z + vx / (double)face->s2->translated.z);
vy /= (double)face->s3->translated.z / ((1-vy) / face->s1->translated.z + vy / (double)face->s3->translated.z);
// Affichage du point
if (FE_zbuffer_set_dist(x,y,z))
dpixel(x, y, 3*FE_get_pixel(face->texturenum, 8*vx, 8*vy)); // 3* means cast to black and white, and vx,and vy casted between 0 and 7
z=face->s1->translated.z + (vx*zAB+vy*zAC)/1024; // calcul de z non corrigé >> fonctionnel
if (z>0)
{
vx = (8 * vx * face->s1->translated.z)
/
(1024 * face->s1->translated.z + (1024 - vx) * face->s2->translated.z);
vy = (8 * vy * face->s1->translated.z)
/
(1024 * face->s1->translated.z + (1024 - vy) * face->s3->translated.z);
// Affichage du point
if (FE_zbuffer_set_dist(x,y,z))
dpixel(x, y, 3*FE_get_pixel(face->texturenum, vx, vy)); // 3* means cast to black and white, and vx,and vy casted between 0 and 7
}
}
}
@ -132,4 +151,4 @@ void FE_draw_face(FE_face const * face)
// soit diviseur_commun = (xAB*yAC-yAB*xAC)
// x=xAM*yAC/diviseur_commun-yAM*xAC/diviseur_commun
// y=yAM*xAB/diviseur_commun-xAM*yAB/diciseur_commun
}
}

View File

@ -2,14 +2,13 @@
#define FE_FACE_H
#include "coord.h"
#include "FxEngine.h"
#include <stdbool.h>
typedef struct FE_face FE_face;
struct FE_face
{
FE_point *s1,*s2,*s3;
bool visible; // true => clockwised
int texturenum;
FE_point *s1,*s2,*s3;
bool visible; // true => clockwised
int texturenum;
};
void FE_draw_face(FE_face const * face);

View File

@ -1,60 +1,66 @@
#include "zbuffer.h"
#include <stdint.h>
#include <stdbool.h>
#include <gint/display.h>
#include <gint/std/stdio.h>
#include <gint/std/stdlib.h>
#include <gint/keyboard.h>
#include <gint/dma.h>
#include <gint/hardware.h>
/** size_uint32
* taille du zbuffer exprimée en uint32_t
* utile pour l'effacement du zbuffer sur sh3
**/
static const int size_uint32 = FE_ZB_SIZE_X*FE_ZB_SIZE_X;
/* size_uint32
taille du zbuffer exprimée en uint32_t
utile pour l'effacement du zbuffer sur sh3 */
static const uint32_t size_int32 = FE_ZB_SIZE_X*FE_ZB_SIZE_Y;
/** size_char
* taille du zbuffer exprimée en octets
* sera utile pour le DMA Controller
**/
static const int size_char = size_uint32*sizeof(uint32_t);
/* size_char
taille du zbuffer exprimée en octets
utile pour malloc */
static const uint32_t size_char = size_int32*sizeof(int32_t);
/** address
* addresse du zbuffer
**/
static uint32_t* address=0;
/* size_char
taille du zbuffer exprimée en octets
utile pour le DMA */
static const uint32_t size_blocks = size_char/32;
// buffer situe a la fin de la RAM
static const int32_t *address = (void *)0x88080000 - size_char;
#include <gint/defs/attributes.h>
GALIGNED(32) GSECTION(".rodata") static const int32_t clearval[8]={3000,3000,3000,3000,3000,3000,3000,3000};
void FE_zbuffer_clear()
{
while (address==0)
{
address = malloc(size_octets);
if (address==0) // cas de figure où il n'y a plus assez de RAM
{
dclear(C_WHITE);
dtext(1, 1, "Not enough RAM...", C_BLACK, C_NONE);
}
}
// TODO déterminer le type d'effacement
// effacement fait par le CPU
uint32_t indice = 0;
for (indice = 0; indice < size_uint32; indice ++)
address[indice] = 3000;
// effacement fait par le DMA
// TODO
if (isSH3())
{ // effacement CPU
uint_fast16_t indice;
for (indice = 0; indice < size_int32; indice ++)
address[indice] = clearval[0];
}
else
{ // effacement DMA
dma_transfer(0, DMA_32B, size_blocks, &clearval, DMA_FIXED, address, DMA_INC);
}
}
bool FE_zbuffer_set_dist(int x, int y, int dist)
void FE_start_rendering()
{
x %= FE_ZB_SIZE_X;
y %= FE_ZB_SIZE_Y;
const int indice = x * 64 + y;
if (address[indice]>dist && dist>0)
{
address[indice] = dist;
return true;
}
else
return false;
}
if (!isSH3())
dma_transfer_wait(0);
}
bool FE_zbuffer_set_dist(int32_t x, int32_t y, int32_t dist)
{
x %= FE_ZB_SIZE_X;
y %= FE_ZB_SIZE_Y;
const uint32_t indice = x * 64 + y;
if (address[indice]>dist && dist>0)
{
address[indice] = dist;
return true;
}
else
return false;
}

View File

@ -12,11 +12,17 @@
void FE_zbuffer_clear();
#include <stdbool.h>
#include <stdint.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_dist(int x, int y, int dist); // if you are allowed to draw the pixel on vram
bool FE_zbuffer_set_dist(int32_t x, int32_t y, int32_t dist); // if you are allowed to draw the pixel on vram
#endif
/* FE_zbuffer_set_dist
doit être appelée avant l'affichage
attend la fin du transfert dma effaçant le zbuffer
**/
void FE_start_rendering();
#endif

View File

@ -10,29 +10,29 @@
int main(void)
{
init_controls();
dclear(C_WHITE);
FE_point point[4]={{{10,0,0},{0,0,0}},{{10,10,0},{0,0,0}},{{10,0,10},{0,0,0}},{{10,10,10},{0,0,0}}};
FE_face face={&point[0],&point[1],&point[2],1,2};
FE_face face2={&point[3],&point[1],&point[2],0,2};
init_controls();
dclear(C_WHITE);
FE_point point[4]={{{10,0,0},{0,0,0}},{{10,10,0},{0,0,0}},{{10,0,10},{0,0,0}},{{10,10,10},{0,0,0}}};
FE_face face={&point[0],&point[1],&point[2],1,2};
FE_face face2={&point[3],&point[1],&point[2],0,2};
while (1)
{
FE_new_frame();
reload_fps_displaying();
for (int i=0;i<4;i++)
{
FE_calc(&point[i]);
if (point[i].translated.z>0)
{
dpixel(point[i].translated.x,point[i].translated.y,C_BLACK);
}
}
FE_draw_face(&face);
FE_draw_face(&face2);
display_fps(100,56);
}
getkey();
return 1;
while (1)
{
FE_new_frame();
reload_fps_displaying();
display_fps(100,56);
for (int i=0;i<4;i++)
{
FE_calc(&point[i]);
if (point[i].translated.z>0)
{
dpixel(point[i].translated.x,point[i].translated.y,C_BLACK);
}
}
FE_start_rendering();
FE_draw_face(&face);
FE_draw_face(&face2);
}
getkey();
return 1;
}