added (incomplete) full block display using triangles

This commit is contained in:
Alexandre 2024-12-31 19:07:26 +01:00
parent 1ebbd622b5
commit de5868f24d
11 changed files with 264 additions and 10 deletions

View File

@ -3,6 +3,7 @@
"ncurses.h": "c", "ncurses.h": "c",
"stdio.h": "c", "stdio.h": "c",
"math.h": "c", "math.h": "c",
"sdl_image.h": "c" "sdl_image.h": "c",
"display.h": "c"
} }
} }

BIN
bin/back

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -18,6 +18,12 @@
#include "generation.h" #include "generation.h"
#include "display.h" #include "display.h"
int* drawOrder;
void init_draworder() {
drawOrder = malloc(sizeof(int)*6) ;
}
void updateRenderer(SDL_Renderer* renderer) { void updateRenderer(SDL_Renderer* renderer) {
//printf("E"); //printf("E");
SDL_RenderPresent(renderer); SDL_RenderPresent(renderer);
@ -160,7 +166,7 @@ void drawStringToRenderer(SDL_Renderer* renderer, imgs data, char* s, int X, int
// 3D stuff // 3D stuff
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) {
// align camera to (0, 0, 0) // align pt to (0, 0, 0)
double x = x0 - camx ; double x = x0 - camx ;
double y = y0 - camy ; double y = y0 - camy ;
double z = z0 - camz ; double z = z0 - camz ;
@ -176,6 +182,23 @@ void project_to_camera(double x0, double y0, double z0, double* rx, double* ry,
*rz = zry*cos(rot_vt) + yry*sin(rot_vt) ; *rz = zry*cos(rot_vt) + yry*sin(rot_vt) ;
} }
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) ;
double y = y0 - (cb.y + cb.h/2) ;
double z = z0 - (cb.z + cb.d/2) ;
// 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) + xry ;
*ry = (cb.y + cb.h/2) + yry*cos(cb.vt_angle) - zry*sin(cb.vt_angle) ;
*rz = (cb.z + cb.d/2) + zry*cos(cb.vt_angle) + yry*sin(cb.vt_angle) ;
}
void draw_segment(SDL_Renderer* renderer, double sx, double sy, double sz, double ex, double ey, double ez) { 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 ; double spx ;double spy ;double spz ;double epx ;double epy ;double epz ;
project_to_camera(sx, sy, sz, &spx, &spy, &spz) ; project_to_camera(sx, sy, sz, &spx, &spy, &spz) ;
@ -266,15 +289,15 @@ void drawSegmentRotated(SDL_Renderer* renderer, double sx, double sy, double sz,
double pex = ex; double pex = ex;
double pey = ey; double pey = ey;
double pez = ez; double pez = ez;
axialRotation_Y(&psx, &psz, hz_angle, center_x, center_z); axialRotation_Y(&psx, &psz, -hz_angle, center_x, center_z);
axialRotation_Y(&pex, &pez, 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(&psy, &psz, vt_angle, center_y, center_z);
axialRotation_X(&pey, &pez, 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); draw_segment(renderer, psx, psy, psz, pex, pey, pez);
} }
void drawOutlineOfCube_0(SDL_Renderer* renderer, cube_0 c) { void drawOutlineOfCube_0(SDL_Renderer* renderer, cube_0 c) {
SDL_SetRenderDrawColor(renderer, c.red, c.green, c.blue, 255) ;
// x = constant // 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.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.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) ;
@ -294,12 +317,219 @@ void drawOutlineOfCube_0(SDL_Renderer* renderer, cube_0 c) {
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) ; 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) {
SDL_Vertex vtx ;
vtx.color.r = r ;
vtx.color.g = g ;
vtx.color.b = b ;
vtx.color.a = SDL_ALPHA_OPAQUE;
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 renderTriangle(
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
) {
double px0; double py0; double pz0;
double px1; double py1; double pz1;
double px2; double py2; double pz2;
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(pz0 >= 0.4 && pz1 >= 0.4 && pz2 >= 0.4) {
const SDL_Vertex vtxs[3] = {
construct_vertex(1500.0 * (1.0 + (px0 / (1.5 * pz0 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py0 / (pz0 * tan_fov))) / 2.0, red, green, blue),
construct_vertex(1500.0 * (1.0 + (px1 / (1.5 * pz1 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py1 / (pz1 * tan_fov))) / 2.0, red, green, blue),
construct_vertex(1500.0 * (1.0 + (px2 / (1.5 * pz2 * tan_fov))) / 2.0, 1000.0 * (1.0 + (py2 / (pz2 * tan_fov))) / 2.0, red, green, blue),
};
SDL_RenderGeometry(renderer, NULL, vtxs, 3, NULL, 0);
} // TODO //
}
void renderTriangleRotated(
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,
cube_0 cb
) {
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);
renderTriangle(renderer, px0, py0, pz0, px1, py1, pz1, px2, py2, pz2, red, green, blue);
}
void drawSfOfCube(SDL_Renderer* renderer, int sf, cube_0 c) {
if(sf == 0 || sf == 1) { // x
renderTriangleRotated(renderer,
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
);
renderTriangleRotated(renderer,
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) { // y
renderTriangleRotated(renderer,
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
);
renderTriangleRotated(renderer,
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
renderTriangleRotated(renderer,
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
);
renderTriangleRotated(renderer,
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 drawFullCube(SDL_Renderer* renderer, cube_0 cb) {
int sfToDraw = surfaceDrawOrder(camx, camy, camz, cb);
for(int k = 0; k < sfToDraw; k++) {
drawSfOfCube(renderer, drawOrder[k], cb);
}
}
// -------------------------------------------------------------------------------------------------------------------------------- //
void swap_cb(cube_0* arr, int i, int j) {
cube_0 temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
void swap_tp(teleporter* arr, int i, int j) {
teleporter temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
void insertionSort_cb(cube_0* arr, int len) {
for(int k = 0; k < len; k++) {
int j = k-1 ;
while(j >= 0) {
if(distance_pt_cube_0_3d(camx, camy, camz, arr[j]) < distance_pt_cube_0_3d(camx, camy, camz, arr[j+1])) {
swap_cb(arr, j, j+1);
j -= 1;
} else {
j = -1;
}
}
}
}
void insertionSort_tp(teleporter* arr, int len) {
for(int k = 0; k < len; k++) {
int j = k-1 ;
while(j >= 0) {
if(distance_pt_cube_0_3d(camx, camy, camz, arr[j].hitbox) < distance_pt_cube_0_3d(camx, camy, camz, arr[j+1].hitbox)) {
swap_tp(arr, j, j+1);
j -= 1;
} else {
j = -1;
}
}
}
}
void drawCurrentRoom(SDL_Renderer* renderer) { void drawCurrentRoom(SDL_Renderer* renderer) {
insertionSort_cb(current_room->map, current_room->map_size);
insertionSort_tp(current_room->tps, current_room->tps_size);
for(int k = 0; k < current_room->map_size; k++) { for(int k = 0; k < current_room->map_size; k++) {
SDL_SetRenderDrawColor(renderer, current_room->map[k].red/2, current_room->map[k].green/2, current_room->map[k].blue/2, 255);
drawOutlineOfCube_0(renderer, current_room->map[k]); drawOutlineOfCube_0(renderer, current_room->map[k]);
drawFullCube(renderer, current_room->map[k]);
} }
for(int k = 0; k < current_room->tps_size; k++) { for(int k = 0; k < current_room->tps_size; k++) {
SDL_SetRenderDrawColor(renderer, current_room->tps[k].hitbox.red/2, current_room->tps[k].hitbox.green/2, current_room->tps[k].hitbox.blue/2, 255);
drawOutlineOfCube_0(renderer, current_room->tps[k].hitbox); drawOutlineOfCube_0(renderer, current_room->tps[k].hitbox);
drawFullCube(renderer, current_room->tps[k].hitbox);
} }
} }
@ -310,8 +540,8 @@ void drawData(SDL_Renderer* renderer) {
drawNumberToRenderer(renderer, digits, (int)camy, 10, 60, 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)camz, 10, 110, 75/2, 105/2, 0) ;
drawNumberToRenderer(renderer, digits, (int)(rot_hz*180.0/3.14159), 10, 160, 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, 210, 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_chx, 310, 10, 75/2, 105/2, 0);
drawNumberToRenderer(renderer, digits, player_chy, 310, 60, 75/2, 105/2, 0); drawNumberToRenderer(renderer, digits, player_chy, 310, 60, 75/2, 105/2, 0);

View File

@ -1,6 +1,8 @@
#ifndef DISPLAY_H #ifndef DISPLAY_H
#define DISPLAY_H #define DISPLAY_H
void init_draworder();
void updateRenderer(SDL_Renderer* renderer); void updateRenderer(SDL_Renderer* renderer);
void resetRenderer(SDL_Renderer* renderer); void resetRenderer(SDL_Renderer* renderer);
@ -33,4 +35,22 @@ void drawCurrentRoom(SDL_Renderer* renderer);
void drawData(SDL_Renderer* renderer); void drawData(SDL_Renderer* renderer);
void renderTriangle(
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
);
void renderTriangleRotated(
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,
cube_0 cb
);
void drawSfOfCube(SDL_Renderer* renderer, int sf, cube_0 cb);
void drawFullCube(SDL_Renderer* renderer, cube_0 cb);
#endif #endif

View File

@ -32,7 +32,7 @@ void build_chunk_1(int chx, int chy) {
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);
new->map[1] = create_cube_0(0.0, 0.0, 0.0, 5.0, 1.0, 5.0, 3.14159/4.0, 0.0, 255, 255, 255); new->map[1] = create_cube_0(0.0, 0.0, 0.0, 5.0, 1.0, 5.0, 3.14159/8.0, 0.0, 255, 255, 255);
new->map[2] = create_cube_0(0.0, 1.0, 0.0, 1.0, 5.0, 1.0, 0.0, 0.0, 255, 255, 128); new->map[2] = create_cube_0(0.0, 1.0, 0.0, 1.0, 5.0, 1.0, 0.0, 0.0, 255, 255, 128);
new->map[3] = create_cube_0(4.0, 1.0, 0.0, 1.0, 5.0, 1.0, 0.0, 0.0, 255, 255, 128); new->map[3] = create_cube_0(4.0, 1.0, 0.0, 1.0, 5.0, 1.0, 0.0, 0.0, 255, 255, 128);
new->map[4] = create_cube_0(0.0, 1.0, 4.0, 1.0, 5.0, 1.0, 0.0, 0.0, 255, 255, 128); new->map[4] = create_cube_0(0.0, 1.0, 4.0, 1.0, 5.0, 1.0, 0.0, 0.0, 255, 255, 128);

View File

@ -46,16 +46,17 @@ int main(int argc, char** argv) {
/* -------------------------------------------------------- */ /* -------------------------------------------------------- */
init_csts() ; init_csts() ;
init_hashtbl() ; init_hashtbl() ;
init_draworder() ;
import_digits(rend) ; import_digits(rend) ;
import_letters(rend) ; import_letters(rend) ;
while(true) { while(true) {
resetRenderer(rend) ; resetRenderer(rend) ;
SDL_SetRenderDrawColor(rend, 255, 255, 255, 255) ; SDL_SetRenderDrawColor(rend, 255, 255, 255, SDL_ALPHA_OPAQUE) ;
playerActions() ; playerActions() ;
drawData(rend) ;
generate_nearby_chunks(1); generate_nearby_chunks(1);
drawCurrentRoom(rend); drawCurrentRoom(rend);
drawData(rend) ;
updateRenderer(rend) ; updateRenderer(rend) ;
usleep(1000000/60) ; usleep(1000000/60) ;

View File

@ -81,4 +81,6 @@ extern room* current_room ;
extern int player_chx ; extern int player_chx ;
extern int player_chy ; extern int player_chy ;
extern int* drawOrder ;
#endif #endif