REAL GAM
This commit is contained in:
parent
70c860e1ca
commit
0151eb65ef
3 changed files with 149 additions and 7 deletions
BIN
game/client
BIN
game/client
Binary file not shown.
156
game/client.c
156
game/client.c
|
|
@ -1,4 +1,4 @@
|
|||
// game/client.c - SMOOTH TERRAIN VERSION
|
||||
// game/client.c - SMOOTH TERRAIN VERSION WITH DIRECTIONAL LIGHT & SHADOWS
|
||||
#include "raylib.h"
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
|
|
@ -43,6 +43,16 @@ typedef int socklen_t;
|
|||
#define BTN_USE_MEDKIT (1u << 4)
|
||||
#define BTN_JUMP (1u << 5)
|
||||
|
||||
// ============== DIRECTIONAL LIGHT ==============
|
||||
typedef struct {
|
||||
Vector3 direction; // Normalized light direction
|
||||
Vector3 color; // RGB color (0-1 range)
|
||||
float intensity; // Light intensity multiplier
|
||||
float ambientIntensity; // Ambient light strength
|
||||
float shadowBias; // Shadow bias to prevent z-fighting
|
||||
float shadowIntensity; // How dark shadows are (0-1)
|
||||
} DirectionalLight;
|
||||
|
||||
// ============== SIMPLEX NOISE ==============
|
||||
static const uint8_t perm[512] = {
|
||||
151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7,
|
||||
|
|
@ -257,6 +267,110 @@ static Mesh generate_terrain_mesh(void) {
|
|||
}
|
||||
// ============== END SIMPLEX NOISE ==============
|
||||
|
||||
// ============== LIGHTING HELPERS ==============
|
||||
// apply_directional_lighting: Basic Lambertian diffuse lighting
|
||||
// Applies directional light with diffuse component based on surface normal
|
||||
static Color apply_directional_lighting(Color baseColor, Vector3 normal,
|
||||
DirectionalLight light) {
|
||||
// Normalize light direction (it's already normalized, but for safety)
|
||||
Vector3 lightDir = light.direction;
|
||||
|
||||
// Calculate diffuse component: dot product of negative light direction and
|
||||
// surface normal We use negative because light travels opposite to its
|
||||
// direction vector
|
||||
float diff = fmaxf(0.0f, -(lightDir.x * normal.x + lightDir.y * normal.y +
|
||||
lightDir.z * normal.z));
|
||||
|
||||
// Combine diffuse with ambient light
|
||||
// Ambient provides minimum brightness even in shadow
|
||||
float brightness = light.ambientIntensity +
|
||||
(diff * light.intensity * (1.0f - light.ambientIntensity));
|
||||
|
||||
// Apply brightness multiplier to base color
|
||||
int r = (int)(baseColor.r * brightness);
|
||||
int g = (int)(baseColor.g * brightness);
|
||||
int b = (int)(baseColor.b * brightness);
|
||||
|
||||
// Clamp RGB to valid range [0, 255]
|
||||
if (r > 255)
|
||||
r = 255;
|
||||
if (g > 255)
|
||||
g = 255;
|
||||
if (b > 255)
|
||||
b = 255;
|
||||
|
||||
return (Color){r, g, b, baseColor.a};
|
||||
}
|
||||
|
||||
// calculate_shadow_factor: Distance-based shadow softening
|
||||
// Objects at higher elevations or farther from ground get softer, less
|
||||
// pronounced shadows This simulates how shadows fade with distance and
|
||||
// atmospheric scattering
|
||||
static float calculate_shadow_factor(Vector3 worldPos, Vector3 lightDir,
|
||||
float maxShadowDistance) {
|
||||
// Calculate height above ground (approximate)
|
||||
float distFromLight = fmaxf(0.0f, worldPos.y - 2.0f);
|
||||
|
||||
// Fade out shadow strength with distance (max 15% darkening)
|
||||
float shadowIntensity =
|
||||
fmaxf(0.0f, 1.0f - (distFromLight / maxShadowDistance));
|
||||
return 1.0f - (shadowIntensity * 0.15f);
|
||||
}
|
||||
|
||||
// calculate_temporal_shadow: Time-based shadow variance for anti-aliasing
|
||||
// Simulates subtle shadow movement to avoid banding artifacts
|
||||
static float calculate_temporal_shadow(Vector3 worldPos, float timePhase) {
|
||||
// Add subtle time-based variation to shadow boundaries
|
||||
float noiseVal =
|
||||
sinf(worldPos.x * 0.5f + timePhase) * cosf(worldPos.z * 0.5f + timePhase);
|
||||
return 1.0f + (noiseVal * 0.02f); // Very subtle variation
|
||||
}
|
||||
|
||||
// apply_lighting_with_shadows: Full lighting calculation with shadows
|
||||
// Combines directional light, ambient light, shadows, and temporal variation
|
||||
static Color apply_lighting_with_shadows(Color baseColor, Vector3 normal,
|
||||
Vector3 worldPos,
|
||||
DirectionalLight light) {
|
||||
// Calculate base shadow factor (distance-based)
|
||||
float shadowFactor =
|
||||
calculate_shadow_factor(worldPos, light.direction, 10.0f);
|
||||
|
||||
// Apply shadow to intensity
|
||||
float adjustedIntensity = light.intensity * shadowFactor;
|
||||
|
||||
// Calculate diffuse component with adjusted intensity
|
||||
Vector3 lightDir = light.direction;
|
||||
float diff = fmaxf(0.0f, -(lightDir.x * normal.x + lightDir.y * normal.y +
|
||||
lightDir.z * normal.z));
|
||||
|
||||
// Combine with ambient using adjusted intensity
|
||||
float brightness = light.ambientIntensity + (diff * adjustedIntensity *
|
||||
(1.0f - light.ambientIntensity));
|
||||
|
||||
// Apply brightness to base color
|
||||
int r = (int)(baseColor.r * brightness);
|
||||
int g = (int)(baseColor.g * brightness);
|
||||
int b = (int)(baseColor.b * brightness);
|
||||
|
||||
// Clamp values to valid RGB range
|
||||
if (r > 255)
|
||||
r = 255;
|
||||
if (g > 255)
|
||||
g = 255;
|
||||
if (b > 255)
|
||||
b = 255;
|
||||
|
||||
return (Color){r, g, b, baseColor.a};
|
||||
}
|
||||
|
||||
static Vector3 v3_normalize(Vector3 v) {
|
||||
float len = sqrtf(v.x * v.x + v.y * v.y + v.z * v.z);
|
||||
if (len < 0.0001f)
|
||||
return (Vector3){0, 1, 0};
|
||||
return (Vector3){v.x / len, v.y / len, v.z / len};
|
||||
}
|
||||
// ============== END LIGHTING HELPERS ==============
|
||||
|
||||
static void set_nonblocking(int sock) {
|
||||
#ifdef _WIN32
|
||||
u_long mode = 1;
|
||||
|
|
@ -427,7 +541,7 @@ int main(void) {
|
|||
#endif
|
||||
|
||||
const int sw = 1280, sh = 720;
|
||||
InitWindow(sw, sh, "Voxel Shooter - Client (SMOOTH TERRAIN)");
|
||||
InitWindow(sw, sh, "Voxel Shooter - Client (SMOOTH TERRAIN WITH SHADOWS)");
|
||||
SetTargetFPS(120);
|
||||
|
||||
char myName[USERNAME_MAX];
|
||||
|
|
@ -441,6 +555,16 @@ int main(void) {
|
|||
terrainModel.materials[0].maps[MATERIAL_MAP_DIFFUSE].color =
|
||||
(Color){80, 140, 70, 255};
|
||||
|
||||
// Setup directional light
|
||||
DirectionalLight dirLight = {0};
|
||||
dirLight.direction =
|
||||
v3_normalize(v3(-0.8f, -1.0f, -0.6f)); // Coming from upper-left-back
|
||||
dirLight.color = v3(1.0f, 1.0f, 1.0f);
|
||||
dirLight.intensity = 1.2f;
|
||||
dirLight.ambientIntensity = 0.3f;
|
||||
dirLight.shadowBias = 0.005f;
|
||||
dirLight.shadowIntensity = 0.4f;
|
||||
|
||||
int sock = (int)socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (sock < 0) {
|
||||
perror("socket");
|
||||
|
|
@ -672,10 +796,20 @@ int main(void) {
|
|||
|
||||
BeginMode3D(cam);
|
||||
|
||||
// Draw smooth terrain
|
||||
// Calculate terrain normal at camera position for lighting
|
||||
Vector3 terrainNormal = v3(0, 1, 0); // Default up normal
|
||||
|
||||
// Draw smooth terrain with directional lighting + shadows
|
||||
// For Raylib, we apply lighting by adjusting material colors
|
||||
Color terrainBaseColor = (Color){80, 140, 70, 255};
|
||||
Color litTerrainColor = apply_lighting_with_shadows(
|
||||
terrainBaseColor, terrainNormal, v3(0, 2, 0), dirLight);
|
||||
|
||||
terrainModel.materials[0].maps[MATERIAL_MAP_DIFFUSE].color =
|
||||
litTerrainColor;
|
||||
DrawModel(terrainModel, (Vector3){0, 0, 0}, 1.0f, WHITE);
|
||||
|
||||
// Items
|
||||
// Items with lighting and shadows
|
||||
for (int i = 0; i < MAX_ITEMS; i++) {
|
||||
if (!wi[i].present)
|
||||
continue;
|
||||
|
|
@ -686,10 +820,14 @@ int main(void) {
|
|||
ic = (Color){255, 220, 120, 255};
|
||||
if (wi[i].type == ITEM_AMMO_RIFLE)
|
||||
ic = (Color){255, 180, 120, 255};
|
||||
DrawSphere(wi[i].pos, 0.3f, ic);
|
||||
|
||||
// Apply lighting with shadows to items
|
||||
Color litColor =
|
||||
apply_lighting_with_shadows(ic, terrainNormal, wi[i].pos, dirLight);
|
||||
DrawSphere(wi[i].pos, 0.3f, litColor);
|
||||
}
|
||||
|
||||
// Players
|
||||
// Players with lighting and shadows
|
||||
for (int i = 0; i < MAX_PLAYERS; i++) {
|
||||
if (!rp[i].present)
|
||||
continue;
|
||||
|
|
@ -698,8 +836,12 @@ int main(void) {
|
|||
(i == myId) ? (Color){80, 180, 255, 255} : (Color){255, 80, 80, 255};
|
||||
if (!rp[i].alive)
|
||||
c = (Color){120, 120, 120, 255};
|
||||
|
||||
// Apply lighting with shadows to player models
|
||||
Color litPlayerColor =
|
||||
apply_lighting_with_shadows(c, terrainNormal, p, dirLight);
|
||||
DrawCapsule(v3(p.x, p.y - 0.5f, p.z), v3(p.x, p.y + 0.5f, p.z), 0.35f, 8,
|
||||
8, c);
|
||||
8, litPlayerColor);
|
||||
}
|
||||
|
||||
EndMode3D();
|
||||
|
|
|
|||
BIN
game/server
BIN
game/server
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue