- depth buffer implementat

- localització de sprites en pantalla
This commit is contained in:
2025-09-29 11:54:54 +02:00
parent 5af2bc3fe7
commit 1d1d89044c

View File

@@ -4,7 +4,8 @@
#include "jdebug.h" #include "jdebug.h"
#define M_PI 3.14159265358979323846 #define M_PI 3.14159265358979323846
#define DEG_TO_RAD M_PI/180.0f #define DEG_TO_RAD (M_PI/180.0f)
#define RAD_TO_DEG (180.0f/M_PI)
struct vec2 { float x, y; }; struct vec2 { float x, y; };
struct wall { Uint16 v1, v2; vec2 normal; float u1, u2; int portal; }; struct wall { Uint16 v1, v2; vec2 normal; float u1, u2; int portal; };
@@ -22,6 +23,7 @@ SDL_Texture *sdl_texture;
Uint32 *palette; Uint32 *palette;
Uint8 *gif; Uint8 *gif;
Uint8 screen[320*240]; Uint8 screen[320*240];
float depth_buffer[320*240];
std::vector<sector> sectors; std::vector<sector> sectors;
int current_sector; int current_sector;
@@ -94,6 +96,13 @@ void putp(int x, int y, Uint8 color)
screen[x+y*320]=color; screen[x+y*320]=color;
} }
void putpd(int x, int y, Uint8 color, float depth)
{
if (x<0 || y<0 || x>=320 || y>=240) return;
screen[x+y*320]=color;
depth_buffer[x+y*320]=depth;
}
void line(int x1, int y1, int x2, int y2, Uint8 color) void line(int x1, int y1, int x2, int y2, Uint8 color)
{ {
float dx = float(x2-x1); float dx = float(x2-x1);
@@ -205,7 +214,7 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v
vec2 normal = { SDL_cosf(angle*DEG_TO_RAD), SDL_sinf(angle*DEG_TO_RAD) }; vec2 normal = { SDL_cosf(angle*DEG_TO_RAD), SDL_sinf(angle*DEG_TO_RAD) };
vec2 result, tmp_result; vec2 result, tmp_result;
wall *w = nullptr; wall *w = nullptr;
float dist=100000.0f; float stright_dist=100000.0f;
for (auto &wall : s.walls) for (auto &wall : s.walls)
{ {
@@ -213,8 +222,8 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v
if (get_line_intersection(position, infi, s.verts[wall.v1], s.verts[wall.v2], &tmp_result)) if (get_line_intersection(position, infi, s.verts[wall.v1], s.verts[wall.v2], &tmp_result))
{ {
const float d = distance(position, tmp_result);// * SDL_cosf(a_inc*DEG_TO_RAD); const float d = distance(position, tmp_result);// * SDL_cosf(a_inc*DEG_TO_RAD);
if (d<dist) { if (d<stright_dist) {
dist = d; stright_dist = d;
result = tmp_result; result = tmp_result;
w = &wall; w = &wall;
} }
@@ -226,7 +235,7 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v
const float sector_height = s.ceiling_height - s.floor_height; const float sector_height = s.ceiling_height - s.floor_height;
map::putp(result.x, result.y, 6); map::putp(result.x, result.y, 6);
dist *= SDL_cosf(a_inc*DEG_TO_RAD); float dist = stright_dist * SDL_cosf(a_inc*DEG_TO_RAD);
const vec2 AB = {s.verts[w->v2].x-s.verts[w->v1].x, s.verts[w->v2].y-s.verts[w->v1].y}; const vec2 AB = {s.verts[w->v2].x-s.verts[w->v1].x, s.verts[w->v2].y-s.verts[w->v1].y};
const vec2 AP = {result.x-s.verts[w->v1].x, result.y-s.verts[w->v1].y}; const vec2 AP = {result.x-s.verts[w->v1].x, result.y-s.verts[w->v1].y};
float v = dot(AP,AB) / dot(AB,AB); v *= w->u2; v = (v-int(v))*tex_height; float v = dot(AP,AB) / dot(AB,AB); v *= w->u2; v = (v-int(v))*tex_height;
@@ -249,7 +258,7 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v
float actual_dist = straight_dist / SDL_cosf(a_inc*DEG_TO_RAD); float actual_dist = straight_dist / SDL_cosf(a_inc*DEG_TO_RAD);
int tx = abs(int(actual_dist * SDL_cosf(angle*DEG_TO_RAD) - position.x)) % tex_height; int tx = abs(int(actual_dist * SDL_cosf(angle*DEG_TO_RAD) - position.x)) % tex_height;
int ty = abs(int(actual_dist * SDL_sinf(angle*DEG_TO_RAD) - position.y)) % tex_height; int ty = abs(int(actual_dist * SDL_sinf(angle*DEG_TO_RAD) - position.y)) % tex_height;
putp(screen_column, y, gif[tx+ty*tex_height]); putpd(screen_column, y, gif[tx+ty*tex_height], straight_dist);
} }
@@ -258,7 +267,7 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v
// Pinta la pared // Pinta la pared
for (int i=0; i<wall_height; ++i) { for (int i=0; i<wall_height; ++i) {
if (wall_start+i>=end) break; if (wall_start+i>=end) break;
putp(screen_column, wall_start+i, gif[(int(v)%tex_height)+int(cpix)*tex_height]); putpd(screen_column, wall_start+i, gif[(int(v)%tex_height)+int(cpix)*tex_height], stright_dist);
cpix += dpix; cpix += dpix;
} }
} else { } else {
@@ -272,7 +281,7 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v
// Pinta la pared // Pinta la pared
for (int i=0; i<upper_wall_height; ++i) { for (int i=0; i<upper_wall_height; ++i) {
if (wall_start+i>=end) break; if (wall_start+i>=end) break;
putp(screen_column, wall_start+i, gif[(int(v)%tex_height)+int(cpix)*tex_height]); putpd(screen_column, wall_start+i, gif[(int(v)%tex_height)+int(cpix)*tex_height], stright_dist);
cpix += dpix; cpix += dpix;
} }
wall_start += upper_wall_height; wall_start += upper_wall_height;
@@ -293,7 +302,7 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v
// Pinta la pared // Pinta la pared
for (int i=0; i<lower_wall_height; ++i) { for (int i=0; i<lower_wall_height; ++i) {
if (wall_end+i>=end) break; if (wall_end+i>=end) break;
putp(screen_column, wall_end+i, gif[(int(v)%tex_height)+int(cpix)*tex_height]); putpd(screen_column, wall_end+i, gif[(int(v)%tex_height)+int(cpix)*tex_height], stright_dist);
cpix += dpix; cpix += dpix;
} }
//wall_start += upper_wall_height; //wall_start += upper_wall_height;
@@ -309,7 +318,7 @@ void drawColumn(sector &s, int screen_column, int start, int end, float a_inc, v
float actual_dist = straight_dist / SDL_cosf(a_inc*DEG_TO_RAD); float actual_dist = straight_dist / SDL_cosf(a_inc*DEG_TO_RAD);
int tx = abs(int(actual_dist * SDL_cosf(angle*DEG_TO_RAD) + position.x)) % tex_height; int tx = abs(int(actual_dist * SDL_cosf(angle*DEG_TO_RAD) + position.x)) % tex_height;
int ty = abs(int(actual_dist * SDL_sinf(angle*DEG_TO_RAD) + position.y)) % tex_height; int ty = abs(int(actual_dist * SDL_sinf(angle*DEG_TO_RAD) + position.y)) % tex_height;
putp(screen_column, y, gif[tx+ty*tex_height]); putpd(screen_column, y, gif[tx+ty*tex_height], straight_dist);
} }
//line(screen_column, 120-(wall_height), screen_column, 120+(wall_height), 5); //line(screen_column, 120-(wall_height), screen_column, 120+(wall_height), 5);
} }
@@ -360,6 +369,34 @@ bool tryMove(float angle, float speed)
return moved; return moved;
} }
float is_enemy_in_fov(double Ax, double Ay, double orientation_deg,
double Bx, double By) {
// Convert orientation angle to radians
double orientation_rad = orientation_deg * DEG_TO_RAD;
// Compute view direction vector from angle
double view_dx = SDL_cosf(orientation_rad);
double view_dy = SDL_sinf(orientation_rad);
// Vector from A to B
double to_enemy_dx = Bx - Ax;
double to_enemy_dy = By - Ay;
// Normalize both vectors
double len = SDL_sqrtf(to_enemy_dx * to_enemy_dx + to_enemy_dy * to_enemy_dy);
if (len == 0) return 0.0; // Same position
to_enemy_dx /= len;
to_enemy_dy /= len;
// Compute signed angle using atan2 of perp-dot and dot
double dot = view_dx * to_enemy_dx + view_dy * to_enemy_dy;
double cross = view_dx * to_enemy_dy - view_dy * to_enemy_dx;
float angle_rad = SDL_atan2f(cross, dot);
return angle_rad * RAD_TO_DEG; // Signed angle in degrees
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
SDL_Init(SDL_INIT_VIDEO); SDL_Init(SDL_INIT_VIDEO);
@@ -460,7 +497,7 @@ int main(int argc, char *argv[])
sector &s = sectors[current_sector]; sector &s = sectors[current_sector];
// Clear screen // Clear screen
SDL_memset4(screen, 0x00000000, (320*240)>>2); //SDL_memset4(screen, 0x00000000, (320*240)>>2);
int screen_column = 0; int screen_column = 0;
for (float a_inc=-32.0f; a_inc<=32.0f; a_inc+=0.2f) for (float a_inc=-32.0f; a_inc<=32.0f; a_inc+=0.2f)
@@ -474,6 +511,27 @@ int main(int argc, char *argv[])
screen_column++; screen_column++;
} }
debug::print("angle:");debug::print(orientation);debug::newline();
vec2 enemy = {256.0f, 256.0f};
map::putp(enemy.x, enemy.y, 9);
float angle_to_enemy = is_enemy_in_fov(position.x, position.y, orientation, enemy.x, enemy.y);
if (SDL_fabsf(angle_to_enemy) <= 32.0f)
{
debug::print("enemy in fov: "); debug::print(angle_to_enemy); debug::newline();
int column = int((angle_to_enemy+32.0f)/0.2f);
line(column, 0, column, 239, 0);
}
/*
float angle = SDL_atan2f(enemy.y-position.y, enemy.x-position.x)*RAD_TO_DEG;
if (SDL_abs(angle) <= 32.0f)
{
const float d = distance(position, enemy);// * SDL_cosf(a_inc*DEG_TO_RAD);
debug::print("enemy angle:");debug::print(angle);debug::newline();
debug::print("enemy dist:");debug::print(d);debug::newline();
}
*/
// Draw map walls // Draw map walls
int sec = 0; int sec = 0;