Last active
July 27, 2021 22:05
-
-
Save edubart/92c13dd4d5caa996cd30a9d627205ef6 to your computer and use it in GitHub Desktop.
Blue Planet in C
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Generated by Nelua 0.2.0-dev */ | |
/* Compile command: c2m "/home/bart/projects/nelua/nelua-lang/nelua_cache/demos/planet.c" -o "/home/bart/projects/nelua/nelua-lang/nelua_cache/demos/planet" -w -lSDL2 */ | |
/* Compile hash: 2oufrcKZe8TBnJwdhtW2c9mqSzEe */ | |
/* ------------------------------ DIRECTIVES -------------------------------- */ | |
#include <math.h> | |
#include <stdint.h> | |
#define SDL_MAIN_HANDLED | |
#define SDL_DISABLE_MMINTRIN_H | |
#define SDL_DISABLE_IMMINTRIN_H | |
#define SDL_DISABLE_XMMINTRIN_H | |
#define SDL_DISABLE_EMMINTRIN_H | |
#define SDL_DISABLE_PMMINTRIN_H | |
#include <SDL2/SDL.h> | |
#include <stdbool.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <stddef.h> | |
#include <string.h> | |
#ifdef __GNUC__ | |
#define nelua_inline __attribute__((always_inline)) inline | |
#elif __STDC_VERSION__ >= 199901L | |
#define nelua_inline inline | |
#else | |
#define nelua_inline | |
#endif | |
/* ------------------------------ DECLARATIONS ------------------------------ */ | |
static nelua_inline float nelua_math_abs_1(float x); | |
static nelua_inline float nelua_math_floor_1(float x); | |
static nelua_inline float nelua_math_sqrt_1(float x); | |
static nelua_inline float nelua_math_exp_1(float x); | |
static nelua_inline float nelua_math_pow_1(float x, float y); | |
static nelua_inline float nelua_math_tan_1(float x); | |
static nelua_inline float nelua_math_fract_1(float x); | |
static nelua_inline float nelua_math_min_1(float __arg1, float __arg2); | |
static nelua_inline float nelua_math_max_1(float __arg1, float __arg2); | |
static nelua_inline float mathx_step_1(float edge, float x); | |
static nelua_inline uint32_t mathx_floatbits2uint(float x); | |
typedef union union_float_uint32 union_float_uint32; | |
union union_float_uint32 { | |
float f; | |
uint32_t i; | |
}; | |
static nelua_inline float mathx_fastsin(float x); | |
typedef struct vec4 vec4; | |
struct vec4 { | |
float x; | |
float y; | |
float z; | |
float w; | |
}; | |
static nelua_inline vec4 vec_add_1(vec4 a, vec4 b); | |
typedef struct vec2 vec2; | |
struct vec2 { | |
float x; | |
float y; | |
}; | |
static nelua_inline vec2 vec_add_2(vec2 a, vec2 b); | |
typedef struct vec3 vec3; | |
struct vec3 { | |
float x; | |
float y; | |
float z; | |
}; | |
static nelua_inline vec3 vec_add_3(float a, vec3 b); | |
static nelua_inline vec3 vec_add_4(vec3 a, float b); | |
static nelua_inline vec3 vec_add_5(vec3 a, vec3 b); | |
static nelua_inline vec2 vec_sub_1(vec2 a, vec2 b); | |
static nelua_inline vec3 vec_sub_3(vec3 a, vec3 b); | |
typedef struct vec_ivec2 vec_ivec2; | |
struct vec_ivec2 { | |
int32_t x; | |
int32_t y; | |
}; | |
static nelua_inline vec2 vec_sub_5(float a, vec_ivec2 b); | |
static nelua_inline vec3 vec_sub_7(float a, vec3 b); | |
static nelua_inline vec3 vec_sub_8(vec3 a, float b); | |
static nelua_inline vec2 vec_mul_3(vec2 a, float b); | |
static nelua_inline vec2 vec_mul_4(vec2 a, vec2 b); | |
static nelua_inline vec3 vec_mul_6(vec3 a, vec3 b); | |
static nelua_inline vec3 vec_mul_7(float a, vec3 b); | |
static nelua_inline vec3 vec_mul_8(vec3 a, float b); | |
static nelua_inline vec4 vec_mul_9(float a, vec4 b); | |
typedef struct bvec4 bvec4; | |
struct bvec4 { | |
uint8_t x; | |
uint8_t y; | |
uint8_t z; | |
uint8_t w; | |
}; | |
static nelua_inline vec4 vec_mul_10(float a, bvec4 b); | |
static nelua_inline vec2 vec_mul_11(float a, vec_ivec2 b); | |
typedef struct uvec2 uvec2; | |
struct uvec2 { | |
uint32_t x; | |
uint32_t y; | |
}; | |
static nelua_inline uvec2 vec_mul_13(uint32_t a, uvec2 b); | |
typedef struct uvec3 uvec3; | |
struct uvec3 { | |
uint32_t x; | |
uint32_t y; | |
uint32_t z; | |
}; | |
static nelua_inline uvec3 vec_mul_14(uint32_t a, uvec3 b); | |
static nelua_inline vec2 vec_div_3(vec_ivec2 a, vec2 b); | |
static nelua_inline vec3 vec_div_4(vec3 a, vec3 b); | |
static nelua_inline vec3 vec_div_5(vec3 a, float b); | |
static nelua_inline uvec2 vec_shr_1(uvec2 a, uint32_t b); | |
static nelua_inline uvec3 vec_shr_2(uvec3 a, uint32_t b); | |
static nelua_inline uvec2 vec_bxor_1(uvec2 a, uvec2 b); | |
static nelua_inline uvec3 vec_bxor_2(uvec3 a, uvec3 b); | |
static nelua_inline vec3 vec_pow_1(vec3 a, vec3 b); | |
static nelua_inline float vec_length_1(vec2 a); | |
static nelua_inline float vec_length_2(vec3 a); | |
static nelua_inline float vec_dot_2(vec3 a, vec3 b); | |
static nelua_inline float vec_max_1(float a, float b); | |
static nelua_inline vec2 vec_max_2(vec2 a, float b); | |
static nelua_inline vec3 vec_max_4(vec3 a, float b); | |
static nelua_inline float vec_min_1(float a, float b); | |
static nelua_inline vec3 vec_min_3(vec3 a, float b); | |
static nelua_inline float vec_step_1(float a, float b); | |
static nelua_inline float vec_exp_1(float a); | |
static nelua_inline vec2 vec_fastsin_1(vec2 a); | |
static nelua_inline vec3 vec_fastsin_2(vec3 a); | |
static nelua_inline float vec_sqrt_1(float a); | |
static nelua_inline vec3 vec_sqrt_2(vec3 a); | |
static nelua_inline float vec_tan_1(float a); | |
static nelua_inline vec3 vec_floor_2(vec3 a); | |
static nelua_inline vec2 vec_abs_2(vec2 a); | |
static nelua_inline vec3 vec_fract_2(vec3 a); | |
static nelua_inline vec2 vec_tovec2_1(vec_ivec2 a); | |
static nelua_inline vec3 vec_tovec3_1(float a); | |
static nelua_inline bvec4 vec_tobvec4_1(vec4 a); | |
static nelua_inline bvec4 vec_topixel_1(vec3 a); | |
static nelua_inline uvec3 vec_uvec3_yzx(uvec3 self); | |
static nelua_inline uvec2 vec_uvec2_yx(uvec2 self); | |
static nelua_inline vec3 vec_normalize_2(vec3 a); | |
static nelua_inline vec3 vec_mix_1(vec3 a, vec3 b, float t); | |
static nelua_inline float vec_clamp_1(float a, float minv, float maxv); | |
static nelua_inline vec3 vec_clamp_2(vec3 a, float minv, float maxv); | |
static nelua_inline vec3 vec_cross(vec3 a, vec3 b); | |
static nelua_inline float vec_fastmix_1(float a, float b, float t); | |
static nelua_inline float vec_linearstep_1(float a, float b, float x); | |
static nelua_inline vec2 vec_fastsincos(float x); | |
static nelua_inline float vec_pow2_1(float a); | |
static nelua_inline uvec2 vec_floatbits2uint_2(vec2 a); | |
static nelua_inline uvec3 vec_floatbits2uint_3(vec3 a); | |
typedef SDL_Window* SDL_Window_ptr; | |
static SDL_Window_ptr application_window; | |
typedef SDL_Renderer* SDL_Renderer_ptr; | |
static SDL_Renderer_ptr application_renderer; | |
typedef SDL_Texture* SDL_Texture_ptr; | |
static SDL_Texture_ptr application_texture; | |
static int32_t application_texture_width; | |
static int32_t application_texture_height; | |
static bool application_quit; | |
static int32_t application_fps; | |
static int32_t application_target_fps; | |
static float application_last_fps; | |
static float application_last_fps_time; | |
typedef void (*function_callback)(); | |
static function_callback application_frame_cb; | |
static function_callback application_shutdown_cb; | |
static uint64_t application_first_perf_count; | |
static float application_freq; | |
static float application_next_frame_time; | |
static float application_frame_time; | |
static vec_ivec2 application_mouse_pos; | |
static vec_ivec2 application_window_size; | |
typedef struct ApplicationDesc ApplicationDesc; | |
struct ApplicationDesc { | |
char* window_title; | |
int width; | |
int height; | |
int target_fps; | |
function_callback setup_cb; | |
function_callback shutdown_cb; | |
function_callback frame_cb; | |
}; | |
static void application_setup(ApplicationDesc app_desc); | |
static void nelua_abort(); | |
typedef struct nlstring nlstring; | |
typedef uint8_t* nluint8_arr0_ptr; | |
struct nlstring { | |
nluint8_arr0_ptr data; | |
uintptr_t size; | |
}; | |
static void nelua_panic_string(nlstring s); | |
static void application_shutdown(); | |
static void application_poll(); | |
static float application_time(); | |
static void application_process_frame(); | |
static void nelua_print_1(nlstring a1, float a2); | |
static void application_recreate_texture(int32_t width, int32_t height); | |
typedef struct Canvas Canvas; | |
typedef Canvas* Canvas_ptr; | |
typedef struct {bvec4 v[128];} bvec4_arr128; | |
typedef struct mat3 mat3; | |
typedef struct {float v[3];} nlfloat32_arr3; | |
struct mat3 { | |
nlfloat32_arr3 m[3]; | |
}; | |
struct Canvas { | |
bvec4_arr128 pixels[128]; | |
mat3 proj; | |
mat3 iproj; | |
mat3 mt; | |
mat3 imt; | |
mat3 m; | |
mat3 im; | |
mat3 mts[8]; | |
mat3 imts[8]; | |
float ss[8]; | |
int32_t tstack; | |
float s; | |
float lw; | |
bool dirty; | |
}; | |
static void application_present_1(Canvas_ptr canvas); | |
typedef bvec4* bvec4_ptr; | |
typedef struct {bvec4_arr128 v[128];} bvec4_arr128_arr128; | |
typedef SDL_Rect* SDL_Rect_ptr; | |
static void application_frame(); | |
static void application_run(ApplicationDesc app_desc); | |
static nelua_inline vec2 mat3___mul_2(mat3 a, vec_ivec2 b); | |
static nelua_inline bvec4 sdfutils_blendalpha_1(vec4 src, bvec4 dst, float sa); | |
static nelua_inline vec2 sdfutils_rd2ncru_1(vec_ivec2 coord, vec_ivec2 size); | |
static nelua_inline vec3 sdfutils_rpow22_1(vec3 x); | |
static nelua_inline float sdf2_sdf2_circle(vec2 p, float r); | |
static nelua_inline float sdf2_sdf2_box(vec2 p, vec2 r); | |
static nelua_inline void Canvas_fragment_draw_2(Canvas_ptr self, float __arg1); | |
typedef bvec4_arr128* bvec4_arr128_ptr; | |
static nelua_inline uint32_t noise_basehash_2(uvec2 v); | |
static nelua_inline uint32_t noise_basehash_3(uvec3 v); | |
static nelua_inline float noise_hash1_2(vec2 v); | |
static nelua_inline float noise_hash1_3(vec3 v); | |
static nelua_inline float noise_noisemix3(float a1, float b1, float c1, float d1, float a2, float b2, float c2, float d2, vec3 f); | |
static nelua_inline float noise_white_1(vec2 p); | |
static nelua_inline float noise_value_1(vec3 p); | |
static float planet_sphere_intersect(vec3 ro, vec3 rd, vec3 p, float r); | |
static float planet_fbm3(vec3 p); | |
static vec3 planet_palette(float x); | |
static vec3 planet_color(vec3 p, float t); | |
static vec3 planet_shade(vec3 rd, vec3 p, float time); | |
static vec3 planet_perspective_camera(vec3 lookfrom, vec3 lookat, float tilt, float vfov, vec2 uv); | |
static float planet_expstep(float x, float k); | |
static vec3 planet_get_background(vec3 rd); | |
static vec3 planet_color_tonemap_aces(vec3 col); | |
static vec3 planet_color_saturate(vec3 col, float sat); | |
static vec3 planet_color_tone_1(vec3 col, float gain, float lift, float invgamma); | |
static vec3 planet_color_gamma_correction(vec3 col); | |
static vec3 planet_vignette(vec3 col, vec2 coord, float strength, float amount); | |
static vec3 planet_dither(vec3 col, vec2 coord, float amount); | |
static vec3 planet_sun_glare(vec3 rd); | |
static void planet_main_image(bvec4_ptr frag_col, vec_ivec2 frag_coord, vec_ivec2 frag_size, float time); | |
static Canvas planet_canvas; | |
static void planet_frame(); | |
static int nelua_main(int nelua_argc, char** nelua_argv); | |
/* ------------------------------ DEFINITIONS ------------------------------- */ | |
float nelua_math_abs_1(float x) { | |
x = ((x < 0) ? (-x) : x); | |
return x; | |
} | |
float nelua_math_floor_1(float x) { | |
return floorf(x); | |
} | |
float nelua_math_sqrt_1(float x) { | |
return sqrtf(x); | |
} | |
float nelua_math_exp_1(float x) { | |
return expf(x); | |
} | |
float nelua_math_pow_1(float x, float y) { | |
return powf(x, y); | |
} | |
float nelua_math_tan_1(float x) { | |
return tanf(x); | |
} | |
float nelua_math_fract_1(float x) { | |
return (x - nelua_math_floor_1(x)); | |
} | |
float nelua_math_min_1(float __arg1, float __arg2) { | |
return ((__arg1 < __arg2) ? __arg1 : __arg2); | |
} | |
float nelua_math_max_1(float __arg1, float __arg2) { | |
return ((__arg2 < __arg1) ? __arg1 : __arg2); | |
} | |
float mathx_step_1(float edge, float x) { | |
x = (float)((x < edge) ? 0 : 1); | |
return x; | |
} | |
uint32_t mathx_floatbits2uint(float x) { | |
union_float_uint32 u = (union_float_uint32){.f = x}; | |
return u.i; | |
} | |
float mathx_fastsin(float x) { | |
float line = (x * 0.318309886f); | |
float stair = nelua_math_floor_1(line); | |
float saw = (line - stair); | |
float wave = (saw * ((saw * ((saw * ((saw * 3.43362939f) + -6.86725877f)) + 0.292036732f)) + 3.14159265f)); | |
float signal = (1.0f - (2.0f * (stair - (2.0f * nelua_math_floor_1((0.5f * line)))))); | |
return (signal * wave); | |
} | |
vec4 vec_add_1(vec4 a, vec4 b) { | |
return (vec4){(a.x + b.x), (a.y + b.y), (a.z + b.z), (a.w + b.w)}; | |
} | |
vec2 vec_add_2(vec2 a, vec2 b) { | |
return (vec2){(a.x + b.x), (a.y + b.y)}; | |
} | |
vec3 vec_add_3(float a, vec3 b) { | |
return (vec3){(a + b.x), (a + b.y), (a + b.z)}; | |
} | |
vec3 vec_add_4(vec3 a, float b) { | |
return (vec3){(a.x + b), (a.y + b), (a.z + b)}; | |
} | |
vec3 vec_add_5(vec3 a, vec3 b) { | |
return (vec3){(a.x + b.x), (a.y + b.y), (a.z + b.z)}; | |
} | |
vec2 vec_sub_1(vec2 a, vec2 b) { | |
return (vec2){(a.x - b.x), (a.y - b.y)}; | |
} | |
vec3 vec_sub_3(vec3 a, vec3 b) { | |
return (vec3){(a.x - b.x), (a.y - b.y), (a.z - b.z)}; | |
} | |
vec2 vec_sub_5(float a, vec_ivec2 b) { | |
return (vec2){(a - b.x), (a - b.y)}; | |
} | |
vec3 vec_sub_7(float a, vec3 b) { | |
return (vec3){(a - b.x), (a - b.y), (a - b.z)}; | |
} | |
vec3 vec_sub_8(vec3 a, float b) { | |
return (vec3){(a.x - b), (a.y - b), (a.z - b)}; | |
} | |
vec2 vec_mul_3(vec2 a, float b) { | |
return (vec2){(a.x * b), (a.y * b)}; | |
} | |
vec2 vec_mul_4(vec2 a, vec2 b) { | |
return (vec2){(a.x * b.x), (a.y * b.y)}; | |
} | |
vec3 vec_mul_6(vec3 a, vec3 b) { | |
return (vec3){(a.x * b.x), (a.y * b.y), (a.z * b.z)}; | |
} | |
vec3 vec_mul_7(float a, vec3 b) { | |
return (vec3){(a * b.x), (a * b.y), (a * b.z)}; | |
} | |
vec3 vec_mul_8(vec3 a, float b) { | |
return (vec3){(a.x * b), (a.y * b), (a.z * b)}; | |
} | |
vec4 vec_mul_9(float a, vec4 b) { | |
return (vec4){(a * b.x), (a * b.y), (a * b.z), (a * b.w)}; | |
} | |
vec4 vec_mul_10(float a, bvec4 b) { | |
return (vec4){(a * b.x), (a * b.y), (a * b.z), (a * b.w)}; | |
} | |
vec2 vec_mul_11(float a, vec_ivec2 b) { | |
return (vec2){(a * b.x), (a * b.y)}; | |
} | |
uvec2 vec_mul_13(uint32_t a, uvec2 b) { | |
return (uvec2){(a * b.x), (a * b.y)}; | |
} | |
uvec3 vec_mul_14(uint32_t a, uvec3 b) { | |
return (uvec3){(a * b.x), (a * b.y), (a * b.z)}; | |
} | |
vec2 vec_div_3(vec_ivec2 a, vec2 b) { | |
return (vec2){(a.x / b.x), (a.y / b.y)}; | |
} | |
vec3 vec_div_4(vec3 a, vec3 b) { | |
return (vec3){(a.x / b.x), (a.y / b.y), (a.z / b.z)}; | |
} | |
vec3 vec_div_5(vec3 a, float b) { | |
float k = (1.0f / b); | |
return (vec3){(a.x * k), (a.y * k), (a.z * k)}; | |
} | |
uvec2 vec_shr_1(uvec2 a, uint32_t b) { | |
return (uvec2){a.x >> b, a.y >> b}; | |
} | |
uvec3 vec_shr_2(uvec3 a, uint32_t b) { | |
return (uvec3){a.x >> b, a.y >> b, a.z >> b}; | |
} | |
uvec2 vec_bxor_1(uvec2 a, uvec2 b) { | |
return (uvec2){(a.x ^ b.x), (a.y ^ b.y)}; | |
} | |
uvec3 vec_bxor_2(uvec3 a, uvec3 b) { | |
return (uvec3){(a.x ^ b.x), (a.y ^ b.y), (a.z ^ b.z)}; | |
} | |
vec3 vec_pow_1(vec3 a, vec3 b) { | |
return (vec3){nelua_math_pow_1(a.x, b.x), nelua_math_pow_1(a.y, b.y), nelua_math_pow_1(a.z, b.z)}; | |
} | |
float vec_length_1(vec2 a) { | |
return nelua_math_sqrt_1(((a.x * a.x) + (a.y * a.y))); | |
} | |
float vec_length_2(vec3 a) { | |
return nelua_math_sqrt_1((((a.x * a.x) + (a.y * a.y)) + (a.z * a.z))); | |
} | |
float vec_dot_2(vec3 a, vec3 b) { | |
return (((a.x * b.x) + (a.y * b.y)) + (a.z * b.z)); | |
} | |
float vec_max_1(float a, float b) { | |
return nelua_math_max_1(a, b); | |
} | |
vec2 vec_max_2(vec2 a, float b) { | |
return (vec2){nelua_math_max_1(a.x, b), nelua_math_max_1(a.y, b)}; | |
} | |
vec3 vec_max_4(vec3 a, float b) { | |
return (vec3){nelua_math_max_1(a.x, b), nelua_math_max_1(a.y, b), nelua_math_max_1(a.z, b)}; | |
} | |
float vec_min_1(float a, float b) { | |
return nelua_math_min_1(a, b); | |
} | |
vec3 vec_min_3(vec3 a, float b) { | |
return (vec3){nelua_math_min_1(a.x, b), nelua_math_min_1(a.y, b), nelua_math_min_1(a.z, b)}; | |
} | |
float vec_step_1(float a, float b) { | |
return mathx_step_1(a, b); | |
} | |
float vec_exp_1(float a) { | |
return nelua_math_exp_1(a); | |
} | |
vec2 vec_fastsin_1(vec2 a) { | |
return (vec2){mathx_fastsin(a.x), mathx_fastsin(a.y)}; | |
} | |
vec3 vec_fastsin_2(vec3 a) { | |
return (vec3){mathx_fastsin(a.x), mathx_fastsin(a.y), mathx_fastsin(a.z)}; | |
} | |
float vec_sqrt_1(float a) { | |
return nelua_math_sqrt_1(a); | |
} | |
vec3 vec_sqrt_2(vec3 a) { | |
return (vec3){nelua_math_sqrt_1(a.x), nelua_math_sqrt_1(a.y), nelua_math_sqrt_1(a.z)}; | |
} | |
float vec_tan_1(float a) { | |
return nelua_math_tan_1(a); | |
} | |
vec3 vec_floor_2(vec3 a) { | |
return (vec3){nelua_math_floor_1(a.x), nelua_math_floor_1(a.y), nelua_math_floor_1(a.z)}; | |
} | |
vec2 vec_abs_2(vec2 a) { | |
return (vec2){nelua_math_abs_1(a.x), nelua_math_abs_1(a.y)}; | |
} | |
vec3 vec_fract_2(vec3 a) { | |
return (vec3){nelua_math_fract_1(a.x), nelua_math_fract_1(a.y), nelua_math_fract_1(a.z)}; | |
} | |
vec2 vec_tovec2_1(vec_ivec2 a) { | |
return (vec2){(float)a.x, (float)a.y}; | |
} | |
vec3 vec_tovec3_1(float a) { | |
return (vec3){a, a, a}; | |
} | |
bvec4 vec_tobvec4_1(vec4 a) { | |
return (bvec4){(uint8_t)a.x, (uint8_t)a.y, (uint8_t)a.z, (uint8_t)a.w}; | |
} | |
bvec4 vec_topixel_1(vec3 a) { | |
a = vec_mul_8(a, 255.0f); | |
return (bvec4){.x = (uint8_t)a.x, .y = (uint8_t)a.y, .z = (uint8_t)a.z, .w = 255U}; | |
} | |
uvec3 vec_uvec3_yzx(uvec3 self) { | |
return (uvec3){self.y, self.z, self.x}; | |
} | |
uvec2 vec_uvec2_yx(uvec2 self) { | |
return (uvec2){self.y, self.x}; | |
} | |
vec3 vec_normalize_2(vec3 a) { | |
return vec_div_5(a, vec_length_2(a)); | |
} | |
vec3 vec_mix_1(vec3 a, vec3 b, float t) { | |
return vec_add_5(vec_mul_8(a, (1.0f - t)), vec_mul_8(b, t)); | |
} | |
float vec_clamp_1(float a, float minv, float maxv) { | |
return vec_min_1(vec_max_1(a, minv), maxv); | |
} | |
vec3 vec_clamp_2(vec3 a, float minv, float maxv) { | |
return vec_min_3(vec_max_4(a, minv), maxv); | |
} | |
vec3 vec_cross(vec3 a, vec3 b) { | |
return (vec3){((a.y * b.z) - (a.z * b.y)), ((a.z * b.x) - (a.x * b.z)), ((a.x * b.y) - (a.y * b.x))}; | |
} | |
float vec_fastmix_1(float a, float b, float t) { | |
return (a + ((b - a) * t)); | |
} | |
float vec_linearstep_1(float a, float b, float x) { | |
return vec_clamp_1(((x - a) / (b - a)), 0.0f, 1.0f); | |
} | |
vec2 vec_fastsincos(float x) { | |
return vec_fastsin_1((vec2){x, (x + 1.57079633f)}); | |
} | |
float vec_pow2_1(float a) { | |
return (a * a); | |
} | |
uvec2 vec_floatbits2uint_2(vec2 a) { | |
return (uvec2){mathx_floatbits2uint(a.x), mathx_floatbits2uint(a.y)}; | |
} | |
uvec3 vec_floatbits2uint_3(vec3 a) { | |
return (uvec3){mathx_floatbits2uint(a.x), mathx_floatbits2uint(a.y), mathx_floatbits2uint(a.z)}; | |
} | |
void nelua_abort(){ | |
fflush(stderr); | |
abort(); | |
} | |
void nelua_panic_string(nlstring s){ | |
if(s.size > 0) { | |
fwrite(s.data, 1, s.size, stderr); | |
fputc('\n', stderr); | |
} | |
nelua_abort(); | |
} | |
void application_setup(ApplicationDesc app_desc) { | |
if((SDL_Init(32U) != 0)) { | |
nelua_panic_string(((nlstring){(uint8_t*)"Could not initialize SDL", 24})); | |
} | |
if((!(app_desc.frame_cb != NULL))) { | |
nelua_panic_string(((nlstring){(uint8_t*)"Frame callback is null", 22})); | |
} | |
char* title = app_desc.window_title; | |
if((!(title != NULL))) { | |
title = "Application"; | |
} | |
application_window = SDL_CreateWindow(title, (int)SDL_WINDOWPOS_UNDEFINED, (int)SDL_WINDOWPOS_UNDEFINED, app_desc.width, app_desc.height, 0U); | |
if((!(application_window != NULL))) { | |
nelua_panic_string(((nlstring){(uint8_t*)"Could not create SDL Window", 27})); | |
} | |
application_renderer = SDL_CreateRenderer(application_window, -1, 0U); | |
if((!(application_renderer != NULL))) { | |
nelua_panic_string(((nlstring){(uint8_t*)"Could not create SDL Renderer", 29})); | |
} | |
int w = 0; | |
int h = 0; | |
SDL_GetWindowSize(application_window, (&w), (&h)); | |
application_window_size = (vec_ivec2){(int32_t)w, (int32_t)h}; | |
application_first_perf_count = SDL_GetPerformanceCounter(); | |
application_freq = (float)SDL_GetPerformanceFrequency(); | |
application_target_fps = (int32_t)app_desc.target_fps; | |
application_frame_cb = app_desc.frame_cb; | |
application_shutdown_cb = app_desc.shutdown_cb; | |
if((app_desc.setup_cb != NULL)) { | |
app_desc.setup_cb(); | |
} | |
} | |
void application_shutdown() { | |
if((application_shutdown_cb != NULL)) { | |
application_shutdown_cb(); | |
} | |
if((application_texture != NULL)) { | |
SDL_DestroyTexture(application_texture); | |
} | |
SDL_DestroyRenderer(application_renderer); | |
SDL_DestroyWindow(application_window); | |
SDL_Quit(); | |
} | |
void application_poll() { | |
SDL_Event event = {0}; | |
while((SDL_PollEvent((&event)) == 1)) { | |
switch(event.type) { | |
case 256: { | |
application_quit = true; | |
break; | |
} | |
case 1024: { | |
application_mouse_pos.x = event.motion.x; | |
application_mouse_pos.y = event.motion.y; | |
break; | |
} | |
case 512: { | |
switch(event.window.event) { | |
case 6: { | |
application_window_size = (vec_ivec2){event.window.data1, event.window.data2}; | |
break; | |
} | |
} | |
break; | |
} | |
} | |
} | |
} | |
float application_time() { | |
return ((SDL_GetPerformanceCounter() - application_first_perf_count) / application_freq); | |
} | |
void nelua_print_1(nlstring a1, float a2) { | |
char buff[48]; | |
buff[sizeof(buff)-1] = 0; | |
int len; | |
if(a1.size > 0) { | |
fwrite(a1.data, 1, a1.size, stdout); | |
} | |
fputc('\t', stdout); | |
len = snprintf(buff, sizeof(buff)-1, "%.7g", a2); | |
if(buff[strspn(buff, "-0123456789")] == 0) { | |
len = snprintf(buff, sizeof(buff)-1, "%.1f", a2); | |
} | |
fwrite(buff, 1, len, stdout); | |
fputc('\n', stdout); | |
fflush(stdout); | |
} | |
void application_process_frame() { | |
float now = application_time(); | |
if((application_target_fps != 0)) { | |
if((application_next_frame_time > now)) { | |
int ms = (int)(((application_next_frame_time - now) * 1000) + 0.5f); | |
SDL_Delay((uint32_t)ms); | |
application_next_frame_time = (application_next_frame_time + (1.0f / application_target_fps)); | |
now = application_time(); | |
} else { | |
application_next_frame_time = (now + (1.0f / application_target_fps)); | |
} | |
} | |
application_fps = (application_fps + 1); | |
float time_delta = (now - application_last_fps_time); | |
if((time_delta >= 1.0f)) { | |
application_last_fps = (application_fps / time_delta); | |
nelua_print_1(((nlstring){(uint8_t*)"FPS", 3}), application_last_fps); | |
application_fps = 0; | |
application_last_fps_time = now; | |
} | |
} | |
void application_recreate_texture(int32_t width, int32_t height) { | |
if((application_texture != NULL)) { | |
SDL_DestroyTexture(application_texture); | |
application_texture = ((SDL_Texture_ptr)NULL); | |
} | |
application_texture = SDL_CreateTexture(application_renderer, 374740996U, 1, (int)width, (int)height); | |
if((!(application_texture != NULL))) { | |
nelua_panic_string(((nlstring){(uint8_t*)"Could not create SDL Texture", 28})); | |
} | |
} | |
void application_present_1(Canvas_ptr canvas) { | |
bvec4_ptr pixels = NULL; | |
pixels = (&(*(bvec4_arr128_arr128*)canvas->pixels).v[0].v[0]); | |
if(((128 != application_texture_width) || (128 != application_texture_height))) { | |
application_recreate_texture(128, 128); | |
} | |
SDL_UpdateTexture(application_texture, ((SDL_Rect_ptr)NULL), (void*)pixels, 512); | |
SDL_RenderCopy(application_renderer, application_texture, ((SDL_Rect_ptr)NULL), ((SDL_Rect_ptr)NULL)); | |
SDL_RenderPresent(application_renderer); | |
} | |
void application_frame() { | |
application_frame_time = application_time(); | |
application_poll(); | |
application_frame_cb(); | |
application_process_frame(); | |
} | |
void application_run(ApplicationDesc app_desc) { | |
application_setup(app_desc); | |
while((!application_quit)) { | |
application_frame(); | |
} | |
application_shutdown(); | |
} | |
vec2 mat3___mul_2(mat3 a, vec_ivec2 b) { | |
return (vec2){(((a.m[0].v[0] * b.x) + (a.m[0].v[1] * b.y)) + a.m[0].v[2]), (((a.m[1].v[0] * b.x) + (a.m[1].v[1] * b.y)) + a.m[1].v[2])}; | |
} | |
bvec4 sdfutils_blendalpha_1(vec4 src, bvec4 dst, float sa) { | |
vec4 col = vec_add_1(vec_mul_9(sa, src), vec_mul_10((1.0f - sa), dst)); | |
return vec_tobvec4_1(col); | |
} | |
vec2 sdfutils_rd2ncru_1(vec_ivec2 coord, vec_ivec2 size) { | |
float ry = (1.0f / size.y); | |
return vec_mul_4(vec_add_2(vec_sub_5(1.0f, size), vec_mul_11(2.0f, coord)), (vec2){ry, (-ry)}); | |
} | |
vec3 sdfutils_rpow22_1(vec3 x) { | |
return vec_sub_3(vec_mul_7(1.12661f, vec_sqrt_2(x)), vec_mul_7(0.126615f, x)); | |
} | |
float sdf2_sdf2_circle(vec2 p, float r) { | |
return (vec_length_1(p) - r); | |
} | |
float sdf2_sdf2_box(vec2 p, vec2 r) { | |
vec2 q = vec_sub_1(vec_abs_2(p), r); | |
return (vec_length_1(vec_max_2(q, 0.0f)) + vec_min_1(vec_max_1(q.x, q.y), 0.0f)); | |
} | |
void Canvas_fragment_draw_2(Canvas_ptr self, float __arg1) { | |
for(int32_t py = 0; py < 128; py = py + 1) { | |
bvec4_arr128_ptr row = (&(*(bvec4_arr128_arr128*)self->pixels).v[py]); | |
for(int32_t px = 0; px < 128; px = px + 1) { | |
planet_main_image((&row->v[px]), (vec_ivec2){px, py}, (vec_ivec2){128, 128}, __arg1); | |
} | |
} | |
} | |
uint32_t noise_basehash_2(uvec2 v) { | |
v = vec_mul_13(1103515245U, vec_bxor_1(vec_uvec2_yx(v), vec_shr_1(v, 1U))); | |
uint32_t h = (1103515245U * (v.x ^ (v.y >> 3U))); | |
return (h ^ (h >> 16U)); | |
} | |
uint32_t noise_basehash_3(uvec3 v) { | |
v = vec_mul_14(1103515245U, vec_bxor_2(vec_uvec3_yzx(v), vec_shr_2(v, 1U))); | |
uint32_t h = (1103515245U * ((v.x ^ v.z) ^ (v.y >> 3U))); | |
return (h ^ (h >> 16U)); | |
} | |
float noise_hash1_2(vec2 v) { | |
uint32_t n = noise_basehash_2(vec_floatbits2uint_2(v)); | |
return ((n & 0x7fffffffU) * 4.65661288e-10f); | |
} | |
float noise_hash1_3(vec3 v) { | |
uint32_t n = noise_basehash_3(vec_floatbits2uint_3(v)); | |
return ((n & 0x7fffffffU) * 4.65661288e-10f); | |
} | |
float noise_noisemix3(float a1, float b1, float c1, float d1, float a2, float b2, float c2, float d2, vec3 f) { | |
vec3 u = vec_mul_6(vec_mul_6(f, f), vec_sub_7(3.0f, vec_mul_7(2.0f, f))); | |
return vec_fastmix_1(vec_fastmix_1(vec_fastmix_1(a1, b1, u.x), vec_fastmix_1(c1, d1, u.x), u.y), vec_fastmix_1(vec_fastmix_1(a2, b2, u.x), vec_fastmix_1(c2, d2, u.x), u.y), u.z); | |
} | |
float noise_white_1(vec2 p) { | |
return noise_hash1_2(p); | |
} | |
float noise_value_1(vec3 p) { | |
vec3 i = vec_floor_2(p); | |
vec3 f = vec_fract_2(p); | |
vec3 I = vec_floor_2(vec_add_4(i, 1.0f)); | |
float a1 = noise_hash1_3(i); | |
float b1 = noise_hash1_3((vec3){I.x, i.y, i.z}); | |
float c1 = noise_hash1_3((vec3){i.x, I.y, i.z}); | |
float d1 = noise_hash1_3((vec3){I.x, I.y, i.z}); | |
float a2 = noise_hash1_3((vec3){i.x, i.y, I.z}); | |
float b2 = noise_hash1_3((vec3){I.x, i.y, I.z}); | |
float c2 = noise_hash1_3((vec3){i.x, I.y, I.z}); | |
float d2 = noise_hash1_3(I); | |
return noise_noisemix3(a1, b1, c1, d1, a2, b2, c2, d2, f); | |
} | |
float planet_sphere_intersect(vec3 ro, vec3 rd, vec3 p, float r) { | |
vec3 oc = vec_sub_3(ro, p); | |
float b = vec_dot_2(oc, rd); | |
float c = (vec_dot_2(oc, oc) - (r * r)); | |
float h = ((b * b) - c); | |
if((h < 0.0f)) { | |
return -1.0f; | |
} else { | |
return ((-b) - vec_sqrt_1(h)); | |
} | |
} | |
float planet_fbm3(vec3 p) { | |
float a = 1.0f; | |
float t = 0.0f; | |
t = (t + (a * noise_value_1(p))); | |
a = (a * 0.5f); | |
p = vec_add_4(vec_mul_7(2.0f, p), 100.0f); | |
t = (t + (a * noise_value_1(p))); | |
a = (a * 0.5f); | |
p = vec_add_4(vec_mul_7(2.0f, p), 100.0f); | |
t = (t + (a * noise_value_1(p))); | |
a = (a * 0.5f); | |
p = vec_add_4(vec_mul_7(2.0f, p), 100.0f); | |
t = (t + (a * noise_value_1(p))); | |
a = (a * 0.5f); | |
p = vec_add_4(vec_mul_7(2.0f, p), 100.0f); | |
t = (t + (a * noise_value_1(p))); | |
a = (a * 0.5f); | |
p = vec_add_4(vec_mul_7(2.0f, p), 100.0f); | |
t = (t + (a * noise_value_1(p))); | |
return t; | |
} | |
vec3 planet_palette(float x) { | |
vec3 col = (vec3){0.1f, 0.6f, 0.9f}; | |
col = vec_add_5(col, vec_mul_7(0.2f, vec_fastsin_2(vec_add_3((6.28318531f * x), (vec3){0.3f, 0.2f, 0.1f})))); | |
col = vec_add_5(col, vec_mul_7(0.1f, vec_fastsin_2(vec_add_3((14.4513262f * x), (vec3){0.1f, 0.2f, 0.3f})))); | |
return col; | |
} | |
vec3 planet_color(vec3 p, float t) { | |
p = vec_mul_8(p, 2.0f); | |
vec3 q = (vec3){(planet_fbm3(vec_add_4(p, (t * 0.03f))) * 0.5f), (planet_fbm3(p) * 0.5f), (planet_fbm3(vec_add_4(p, 33.33f)) * 0.5f)}; | |
vec3 r = (vec3){(planet_fbm3(vec_add_4(vec_add_5(p, q), (t * 0.01f))) * 0.5f), (planet_fbm3(vec_add_5(p, q)) * 0.5f), (planet_fbm3(vec_add_4(vec_add_5(p, q), 33.33f)) * 0.6f)}; | |
float f = (planet_fbm3(vec_add_4(vec_add_5(p, vec_mul_7(5.0f, r)), (t * 0.02f))) * 0.5f); | |
vec3 col = planet_palette(r.y); | |
col = vec_mul_8(col, ((vec_clamp_1((f * f), 0.0f, 1.0f) * 0.9f) + 0.1f)); | |
col = vec_clamp_2(col, 0.0f, 1.0f); | |
return col; | |
} | |
vec3 planet_shade(vec3 rd, vec3 p, float time) { | |
vec3 normal = vec_normalize_2(p); | |
float ambient_dif = 0.03f; | |
vec3 dif = vec_tovec3_1(ambient_dif); | |
vec3 sun_dir = (vec3){0.0f, 0.0f, 1.0f}; | |
vec3 sun_col = vec_mul_8((vec3){1.0f, 0.9f, 0.9f}, 4.0f); | |
float sun_dif = vec_clamp_1(((vec_dot_2(normal, sun_dir) * 0.9f) + 0.1f), 0.0f, 1.0f); | |
dif = vec_add_5(dif, vec_mul_8(sun_col, sun_dif)); | |
vec3 mate = vec_mul_8(planet_color(p, time), 0.4f); | |
vec3 col = vec_mul_6(mate, dif); | |
float fres = vec_clamp_1((1.0f + vec_dot_2(normal, rd)), 0.0f, 1.0f); | |
float sun_fres = (fres * vec_clamp_1(vec_dot_2(rd, sun_dir), 0.0f, 1.0f)); | |
col = vec_mul_8(col, (1.0f - fres)); | |
col = vec_add_5(col, vec_mul_8(vec_mul_7(vec_pow2_1(vec_pow2_1(vec_pow2_1(sun_fres))), (vec3){0.4f, 0.3f, 0.1f}), 5.0f)); | |
return col; | |
} | |
vec3 planet_perspective_camera(vec3 lookfrom, vec3 lookat, float tilt, float vfov, vec2 uv) { | |
vec2 sc = vec_fastsincos(tilt); | |
vec3 vup = vec_normalize_2((vec3){sc.x, sc.y, 0.0f}); | |
vec3 w = vec_normalize_2(vec_sub_3(lookat, lookfrom)); | |
vec3 u = vec_cross(w, vup); | |
vec3 v = vec_cross(u, w); | |
float wf = (1.0f / vec_tan_1(((vfov * 3.14159265f) / 360.0f))); | |
return vec_normalize_2(vec_add_5(vec_add_5(vec_mul_7(uv.x, u), vec_mul_7(uv.y, v)), vec_mul_7(wf, w))); | |
} | |
float planet_expstep(float x, float k) { | |
return vec_exp_1(((k * x) - k)); | |
} | |
vec3 planet_get_background(vec3 rd) { | |
vec3 sun_dir = (vec3){0.0f, 0.0f, 1.0f}; | |
float sun_dif = vec_dot_2(rd, sun_dir); | |
vec3 col = vec_mul_8((vec3){1.0f, 0.9f, 0.9f}, planet_expstep(sun_dif, 600.0f)); | |
col = vec_add_5(col, vec_mul_8((vec3){1.0f, 1.0f, 0.1f}, planet_expstep(sun_dif, 100.0f))); | |
col = vec_add_5(col, vec_mul_8((vec3){1.0f, 0.7f, 0.7f}, planet_expstep(sun_dif, 50.0f))); | |
col = vec_add_5(col, vec_mul_8((vec3){1.0f, 0.6f, 0.05f}, planet_expstep(sun_dif, 10.0f))); | |
return col; | |
} | |
vec3 planet_color_tonemap_aces(vec3 col) { | |
return vec_clamp_2(vec_div_4(vec_mul_6(col, vec_add_4(vec_mul_7(2.51f, col), 0.03f)), vec_add_4(vec_mul_6(col, vec_add_4(vec_mul_7(2.43f, col), 0.59f)), 0.14f)), 0.0f, 1.0f); | |
} | |
vec3 planet_color_saturate(vec3 col, float sat) { | |
float grey = vec_dot_2(col, (vec3){0.2125f, 0.7154f, 0.0721f}); | |
return vec_add_3(grey, vec_mul_7(sat, vec_sub_8(col, grey))); | |
} | |
vec3 planet_color_tone_1(vec3 col, float gain, float lift, float invgamma) { | |
col = vec_pow_1(col, vec_tovec3_1(invgamma)); | |
return vec_add_4(vec_mul_7((gain - lift), col), lift); | |
} | |
vec3 planet_color_gamma_correction(vec3 col) { | |
return sdfutils_rpow22_1(col); | |
} | |
vec3 planet_vignette(vec3 col, vec2 coord, float strength, float amount) { | |
float x = (((coord.x * coord.y) * (1.0f - coord.x)) * (1.0f - coord.y)); | |
float f = (vec_sqrt_1((16.0f * x)) + (strength * (x - 0.0625f))); | |
return vec_mul_8(col, ((1.0f - amount) + (amount * f))); | |
} | |
vec3 planet_dither(vec3 col, vec2 coord, float amount) { | |
return vec_clamp_2(vec_add_4(col, (noise_white_1(coord) * amount)), 0.0f, 1.0f); | |
} | |
vec3 planet_sun_glare(vec3 rd) { | |
vec3 sun_dir = (vec3){0.0f, 0.0f, 1.0f}; | |
vec3 glare_col = (vec3){1.0f, 0.6f, 0.2f}; | |
return vec_mul_8(glare_col, vec_pow2_1(vec_max_1(vec_dot_2(sun_dir, rd), 0.0f))); | |
} | |
void planet_main_image(bvec4_ptr frag_col, vec_ivec2 frag_coord, vec_ivec2 frag_size, float time) { | |
vec2 coord = sdfutils_rd2ncru_1(frag_coord, frag_size); | |
vec2 res = vec_tovec2_1(frag_size); | |
float theta = (6.28318531f + (time * 0.2f)); | |
vec3 lookat = (vec3){0.0f, 0.0f, 0.0f}; | |
vec2 sc = vec_mul_3(vec_fastsincos(theta), 2.0f); | |
vec3 ro = (vec3){sc.x, 0.5f, sc.y}; | |
vec3 rd = planet_perspective_camera(ro, lookat, 0.0f, 50.0f, coord); | |
float t = planet_sphere_intersect(ro, rd, (vec3){0.0f, 0.0f, 0.0f}, 0.6f); | |
vec3 p = vec_add_5(ro, vec_mul_8(rd, t)); | |
vec3 col = vec_mix_1(planet_get_background(rd), planet_shade(rd, p, time), vec_step_1(0.0f, t)); | |
col = vec_add_5(col, vec_mul_7(0.2f, planet_sun_glare(rd))); | |
col = planet_color_tonemap_aces(col); | |
col = planet_color_tone_1(col, 1.7f, 0.002f, 1.2f); | |
col = planet_color_saturate(col, 0.9f); | |
col = planet_color_gamma_correction(col); | |
col = planet_vignette(col, vec_div_3(frag_coord, res), -3.0f, 0.7f); | |
col = planet_dither(col, vec_tovec2_1(frag_coord), 0.01f); | |
(*frag_col) = vec_topixel_1(col); | |
} | |
void planet_frame() { | |
Canvas_fragment_draw_2((&planet_canvas), application_frame_time); | |
application_present_1((&planet_canvas)); | |
} | |
int nelua_main(int nelua_argc, char** nelua_argv) { | |
application_run((ApplicationDesc){.width = 512, .height = 512, .target_fps = 0, .window_title = "SDF", .frame_cb = planet_frame}); | |
return 0; | |
} | |
int main(int argc, char** argv) { | |
return nelua_main(argc, argv); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment