major reworks + added colors + added z testing

This commit is contained in:
Alexandre 2025-01-31 17:50:43 +01:00
parent af20c1084e
commit 576e83feeb
30 changed files with 212 additions and 1960 deletions

View File

@ -7,7 +7,10 @@ all: bin/back
test: bin/back test: bin/back
bin/back bin/back
bin/back: obj/main.o obj/generation.o obj/display.o obj/proj.o obj/entities.o obj/bullets.o obj/menus.o obj/triangles.o obj/move.o obj/base.o obj/hash.o mem: bin/back
valgrind --leak-check=full ./bin/back
bin/back: obj/main.o obj/generation.o obj/display.o obj/proj.o obj/entities.o obj/bullets.o obj/menus.o obj/move.o obj/base.o obj/hash.o
mkdir -p bin mkdir -p bin
$(CC) $(FLAGS) $^ $(LFLAGS) -o $@ $(CC) $(FLAGS) $^ $(LFLAGS) -o $@
@ -19,7 +22,6 @@ obj/main.o: src/main.c
obj/generation.o: src/generation.c obj/generation.o: src/generation.c
obj/display.o: src/display.c obj/display.o: src/display.c
obj/entities.o: src/entities.c obj/entities.o: src/entities.c
obj/triangles.o: src/triangles.c
obj/bullets.o: src/bullets.c obj/bullets.o: src/bullets.c
obj/move.o: src/move.c obj/move.o: src/move.c
obj/base.o: src/base.c obj/base.o: src/base.c

BIN
bin/back

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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

@ -198,6 +198,20 @@ cube_0* create_cube_0(double x, double y, double z, double w, double h, double d
return cb ; return cb ;
} }
void fill_cube_0(cube_0* cb, double x, double y, double z, double w, double h, double d, double hz_a, double vt_a, int r, int g, int b) {
cb->red = r ;
cb->green = g ;
cb->blue = b ;
cb->x = x ;
cb->y = y ;
cb->z = z ;
cb->w = w ;
cb->h = h ;
cb->d = d ;
cb->hz_angle = hz_a ;
cb->vt_angle = vt_a ;
}
cube create_cube(double x, double y, double z, double w, double h, double d, double hz_a, double vt_a, int r, int g, int b) { cube create_cube(double x, double y, double z, double w, double h, double d, double hz_a, double vt_a, int r, int g, int b) {
cube cb = malloc(sizeof(cube_0)); cube cb = malloc(sizeof(cube_0));
cb = create_cube_0(x, y, z, w, h, d, hz_a, vt_a, r, g, b) ; cb = create_cube_0(x, y, z, w, h, d, hz_a, vt_a, r, g, b) ;
@ -208,7 +222,7 @@ void free_cube(cube c) {
free(c) ; free(c) ;
} }
teleporter create_teleporter( teleporter* create_teleporter(
double x, double y, double z, double w, double h, double d, double hz_a, double vt_a, int r, int g, int b, double x, double y, double z, double w, double h, double d, double hz_a, double vt_a, int r, int g, int b,
int chx_dest, int chy_dest, double x_dest, double y_dest, double z_dest int chx_dest, int chy_dest, double x_dest, double y_dest, double z_dest
) { ) {
@ -219,7 +233,7 @@ teleporter create_teleporter(
tp->dest_y = y_dest ; tp->dest_y = y_dest ;
tp->dest_z = z_dest ; tp->dest_z = z_dest ;
tp->hitbox = create_cube_0(x, y, z, w, h, d, hz_a, vt_a, r, g, b); tp->hitbox = create_cube_0(x, y, z, w, h, d, hz_a, vt_a, r, g, b);
return *tp ; return tp ;
} }
// ------------------------------------------------------------------------------------------------ // // ------------------------------------------------------------------------------------------------ //
@ -236,18 +250,6 @@ double distance_pt_pt_3d_sq(double x0, double y0, double z0, double x1, double y
return (x1 - x0)*(x1 - x0)+(y1 - y0)*(y1 - y0)+(z1 - z0)*(z1 - z0); return (x1 - x0)*(x1 - x0)+(y1 - y0)*(y1 - y0)+(z1 - z0)*(z1 - z0);
} }
double proj_distance_to_camera(double x, double y, double z) {
return sqrt(x*x + y*y + z*z);
}
double proj_pt_distance_to_camera(pt_2d p) {
return proj_distance_to_camera(p.x, p.y, p.z);
}
double proj_pt_distance_to_camera_sq(pt_2d p) {
return (p.x*p.x + p.y*p.y + p.z*p.z);
}
double distance_pt_seg_3d(double x, double y, double z, double sx, double sy, double sz, double ex, double ey, double ez) { double distance_pt_seg_3d(double x, double y, double z, double sx, double sy, double sz, double ex, double ey, double ez) {
double theta = -( double theta = -(
((ex - sx) * (sx - x) + (ey - sy) * (sy - y) + (ez - sz) * (sz - z)) / ((ex - sx) * (sx - x) + (ey - sy) * (sy - y) + (ez - sz) * (sz - z)) /
@ -307,58 +309,6 @@ double distance_pt_cube_0_3d(double x0, double y0, double z0, cube_0* c) {
return distance_pt_cube_aligned_3d(xrx, yrx, zrx, -c->w/2.0, -c->h/2.0, -c->d/2.0, c->w, c->h, c->d) ; return distance_pt_cube_aligned_3d(xrx, yrx, zrx, -c->w/2.0, -c->h/2.0, -c->d/2.0, c->w, c->h, c->d) ;
} }
double distance_pt_cube_0_3d_max(double x0, double y0, double z0, cube_0 c) {
// places the origin at the center of the cube
double x = x0 - (c.x + c.w/2.0) ;
double y = y0 - (c.y + c.h/2.0) ;
double z = z0 - (c.z + c.d/2.0) ;
// rotate the point : y then x
double xry = x*cos(c.hz_angle) + z*sin(c.hz_angle) ;
double yry = y ;
double zry = z*cos(c.hz_angle) - x*sin(c.hz_angle) ;
double xrx = xry ;
double yrx = yry*cos(c.vt_angle) - zry*sin(c.vt_angle) ;
double zrx = zry*cos(c.vt_angle) + yry*sin(c.vt_angle) ;
// now the cube and pt are aligned, and (0, 0, 0) is at the cube's (bary)center
return distance_pt_cube_aligned_3d_max(xrx, yrx, zrx, -c.w/2.0, -c.h/2.0, -c.d/2.0, c.w, c.h, c.d) ;
}
double distance_pt_cube_aligned_3d_weighted(double x0, double y0, double z0, double cx, double cy, double cz, double cw, double ch, double cd, double mx, double my, double mz) {
return (mx*distance_pt_cube_axis(x0, cx, cx+cw)+my*distance_pt_cube_axis(y0, cy, cy+ch)+mz*distance_pt_cube_axis(z0, cz, cz+cd)) ;
}
double distance_pt_cube_0_3d_weighted(double x0, double y0, double z0, double mx, double my, double mz, cube_0 c) {
// places the origin at the center of the cube
double x = x0 - (c.x + c.w/2.0) ;
double y = y0 - (c.y + c.h/2.0) ;
double z = z0 - (c.z + c.d/2.0) ;
// rotate the point : y then x
double xry = x*cos(c.hz_angle) + z*sin(c.hz_angle) ;
double yry = y ;
double zry = z*cos(c.hz_angle) - x*sin(c.hz_angle) ;
double xrx = xry ;
double yrx = yry*cos(c.vt_angle) - zry*sin(c.vt_angle) ;
double zrx = zry*cos(c.vt_angle) + yry*sin(c.vt_angle) ;
// now the cube and pt are aligned, and (0, 0, 0) is at the cube's (bary)center
return distance_pt_cube_aligned_3d_weighted(xrx, yrx, zrx, -c.w/2.0, -c.h/2.0, -c.d/2.0, c.w, c.h, c.d, mx, my, mz) ;
}
double distance_pt_cube_3d(double x0, double y0, double z0, cube cb) {
return distance_pt_cube_0_3d(x0, y0, z0, cb) ;
}
double zdepth_of_pt(double x0, double y0, double z0) {
double pz0;
project_to_camera(x0, y0, z0, NULL, NULL, &pz0);
return pz0;
}
// ------------------------------------------------------------------------------------------------ // // ------------------------------------------------------------------------------------------------ //
void project_to_camera(double x0, double y0, double z0, double* rx, double* ry, double* rz) { void project_to_camera(double x0, double y0, double z0, double* rx, double* ry, double* rz) {
@ -440,256 +390,3 @@ void add_entity(entity** arr, int* memlen, int* len, entity ent) {
(*arr)[*len] = ent ; (*arr)[*len] = ent ;
*len += 1; *len += 1;
} }
// ------------------------------------------------------------------------------------------------ //
void import_digits(SDL_Renderer* renderer) {
imgs res;
res.arr = malloc(sizeof(SDL_Texture*)*11);
SDL_Texture* texture;
SDL_Surface* img;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/digits/digit-0.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[0] = texture;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/digits/digit-1.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[1] = texture;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/digits/digit-2.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[2] = texture;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/digits/digit-3.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[3] = texture;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/digits/digit-4.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[4] = texture;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/digits/digit-5.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[5] = texture;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/digits/digit-6.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[6] = texture;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/digits/digit-7.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[7] = texture;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/digits/digit-8.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[8] = texture;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/digits/digit-9.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[9] = texture;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/digits/sign-minus.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[10] = texture;
res.len = 11 ;
digits = res;
}
void import_letters(SDL_Renderer* renderer) {
imgs res;
res.arr = malloc(sizeof(SDL_Texture*)*26);
SDL_Texture* texture;
SDL_Surface* img;
int cc = 0 ;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/letters/letter-a.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[cc] = texture;
cc += 1 ;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/letters/letter-b.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[cc] = texture;
cc += 1 ;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/letters/letter-c.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[cc] = texture;
cc += 1 ;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/letters/letter-d.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[cc] = texture;
cc += 1 ;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/letters/letter-e.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[cc] = texture;
cc += 1 ;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/letters/letter-f.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[cc] = texture;
cc += 1 ;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/letters/letter-g.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[cc] = texture;
cc += 1 ;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/letters/letter-h.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[cc] = texture;
cc += 1 ;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/letters/letter-i.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[cc] = texture;
cc += 1 ;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/letters/letter-j.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[cc] = texture;
cc += 1 ;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/letters/letter-k.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[cc] = texture;
cc += 1 ;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/letters/letter-l.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[cc] = texture;
cc += 1 ;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/letters/letter-m.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[cc] = texture;
cc += 1 ;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/letters/letter-n.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[cc] = texture;
cc += 1 ;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/letters/letter-o.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[cc] = texture;
cc += 1 ;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/letters/letter-p.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[cc] = texture;
cc += 1 ;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/letters/letter-q.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[cc] = texture;
cc += 1 ;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/letters/letter-r.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[cc] = texture;
cc += 1 ;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/letters/letter-s.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[cc] = texture;
cc += 1 ;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/letters/letter-t.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[cc] = texture;
cc += 1 ;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/letters/letter-u.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[cc] = texture;
cc += 1 ;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/letters/letter-v.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[cc] = texture;
cc += 1 ;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/letters/letter-w.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[cc] = texture;
cc += 1 ;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/letters/letter-x.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[cc] = texture;
cc += 1 ;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/letters/letter-y.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[cc] = texture;
cc += 1 ;
// -------------------------------------------------------- //
img = SDL_LoadBMP("./res/letters/letter-z.bmp");
texture = SDL_CreateTextureFromSurface(renderer, img);
SDL_FreeSurface(img);
res.arr[cc] = texture;
res.len = 26 ;
letters = res;
}
void free_digits(imgs dgts) {
for(int i = 0; i < dgts.len; i++) {
SDL_DestroyTexture(dgts.arr[i]);
}
free(dgts.arr);
}

View File

@ -30,18 +30,16 @@ double dot2D(pt_2d p1, pt_2d p2);
double dot3D(pt_2d p1, pt_2d p2); double dot3D(pt_2d p1, pt_2d p2);
cube_0* create_cube_0(double x, double y, double z, double w, double h, double d, double hz_a, double vt_a, int r, int g, int b); cube_0* create_cube_0(double x, double y, double z, double w, double h, double d, double hz_a, double vt_a, int r, int g, int b);
void fill_cube_0(cube_0* cb, double x, double y, double z, double w, double h, double d, double hz_a, double vt_a, int r, int g, int b);
cube create_cube(double x, double y, double z, double w, double h, double d, double hz_a, double vt_a, int r, int g, int b); cube create_cube(double x, double y, double z, double w, double h, double d, double hz_a, double vt_a, int r, int g, int b);
void free_cube(cube c); void free_cube(cube c);
teleporter create_teleporter( teleporter* create_teleporter(
double x, double y, double z, double w, double h, double d, double hz_a, double vt_a, int r, int g, int b, double x, double y, double z, double w, double h, double d, double hz_a, double vt_a, int r, int g, int b,
int chx_dest, int chy_dest, double x_dest, double y_dest, double z_dest int chx_dest, int chy_dest, double x_dest, double y_dest, double z_dest
); );
double convex_pt(double a, double b, double theta); double convex_pt(double a, double b, double theta);
double distance_pt_pt_3d(double x0, double y0, double z0, double x1, double y1, double z1); double distance_pt_pt_3d(double x0, double y0, double z0, double x1, double y1, double z1);
double proj_distance_to_camera(double x, double y, double z);
double proj_pt_distance_to_camera(pt_2d p);
double proj_pt_distance_to_camera_sq(pt_2d p);
double distance_pt_seg_3d(double x, double y, double z, double sx, double sy, double sz, double ex, double ey, double ez); double distance_pt_seg_3d(double x, double y, double z, double sx, double sy, double sz, double ex, double ey, double ez);
double convex_pt(double a, double b, double theta); double convex_pt(double a, double b, double theta);
@ -53,24 +51,14 @@ double distance_pt_cube_axis(double coord, double begin, double end);
double distance_pt_cube_aligned_3d(double x0, double y0, double z0, double cx, double cy, double cz, double cw, double ch, double cd); double distance_pt_cube_aligned_3d(double x0, double y0, double z0, double cx, double cy, double cz, double cw, double ch, double cd);
double distance_pt_cube_0_3d(double x0, double y0, double z0, cube_0* c); double distance_pt_cube_0_3d(double x0, double y0, double z0, cube_0* c);
double distance_pt_cube_aligned_3d_weighted(double x0, double y0, double z0, double cx, double cy, double cz, double cw, double ch, double cd, double mx, double my, double mz);
double distance_pt_cube_0_3d_weighted(double x0, double y0, double z0, double mx, double my, double mz, cube_0 c);
double distance_pt_cube_axis_max(double coord, double begin, double end); double distance_pt_cube_axis_max(double coord, double begin, double end);
double distance_pt_cube_aligned_3d_max(double x0, double y0, double z0, double cx, double cy, double cz, double cw, double ch, double cd); double distance_pt_cube_aligned_3d_max(double x0, double y0, double z0, double cx, double cy, double cz, double cw, double ch, double cd);
double distance_pt_cube_0_3d_max(double x0, double y0, double z0, cube_0 c);
double zdepth_of_pt(double x0, double y0, double z0);
void remove_entity(entity** arr, int* memlen, int* len, int index); void remove_entity(entity** arr, int* memlen, int* len, int index);
void add_entity(entity** arr, int* memlen, int* len, entity ent); void add_entity(entity** arr, int* memlen, int* len, entity ent);
double distance_pt_cube_3d(double x0, double y0, double z0, cube cb);
void project_to_camera(double x0, double y0, double z0, double* rx, double* ry, double* rz); void project_to_camera(double x0, double y0, double z0, double* rx, double* ry, double* rz);
void project_to_cube(double x0, double y0, double z0, double* rx, double* ry, double* rz, cube_0 c); void project_to_cube(double x0, double y0, double z0, double* rx, double* ry, double* rz, cube_0 c);
double dist_to_cam_cube(double x0, double y0, double z0, cube_0 c); double dist_to_cam_cube(double x0, double y0, double z0, cube_0 c);
void import_digits(SDL_Renderer* renderer);
void import_letters(SDL_Renderer* renderer);
void free_digits(imgs dgts);
#endif #endif

View File

@ -17,3 +17,4 @@
#include "move.h" #include "move.h"
#include "entities.h" #include "entities.h"
#include "bullets.h" #include "bullets.h"

View File

@ -2,4 +2,5 @@
#define BULLETS_H #define BULLETS_H
#endif #endif

View File

@ -17,7 +17,6 @@
#include "hash.h" #include "hash.h"
#include "structure.h" #include "structure.h"
#include "base.h" #include "base.h"
#include "triangles.h"
#include "move.h" #include "move.h"
#include "proj.h" #include "proj.h"
#include "entities.h" #include "entities.h"
@ -28,854 +27,10 @@ int flashlight = 10 ;
int MAX_SIZE = 8192 ; int MAX_SIZE = 8192 ;
int* drawOrder; int* drawOrder ;
double draw_constant ;
pt_2d** triangles_to_render ;
pt_2d** triangles_og_coords ;
//double* triangles_areas ;
int triangles_i ;
int* reds ;
int* greens ;
int* blues ;
int* triangles_order ;
bool* visited_tri ;
bool* triangles_shr ;
int visited_i ;
double shrink_distance;
void init_draworder() { void init_draworder() {
drawOrder = malloc(sizeof(int)*6) ; drawOrder = malloc(sizeof(int)*6) ;
draw_constant = 0.4 ;
triangles_to_render = malloc(sizeof(pt_2d*)*MAX_SIZE) ;
triangles_og_coords = malloc(sizeof(pt_2d*)*MAX_SIZE) ;
reds = malloc(sizeof(int)*MAX_SIZE) ;
greens = malloc(sizeof(int)*MAX_SIZE) ;
blues = malloc(sizeof(int)*MAX_SIZE) ;
triangles_order = malloc(sizeof(int)*MAX_SIZE) ;
//triangles_areas = malloc(sizeof(double)*MAX_SIZE) ;
visited_tri = malloc(sizeof(bool)*MAX_SIZE) ;
triangles_shr = malloc(sizeof(bool)*MAX_SIZE) ;
for(int k = 0; k < MAX_SIZE; k++) {
triangles_to_render[k] = malloc(sizeof(pt_2d)*3);
triangles_og_coords[k] = malloc(sizeof(pt_2d)*3);
triangles_order[k] = k;
visited_tri[k] = false;
triangles_shr[k] = false;
}
triangles_i = 0;
visited_i = 0;
shrink_distance = 800.0;
}
void updateRenderer(SDL_Renderer* renderer) {
//printf("E");
SDL_RenderPresent(renderer);
}
void resetRenderer(SDL_Renderer* renderer) {
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
}
void drawRectToRenderer(SDL_Renderer* renderer, SDL_Rect* rect, int R, int G, int B, int A) {
SDL_SetRenderDrawColor(renderer, R, G, B, A);
SDL_RenderFillRect(renderer, rect);
}
void placeRectToRenderer(SDL_Renderer* renderer, int X, int Y, int W, int H, int R, int G, int B, int A) {
SDL_Rect rect;
rect.x = X;
rect.y = Y;
rect.w = W;
rect.h = H;
assert(SDL_SetRenderDrawColor(renderer, R, G, B, A) == 0);
assert(SDL_RenderFillRect(renderer, &rect) == 0);
}
void placeRectToRendererNoColor(SDL_Renderer* renderer, int X, int Y, int W, int H) {
SDL_Rect rect;
rect.x = X;
rect.y = Y;
rect.w = W;
rect.h = H;
SDL_RenderFillRect(renderer, &rect);
}
void drawLineWithThicc(SDL_Renderer* renderer, int width, int x1, int x2, int y1, int y2, int R, int G, int B, int A) {
// draws line with width (native SDL cannot do that)
double theta = 0.0;
double seglen = distance_pt_pt_3d(x1, y1, 0.0, x2, y2, 0.0);
while(theta < 1.0) {
placeRectToRenderer(renderer, convex_seg(x1, x2, theta)-width/2, convex_seg(y1, y2, theta)-width/2, width, width, R, G, B, A);
theta += 1 / seglen;
}
}
void drawLineWithThiccNoColor(SDL_Renderer* renderer, int width, int x1, int x2, int y1, int y2) {
// draws line with width (native SDL cannot do that)
double theta = 0.0;
double seglen = distance_pt_pt_3d(x1, y1, 0.0, x2, y2, 0.0);
while(theta < 1.0) {
placeRectToRendererNoColor(renderer, convex_seg(x1, x2, theta)-width/2, convex_seg(y1, y2, theta)-width/2, width, width);
theta += 1 / seglen;
}
}
void drawLineWithThiccGradient(SDL_Renderer* renderer, int start_width, int end_width, int x1, int x2, int y1, int y2, int R, int G, int B, int A) {
// draws line with width ;
// width goes from start_width to end_with in a linear way
double theta = 0.0;
double seglen = distance_pt_pt_3d(x1, y1, 0.0, x2, y2, 0.0);
while(theta < 1.0) {
int width = convex_seg(start_width, end_width, theta) ;
placeRectToRenderer(renderer, convex_seg(x1, x2, theta)-width/2, convex_seg(y1, y2, theta)-width/2, width, width, R, G, B, A);
theta += 1 / seglen;
}
}
void drawDigitToRenderer(SDL_Renderer* renderer, imgs data, int digit, int X, int Y, int W, int H) {
if(digit == -727) {
SDL_Rect rect;
rect.x = X;
rect.y = Y;
rect.w = W;
rect.h = H;
SDL_Texture* texture = data.arr[10];
SDL_RenderCopy(renderer, texture, NULL, &rect);
} else if (!(0 <= digit && digit <= 9)) {
fprintf(stderr, "Illegal digit : '%d'.\n", digit);
exit(1);
} else {
SDL_Rect rect;
rect.x = X;
rect.y = Y;
rect.w = W;
rect.h = H;
SDL_Texture* texture = data.arr[digit];
SDL_RenderCopy(renderer, texture, NULL, &rect);
}
}
void drawCharToRenderer(SDL_Renderer* renderer, imgs data, char c, int X, int Y, int W, int H) {
if ((int)c >= 97 && (int)c <= 122) {
SDL_Rect rect;
rect.x = X;
rect.y = Y;
rect.w = W;
rect.h = H;
SDL_Texture* texture = data.arr[(int)c - 97];
SDL_RenderCopy(renderer, texture, NULL, &rect);
}
}
void drawNumberToRenderer(SDL_Renderer* renderer, imgs data, int n, int X, int Y, int W, int H, int Woffset) {
if(n == 0) {
drawDigitToRenderer(renderer, data, 0, X + W, Y, W, H);
} else if(n > 0) {
int toDraw = 0, remaining = n, nIter = ln_baseN(n, 10);
while(nIter != 0) {
toDraw = remaining%10;
remaining = remaining / 10;
drawDigitToRenderer(renderer, data, toDraw, X + (W-Woffset)*nIter, Y, W, H);
nIter--;
}
} else {
int toDraw = 0, remaining = -n, nIter = ln_baseN(-n, 10);
drawDigitToRenderer(renderer, data, -727, X, Y, W, H);
while(nIter != 0) {
toDraw = remaining%10;
remaining = remaining / 10;
drawDigitToRenderer(renderer, data, toDraw, X + (W-Woffset)*nIter, Y, W, H);
nIter--;
}
}
}
void drawStringToRenderer(SDL_Renderer* renderer, imgs data, char* s, int X, int Y, int W, int H) {
int k = 0 ;
while(s[k] != '\0') {
drawCharToRenderer(renderer, data, s[k], X + W*k, Y, W, H);
k += 1;
}
}
// ---------------------------------------------------------------------------------------------------------------------------------- //
// 3D stuff
double pt_z_distance_to_camera(double x, double y, double z) {
double ret ;
project_to_camera(x, y, z, NULL, NULL, &ret) ;
return absf(ret) ;
}
double segment_z_distance_to_camera(double x0, double y0, double z0, double x1, double y1, double z1) {
double ret0 = pt_z_distance_to_camera(x0, y0, z0);
double ret1 = pt_z_distance_to_camera(x1, y1, z1);
double theta = -(
((x1 - x0) * (x0 - camx) + (y1 - y0) * (y0 - camy) + (z1 - z0) * (z0 - camz)) /
((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0) + (z1 - z0) * (z1 - z0))
); // projection factor of camera onto the line
return absf(convex_pt(ret0, ret1, mind(maxd(theta, 0.0), 1.0)));
}
double square_z_distance_to_camera(
double x0, double y0, double z0,
double x1, double y1, double z1,
double x2, double y2, double z2
) {
return maxd(segment_z_distance_to_camera(x0, y0, z0, x1, y1, z1), segment_z_distance_to_camera(x0, y0, z0, x2, y2, z2));
}
// ---------------------------------------------------------------------------------------------------------------------------------- //
void rotate_cube(double x0, double y0, double z0, double* rx, double* ry, double* rz, cube_0* cb) {
// align pt to (0, 0, 0)
double x = x0 - (cb->x + cb->w/2.0) ;
double y = y0 - (cb->y + cb->h/2.0) ;
double z = z0 - (cb->z + cb->d/2.0) ;
// rotate (y)
double xry = x*cos(cb->hz_angle) - z*sin(cb->hz_angle) ;
double yry = y ;
double zry = z*cos(cb->hz_angle) + x*sin(cb->hz_angle) ;
// rotate (x)
*rx = (cb->x + cb->w/2.0) + xry ;
*ry = (cb->y + cb->h/2.0) + yry*cos(cb->vt_angle) - zry*sin(cb->vt_angle) ;
*rz = (cb->z + cb->d/2.0) + zry*cos(cb->vt_angle) + yry*sin(cb->vt_angle) ;
}
pt_2d pt_rotate_cube_3d(double x0, double y0, double z0, cube_0* cb) {
pt_2d res;
rotate_cube(x0, y0, z0, &(res.x), &(res.y), &(res.z), cb);
return res;
}
void draw_segment(SDL_Renderer* renderer, double sx, double sy, double sz, double ex, double ey, double ez) {
double spx ;double spy ;double spz ;double epx ;double epy ;double epz ;
project_to_camera(sx, sy, sz, &spx, &spy, &spz) ;
project_to_camera(ex, ey, ez, &epx, &epy, &epz) ;
if(spz >= draw_constant && epz >= draw_constant) {
drawLineWithThiccNoColor(renderer, 1,
(int)(1500.0 * (1.0 + (spx / (1.5 * spz * tan_fov))) / 2.0),
(int)(1500.0 * (1.0 + (epx / (1.5 * epz * tan_fov))) / 2.0),
(int)(1000.0 * (1.0 + (spy / (spz * tan_fov))) / 2.0),
(int)(1000.0 * (1.0 + (epy / (epz * tan_fov))) / 2.0)
) ;
} else if(epz >= draw_constant) {
double midx = convex_pt(ex, sx, (epz - draw_constant)/(epz - spz)) ;
double midy = convex_pt(ey, sy, (epz - draw_constant)/(epz - spz)) ;
double midz = convex_pt(ez, sz, (epz - draw_constant)/(epz - spz)) ;
project_to_camera(midx, midy, midz, &spx, &spy, &spz) ;
//printf("* %f\n", spz) ;
drawLineWithThiccNoColor(renderer, 1,
(int)(1500.0 * (1.0 + (spx / (1.5 * spz * tan_fov))) / 2.0),
(int)(1500.0 * (1.0 + (epx / (1.5 * epz * tan_fov))) / 2.0),
(int)(1000.0 * (1.0 + (spy / (spz * tan_fov))) / 2.0),
(int)(1000.0 * (1.0 + (epy / (epz * tan_fov))) / 2.0)
) ;
} else if(spz >= draw_constant) {
double midx = convex_pt(sx, ex, (spz - draw_constant)/(spz - epz)) ;
double midy = convex_pt(sy, ey, (spz - draw_constant)/(spz - epz)) ;
double midz = convex_pt(sz, ez, (spz - draw_constant)/(spz - epz)) ;
project_to_camera(midx, midy, midz, &epx, &epy, &epz) ;
//printf("%f *\n", epz) ;
drawLineWithThiccNoColor(renderer, 1,
(int)(1500.0 * (1.0 + (spx / (1.5 * spz * tan_fov))) / 2.0),
(int)(1500.0 * (1.0 + (epx / (1.5 * epz * tan_fov))) / 2.0),
(int)(1000.0 * (1.0 + (spy / (spz * tan_fov))) / 2.0),
(int)(1000.0 * (1.0 + (epy / (epz * tan_fov))) / 2.0)
) ;
} // else : not visible (behind camera)
}
void axialRotation_X0(double* y, double* z, double theta) {
double y0 = *y ;
*y = (*y)*cos(theta) - (*z)*sin(theta) ;
*z = (*z)*cos(theta) + y0*sin(theta) ;
}
void axialRotation_X(double* y, double* z, double theta, double cst_y, double cst_z) {
// project the space onto the (y, z) plane to get cst_y and cst_z
double y1 = *y - cst_y;
double z1 = *z - cst_z;
axialRotation_X0(&y1, &z1, theta);
*y = y1 + cst_y ;
*z = z1 + cst_z ;
}
void axialRotation_Y0(double* x, double* z, double theta) {
double x0 = *x ;
*x = (*x)*cos(theta) + (*z)*sin(theta) ;
*z = (*z)*cos(theta) - x0*sin(theta) ;
}
void axialRotation_Y(double* x, double* z, double theta, double cst_x, double cst_z) {
// project the space onto the (y, z) plane to get cst_y and cst_z
double x1 = *x - cst_x;
double z1 = *z - cst_z;
axialRotation_Y0(&x1, &z1, theta);
*x = x1 + cst_x ;
*z = z1 + cst_z ;
}
void axialRotation_Z0(double* x, double* y, double theta) {
double x0 = *x ;
*x = (*x)*cos(theta) - (*y)*sin(theta) ;
*y = (*y)*cos(theta) + x0*sin(theta) ;
}
void axialRotation_Z(double* x, double* y, double theta, double cst_x, double cst_y) {
// project the space onto the (y, z) plane to get cst_y and cst_z
double x1 = *x - cst_x;
double y1 = *y - cst_y;
axialRotation_Z0(&x1, &y1, theta);
*x = x1 + cst_x ;
*y = y1 + cst_y ;
}
void drawSegmentRotated(SDL_Renderer* renderer, double sx, double sy, double sz, double ex, double ey, double ez, double hz_angle, double vt_angle, double center_x, double center_y, double center_z) {
double psx = sx;
double psy = sy;
double psz = sz;
double pex = ex;
double pey = ey;
double pez = ez;
axialRotation_Y(&psx, &psz, -hz_angle, center_x, center_z);
axialRotation_Y(&pex, &pez, -hz_angle, center_x, center_z);
// minus signs cause the base is indirect
axialRotation_X(&psy, &psz, vt_angle, center_y, center_z);
axialRotation_X(&pey, &pez, vt_angle, center_y, center_z);
draw_segment(renderer, psx, psy, psz, pex, pey, pez);
}
void drawOutlineOfCube_0(SDL_Renderer* renderer, cube_0 c) {
// x = constant
drawSegmentRotated(renderer, c.x, c.y, c.z, c.x + c.w, c.y, c.z, c.hz_angle, c.vt_angle, c.x + c.w/2.0, c.y + c.h/2.0, c.z + c.d/2.0) ;
drawSegmentRotated(renderer, c.x, c.y + c.h, c.z, c.x + c.w, c.y + c.h, c.z, c.hz_angle, c.vt_angle, c.x + c.w/2.0, c.y + c.h/2.0, c.z + c.d/2.0) ;
drawSegmentRotated(renderer, c.x, c.y, c.z + c.d, c.x + c.w, c.y, c.z + c.d, c.hz_angle, c.vt_angle, c.x + c.w/2.0, c.y + c.h/2.0, c.z + c.d/2.0) ;
drawSegmentRotated(renderer, c.x, c.y + c.h, c.z + c.d, c.x + c.w, c.y + c.h, c.z + c.d, c.hz_angle, c.vt_angle, c.x + c.w/2.0, c.y + c.h/2.0, c.z + c.d/2.0) ;
// y = constant
drawSegmentRotated(renderer, c.x, c.y, c.z, c.x, c.y + c.h, c.z, c.hz_angle, c.vt_angle, c.x + c.w/2.0, c.y + c.h/2.0, c.z + c.d/2.0) ;
drawSegmentRotated(renderer, c.x + c.w, c.y, c.z, c.x + c.w, c.y + c.h, c.z, c.hz_angle, c.vt_angle, c.x + c.w/2.0, c.y + c.h/2.0, c.z + c.d/2.0) ;
drawSegmentRotated(renderer, c.x, c.y, c.z + c.d, c.x, c.y + c.h, c.z + c.d, c.hz_angle, c.vt_angle, c.x + c.w/2.0, c.y + c.h/2.0, c.z + c.d/2.0) ;
drawSegmentRotated(renderer, c.x + c.w, c.y, c.z + c.d, c.x + c.w, c.y + c.h, c.z + c.d, c.hz_angle, c.vt_angle, c.x + c.w/2.0, c.y + c.h/2.0, c.z + c.d/2.0) ;
// z = constant
drawSegmentRotated(renderer, c.x, c.y, c.z, c.x, c.y, c.z + c.d, c.hz_angle, c.vt_angle, c.x + c.w/2.0, c.y + c.h/2.0, c.z + c.d/2.0) ;
drawSegmentRotated(renderer, c.x + c.w, c.y, c.z, c.x + c.w, c.y, c.z + c.d, c.hz_angle, c.vt_angle, c.x + c.w/2.0, c.y + c.h/2.0, c.z + c.d/2.0) ;
drawSegmentRotated(renderer, c.x, c.y + c.h, c.z, c.x, c.y + c.h, c.z + c.d, c.hz_angle, c.vt_angle, c.x + c.w/2.0, c.y + c.h/2.0, c.z + c.d/2.0) ;
drawSegmentRotated(renderer, c.x + c.w, c.y + c.h, c.z, c.x + c.w, c.y + c.h, c.z + c.d, c.hz_angle, c.vt_angle, c.x + c.w/2.0, c.y + c.h/2.0, c.z + c.d/2.0) ;
}
// -------------------------------------------------------------------------------------------------------------------------------- //
// this is where the fun begins
int surfaceDrawOrder(double x0, double y0, double z0, cube_0* cb) {
// returns the number of surfaces that should be drawn, as well as filling drawOrder for said surfaces :
// 0 = +x ; 1 = -x
// 2 = +y ; 3 = -y
// 4 = +z ; 5 = -z
// align cube center to (0, 0, 0)
double x = x0 - (cb->x + cb->w/2.0) ;
double y = y0 - (cb->y + cb->h/2.0) ;
double z = z0 - (cb->z + cb->d/2.0) ;
// rotate (y)
double xry = x*cos(cb->hz_angle) + z*sin(cb->hz_angle) ;
double yry = y ;
double zry = z*cos(cb->hz_angle) - x*sin(cb->hz_angle) ;
// rotate (x)
double xrx = xry ;
double yrx = yry*cos(cb->vt_angle) + zry*sin(cb->vt_angle) ;
double zrx = zry*cos(cb->vt_angle) - yry*sin(cb->vt_angle) ;
// cube is centered and aligned
int id = 0 ;
if(xrx > cb->w/2.0) {
drawOrder[id] = 0 ;
id += 1 ;
} else if(xrx < -cb->w/2.0) {
drawOrder[id] = 1 ;
id += 1 ;
}
if(yrx > cb->h/2.0) {
drawOrder[id] = 2 ;
id += 1 ;
} else if(yrx < -cb->h/2.0) {
drawOrder[id] = 3 ;
id += 1 ;
}
if(zrx > cb->d/2.0) {
drawOrder[id] = 4 ;
id += 1 ;
} else if(zrx < -cb->d/2.0) {
drawOrder[id] = 5 ;
id += 1 ;
}
if(id == 0) { // inside the cube
for(int k = 0; k < 6; k++) {
drawOrder[k] = k ;
}
return 6;
} else {
return id ;
}
}
SDL_Vertex construct_vertex(double px, double py, int r, int g, int b, int a) {
SDL_Vertex vtx ;
vtx.color.r = r ;
vtx.color.g = g ;
vtx.color.b = b ;
vtx.color.a = a ;
vtx.position.x = (float)px ;
vtx.position.y = (float)py ;
vtx.tex_coord.x = 0.0f;
vtx.tex_coord.y = 0.0f;
return vtx ;
}
void renderTriangleNoProject(
SDL_Renderer* renderer,
double px0, double py0, double pz0,
double px1, double py1, double pz1,
double px2, double py2, double pz2,
int red, int green, int blue, bool debug
) {
const SDL_Vertex vtxs[3] = {
construct_vertex(px0, py0, max(red - (int)(flashlight*pz0), 0), max(green - (int)(flashlight*pz0), 0), max(blue - (int)(flashlight*pz0), 0), 255),
construct_vertex(px1, py1, max(red - (int)(flashlight*pz1), 0), max(green - (int)(flashlight*pz1), 0), max(blue - (int)(flashlight*pz1), 0), 255),
construct_vertex(px2, py2, max(red - (int)(flashlight*pz2), 0), max(green - (int)(flashlight*pz2), 0), max(blue - (int)(flashlight*pz2), 0), 255),
};
if(debug) {
printf("P[*] : (%f, %f), (%f, %f), (%f, %f)\n", vtxs[0].position.x, vtxs[0].position.y, vtxs[1].position.x, vtxs[1].position.y, vtxs[2].position.x, vtxs[2].position.y);
}
assert(SDL_RenderGeometry(renderer, NULL, vtxs, 3, NULL, 0) == 0);
}
double getZbuffer(double x, double y, double z) {
return sqrt(x*x + y*y + z*z);
//return z;
//return (2.0*(z - near)/(far - near) -1.0);
//return ((far + near)/(far - near) + (1.0/z)*((-2.0*far*near)/(far - near)));
}
pt_2d to_pt_2d(double x0, double y0, double z0) {
pt_2d res;
res.x = x0;
res.y = y0;
res.z = z0;
return res;
}
bool inside_fov(double px, double py) {
return true ;
}
pt_2d bounding_box_botleft(int k) {
pt_2d res;
res.x = mind(triangles_to_render[k][0].x, mind(triangles_to_render[k][1].x, triangles_to_render[k][2].x));
res.y = mind(triangles_to_render[k][0].y, mind(triangles_to_render[k][1].y, triangles_to_render[k][2].y));
return res;
}
pt_2d bounding_box_topright(int k) {
pt_2d res;
res.x = maxd(triangles_to_render[k][0].x, maxd(triangles_to_render[k][1].x, triangles_to_render[k][2].x));
res.y = maxd(triangles_to_render[k][0].y, maxd(triangles_to_render[k][1].y, triangles_to_render[k][2].y));
return res;
}
bool bbox_inside_cam(int k) {
pt_2d btl = bounding_box_botleft(k);
pt_2d tpr = bounding_box_topright(k);
return !(tpr.x <= 0.0 || btl.x >= 1500.0 || tpr.y <= 0.0 || btl.y >= 1000.0);
}
bool triangle_reduce(pt_2d* tri) {
return (
distance_pt_pt_2d_sq(tri[0].x, tri[0].y, tri[1].x, tri[1].y) +
distance_pt_pt_2d_sq(tri[1].x, tri[1].y, tri[2].x, tri[2].y) +
distance_pt_pt_2d_sq(tri[2].x, tri[2].y, tri[0].x, tri[0].y) <= shrink_distance
);
}
void addTriangle(
double x0, double y0, double z0,
double x1, double y1, double z1,
double x2, double y2, double z2,
int red, int green, int blue
) {
double px0; double py0; double pz0;
double px1; double py1; double pz1;
double px2; double py2; double pz2;
double fpx0; double fpy0; double fpz0;
double fpx1; double fpy1; double fpz1;
double mpx0; double mpy0; double mpz0;
double mpx1; double mpy1; double mpz1;
double mx0, my0, mz0, mx1, my1, mz1;
project_to_camera(x0, y0, z0, &px0, &py0, &pz0);
project_to_camera(x1, y1, z1, &px1, &py1, &pz1);
project_to_camera(x2, y2, z2, &px2, &py2, &pz2);
if(inside_fov(px0, py0) || inside_fov(px1, py1) || inside_fov(px2, py2)) {
if(pz0 >= draw_constant && pz1 >= draw_constant && pz2 >= draw_constant) {
triangles_to_render[triangles_i][0] = to_pt_2d(1500.0 * (1.0 + (px0 / (1.5 * pz0 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py0 / (pz0 * tan_fov))) / 2.0, getZbuffer(px0, py0, pz0));
triangles_to_render[triangles_i][1] = to_pt_2d(1500.0 * (1.0 + (px1 / (1.5 * pz1 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py1 / (pz1 * tan_fov))) / 2.0, getZbuffer(px1, py1, pz1));
triangles_to_render[triangles_i][2] = to_pt_2d(1500.0 * (1.0 + (px2 / (1.5 * pz2 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py2 / (pz2 * tan_fov))) / 2.0, getZbuffer(px2, py2, pz2));
if(bbox_inside_cam(triangles_i)) {
triangles_og_coords[triangles_i][0] = to_pt_2d(px0, py0, pz0);
triangles_og_coords[triangles_i][1] = to_pt_2d(px1, py1, pz1);
triangles_og_coords[triangles_i][2] = to_pt_2d(px2, py2, pz2);
triangles_shr[triangles_i] = triangle_reduce(triangles_to_render[triangles_i]);
//triangles_areas[triangles_i] = area_of_triangle(triangles_to_render[triangles_i]);
reds[triangles_i] = red ;
greens[triangles_i] = green ;
blues[triangles_i] = blue ;
triangles_i += 1;
}
} else if((pz0 >= draw_constant) + (pz1 >= draw_constant) + (pz2 >= draw_constant) == 2) {
if(pz0 < draw_constant) {
// pz1 >= draw_constant and pz2 >+ draw_constant
fpx0 = px1 ; fpy0 = py1 ; fpz0 = pz1 ;
fpx1 = px2 ; fpy1 = py2 ; fpz1 = pz2 ;
mx0 = convex_pt(x1, x0, (pz1 - draw_constant)/(pz1 - pz0));
my0 = convex_pt(y1, y0, (pz1 - draw_constant)/(pz1 - pz0));
mz0 = convex_pt(z1, z0, (pz1 - draw_constant)/(pz1 - pz0));
mx1 = convex_pt(x2, x0, (pz2 - draw_constant)/(pz2 - pz0));
my1 = convex_pt(y2, y0, (pz2 - draw_constant)/(pz2 - pz0));
mz1 = convex_pt(z2, z0, (pz2 - draw_constant)/(pz2 - pz0));
// 1-0 segment
project_to_camera(mx0, my0, mz0, &mpx0, &mpy0, &mpz0) ;
// 0-2 segment
project_to_camera(mx1, my1, mz1, &mpx1, &mpy1, &mpz1) ;
} else if(pz1 < draw_constant) {
// pz0 >= draw_constant and pz2 >+ draw_constant
fpx0 = px0 ; fpy0 = py0 ; fpz0 = pz0 ;
fpx1 = px2 ; fpy1 = py2 ; fpz1 = pz2 ;
mx0 = convex_pt(x0, x1, (pz0 - draw_constant)/(pz0 - pz1));
my0 = convex_pt(y0, y1, (pz0 - draw_constant)/(pz0 - pz1));
mz0 = convex_pt(z0, z1, (pz0 - draw_constant)/(pz0 - pz1));
mx1 = convex_pt(x2, x1, (pz2 - draw_constant)/(pz2 - pz1));
my1 = convex_pt(y2, y1, (pz2 - draw_constant)/(pz2 - pz1));
mz1 = convex_pt(z2, z1, (pz2 - draw_constant)/(pz2 - pz1));
// 0-1 segment
project_to_camera(mx0, my0, mz0, &mpx0, &mpy0, &mpz0) ;
// 1-2 segment
project_to_camera(mx1, my1, mz1, &mpx1, &mpy1, &mpz1) ;
} else /*if(pz2 < draw_constant)*/ {
// pz1 >= draw_constant and pz0 >+ draw_constant
fpx0 = px0 ; fpy0 = py0 ; fpz0 = pz0 ;
fpx1 = px1 ; fpy1 = py1 ; fpz1 = pz1 ;
mx0 = convex_pt(x0, x2, (pz0 - draw_constant)/(pz0 - pz2));
my0 = convex_pt(y0, y2, (pz0 - draw_constant)/(pz0 - pz2));
mz0 = convex_pt(z0, z2, (pz0 - draw_constant)/(pz0 - pz2));
mx1 = convex_pt(x1, x2, (pz1 - draw_constant)/(pz1 - pz2));
my1 = convex_pt(y1, y2, (pz1 - draw_constant)/(pz1 - pz2));
mz1 = convex_pt(z1, z2, (pz1 - draw_constant)/(pz1 - pz2));
// 0-2 segment
project_to_camera(mx0, my0, mz0, &mpx0, &mpy0, &mpz0) ;
// 1-2 segment
project_to_camera(mx1, my1, mz1, &mpx1, &mpy1, &mpz1) ;
}
triangles_to_render[triangles_i][0] = to_pt_2d(1500.0 * (1.0 + (fpx0 / (1.5 * fpz0 * tan_fov))) / 2.0, 1000.0 * (1.0 + (fpy0 / (fpz0 * tan_fov))) / 2.0, getZbuffer(fpx0, fpy0, fpz0));
triangles_to_render[triangles_i][1] = to_pt_2d(1500.0 * (1.0 + (mpx0 / (1.5 * mpz0 * tan_fov))) / 2.0, 1000.0 * (1.0 + (mpy0 / (mpz0 * tan_fov))) / 2.0, getZbuffer(mpx0, mpy0, mpz0));
triangles_to_render[triangles_i][2] = to_pt_2d(1500.0 * (1.0 + (fpx1 / (1.5 * fpz1 * tan_fov))) / 2.0, 1000.0 * (1.0 + (fpy1 / (fpz1 * tan_fov))) / 2.0, getZbuffer(fpx1, fpy1, fpz1));
if(bbox_inside_cam(triangles_i)) {
triangles_og_coords[triangles_i][0] = to_pt_2d(fpx0, fpy0, fpz0);
triangles_og_coords[triangles_i][1] = to_pt_2d(mpx0, mpy0, mpz0);
triangles_og_coords[triangles_i][2] = to_pt_2d(fpx1, fpy1, fpz1);
triangles_shr[triangles_i] = triangle_reduce(triangles_to_render[triangles_i]);
reds[triangles_i] = red ;
greens[triangles_i] = green ;
blues[triangles_i] = blue ;
triangles_i += 1;
}
//triangles_areas[triangles_i] = area_of_triangle(triangles_to_render[triangles_i]);
triangles_to_render[triangles_i][0] = to_pt_2d(1500.0 * (1.0 + (mpx0 / (1.5 * mpz0 * tan_fov))) / 2.0, 1000.0 * (1.0 + (mpy0 / (mpz0 * tan_fov))) / 2.0, getZbuffer(mpx0, mpy0, mpz0));
triangles_to_render[triangles_i][1] = to_pt_2d(1500.0 * (1.0 + (mpx1 / (1.5 * mpz1 * tan_fov))) / 2.0, 1000.0 * (1.0 + (mpy1 / (mpz1 * tan_fov))) / 2.0, getZbuffer(mpx1, mpy1, mpz1));
triangles_to_render[triangles_i][2] = to_pt_2d(1500.0 * (1.0 + (fpx1 / (1.5 * fpz1 * tan_fov))) / 2.0, 1000.0 * (1.0 + (fpy1 / (fpz1 * tan_fov))) / 2.0, getZbuffer(fpx1, fpy1, fpz1));
if(bbox_inside_cam(triangles_i)) {
triangles_og_coords[triangles_i][0] = to_pt_2d(mpx0, mpy0, mpz0);
triangles_og_coords[triangles_i][1] = to_pt_2d(mpx1, mpy1, mpz1);
triangles_og_coords[triangles_i][2] = to_pt_2d(fpx1, fpy1, fpz1);
triangles_shr[triangles_i] = triangle_reduce(triangles_to_render[triangles_i]);
reds[triangles_i] = red ;
greens[triangles_i] = green ;
blues[triangles_i] = blue ;
triangles_i += 1;
}
//triangles_areas[triangles_i+1] = area_of_triangle(triangles_to_render[triangles_i+1]);
} else if((pz0 >= draw_constant) + (pz1 >= draw_constant) + (pz2 >= draw_constant) == 1) {
if(pz0 >= draw_constant) {
project_to_camera(
convex_pt(x0, x1, (pz0 - draw_constant)/(pz0 - pz1)),
convex_pt(y0, y1, (pz0 - draw_constant)/(pz0 - pz1)),
convex_pt(z0, z1, (pz0 - draw_constant)/(pz0 - pz1)),
&px1, &py1, &pz1);
project_to_camera(
convex_pt(x0, x2, (pz0 - draw_constant)/(pz0 - pz2)),
convex_pt(y0, y2, (pz0 - draw_constant)/(pz0 - pz2)),
convex_pt(z0, z2, (pz0 - draw_constant)/(pz0 - pz2)),
&px2, &py2, &pz2);
} else if(pz1 >= draw_constant) {
project_to_camera(
convex_pt(x1, x0, (pz1 - draw_constant)/(pz1 - pz0)),
convex_pt(y1, y0, (pz1 - draw_constant)/(pz1 - pz0)),
convex_pt(z1, z0, (pz1 - draw_constant)/(pz1 - pz0)),
&px0, &py0, &pz0);
project_to_camera(
convex_pt(x1, x2, (pz1 - draw_constant)/(pz1 - pz2)),
convex_pt(y1, y2, (pz1 - draw_constant)/(pz1 - pz2)),
convex_pt(z1, z2, (pz1 - draw_constant)/(pz1 - pz2)),
&px2, &py2, &pz2);
} else if(pz2 >= draw_constant) {
project_to_camera(
convex_pt(x2, x0, (pz2 - draw_constant)/(pz2 - pz0)),
convex_pt(y2, y0, (pz2 - draw_constant)/(pz2 - pz0)),
convex_pt(z2, z0, (pz2 - draw_constant)/(pz2 - pz0)),
&px0, &py0, &pz0);
project_to_camera(
convex_pt(x2, x1, (pz2 - draw_constant)/(pz2 - pz1)),
convex_pt(y2, y1, (pz2 - draw_constant)/(pz2 - pz1)),
convex_pt(z2, z1, (pz2 - draw_constant)/(pz2 - pz1)),
&px1, &py1, &pz1);
}
triangles_to_render[triangles_i][0] = to_pt_2d(1500.0 * (1.0 + (px0 / (1.5 * pz0 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py0 / (pz0 * tan_fov))) / 2.0, getZbuffer(px0, py0, pz0));
triangles_to_render[triangles_i][1] = to_pt_2d(1500.0 * (1.0 + (px1 / (1.5 * pz1 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py1 / (pz1 * tan_fov))) / 2.0, getZbuffer(px1, py1, pz1));
triangles_to_render[triangles_i][2] = to_pt_2d(1500.0 * (1.0 + (px2 / (1.5 * pz2 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py2 / (pz2 * tan_fov))) / 2.0, getZbuffer(px2, py2, pz2));
if(bbox_inside_cam(triangles_i)) {
triangles_og_coords[triangles_i][0] = to_pt_2d(px0, py0, pz0);
triangles_og_coords[triangles_i][1] = to_pt_2d(px1, py1, pz1);
triangles_og_coords[triangles_i][2] = to_pt_2d(px2, py2, pz2);
triangles_shr[triangles_i] = triangle_reduce(triangles_to_render[triangles_i]);
//triangles_areas[triangles_i] = area_of_triangle(triangles_to_render[triangles_i]);
reds[triangles_i] = red ;
greens[triangles_i] = green ;
blues[triangles_i] = blue ;
triangles_i += 1;
}
} else {
}
}
}
void addTriangleRotated(
double x0, double y0, double z0,
double x1, double y1, double z1,
double x2, double y2, double z2,
int red, int green, int blue,
cube_0* cb
) {
if(true) {
double px0; double py0; double pz0;
double px1; double py1; double pz1;
double px2; double py2; double pz2;
rotate_cube(x0, y0, z0, &px0, &py0, &pz0, cb);
rotate_cube(x1, y1, z1, &px1, &py1, &pz1, cb);
rotate_cube(x2, y2, z2, &px2, &py2, &pz2, cb);
if(triangles_i < MAX_SIZE -1) {
addTriangle(px0, py0, pz0, px1, py1, pz1, px2, py2, pz2, red, green, blue);
}
}
}
// -------------------------------------------------------------------------------------------------------------------------------- //
void add_single(cube_0* c) { // x
int leng = surfaceDrawOrder(camx, camy, camz, c);
for(int sf0 = 0; sf0 < leng; sf0++) {
int sf = drawOrder[sf0];
if(sf == 0 || sf == 1) {
addTriangleRotated(
c->x + c->w*(sf==0), c->y , c->z,
c->x + c->w*(sf==0), c->y + c->h, c->z,
c->x + c->w*(sf==0), c->y + c->h, c->z + c->d,
c->red, c->green, c->blue, c
);
addTriangleRotated(
c->x + c->w*(sf==0), c->y, c->z,
c->x + c->w*(sf==0), c->y, c->z + c->d,
c->x + c->w*(sf==0), c->y + c->h, c->z + c->d,
c->red, c->green, c->blue, c
);
} else if(sf == 2 || sf == 3) {
addTriangleRotated(
c->x , c->y + c->h*(sf==2), c->z,
c->x + c->w, c->y + c->h*(sf==2), c->z,
c->x + c->w, c->y + c->h*(sf==2), c->z + c->d,
c->red, c->green, c->blue, c
);
addTriangleRotated(
c->x , c->y + c->h*(sf==2), c->z,
c->x , c->y + c->h*(sf==2), c->z + c->d,
c->x + c->w, c->y + c->h*(sf==2), c->z + c->d,
c->red, c->green, c->blue, c
);
} else { // z
addTriangleRotated(
c->x , c->y , c->z + c->d*(sf==4),
c->x + c->w, c->y , c->z + c->d*(sf==4),
c->x + c->w, c->y + c->h, c->z + c->d*(sf==4),
c->red, c->green, c->blue, c
);
addTriangleRotated(
c->x , c->y , c->z + c->d*(sf==4),
c->x , c->y + c->h, c->z + c->d*(sf==4),
c->x + c->w, c->y + c->h, c->z + c->d*(sf==4),
c->red, c->green, c->blue, c
);
}
}
}
void add_triangles_cb(cube_0** arr, int len) {
for(int k = 0; k < len; k++) {
add_single(arr[k]);
}
}
void add_triangles_tp(teleporter* arr, int len) {
for(int k = 0; k < len; k++) {
add_single(arr[k].hitbox);
}
}
void add_triangles_ent(entity* arr, int len) {
for(int k = 0; k < len; k++) {
add_single(arr[k].pos);
}
}
void renderTriangleFull(SDL_Renderer* renderer, int k) {
renderTriangleNoProject(renderer,
triangles_to_render[k][0].x, triangles_to_render[k][0].y, triangles_to_render[k][0].z,
triangles_to_render[k][1].x, triangles_to_render[k][1].y, triangles_to_render[k][1].z,
triangles_to_render[k][2].x, triangles_to_render[k][2].y, triangles_to_render[k][2].z,
reds[k], greens[k], blues[k], false
);
}
void remove_hidden(SDL_Renderer* renderer) {
//printf("%d --> ", triangles_i);
for(int k = 0; k < triangles_i; k++) {
int halt = 1 ;
bool fst = false ;
bool snd = false ;
bool thd = false ;
for(int l = 0; l < halt*triangles_i; l++) {
if(l != k) {
fst = fst || (is_hidden(renderer, triangles_to_render[k][0], triangles_og_coords[k][0], triangles_to_render[l], triangles_og_coords[l]));
snd = snd || (is_hidden(renderer, triangles_to_render[k][1], triangles_og_coords[k][1], triangles_to_render[l], triangles_og_coords[l]));
thd = thd || (is_hidden(renderer, triangles_to_render[k][2], triangles_og_coords[k][2], triangles_to_render[l], triangles_og_coords[l]));
if(fst && snd && thd) {
triangles_to_render[k][0] = triangles_to_render[triangles_i-1][0] ;
triangles_to_render[k][1] = triangles_to_render[triangles_i-1][1] ;
triangles_to_render[k][2] = triangles_to_render[triangles_i-1][2] ;
reds[k] = reds[triangles_i-1];
greens[k] = greens[triangles_i-1];
blues[k] = blues[triangles_i-1];
//triangles_areas[k] = triangles_areas[triangles_i-1];
triangles_i -= 1;
k -= 1;
halt = 0;
}
}
}
halt = 1 ;
}
//printf("%d\n", triangles_i);
}
void visit(int k, bool vflag) {
if(visited_tri[k] != vflag) {
visited_tri[k] = vflag ;
for(int l = 0; l < triangles_i; l++) {
if(l != k && visited_tri[l] != vflag) {
if(triangles_shr[k] == false && triangles_shr[l] == false) {
if(is_in_front(triangles_to_render[k], triangles_og_coords[k], triangles_to_render[l], triangles_og_coords[l])) {
visit(l, vflag);
}
} else if(triangles_shr[k] == false) {
if(!is_in_front_lite(triangles_to_render[l], triangles_og_coords[l], triangles_to_render[k], triangles_og_coords[k])) {
visit(l, vflag);
}
} else if(triangles_shr[l] == false) {
if(is_in_front_lite(triangles_to_render[k], triangles_og_coords[k], triangles_to_render[l], triangles_og_coords[l])) {
visit(l, vflag);
}
} else {
if(is_in_front_pt_pt(triangles_to_render[k], triangles_og_coords[k], triangles_to_render[l], triangles_og_coords[l])) {
visit(l, vflag);
}
}
}
}
triangles_order[visited_i] = k;
visited_i += 1;
}
}
void topological_sort() {
bool vflag = !visited_tri[0];
for(int k = 0; k < triangles_i; k++) {
visit(k, vflag);
}
}
void drawCurrentRoom(SDL_Renderer* renderer) {
triangles_i = 0;
visited_i = 0;
add_triangles_cb(current_room->map, current_room->map_size);
add_triangles_tp(current_room->tps, current_room->tps_size);
add_triangles_ent(current_room->ents, current_room->ent_len);
drawProj();
//topological_sort();
//remove_hidden(renderer);
topological_sort();
for(int k = 0; k < triangles_i; k++) {
renderTriangleFull(renderer, triangles_order[k]);
}
for(int k = 0; k < 0*triangles_i; k++) {
for(int l = 0; l < 3; l++) {
drawNumberToRenderer(renderer, digits,
(int)(proj_pt_distance_to_camera(triangles_og_coords[k][l])),
(int)(triangles_to_render[k][l].x),
(int)(triangles_to_render[k][l].y),
75/5, 105/5, 0
);
}
}
}
// -------------------------------------------------------------------------------------------------------------------------------- //
void drawData(SDL_Renderer* renderer) {
drawNumberToRenderer(renderer, digits, (int)camx, 10, 10, 75/2, 105/2, 0) ;
drawNumberToRenderer(renderer, digits, (int)camy, 10, 60, 75/2, 105/2, 0) ;
drawNumberToRenderer(renderer, digits, (int)camz, 10, 110, 75/2, 105/2, 0) ;
drawNumberToRenderer(renderer, digits, (int)(rot_hz*180.0/3.14159), 10, 190, 75/2, 105/2, 0) ;
drawNumberToRenderer(renderer, digits, (int)(rot_vt*180.0/3.14159), 10, 240, 75/2, 105/2, 0) ;
drawNumberToRenderer(renderer, digits, player_chx, 310, 10, 75/2, 105/2, 0);
drawNumberToRenderer(renderer, digits, player_chy, 310, 60, 75/2, 105/2, 0);
} }
float vertices[9] ; float vertices[9] ;
@ -935,55 +90,8 @@ pt_2d gl_project(pt_2d p) {
return res; return res;
} }
mat4 model, view, projection;
void gl_renderSurface(unsigned int shaderProgram, unsigned int fragmentShader, unsigned int VAO, unsigned int VBO, cube_0* c, int sf) {
/*
float vertices[] = {
// Positions
-0.5f, -0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
-0.5f, 0.5f, -0.5f,
-0.5f, -0.5f, -0.5f,
-0.5f, -0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
-0.5f, -0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, -0.5f,
-0.5f, -0.5f, -0.5f,
-0.5f, -0.5f, -0.5f,
-0.5f, -0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
0.5f, 0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
0.5f, -0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
-0.5f, -0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
0.5f, -0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
-0.5f, -0.5f, 0.5f,
-0.5f, -0.5f, -0.5f,
-0.5f, 0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, -0.5f
};*/
void gl_renderSurface(unsigned int shaderProgram, unsigned int VAO, unsigned int VBO, cube_0* c, int sf) {
float vertices[] = { float vertices[] = {
(float)(-c->w/2.0), (float)(-c->h/2.0), (float)(-c->d/2.0), (float)(-c->w/2.0), (float)(-c->h/2.0), (float)(-c->d/2.0),
(float)(-c->w/2.0), (float)(c->h/2.0), (float)(-c->d/2.0), (float)(-c->w/2.0), (float)(c->h/2.0), (float)(-c->d/2.0),
@ -1028,7 +136,6 @@ void gl_renderSurface(unsigned int shaderProgram, unsigned int VAO, unsigned int
(float)(c->w/2.0), (float)(c->h/2.0), (float)(c->d/2.0), (float)(c->w/2.0), (float)(c->h/2.0), (float)(c->d/2.0),
}; };
mat4 model, view, projection;
glm_mat4_identity(model); glm_mat4_identity(model);
glm_translate(model, (vec3){(float)(c->x+c->w/2.0), (float)(c->y+c->h/2.0), (float)(c->z+c->d/2.0)}); glm_translate(model, (vec3){(float)(c->x+c->w/2.0), (float)(c->y+c->h/2.0), (float)(c->z+c->d/2.0)});
glm_rotate(model, (float)(-c->hz_angle), (vec3){0.0f, 1.0f, 0.0f}); glm_rotate(model, (float)(-c->hz_angle), (vec3){0.0f, 1.0f, 0.0f});
@ -1053,6 +160,9 @@ void gl_renderSurface(unsigned int shaderProgram, unsigned int VAO, unsigned int
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "view"), 1, GL_FALSE, (float*)view); glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "view"), 1, GL_FALSE, (float*)view);
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "projection"), 1, GL_FALSE, (float*)projection); glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "projection"), 1, GL_FALSE, (float*)projection);
glUseProgram(fragmentShader);
glUniform4f(glGetUniformLocation(fragmentShader, "u_color"), c->red/255.0f, c->green/255.0f, c->blue/255.0f, 1.0f);
glBindBuffer(GL_ARRAY_BUFFER, VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
@ -1071,20 +181,20 @@ void gl_renderSurface(unsigned int shaderProgram, unsigned int VAO, unsigned int
glDrawArrays(GL_TRIANGLES, 0, 36); glDrawArrays(GL_TRIANGLES, 0, 36);
} }
void gl_renderCube(unsigned int shaderProgram, unsigned int VAO, unsigned int VBO, cube_0* c) { void gl_renderCube(unsigned int shaderProgram, unsigned int fragmentShader, unsigned int VAO, unsigned int VBO, cube_0* c) {
for(int k = 0; k < 6; k++) { for(int k = 0; k < 6; k++) {
gl_renderSurface(shaderProgram, VAO, VBO, c, k); gl_renderSurface(shaderProgram, fragmentShader, VAO, VBO, c, k);
} }
} }
void gl_renderAll(unsigned int shaderProgram, unsigned int VAO, unsigned int VBO) { void gl_renderAll(unsigned int shaderProgram, unsigned int fragmentShader, unsigned int VAO, unsigned int VBO) {
for(int k = 0; k < current_room->map_size; k++) { for(int k = 0; k < current_room->map_size; k++) {
gl_renderCube(shaderProgram, VAO, VBO, current_room->map[k]); gl_renderCube(shaderProgram, fragmentShader, VAO, VBO, current_room->map[k]);
} }
for(int k = 0; k < current_room->tps_size; k++) { for(int k = 0; k < current_room->tps_size; k++) {
gl_renderCube(shaderProgram, VAO, VBO, current_room->tps[k].hitbox); gl_renderCube(shaderProgram, fragmentShader, VAO, VBO, current_room->tps[k]->hitbox);
} }
for(int k = 0; k < current_room->ent_len; k++) { for(int k = 0; k < current_room->ent_len; k++) {
gl_renderCube(shaderProgram, VAO, VBO, current_room->ents[k].pos); gl_renderCube(shaderProgram, fragmentShader, VAO, VBO, current_room->ents[k].pos);
} }
} }

View File

@ -1,61 +1,7 @@
#ifndef DISPLAY_H #ifndef DISPLAY_H
#define DISPLAY_H #define DISPLAY_H
void init_draworder(); void gl_renderCube(unsigned int shaderProgram, unsigned int fragmentShader, unsigned int VAO, unsigned int VBO, cube_0* c);
void gl_renderAll(unsigned int shaderProgram, unsigned int fragmentShader, unsigned int VAO, unsigned int VBO);
void updateRenderer(SDL_Renderer* renderer);
void resetRenderer(SDL_Renderer* renderer);
void drawRectToRenderer(SDL_Renderer* renderer, SDL_Rect* rect, int R, int G, int B, int A);
void placeRectToRenderer(SDL_Renderer* renderer, int X, int Y, int W, int H, int R, int G, int B, int A);
void placeRectToRendererNoColor(SDL_Renderer* renderer, int X, int Y, int W, int H);
void drawLineWithThicc(SDL_Renderer* renderer, int width, int x1, int x2, int y1, int y2, int R, int G, int B, int A);
void drawLineWithThiccNoColor(SDL_Renderer* renderer, int width, int x1, int x2, int y1, int y2);
void drawLineWithThiccGradient(SDL_Renderer* renderer, int start_width, int end_width, int x1, int x2, int y1, int y2, int R, int G, int B, int A);
void drawDigitToRenderer(SDL_Renderer* renderer, imgs data, int digit, int X, int Y, int W, int H);
void drawCharToRenderer(SDL_Renderer* renderer, imgs data, char c, int X, int Y, int W, int H);
void drawNumberToRenderer(SDL_Renderer* renderer, imgs data, int n, int X, int Y, int W, int H, int Woffset);
void drawStringToRenderer(SDL_Renderer* renderer, imgs data, char* s, int X, int Y, int W, int H);
double pt_z_distance_to_camera(double x, double y, double z);
double segment_z_distance_to_camera(double x0, double y0, double z0, double x1, double y1, double z1);
double square_z_distance_to_camera(
double x0, double y0, double z0,
double x1, double y1, double z1,
double x2, double y2, double z2
);
void addTriangle(
double x0, double y0, double z0,
double x1, double y1, double z1,
double x2, double y2, double z2,
int red, int green, int blue
);
void axialRotation_X0(double* y, double* z, double theta);
void axialRotation_X(double* y, double* z, double theta, double cst_y, double cst_z);
void axialRotation_Y0(double* x, double* z, double theta);
void axialRotation_Y(double* x, double* z, double theta, double cst_x, double cst_z);
void axialRotation_Z0(double* x, double* y, double theta);
void axialRotation_Z(double* x, double* z, double theta, double cst_x, double cst_z);
void project_to_camera(double x0, double y0, double z0, double* rx, double* ry, double* rz);
void draw_segment(SDL_Renderer* renderer, double sx, double sy, double sz, double ex, double ey, double ez);
void drawOutlineOfCube_0(SDL_Renderer* renderer, cube_0 c);
void drawCurrentRoom(SDL_Renderer* renderer);
void drawData(SDL_Renderer* renderer);
void renderTriangleNoProject(
SDL_Renderer* renderer,
double x0, double y0, double z0,
double x1, double y1, double z1,
double x2, double y2, double z2,
int red, int green, int blue, bool debug
);
#endif #endif

View File

@ -20,10 +20,10 @@
// ------------------------------------------------------------------------------------------------------------------------------------------------ // // ------------------------------------------------------------------------------------------------------------------------------------------------ //
bool is_colliding_with_map(cube_0 cb) { bool is_colliding_with_map(cube_0* cb) {
for(int k = 0; k < current_room->map_size; k++) { for(int k = 0; k < current_room->map_size; k++) {
for(int d = 0; d < 8; d++) { for(int d = 0; d < 8; d++) {
if(distance_pt_cube_0_3d(cb.x+cb.w*(d%2==0), cb.y+cb.h*((d/2)%2==0), cb.z+cb.d*((d/4)%2==0), current_room->map[k]) <= 0.01) { if(distance_pt_cube_0_3d(cb->x+cb->w*(d%2==0), cb->y+cb->h*((d/2)%2==0), cb->z+cb->d*((d/4)%2==0), current_room->map[k]) <= 0.01) {
return true ; return true ;
} }
} }
@ -31,10 +31,10 @@ bool is_colliding_with_map(cube_0 cb) {
return false ; return false ;
} }
bool is_colliding_with_tp(cube_0 cb) { bool is_colliding_with_tp(cube_0* cb) {
for(int k = 0; k < current_room->tps_size; k++) { for(int k = 0; k < current_room->tps_size; k++) {
for(int d = 0; d < 8; d++) { for(int d = 0; d < 8; d++) {
if(distance_pt_cube_0_3d(cb.x+cb.w*(d%2==0), cb.y+cb.h*((d/2)%2==0), cb.z+cb.d*((d/4)%2==0), current_room->tps[k].hitbox) <= 0.01) { if(distance_pt_cube_0_3d(cb->x+cb->w*(d%2==0), cb->y+cb->h*((d/2)%2==0), cb->z+cb->d*((d/4)%2==0), current_room->tps[k]->hitbox) <= 0.01) {
return true ; return true ;
} }
} }
@ -65,7 +65,7 @@ void speen(double x, double y, double z, double w, double h, double d, double hz
void speen2(double x, double y, double z, double w, double h, double d, double hz_angle, double vt_angle, float dtime, cube_0* ret) { void speen2(double x, double y, double z, double w, double h, double d, double hz_angle, double vt_angle, float dtime, cube_0* ret) {
ret->hz_angle += ((double)dtime)*22.5; ret->hz_angle += ((double)dtime)*22.5;
if((int)(10.0*ret->hz_angle) != (int)(10.0*(ret->hz_angle - ((double)dtime)*22.5))) { if((int)(5.0*ret->hz_angle) != (int)(5.0*(ret->hz_angle - ((double)dtime)*22.5))) {
double dx = (x+w/2 - camx); double dx = (x+w/2 - camx);
double dy = (y+h/2 - camy); double dy = (y+h/2 - camy);
double dz = (z+d/2 - camz); double dz = (z+d/2 - camz);
@ -73,15 +73,12 @@ void speen2(double x, double y, double z, double w, double h, double d, double h
dx = 170.0*dx/total; dx = 170.0*dx/total;
dy = 170.0*dy/total; dy = 170.0*dy/total;
dz = 170.0*dz/total; dz = 170.0*dz/total;
appendProj(x+w/2, y+h/2, z+d/2, -dx, -dy, -dz, 0.0, 0.0, 0.0, 192, 32, 192, 10, 2.0); appendProj(x, y, z, 0.1, 0.1, 0.1, -dx, -dy, -dz, 0.0, 0.0, 0.0, 255, 0, 0, 10, 3.0);
} }
} }
void speen3(double x, double y, double z, double w, double h, double d, double hz_angle, double vt_angle, float dtime, cube_0* ret) { void speen3(double x, double y, double z, double w, double h, double d, double hz_angle, double vt_angle, float dtime, cube_0* ret) {
ret->vt_angle += ((double)dtime)*22.5; ret->vt_angle += ((double)dtime)*22.5;
if((int)(ret->vt_angle) != (int)(ret->vt_angle - ((double)dtime)*22.5)) {
appendProj(x+w/2, y+h/2, z+d/2, 10.0 + rand()%15, 10.0 + rand()%15, 0.0, 0.0, 0.0, 0.0, 32, 32, 255, 1, 5.0);
}
} }
void detectHit(float dtime, int* hp, int* dmg, cube_0* ret) { void detectHit(float dtime, int* hp, int* dmg, cube_0* ret) {
@ -107,15 +104,15 @@ void go_to_player(double x, double y, double z, double w, double h, double d, do
dy = 110.0*dy/total; dy = 110.0*dy/total;
dz = 110.0*dz/total; dz = 110.0*dz/total;
ret->x -= dtime*dx ; ret->x -= dtime*dx ;
if(is_colliding_with_map(*ret) || is_colliding_with_tp(*ret)) { if(is_colliding_with_map(ret) || is_colliding_with_tp(ret)) {
ret->x += dtime*dx ; ret->x += dtime*dx ;
} }
ret->y -= dtime*dy ; ret->y -= dtime*dy ;
if(is_colliding_with_map(*ret) || is_colliding_with_tp(*ret)) { if(is_colliding_with_map(ret) || is_colliding_with_tp(ret)) {
ret->y += dtime*dy ; ret->y += dtime*dy ;
} }
ret->z -= dtime*dz ; ret->z -= dtime*dz ;
if(is_colliding_with_map(*ret) || is_colliding_with_tp(*ret)) { if(is_colliding_with_map(ret) || is_colliding_with_tp(ret)) {
ret->z += dtime*dz ; ret->z += dtime*dz ;
} }
if((int)(ret->x+ret->y+ret->z) != (int)(ret->x+ret->y+ret->z-dx-dy-dz)) { if((int)(ret->x+ret->y+ret->z) != (int)(ret->x+ret->y+ret->z-dx-dy-dz)) {

View File

@ -1,8 +1,8 @@
#ifndef ENTITIES_H #ifndef ENTITIES_H
#define ENTITIES_H #define ENTITIES_H
bool is_colliding_with_map(cube_0 cb); bool is_colliding_with_map(cube_0* cb);
bool is_colliding_with_tp(cube_0 cb); bool is_colliding_with_tp(cube_0* cb);
void update_entity(entity* ent, float dtime); void update_entity(entity* ent, float dtime);
void update_entities(float dtime); void update_entities(float dtime);

View File

@ -86,18 +86,19 @@ void copy_room(room* src, room* dest, int chx, int chy) {
); );
} }
dest->map_size = src->map_size ; dest->map_size = src->map_size ;
dest->tps = malloc(sizeof(teleporter)*src->tps_size); dest->tps = malloc(sizeof(teleporter*)*src->tps_size);
for(int k = 0; k < src->tps_size; k++) { for(int k = 0; k < src->tps_size; k++) {
dest->tps[k].hitbox = create_cube_0( dest->tps[k] = malloc(sizeof(teleporter));
src->tps[k].hitbox->x, src->tps[k].hitbox->y, src->tps[k].hitbox->z, dest->tps[k]->hitbox = create_cube_0(
src->tps[k].hitbox->w, src->tps[k].hitbox->h, src->tps[k].hitbox->d, src->tps[k]->hitbox->x, src->tps[k]->hitbox->y, src->tps[k]->hitbox->z,
src->tps[k].hitbox->hz_angle, src->tps[k].hitbox->vt_angle, src->tps[k].hitbox->red, src->tps[k].hitbox->green, src->tps[k].hitbox->blue src->tps[k]->hitbox->w, src->tps[k]->hitbox->h, src->tps[k]->hitbox->d,
src->tps[k]->hitbox->hz_angle, src->tps[k]->hitbox->vt_angle, src->tps[k]->hitbox->red, src->tps[k]->hitbox->green, src->tps[k]->hitbox->blue
); );
dest->tps[k].dest_chx = src->tps[k].dest_chx + chx; dest->tps[k]->dest_chx = src->tps[k]->dest_chx + chx;
dest->tps[k].dest_chy = src->tps[k].dest_chy + chy; dest->tps[k]->dest_chy = src->tps[k]->dest_chy + chy;
dest->tps[k].dest_x = src->tps[k].dest_x ; dest->tps[k]->dest_x = src->tps[k]->dest_x ;
dest->tps[k].dest_y = src->tps[k].dest_y ; dest->tps[k]->dest_y = src->tps[k]->dest_y ;
dest->tps[k].dest_z = src->tps[k].dest_z ; dest->tps[k]->dest_z = src->tps[k]->dest_z ;
} }
dest->ents = malloc(sizeof(entity)*src->ent_memlen); dest->ents = malloc(sizeof(entity)*src->ent_memlen);
dest->ent_memlen = src->ent_memlen ; dest->ent_memlen = src->ent_memlen ;
@ -122,9 +123,9 @@ void build_starting_chunk(int chx, int chy) {
room* new = malloc(sizeof(room)); room* new = malloc(sizeof(room));
new->chunk_x = chx ; new->chunk_x = chx ;
new->chunk_y = chy ; new->chunk_y = chy ;
new->map = malloc(sizeof(cube_0)*9); new->map = malloc(sizeof(cube_0*)*9);
new->map_size = 9 ; new->map_size = 9 ;
new->tps = malloc(sizeof(teleporter)*4); new->tps = malloc(sizeof(teleporter*)*4);
new->tps_size = 4 ; new->tps_size = 4 ;
new->map[0] = create_cube_0(0.0, 0.0, 0.0, 5.0, 1.0, 5.0, 0.0, 0.0, 255, 255, 255); new->map[0] = create_cube_0(0.0, 0.0, 0.0, 5.0, 1.0, 5.0, 0.0, 0.0, 255, 255, 255);
@ -262,14 +263,20 @@ void parse_one_room(int id, char* filename) {
nmemlen *= 2.; nmemlen *= 2.;
} }
pool[id].area->map = malloc(sizeof(cube_0)*ncubes); pool[id].area->map = malloc(sizeof(cube_0*)*ncubes);
pool[id].area->map_size = ncubes; pool[id].area->map_size = ncubes;
pool[id].area->tps = malloc(sizeof(teleporter)*ntps); pool[id].area->tps = malloc(sizeof(teleporter*)*ntps);
for(int k = 0; k < ntps; k++) {
pool[id].area->tps[k] = malloc(sizeof(teleporter));
}
pool[id].area->tps_size = ntps; pool[id].area->tps_size = ntps;
pool[id].area->ents = malloc(sizeof(entity)*nmemlen); pool[id].area->ents = malloc(sizeof(entity)*nmemlen);
pool[id].area->ent_len = nent ; pool[id].area->ent_len = nent ;
pool[id].area->ent_memlen = nmemlen ; pool[id].area->ent_memlen = nmemlen ;
printf("0/3...\n");
fflush(stdout);
for(int k = 0; k < ncubes; k++) { for(int k = 0; k < ncubes; k++) {
align_to(ptr, '['); align_to(ptr, '[');
double cx = read_float(ptr); double cx = read_float(ptr);
@ -287,6 +294,9 @@ void parse_one_room(int id, char* filename) {
//printf("\n"); //printf("\n");
} }
printf("1/3...\n");
fflush(stdout);
for(int k = 0; k < ntps; k++) { for(int k = 0; k < ntps; k++) {
align_to(ptr, '['); align_to(ptr, '[');
double cx = read_float(ptr); double cx = read_float(ptr);
@ -300,12 +310,15 @@ void parse_one_room(int id, char* filename) {
int red = read_int(ptr, true); int red = read_int(ptr, true);
int green = read_int(ptr, true); int green = read_int(ptr, true);
int blue = read_int(ptr, true); int blue = read_int(ptr, true);
pool[id].area->tps[k].hitbox = create_cube_0(cx, cy, cz, cw, ch, cd, chz, cvt, red, green, blue); pool[id].area->tps[k]->hitbox = create_cube_0(cx, cy, cz, cw, ch, cd, chz, cvt, red, green, blue);
pool[id].area->tps[k].dest_chx = read_int(ptr, true); pool[id].area->tps[k]->dest_chx = read_int(ptr, true);
pool[id].area->tps[k].dest_chy = read_int(ptr, true); pool[id].area->tps[k]->dest_chy = read_int(ptr, true);
//printf("\n"); //printf("\n");
} }
printf("2/3...\n");
fflush(stdout);
for(int k = 0; k < nent; k++) { for(int k = 0; k < nent; k++) {
align_to(ptr, '['); align_to(ptr, '[');
double cx = read_float(ptr); double cx = read_float(ptr);
@ -340,6 +353,9 @@ void parse_one_room(int id, char* filename) {
//printf("\n"); //printf("\n");
} }
printf("3/3...\n");
fflush(stdout);
// debug // debug
for(int k = 0; k < ncubes; k++) { for(int k = 0; k < ncubes; k++) {
printf("(%lf, %lf, %lf), (%lf, %lf, %lf), (%lf, %lf), (%d, %d, %d)\n", printf("(%lf, %lf, %lf), (%lf, %lf, %lf), (%lf, %lf), (%d, %d, %d)\n",
@ -356,6 +372,9 @@ void parse_one_room(int id, char* filename) {
pool[id].area->map[k]->blue pool[id].area->map[k]->blue
); );
} }
printf("OK\n");
fflush(stdout);
printf("\n\n"); printf("\n\n");
pool[id].weight = read_int(ptr, true); pool[id].weight = read_int(ptr, true);
@ -436,7 +455,8 @@ void free_pool() {
free(pool[k0].area->map[k]); free(pool[k0].area->map[k]);
} }
for(int k = 0; k < pool[k0].area->tps_size; k++) { for(int k = 0; k < pool[k0].area->tps_size; k++) {
free(pool[k0].area->tps[k].hitbox); free(pool[k0].area->tps[k]->hitbox);
free(pool[k0].area->tps[k]);
} }
for(int k = 0; k < pool[k0].area->ent_len; k++) { for(int k = 0; k < pool[k0].area->ent_len; k++) {
free(pool[k0].area->ents[k].hitpoints); free(pool[k0].area->ents[k].hitpoints);

View File

@ -65,7 +65,8 @@ void free_all_cubes(room* r) {
free(r->map[k]); free(r->map[k]);
} }
for(int k = 0; k < r->tps_size; k++) { for(int k = 0; k < r->tps_size; k++) {
free(r->tps[k].hitbox); free(r->tps[k]->hitbox);
free(r->tps[k]);
} }
for(int k = 0; k < r->ent_len; k++) { for(int k = 0; k < r->ent_len; k++) {
free(r->ents[k].hitpoints); free(r->ents[k].hitpoints);
@ -77,7 +78,7 @@ void free_all_cubes(room* r) {
} }
void linkedList_free(linkedList lst) { void linkedList_free(linkedList lst) {
// frees rooms as well (require all created rooms to be there) // frees rooms as well (requires all created rooms to be there)
if(lst != NULL) { if(lst != NULL) {
printf("freeing (%d, %d)\n", lst->chx, lst->chy); printf("freeing (%d, %d)\n", lst->chx, lst->chy);
free_all_cubes(lst->area); free_all_cubes(lst->area);

View File

@ -17,7 +17,6 @@
#include "structure.h" #include "structure.h"
#include "base.h" #include "base.h"
#include "move.h" #include "move.h"
#include "triangles.h"
#include "proj.h" #include "proj.h"
#include "entities.h" #include "entities.h"
#include "display.h" #include "display.h"
@ -82,10 +81,10 @@ void processInput(GLFWwindow *window, float dtime) {
stop_evetything = true ; stop_evetything = true ;
} }
if(glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) { if(glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS) {
rot_hz -= sensitivity; rot_hz -= sensitivity;
} }
if(glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS) { if(glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) {
rot_hz += sensitivity; rot_hz += sensitivity;
} }
@ -108,9 +107,10 @@ const char *vertexShaderSource = "#version 330 core\n"
// Fragment Shader Source // Fragment Shader Source
const char *fragmentShaderSource = "#version 330 core\n" const char *fragmentShaderSource = "#version 330 core\n"
"uniform vec4 u_color;\n"
"out vec4 FragColor;\n" "out vec4 FragColor;\n"
"void main() {\n" "void main() {\n"
" FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n" " FragColor = u_color;\n"
"}\0"; "}\0";
int main_alt() { int main_alt() {
@ -140,6 +140,9 @@ int main_alt() {
return -1; return -1;
} }
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
//printf("%f\n", glDepthRange); //printf("%f\n", glDepthRange);
// build and compile our shader program // build and compile our shader program
@ -179,6 +182,7 @@ int main_alt() {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
fprintf(stderr, "ERROR : cannot link shaders"); fprintf(stderr, "ERROR : cannot link shaders");
} }
glDeleteShader(vertexShader); glDeleteShader(vertexShader);
glDeleteShader(fragmentShader); glDeleteShader(fragmentShader);
@ -191,17 +195,13 @@ int main_alt() {
// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s). // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
glBindVertexArray(VAO); glBindVertexArray(VAO);
// uncomment this call to draw in wireframe polygons.
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
// render loop // render loop
// ----------- // -----------
init_csts(); init_csts();
init_hashtbl(); init_hashtbl();
init_draworder();
init_ent_generator(10); init_ent_generator(10);
trInit();
init_proj(); init_proj();
parse_rooms(5); parse_rooms(5);
@ -214,12 +214,13 @@ int main_alt() {
// input // input
// ----- // -----
glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
origin = clock(); origin = clock();
generate_nearby_chunks(1); generate_nearby_chunks(1);
gl_renderAll(shaderProgram, VAO, VBO); gl_renderAll(shaderProgram, shaderProgram, VAO, VBO);
gl_renderProj(shaderProgram, shaderProgram, VAO, VBO);
//printf("01\n"); //printf("01\n");
//fflush(stdout); //fflush(stdout);
@ -229,7 +230,7 @@ int main_alt() {
finish = clock(); finish = clock();
processInput(window, ((float)finish - (float)origin)/CLOCKS_PER_SEC); processInput(window, ((float)finish - (float)origin)/CLOCKS_PER_SEC);
update_entities(((float)finish - (float)origin)/CLOCKS_PER_SEC); update_entities(((float)finish - (float)origin)/CLOCKS_PER_SEC);
updateAllProj(((float)finish - (float)origin)/CLOCKS_PER_SEC); updateProj(((float)finish - (float)origin)/CLOCKS_PER_SEC);
glfwSwapBuffers(window); glfwSwapBuffers(window);
glfwPollEvents(); glfwPollEvents();
@ -238,23 +239,10 @@ int main_alt() {
usleep(interval); usleep(interval);
} }
for(int k = 0; k < MAX_SIZE; k++) {
free(triangles_to_render[k]);
free(triangles_og_coords[k]);
}
free(drawOrder);
free(triangles_to_render);
free(triangles_og_coords);
free(reds);
free(greens);
free(blues);
free(triangles_order);
free(triangles_shr);
free(visited_tri);
free_proj();
//printf("10\n"); //printf("10\n");
//fflush(stdout); //fflush(stdout);
hashtbl_free(visited); hashtbl_free(visited);
free_proj();
free_pool(); free_pool();
// optional: de-allocate all resources once they've outlived their purpose: // optional: de-allocate all resources once they've outlived their purpose:

View File

@ -16,3 +16,4 @@
#include "base.h" #include "base.h"
#include "entities.h" #include "entities.h"
#include "menus.h" #include "menus.h"

View File

@ -2,5 +2,4 @@
#define MENUS_H #define MENUS_H
#endif #endif

View File

@ -58,11 +58,11 @@ void init_csts() {
void set_player_coords(int old_chx, int old_chy) { void set_player_coords(int old_chx, int old_chy) {
for(int k = 0; k < current_room->tps_size; k++) { for(int k = 0; k < current_room->tps_size; k++) {
if(current_room->tps[k].dest_chx == old_chx && current_room->tps[k].dest_chy == old_chy) { if(current_room->tps[k]->dest_chx == old_chx && current_room->tps[k]->dest_chy == old_chy) {
if(true) { if(true) {
camx = current_room->tps[k].hitbox->x + current_room->tps[k].hitbox->w/2.0; camx = current_room->tps[k]->hitbox->x + current_room->tps[k]->hitbox->w/2.0;
camy = current_room->tps[k].hitbox->y + current_room->tps[k].hitbox->h +1.5; camy = current_room->tps[k]->hitbox->y + current_room->tps[k]->hitbox->h +1.5;
camz = current_room->tps[k].hitbox->z + current_room->tps[k].hitbox->d/2.0; camz = current_room->tps[k]->hitbox->z + current_room->tps[k]->hitbox->d/2.0;
} }
return ; return ;
} }
@ -77,15 +77,15 @@ bool is_colliding(float dtime) {
} }
} }
for(int k = 0; k < current_room->tps_size; k++) { for(int k = 0; k < current_room->tps_size; k++) {
double dist = distance_pt_cube_0_3d(camx, camy, camz, current_room->tps[k].hitbox) ; double dist = distance_pt_cube_0_3d(camx, camy, camz, current_room->tps[k]->hitbox) ;
if(dist <= min_dist) { if(dist <= min_dist) {
int old_chx = player_chx ; int old_chx = player_chx ;
int old_chy = player_chy ; int old_chy = player_chy ;
player_chx = current_room->tps[k].dest_chx ; player_chx = current_room->tps[k]->dest_chx ;
player_chy = current_room->tps[k].dest_chy ; player_chy = current_room->tps[k]->dest_chy ;
current_room = hashtbl_find_opt(visited, player_chx, player_chy); current_room = hashtbl_find_opt(visited, player_chx, player_chy);
set_player_coords(old_chx, old_chy); set_player_coords(old_chx, old_chy);
resetProj(); //resetProj();
return true ; return true ;
} }
} }

View File

@ -16,167 +16,110 @@
#include "base.h" #include "base.h"
#include "move.h" #include "move.h"
#include "entities.h" #include "entities.h"
#include "display.h"
#include "proj.h" #include "proj.h"
projectile** bullets ; projectile* bullets ;
int bullets_id ; int bullets_id ;
double psize = 1.5; int MAX_PROJ = 2048 ;
pt_2d build_pt(double x, double y, double z) {
pt_2d res;
res.x = x ;
res.y = y ;
res.z = z ;
return res;
}
void init_proj() { void init_proj() {
bullets = malloc(sizeof(projectile*)*MAX_SIZE); bullets = malloc(sizeof(projectile)*MAX_PROJ);
for(int k = 0; k < MAX_SIZE; k++) { for(int k = 0; k < MAX_PROJ; k++) {
bullets[k] = malloc(sizeof(projectile)); bullets[k].pos = malloc(sizeof(cube_0));
bullets[k]->pos = build_pt(0.0, 0.0, 0.0); bullets[k].vel = malloc(sizeof(pt_2d));
bullets[k]->vel = build_pt(0.0, 0.0, 0.0); bullets[k].acc = malloc(sizeof(pt_2d));
bullets[k]->acc = build_pt(0.0, 0.0, 0.0); bullets[k].ttl = malloc(sizeof(double));
bullets[k]->size = 1.0;
bullets[k]->ttl = 1.0;
bullets[k]->red = 0;
bullets[k]->green = 0;
bullets[k]->blue = 0;
bullets[k]->damage = 0;
}
bullets_id = 0;
}
bool is_proj_colliding_with_map(double x, double y, double z, double size) {
for(int k = 0; k < current_room->map_size; k++) {
if(distance_pt_cube_0_3d(x+size/2, y+size/2, z+size/2, current_room->map[k]) <= size/2) {
return true ;
}
}
return false ;
}
bool is_proj_colliding_with_tp(double x, double y, double z, double size) {
for(int k = 0; k < current_room->tps_size; k++) {
for(int d = 0; d < 8; d++) {
if(distance_pt_cube_0_3d(x+size/2, y+size/2, z+size/2, current_room->tps[k].hitbox) <= size/2) {
return true ;
}
}
}
return false ;
}
bool is_proj_colliding_w_player(double x, double y, double z, double size) {
return (distance_pt_pt_3d(x, y, z, camx, camy, camz) <= size);
}
double ppx, ppy, ppz;
double projx, projy;
void addProjectileToDraw(projectile* proj) {
if(triangles_i < MAX_SIZE-1) {
project_to_camera(proj->pos.x, proj->pos.y, proj->pos.z, &ppx, &ppy, &ppz);
if(ppz >= draw_constant) {
projx = 1500.0 * (1.0 + (ppx / (1.5 * ppz * tan_fov))) / 2.0;
projy = 1000.0 * (1.0 + (ppy / (ppz * tan_fov))) / 2.0;
double rpsize = (40.0*psize/maxd(0.07, ppz));
//printf("%lf\n", rpsize);
triangles_to_render[triangles_i][0] = build_pt(projx-rpsize/2, projy-rpsize/2, 0.0);
triangles_to_render[triangles_i][1] = build_pt(projx-rpsize/2, projy+rpsize/2, 0.0);
triangles_to_render[triangles_i][2] = build_pt(projx+rpsize/2, projy+rpsize/2, 0.0);
triangles_og_coords[triangles_i][0] = build_pt(ppx, ppy, ppz);
triangles_og_coords[triangles_i][1] = build_pt(ppx, ppy, ppz);
triangles_og_coords[triangles_i][2] = build_pt(ppx, ppy, ppz);
triangles_shr[triangles_i] = true;
reds[triangles_i] = proj->red;
greens[triangles_i] = proj->green;
blues[triangles_i] = proj->blue;
triangles_i += 1;
triangles_to_render[triangles_i][0] = build_pt(projx-rpsize/2, projy-rpsize/2, 0.0);
triangles_to_render[triangles_i][1] = build_pt(projx+rpsize/2, projy-rpsize/2, 0.0);
triangles_to_render[triangles_i][2] = build_pt(projx+rpsize/2, projy+rpsize/2, 0.0);
triangles_og_coords[triangles_i][0] = build_pt(ppx, ppy, ppz);
triangles_og_coords[triangles_i][1] = build_pt(ppx, ppy, ppz);
triangles_og_coords[triangles_i][2] = build_pt(ppx, ppy, ppz);
triangles_shr[triangles_i] = true;
reds[triangles_i] = proj->red;
greens[triangles_i] = proj->green;
blues[triangles_i] = proj->blue;
triangles_i += 1;
}
} }
} }
void drawProj() { void free_proj() {
for(int k = 0; k < bullets_id; k++) { for(int k = 0; k < MAX_PROJ; k++) {
addProjectileToDraw(bullets[k]); free(bullets[k].acc);
} free(bullets[k].vel);
} free(bullets[k].pos);
free(bullets[k].ttl);
void appendProj(double x, double y, double z, double vx, double vy, double vz, double ax, double ay, double az, int r, int g, int b, int dmg, double ttl) {
if(bullets_id < MAX_SIZE) {
bullets[bullets_id]->red = r ;
bullets[bullets_id]->green = g ;
bullets[bullets_id]->blue = b ;
bullets[bullets_id]->size = 1.0 ;
bullets[bullets_id]->damage = dmg ;
bullets[bullets_id]->ttl = ttl ;
bullets[bullets_id]->pos = build_pt(x, y, z) ;
bullets[bullets_id]->vel = build_pt(vx, vy, vz) ;
bullets[bullets_id]->acc = build_pt(ax, ay, az) ;
bullets_id += 1;
}
}
void removeProj(int k) {
bullets[k]->red = bullets[bullets_id]->red;
bullets[k]->green = bullets[bullets_id]->green;
bullets[k]->blue = bullets[bullets_id]->blue;
bullets[k]->size = bullets[bullets_id]->size;
bullets[k]->pos = bullets[bullets_id]->pos;
bullets[k]->vel = bullets[bullets_id]->vel;
bullets[k]->acc = bullets[bullets_id]->acc;
bullets[k]->ttl = bullets[bullets_id]->ttl;
bullets[k]->damage = bullets[bullets_id]->damage;
bullets_id -= 1;
}
void updateAllProj(float dtime) {
for(int k = 0; k < bullets_id; k++) {
bullets[k]->vel.x += ((double)dtime)*(bullets[k]->acc.x);
bullets[k]->vel.y += ((double)dtime)*(bullets[k]->acc.y);
bullets[k]->vel.z += ((double)dtime)*(bullets[k]->acc.z);
bullets[k]->pos.x += ((double)dtime)*(bullets[k]->vel.x);
bullets[k]->pos.y += ((double)dtime)*(bullets[k]->vel.y);
bullets[k]->pos.z += ((double)dtime)*(bullets[k]->vel.z);
bullets[k]->ttl -= 20.0*(double)dtime;
//if(k==0) printf("[%d] %lf\n", k, bullets[k]->ttl);
if(is_proj_colliding_w_player(bullets[k]->pos.x - bullets[k]->size/2.0, bullets[k]->pos.y - bullets[k]->size/2.0, bullets[k]->pos.z - bullets[k]->size/2.0, bullets[k]->size)) {
if(bullets[k]->damage != 0) {
player_hp -= bullets[k]->damage ;
fade_dmg = 255 ;
}
removeProj(k);
k -= 1;
} else if(bullets[k]->ttl <= 0.0 || (
is_proj_colliding_with_map(bullets[k]->pos.x - bullets[k]->size/2.0, bullets[k]->pos.y - bullets[k]->size/2.0, bullets[k]->pos.z - bullets[k]->size/2.0, bullets[k]->size) ||
is_proj_colliding_with_tp(bullets[k]->pos.x - bullets[k]->size/2.0, bullets[k]->pos.y - bullets[k]->size/2.0, bullets[k]->pos.z - bullets[k]->size/2.0, bullets[k]->size)
)) {
removeProj(k);
k -= 1;
}
} }
free(bullets);
} }
void resetProj() { void resetProj() {
bullets_id = 0; bullets_id = 0;
} }
void free_proj() { void appendProj(double x, double y, double z, double w, double h, double d, double vx, double vy, double vz, double ax, double ay, double az, int red, int green, int blue, int dmg, double ttl) {
for(int k = 0; k < MAX_SIZE; k++) { if(bullets_id < MAX_PROJ) {
free(bullets[k]); fill_cube_0(bullets[bullets_id].pos, x, y, z, w, h, d, 0.0, 0.0, red, green, blue);
bullets[bullets_id].vel->x = vx;
bullets[bullets_id].vel->y = vy;
bullets[bullets_id].vel->z = vz;
bullets[bullets_id].acc->x = ax;
bullets[bullets_id].acc->y = ay;
bullets[bullets_id].acc->z = az;
*(bullets[bullets_id].ttl) = ttl;
bullets[bullets_id].damage = dmg;
bullets_id += 1;
}
}
void copy_cube(cube_0* src, cube_0* dest) {
dest->red = src->red;
dest->green = src->green;
dest->blue = src->blue;
dest->hz_angle = src->hz_angle;
dest->vt_angle = src->vt_angle;
dest->x = src->x;
dest->y = src->y;
dest->z = src->z;
dest->w = src->w;
dest->h = src->h;
dest->d = src->d;
}
void removeProj(int k) {
if(k >= 0 && k < bullets_id) {
copy_cube(bullets[bullets_id-1].pos, bullets[k].pos);
bullets[k].damage = bullets[bullets_id-1].damage;
*(bullets[k].ttl) = *(bullets[bullets_id-1].ttl);
bullets[k].acc->x = bullets[bullets_id-1].acc->x;
bullets[k].acc->y = bullets[bullets_id-1].acc->y;
bullets[k].acc->z = bullets[bullets_id-1].acc->z;
bullets[k].vel->x = bullets[bullets_id-1].vel->x;
bullets[k].vel->y = bullets[bullets_id-1].vel->y;
bullets[k].vel->z = bullets[bullets_id-1].vel->z;
bullets_id -= 1;
}
}
void gl_renderProj(unsigned int shaderProgram, unsigned int fragmentShader, unsigned int VAO, unsigned int VBO) {
for(int k = 0; k < bullets_id; k++) {
gl_renderCube(shaderProgram, fragmentShader, VAO, VBO, bullets[k].pos);
}
}
void move_cube(cube_0* cb, double dx, double dy, double dz) {
cb->x += dx+dy+dz;
cb->y += dx+dy+dz;
cb->z += dx+dy+dz;
}
void updateProj(float dtime) {
//printf("%d\n", bullets_id);
for(int k = 0; k < bullets_id; k++) {
*(bullets[k].ttl) -= 50.0*(double)dtime;
if(*(bullets[k].ttl) <= 0.0 || is_colliding_with_map(bullets[k].pos) || is_colliding_with_tp(bullets[k].pos)) {
removeProj(k);
k -= 1;
} else {
bullets[k].vel->x += ((double)dtime)*bullets[k].acc->x;
bullets[k].vel->y += ((double)dtime)*bullets[k].acc->y;
bullets[k].vel->z += ((double)dtime)*bullets[k].acc->z;
move_cube(bullets[k].pos, ((double)dtime)*bullets[k].vel->x, ((double)dtime)*bullets[k].vel->y, ((double)dtime)*bullets[k].vel->z);
}
} }
free(bullets);
} }

View File

@ -2,25 +2,20 @@
#define PROJ_H #define PROJ_H
typedef struct projectile { typedef struct projectile {
pt_2d pos ; cube_0* pos;
pt_2d vel ; pt_2d* vel;
pt_2d acc ; pt_2d* acc;
double size; double* ttl;
double ttl;
int red;
int green;
int blue;
int damage; int damage;
} projectile ; } projectile ;
void init_proj(); void init_proj();
void free_proj(); void free_proj();
void drawProj();
void appendProj(double x, double y, double z, double vx, double vy, double vz, double ax, double ay, double az, int r, int g, int b, int dmg, double ttl);
void removeProj(int k);
void updateAllProj(float dtime);
void resetProj(); void resetProj();
void appendProj(double x, double y, double z, double w, double h, double d, double vx, double vy, double vz, double ax, double ay, double az, int red, int green, int blue, int dmg, double ttl);
void removeProj(int k);
void gl_renderProj(unsigned int shaderProgram, unsigned int fragmentShader, unsigned int VAO, unsigned int VBO);
void updateProj(float dtime);
#endif #endif

View File

@ -56,7 +56,7 @@ struct room {
int chunk_y ; int chunk_y ;
cube_0** map ; cube_0** map ;
int map_size ; int map_size ;
teleporter* tps ; teleporter** tps ;
int tps_size ; int tps_size ;
entity* ents ; entity* ents ;
int ent_len ; int ent_len ;
@ -113,29 +113,12 @@ extern int coins ;
extern int draw_type ; extern int draw_type ;
extern double draw_constant ;
extern pt_2d** triangles_to_render ;
extern pt_2d** triangles_og_coords ;
extern double* triangles_areas;
extern int triangles_i ;
extern int player_hp ; extern int player_hp ;
extern int fade_dmg ; extern int fade_dmg ;
extern bool stop_evetything ; extern bool stop_evetything ;
extern int* reds ;
extern int* greens ;
extern int* blues ;
extern int* triangles_order ;
extern bool* triangles_shr ;
extern bool* visited_tri ;
extern int MAX_SIZE ;
extern double shrink_distance ; extern double shrink_distance ;
// ---------------------------------------------------------------------------------------------------- // // ---------------------------------------------------------------------------------------------------- //

View File

@ -1,398 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include <stdbool.h>
#include <ncurses.h>
#include <unistd.h>
#include <termios.h>
#include <limits.h>
#include <time.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include "hash.h"
#include "structure.h"
#include "base.h"
#include "display.h"
#include "triangles.h"
double draw_incr = 0.0 ;
int errno = 0;
pt_2d* triangle_1 ;
pt_2d* triangle_2 ;
pt_2d* cube_t1 ;
pt_2d* cube_t2 ;
int* dOrder1 ;
int* dOrder2 ;
double* zdepths1 ;
double* zdepths2 ;
void trInit() {
triangle_1 = malloc(sizeof(pt_2d)*3);
triangle_2 = malloc(sizeof(pt_2d)*3);
cube_t1 = malloc(sizeof(pt_2d)*6);
cube_t2 = malloc(sizeof(pt_2d)*6);
dOrder1 = malloc(sizeof(int)*6);
dOrder2 = malloc(sizeof(int)*6);
zdepths1 = malloc(sizeof(double)*4);
zdepths2 = malloc(sizeof(double)*4);
}
double det2D(pt_2d* p1, pt_2d* p2, pt_2d* p3) {
return p1->x * (p2->y - p3->y)
+ p2->x * (p3->y - p1->y)
+ p3->x * (p1->y - p2->y);
}
void checkTriWinding(pt_2d * p1, pt_2d * p2, pt_2d * p3, bool allowReversed) {
double detTri = det2D(p1, p2, p3);
if (detTri < 0.0) {
if (allowReversed) {
double t = p3->x;
p3->x = p2->x;
p2->x = t;
t = p3->y;
p3->y = p2->y;
p2->y = t;
} else {
errno = 1;
}
}
}
bool boundaryCollideChk(pt_2d *p1, pt_2d *p2, pt_2d *p3, double eps) {
return det2D(p1, p2, p3) < eps;
}
bool boundaryDoesntCollideChk(pt_2d *p1, pt_2d *p2, pt_2d *p3, double eps) {
return det2D(p1, p2, p3) <= eps;
}
bool triTri2D(pt_2d* t1, pt_2d* t2, double eps, bool allowReversed, bool onBoundary) {
bool(*chkEdge)(pt_2d*, pt_2d*, pt_2d*, double);
int i;
errno = 0;
// Triangles must be expressed anti-clockwise
checkTriWinding(&t1[0], &t1[1], &t1[2], allowReversed);
if (errno != 0) {
return false;
}
checkTriWinding(&t2[0], &t2[1], &t2[2], allowReversed);
if (errno != 0) {
return false;
}
if (onBoundary) {
// pt_2ds on the boundary are considered as colliding
chkEdge = boundaryCollideChk;
} else {
// pt_2ds on the boundary are not considered as colliding
chkEdge = boundaryDoesntCollideChk;
}
//For edge E of trangle 1,
for (i = 0; i < 3; ++i) {
int j = (i + 1) % 3;
//Check all points of trangle 2 lay on the external side of the edge E. If
//they do, the triangles do not collide.
if (chkEdge(&t1[i], &t1[j], &t2[0], eps) &&
chkEdge(&t1[i], &t1[j], &t2[1], eps) &&
chkEdge(&t1[i], &t1[j], &t2[2], eps)) {
return false;
}
}
//For edge E of trangle 2,
for (i = 0; i < 3; i++) {
int j = (i + 1) % 3;
//Check all points of trangle 1 lay on the external side of the edge E. If
//they do, the triangles do not collide.
if (chkEdge(&t2[i], &t2[j], &t1[0], eps) &&
chkEdge(&t2[i], &t2[j], &t1[1], eps) &&
chkEdge(&t2[i], &t2[j], &t1[2], eps))
return false;
}
//The triangles collide
return true;
}
bool triangleIntersection(pt_2d* tri1, pt_2d* tri2) {
return triTri2D(tri1, tri2, 0.0, false, false);
}
bool triangleIntersectionDec(pt_2d t1_1, pt_2d t1_2, pt_2d t1_3, pt_2d t2_1, pt_2d t2_2, pt_2d t2_3) {
triangle_1[0] = t1_1;
triangle_1[1] = t1_2;
triangle_1[2] = t1_3;
triangle_2[0] = t2_1;
triangle_2[1] = t2_2;
triangle_2[2] = t2_3;
return triangleIntersection(triangle_1, triangle_2);
}
bool multipleTrianglesIntersection(pt_2d* tri1, int len1, pt_2d* tri2, int len2, int* ret1, int* ret2) {
for(int k1 = 0; k1 < len1; k1+=3) {
for(int k2 = 0; k2 < len2; k2+=3) {
if(triangleIntersection(&tri1[k1], &tri2[k2])) {
if(ret1 != NULL) {*ret1 = k1;}
if(ret2 != NULL) {*ret2 = k2;}
return true;
}
}
}
return false ;
}
int visibleSurfaces(double x0, double y0, double z0, cube_0 cb, int* dOrd) {
// returns the number of surfaces that should be drawn, as well as filling dOrd for said surfaces :
// 0 = +x ; 1 = -x
// 2 = +y ; 3 = -y
// 4 = +z ; 5 = -z
// align cube center to (0, 0, 0)
double x = x0 - (cb.x + cb.w/2.0) ;
double y = y0 - (cb.y + cb.h/2.0) ;
double z = z0 - (cb.z + cb.d/2.0) ;
// rotate (y)
double xry = x*cos(cb.hz_angle) + z*sin(cb.hz_angle) ;
double yry = y ;
double zry = z*cos(cb.hz_angle) - x*sin(cb.hz_angle) ;
// rotate (x)
double xrx = xry ;
double yrx = yry*cos(cb.vt_angle) + zry*sin(cb.vt_angle) ;
double zrx = zry*cos(cb.vt_angle) - yry*sin(cb.vt_angle) ;
// cube is centered and aligned
int id = 0 ;
if(xrx > cb.w/2.0) {
dOrd[id] = 0 ;
id += 1 ;
} else if(xrx < -cb.w/2.0) {
dOrd[id] = 1 ;
id += 1 ;
}
if(yrx > cb.h/2.0) {
dOrd[id] = 2 ;
id += 1 ;
} else if(yrx < -cb.h/2.0) {
dOrd[id] = 3 ;
id += 1 ;
}
if(zrx > cb.d/2.0) {
dOrd[id] = 4 ;
id += 1 ;
} else if(zrx < -cb.d/2.0) {
dOrd[id] = 5 ;
id += 1 ;
}
if(id == 0) { // inside the cube
for(int k = 0; k < 6; k++) {
dOrd[k] = k ;
}
return 6;
} else {
return id ;
}
}
bool noWT;
double sign_triangle(pt_2d p1, pt_2d p2, pt_2d p3) {
return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y);
}
pt_2d to_pt2d(double x0, double y0, double z0) {
pt_2d res;
res.x = x0;
res.y = y0;
res.z = z0;
return res;
}
double dot_product_3D(pt_2d p1, pt_2d p2) {
return p1.x*p2.x + p1.y*p2.y + p1.z*p2.z ;
}
double dot_product_2D(pt_2d p1, pt_2d p2) {
return p1.x*p2.x + p1.y*p2.y ;
}
void return_barycentric(pt_2d p, pt_2d a, pt_2d b, pt_2d c, double* u, double* v, double* w) {
// get barycentric coords of p inside ABC triangle
pt_2d v0 = to_pt2d(b.x - a.x, b.y - a.y, b.z - a.z);
pt_2d v1 = to_pt2d(c.x - a.x, c.y - a.y, c.z - a.z);
pt_2d v2 = to_pt2d(p.x - a.x, p.y - a.y, p.z - a.z);
double d00 = dot_product_2D(v0, v0);
double d01 = dot_product_2D(v0, v1);
double d11 = dot_product_2D(v1, v1);
double d20 = dot_product_2D(v2, v0);
double d21 = dot_product_2D(v2, v1);
double denom = d00 * d11 - d01 * d01;
if(v != NULL) {*v = (d11 * d20 - d01 * d21) / denom;}
if(w != NULL) {*w = (d00 * d21 - d01 * d20) / denom;}
if(u != NULL && v != NULL && w != NULL) {*u = 1.0 - *v - *w;}
}
bool point_in_triangle(pt_2d pt, pt_2d v1, pt_2d v2, pt_2d v3, double* thetaA, double* thetaB, double* thetaC) {
double d1, d2, d3;
bool has_neg, has_pos;
d1 = sign_triangle(pt, v1, v2);
d2 = sign_triangle(pt, v2, v3);
d3 = sign_triangle(pt, v3, v1);
has_neg = (d1 < 0) || (d2 < 0) || (d3 < 0);
has_pos = (d1 > 0) || (d2 > 0) || (d3 > 0);
if(!(has_neg && has_pos)) {
return_barycentric(pt, v1, v2, v3, thetaA, thetaB, thetaC);
return true;
}
return false;
}
bool seg_seg_inter(pt_2d* p1, pt_2d* p2, pt_2d* p3, pt_2d* p4, double* ret0, double* ret1) {
double deno = ((*p4).x - (*p3).x)*((*p2).y - (*p1).y) - ((*p4).y - (*p3).y)*((*p2).x - (*p1).x);
if(absf(deno) <= 0.001) {
return false;
}
//printf("%lf\n", deno);
double alpha =
(((*p4).x - (*p3).x)*((*p3).y - (*p1).y) - ((*p4).y - (*p3).y)*((*p3).x - (*p1).x))/
(deno) ;
double beta =
(((*p2).x - (*p1).x)*((*p3).y - (*p1).y) - ((*p2).y - (*p1).y)*((*p3).x - (*p1).x))/
(deno) ;
if(ret0 != NULL) {*ret0 = alpha;}
if(ret1 != NULL) {*ret1 = beta;}
return (alpha >= 0.0 && alpha <= 1.0 && beta >= 0.0 && beta <= 1.0);
}
void get_barycentric(pt_2d p, pt_2d* tri, double* retu, double* retv, double* retw) {
pt_2d a = tri[0] ; pt_2d b = tri[1] ; pt_2d c = tri[2] ;
pt_2d v0 = vect_diff(b, a);
pt_2d v1 = vect_diff(c, a);
pt_2d v2 = vect_diff(p, a);
double d00 = dot2D(v0, v0);
double d01 = dot2D(v0, v1);
double d11 = dot2D(v1, v1);
double d20 = dot2D(v2, v0);
double d21 = dot2D(v2, v1);
double denom = d00 * d11 - d01 * d01;
if(retv != NULL) {
*retv = (d11 * d20 - d01 * d21) / denom;
}
if(retw != NULL) {
*retw = (d00 * d21 - d01 * d20) / denom;
}
if(retu != NULL) {
*retu = 1.0 - *retv - *retw ;
}
}
bool pt_equal(pt_2d p1, pt_2d p2, double epsilon) {
return (absf(p2.x - p1.x) <= epsilon && absf(p2.y - p1.y) <= epsilon && absf(p2.z - p1.z) <= epsilon) ;
}
bool nonzero(double tha, double thb, double thc, double epsilon) {
return (absf(tha) > epsilon && absf(thb) > epsilon && absf(thc) > epsilon);
}
double u = 0.0 ;
double v = 0.0 ;
double w = 0.0 ;
double th1, th2;
double dist ;
bool is_hidden(SDL_Renderer* renderer, pt_2d p, pt_2d ogp, pt_2d* tri, pt_2d* og) {
if(pt_equal(p, tri[0], 0.001) || pt_equal(p, tri[1], 0.001) || pt_equal(p, tri[2], 0.001)) {
return false;
}
get_barycentric(p, tri, &u, &v, &w);
if(((u >= 0.0) && (v >= 0.0) && (w >= 0.0) && (u+v+w <= 1.0)) && nonzero(u, v, w, 0.001)) {
pt_2d mid = convex_pt2d_tri(og[0], u, og[1], v, og[2], w);
dist = proj_pt_distance_to_camera_sq(mid) - proj_pt_distance_to_camera_sq(ogp);
if(absf(dist) >= 0.001) {
//return (proj_pt_distance_to_camera_sq(mid) <= proj_pt_distance_to_camera_sq(ogp));
return (dist <= 0.0);
}
}
return false;
}
bool is_in_front(pt_2d* tri1, pt_2d* og1, pt_2d* tri2, pt_2d* og2) {
for(int k1 = 0; k1 < 3; k1++) {
for(int k2 = 0; k2 < 3; k2++) {
if(seg_seg_inter(&(tri1[k1]), &(tri1[(k1+1)%3]), &(tri2[k2]), &(tri2[(k2+1)%3]), &th1, &th2)) {
pt_2d mid1 = convex_pt2d(tri1[k1], tri1[(k1+1)%3], th1);
pt_2d mid2 = convex_pt2d(tri2[k2], tri2[(k2+1)%3], th2);
dist = proj_pt_distance_to_camera_sq(mid1) - proj_pt_distance_to_camera_sq(mid2);
if(absf(dist) >= 0.001) {
//return (proj_pt_distance_to_camera_sq(mid1) <= proj_pt_distance_to_camera_sq(mid2));
return (dist <= 0.0);
}
}
}
}
return false;
for(int k = 0; k < 3; k++) {
pt_2d p = tri1[k];
if(pt_equal(p, tri2[0], 0.001) || pt_equal(p, tri2[1], 0.001) || pt_equal(p, tri2[2], 0.001)) {
return false;
}
get_barycentric(p, tri2, &u, &v, &w);
pt_2d mid = convex_pt2d_tri(og2[0], u, og2[1], v, og2[2], w);
if(((u >= 0.0) && (v >= 0.0) && (w >= 0.0) && (u+v+w <= 1.0)) && nonzero(u, v, w, 0.001)) {
dist = proj_pt_distance_to_camera_sq(mid) - proj_pt_distance_to_camera_sq(og1[k]);
if(absf(dist) >= 0.001) {
//return !(proj_pt_distance_to_camera_sq(mid) <= proj_pt_distance_to_camera_sq(og1[k]));
return !(dist <= 0.0);
}
}
}
for(int k = 0; k < 3; k++) {
pt_2d p = tri2[k];
if(pt_equal(p, tri1[0], 0.001) || pt_equal(p, tri1[1], 0.001) || pt_equal(p, tri1[2], 0.001)) {
return false;
}
get_barycentric(p, tri1, &u, &v, &w);
pt_2d mid = convex_pt2d_tri(og1[0], u, og1[1], v, og1[2], w);
if(((u >= 0.0) && (v >= 0.0) && (w >= 0.0) && (u+v+w <= 1.0)) && nonzero(u, v, w, 0.001)) {
dist = proj_pt_distance_to_camera_sq(mid) - proj_pt_distance_to_camera_sq(og2[k]);
if(absf(dist) >= 0.001) {
//return !(proj_pt_distance_to_camera_sq(mid) >= proj_pt_distance_to_camera_sq(og2[k]));
return !(dist >= 0.0) ;
}
}
}
return false;
}
bool is_in_front_lite(pt_2d* p, pt_2d* ogp, pt_2d* tri2, pt_2d* og2) {
if(pt_equal(p[0], tri2[0], 0.001) || pt_equal(p[0], tri2[1], 0.001) || pt_equal(p[0], tri2[2], 0.001)) {
return false;
}
get_barycentric(p[0], tri2, &u, &v, &w);
if(((u >= 0.0) && (v >= 0.0) && (w >= 0.0) && (u+v+w <= 1.0)) && nonzero(u, v, w, 0.001)) {
pt_2d mid = convex_pt2d_tri(og2[0], u, og2[1], v, og2[2], w);
dist = proj_pt_distance_to_camera_sq(ogp[0]) - proj_pt_distance_to_camera_sq(mid);
if(absf(dist) >= 0.001) {
//return !(proj_pt_distance_to_camera_sq(mid) >= proj_pt_distance_to_camera_sq(og2[k]));
return (dist <= 0.0) ;
}
}
return false;
}
bool is_in_front_pt_pt(pt_2d* p1, pt_2d* ogp1, pt_2d* p2, pt_2d* ogp2) {
return ((pt_equal(*p1, *p2, 0.001)) && proj_pt_distance_to_camera_sq(*ogp1) - proj_pt_distance_to_camera_sq(*ogp2) <= 0.0);
}

View File

@ -1,22 +0,0 @@
#ifndef TRIANGLES_H
#define TRIANGLES_H
void trInit();
double det2D(pt_2d * p1, pt_2d * p2, pt_2d * p3) ;
void checkTriWinding(pt_2d * p1, pt_2d * p2, pt_2d * p3, bool allowReversed) ;
bool boundaryCollideChk(pt_2d *p1, pt_2d *p2, pt_2d *p3, double eps) ;
bool boundaryDoesntCollideChk(pt_2d *p1, pt_2d *p2, pt_2d *p3, double eps) ;
bool triTri2D(pt_2d* t1, pt_2d* t2, double eps, bool allowReversed, bool onBoundary) ;
bool triangleIntersection(pt_2d* tri1, pt_2d* tri2);
bool triangleIntersectionDec(pt_2d t1_1, pt_2d t1_2, pt_2d t1_3, pt_2d t2_1, pt_2d t2_2, pt_2d t2_3);
bool multipleTrianglesIntersection(pt_2d* tri1, int len1, pt_2d* tri2, int len2, int* ret1, int* ret2);
bool is_in_front(pt_2d* tri1, pt_2d* og1, pt_2d* tri2, pt_2d* og2);
bool is_in_front_lite(pt_2d* tri1, pt_2d* og1, pt_2d* tri2, pt_2d* og2);
bool is_in_front_pt_pt(pt_2d* p1, pt_2d* ogp1, pt_2d* p2, pt_2d* ogp2);
bool is_hidden(SDL_Renderer* renderer, pt_2d p, pt_2d ogp, pt_2d* tri, pt_2d* og);
#endif