-#ifndef ADDON_C
-#define ADDON_C
-
+#include "vg/vg_engine.h"
#include "addon.h"
#include "addon_types.h"
#include "vg/vg_msg.h"
#include "steam.h"
#include "workshop.h"
-static u32 addon_count( enum addon_type type, u32 ignoreflags ){
+struct addon_system addon_system;
+
+u32 addon_count( enum addon_type type, u32 ignoreflags )
+{
if( ignoreflags ){
u32 typecount = 0, count = 0;
for( u32 i=0; typecount<addon_count( type, 0 ); i++ ){
/* these kind of suck, oh well. */
-static addon_reg *get_addon_from_index( enum addon_type type, u32 index,
- u32 ignoreflags ){
+addon_reg *get_addon_from_index( enum addon_type type, u32 index,
+ u32 ignoreflags )
+{
u32 typecount = 0, count = 0;
for( u32 i=0; typecount<addon_count(type,0); i++ ){
addon_reg *reg = &addon_system.registry[i];
return NULL;
}
-static u32 get_index_from_addon( enum addon_type type, addon_reg *a ){
+u32 get_index_from_addon( enum addon_type type, addon_reg *a )
+{
u32 count = 0;
for( u32 i=0; count<addon_system.registry_type_counts[type]; i++ ){
addon_reg *reg = &addon_system.registry[i];
return 0xffffffff;
}
-static u32 addon_match( addon_alias *alias ){
+u32 addon_match( addon_alias *alias )
+{
if( alias->type == k_addon_type_none ) return 0xffffffff;
u32 foldername_djb2 = 0;
/*
* Create a string version of addon alias in buf
*/
-static void addon_alias_uid( addon_alias *alias, char buf[ADDON_UID_MAX] ){
+void addon_alias_uid( addon_alias *alias, char buf[ADDON_UID_MAX] )
+{
if( alias->workshop_id ){
snprintf( buf, 128, "sr%03d-steam-"PRINTF_U64,
alias->type, alias->workshop_id );
/*
* equality check
*/
-static int addon_alias_eq( addon_alias *a, addon_alias *b ){
+int addon_alias_eq( addon_alias *a, addon_alias *b )
+{
if( a->type == b->type ){
if( a->workshop_id == b->workshop_id ){
if( a->workshop_id )
/*
* make alias represent NULL.
*/
-static void invalidate_addon_alias( addon_alias *alias ){
+void invalidate_addon_alias( addon_alias *alias )
+{
alias->type = k_addon_type_none;
alias->workshop_id = 0;
alias->foldername[0] = '\0';
/*
* parse uid to alias. returns 1 if successful
*/
-static int addon_uid_to_alias( const char *uid, addon_alias *alias ){
+int addon_uid_to_alias( const char *uid, addon_alias *alias )
+{
/* 1
* 01234567890123
* sr&&&-@@@@@-#*
return 1;
}
-static void addon_system_init( void ){
+void addon_system_init( void )
+{
u32 reg_size = sizeof(addon_reg)*ADDON_MOUNTED_MAX;
addon_system.registry = vg_linear_alloc( vg_mem.rtmemory, reg_size );
/*
* Reciever for scan completion. copies the registry counts back into main fred
*/
-static void async_addon_reg_update( void *data, u32 size )
+void async_addon_reg_update( void *data, u32 size )
{
vg_info( "Registry update notify\n" );
/*
* Mount a local folder. may or may not have addon.inf
*/
-static addon_reg *addon_mount_local_addon( const char *folder,
- enum addon_type type,
- const char *content_ext )
+addon_reg *addon_mount_local_addon( const char *folder,
+ enum addon_type type,
+ const char *content_ext )
{
char folder_path_buf[4096];
vg_str folder_path;
/*
* Check all subscribed items
*/
-static void addon_mount_workshop_items(void){
+void addon_mount_workshop_items(void)
+{
if( skaterift.demo_mode ){
vg_info( "Won't load workshop items in demo mode\n" );
return;
* Scan a local content folder for addons. It must find at least one file with
* the specified content_ext to be considered.
*/
-static void addon_mount_content_folder( enum addon_type type,
- const char *base_folder,
- const char *content_ext )
+void addon_mount_content_folder( enum addon_type type,
+ const char *base_folder,
+ const char *content_ext )
{
vg_info( "Mounting addons(type:%d) matching skaterift/%s/*/*%s\n",
type, base_folder, content_ext );
/*
* write the full path of the addon's folder into the vg_str
*/
-static int addon_get_content_folder( addon_reg *reg, vg_str *folder, int async){
+int addon_get_content_folder( addon_reg *reg, vg_str *folder, int async)
+{
if( reg->alias.workshop_id ){
struct async_workshop_filepath_info *info = NULL;
vg_async_item *call = NULL;
* Return existing cache id if reg_index points to a registry with its cache
* already set.
*/
-static u16 addon_cache_fetch( enum addon_type type, u32 reg_index ){
+u16 addon_cache_fetch( enum addon_type type, u32 reg_index )
+{
addon_reg *reg = NULL;
if( reg_index < addon_count( type, 0 ) ){
/*
* Allocate a new cache item from the pool
*/
-static u16 addon_cache_alloc( enum addon_type type, u32 reg_index ){
+u16 addon_cache_alloc( enum addon_type type, u32 reg_index )
+{
struct addon_cache *cache = &addon_system.cache[ type ];
u16 new_id = vg_pool_lru( &cache->pool );
/*
* Get the real item data for cache id
*/
-static void *addon_cache_item( enum addon_type type, u16 id ){
+void *addon_cache_item( enum addon_type type, u16 id )
+{
if( !id ) return NULL;
struct addon_cache *cache = &addon_system.cache[type];
/*
* Get the real item data for cache id ONLY if the item is completely loaded.
*/
-static void *addon_cache_item_if_loaded( enum addon_type type, u16 id ){
+void *addon_cache_item_if_loaded( enum addon_type type, u16 id )
+{
if( !id ) return NULL;
struct addon_cache *cache = &addon_system.cache[type];
/*
* Updates the item state from the main thread
*/
-static void async_addon_setstate( void *_entry, u32 _state ){
+void async_addon_setstate( void *_entry, u32 _state )
+{
addon_cache_entry *entry = _entry;
SDL_AtomicLock( &addon_system.sl_cache_using_resources );
entry->state = _state;
/*
* Goes over cache item load requests and calls the above ^
*/
-static void addon_cache_load_loop(void){
+void addon_cache_load_loop(void)
+{
vg_info( "Running load loop\n" );
char path_buf[4096];
* Perform the cache interactions required to create a viewslot which will
* eventually be loaded by other parts of the system.
*/
-static u16 addon_cache_create_viewer( enum addon_type type, u16 reg_id ){
+u16 addon_cache_create_viewer( enum addon_type type, u16 reg_id )
+{
struct addon_cache *cache = &addon_system.cache[type];
vg_pool *pool = &cache->pool;
return cache_id;
}
-static u16 addon_cache_create_viewer_from_uid( enum addon_type type,
- char uid[ADDON_UID_MAX] ){
+u16 addon_cache_create_viewer_from_uid( enum addon_type type,
+ char uid[ADDON_UID_MAX] )
+{
addon_alias q;
if( !addon_uid_to_alias( uid, &q ) ) return 0;
if( q.type != type ) return 0;
}
}
-static void addon_cache_watch( enum addon_type type, u16 cache_id ){
+void addon_cache_watch( enum addon_type type, u16 cache_id )
+{
if( !cache_id ) return;
struct addon_cache *cache = &addon_system.cache[type];
vg_pool_watch( pool, cache_id );
}
-static void addon_cache_unwatch( enum addon_type type, u16 cache_id ){
+void addon_cache_unwatch( enum addon_type type, u16 cache_id )
+{
if( !cache_id ) return;
struct addon_cache *cache = &addon_system.cache[type];
vg_pool *pool = &cache->pool;
vg_pool_unwatch( pool, cache_id );
}
-
-#endif /* ADDON_C */
-#ifndef ADDON_H
-#define ADDON_H
-
-#include "skaterift.h"
+#pragma once
#include "vg/vg_steam_ugc.h"
-#include "addon_types.h"
#include "vg/vg_mem_pool.h"
-
-#include "world.h"
-#include "player.h"
+#include "vg/vg_string.h"
+#include "addon_types.h"
typedef struct addon_reg addon_reg;
typedef struct addon_cache_entry addon_cache_entry;
typedef struct addon_alias addon_alias;
-struct addon_alias {
+struct addon_alias
+{
enum addon_type type;
PublishedFileId_t workshop_id;
char foldername[ ADDON_FOLDERNAME_MAX ];
#define ADDON_REG_CITY 0x4
#define ADDON_REG_PREMIUM 0x8
-struct {
- struct addon_reg{
+struct addon_system
+{
+ struct addon_reg
+ {
addon_alias alias;
u32 foldername_hash;
u8 metadata[512]; /* vg_msg buffer */
/* deffered: updates in main thread */
u32 registry_type_counts[k_addon_type_max];
- struct addon_cache{
- struct addon_cache_entry{
+ struct addon_cache
+ {
+ struct addon_cache_entry
+ {
u32 reg_index;
addon_reg *reg_ptr; /* TODO: only use reg_index? */
cache[k_addon_type_max];
SDL_SpinLock sl_cache_using_resources;
}
-static addon_system;
+extern addon_system;
-static void addon_system_init( void );
-static u32 addon_count( enum addon_type type, u32 ignoreflags );
-static addon_reg *get_addon_from_index( enum addon_type type, u32 index,
- u32 ignoreflags );
-static u32 get_index_from_addon( enum addon_type type, addon_reg *a );
-static int addon_get_content_folder( addon_reg *reg, vg_str *folder, int async);
+void addon_system_init( void );
+u32 addon_count( enum addon_type type, u32 ignoreflags );
+addon_reg *get_addon_from_index( enum addon_type type, u32 index,
+ u32 ignoreflags );
+u32 get_index_from_addon( enum addon_type type, addon_reg *a );
+int addon_get_content_folder( addon_reg *reg, vg_str *folder, int async);
/* scanning routines */
-static u32 addon_match( addon_alias *alias );
-static int addon_alias_eq( addon_alias *a, addon_alias *b );
-static void addon_alias_uid( addon_alias *alias, char buf[ADDON_UID_MAX] );
-static int addon_uid_to_alias( const char *uid, addon_alias *alias );
-static void invalidate_addon_alias( addon_alias *alias );
-static void addon_mount_content_folder( enum addon_type type,
- const char *base_folder,
- const char *content_ext );
-static void addon_mount_workshop_items(void);
-static void async_addon_reg_update( void *data, u32 size );
-static addon_reg *addon_mount_local_addon( const char *folder,
- enum addon_type type,
- const char *content_ext );
-static u16 addon_cache_fetch( enum addon_type type, u32 reg_index );
-static u16 addon_cache_alloc( enum addon_type type, u32 reg_index );
-static void *addon_cache_item( enum addon_type type, u16 id );
-static void *addon_cache_item_if_loaded( enum addon_type type, u16 id );
-static void async_addon_setstate( void *data, u32 size );
-static void addon_cache_load_loop(void);
-static u16 addon_cache_create_viewer( enum addon_type type, u16 reg_id);
-
-static void addon_cache_watch( enum addon_type type, u16 cache_id );
-static void addon_cache_unwatch( enum addon_type type, u16 cache_id );
-static u16 addon_cache_create_viewer_from_uid( enum addon_type type,
- char uid[ADDON_UID_MAX] );
-
-#endif /* ADDON_H */
+u32 addon_match( addon_alias *alias );
+int addon_alias_eq( addon_alias *a, addon_alias *b );
+void addon_alias_uid( addon_alias *alias, char buf[ADDON_UID_MAX] );
+int addon_uid_to_alias( const char *uid, addon_alias *alias );
+void invalidate_addon_alias( addon_alias *alias );
+void addon_mount_content_folder( enum addon_type type,
+ const char *base_folder,
+ const char *content_ext );
+void addon_mount_workshop_items(void);
+void async_addon_reg_update( void *data, u32 size );
+addon_reg *addon_mount_local_addon( const char *folder,
+ enum addon_type type,
+ const char *content_ext );
+u16 addon_cache_fetch( enum addon_type type, u32 reg_index );
+u16 addon_cache_alloc( enum addon_type type, u32 reg_index );
+void *addon_cache_item( enum addon_type type, u16 id );
+void *addon_cache_item_if_loaded( enum addon_type type, u16 id );
+void async_addon_setstate( void *data, u32 size );
+void addon_cache_load_loop(void);
+u16 addon_cache_create_viewer( enum addon_type type, u16 reg_id);
+
+void addon_cache_watch( enum addon_type type, u16 cache_id );
+void addon_cache_unwatch( enum addon_type type, u16 cache_id );
+u16 addon_cache_create_viewer_from_uid( enum addon_type type,
+ char uid[ADDON_UID_MAX] );
--- /dev/null
+#include "player.h"
+#include "player_render.h"
+#include "player_api.h"
+
+struct addon_type_info addon_type_infos[] =
+{
+ [k_addon_type_board] = {
+ .local_content_folder = "boards/",
+ .cache_stride = sizeof(struct player_board),
+ .cache_count = 20
+ },
+ [k_addon_type_player] = {
+ .local_content_folder = "playermodels/",
+ .cache_stride = sizeof(struct player_model),
+ .cache_count = 20
+ },
+ [k_addon_type_world] = {
+ .local_content_folder = "maps/"
+ }
+};
-#ifndef ADDON_TYPES_H
-#define ADDON_TYPES_H
+#pragma once
enum addon_type{
k_addon_type_none = 0,
};
#define ADDON_FOLDERNAME_MAX 64
-
-/* total count that we have knowledge of */
-#define ADDON_MOUNTED_MAX 128
+#define ADDON_MOUNTED_MAX 128 /* total count that we have knowledge of */
#define ADDON_UID_MAX 76
#ifdef VG_ENGINE
-#include "world.h"
-#include "player.h"
-
struct addon_type_info {
size_t cache_stride;
u16 cache_count;
const char *local_content_folder;
}
-static addon_type_infos[] = {
- [k_addon_type_board] = {
- .local_content_folder = "boards/",
- .cache_stride = sizeof(struct player_board),
- .cache_count = 20
- },
- [k_addon_type_player] = {
- .local_content_folder = "playermodels/",
- .cache_stride = sizeof(struct player_model),
- .cache_count = 20
- },
- [k_addon_type_world] = {
- .local_content_folder = "maps/"
- }
-};
+extern addon_type_infos[];
#endif
-
-#endif /* ADDON_TYPES_H */
--- /dev/null
+#include "world.h"
+#include "audio.h"
+#include "vg/vg_audio_dsp.h"
+
+audio_clip audio_board[] =
+{
+ { .path="sound/skate_hpf.ogg" },
+ { .path="sound/wheel.ogg" },
+ { .path="sound/slide.ogg" },
+ { .path="sound/grind_enter.ogg" },
+ { .path="sound/grind_exit.ogg" },
+ { .path="sound/grind_loop.ogg" },
+ { .path="sound/woodslide.ogg" },
+ { .path="sound/metalscrape.ogg" },
+ { .path="sound/slidetap.ogg" }
+};
+
+audio_clip audio_taps[] =
+{
+ { .path="sound/tap0.ogg" },
+ { .path="sound/tap1.ogg" },
+ { .path="sound/tap2.ogg" },
+ { .path="sound/tap3.ogg" }
+};
+
+audio_clip audio_flips[] =
+{
+ { .path="sound/lf0.ogg" },
+ { .path="sound/lf1.ogg" },
+ { .path="sound/lf2.ogg" },
+ { .path="sound/lf3.ogg" },
+};
+
+audio_clip audio_hits[] =
+{
+ { .path="sound/hit0.ogg" },
+ { .path="sound/hit1.ogg" },
+ { .path="sound/hit2.ogg" },
+ { .path="sound/hit3.ogg" },
+ { .path="sound/hit4.ogg" }
+};
+
+audio_clip audio_splash =
+{ .path = "sound/splash.ogg" };
+
+audio_clip audio_jumps[] = {
+ { .path = "sound/jump0.ogg" },
+ { .path = "sound/jump1.ogg" },
+};
+
+audio_clip audio_footsteps[] = {
+ {.path = "sound/step_concrete0.ogg" },
+ {.path = "sound/step_concrete1.ogg" },
+ {.path = "sound/step_concrete2.ogg" },
+ {.path = "sound/step_concrete3.ogg" }
+};
+
+audio_clip audio_footsteps_grass[] = {
+ {.path = "sound/step_bush0.ogg" },
+ {.path = "sound/step_bush1.ogg" },
+ {.path = "sound/step_bush2.ogg" },
+ {.path = "sound/step_bush3.ogg" },
+ {.path = "sound/step_bush4.ogg" },
+ {.path = "sound/step_bush5.ogg" }
+};
+
+audio_clip audio_footsteps_wood[] = {
+ {.path = "sound/step_wood0.ogg" },
+ {.path = "sound/step_wood1.ogg" },
+ {.path = "sound/step_wood2.ogg" },
+ {.path = "sound/step_wood3.ogg" },
+ {.path = "sound/step_wood4.ogg" },
+ {.path = "sound/step_wood5.ogg" }
+};
+
+audio_clip audio_lands[] = {
+ { .path = "sound/land0.ogg" },
+ { .path = "sound/land1.ogg" },
+ { .path = "sound/land2.ogg" },
+ { .path = "sound/landsk0.ogg" },
+ { .path = "sound/landsk1.ogg" },
+ { .path = "sound/onto.ogg" },
+ { .path = "sound/outo.ogg" },
+};
+
+audio_clip audio_water[] = {
+ { .path = "sound/wave0.ogg" },
+ { .path = "sound/wave1.ogg" },
+ { .path = "sound/wave2.ogg" },
+ { .path = "sound/wave3.ogg" },
+ { .path = "sound/wave4.ogg" },
+ { .path = "sound/wave5.ogg" }
+};
+
+audio_clip audio_grass[] = {
+ { .path = "sound/grass0.ogg" },
+ { .path = "sound/grass1.ogg" },
+ { .path = "sound/grass2.ogg" },
+ { .path = "sound/grass3.ogg" },
+};
+
+audio_clip audio_ambience[] =
+{
+ { .path="sound/town_generic.ogg" }
+};
+
+audio_clip audio_gate_pass = {
+ .path = "sound/gate_pass.ogg"
+};
+
+audio_clip audio_gate_lap = {
+ .path = "sound/gate_lap.ogg"
+};
+
+audio_clip audio_gate_ambient = {
+.path = "sound/gate_ambient.ogg"
+};
+
+audio_clip audio_rewind[] = {
+{ .path = "sound/rewind_start.ogg" },
+{ .path = "sound/rewind_end_1.5.ogg" },
+{ .path = "sound/rewind_end_2.5.ogg" },
+{ .path = "sound/rewind_end_6.5.ogg" },
+{ .path = "sound/rewind_clack.ogg" },
+};
+
+audio_clip audio_ui[] = {
+ { .path = "sound/ui_click.ogg" },
+ { .path = "sound/ui_ding.ogg" },
+ { .path = "sound/teleport.ogg" }
+};
+
+audio_clip audio_challenge[] = {
+ { .path = "sound/objective0.ogg" },
+ { .path = "sound/objective1.ogg" },
+ { .path = "sound/objective_win.ogg" },
+ { .path = "sound/ui_good.ogg" },
+ { .path = "sound/ui_inf.ogg" },
+ { .path = "sound/ui_ok.ogg" },
+ { .path = "sound/objective_fail.ogg" }
+};
+
+struct air_synth_data air_audio_data;
+
+static void audio_air_synth_get_samples( void *_data, f32 *buf, u32 count ){
+ struct air_synth_data *data = _data;
+
+ SDL_AtomicLock( &data->sl );
+ f32 spd = data->speed;
+ SDL_AtomicUnlock( &data->sl );
+
+ f32 s0 = sinf(data->t*2.0f),
+ s1 = sinf(data->t*0.43f),
+ s2 = sinf(data->t*1.333f),
+ sm = vg_clampf( data->speed / 45.0f, 0, 1 ),
+ ft = (s0*s1*s2)*0.5f+0.5f,
+ f = vg_lerpf( 200.0f, 1200.0f, sm*0.7f + ft*0.3f ),
+ vol = 0.25f * sm;
+
+ dsp_init_biquad_butterworth_lpf( &data->lpf, f );
+
+ for( u32 i=0; i<count; i ++ ){
+ f32 v = (vg_randf64(&vg_dsp.rand) * 2.0f - 1.0f) * vol;
+ v = dsp_biquad_process( &data->lpf, v );
+
+ buf[i*2+0] = v;
+ buf[i*2+1] = v;
+ }
+
+ data->t += (f32)(count)/44100.0f;
+};
+
+static audio_clip air_synth = {
+ .flags = k_audio_format_gen,
+ .size = 0,
+ .func = audio_air_synth_get_samples,
+ .data = &air_audio_data
+};
+
+void audio_init(void)
+{
+ audio_clip_loadn( audio_board, vg_list_size(audio_board), NULL );
+ audio_clip_loadn( audio_taps, vg_list_size(audio_taps), NULL );
+ audio_clip_loadn( audio_flips, vg_list_size(audio_flips), NULL );
+ audio_clip_loadn( audio_hits, vg_list_size(audio_hits), NULL );
+ audio_clip_loadn( audio_ambience, vg_list_size(audio_ambience), NULL );
+ audio_clip_loadn( &audio_splash, 1, NULL );
+ audio_clip_loadn( &audio_gate_pass, 1, NULL );
+ audio_clip_loadn( &audio_gate_lap, 1, NULL );
+ audio_clip_loadn( &audio_gate_ambient, 1, NULL );
+
+ audio_clip_loadn( audio_jumps, vg_list_size(audio_jumps), NULL );
+ audio_clip_loadn( audio_lands, vg_list_size(audio_lands), NULL );
+ audio_clip_loadn( audio_water, vg_list_size(audio_water), NULL );
+ audio_clip_loadn( audio_grass, vg_list_size(audio_grass), NULL );
+ audio_clip_loadn( audio_footsteps, vg_list_size(audio_footsteps), NULL );
+ audio_clip_loadn( audio_footsteps_grass,
+ vg_list_size(audio_footsteps_grass), NULL );
+ audio_clip_loadn( audio_footsteps_wood,
+ vg_list_size(audio_footsteps_wood), NULL );
+ audio_clip_loadn( audio_rewind, vg_list_size(audio_rewind), NULL );
+ audio_clip_loadn( audio_ui, vg_list_size(audio_ui), NULL );
+ audio_clip_loadn( audio_challenge, vg_list_size(audio_challenge), NULL );
+
+ audio_lock();
+ audio_set_lfo_wave( 0, k_lfo_polynomial_bipolar, 80.0f );
+ audio_set_lfo_frequency( 0, 20.0f );
+
+ air_audio_data.channel = audio_get_first_idle_channel();
+ if( air_audio_data.channel )
+ audio_channel_init( air_audio_data.channel, &air_synth, 0 );
+
+ audio_unlock();
+}
+
+void audio_free(void)
+{
+ /* TODO! */
+ vg_warn( "UNIMPLEMENTED: audio_free()\n" );
+}
+
+void audio_ambient_sprite_play( v3f co, audio_clip *clip )
+{
+ audio_lock();
+ u16 group_id = 0xfff0;
+ audio_channel *ch = audio_get_group_idle_channel( group_id, 4 );
+
+ if( ch ){
+ audio_channel_init( ch, clip, AUDIO_FLAG_SPACIAL_3D );
+ audio_channel_group( ch, group_id );
+ audio_channel_set_spacial( ch, co, 80.0f );
+ audio_channel_edit_volume( ch, 1.0f, 1 );
+ ch = audio_relinquish_channel( ch );
+ }
+ audio_unlock();
+}
+
+enum audio_sprite_type world_audio_sample_sprite_random(v3f origin, v3f output);
+void audio_ambient_sprites_update( world_instance *world, v3f co )
+{
+ static float accum = 0.0f;
+ accum += vg.time_delta;
+
+ if( accum > 0.1f )
+ accum -= 0.1f;
+ else return;
+
+ v3f sprite_pos;
+ enum audio_sprite_type sprite_type =
+ world_audio_sample_sprite_random( co, sprite_pos );
+
+ if( sprite_type != k_audio_sprite_type_none ){
+ if( sprite_type == k_audio_sprite_type_grass ){
+ audio_ambient_sprite_play( sprite_pos,
+ &audio_grass[vg_randu32(&vg.rand)%4] );
+ }
+ else if( sprite_type == k_audio_sprite_type_water ){
+ if( world->water.enabled ){
+ audio_ambient_sprite_play( sprite_pos,
+ &audio_water[vg_randu32(&vg.rand)%6] );
+ }
+ }
+ }
+}
* Copyright (C) 2021-2022 Mt.ZERO Software, Harry Godden - All Rights Reserved
*/
-#include "common.h"
+#pragma once
-#ifndef AUDIO_H
-#define AUDIO_H
-
-#include "world.h"
+#include "vg/vg_engine.h"
+#include "vg/vg_audio.h"
#include "vg/vg_audio_dsp.h"
-
-audio_clip audio_board[] =
-{
- { .path="sound/skate_hpf.ogg" },
- { .path="sound/wheel.ogg" },
- { .path="sound/slide.ogg" },
- { .path="sound/grind_enter.ogg" },
- { .path="sound/grind_exit.ogg" },
- { .path="sound/grind_loop.ogg" },
- { .path="sound/woodslide.ogg" },
- { .path="sound/metalscrape.ogg" },
- { .path="sound/slidetap.ogg" }
-};
-
-audio_clip audio_taps[] =
-{
- { .path="sound/tap0.ogg" },
- { .path="sound/tap1.ogg" },
- { .path="sound/tap2.ogg" },
- { .path="sound/tap3.ogg" }
-};
-
-audio_clip audio_flips[] =
-{
- { .path="sound/lf0.ogg" },
- { .path="sound/lf1.ogg" },
- { .path="sound/lf2.ogg" },
- { .path="sound/lf3.ogg" },
-};
-
-audio_clip audio_hits[] =
-{
- { .path="sound/hit0.ogg" },
- { .path="sound/hit1.ogg" },
- { .path="sound/hit2.ogg" },
- { .path="sound/hit3.ogg" },
- { .path="sound/hit4.ogg" }
-};
-
-audio_clip audio_splash =
-{ .path = "sound/splash.ogg" };
-
-audio_clip audio_jumps[] = {
- { .path = "sound/jump0.ogg" },
- { .path = "sound/jump1.ogg" },
-};
-
-audio_clip audio_footsteps[] = {
- {.path = "sound/step_concrete0.ogg" },
- {.path = "sound/step_concrete1.ogg" },
- {.path = "sound/step_concrete2.ogg" },
- {.path = "sound/step_concrete3.ogg" }
-};
-
-audio_clip audio_footsteps_grass[] = {
- {.path = "sound/step_bush0.ogg" },
- {.path = "sound/step_bush1.ogg" },
- {.path = "sound/step_bush2.ogg" },
- {.path = "sound/step_bush3.ogg" },
- {.path = "sound/step_bush4.ogg" },
- {.path = "sound/step_bush5.ogg" }
-};
-
-audio_clip audio_footsteps_wood[] = {
- {.path = "sound/step_wood0.ogg" },
- {.path = "sound/step_wood1.ogg" },
- {.path = "sound/step_wood2.ogg" },
- {.path = "sound/step_wood3.ogg" },
- {.path = "sound/step_wood4.ogg" },
- {.path = "sound/step_wood5.ogg" }
-};
-
-audio_clip audio_lands[] = {
- { .path = "sound/land0.ogg" },
- { .path = "sound/land1.ogg" },
- { .path = "sound/land2.ogg" },
- { .path = "sound/landsk0.ogg" },
- { .path = "sound/landsk1.ogg" },
- { .path = "sound/onto.ogg" },
- { .path = "sound/outo.ogg" },
-};
-
-audio_clip audio_water[] = {
- { .path = "sound/wave0.ogg" },
- { .path = "sound/wave1.ogg" },
- { .path = "sound/wave2.ogg" },
- { .path = "sound/wave3.ogg" },
- { .path = "sound/wave4.ogg" },
- { .path = "sound/wave5.ogg" }
-};
-
-audio_clip audio_grass[] = {
- { .path = "sound/grass0.ogg" },
- { .path = "sound/grass1.ogg" },
- { .path = "sound/grass2.ogg" },
- { .path = "sound/grass3.ogg" },
-};
-
-audio_clip audio_ambience[] =
-{
- { .path="sound/town_generic.ogg" }
-};
-
-audio_clip audio_gate_pass = {
- .path = "sound/gate_pass.ogg"
-};
-
-audio_clip audio_gate_lap = {
- .path = "sound/gate_lap.ogg"
-};
-
-audio_clip audio_gate_ambient = {
-.path = "sound/gate_ambient.ogg"
-};
-
-audio_clip audio_rewind[] = {
-{ .path = "sound/rewind_start.ogg" },
-{ .path = "sound/rewind_end_1.5.ogg" },
-{ .path = "sound/rewind_end_2.5.ogg" },
-{ .path = "sound/rewind_end_6.5.ogg" },
-{ .path = "sound/rewind_clack.ogg" },
-};
-
-audio_clip audio_ui[] = {
- { .path = "sound/ui_click.ogg" },
- { .path = "sound/ui_ding.ogg" },
- { .path = "sound/teleport.ogg" }
-};
-
-audio_clip audio_challenge[] = {
- { .path = "sound/objective0.ogg" },
- { .path = "sound/objective1.ogg" },
- { .path = "sound/objective_win.ogg" },
- { .path = "sound/ui_good.ogg" },
- { .path = "sound/ui_inf.ogg" },
- { .path = "sound/ui_ok.ogg" },
- { .path = "sound/objective_fail.ogg" }
-};
+#include "world.h"
struct air_synth_data {
f32 speed;
f32 t;
struct dsp_biquad lpf;
SDL_SpinLock sl;
-}
-static air_data;
-
-static void audio_air_synth_get_samples( void *_data, f32 *buf, u32 count ){
- struct air_synth_data *data = _data;
-
- SDL_AtomicLock( &data->sl );
- f32 spd = data->speed;
- SDL_AtomicUnlock( &data->sl );
- f32 s0 = sinf(data->t*2.0f),
- s1 = sinf(data->t*0.43f),
- s2 = sinf(data->t*1.333f),
- sm = vg_clampf( data->speed / 45.0f, 0, 1 ),
- ft = (s0*s1*s2)*0.5f+0.5f,
- f = vg_lerpf( 200.0f, 1200.0f, sm*0.7f + ft*0.3f ),
- vol = 0.25f * sm;
-
- dsp_init_biquad_butterworth_lpf( &data->lpf, f );
-
- for( u32 i=0; i<count; i ++ ){
- f32 v = (vg_randf64(&vg_dsp.rand) * 2.0f - 1.0f) * vol;
- v = dsp_biquad_process( &data->lpf, v );
-
- buf[i*2+0] = v;
- buf[i*2+1] = v;
- }
-
- data->t += (f32)(count)/44100.0f;
-};
-
-static audio_clip air_synth = {
- .flags = k_audio_format_gen,
- .size = 0,
- .func = audio_air_synth_get_samples,
- .data = &air_data
-};
-
-static void audio_init(void)
-{
- audio_clip_loadn( audio_board, vg_list_size(audio_board), NULL );
- audio_clip_loadn( audio_taps, vg_list_size(audio_taps), NULL );
- audio_clip_loadn( audio_flips, vg_list_size(audio_flips), NULL );
- audio_clip_loadn( audio_hits, vg_list_size(audio_hits), NULL );
- audio_clip_loadn( audio_ambience, vg_list_size(audio_ambience), NULL );
- audio_clip_loadn( &audio_splash, 1, NULL );
- audio_clip_loadn( &audio_gate_pass, 1, NULL );
- audio_clip_loadn( &audio_gate_lap, 1, NULL );
- audio_clip_loadn( &audio_gate_ambient, 1, NULL );
-
- audio_clip_loadn( audio_jumps, vg_list_size(audio_jumps), NULL );
- audio_clip_loadn( audio_lands, vg_list_size(audio_lands), NULL );
- audio_clip_loadn( audio_water, vg_list_size(audio_water), NULL );
- audio_clip_loadn( audio_grass, vg_list_size(audio_grass), NULL );
- audio_clip_loadn( audio_footsteps, vg_list_size(audio_footsteps), NULL );
- audio_clip_loadn( audio_footsteps_grass,
- vg_list_size(audio_footsteps_grass), NULL );
- audio_clip_loadn( audio_footsteps_wood,
- vg_list_size(audio_footsteps_wood), NULL );
- audio_clip_loadn( audio_rewind, vg_list_size(audio_rewind), NULL );
- audio_clip_loadn( audio_ui, vg_list_size(audio_ui), NULL );
- audio_clip_loadn( audio_challenge, vg_list_size(audio_challenge), NULL );
-
- audio_lock();
- audio_set_lfo_wave( 0, k_lfo_polynomial_bipolar, 80.0f );
- audio_set_lfo_frequency( 0, 20.0f );
-
- skaterift.aud_air = audio_get_first_idle_channel();
- if( skaterift.aud_air )
- audio_channel_init( skaterift.aud_air, &air_synth, 0 );
-
- audio_unlock();
+ /* not used in locking */
+ audio_channel *channel;
}
+extern air_audio_data;
-static void audio_free(void)
-{
- /* TODO! */
- vg_warn( "UNIMPLEMENTED: audio_free()\n" );
-}
+void audio_init(void);
+void audio_free(void);
+void audio_ambient_sprite_play( v3f co, audio_clip *clip );
+void audio_ambient_sprites_update( world_instance *world, v3f co );
+
+/* TODO(ASSETS):
+ * Have these as asignable ID's and not a bunch of different arrays.
+ */
+extern audio_clip audio_board[];
+extern audio_clip audio_taps[];
+extern audio_clip audio_flips[];
+extern audio_clip audio_hits[];
+extern audio_clip audio_splash;
+extern audio_clip audio_jumps[];
+extern audio_clip audio_footsteps[];
+extern audio_clip audio_footsteps_grass[];
+extern audio_clip audio_footsteps_wood[];
+extern audio_clip audio_lands[];
+extern audio_clip audio_water[];
+extern audio_clip audio_grass[];
+extern audio_clip audio_ambience[];
+extern audio_clip audio_gate_pass;
+extern audio_clip audio_gate_lap;
+extern audio_clip audio_gate_ambient;
+extern audio_clip audio_rewind[];
+extern audio_clip audio_ui[];
+extern audio_clip audio_challenge[];
enum audio_sprite_type
{
k_audio_sprite_type_grass,
k_audio_sprite_type_water
};
-
-static void audio_ambient_sprite_play( v3f co, audio_clip *clip )
-{
- audio_lock();
- u16 group_id = 0xfff0;
- audio_channel *ch = audio_get_group_idle_channel( group_id, 4 );
-
- if( ch ){
- audio_channel_init( ch, clip, AUDIO_FLAG_SPACIAL_3D );
- audio_channel_group( ch, group_id );
- audio_channel_set_spacial( ch, co, 80.0f );
- audio_channel_edit_volume( ch, 1.0f, 1 );
- ch = audio_relinquish_channel( ch );
- }
- audio_unlock();
-}
-
-static
-enum audio_sprite_type world_audio_sample_sprite_random(v3f origin, v3f output);
-static void audio_ambient_sprites_update( world_instance *world, v3f co )
-{
- static float accum = 0.0f;
- accum += vg.time_delta;
-
- if( accum > 0.1f )
- accum -= 0.1f;
- else return;
-
- v3f sprite_pos;
- enum audio_sprite_type sprite_type =
- world_audio_sample_sprite_random( co, sprite_pos );
-
- if( sprite_type != k_audio_sprite_type_none ){
- if( sprite_type == k_audio_sprite_type_grass ){
- audio_ambient_sprite_play( sprite_pos,
- &audio_grass[vg_randu32(&vg.rand)%4] );
- }
- else if( sprite_type == k_audio_sprite_type_water ){
- if( world->water.enabled ){
- audio_ambient_sprite_play( sprite_pos,
- &audio_water[vg_randu32(&vg.rand)%6] );
- }
- }
- }
-}
-
-#endif /* AUDIO_H */
_S( "blitcolour","blit.vs", "colour.fs" );
_S( "blit_transition", "blit.vs", "blit_transition.fs" );
_S( "routeui", "routeui.vs", "routeui.fs" );
+
+ vg_build_shader_impl( "shaders/impl.c" );
}
void build_game_content( struct vg_project *proj )
.log_source_info = 1,
.steam_api = 1,
.use_3d = 1,
- .custom_game_settings = 0
+ .custom_game_settings = 0,
+ .custom_shaders = 1
});
vg_add_source( proj, "skaterift.c " );
+++ /dev/null
-/*
- * Copyright (C) 2021-2022 Mt.ZERO Software, Harry Godden - All Rights Reserved
- */
-
-#ifndef BVH_H
-#define BVH_H
-
-#include "vg/vg_mem.h"
-#include "vg/vg_m.h"
-#include "vg/vg_lines.h"
-
-/*
- * Usage:
- *
- * create a bh_system with functions filled out for expand, centroid, and swap.
- * optionally include item_debug and cast_ray functions if needed, otherwise,
- * set them to null
- *
- * create a bh_tree struct with:
- * user: a pointer back the base of the data you are ordering
- * system: the system we created above which will deal with the data
- *
- * call bh_create( bh_tree *bh, u32 item_count )
- * static int bh_ray( bh_tree *bh, u32 inode, v3f co, v3f dir, ray_hit *hit )
- * static int bh_select( bh_tree *bh, boxf box, u32 *buffer, int len )
- */
-
-typedef struct bh_node bh_node;
-typedef struct bh_tree bh_tree;
-typedef struct bh_system bh_system;
-
-typedef struct ray_hit ray_hit;
-struct ray_hit{
- float dist;
- u32 *tri;
- v3f pos, normal;
-};
-
-struct bh_tree{
- u32 node_count;
-
- bh_system *system;
- void *user;
- u32 max_per_leaf;
-
- struct bh_node
- {
- boxf bbx;
-
- /* if il is 0, this is a leaf */
- int il, count;
- union{ int ir, start; };
- }
- nodes[];
-};
-
-struct bh_system{
- u32 system_type;
- void (*expand_bound)( void *user, boxf bound, u32 item_index );
- float (*item_centroid)( void *user, u32 item_index, int axis );
- void (*item_closest)( void *user, u32 item_index, v3f point, v3f closest );
- void (*item_swap)( void *user, u32 ia, u32 ib );
-
- /*
- * Optional:
- * item_debug - draw this item quickly usually with lines
- * cast_ray - shoot a ray against the object, if this is not set,
- * raycasts will simply return the hit on the bvh node
- */
-
- void (*item_debug)( void *user, u32 item_index );
- int (*cast_ray)( void *user, u32 index, v3f co, v3f dir, ray_hit *hit );
-};
-
-static float scene_bh_centroid( void *user, u32 item_index, int axis );
-static void scene_bh_swap( void *user, u32 ia, u32 ib );
-static void scene_bh_expand_bound( void *user, boxf bound, u32 item_index );
-
-static void bh_update_bounds( bh_tree *bh, u32 inode ){
- bh_node *node = &bh->nodes[ inode ];
-
- box_init_inf( node->bbx );
- for( u32 i=0; i<node->count; i++ ){
- u32 idx = node->start+i;
- if( bh->system->system_type == 0x1 )
- scene_bh_expand_bound( bh->user, node->bbx, idx );
- else
- bh->system->expand_bound( bh->user, node->bbx, idx );
- }
-}
-
-static void bh_subdivide( bh_tree *bh, u32 inode ){
- bh_node *node = &bh->nodes[ inode ];
-
- if( node->count <= bh->max_per_leaf )
- return;
-
- v3f extent;
- v3_sub( node->bbx[1], node->bbx[0], extent );
-
- int axis = 0;
- if( extent[1] > extent[0] ) axis = 1;
- if( extent[2] > extent[axis] ) axis = 2;
-
- float split = node->bbx[0][axis] + extent[axis]*0.5f;
- float avg = 0.0;
- for( u32 t=0; t<node->count; t++ ){
- u32 idx = node->start+t;
-
- if( bh->system->system_type == 0x1 )
- avg += scene_bh_centroid( bh->user, idx, axis );
- else
- avg += bh->system->item_centroid( bh->user, idx, axis );
- }
- avg /= (float)node->count;
- split = avg;
-
-
- i32 i = node->start,
- j = i + node->count-1;
-
- while( i <= j ){
- f32 centroid;
-
- if( bh->system->system_type == 0x1 )
- centroid = scene_bh_centroid( bh->user, i, axis );
- else
- centroid = bh->system->item_centroid( bh->user, i, axis );
-
- if( centroid < split )
- i ++;
- else{
- if( bh->system->system_type == 0x1 )
- scene_bh_swap( bh->user, i, j );
- else
- bh->system->item_swap( bh->user, i, j );
- j --;
- }
- }
-
- u32 left_count = i - node->start;
- if( left_count == 0 || left_count == node->count ) return;
-
- u32 il = bh->node_count ++,
- ir = bh->node_count ++;
-
- bh_node *lnode = &bh->nodes[il],
- *rnode = &bh->nodes[ir];
-
- lnode->start = node->start;
- lnode->count = left_count;
- rnode->start = i;
- rnode->count = node->count - left_count;
-
- node->il = il;
- node->ir = ir;
- node->count = 0;
-
- bh_update_bounds( bh, il );
- bh_update_bounds( bh, ir );
- bh_subdivide( bh, il );
- bh_subdivide( bh, ir );
-}
-
-static bh_tree *bh_create( void *lin_alloc, bh_system *system,
- void *user, u32 item_count, u32 max_per_leaf ){
- if( max_per_leaf == 0 )
- vg_fatal_error( "Minimum of 1 per leaf\n" );
-
- u32 alloc_count = VG_MAX( 1, item_count );
-
- u32 totsize = sizeof(bh_tree) + sizeof(bh_node)*(alloc_count*2-1);
- bh_tree *bh = vg_linear_alloc( lin_alloc, vg_align8(totsize) );
- bh->system = system;
- bh->user = user;
- bh->max_per_leaf = max_per_leaf;
-
- bh_node *root = &bh->nodes[0];
- bh->node_count = 1;
-
- root->il = 0;
- root->ir = 0;
- root->count = item_count;
- root->start = 0;
-
- bh_update_bounds( bh, 0 );
-
- if( item_count > 2 )
- bh_subdivide( bh, 0 );
-
- totsize = vg_align8(sizeof(bh_tree) + sizeof(bh_node) * bh->node_count);
- bh = vg_linear_resize( lin_alloc, bh, totsize );
-
- vg_success( "BVH done, size: %u/%u\n", bh->node_count, (alloc_count*2-1) );
- return bh;
-}
-
-/*
- * Draw items in this leaf node.
- * *item_debug() must be set!
- */
-static void bh_debug_leaf( bh_tree *bh, bh_node *node ){
- vg_line_boxf( node->bbx, 0xff00ff00 );
-
- if( bh->system->item_debug ){
- for( u32 i=0; i<node->count; i++ ){
- u32 idx = node->start+i;
- bh->system->item_debug( bh->user, idx );
- }
- }
-}
-
-/*
- * Trace the bh tree all the way down to the leaf nodes where pos is inside
- */
-static void bh_debug_trace( bh_tree *bh, u32 inode, v3f pos, u32 colour ){
- bh_node *node = &bh->nodes[ inode ];
-
- if( (pos[0] >= node->bbx[0][0] && pos[0] <= node->bbx[1][0]) &&
- (pos[2] >= node->bbx[0][2] && pos[2] <= node->bbx[1][2]) )
- {
- if( !node->count ){
- vg_line_boxf( node->bbx, colour );
-
- bh_debug_trace( bh, node->il, pos, colour );
- bh_debug_trace( bh, node->ir, pos, colour );
- }
- else{
- if( bh->system->item_debug )
- bh_debug_leaf( bh, node );
- }
- }
-}
-
-typedef struct bh_iter bh_iter;
-struct bh_iter{
- struct {
- i32 id, depth;
- }
- stack[64];
-
- enum bh_query_type{
- k_bh_query_box,
- k_bh_query_ray,
- k_bh_query_range
- }
- query;
-
- union{
- struct{
- boxf box;
- }
- box;
-
- struct{
- v3f co, inv_dir;
- f32 max_dist;
- }
- ray;
-
- struct {
- v3f co;
- f32 dist_sqr;
- }
- range;
- };
-
- i32 depth, i;
-};
-
-static void bh_iter_init_generic( i32 root, bh_iter *it ){
- it->stack[0].id = root;
- it->stack[0].depth = 0;
- it->depth = 0;
- it->i = 0;
-}
-
-static void bh_iter_init_box( i32 root, bh_iter *it, boxf box ){
- bh_iter_init_generic( root, it );
- it->query = k_bh_query_box;
-
- box_copy( box, it->box.box );
-}
-
-static void bh_iter_init_ray( i32 root, bh_iter *it, v3f co,
- v3f dir, f32 max_dist ){
- bh_iter_init_generic( root, it );
- it->query = k_bh_query_ray;
-
- v3_div( (v3f){1.0f,1.0f,1.0f}, dir, it->ray.inv_dir );
- v3_copy( co, it->ray.co );
- it->ray.max_dist = max_dist;
-}
-
-static void bh_iter_init_range( i32 root, bh_iter *it, v3f co, f32 range ){
- bh_iter_init_generic( root, it );
- it->query = k_bh_query_range;
-
- v3_copy( co, it->range.co );
- it->range.dist_sqr = range*range;
-}
-
-/* NOTE: does not compute anything beyond the leaf level. element level tests
- * should be implemented by the users code.
- *
- * this is like a 'broad phase only' deal.
- */
-static i32 bh_next( bh_tree *bh, bh_iter *it, i32 *em ){
- while( it->depth >= 0 ){
- bh_node *inode = &bh->nodes[ it->stack[it->depth].id ];
-
- /* Only process overlapping nodes */
- i32 q = 0;
-
- if( it->i ) /* already checked */
- q = 1;
- else{
- if( it->query == k_bh_query_box )
- q = box_overlap( inode->bbx, it->box.box );
- else if( it->query == k_bh_query_ray )
- q = ray_aabb1( inode->bbx, it->ray.co,
- it->ray.inv_dir, it->ray.max_dist );
- else {
- v3f nearest;
- closest_point_aabb( it->range.co, inode->bbx, nearest );
-
- if( v3_dist2( nearest, it->range.co ) <= it->range.dist_sqr )
- q = 1;
- }
- }
-
- if( !q ){
- it->depth --;
- continue;
- }
-
- if( inode->count ){
- if( it->i < inode->count ){
- *em = inode->start+it->i;
- it->i ++;
- return 1;
- }
- else{
- it->depth --;
- it->i = 0;
- }
- }
- else{
- if( it->depth+1 >= vg_list_size(it->stack) ){
- vg_error( "Maximum stack reached!\n" );
- return 0;
- }
-
- it->stack[it->depth ].id = inode->il;
- it->stack[it->depth+1].id = inode->ir;
- it->depth ++;
- it->i = 0;
- }
- }
-
- return 0;
-}
-
-static int bh_closest_point( bh_tree *bh, v3f pos,
- v3f closest, float max_dist )
-{
- if( bh->node_count < 2 )
- return -1;
-
- max_dist = max_dist*max_dist;
-
- int queue[ 128 ],
- depth = 0,
- best_item = -1;
-
- queue[0] = 0;
-
- while( depth >= 0 ){
- bh_node *inode = &bh->nodes[ queue[depth] ];
-
- v3f p1;
- closest_point_aabb( pos, inode->bbx, p1 );
-
- /* branch into node if its closer than current best */
- float node_dist = v3_dist2( pos, p1 );
- if( node_dist < max_dist ){
- if( inode->count ){
- for( int i=0; i<inode->count; i++ ){
- v3f p2;
- bh->system->item_closest( bh->user, inode->start+i, pos, p2 );
-
- float item_dist = v3_dist2( pos, p2 );
- if( item_dist < max_dist ){
- max_dist = item_dist;
- v3_copy( p2, closest );
- best_item = inode->start+i;
- }
- }
-
- depth --;
- }
- else{
- queue[depth] = inode->il;
- queue[depth+1] = inode->ir;
-
- depth ++;
- }
- }
- else
- depth --;
- }
-
- return best_item;
-}
-
-#endif /* BVH_H */
-#ifndef CAMERA_H
-#define CAMERA_H
-
-#include "skaterift.h"
+#pragma once
+#if 0
typedef struct camera camera;
struct camera{
m4x4_copy( cam->mtx.pv, cam->mtx_prev.pv );
m4x4_mul( cam->mtx.p, cam->mtx.v, cam->mtx.pv );
}
-
-#endif /* CAMERA_H */
+#endif
-#ifndef DEPTH_COMPARE_H
-#define DEPTH_COMPARE_H
-
+#pragma once
#include "vg/vg_m.h"
+#include "skaterift.h"
#include "render.h"
-static void depth_compare_bind(
+static inline void depth_compare_bind(
void (*uTexSceneDepth)(int),
void (*uInverseRatioDepth)(v3f),
void (*uInverseRatioMain)(v3f),
- camera *cam ){
+ vg_camera *cam )
+{
uTexSceneDepth( 5 );
render_fb_bind_texture( gpipeline.fb_main, 2, 5 );
v3f inverse;
inverse[2] = cam->farz-cam->nearz;
uInverseRatioMain( inverse );
}
-
-#endif /* DEPTH_COMPARE_H */
-#ifndef ENT_CHALLENGE_C
-#define ENT_CHALLENGE_C
-
#include "entity.h"
#include "input.h"
#include "gui.h"
#include "audio.h"
-static void ent_challenge_call( world_instance *world, ent_call *call ){
+void ent_challenge_call( world_instance *world, ent_call *call )
+{
u32 index = mdl_entity_id_id( call->id );
ent_challenge *challenge = mdl_arritm( &world->ent_challenge, index );
}
}
-static void ent_challenge_preupdate( ent_challenge *challenge, int active ){
+void ent_challenge_preupdate( ent_challenge *challenge, int active )
+{
world_instance *world = world_current_instance();
/* maximum distance from active challenge */
static void ent_challenge_render( ent_challenge *challenge ){
}
-
-#endif /* ENT_CHALLENGE_C */
-#ifndef ENT_CHALLENGE_H
-#define ENT_CHALLENGE_H
-
+#pragma once
#include "entity.h"
-static void ent_challenge_preupdate( ent_challenge *challenge, int active );
-static void ent_challenge_call( world_instance *world, ent_call *call );
-
-#endif /* ENT_CHALLENGE_H */
+void ent_challenge_preupdate( ent_challenge *challenge, int active );
+void ent_challenge_call( world_instance *world, ent_call *call );
#include "gui.h"
#include "menu.h"
-static void ent_miniworld_call( world_instance *world, ent_call *call ){
+struct global_miniworld global_miniworld;
+
+void ent_miniworld_call( world_instance *world, ent_call *call )
+{
ent_miniworld *miniworld = mdl_arritm( &world->ent_miniworld,
mdl_entity_id_id(call->id) );
}
}
-static void miniworld_icon( camera *cam, enum gui_icon icon, v3f pos, f32 size){
+static void miniworld_icon( vg_camera *cam, enum gui_icon icon,
+ v3f pos, f32 size)
+{
m4x3f mmdl;
v3_copy( cam->transform[2], mmdl[2] );
mmdl[2][1] = 0.0f;
mdl_draw_submesh( sm );
}
-static void ent_miniworld_render( world_instance *host_world, camera *cam ){
+void ent_miniworld_render( world_instance *host_world, vg_camera *cam )
+{
if( host_world != &world_static.instances[k_world_purpose_hub] )
return;
}
}
-static void ent_miniworld_preupdate(void){
+void ent_miniworld_preupdate(void)
+{
world_instance *hub = world_current_instance(),
*dest = &world_static.instances[k_world_purpose_client];
}
}
-static void ent_miniworld_goback(void){
+void ent_miniworld_goback(void)
+{
audio_lock();
audio_oneshot( &audio_ui[2], 1.0f, 0.0f );
audio_unlock();
global_miniworld.t = 1.0f;
global_miniworld.cam = skaterift.cam;
- m4x3_transform_camera( global_miniworld.mmdl, &global_miniworld.cam );
+ vg_m4x3_transform_camera( global_miniworld.mmdl, &global_miniworld.cam );
world_switch_instance(0);
}
-#ifndef ENT_MINIWORLD_H
-#define ENT_MINIWORLD_H
-
+#pragma once
#include "entity.h"
-struct {
+struct global_miniworld
+{
ent_miniworld *active;
int transition;
f32 t;
m4x3f mmdl;
- camera cam;
+ vg_camera cam;
}
-static global_miniworld;
-
-static void ent_miniworld_call( world_instance *world, ent_call *call );
-static void ent_miniworld_render( world_instance *host_world, camera *cam );
-static void ent_miniworld_goback(void);
+extern global_miniworld;
-#endif /* ENT_MINIWORLD_H */
+void ent_miniworld_call( world_instance *world, ent_call *call );
+void ent_miniworld_render( world_instance *host_world, vg_camera *cam );
+void ent_miniworld_goback(void);
+void ent_miniworld_preupdate(void);
-#ifndef ENT_OBJECTIVE_C
-#define ENT_OBJECTIVE_C
-
#include "world.h"
#include "world_load.h"
#include "entity.h"
#include "audio.h"
#include "steam.h"
+#include "ent_region.h"
+#include "player.h"
+#include "player_skate.h"
static void ent_objective_pass( world_instance *world,
ent_objective *objective ){
}
}
-static void ent_objective_call( world_instance *world, ent_call *call ){
+void ent_objective_call( world_instance *world, ent_call *call )
+{
u32 index = mdl_entity_id_id( call->id );
ent_objective *objective = mdl_arritm( &world->ent_objective, index );
vg_error( "Unhandled function id: %u\n", call->function );
}
}
-
-#endif /* ENT_OBJECTIVE_C */
--- /dev/null
+#pragma once
+#include "entity.h"
+#include "world.h"
+void ent_objective_call( world_instance *world, ent_call *call );
#include "network_common.h"
#include "network.h"
-static u32 region_spark_colour( u32 flags ){
+struct global_ent_region global_ent_region;
+
+u32 region_spark_colour( u32 flags )
+{
if( flags & k_ent_route_flag_achieve_gold )
return 0xff8ce0fa;
else if( flags & k_ent_route_flag_achieve_silver )
return 0x00;
}
-static void ent_region_call( world_instance *world, ent_call *call ){
+void ent_region_call( world_instance *world, ent_call *call )
+{
ent_region *region =
mdl_arritm( &world->ent_region, mdl_entity_id_id(call->id) );
/*
* reevaluate all achievements to calculate the compiled achievement
*/
-static void ent_region_re_eval( world_instance *world ){
+void ent_region_re_eval( world_instance *world )
+{
u32 world_total = k_ent_route_flag_achieve_gold |
k_ent_route_flag_achieve_silver;
-#ifndef ENT_REGION_H
-#define ENT_REGION_H
-
+#pragma once
#include "world_entity.h"
-struct {
+struct global_ent_region
+{
char location[ NETWORK_REGION_MAX ];
u32 flags;
}
-static global_ent_region;
-
-static u32 region_spark_colour( u32 flags );
+extern global_ent_region;
-#endif /* ENT_REGION_H */
+u32 region_spark_colour( u32 flags );
+void ent_region_re_eval( world_instance *world );
+void ent_region_call( world_instance *world, ent_call *call );
-#ifndef ENT_RELAY_C
-#define ENT_RELAY_C
+#include "ent_relay.h"
-#include "entity.h"
-
-static void ent_relay_call( world_instance *world, ent_call *call ){
+void ent_relay_call( world_instance *world, ent_call *call )
+{
u32 index = mdl_entity_id_id( call->id );
ent_relay *relay = mdl_arritm( &world->ent_relay, index );
vg_error( "Unhandled function id: %u\n", call->function );
}
}
-
-#endif /* ENT_RELAY_C */
--- /dev/null
+#pragma once
+#include "entity.h"
+void ent_relay_call( world_instance *world, ent_call *call );
-#ifndef ENT_ROUTE_C
-#define ENT_ROUTE_C
-
#include "ent_route.h"
#include "input.h"
#include "gui.h"
-static void ent_route_call( world_instance *world, ent_call *call ){
+struct global_ent_route global_ent_route;
+
+void ent_route_call( world_instance *world, ent_call *call )
+{
u32 index = mdl_entity_id_id( call->id );
ent_route *route = mdl_arritm( &world->ent_route, index );
}
/* TODO: these should recieve the world instance */
-static void ent_route_preupdate( ent_route *route, int active ){
+void ent_route_preupdate( ent_route *route, int active )
+{
if( !active ) return;
world_instance *world = world_current_instance();
return;
}
}
-
-#endif /* ENT_ROUTE_C */
-#ifndef ENT_ROUTE_H
-#define ENT_ROUTE_H
-
+#pragma once
#include "entity.h"
-static struct {
+struct global_ent_route
+{
struct gui_helper *helper_weekly, *helper_alltime;
}
-global_ent_route;
-
-static void ent_route_call( world_instance *world, ent_call *call );
-static void ent_route_preupdate( ent_route *route, int active );
+extern global_ent_route;
-#endif /* ENT_ROUTE_H */
+void ent_route_call( world_instance *world, ent_call *call );
+void ent_route_preupdate( ent_route *route, int active );
#include "vg/vg_steam_ugc.h"
#include "vg/vg_msg.h"
+#include "vg/vg_tex.h"
+#include "vg/vg_image.h"
+#include "vg/vg_loader.h"
#include "ent_skateshop.h"
#include "world.h"
#include "player.h"
#include "save.h"
#include "network.h"
+struct global_skateshop global_skateshop =
+{
+ .render={.reg_id=0xffffffff,.world_reg=0xffffffff}
+};
+
/*
* Checks string equality but does a hash check first
*/
}
/* TODO: migrate to addon.c */
-static void skateshop_autostart_loading(void){
+void skateshop_autostart_loading(void)
+{
if( !vg_loader_availible() ) return;
SDL_AtomicLock( &addon_system.sl_cache_using_resources );
/*
* VG event init
*/
-static void skateshop_init(void){
+void skateshop_init(void)
+{
vg_async_call( skateshop_init_async, NULL, 0 );
}
* VG event preupdate
*/
void temp_update_playermodel(void);
-static void ent_skateshop_preupdate( ent_skateshop *shop, int active ){
+void ent_skateshop_preupdate( ent_skateshop *shop, int active )
+{
if( !active ) return;
/* input filter */
}
}
-static void skateshop_world_preupdate( world_instance *world ){
+void skateshop_world_preupdate( world_instance *world )
+{
for( u32 i=0; i<mdl_arrcount(&world->ent_skateshop); i++ ){
ent_skateshop *shop = mdl_arritm( &world->ent_skateshop, i );
/*
* World: render event
*/
-static void skateshop_render( ent_skateshop *shop ){
+void skateshop_render( ent_skateshop *shop )
+{
if( shop->type == k_skateshop_type_boardshop )
skateshop_render_boardshop( shop );
else if( shop->type == k_skateshop_type_charshop )
vg_fatal_error( "Unknown store (%u)\n", shop->type );
}
-static void skateshop_render_nonfocused( world_instance *world, camera *cam ){
+void skateshop_render_nonfocused( world_instance *world, vg_camera *cam )
+{
for( u32 j=0; j<mdl_arrcount( &world->ent_skateshop ); j ++ ){
ent_skateshop *shop = mdl_arritm(&world->ent_skateshop, j );
/*
* Entity logic: entrance event
*/
-static void ent_skateshop_call( world_instance *world, ent_call *call ){
+void ent_skateshop_call( world_instance *world, ent_call *call )
+{
u32 index = mdl_entity_id_id( call->id );
ent_skateshop *shop = mdl_arritm( &world->ent_skateshop, index );
vg_info( "skateshop_call\n" );
-#ifndef ENT_SKATESHOP_H
-#define ENT_SKATESHOP_H
-
+#pragma once
#include "world.h"
#include "world_load.h"
#include "player.h"
#define SKATESHOP_VIEW_SLOT_MAX 5
-struct{
+struct global_skateshop
+{
v3f look_target;
struct shop_view_slot{
addon_reg *reg_preview, *reg_loaded_preview;
GLuint tex_preview;
}
-static global_skateshop={
- .render={.reg_id=0xffffffff,.world_reg=0xffffffff}
-};
-
-static void ent_skateshop_preupdate( ent_skateshop *shop, int active );
-static void skateshop_render( ent_skateshop *shop );
-static void skateshop_render_nonfocused( world_instance *world, camera *cam );
-
-#endif /* ENT_SKATESHOP_H */
+extern global_skateshop;
+
+void skateshop_init(void);
+void ent_skateshop_preupdate( ent_skateshop *shop, int active );
+void skateshop_render( ent_skateshop *shop );
+void skateshop_render_nonfocused( world_instance *world, vg_camera *cam );
+void skateshop_autostart_loading(void);
+void skateshop_world_preupdate( world_instance *world );
+void ent_skateshop_call( world_instance *world, ent_call *call );
k_tornado_ratio = 0.5f,
k_tornado_range = 10.f;
-static void ent_tornado_init(void){
+void ent_tornado_init(void)
+{
vg_console_reg_var( "k_tonado_strength", &k_tornado_strength,
k_var_dtype_f32, VG_VAR_PERSISTENT|VG_VAR_CHEAT );
vg_console_reg_var( "k_tonado_ratio", &k_tornado_ratio,
k_var_dtype_f32, VG_VAR_PERSISTENT|VG_VAR_CHEAT );
}
-static void ent_tornado_debug(void) {
+void ent_tornado_debug(void)
+{
world_instance *world = world_current_instance();
for( u32 i=0; i<mdl_arrcount(&world->ent_marker); i ++ ){
ent_marker *marker = mdl_arritm( &world->ent_marker, i );
}
}
-static void ent_tornado_forces( v3f co, v3f cv, v3f out_a ){
+void ent_tornado_forces( v3f co, v3f cv, v3f out_a )
+{
world_instance *world = world_current_instance();
v3_zero( out_a );
}
}
-static void ent_tornado_pre_update(void){
+void ent_tornado_pre_update(void)
+{
world_instance *world = world_current_instance();
for( u32 i=0; i<mdl_arrcount(&world->ent_marker); i ++ ){
ent_marker *marker = mdl_arritm( &world->ent_marker, i );
--- /dev/null
+#pragma once
+
+void ent_tornado_init(void);
+void ent_tornado_debug(void);
+void ent_tornado_forces( v3f co, v3f cv, v3f out_a );
+void ent_tornado_pre_update(void);
-#ifndef ENT_TRAFFIC_C
-#define ENT_TRAFFIC_C
-
#include "world.h"
static void ent_traffic_update( world_instance *world, v3f pos ){
vg_line_point( traffic->transform.co, 0.3f, VG__BLUE );
}
}
-
-#endif /* ENT_TRAFFIC_C */
-#ifndef ENT_TRAFFIC_H
-#define ENT_TRAFFIC_H
-
+#pragma once
#include "world.h"
-static void ent_traffic_update( world_instance *world, v3f pos );
-
-#endif /* ENT_TRAFFIC_H */
+void ent_traffic_update( world_instance *world, v3f pos );
-#ifndef ENTITY_C
-#define ENTITY_C
-
#include "world.h"
#include "entity.h"
#include "world_entity.h"
-#include "ent_skateshop.c"
-#include "ent_objective.c"
-#include "ent_challenge.c"
-#include "ent_relay.c"
-#include "ent_route.c"
-#include "ent_miniworld.c"
-#include "ent_region.c"
-#include "ent_traffic.c"
-#include "ent_glider.c"
+#include "ent_objective.h"
+#include "ent_skateshop.h"
+#include "ent_relay.h"
+#include "ent_challenge.h"
+#include "ent_route.h"
+#include "ent_miniworld.h"
+#include "ent_region.h"
+#include "ent_glider.h"
typedef void (*fn_entity_call_handler)( world_instance *, ent_call *);
-static void entity_call( world_instance *world, ent_call *call ){
+void entity_call( world_instance *world, ent_call *call )
+{
u32 type = mdl_entity_id_type( call->id );
fn_entity_call_handler table[] = {
fn( world, call );
}
-#endif /* ENTITY_C */
+ent_marker *ent_find_marker( mdl_context *mdl, mdl_array_ptr *arr,
+ const char *alias )
+{
+ for( u32 i=0; i<mdl_arrcount(arr); i++ ){
+ ent_marker *marker = mdl_arritm( arr, i );
+
+ if( !strcmp( mdl_pstr( mdl, marker->pstr_alias ), alias ) ){
+ return marker;
+ }
+ }
+
+ return NULL;
+}
+
k_ent_glider = 26
};
-static u32 mdl_entity_id_type( u32 entity_id ){
+static inline u32 mdl_entity_id_type( u32 entity_id )
+{
return (entity_id & 0x0fff0000) >> 16;
}
-static u32 mdl_entity_id_id( u32 entity_id ){
+static inline u32 mdl_entity_id_id( u32 entity_id )
+{
return entity_id & 0x0000ffff;
}
-static u32 mdl_entity_id( u32 type, u32 index ){
+static inline u32 mdl_entity_id( u32 type, u32 index )
+{
return (type & 0xfffff)<<16 | (index & 0xfffff);
}
-enum entity_function{
+enum entity_function
+{
k_ent_function_trigger,
k_ent_function_particle_spawn,
k_ent_function_trigger_leave
u32 flags;
};
-static ent_marker *ent_find_marker( mdl_context *mdl,
- mdl_array_ptr *arr, const char *alias )
-{
- for( u32 i=0; i<mdl_arrcount(arr); i++ ){
- ent_marker *marker = mdl_arritm( arr, i );
-
- if( !strcmp( mdl_pstr( mdl, marker->pstr_alias ), alias ) ){
- return marker;
- }
- }
-
- return NULL;
-}
+ent_marker *ent_find_marker( mdl_context *mdl, mdl_array_ptr *arr,
+ const char *alias );
enum channel_behaviour{
k_channel_behaviour_unlimited = 0,
};
#include "world.h"
-static void entity_call( world_instance *world, ent_call *call );
+void entity_call( world_instance *world, ent_call *call );
-#ifndef FONT_H
-#define FONT_H
-
+#pragma once
#include "model.h"
#include "entity.h"
-#include "camera.h"
+#include "vg/vg_camera.h"
#include "shaders/model_font.h"
#include "shaders/scene_font.h"
#include "world_render.h"
mdl_close( &font->mdl );
}
-static void font3d_init(void){
- shader_model_font_register();
- shader_scene_font_register();
-}
-
static u32 font3d_find_variant( font3d *font, const char *name ){
for( u32 i=0; i<mdl_arrcount( &font->font_variants ); i ++ ){
ent_font_variant *variant = mdl_arritm( &font->font_variants, i );
*/
static void font3d_bind( font3d *font, enum font_shader shader,
int depth_compare, world_instance *world,
- camera *cam ){
+ vg_camera *cam ){
gui_font3d.shader = shader;
gui_font3d.font = font;
glActiveTexture( GL_TEXTURE1 );
}
static void font3d_set_transform( const char *text,
- camera *cam, m4x3f transform ){
+ vg_camera *cam, m4x3f transform ){
v4_copy( (v4f){0.0f,0.0f,0.0f,1.0f}, gui_font3d.offset );
m4x4f prev_mtx;
}
static f32 font3d_simple_draw( u32 variant_id, const char *text,
- camera *cam, m4x3f transform ){
+ vg_camera *cam, m4x3f transform ){
if( !text ) return 0.0f;
gui_font3d.variant_id = variant_id;
return width;
}
-
-#endif /* FONT_H */
#include "skaterift.h"
+#include "player_replay.h"
#include "input.h"
-static void freecam_preupdate(void){
- camera *cam = &skaterift.replay_freecam;
+void freecam_preupdate(void)
+{
+ vg_camera *cam = &player_replay.replay_freecam;
v3f angles;
v3_copy( cam->angles, angles );
player_look( angles, 1.0f );
v3f d;
v3_sub( angles, cam->angles, d );
- v3_muladds( skaterift.freecam_w, d, 20.0f, skaterift.freecam_w );
- v3_muls( skaterift.freecam_w, decay, skaterift.freecam_w );
- v3_muladds( cam->angles, skaterift.freecam_w, vg.time_frame_delta,
+ v3_muladds( player_replay.freecam_w, d, 20.0f, player_replay.freecam_w );
+ v3_muls( player_replay.freecam_w, decay, player_replay.freecam_w );
+ v3_muladds( cam->angles, player_replay.freecam_w, vg.time_frame_delta,
cam->angles );
cam->angles[1] = vg_clampf( cam->angles[1], -VG_PIf*0.5f,VG_PIf*0.5f);
- camera_update_transform( cam );
+ vg_camera_update_transform( cam );
v3f lookdir = { 0.0f, 0.0f, -1.0f },
sidedir = { 1.0f, 0.0f, 0.0f };
joystick_state( k_srjoystick_steer, input );
v2_muls( input, vg.time_frame_delta*6.0f*20.0f, input );
- v3_muladds( skaterift.freecam_v, lookdir, -input[1],
- skaterift.freecam_v );
- v3_muladds( skaterift.freecam_v, sidedir, input[0],
- skaterift.freecam_v );
+ v3_muladds( player_replay.freecam_v, lookdir, -input[1],
+ player_replay.freecam_v );
+ v3_muladds( player_replay.freecam_v, sidedir, input[0],
+ player_replay.freecam_v );
- v3_muls( skaterift.freecam_v, decay, skaterift.freecam_v );
+ v3_muls( player_replay.freecam_v, decay, player_replay.freecam_v );
v3_muladds( cam->pos,
- skaterift.freecam_v, vg.time_frame_delta, cam->pos );
+ player_replay.freecam_v, vg.time_frame_delta, cam->pos );
}
-static int freecam_cmd( int argc, const char *argv[] ){
+int freecam_cmd( int argc, const char *argv[] )
+{
if( argc ){
- skaterift.freecam = atoi(argv[0]);
+ player_replay.freecam = atoi(argv[0]);
- if( skaterift.freecam ){
- camera_copy( &skaterift.cam, &skaterift.replay_freecam );
+ if( player_replay.freecam ){
+ vg_camera_copy( &skaterift.cam, &player_replay.replay_freecam );
}
}
return 0;
-static void freecam_preupdate(void);
+#pragma once
+void freecam_preupdate(void);
+int freecam_cmd( int argc, const char *argv[] );
-#ifndef GUI_H
-#define GUI_H
-
+#pragma once
#include "font.h"
#include "input.h"
#include "player.h"
(v3_dist2(localplayer.rb.co,gui.trick_co) > 2.0f) )
gui_helper_clear();
- camera ortho;
+ vg_camera ortho;
float fl = 0.0f,
fr = vg.window_x,
ortho.mtx.p[3][1] = (ft + fb) * -tb;
ortho.mtx.p[3][3] = 1.0f;
m4x3_identity( ortho.transform );
- camera_update_view( &ortho );
+ vg_camera_update_view( &ortho );
m4x4_mul( ortho.mtx.p, ortho.mtx.v, ortho.mtx.pv ); /* HACK */
- camera_finalize( &ortho );
+ vg_camera_finalize( &ortho );
/* icons */
mdl_async_load_glmesh( &gui.model_icons, &gui.icons_mesh, NULL );
mdl_close( &gui.model_icons );
}
-
-#endif /* GUI_H */
--- /dev/null
+#pragma once
+#include "skaterift.h"
+#include "menu.h"
+#include "model.h"
+#include "entity.h"
+#include "input.h"
+#include "world_map.h"
+#include "ent_miniworld.h"
+#include "audio.h"
+#include "workshop.h"
+#include "gui.h"
+#include "shaders/model_menu.h"
+
+struct global_menu menu;
+
+/*
+ * Attaches memory locations to the various items in the menu
+ */
+void menu_link(void)
+{
+ /* link data locations */
+ for( u32 i=0; i<mdl_arrcount(&menu.items); i++ ){
+ ent_menuitem *item = mdl_arritm( &menu.items, i );
+
+ if( item->type == k_ent_menuitem_type_toggle ||
+ item->type == k_ent_menuitem_type_slider ){
+
+ const char *name;
+
+ if( item->type == k_ent_menuitem_type_slider )
+ name = mdl_pstr( &menu.model, item->slider.pstr_data );
+ else
+ name = mdl_pstr( &menu.model, item->checkmark.pstr_data );
+ vg_var *var = vg_console_match_var( name );
+
+ if( var ){
+ if( ( item->type == k_ent_menuitem_type_slider &&
+ var->data_type != k_var_dtype_f32
+ ) ||
+ ( item->type == k_ent_menuitem_type_toggle &&!
+ ( var->data_type == k_var_dtype_i32 ||
+ var->data_type == k_var_dtype_u32
+ )
+ )
+ ){
+ vg_error( "Cannot hook to data %s(%p), because it is type %d.\n",
+ name, var, var->data_type );
+ item->pvoid = NULL;
+ }
+ else{
+ item->pvoid = var->data;
+ }
+ }
+ else{
+ vg_error( "No data named %s\n", name );
+ item->pvoid = NULL;
+ }
+ }
+ else{
+ item->pvoid = NULL;
+ }
+ }
+
+ /* link controllers */
+ menu.ctr_deck = NULL;
+ menu.ctr_kbm = NULL;
+ menu.ctr_ps = NULL;
+ menu.ctr_steam = NULL;
+ menu.ctr_xbox = NULL;
+
+ for( u32 i=0; i<mdl_arrcount(&menu.items); i++ ){
+ ent_menuitem *item = mdl_arritm( &menu.items, i );
+
+ if( MDL_CONST_PSTREQ( &menu.model, item->visual.pstr_name, "deck" ) )
+ menu.ctr_deck = item;
+ if( MDL_CONST_PSTREQ( &menu.model, item->visual.pstr_name, "kbm" ) )
+ menu.ctr_kbm = item;
+ if( MDL_CONST_PSTREQ( &menu.model, item->visual.pstr_name, "ps" ) )
+ menu.ctr_ps = item;
+ if( MDL_CONST_PSTREQ( &menu.model, item->visual.pstr_name, "steam" ) )
+ menu.ctr_steam = item;
+ if( MDL_CONST_PSTREQ( &menu.model, item->visual.pstr_name, "xbox" ) )
+ menu.ctr_xbox = item;
+ }
+}
+
+void menu_close(void)
+{
+ skaterift.activity = k_skaterift_default;
+ menu.page_depth = 0;
+ menu.page = 0xffffffff;
+ srinput.state = k_input_state_resume;
+}
+
+void menu_init(void)
+{
+ void *alloc = vg_mem.rtmemory;
+
+ mdl_open( &menu.model, "models/rs_menu.mdl", alloc );
+ mdl_load_metadata_block( &menu.model, alloc );
+
+ vg_linear_clear( vg_mem.scratch );
+
+ MDL_LOAD_ARRAY( &menu.model, &menu.items, ent_menuitem, alloc );
+ MDL_LOAD_ARRAY( &menu.model, &menu.markers, ent_marker, alloc );
+ MDL_LOAD_ARRAY( &menu.model, &menu.cameras, ent_camera, alloc );
+
+ u32 count = mdl_arrcount( &menu.model.textures );
+ menu.textures = vg_linear_alloc(alloc,vg_align8(sizeof(GLuint)*(count+1)));
+ menu.textures[0] = vg.tex_missing;
+
+ mdl_async_load_glmesh( &menu.model, &menu.mesh, NULL );
+
+ for( u32 i=0; i<count; i ++ ){
+ vg_linear_clear( vg_mem.scratch );
+ menu.textures[i+1] = vg.tex_missing;
+
+ mdl_texture *tex = mdl_arritm( &menu.model.textures, i );
+ void *data = vg_linear_alloc( vg_mem.scratch, tex->file.pack_size );
+ mdl_fread_pack_file( &menu.model, &tex->file, data );
+ vg_tex2d_load_qoi_async( data, tex->file.pack_size,
+ VG_TEX2D_LINEAR|VG_TEX2D_CLAMP,
+ &menu.textures[i+1] );
+ }
+
+ mdl_close( &menu.model );
+}
+
+/*
+ * Drop back a page until we're at the bottom which then we jus quit
+ */
+static void menu_back_page(void){
+ menu.page_depth --;
+ if( menu.page_depth == 0 ){
+ menu_close();
+ }
+ else{
+ menu.page = menu.page_stack[ menu.page_depth ].page;
+ menu.cam = menu.page_stack[ menu.page_depth ].cam;
+
+ if( menu.input_mode == k_menu_input_mode_keys )
+ menu.loc = menu.page_stack[ menu.page_depth ].loc;
+ else menu.loc = NULL;
+ }
+}
+
+/*
+ * Open page to the string identifier
+ */
+void menu_open_page( const char *name,
+ enum ent_menuitem_stack_behaviour stackmode )
+{
+ srinput.state = k_input_state_resume;
+ if( stackmode == k_ent_menuitem_stack_append ){
+ if( menu.page_depth >= MENU_STACK_SIZE )
+ vg_fatal_error( "Stack overflow\n" );
+ }
+ else{
+ if( menu.page_depth == 0 )
+ vg_fatal_error( "Stack underflow\n" );
+ }
+
+ u32 hash = vg_strdjb2( name );
+ for( u32 i=0; i<mdl_arrcount(&menu.items); i++ ){
+ ent_menuitem *item = mdl_arritm( &menu.items, i );
+
+ if( item->type == k_ent_menuitem_type_page ){
+ if( mdl_pstreq( &menu.model, item->page.pstr_name, name, hash ) ){
+ u32 new_page = __builtin_ctz( item->groups );
+
+ if( new_page == menu.page ){
+ if( stackmode != k_ent_menuitem_stack_replace )
+ menu_back_page();
+ }
+ else{
+ menu.page_stack[ menu.page_depth ].page = menu.page;
+ menu.page_stack[ menu.page_depth ].cam = menu.cam;
+ menu.page_stack[ menu.page_depth ].loc = menu.loc;
+
+ if( stackmode == k_ent_menuitem_stack_append )
+ menu.page_depth ++;
+
+ menu.page = __builtin_ctz( item->groups );
+
+ if( menu.input_mode == k_menu_input_mode_keys ){
+ if( item->page.id_entrypoint ){
+ u32 id = mdl_entity_id_id( item->page.id_entrypoint );
+ menu.loc = mdl_arritm( &menu.items, id );
+ }
+ }
+
+ if( item->page.id_viewpoint ){
+ u32 id = mdl_entity_id_id( item->page.id_viewpoint );
+ menu.cam = mdl_arritm( &menu.cameras, id );
+ }
+ }
+ return;
+ }
+ }
+ }
+}
+
+/*
+ * activate a pressable type
+ */
+static void menu_trigger_item( ent_menuitem *item ){
+ if ( item->type == k_ent_menuitem_type_event_button ){
+ u32 q = item->button.pstr;
+
+ if( MDL_CONST_PSTREQ( &menu.model, q, "quit" ) ){
+ vg.window_should_close = 1;
+ }
+ else if( MDL_CONST_PSTREQ( &menu.model, q, "map" ) ){
+ menu_close();
+ world_map_enter();
+ }
+ else if( MDL_CONST_PSTREQ( &menu.model, q, "hub" ) ){
+ if( world_static.active_instance == k_world_purpose_client ){
+ menu_close();
+ ent_miniworld_goback();
+ }
+ }
+ else if( MDL_CONST_PSTREQ( &menu.model, q, "credits" ) ){
+ menu.credits_open = 1;
+ }
+ else if( MDL_CONST_PSTREQ( &menu.model, q, "workshop" ) ){
+ workshop_submit_command(0,NULL);
+ }
+ else if( MDL_CONST_PSTREQ( &menu.model, q, "engine" ) ){
+ vg_settings_open();
+ }
+ else if( MDL_CONST_PSTREQ( &menu.model, q, "prem_store" ) ){
+ if( steam_ready )
+ SteamAPI_ISteamFriends_ActivateGameOverlayToStore(
+ SteamAPI_SteamFriends(), 2103940, k_EOverlayToStoreFlag_None);
+ }
+ else if( MDL_CONST_PSTREQ( &menu.model, q, "prem_nevermind" ) ){
+ menu_close();
+ }
+ }
+ else if( item->type == k_ent_menuitem_type_page_button ){
+ menu_open_page( mdl_pstr( &menu.model, item->button.pstr ),
+ item->button.stack_behaviour );
+ }
+ else if( item->type == k_ent_menuitem_type_toggle ){
+ if( item->pi32 ){
+ *item->pi32 = *item->pi32 ^ 0x1;
+ }
+ }
+}
+
+static f32 menu_slider_snap( f32 value, f32 old, f32 notch ){
+ f32 const k_epsilon = 0.0125f;
+
+ if( fabsf(notch-value) < k_epsilon ){
+ if( fabsf(notch-old) > k_epsilon ){
+ audio_lock();
+ audio_oneshot( &audio_ui[0], 1.0f, 0.0f );
+ audio_unlock();
+ }
+
+ return notch;
+ }
+ else
+ return value;
+}
+
+static void menu_setitem_type( ent_menuitem *item,
+ enum ent_menuitem_type type ){
+ if( !item ) return;
+ item->type = type;
+}
+
+/*
+ * Run from vg_gui every frame
+ */
+void menu_update(void)
+{
+ if( workshop_form.page != k_workshop_form_hidden ){
+ return;
+ }
+
+ int escape = button_down( k_srbind_mback );
+ if( menu.credits_open || vg.settings_open ){
+ if( escape ){
+ menu.credits_open = 0;
+
+ if( vg.settings_open )
+ vg_settings_close();
+ }
+ return;
+ }
+
+ if( button_down( k_srbind_mopen ) ){
+ if( skaterift.activity == k_skaterift_default ){
+ skaterift.activity = k_skaterift_menu;
+ menu.page = 0xffffffff;
+ menu_open_page( "Main Menu", k_ent_menuitem_stack_append );
+ return;
+ }
+ }
+
+ if( skaterift.activity != k_skaterift_menu ) return;
+ enum menu_input_mode prev_mode = menu.input_mode;
+
+ /* get buttons inputs
+ * -------------------------------------------------------------------*/
+ int ml = button_down( k_srbind_mleft ),
+ mr = button_down( k_srbind_mright ),
+ mu = button_down( k_srbind_mup ),
+ md = button_down( k_srbind_mdown ),
+ mh = ml-mr,
+ mv = mu-md,
+ enter = button_down( k_srbind_maccept );
+
+ if( mh||mv||enter ){
+ menu.input_mode = k_menu_input_mode_keys;
+ }
+
+ /* get mouse inputs
+ * --------------------------------------------------------------------*/
+ menu.mouse_dist += v2_length( vg.mouse_delta ); /* TODO: Move to UI */
+ menu.mouse_track += vg.time_frame_delta;
+ if( menu.mouse_track > 0.1f ){
+ menu.mouse_track = fmodf( menu.mouse_track, 0.1f );
+ if( menu.mouse_dist > 10.0f ){
+ menu.input_mode = k_menu_input_mode_mouse;
+ menu.mouse_dist = 0.0f;
+ }
+ }
+
+ if( ui_clicking(UI_MOUSE_LEFT) || ui_clicking(UI_MOUSE_RIGHT) ){
+ menu.input_mode = k_menu_input_mode_mouse;
+ }
+
+ if( menu.input_mode == k_menu_input_mode_mouse ){
+ /*
+ * handle mouse input
+ * ------------------------------------------------------------*/
+ vg_ui.wants_mouse = 1;
+
+ /*
+ * this raycasting is super cumbersome because all the functions were
+ * designed for other purposes. we dont care though.
+ */
+ m4x4f inverse;
+ m4x4_inv( menu.view.mtx.p, inverse );
+ v4f coords;
+ coords[0] = vg_ui.mouse[0];
+ coords[1] = vg.window_y - vg_ui.mouse[1];
+ v2_div( coords, (v2f){ vg.window_x, vg.window_y }, coords );
+ v2_muls( coords, 2.0f, coords );
+ v2_add( coords, (v2f){-1.0f,-1.0f}, coords );
+ coords[2] = 1.0f;
+ coords[3] = 1.0f;
+ m4x4_mulv( inverse, coords, coords );
+ v3f ray;
+ m3x3_mulv( menu.view.transform, coords, ray );
+ v3_normalize( ray );
+
+ if( menu.loc && (menu.loc->type == k_ent_menuitem_type_slider) &&
+ ui_clicking(UI_MOUSE_LEFT) && menu.loc->pf32 ){
+
+ u32 il = mdl_entity_id_id( menu.loc->slider.id_min ),
+ ir = mdl_entity_id_id( menu.loc->slider.id_max );
+ ent_marker *ml = mdl_arritm( &menu.markers, il ),
+ *mr = mdl_arritm( &menu.markers, ir );
+
+ v3f q2;
+ v3_muladds( menu.view.pos, ray, 100.0f, q2 );
+
+ f32 s,t;
+ v3f c1, c2;
+ v3f p1, q1, v0;
+ v3_sub( mr->transform.co, ml->transform.co, v0 );
+ v3_muladds( ml->transform.co, v0, -1.0f, p1 );
+ v3_muladds( mr->transform.co, v0, 1.0f, q1 );
+ closest_segment_segment( p1, q1, menu.view.pos, q2, &s,&t, c1,c2 );
+
+ s-=(1.0f/3.0f);
+ s/=(1.0f/3.0f);
+
+ if( ui_click_down(UI_MOUSE_LEFT) ){
+ menu.slider_offset = *menu.loc->pf32 - s;
+ }
+
+ f32 newvalue = vg_clampf( s+menu.slider_offset, 0.0f, 1.0f );
+
+ newvalue = menu_slider_snap( newvalue, *menu.loc->pf32, 0.00f );
+ newvalue = menu_slider_snap( newvalue, *menu.loc->pf32, 1.00f );
+ newvalue = menu_slider_snap( newvalue, *menu.loc->pf32, 0.25f );
+ newvalue = menu_slider_snap( newvalue, *menu.loc->pf32, 0.50f );
+ newvalue = menu_slider_snap( newvalue, *menu.loc->pf32, 0.75f );
+
+ *menu.loc->pf32 = newvalue;
+ return;
+ }
+
+ ent_menuitem *hit_item = NULL;
+
+ for( u32 i=0; i<mdl_arrcount(&menu.items); i++ ){
+ ent_menuitem *item = mdl_arritm( &menu.items, i );
+
+ if( item->type == k_ent_menuitem_type_page ) continue;
+ if( (item->type == k_ent_menuitem_type_visual) ||
+ (item->type == k_ent_menuitem_type_visual_nocol) ) continue;
+ if( item->type == k_ent_menuitem_type_binding ) continue;
+ if( !(item->groups & (0x1<<menu.page)) ) continue;
+
+ ent_menuitem *ray_item = item;
+
+ if( item->type == k_ent_menuitem_type_slider ){
+ u32 subtarget = mdl_entity_id_id( item->slider.id_handle );
+ ray_item = mdl_arritm( &menu.items, subtarget );
+ }
+
+ v3f local_ray,
+ local_co;
+
+ m4x3f inverse_mtx;
+ mdl_transform_m4x3( &ray_item->transform, inverse_mtx );
+ m4x3_invert_full( inverse_mtx, inverse_mtx );
+
+ m4x3_mulv( inverse_mtx, menu.view.transform[3], local_co );
+ m3x3_mulv( inverse_mtx, ray, local_ray );
+ v3_normalize( local_ray );
+
+ local_ray[0] = 1.0f/local_ray[0];
+ local_ray[1] = 1.0f/local_ray[1];
+ local_ray[2] = 1.0f/local_ray[2];
+
+ for( u32 j=0; j<ray_item->submesh_count; j++ ){
+ mdl_submesh *sm = mdl_arritm( &menu.model.submeshs,
+ ray_item->submesh_start + j );
+ if( ray_aabb1( sm->bbx, local_co, local_ray, 1000.0f ) ){
+ hit_item = item;
+ break;
+ }
+ }
+ }
+
+ if( hit_item != menu.loc ){
+ menu.loc = hit_item;
+ }
+
+ if( escape ){
+ menu_back_page();
+ }
+ else if( menu.loc ){
+ if( ui_click_down( UI_MOUSE_LEFT ) ){
+ menu_trigger_item( menu.loc );
+ }
+ }
+ }
+ else if( menu.input_mode == k_menu_input_mode_keys ){
+ /*
+ * handle button input
+ * ------------------------------------------------------------*/
+ if( (prev_mode != k_menu_input_mode_keys) && !menu.loc ){
+ for( u32 i=0; i<mdl_arrcount(&menu.items); i++ ){
+ ent_menuitem *item = mdl_arritm( &menu.items, i );
+
+ if( (item->type != k_ent_menuitem_type_page) &&
+ (item->type != k_ent_menuitem_type_visual) &&
+ (item->type != k_ent_menuitem_type_visual_nocol) &&
+ (item->groups & (0x1<<menu.page)) ){
+ menu.loc = item;
+ }
+ }
+ }
+
+ if( !menu.loc ) vg_fatal_error( "No location\n" );
+
+ if( menu.loc->type == k_ent_menuitem_type_slider && menu.loc->pf32 ){
+ f32 move = 0.0f;
+
+ if( vg_input.display_input_method == k_input_method_controller ){
+ move += button_press( k_srbind_mright );
+ move -= button_press( k_srbind_mleft );
+ }
+ else{
+ move += axis_state( k_sraxis_mbrowse_h );
+ }
+
+ move *= vg.time_frame_delta;
+ *menu.loc->pf32 = vg_clampf( *menu.loc->pf32 + move, 0.0f, 1.0f );
+
+ mh = 0;
+ }
+
+ if( escape ){
+ menu_back_page();
+ }
+ else if( enter ){
+ menu_trigger_item( menu.loc );
+ }
+ else if( mh||mv ){
+ v3f opt;
+ v3_zero( opt );
+ f32 best = 0.707f;
+ ent_menuitem *nextpos = NULL;
+
+ opt[0] += mh;
+ opt[2] += mv;
+ mdl_transform_vector( &menu.cam->transform, opt, opt );
+
+ for( u32 i=0; i<4; i++ ){
+ u32 id = menu.loc->id_links[i];
+ if( !id ) continue;
+ u32 index = mdl_entity_id_id( id );
+
+ ent_menuitem *other = mdl_arritm( &menu.items, index );
+ v3f delta;
+ v3_sub( menu.loc->transform.co, other->transform.co, delta );
+ v3_normalize( delta );
+
+ f32 score = v3_dot( delta, opt );
+ if( score > best ){
+ best = score;
+ nextpos = other;
+ }
+ }
+
+ if( nextpos ){
+ menu.loc = nextpos;
+ }
+ }
+ }
+
+ menu_setitem_type( menu.ctr_deck, k_ent_menuitem_type_disabled );
+ menu_setitem_type( menu.ctr_ps, k_ent_menuitem_type_disabled );
+ menu_setitem_type( menu.ctr_kbm, k_ent_menuitem_type_disabled );
+ menu_setitem_type( menu.ctr_xbox, k_ent_menuitem_type_disabled );
+ menu_setitem_type( menu.ctr_steam, k_ent_menuitem_type_disabled );
+
+ if( vg_input.display_input_method == k_input_method_kbm )
+ menu_setitem_type( menu.ctr_kbm, k_ent_menuitem_type_visual_nocol );
+ else{
+ if( vg_input.display_input_type == SDL_CONTROLLER_TYPE_PS3 ||
+ vg_input.display_input_type == SDL_CONTROLLER_TYPE_PS4 ||
+ vg_input.display_input_type == SDL_CONTROLLER_TYPE_PS5 ){
+ menu_setitem_type( menu.ctr_ps, k_ent_menuitem_type_visual_nocol );
+ }
+ else {
+ menu_setitem_type( menu.ctr_xbox, k_ent_menuitem_type_visual_nocol );
+ }
+ /* FIXME: Steam/Deck controller detection? */
+ }
+}
+
+static void menu_binding_string( char buf[128], u32 pstr );
+
+/*
+ * Run from vg_gui when active
+ */
+void menu_render(void)
+{
+ glEnable(GL_BLEND);
+ glDisable(GL_DEPTH_TEST);
+ glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+ glBlendEquation(GL_FUNC_ADD);
+
+ shader_blitcolour_use();
+ v4f colour;
+ ui_hex_to_norm( ui_colour( k_ui_bg+3 ), colour );
+ colour[3] = 0.5f;
+
+ shader_blitcolour_uColour( colour );
+ render_fsquad();
+
+ if( (workshop_form.page != k_workshop_form_hidden) ||
+ (vg_ui.focused_control_type != k_ui_control_none) ){
+ return;
+ }
+
+ if( vg.settings_open )
+ return;
+
+ if( menu.credits_open ){
+ ui_rect panel = { 0,0, 460, 400 },
+ screen = { 0,0, vg.window_x,vg.window_y };
+ ui_rect_center( screen, panel );
+ ui_fill( panel, ui_colour(k_ui_bg) );
+ ui_outline( panel, 1, ui_colour(k_ui_fg), 0 );
+ ui_rect_pad( panel, (ui_px[]){8,8} );
+
+ ui_rect title;
+ ui_split( panel, k_ui_axis_h, 28*2, 0, title, panel );
+ ui_text( title, "Skate Rift - Credits", 2, k_ui_align_middle_center, 0 );
+ ui_split( panel, k_ui_axis_h, 28, 0, title, panel );
+ ui_text( title, "Mt.Zero Software", 1, k_ui_align_middle_center, 0 );
+
+ ui_split( panel, k_ui_axis_h, 8, 0, title, panel );
+ ui_split( panel, k_ui_axis_h, 28*2, 0, title, panel );
+ ui_text( title, "Free Software", 2, k_ui_align_middle_center, 0 );
+
+ ui_split( panel, k_ui_axis_h, 8, 0, title, panel );
+ ui_text( panel,
+ "Sam Lantinga - SDL2 - libsdl.org\n"
+ "Hunter WB - Anyascii\n"
+ "David Herberth - GLAD\n"
+ "Dominic Szablewski - QOI - qoiformat.org\n"
+ "Sean Barrett - stb_image,stb_vorbis,stb_include\n"
+ "Khronos Group - OpenGL\n"
+ , 1, k_ui_align_left, 0 );
+ return;
+ }
+
+ glEnable( GL_DEPTH_TEST );
+ glDisable( GL_BLEND );
+
+ f32 rate = vg.time_frame_delta * 12.0f;
+
+ if( menu.cam ){
+ vg_camera target;
+
+ target.fov = menu.cam->fov;
+ v3_copy( menu.cam->transform.co, target.pos );
+
+ v3f v0;
+ mdl_transform_vector( &menu.cam->transform, (v3f){0.0f,-1.0f,0.0f}, v0 );
+ v3_angles( v0, target.angles );
+
+ vg_camera_lerp( &menu.view, &target, rate, &menu.view );
+
+ menu.view.farz = 150.0f;
+ menu.view.nearz = 0.01f;
+
+ vg_camera_update_transform( &menu.view );
+ vg_camera_update_view( &menu.view );
+ vg_camera_update_projection( &menu.view );
+ vg_camera_finalize( &menu.view );
+ }
+ else return;
+
+ shader_model_menu_use();
+ shader_model_menu_uTexMain( 1 );
+ shader_model_menu_uPv( menu.view.mtx.pv );
+ shader_model_menu_uPvmPrev( menu.view.mtx_prev.pv );
+
+ mesh_bind( &menu.mesh );
+
+ v4f white, blue;
+
+ ui_hex_to_norm( ui_colour( k_ui_fg ), white );
+ ui_hex_to_norm( ui_colour( k_ui_orange+k_ui_brighter ), blue );
+
+ ent_menuitem *text_list[ 8 ];
+ u32 text_count = 0;
+
+ u32 current_tex = 0xffffffff;
+
+ for( u32 i=0; i<mdl_arrcount(&menu.items); i++ ){
+ ent_menuitem *item = mdl_arritm( &menu.items, i );
+
+ if( item->type == k_ent_menuitem_type_disabled ) continue;
+ if( item->type == k_ent_menuitem_type_page ) continue;
+ if( !(item->groups & (0x1 << menu.page)) ) continue;
+
+ if( item->type == k_ent_menuitem_type_binding ){
+ if( text_count < vg_list_size(text_list) )
+ text_list[ text_count ++ ] = item;
+ else
+ vg_fatal_error( "Text list overflow" );
+
+ continue;
+ }
+
+ int selected = 0;
+
+ if( menu.loc ){
+ if( menu.loc->type == k_ent_menuitem_type_slider ){
+ u32 subid = menu.loc->slider.id_handle;
+ if( item == mdl_arritm( &menu.items, mdl_entity_id_id(subid) ))
+ selected = 1;
+ }
+ else{
+ if( item == menu.loc )
+ selected = 1;
+ }
+ }
+
+ if( item->type == k_ent_menuitem_type_visual_nocol ){
+ shader_model_menu_uColour( (v4f){1.0f,1.0f,1.0f,1.0f} );
+ }
+ else{
+ v4f colour;
+ item->factive = vg_lerpf( item->factive, selected, rate );
+ v4_lerp( white, blue, item->factive, colour );
+ shader_model_menu_uColour( colour );
+ }
+
+ f32 scale = 1.0f+item->factive*0.1f;
+
+ m4x3f mmdl;
+ mdl_transform transform = item->transform;
+ v3_muls( transform.s, scale, transform.s );
+ mdl_transform_m4x3( &transform, mmdl );
+
+ if( item->type == k_ent_menuitem_type_toggle && item->pi32 ){
+ u32 subid = mdl_entity_id_id( item->checkmark.id_check );
+ ent_menuitem *subitem = mdl_arritm( &menu.items, subid );
+
+ v3_muladds( item->transform.co, item->checkmark.offset, scale,
+ subitem->transform.co );
+
+ subitem->fvisible = vg_lerpf( subitem->fvisible, *item->pi32, rate );
+ v3_fill( subitem->transform.s, subitem->fvisible );
+ }
+ else if( item->type == k_ent_menuitem_type_slider && item->pf32 ){
+ u32 il = mdl_entity_id_id( item->slider.id_min ),
+ ir = mdl_entity_id_id( item->slider.id_max ),
+ ih = mdl_entity_id_id( item->slider.id_handle );
+ ent_marker *ml = mdl_arritm( &menu.markers, il ),
+ *mr = mdl_arritm( &menu.markers, ir );
+ ent_menuitem *handle = mdl_arritm( &menu.items, ih );
+
+ v3_lerp( ml->transform.co, mr->transform.co, *item->pf32,
+ handle->transform.co );
+ }
+
+ shader_model_menu_uMdl( mmdl );
+
+ for( u32 j=0; j<item->submesh_count; j++ ){
+ u32 index = item->submesh_start + j;
+ mdl_submesh *sm = mdl_arritm( &menu.model.submeshs, index );
+
+ mdl_material *mat = mdl_arritm( &menu.model.materials,
+ sm->material_id-1 );
+
+ if( mat->tex_diffuse != current_tex ){
+ glActiveTexture( GL_TEXTURE1 );
+ glBindTexture( GL_TEXTURE_2D, menu.textures[ mat->tex_diffuse ] );
+ current_tex = mat->tex_diffuse;
+ }
+
+ mdl_draw_submesh( sm );
+ }
+ }
+
+ if( !text_count ) return;
+
+ char buf[ 128 ];
+
+ m4x3f local;
+ m4x3_identity( local );
+
+ font3d_bind( &gui.font, k_font_shader_default, 0, NULL, &menu.view );
+ for( u32 i=0; i<text_count; i++ ){
+ ent_menuitem *item = text_list[ i ];
+ m4x3f transform;
+ mdl_transform_m4x3( &item->transform, transform );
+
+ u32 variant = item->binding.font_variant;
+ menu_binding_string( buf, item->binding.pstr_bind );
+ f32 offset = font3d_string_width( variant, buf );
+
+ local[3][0] = -0.5f * offset;
+ m4x3_mul( transform, local, transform );
+
+ font3d_simple_draw( variant, buf, &menu.view, transform );
+ }
+}
+
+static void menu_binding_string( char buf[128], u32 pstr ){
+ vg_str str;
+ vg_strnull( &str, buf, 128 );
+
+ if( MDL_CONST_PSTREQ( &menu.model, pstr, "bind_jump" ) ){
+ vg_input_string( &str, input_button_list[k_srbind_jump], 1 );
+ }
+ else if( MDL_CONST_PSTREQ( &menu.model, pstr, "bind_trick0" ) ){
+ vg_strcat( &str, "SHUVIT " );
+ vg_input_string( &str, input_button_list[k_srbind_trick0], 1 );
+ }
+ else if( MDL_CONST_PSTREQ( &menu.model, pstr, "bind_trick1" ) ){
+ vg_strcat( &str, "KICKFLIP " );
+ vg_input_string( &str, input_button_list[k_srbind_trick1], 1 );
+ }
+ else if( MDL_CONST_PSTREQ( &menu.model, pstr, "bind_trick2" ) ){
+ vg_strcat( &str, "TREFLIP " );
+ vg_input_string( &str, input_button_list[k_srbind_trick2], 1 );
+ }
+ else if( MDL_CONST_PSTREQ( &menu.model, pstr, "bind_grab" ) ){
+ vg_input_string( &str, input_axis_list[k_sraxis_grab], 1 );
+ }
+ else if( MDL_CONST_PSTREQ( &menu.model, pstr, "bind_grab_mod" ) ){
+ vg_input_string( &str, input_joy_list[k_srjoystick_grab], 1 );
+ }
+ else
+ vg_strcat( &str, "error" );
+}
#pragma once
-#include "model.h"
-#include "world_render.h"
-#include "player.h"
-#include "shaders/model_menu.h"
-#include "audio.h"
-#include "input.h"
-#include "workshop.h"
-#include "world_map.h"
-#include "gui.h"
-#include "ent_miniworld.h"
-
#define MENU_STACK_SIZE 8
-struct {
+#include "vg/vg_engine.h"
+#include "entity.h"
+
+struct global_menu
+{
int credits_open;
int disable_open;
ent_menuitem *loc;
ent_camera *cam;
- camera view;
+ vg_camera view;
mdl_context model;
GLuint *textures;
mdl_array_ptr items, markers, cameras;
}
-static menu;
-
-/*
- * Attaches memory locations to the various items in the menu
- */
-static void menu_link(void){
- /* link data locations */
- for( u32 i=0; i<mdl_arrcount(&menu.items); i++ ){
- ent_menuitem *item = mdl_arritm( &menu.items, i );
-
- if( item->type == k_ent_menuitem_type_toggle ||
- item->type == k_ent_menuitem_type_slider ){
-
- const char *name;
-
- if( item->type == k_ent_menuitem_type_slider )
- name = mdl_pstr( &menu.model, item->slider.pstr_data );
- else
- name = mdl_pstr( &menu.model, item->checkmark.pstr_data );
- vg_var *var = vg_console_match_var( name );
-
- if( var ){
- if( ( item->type == k_ent_menuitem_type_slider &&
- var->data_type != k_var_dtype_f32
- ) ||
- ( item->type == k_ent_menuitem_type_toggle &&!
- ( var->data_type == k_var_dtype_i32 ||
- var->data_type == k_var_dtype_u32
- )
- )
- ){
- vg_error( "Cannot hook to data %s(%p), because it is type %d.\n",
- name, var, var->data_type );
- item->pvoid = NULL;
- }
- else{
- item->pvoid = var->data;
- }
- }
- else{
- vg_error( "No data named %s\n", name );
- item->pvoid = NULL;
- }
- }
- else{
- item->pvoid = NULL;
- }
- }
-
- /* link controllers */
- menu.ctr_deck = NULL;
- menu.ctr_kbm = NULL;
- menu.ctr_ps = NULL;
- menu.ctr_steam = NULL;
- menu.ctr_xbox = NULL;
-
- for( u32 i=0; i<mdl_arrcount(&menu.items); i++ ){
- ent_menuitem *item = mdl_arritm( &menu.items, i );
-
- if( MDL_CONST_PSTREQ( &menu.model, item->visual.pstr_name, "deck" ) )
- menu.ctr_deck = item;
- if( MDL_CONST_PSTREQ( &menu.model, item->visual.pstr_name, "kbm" ) )
- menu.ctr_kbm = item;
- if( MDL_CONST_PSTREQ( &menu.model, item->visual.pstr_name, "ps" ) )
- menu.ctr_ps = item;
- if( MDL_CONST_PSTREQ( &menu.model, item->visual.pstr_name, "steam" ) )
- menu.ctr_steam = item;
- if( MDL_CONST_PSTREQ( &menu.model, item->visual.pstr_name, "xbox" ) )
- menu.ctr_xbox = item;
- }
-}
-
-static void menu_close(void){
- skaterift.activity = k_skaterift_default;
- menu.page_depth = 0;
- menu.page = 0xffffffff;
- srinput.state = k_input_state_resume;
-}
-
-static void menu_init(void){
- void *alloc = vg_mem.rtmemory;
-
- mdl_open( &menu.model, "models/rs_menu.mdl", alloc );
- mdl_load_metadata_block( &menu.model, alloc );
-
- vg_linear_clear( vg_mem.scratch );
-
- MDL_LOAD_ARRAY( &menu.model, &menu.items, ent_menuitem, alloc );
- MDL_LOAD_ARRAY( &menu.model, &menu.markers, ent_marker, alloc );
- MDL_LOAD_ARRAY( &menu.model, &menu.cameras, ent_camera, alloc );
-
- u32 count = mdl_arrcount( &menu.model.textures );
- menu.textures = vg_linear_alloc(alloc,vg_align8(sizeof(GLuint)*(count+1)));
- menu.textures[0] = vg.tex_missing;
-
- mdl_async_load_glmesh( &menu.model, &menu.mesh, NULL );
-
- for( u32 i=0; i<count; i ++ ){
- vg_linear_clear( vg_mem.scratch );
- menu.textures[i+1] = vg.tex_missing;
-
- mdl_texture *tex = mdl_arritm( &menu.model.textures, i );
- void *data = vg_linear_alloc( vg_mem.scratch, tex->file.pack_size );
- mdl_fread_pack_file( &menu.model, &tex->file, data );
- vg_tex2d_load_qoi_async( data, tex->file.pack_size,
- VG_TEX2D_LINEAR|VG_TEX2D_CLAMP,
- &menu.textures[i+1] );
- }
-
- mdl_close( &menu.model );
- shader_model_menu_register();
-}
-
-/*
- * Drop back a page until we're at the bottom which then we jus quit
- */
-static void menu_back_page(void){
- menu.page_depth --;
- if( menu.page_depth == 0 ){
- menu_close();
- }
- else{
- menu.page = menu.page_stack[ menu.page_depth ].page;
- menu.cam = menu.page_stack[ menu.page_depth ].cam;
-
- if( menu.input_mode == k_menu_input_mode_keys )
- menu.loc = menu.page_stack[ menu.page_depth ].loc;
- else menu.loc = NULL;
- }
-}
-
-/*
- * Open page to the string identifier
- */
-static void menu_open_page( const char *name,
- enum ent_menuitem_stack_behaviour stackmode ){
- srinput.state = k_input_state_resume;
- if( stackmode == k_ent_menuitem_stack_append ){
- if( menu.page_depth >= MENU_STACK_SIZE )
- vg_fatal_error( "Stack overflow\n" );
- }
- else{
- if( menu.page_depth == 0 )
- vg_fatal_error( "Stack underflow\n" );
- }
-
- u32 hash = vg_strdjb2( name );
- for( u32 i=0; i<mdl_arrcount(&menu.items); i++ ){
- ent_menuitem *item = mdl_arritm( &menu.items, i );
-
- if( item->type == k_ent_menuitem_type_page ){
- if( mdl_pstreq( &menu.model, item->page.pstr_name, name, hash ) ){
- u32 new_page = __builtin_ctz( item->groups );
-
- if( new_page == menu.page ){
- if( stackmode != k_ent_menuitem_stack_replace )
- menu_back_page();
- }
- else{
- menu.page_stack[ menu.page_depth ].page = menu.page;
- menu.page_stack[ menu.page_depth ].cam = menu.cam;
- menu.page_stack[ menu.page_depth ].loc = menu.loc;
-
- if( stackmode == k_ent_menuitem_stack_append )
- menu.page_depth ++;
-
- menu.page = __builtin_ctz( item->groups );
-
- if( menu.input_mode == k_menu_input_mode_keys ){
- if( item->page.id_entrypoint ){
- u32 id = mdl_entity_id_id( item->page.id_entrypoint );
- menu.loc = mdl_arritm( &menu.items, id );
- }
- }
-
- if( item->page.id_viewpoint ){
- u32 id = mdl_entity_id_id( item->page.id_viewpoint );
- menu.cam = mdl_arritm( &menu.cameras, id );
- }
- }
- return;
- }
- }
- }
-}
-
-/*
- * activate a pressable type
- */
-static void menu_trigger_item( ent_menuitem *item ){
- if ( item->type == k_ent_menuitem_type_event_button ){
- u32 q = item->button.pstr;
-
- if( MDL_CONST_PSTREQ( &menu.model, q, "quit" ) ){
- vg.window_should_close = 1;
- }
- else if( MDL_CONST_PSTREQ( &menu.model, q, "map" ) ){
- menu_close();
- world_map_enter();
- }
- else if( MDL_CONST_PSTREQ( &menu.model, q, "hub" ) ){
- if( world_static.active_instance == k_world_purpose_client ){
- menu_close();
- ent_miniworld_goback();
- }
- }
- else if( MDL_CONST_PSTREQ( &menu.model, q, "credits" ) ){
- menu.credits_open = 1;
- }
- else if( MDL_CONST_PSTREQ( &menu.model, q, "workshop" ) ){
- workshop_submit_command(0,NULL);
- }
- else if( MDL_CONST_PSTREQ( &menu.model, q, "engine" ) ){
- vg_settings_open();
- }
- else if( MDL_CONST_PSTREQ( &menu.model, q, "prem_store" ) ){
- if( steam_ready )
- SteamAPI_ISteamFriends_ActivateGameOverlayToStore(
- SteamAPI_SteamFriends(), 2103940, k_EOverlayToStoreFlag_None);
- }
- else if( MDL_CONST_PSTREQ( &menu.model, q, "prem_nevermind" ) ){
- menu_close();
- }
- }
- else if( item->type == k_ent_menuitem_type_page_button ){
- menu_open_page( mdl_pstr( &menu.model, item->button.pstr ),
- item->button.stack_behaviour );
- }
- else if( item->type == k_ent_menuitem_type_toggle ){
- if( item->pi32 ){
- *item->pi32 = *item->pi32 ^ 0x1;
- }
- }
-}
-
-static f32 menu_slider_snap( f32 value, f32 old, f32 notch ){
- f32 const k_epsilon = 0.0125f;
-
- if( fabsf(notch-value) < k_epsilon ){
- if( fabsf(notch-old) > k_epsilon ){
- audio_lock();
- audio_oneshot( &audio_ui[0], 1.0f, 0.0f );
- audio_unlock();
- }
-
- return notch;
- }
- else
- return value;
-}
-
-static void menu_setitem_type( ent_menuitem *item,
- enum ent_menuitem_type type ){
- if( !item ) return;
- item->type = type;
-}
-
-/*
- * Run from vg_gui every frame
- */
-static void menu_update(void){
- if( workshop_form.page != k_workshop_form_hidden ){
- return;
- }
-
- int escape = button_down( k_srbind_mback );
- if( menu.credits_open || vg.settings_open ){
- if( escape ){
- menu.credits_open = 0;
-
- if( vg.settings_open )
- vg_settings_close();
- }
- return;
- }
-
- if( button_down( k_srbind_mopen ) ){
- if( skaterift.activity == k_skaterift_default ){
- skaterift.activity = k_skaterift_menu;
- menu.page = 0xffffffff;
- menu_open_page( "Main Menu", k_ent_menuitem_stack_append );
- return;
- }
- }
-
- if( skaterift.activity != k_skaterift_menu ) return;
- enum menu_input_mode prev_mode = menu.input_mode;
-
- /* get buttons inputs
- * -------------------------------------------------------------------*/
- int ml = button_down( k_srbind_mleft ),
- mr = button_down( k_srbind_mright ),
- mu = button_down( k_srbind_mup ),
- md = button_down( k_srbind_mdown ),
- mh = ml-mr,
- mv = mu-md,
- enter = button_down( k_srbind_maccept );
-
- if( mh||mv||enter ){
- menu.input_mode = k_menu_input_mode_keys;
- }
-
- /* get mouse inputs
- * --------------------------------------------------------------------*/
- menu.mouse_dist += v2_length( vg.mouse_delta ); /* TODO: Move to UI */
- menu.mouse_track += vg.time_frame_delta;
- if( menu.mouse_track > 0.1f ){
- menu.mouse_track = fmodf( menu.mouse_track, 0.1f );
- if( menu.mouse_dist > 10.0f ){
- menu.input_mode = k_menu_input_mode_mouse;
- menu.mouse_dist = 0.0f;
- }
- }
-
- if( ui_clicking(UI_MOUSE_LEFT) || ui_clicking(UI_MOUSE_RIGHT) ){
- menu.input_mode = k_menu_input_mode_mouse;
- }
-
- if( menu.input_mode == k_menu_input_mode_mouse ){
- /*
- * handle mouse input
- * ------------------------------------------------------------*/
- vg_ui.wants_mouse = 1;
-
- /*
- * this raycasting is super cumbersome because all the functions were
- * designed for other purposes. we dont care though.
- */
- m4x4f inverse;
- m4x4_inv( menu.view.mtx.p, inverse );
- v4f coords;
- coords[0] = vg_ui.mouse[0];
- coords[1] = vg.window_y - vg_ui.mouse[1];
- v2_div( coords, (v2f){ vg.window_x, vg.window_y }, coords );
- v2_muls( coords, 2.0f, coords );
- v2_add( coords, (v2f){-1.0f,-1.0f}, coords );
- coords[2] = 1.0f;
- coords[3] = 1.0f;
- m4x4_mulv( inverse, coords, coords );
- v3f ray;
- m3x3_mulv( menu.view.transform, coords, ray );
- v3_normalize( ray );
-
- if( menu.loc && (menu.loc->type == k_ent_menuitem_type_slider) &&
- ui_clicking(UI_MOUSE_LEFT) && menu.loc->pf32 ){
-
- u32 il = mdl_entity_id_id( menu.loc->slider.id_min ),
- ir = mdl_entity_id_id( menu.loc->slider.id_max );
- ent_marker *ml = mdl_arritm( &menu.markers, il ),
- *mr = mdl_arritm( &menu.markers, ir );
-
- v3f q2;
- v3_muladds( menu.view.pos, ray, 100.0f, q2 );
-
- f32 s,t;
- v3f c1, c2;
- v3f p1, q1, v0;
- v3_sub( mr->transform.co, ml->transform.co, v0 );
- v3_muladds( ml->transform.co, v0, -1.0f, p1 );
- v3_muladds( mr->transform.co, v0, 1.0f, q1 );
- closest_segment_segment( p1, q1, menu.view.pos, q2, &s,&t, c1,c2 );
-
- s-=(1.0f/3.0f);
- s/=(1.0f/3.0f);
-
- if( ui_click_down(UI_MOUSE_LEFT) ){
- menu.slider_offset = *menu.loc->pf32 - s;
- }
-
- f32 newvalue = vg_clampf( s+menu.slider_offset, 0.0f, 1.0f );
-
- newvalue = menu_slider_snap( newvalue, *menu.loc->pf32, 0.00f );
- newvalue = menu_slider_snap( newvalue, *menu.loc->pf32, 1.00f );
- newvalue = menu_slider_snap( newvalue, *menu.loc->pf32, 0.25f );
- newvalue = menu_slider_snap( newvalue, *menu.loc->pf32, 0.50f );
- newvalue = menu_slider_snap( newvalue, *menu.loc->pf32, 0.75f );
-
- *menu.loc->pf32 = newvalue;
- return;
- }
-
- ent_menuitem *hit_item = NULL;
-
- for( u32 i=0; i<mdl_arrcount(&menu.items); i++ ){
- ent_menuitem *item = mdl_arritm( &menu.items, i );
-
- if( item->type == k_ent_menuitem_type_page ) continue;
- if( (item->type == k_ent_menuitem_type_visual) ||
- (item->type == k_ent_menuitem_type_visual_nocol) ) continue;
- if( item->type == k_ent_menuitem_type_binding ) continue;
- if( !(item->groups & (0x1<<menu.page)) ) continue;
-
- ent_menuitem *ray_item = item;
-
- if( item->type == k_ent_menuitem_type_slider ){
- u32 subtarget = mdl_entity_id_id( item->slider.id_handle );
- ray_item = mdl_arritm( &menu.items, subtarget );
- }
-
- v3f local_ray,
- local_co;
-
- m4x3f inverse_mtx;
- mdl_transform_m4x3( &ray_item->transform, inverse_mtx );
- m4x3_invert_full( inverse_mtx, inverse_mtx );
-
- m4x3_mulv( inverse_mtx, menu.view.transform[3], local_co );
- m3x3_mulv( inverse_mtx, ray, local_ray );
- v3_normalize( local_ray );
-
- local_ray[0] = 1.0f/local_ray[0];
- local_ray[1] = 1.0f/local_ray[1];
- local_ray[2] = 1.0f/local_ray[2];
-
- for( u32 j=0; j<ray_item->submesh_count; j++ ){
- mdl_submesh *sm = mdl_arritm( &menu.model.submeshs,
- ray_item->submesh_start + j );
- if( ray_aabb1( sm->bbx, local_co, local_ray, 1000.0f ) ){
- hit_item = item;
- break;
- }
- }
- }
-
- if( hit_item != menu.loc ){
- menu.loc = hit_item;
- }
-
- if( escape ){
- menu_back_page();
- }
- else if( menu.loc ){
- if( ui_click_down( UI_MOUSE_LEFT ) ){
- menu_trigger_item( menu.loc );
- }
- }
- }
- else if( menu.input_mode == k_menu_input_mode_keys ){
- /*
- * handle button input
- * ------------------------------------------------------------*/
- if( (prev_mode != k_menu_input_mode_keys) && !menu.loc ){
- for( u32 i=0; i<mdl_arrcount(&menu.items); i++ ){
- ent_menuitem *item = mdl_arritm( &menu.items, i );
-
- if( (item->type != k_ent_menuitem_type_page) &&
- (item->type != k_ent_menuitem_type_visual) &&
- (item->type != k_ent_menuitem_type_visual_nocol) &&
- (item->groups & (0x1<<menu.page)) ){
- menu.loc = item;
- }
- }
- }
-
- if( !menu.loc ) vg_fatal_error( "No location\n" );
-
- if( menu.loc->type == k_ent_menuitem_type_slider && menu.loc->pf32 ){
- f32 move = 0.0f;
-
- if( vg_input.display_input_method == k_input_method_controller ){
- move += button_press( k_srbind_mright );
- move -= button_press( k_srbind_mleft );
- }
- else{
- move += axis_state( k_sraxis_mbrowse_h );
- }
-
- move *= vg.time_frame_delta;
- *menu.loc->pf32 = vg_clampf( *menu.loc->pf32 + move, 0.0f, 1.0f );
-
- mh = 0;
- }
-
- if( escape ){
- menu_back_page();
- }
- else if( enter ){
- menu_trigger_item( menu.loc );
- }
- else if( mh||mv ){
- v3f opt;
- v3_zero( opt );
- f32 best = 0.707f;
- ent_menuitem *nextpos = NULL;
-
- opt[0] += mh;
- opt[2] += mv;
- mdl_transform_vector( &menu.cam->transform, opt, opt );
-
- for( u32 i=0; i<4; i++ ){
- u32 id = menu.loc->id_links[i];
- if( !id ) continue;
- u32 index = mdl_entity_id_id( id );
-
- ent_menuitem *other = mdl_arritm( &menu.items, index );
- v3f delta;
- v3_sub( menu.loc->transform.co, other->transform.co, delta );
- v3_normalize( delta );
-
- f32 score = v3_dot( delta, opt );
- if( score > best ){
- best = score;
- nextpos = other;
- }
- }
-
- if( nextpos ){
- menu.loc = nextpos;
- }
- }
- }
-
- menu_setitem_type( menu.ctr_deck, k_ent_menuitem_type_disabled );
- menu_setitem_type( menu.ctr_ps, k_ent_menuitem_type_disabled );
- menu_setitem_type( menu.ctr_kbm, k_ent_menuitem_type_disabled );
- menu_setitem_type( menu.ctr_xbox, k_ent_menuitem_type_disabled );
- menu_setitem_type( menu.ctr_steam, k_ent_menuitem_type_disabled );
-
- if( vg_input.display_input_method == k_input_method_kbm )
- menu_setitem_type( menu.ctr_kbm, k_ent_menuitem_type_visual_nocol );
- else{
- if( vg_input.display_input_type == SDL_CONTROLLER_TYPE_PS3 ||
- vg_input.display_input_type == SDL_CONTROLLER_TYPE_PS4 ||
- vg_input.display_input_type == SDL_CONTROLLER_TYPE_PS5 ){
- menu_setitem_type( menu.ctr_ps, k_ent_menuitem_type_visual_nocol );
- }
- else {
- menu_setitem_type( menu.ctr_xbox, k_ent_menuitem_type_visual_nocol );
- }
- /* FIXME: Steam/Deck controller detection? */
- }
-}
-
-static void menu_binding_string( char buf[128], u32 pstr );
-
-/*
- * Run from vg_gui when active
- */
-static void menu_render(void){
- glEnable(GL_BLEND);
- glDisable(GL_DEPTH_TEST);
- glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
- glBlendEquation(GL_FUNC_ADD);
-
- shader_blitcolour_use();
- v4f colour;
- ui_hex_to_norm( ui_colour( k_ui_bg+3 ), colour );
- colour[3] = 0.5f;
-
- shader_blitcolour_uColour( colour );
- render_fsquad();
-
- if( (workshop_form.page != k_workshop_form_hidden) ||
- (vg_ui.focused_control_type != k_ui_control_none) ){
- return;
- }
-
- if( vg.settings_open )
- return;
-
- if( menu.credits_open ){
- ui_rect panel = { 0,0, 460, 400 },
- screen = { 0,0, vg.window_x,vg.window_y };
- ui_rect_center( screen, panel );
- ui_fill( panel, ui_colour(k_ui_bg) );
- ui_outline( panel, 1, ui_colour(k_ui_fg), 0 );
- ui_rect_pad( panel, (ui_px[]){8,8} );
-
- ui_rect title;
- ui_split( panel, k_ui_axis_h, 28*2, 0, title, panel );
- ui_text( title, "Skate Rift - Credits", 2, k_ui_align_middle_center, 0 );
- ui_split( panel, k_ui_axis_h, 28, 0, title, panel );
- ui_text( title, "Mt.Zero Software", 1, k_ui_align_middle_center, 0 );
-
- ui_split( panel, k_ui_axis_h, 8, 0, title, panel );
- ui_split( panel, k_ui_axis_h, 28*2, 0, title, panel );
- ui_text( title, "Free Software", 2, k_ui_align_middle_center, 0 );
-
- ui_split( panel, k_ui_axis_h, 8, 0, title, panel );
- ui_text( panel,
- "Sam Lantinga - SDL2 - libsdl.org\n"
- "Hunter WB - Anyascii\n"
- "David Herberth - GLAD\n"
- "Dominic Szablewski - QOI - qoiformat.org\n"
- "Sean Barrett - stb_image,stb_vorbis,stb_include\n"
- "Khronos Group - OpenGL\n"
- , 1, k_ui_align_left, 0 );
- return;
- }
-
- glEnable( GL_DEPTH_TEST );
- glDisable( GL_BLEND );
-
- f32 rate = vg.time_frame_delta * 12.0f;
-
- if( menu.cam ){
- camera target;
-
- target.fov = menu.cam->fov;
- v3_copy( menu.cam->transform.co, target.pos );
-
- v3f v0;
- mdl_transform_vector( &menu.cam->transform, (v3f){0.0f,-1.0f,0.0f}, v0 );
- v3_angles( v0, target.angles );
-
- camera_lerp( &menu.view, &target, rate, &menu.view );
-
- menu.view.farz = 150.0f;
- menu.view.nearz = 0.01f;
-
- camera_update_transform( &menu.view );
- camera_update_view( &menu.view );
- camera_update_projection( &menu.view );
- camera_finalize( &menu.view );
- }
- else return;
-
- shader_model_menu_use();
- shader_model_menu_uTexMain( 1 );
- shader_model_menu_uPv( menu.view.mtx.pv );
- shader_model_menu_uPvmPrev( menu.view.mtx_prev.pv );
-
- mesh_bind( &menu.mesh );
-
- v4f white, blue;
-
- ui_hex_to_norm( ui_colour( k_ui_fg ), white );
- ui_hex_to_norm( ui_colour( k_ui_orange+k_ui_brighter ), blue );
-
- ent_menuitem *text_list[ 8 ];
- u32 text_count = 0;
-
- u32 current_tex = 0xffffffff;
-
- for( u32 i=0; i<mdl_arrcount(&menu.items); i++ ){
- ent_menuitem *item = mdl_arritm( &menu.items, i );
-
- if( item->type == k_ent_menuitem_type_disabled ) continue;
- if( item->type == k_ent_menuitem_type_page ) continue;
- if( !(item->groups & (0x1 << menu.page)) ) continue;
-
- if( item->type == k_ent_menuitem_type_binding ){
- if( text_count < vg_list_size(text_list) )
- text_list[ text_count ++ ] = item;
- else
- vg_fatal_error( "Text list overflow" );
-
- continue;
- }
-
- int selected = 0;
-
- if( menu.loc ){
- if( menu.loc->type == k_ent_menuitem_type_slider ){
- u32 subid = menu.loc->slider.id_handle;
- if( item == mdl_arritm( &menu.items, mdl_entity_id_id(subid) ))
- selected = 1;
- }
- else{
- if( item == menu.loc )
- selected = 1;
- }
- }
-
- if( item->type == k_ent_menuitem_type_visual_nocol ){
- shader_model_menu_uColour( (v4f){1.0f,1.0f,1.0f,1.0f} );
- }
- else{
- v4f colour;
- item->factive = vg_lerpf( item->factive, selected, rate );
- v4_lerp( white, blue, item->factive, colour );
- shader_model_menu_uColour( colour );
- }
-
- f32 scale = 1.0f+item->factive*0.1f;
-
- m4x3f mmdl;
- mdl_transform transform = item->transform;
- v3_muls( transform.s, scale, transform.s );
- mdl_transform_m4x3( &transform, mmdl );
-
- if( item->type == k_ent_menuitem_type_toggle && item->pi32 ){
- u32 subid = mdl_entity_id_id( item->checkmark.id_check );
- ent_menuitem *subitem = mdl_arritm( &menu.items, subid );
-
- v3_muladds( item->transform.co, item->checkmark.offset, scale,
- subitem->transform.co );
-
- subitem->fvisible = vg_lerpf( subitem->fvisible, *item->pi32, rate );
- v3_fill( subitem->transform.s, subitem->fvisible );
- }
- else if( item->type == k_ent_menuitem_type_slider && item->pf32 ){
- u32 il = mdl_entity_id_id( item->slider.id_min ),
- ir = mdl_entity_id_id( item->slider.id_max ),
- ih = mdl_entity_id_id( item->slider.id_handle );
- ent_marker *ml = mdl_arritm( &menu.markers, il ),
- *mr = mdl_arritm( &menu.markers, ir );
- ent_menuitem *handle = mdl_arritm( &menu.items, ih );
-
- v3_lerp( ml->transform.co, mr->transform.co, *item->pf32,
- handle->transform.co );
- }
-
- shader_model_menu_uMdl( mmdl );
-
- for( u32 j=0; j<item->submesh_count; j++ ){
- u32 index = item->submesh_start + j;
- mdl_submesh *sm = mdl_arritm( &menu.model.submeshs, index );
-
- mdl_material *mat = mdl_arritm( &menu.model.materials,
- sm->material_id-1 );
-
- if( mat->tex_diffuse != current_tex ){
- glActiveTexture( GL_TEXTURE1 );
- glBindTexture( GL_TEXTURE_2D, menu.textures[ mat->tex_diffuse ] );
- current_tex = mat->tex_diffuse;
- }
-
- mdl_draw_submesh( sm );
- }
- }
-
- if( !text_count ) return;
-
- char buf[ 128 ];
-
- m4x3f local;
- m4x3_identity( local );
-
- font3d_bind( &gui.font, k_font_shader_default, 0, NULL, &menu.view );
- for( u32 i=0; i<text_count; i++ ){
- ent_menuitem *item = text_list[ i ];
- m4x3f transform;
- mdl_transform_m4x3( &item->transform, transform );
-
- u32 variant = item->binding.font_variant;
- menu_binding_string( buf, item->binding.pstr_bind );
- f32 offset = font3d_string_width( variant, buf );
-
- local[3][0] = -0.5f * offset;
- m4x3_mul( transform, local, transform );
-
- font3d_simple_draw( variant, buf, &menu.view, transform );
- }
-}
-
-static void menu_binding_string( char buf[128], u32 pstr ){
- vg_str str;
- vg_strnull( &str, buf, 128 );
-
- if( MDL_CONST_PSTREQ( &menu.model, pstr, "bind_jump" ) ){
- vg_input_string( &str, input_button_list[k_srbind_jump], 1 );
- }
- else if( MDL_CONST_PSTREQ( &menu.model, pstr, "bind_trick0" ) ){
- vg_strcat( &str, "SHUVIT " );
- vg_input_string( &str, input_button_list[k_srbind_trick0], 1 );
- }
- else if( MDL_CONST_PSTREQ( &menu.model, pstr, "bind_trick1" ) ){
- vg_strcat( &str, "KICKFLIP " );
- vg_input_string( &str, input_button_list[k_srbind_trick1], 1 );
- }
- else if( MDL_CONST_PSTREQ( &menu.model, pstr, "bind_trick2" ) ){
- vg_strcat( &str, "TREFLIP " );
- vg_input_string( &str, input_button_list[k_srbind_trick2], 1 );
- }
- else if( MDL_CONST_PSTREQ( &menu.model, pstr, "bind_grab" ) ){
- vg_input_string( &str, input_axis_list[k_sraxis_grab], 1 );
- }
- else if( MDL_CONST_PSTREQ( &menu.model, pstr, "bind_grab_mod" ) ){
- vg_input_string( &str, input_joy_list[k_srjoystick_grab], 1 );
- }
- else
- vg_strcat( &str, "error" );
-}
+extern menu;
+void menu_close(void);
+void menu_init(void);
+void menu_open_page( const char *name,
+ enum ent_menuitem_stack_behaviour stackmode );
+void menu_link(void);
+void menu_update(void);
+void menu_render(void);
#pragma once
-#include "skaterift.h"
-
#include "vg/vg_io.h"
#include "vg/vg_async.h"
#include "vg/vg_tex.h"
+#include "skaterift.h"
+#include "vg/vg_steam.h"
+#include "vg/vg_steam_networking.h"
+#include "vg/vg_steam_auth.h"
+#include "vg/vg_steam_friends.h"
#include "player.h"
#include "network.h"
#include "network_msg.h"
#include "gui.h"
#include "ent_region.h"
+struct network_client network_client =
+{
+ .auth_mode = eServerModeAuthentication,
+ .state = k_ESteamNetworkingConnectionState_None,
+ .server_adress = "46.101.34.155",
+ .last_intent_change = -99999.9
+};
+
static void scores_update(void);
-static int packet_minsize( SteamNetworkingMessage_t *msg, u32 size ){
+int packet_minsize( SteamNetworkingMessage_t *msg, u32 size ){
if( msg->m_cbSize < size ) {
vg_error( "Invalid packet size (must be at least %u)\n", size );
return 0;
k_nSteamNetworkingSend_Reliable, NULL );
}
-static void network_send_region(void){
+void network_send_region(void)
+{
if( !network_connected() )
return;
* .
* 10+ specific week index
*/
-static void network_request_scoreboard( const char *mod_uid,
- const char *route_uid,
- u32 week, u64 userdata ){
+void network_request_scoreboard( const char *mod_uid,
+ const char *route_uid,
+ u32 week, u64 userdata ){
if( !network_connected() )
return;
}
}
-static void network_publish_laptime( const char *mod_uid,
- const char *route_uid, f64 lap_time ){
+void network_publish_laptime( const char *mod_uid,
+ const char *route_uid, f64 lap_time ){
if( !network_connected() )
return;
}
}
-static void network_send_item( enum netmsg_playeritem_type type ){
+void network_send_item( enum netmsg_playeritem_type type )
+{
if( !network_connected() )
return;
}
}
-static void network_status_string( vg_str *str, u32 *colour ){
+void network_status_string( vg_str *str, u32 *colour )
+{
if( skaterift.demo_mode ){
vg_strcat( str, "Offline" );
return;
}
}
-static void render_server_status_gui(void){
+void render_server_status_gui(void)
+{
render_fb_bind( gpipeline.fb_workshop_preview, 0 );
/* HACK */
}
}
-static void network_update(void){
+void network_update(void)
+{
if( !steam_ready )
return;
}
}
-static void chat_send_message( const char *message ){
+void chat_send_message( const char *message )
+{
if( !network_connected() ){
return;
}
return 0;
}
-static void network_init(void){
+void network_init(void)
+{
vg_console_reg_var( "network_info", &network_client.network_info,
k_var_dtype_i32, VG_VAR_PERSISTENT );
if( steam_ready ){
}
}
-static void network_end(void){
+void network_end(void)
+{
/* TODO: Send buffered highscores that were not already */
if( (network_client.state == k_ESteamNetworkingConnectionState_Connected) ||
(network_client.state == k_ESteamNetworkingConnectionState_Connecting) )
* All trademarks are property of their respective owners
*/
-#ifndef NETWORK_H
-#define NETWORK_H
-
+#pragma once
#include "vg/vg_platform.h"
+#include "vg/vg_steam_networking.h"
#include "steam.h"
#include "network_common.h"
#include "network_msg.h"
*/
/* Call it at start; Connects us to the gameserver */
-static void network_init(void);
+void network_init(void);
/* Run this from main loop */
-static void network_update(void);
+void network_update(void);
/* Call it at shutdown */
-static void network_end(void);
+void network_end(void);
/*
* Can buffer up a bunch of these by calling many times, they will be
* sent at the next connection
*/
-static void network_submit_highscore( u32 trackid, u16 points, u16 time );
+void network_submit_highscore( u32 trackid, u16 points, u16 time );
/*
* Game endpoints are provided with the same names to allow running without a
* network connection.
*/
-struct {
+struct network_client
+{
u8 app_symmetric_key[ 1024 ];
u32 app_key_length;
EServerMode auth_mode;
f64 last_intent_change;
f32 fintent; /* yeah this shit really shouldnt be here but oh well */
}
-static network_client = {
- .auth_mode = eServerModeAuthentication,
- .state = k_ESteamNetworkingConnectionState_None,
- .server_adress = "46.101.34.155",
- .last_intent_change = -99999.9
-};
-
-static int packet_minsize( SteamNetworkingMessage_t *msg, u32 size );
-static void network_send_item( enum netmsg_playeritem_type type );
-static void network_request_scoreboard( const char *mod_uid,
- const char *route_uid,
- u32 week, u64 userdata );
-static void network_publish_laptime( const char *mod_uid,
- const char *route_uid, f64 lap_time );
-static void chat_send_message( const char *message );
-static void render_server_status_gui(void);
-static void network_status_string( vg_str *str, u32 *colour );
-static void network_send_region(void);
-
-static int network_connected(void){
+extern network_client;
+
+int packet_minsize( SteamNetworkingMessage_t *msg, u32 size );
+void network_send_item( enum netmsg_playeritem_type type );
+void network_request_scoreboard( const char *mod_uid,
+ const char *route_uid,
+ u32 week, u64 userdata );
+void network_publish_laptime( const char *mod_uid,
+ const char *route_uid, f64 lap_time );
+void chat_send_message( const char *message );
+void render_server_status_gui(void);
+void network_status_string( vg_str *str, u32 *colour );
+void network_send_region(void);
+
+static inline int network_connected(void)
+{
if( network_client.remote_version != NETWORK_SKATERIFT_VERSION ) return 0;
return network_client.state == k_ESteamNetworkingConnectionState_Connected;
}
-
-#endif /* NETWORK_H */
+#include "vg/vg_lines.h"
+#include "vg/vg_async.h"
#include "particle.h"
-#include "shaders/trail.h"
+#include "shaders/particle.h"
+
+struct particle_system particles_grind = {
+ .scale = 0.02f,
+ .velocity_scale = 0.001f,
+ .width = 0.0125f
+},
+particles_env = {
+ .scale = 0.04f,
+ .velocity_scale = 0.001f,
+ .width = 0.25f
+};
-static void particle_spawn( particle_system *sys,
- v3f co, v3f v, f32 lifetime, u32 colour ){
+void particle_spawn( particle_system *sys, v3f co, v3f v,
+ f32 lifetime, u32 colour )
+{
if( sys->alive == sys->max ) return;
particle *p = &sys->array[ sys->alive ++ ];
p->colour = colour;
}
-static void particle_spawn_cone( particle_system *sys,
- v3f co, v3f dir, f32 angle, f32 speed,
- f32 lifetime, u32 colour ){
+void particle_spawn_cone( particle_system *sys,
+ v3f co, v3f dir, f32 angle, f32 speed,
+ f32 lifetime, u32 colour )
+{
if( sys->alive == sys->max ) return;
particle *p = &sys->array[ sys->alive ++ ];
v3_copy( co, p->co );
}
-static void particle_system_update( particle_system *sys, f32 dt ){
+void particle_system_update( particle_system *sys, f32 dt )
+{
u32 i = 0;
iter: if( i == sys->alive ) return;
goto iter;
}
-static void particle_system_debug( particle_system *sys ){
+void particle_system_debug( particle_system *sys )
+{
for( u32 i=0; i<sys->alive; i ++ ){
particle *p = &sys->array[i];
v3f p1;
VG_CHECK_GL_ERR();
}
-static void particle_init(void){
- shader_particle_register();
-}
-
-static void particle_alloc( particle_system *sys, u32 max ){
+void particle_alloc( particle_system *sys, u32 max )
+{
size_t stride = sizeof(particle_vert);
sys->max = max;
vg_async_dispatch( call, async_particle_init );
}
-static void particle_system_prerender( particle_system *sys ){
+void particle_system_prerender( particle_system *sys )
+{
for( u32 i=0; i<sys->alive; i ++ ){
particle *p = &sys->array[i];
particle_vert *vs = &sys->vertices[i*4];
glBufferSubData( GL_ARRAY_BUFFER, 0, sys->alive*stride*4, sys->vertices );
}
-static void particle_system_render( particle_system *sys, camera *cam ){
+void particle_system_render( particle_system *sys, vg_camera *cam )
+{
glDisable( GL_CULL_FACE );
glEnable( GL_DEPTH_TEST );
-#ifndef PARTICLE_H
-#define PARTICLE_H
-
+#pragma once
#include "skaterift.h"
typedef struct particle_system particle_system;
/* render settings */
f32 scale, velocity_scale, width;
}
-static particles_grind = {
- .scale = 0.02f,
- .velocity_scale = 0.001f,
- .width = 0.0125f
-},
-particles_env = {
- .scale = 0.04f,
- .velocity_scale = 0.001f,
- .width = 0.25f
-};
-
-static void particle_alloc( particle_system *sys, u32 max );
-static void particle_system_update( particle_system *sys, f32 dt );
-static void particle_system_debug( particle_system *sys );
-static void particle_system_prerender( particle_system *sys );
-static void particle_system_render( particle_system *sys, camera *cam );
-
-static void particle_spawn( particle_system *sys,
- v3f co, v3f v, f32 lifetime, u32 colour );
-static void particle_spawn_cone( particle_system *sys,
- v3f co, v3f dir, f32 angle, f32 speed,
- f32 lifetime, u32 colour );
-
-#include "shaders/particle.h"
-
-#endif /* PARTICLE_H */
+extern particles_grind, particles_env;
+
+void particle_alloc( particle_system *sys, u32 max );
+void particle_system_update( particle_system *sys, f32 dt );
+void particle_system_debug( particle_system *sys );
+void particle_system_prerender( particle_system *sys );
+void particle_system_render( particle_system *sys, vg_camera *cam );
+
+void particle_spawn( particle_system *sys,
+ v3f co, v3f v, f32 lifetime, u32 colour );
+void particle_spawn_cone( particle_system *sys,
+ v3f co, v3f dir, f32 angle, f32 speed,
+ f32 lifetime, u32 colour );
-#ifndef PLAYER_C
-#define PLAYER_C
-
#include "player.h"
+#include "addon.h"
#include "camera.h"
#include "player_model.h"
#include "input.h"
#include "shaders/model_character_view.h"
#include "shaders/model_board_view.h"
-static int localplayer_cmd_respawn( int argc, const char *argv[] ){
+#include "player_walk.h"
+#include "player_dead.h"
+#include "player_drive.h"
+#include "player_skate.h"
+#include "player_basic_info.h"
+#include "player_glide.h"
+
+i32 k_invert_y = 0;
+struct localplayer localplayer =
+{
+ .rb =
+ {
+ .co = { 0,0,0 },
+ .w = { 0,0,0 },
+ .v = { 0,0,0 },
+ .q = { 0,0,0,1 },
+ .to_world = M4X3_IDENTITY,
+ .to_local = M4X3_IDENTITY
+ }
+};
+
+struct player_subsystem_interface *player_subsystems[] =
+{
+ [k_player_subsystem_walk] = &player_subsystem_walk,
+ [k_player_subsystem_dead] = &player_subsystem_dead,
+ [k_player_subsystem_drive] = &player_subsystem_drive,
+ [k_player_subsystem_skate] = &player_subsystem_skate,
+ [k_player_subsystem_basic_info]=&player_subsystem_basic_info,
+ [k_player_subsystem_glide] = &player_subsystem_glide,
+};
+
+int localplayer_cmd_respawn( int argc, const char *argv[] )
+{
ent_spawn *rp = NULL, *r;
world_instance *world = world_current_instance();
return 1;
}
-static void player_init(void){
- for( u32 i=0; i<vg_list_size(player_subsystems); i++ ){
+void player_init(void)
+{
+ for( u32 i=0; i<k_player_subsystem_max; i++ )
+ {
struct player_subsystem_interface *sys = player_subsystems[i];
if( sys->system_register ) sys->system_register();
}
VG_VAR_F32( k_cam_shake_trackspeed );
VG_VAR_I32( k_player_debug_info, flags=VG_VAR_PERSISTENT );
+#if 0
vg_console_reg_var( "cinema", &k_cinema, k_var_dtype_f32, 0 );
vg_console_reg_var( "cinema_fixed", &k_cinema_fixed, k_var_dtype_i32, 0 );
- vg_console_reg_var( "invert_y", &k_invert_y,
+#endif
+ vg_console_reg_var( "invert_y", &k_invert_y,
k_var_dtype_i32, VG_VAR_PERSISTENT );
-
- shader_model_character_view_register();
- shader_model_board_view_register();
- shader_model_entity_register();
}
-static void player__debugtext( int size, const char *fmt, ... ){
+void player__debugtext( int size, const char *fmt, ... )
+{
char buffer[ 1024 ];
va_list args;
* Appearence
*/
-static void player__use_model( u16 reg_id ){
+void player__use_model( u16 reg_id )
+{
addon_cache_unwatch( k_addon_type_player,
localplayer.playermodel_view_slot );
localplayer.playermodel_view_slot =
addon_cache_create_viewer( k_addon_type_player, reg_id );
}
-static void player__bind(void){
- for( u32 i=0; i<vg_list_size(player_subsystems); i++ ){
+void player__bind(void)
+{
+ for( u32 i=0; i<k_player_subsystem_max; i++ )
+ {
struct player_subsystem_interface *sys = player_subsystems[i];
if( sys->bind ) sys->bind();
* ----------------------------------------------------------------------------
*/
-static void player__pre_update(void){
+void player__pre_update(void)
+{
if( button_down( k_srbind_camera ) && !localplayer.immobile &&
(localplayer.subsystem != k_player_subsystem_dead) ){
if( localplayer.cam_control.camera_mode == k_cam_firstperson )
player_subsystems[ localplayer.subsystem ]->pre_update();
}
-static void player__update(void){
+void player__update(void)
+{
if( player_subsystems[ localplayer.subsystem ]->update )
player_subsystems[ localplayer.subsystem ]->update();
glider_physics( (v2f){0,0} );
}
-static void player__post_update(void)
+void player__post_update(void)
{
struct player_subsystem_interface *sys =
player_subsystems[ localplayer.subsystem ];
if( sys->post_update ) sys->post_update();
- SDL_AtomicLock( &air_data.sl );
- air_data.speed = v3_length( localplayer.rb.v ) * vg.time_rate;
- SDL_AtomicUnlock( &air_data.sl );
+ SDL_AtomicLock( &air_audio_data.sl );
+ air_audio_data.speed = v3_length( localplayer.rb.v ) * vg.time_rate;
+ SDL_AtomicUnlock( &air_audio_data.sl );
}
/*
* Applies gate transport to a player_interface
*/
-static void player__pass_gate( u32 id )
+void player__pass_gate( u32 id )
{
world_instance *world = world_current_instance();
- skaterift_record_frame( &skaterift.replay, 1 );
+ skaterift_record_frame( &player_replay.local, 1 );
/* update boundary hash (network animation) */
u16 index = mdl_entity_id_id(id) & ~NETMSG_BOUNDARY_MASK;
world_static.active_instance = gate->target;
player__clean_refs();
- replay_clear( &skaterift.replay );
+ replay_clear( &player_replay.local );
}
else
{
audio_unlock();
}
-static void player_apply_transport_to_cam( m4x3f transport )
+void player_apply_transport_to_cam( m4x3f transport )
{
/* Pre-emptively edit the camera matrices so that the motion vectors
* are correct */
m4x4_mul( world_gates.cam.mtx.v, transport_4, world_gates.cam.mtx.v );
}
-static void player__im_gui(void)
+void player__im_gui(void)
{
if( !k_player_debug_info ) return;
skaterift_replay_debug_info();
}
-static void player__setpos( v3f pos ){
+void player__setpos( v3f pos )
+{
v3_copy( pos, localplayer.rb.co );
v3_zero( localplayer.rb.v );
rb_update_matrices( &localplayer.rb );
}
-static void player__clean_refs(void){
- replay_clear( &skaterift.replay );
+void player__clean_refs(void)
+{
+ replay_clear( &player_replay.local );
gui_helper_clear();
world_static.challenge_target = NULL;
}
}
-static void player__reset(void){
+void player__reset(void)
+{
v3_zero( localplayer.rb.v );
v3_zero( localplayer.rb.w );
player__clean_refs();
}
-static void player__spawn( ent_spawn *rp ){
+void player__spawn( ent_spawn *rp )
+{
player__setpos( rp->transform.co );
player__reset();
}
-static void player__kill(void){
+void player__kill(void)
+{
}
-static void player__begin_holdout( v3f offset ){
+void player__begin_holdout( v3f offset )
+{
memcpy( &localplayer.holdout_pose, &localplayer.pose,
sizeof(localplayer.pose) );
v3_copy( offset, localplayer.holdout_pose.root_co );
localplayer.holdout_time = 1.0f;
}
-static void net_sfx_exchange( bitpack_ctx *ctx, struct net_sfx *sfx ){
+void net_sfx_exchange( bitpack_ctx *ctx, struct net_sfx *sfx )
+{
bitpack_bytes( ctx, 1, &sfx->system );
bitpack_bytes( ctx, 1, &sfx->priority );
bitpack_bytes( ctx, 1, &sfx->id );
bitpack_qv3f( ctx, 16, -1024.0f, 1024.0f, sfx->location );
}
-static void net_sfx_play( struct net_sfx *sfx ){
+void net_sfx_play( struct net_sfx *sfx )
+{
if( sfx->system < k_player_subsystem_max ){
struct player_subsystem_interface *sys = player_subsystems[sfx->system];
if( sys->sfx_oneshot ){
return p_sfx;
}
-static void player__networked_sfx( u8 system, u8 priority, u8 id,
- v3f pos, f32 volume ){
+void player__networked_sfx( u8 system, u8 priority, u8 id,
+ v3f pos, f32 volume )
+{
struct net_sfx sfx,
*p_net = find_lower_priority_sfx(
localplayer.sfx_buffer, 4,
net_sfx_play( &sfx );
}
-
-/* implementation */
-#include "player_common.c"
-
-#include "player_walk.c"
-#include "player_skate.c"
-#include "player_dead.c"
-#include "player_drive.c"
-#include "player_glide.c"
-#include "player_basic_info.c"
-
-#include "player_render.c"
-#include "player_ragdoll.c"
-#include "player_replay.c"
-
-#endif /* PLAYER_C */
-#ifndef PLAYER_H
-#define PLAYER_H
-
-#include "skaterift.h"
-#include "player_common.h"
-#include "network_compression.h"
-#include "player_effects.h"
-
-enum player_subsystem{
- k_player_subsystem_walk = 0,
- k_player_subsystem_skate = 1,
- k_player_subsystem_dead = 2,
- k_player_subsystem_drive = 3,
- k_player_subsystem_basic_info = 4,
- k_player_subsystem_glide = 5,
- k_player_subsystem_max,
- k_player_subsystem_invalid = 255
-};
+#pragma once
+#include "vg/vg_platform.h"
struct player_cam_controller {
enum camera_mode{
cam_velocity_smooth;
};
+#include "player_common.h"
+#include "network_compression.h"
+#include "player_effects.h"
+#include "player_api.h"
+#include "player_ragdoll.h"
+#include "player_model.h"
+#include "player_render.h"
+
struct player_subsystem_interface{
void(*system_register)(void);
void(*bind)(void);
const char *name;
};
-#include "player_ragdoll.h"
-#include "player_render.h"
-#include "player_model.h"
-
-/* subsystem headers */
-#include "player_walk.h"
-#include "player_skate.h"
-#include "player_dead.h"
-#include "player_drive.h"
-#include "player_glide.h"
-#include "player_basic_info.h"
-
-#include "player_replay.h"
-
#define PLAYER_REWIND_FRAMES 60*4
#define RESET_MAX_TIME 45.0
-static i32 k_cinema_fixed = 0;
-static f32 k_cinema = 0.0f;
-static i32 k_invert_y = 0;
-static f32 k_cam_dist = 1.8f;
-
-struct {
+extern i32 k_invert_y;
+struct localplayer
+{
/* transform definition */
rigidbody rb;
v3f angles;
* Camera management
* ---------------------------
*/
- camera cam;
+ vg_camera cam;
struct player_cam_controller cam_control;
f32 cam_trackshake;
struct player_effects_data effect_data;
}
-static localplayer = {
- .rb = {
- .co = { 0,0,0 },
- .w = { 0,0,0 },
- .v = { 0,0,0 },
- .q = { 0,0,0,1 },
- .to_world = M4X3_IDENTITY,
- .to_local = M4X3_IDENTITY
- }
-};
-
-struct player_subsystem_interface static *player_subsystems[] = {
- [k_player_subsystem_walk] = &player_subsystem_walk,
- [k_player_subsystem_dead] = &player_subsystem_dead,
- [k_player_subsystem_drive] = &player_subsystem_drive,
- [k_player_subsystem_skate] = &player_subsystem_skate,
- [k_player_subsystem_basic_info]=&player_subsystem_basic_info,
- [k_player_subsystem_glide] = &player_subsystem_glide,
-};
+extern localplayer;
+extern struct player_subsystem_interface *player_subsystems[];
/*
* Gameloop tables
* ---------------------------------------------------------
*/
-static void player__debugtext( int size, const char *fmt, ... );
-static void player__use_mesh( glmesh *mesh );
-static void player__use_model( u16 reg_id );
-
-static void player__bind(void);
-static void player__pre_update(void);
-static void player__update(void);
-static void player__post_update(void);
-
-static void player__pass_gate( u32 id );
-static void player__im_gui(void);
-static void player__setpos( v3f pos );
-static void player__spawn( ent_spawn *rp );
-static void player__clean_refs(void);
-static void player__reset(void);
-static void player__kill(void);
-static void player__begin_holdout( v3f offset );
-
-static int localplayer_cmd_respawn( int argc, const char *argv[] );
-static void player_apply_transport_to_cam( m4x3f transport );
-
-static void player__clear_sfx_buffer(void);
-static void player__networked_sfx( u8 system, u8 priority, u8 id,
- v3f pos, f32 volume );
-static void net_sfx_exchange( bitpack_ctx *ctx, struct net_sfx *sfx );
-static void net_sfx_play( struct net_sfx *sfx );
-
-#endif /* PLAYER_H */
+void player_init(void);
+void player__debugtext( int size, const char *fmt, ... );
+void player__use_mesh( glmesh *mesh );
+void player__use_model( u16 reg_id );
+
+void player__bind(void);
+void player__pre_update(void);
+void player__update(void);
+void player__post_update(void);
+
+void player__pass_gate( u32 id );
+void player__im_gui(void);
+void player__setpos( v3f pos );
+void player__spawn( ent_spawn *rp );
+void player__clean_refs(void);
+void player__reset(void);
+void player__kill(void);
+void player__begin_holdout( v3f offset );
+
+int localplayer_cmd_respawn( int argc, const char *argv[] );
+void player_apply_transport_to_cam( m4x3f transport );
+
+void player__clear_sfx_buffer(void);
+void player__networked_sfx( u8 system, u8 priority, u8 id,
+ v3f pos, f32 volume );
+void net_sfx_exchange( bitpack_ctx *ctx, struct net_sfx *sfx );
+void net_sfx_play( struct net_sfx *sfx );
-#ifndef PLAYER_API_H
-#define PLAYER_API_H
-
+#pragma once
#include "model.h"
#include "camera.h"
-#include "entity.h"
-#define PLAYER_API static
typedef struct player_instance player_instance;
typedef struct player_pose player_pose;
board;
};
-#endif /* PLAYER_API_H */
+enum player_subsystem{
+ k_player_subsystem_walk = 0,
+ k_player_subsystem_skate = 1,
+ k_player_subsystem_dead = 2,
+ k_player_subsystem_drive = 3,
+ k_player_subsystem_basic_info = 4,
+ k_player_subsystem_glide = 5,
+ k_player_subsystem_max,
+ k_player_subsystem_invalid = 255
+};
#include "player_basic_info.h"
#include "network_compression.h"
-static void player__basic_info_animator_exchange(bitpack_ctx *ctx, void *data){
+struct player_basic_info player_basic_info;
+struct player_subsystem_interface player_subsystem_basic_info =
+{
+ .pose = player__basic_info_pose,
+ .network_animator_exchange = player__basic_info_animator_exchange,
+ .animator_data = &player_basic_info.animator,
+ .animator_size = sizeof(player_basic_info.animator),
+ .name = "Basic Info"
+};
+
+void player__basic_info_animator_exchange(bitpack_ctx *ctx, void *data)
+{
struct player_basic_info_animator *animator = data;
/* TODO: This range needs to be standardized in a common header */
bitpack_qv3f( ctx, 24, -1024.0f, 1024.0f, animator->root_co );
}
-static void player__basic_info_pose( void *_animator, player_pose *pose ){
+void player__basic_info_pose( void *_animator, player_pose *pose )
+{
struct player_basic_info_animator *animator = _animator;
v3_copy( animator->root_co, pose->root_co );
q_identity( pose->root_q );
-#ifndef PLAYER_BASIC_INFO_H
-#define PLAYER_BASIC_INFO_H
-
+#pragma once
#include "player.h"
#include "player_api.h"
-struct player_basic_info {
- struct player_basic_info_animator {
+struct player_basic_info
+{
+ struct player_basic_info_animator
+ {
v3f root_co;
}
animator;
}
-static player_basic_info;
-static void player__basic_info_animator_exchange(bitpack_ctx *ctx, void *data);
-static void player__basic_info_pose( void *_animator, player_pose *pose );
+extern player_basic_info;
+extern struct player_subsystem_interface player_subsystem_basic_info;
-struct player_subsystem_interface static player_subsystem_basic_info = {
- .pose = player__basic_info_pose,
- .network_animator_exchange = player__basic_info_animator_exchange,
- .animator_data = &player_basic_info.animator,
- .animator_size = sizeof(player_basic_info.animator),
- .name = "Basic Info"
-};
+void player__basic_info_animator_exchange(bitpack_ctx *ctx, void *data);
+void player__basic_info_pose( void *_animator, player_pose *pose );
-#endif /* PLAYER_BASIC_INFO_H */
-#ifndef PLAYER_COMMON_C
-#define PLAYER_COMMON_C
-
#include "ent_skateshop.h"
#include "player.h"
#include "input.h"
localplayer.final_mtx );
/* record and re-put things again */
- if( cleared ){
- skaterift_record_frame( &skaterift.replay, 1 );
+ if( cleared )
+ {
+ skaterift_record_frame( &player_replay.local, 1 );
localplayer.deferred_frame_record = 1;
skeleton_apply_transform( &localplayer.skeleton,
inf_tpv = localplayer.cam_velocity_influence_smooth *
(1.0f-cc->camera_type_blend);
- camera_lerp_angles( localplayer.angles, velocity_angles,
+ vg_camera_lerp_angles( localplayer.angles, velocity_angles,
inf_fpv,
localplayer.angles );
float ya = atan2f( -cc->cam_velocity_smooth[1], 30.0f );
follow_angles[1] = 0.3f + ya;
- camera_lerp_angles( localplayer.angles, follow_angles,
+ vg_camera_lerp_angles( localplayer.angles, follow_angles,
inf_tpv,
localplayer.angles );
v3_add( localplayer.cam_land_punch, localplayer.cam.pos,
localplayer.cam.pos );
- if( k_cinema >= 0.0001f ){
- ent_camera *cam = NULL;
- f32 min_dist = k_cinema;
-
- world_instance *world = world_current_instance();
- for( u32 i=0; i<mdl_arrcount(&world->ent_camera); i++ ){
- ent_camera *c = mdl_arritm(&world->ent_camera,i);
-
- f32 dist = v3_dist( c->transform.co, localplayer.rb.co );
-
- if( dist < min_dist ){
- min_dist = dist;
- cam = c;
- }
- }
-
- if( cam ){
- localplayer.cam.fov = cam->fov;
- v3_copy( cam->transform.co, localplayer.cam.pos );
- v3f v0;
- if( k_cinema_fixed )
- mdl_transform_vector( &cam->transform, (v3f){0.0f,-1.0f,0.0f}, v0 );
- else
- v3_sub( localplayer.rb.co, cam->transform.co, v0 );
-
- v3_angles( v0, localplayer.cam.angles );
- }
- }
-
/* portal transitions */
player_camera_portal_correction();
}
angles[1] += input_y * speed;
angles[1] = vg_clampf( angles[1], -VG_PIf*0.5f, VG_PIf*0.5f );
}
-
-#endif /* PLAYER_COMMON_C */
-#ifndef PLAYER_DEAD_C
-#define PLAYER_DEAD_C
-
-#include "player.h"
+#include "skaterift.h"
+#include "player_dead.h"
#include "gui.h"
-static void player__dead_update(void){
+struct player_dead player_dead;
+struct player_subsystem_interface player_subsystem_dead = {
+ .update = player__dead_update,
+ .post_update = player__dead_post_update,
+ .animate = player__dead_animate,
+ .pose = player__dead_pose,
+ .post_animate = player__dead_post_animate,
+ .im_gui = player__dead_im_gui,
+ .bind = player__dead_bind,
+
+ .animator_data = &player_dead.animator,
+ .animator_size = sizeof(player_dead.animator),
+ .network_animator_exchange = player__dead_animator_exchange,
+ .name = "Dead"
+};
+
+void player__dead_update(void){
player_ragdoll_iter( &localplayer.ragdoll );
}
-static void player__dead_post_update(void){
+void player__dead_post_update(void){
struct ragdoll_part *part =
&localplayer.ragdoll.parts[ localplayer.id_hip-1 ];
struct player_dead *d = &player_dead;
}
}
-static void player__dead_animate(void){
+void player__dead_animate(void){
struct player_dead *d = &player_dead;
struct player_dead_animator *animator = &d->animator;
struct player_ragdoll *rd = &localplayer.ragdoll;
}
}
-static void player__dead_pose( void *_animator, player_pose *pose ){
+void player__dead_pose( void *_animator, player_pose *pose )
+{
struct player_dead_animator *animator = _animator;
struct player_ragdoll *rd = &localplayer.ragdoll;
struct skeleton *sk = &localplayer.skeleton;
}
}
-static void player__dead_post_animate(void){
+void player__dead_post_animate(void)
+{
localplayer.cam_velocity_influence = 1.0f;
}
-static void player__dead_im_gui(void){
+void player__dead_im_gui(void)
+{
}
-static void player__dead_transition( enum player_die_type type ){
+void player__dead_transition( enum player_die_type type )
+{
localplayer.subsystem = k_player_subsystem_dead;
copy_localplayer_to_ragdoll( &localplayer.ragdoll, type );
vg_strcat( &str, "spawn" );
}
-static void player__dead_animator_exchange( bitpack_ctx *ctx, void *data ){
+void player__dead_animator_exchange( bitpack_ctx *ctx, void *data )
+{
struct player_dead_animator *animator = data;
for( u32 i=0; i<localplayer.skeleton.bone_count; i ++ ){
}
}
-static void player__dead_bind(void){
+void player__dead_bind(void)
+{
struct skeleton *sk = &localplayer.skeleton;
player_dead.anim_bail = skeleton_get_anim( sk, "pose_bail_ball" );
}
-
-#endif /* PLAYER_DEAD_C */
-#ifndef PLAYER_DEAD_H
-#define PLAYER_DEAD_H
-
+#pragma once
#include "player.h"
#include "player_api.h"
-struct player_dead{
+struct player_dead
+{
v3f co_lpf, v_lpf, w_lpf;
struct player_dead_animator{
struct skeleton_anim *anim_bail;
}
-static player_dead;
-
-static void player__dead_update (void);
-static void player__dead_post_update (void);
-static void player__dead_animate (void);
-static void player__dead_pose (void *animator, player_pose *pose);
-static void player__dead_post_animate(void);
-static void player__dead_im_gui (void);
-static void player__dead_bind (void);
-static void player__dead_transition ( enum player_die_type type );
-static void player__dead_animator_exchange( bitpack_ctx *ctx, void *data );
-
-struct player_subsystem_interface static player_subsystem_dead = {
- .update = player__dead_update,
- .post_update = player__dead_post_update,
- .animate = player__dead_animate,
- .pose = player__dead_pose,
- .post_animate = player__dead_post_animate,
- .im_gui = player__dead_im_gui,
- .bind = player__dead_bind,
-
- .animator_data = &player_dead.animator,
- .animator_size = sizeof(player_dead.animator),
- .network_animator_exchange = player__dead_animator_exchange,
- .name = "Dead"
-};
+extern player_dead;
+extern struct player_subsystem_interface player_subsystem_dead;
+
+void player__dead_update (void);
+void player__dead_post_update (void);
+void player__dead_animate (void);
+void player__dead_pose (void *animator, player_pose *pose);
+void player__dead_post_animate(void);
+void player__dead_im_gui (void);
+void player__dead_bind (void);
+void player__dead_transition ( enum player_die_type type );
+void player__dead_animator_exchange( bitpack_ctx *ctx, void *data );
-#endif /* PLAYER_DEAD_H */
-#ifndef PLAYER_DRIVE_C
-#define PLAYER_DRIVE_C
-
-#include "player.h"
+#include "player_drive.h"
#include "input.h"
-static void player__drive_pre_update(void){
+struct player_drive player_drive;
+struct player_subsystem_interface player_subsystem_drive =
+{
+ .pre_update = player__drive_pre_update,
+ .update = player__drive_update,
+ .post_update = player__drive_post_update,
+ .animate = player__drive_animate,
+ .pose = player__drive_pose,
+ .post_animate = player__drive_post_animate,
+ .im_gui = player__drive_im_gui,
+ .bind = player__drive_bind,
+
+ .animator_data = NULL,
+ .animator_size = 0,
+ .name = "Drive"
+};
+
+void player__drive_pre_update(void)
+{
drivable_vehicle *vehc = player_drive.vehicle;
v2f steer;
vehc->drive = steer[1];
}
-static void player__drive_update(void){}
+void player__drive_update(void){}
-static void player__drive_post_update(void){
+void player__drive_post_update(void)
+{
v3_copy( player_drive.vehicle->rb.co,localplayer.rb.co );
v3_copy( player_drive.vehicle->rb.v, localplayer.rb.v );
v4_copy( player_drive.vehicle->rb.q, localplayer.rb.q );
v3_copy( player_drive.vehicle->rb.w, localplayer.rb.w );
}
-static void player__drive_animate(void){}
+void player__drive_animate(void){}
-static void player__drive_pose( void *animator, player_pose *pose ){
+void player__drive_pose( void *animator, player_pose *pose )
+{
struct skeleton *sk = &localplayer.skeleton;
skeleton_sample_anim( sk, player_drive.anim_drive, 0.0f, pose->keyframes );
v4_copy( localplayer.rb.q, pose->root_q );
}
-static void player__drive_post_animate(void){
+void player__drive_post_animate(void)
+{
if( localplayer.cam_control.camera_mode == k_cam_firstperson )
localplayer.cam_velocity_influence = 0.0f;
else
localplayer.angles[1] = pitch;
}
-static void player__drive_im_gui(void){
+void player__drive_im_gui(void)
+{
player__debugtext( 1, "Nothing here" );
}
-static void player__drive_bind(void){
+void player__drive_bind(void)
+{
struct skeleton *sk = &localplayer.skeleton;
player_drive.vehicle = &gzoomer;
player_drive.anim_drive = skeleton_get_anim( sk, "idle_cycle+y" );
}
-
-#endif /* PLAYER_DRIVE_C */
-#ifndef PLAYER_DRIVE_H
-#define PLAYER_DRIVE_H
-
+#pragma once
#include "player.h"
#include "vehicle.h"
-struct player_drive {
+struct player_drive
+{
drivable_vehicle *vehicle;
struct skeleton_anim *anim_drive;
}
-static player_drive;
-
-static void player__drive_pre_update(void);
-static void player__drive_update(void);
-static void player__drive_post_update(void);
-static void player__drive_animate(void);
-static void player__drive_pose( void *animator, player_pose *pose );
-
-static void player__drive_post_animate(void);
-static void player__drive_im_gui(void);
-static void player__drive_bind(void);
-
-struct player_subsystem_interface static player_subsystem_drive = {
- .pre_update = player__drive_pre_update,
- .update = player__drive_update,
- .post_update = player__drive_post_update,
- .animate = player__drive_animate,
- .pose = player__drive_pose,
- .post_animate = player__drive_post_animate,
- .im_gui = player__drive_im_gui,
- .bind = player__drive_bind,
+extern player_drive;
+extern struct player_subsystem_interface player_subsystem_drive;
- .animator_data = NULL,
- .animator_size = 0,
- .name = "Drive"
-};
+void player__drive_pre_update(void);
+void player__drive_update(void);
+void player__drive_post_update(void);
+void player__drive_animate(void);
+void player__drive_pose( void *animator, player_pose *pose );
-#endif /* PLAYER_DRIVE_H */
+void player__drive_post_animate(void);
+void player__drive_im_gui(void);
+void player__drive_bind(void);
#include "player_effects.h"
+#include "player_render.h"
#include "particle.h"
-static void effect_blink_apply( effect_blink *ef, player_pose *pose, f32 dt ){
+void effect_blink_apply( effect_blink *ef, player_pose *pose, f32 dt )
+{
if( ef->t < 0.0f ){
ef->t = (1.0f-powf(vg_randf64(&vg.rand),4.0f))*4.0f;
ef->l = 0.08f;
ef->l -= dt;
}
-static void effect_spark_apply( effect_spark *ef, v3f co, v3f v, f32 dt ){
+void effect_spark_apply( effect_spark *ef, v3f co, v3f v, f32 dt )
+{
if( !ef->colour ) return;
if( ef->t < 0.0f ){
-#ifndef PLAYER_EFFECTS
-#define PLAYER_EFFECTS
-
-#include "skaterift.h"
+#pragma once
+#include "vg/vg_platform.h"
typedef struct effect_blink effect_blink;
typedef struct effect_spark effect_spark;
-struct effect_blink {
+struct effect_blink
+{
f32 t, l;
};
-struct effect_spark {
+struct effect_spark
+{
u32 colour;
f32 t;
};
-static void effect_blink_apply( effect_blink *ef, player_pose *pose, f32 dt );
-static void effect_spark_apply( effect_spark *ef, v3f co, v3f v, f32 dt );
+void effect_blink_apply( effect_blink *ef, player_pose *pose, f32 dt );
+void effect_spark_apply( effect_spark *ef, v3f co, v3f v, f32 dt );
-struct player_effects_data {
+struct player_effects_data
+{
effect_blink blink;
effect_spark spark, sand;
};
-
-#endif /* PLAYER_EFFECTS */
-#ifndef PLAYER_GLIDE_C
-#define PLAYER_GLIDE_C
-
#include "player_glide.h"
-#include "input.h"
-
#include "vg/vg_rigidbody.h"
#include "scene_rigidbody.h"
#include "shaders/model_board_view.h"
#include "shaders/model_entity.h"
+#include "input.h"
+#include "skaterift.h"
+
+#include "player_dead.h"
+#include "player_skate.h"
+
+trail_system trails_glider[] = {
+ {
+ .width = 0.035f,
+ .lifetime = 5.0f,
+ .min_dist = 0.5f
+ },
+ {
+ .width = 0.035f,
+ .lifetime = 5.0f,
+ .min_dist = 0.5f
+ },
+};
+
+struct player_glide player_glide =
+{
+ .parts = {
+ {
+ .co = { 1.0f, 0.5f, -1.0f },
+ .euler = { VG_TAUf*0.25f, VG_TAUf*0.125f, 0.0f },
+ .shape = k_rb_shape_capsule,
+ .inf = { .h = 2.82842712475f, .r = 0.25f },
+ },
+ {
+ .co = { -1.0f, 0.5f, -1.0f },
+ .euler = { VG_TAUf*0.25f, -VG_TAUf*0.125f, 0.0f },
+ .shape = k_rb_shape_capsule,
+ .inf = { .h = 2.82842712475f, .r = 0.25f },
+ },
+ {
+ .co = { 0.0f, 0.5f, 1.0f },
+ .euler = { VG_TAUf*0.25f, VG_TAUf*0.25f, 0.0f },
+ .shape = k_rb_shape_capsule,
+ .inf = { .h = 6.0f, .r = 0.25f },
+ },
+ {
+ .co = { 0.0f, -0.5f, 0.0f },
+ .euler = { VG_TAUf*0.25f, VG_TAUf*0.25f, 0.0f },
+ .shape = k_rb_shape_capsule,
+ .inf = { .h = 2.0f, .r = 0.25f },
+ .is_damage = 1,
+ },
+ }
+};
+
+struct player_subsystem_interface player_subsystem_glide =
+{
+ .pre_update = player_glide_pre_update,
+ .update = player_glide_update,
+ .post_update = player_glide_post_update,
+ .animate = player_glide_animate,
+ .pose = player_glide_pose,
+ .post_animate = player_glide_post_animate,
+ .network_animator_exchange = player_glide_animator_exchange,
+ .im_gui = player_glide_im_gui,
+ .bind = player_glide_bind,
+
+ .animator_data = &player_glide.animator,
+ .animator_size = sizeof(player_glide.animator),
+ .name = "Glide"
+};
static f32 k_glide_steer = 2.0f,
k_glide_cl = 0.04f,
static i32 k_glide_pause = 0;
-static void player_glide_pre_update(void){
+void player_glide_pre_update(void)
+{
if( button_down(k_srbind_use) ){
localplayer.subsystem = k_player_subsystem_skate;
localplayer.glider_orphan = 1;
/*
* Returns true if the bottom sphere is hit
*/
-static bool glider_physics( v2f steer ){
+bool glider_physics( v2f steer )
+{
rigidbody *rb = &player_glide.rb;
/* lift */
return bottom_hit;
}
-static void player_glide_update(void){
+void player_glide_update(void)
+{
v2f steer;
joystick_state( k_srjoystick_steer, steer );
}
}
-static void player_glide_post_update(void){
+void player_glide_post_update(void)
+{
v3_copy( player_glide.rb.co, localplayer.rb.co );
v4_copy( player_glide.rb.q, localplayer.rb.q );
v3_copy( player_glide.rb.v, localplayer.rb.v );
rb_update_matrices( &localplayer.rb );
}
-static void player_glide_animate(void){
+void player_glide_animate(void)
+{
struct player_glide *g = &player_glide;
struct player_glide_animator *animator = &g->animator;
rb_extrapolate( &localplayer.rb, animator->root_co, animator->root_q );
}
-static void player_glide_pose( void *_animator, player_pose *pose ){
+void player_glide_pose( void *_animator, player_pose *pose )
+{
struct skeleton *sk = &localplayer.skeleton;
struct player_glide_animator *animator = _animator;
pose->type = k_player_pose_type_ik;
v4_copy( animator->root_q, pose->root_q );
}
-static void player_glide_post_animate(void){
+void player_glide_post_animate(void)
+{
if( localplayer.cam_control.camera_mode == k_cam_firstperson )
localplayer.cam_velocity_influence = 0.0f;
else
localplayer.cam_dist = 2.0f + v3_length( localplayer.rb.v )*0.2f;
}
-static void player_glide_animator_exchange( bitpack_ctx *ctx, void *data ){
+void player_glide_animator_exchange( bitpack_ctx *ctx, void *data )
+{
struct player_glide_animator *animator = data;
bitpack_qv3f( ctx, 24, -1024.0f, 1024.0f, animator->root_co );
bitpack_qquat( ctx, animator->root_q );
}
-static void
-player_glide_remote_animator_exchange( bitpack_ctx *ctx, void *data ){
+void player_glide_remote_animator_exchange( bitpack_ctx *ctx, void *data )
+{
struct remote_glider_animator *animator = data;
bitpack_qv3f( ctx, 24, -1024.0f, 1024.0f, animator->root_co );
bitpack_qquat( ctx, animator->root_q );
}
-static void player_glide_im_gui(void){
+void player_glide_im_gui(void)
+{
player__debugtext( 1, "Nothing here" );
player__debugtext( 1, " lift: %.2f %.2f %.2f",
player_glide.info_lift[0],
player_glide.info_drag[2] );
}
-static void player_glide_equip_glider(void){
+void player_glide_equip_glider(void)
+{
if( !localplayer.have_glider ){
localplayer.have_glider = 1;
localplayer.glider_orphan = 0;
return 0;
}
-static void player_glide_bind(void)
+void player_glide_bind(void)
{
u32 mask = VG_VAR_CHEAT|VG_VAR_PERSISTENT;
VG_VAR_F32( k_glide_steer, flags=mask );
u32 count = mdl_arrcount( &mdl->textures );
player_glide.glider_textures =
- vg_linear_alloc(alloc,vg_align8(sizeof(GLuint)*(count+1)));
+ vg_linear_alloc( alloc, vg_align8(sizeof(GLuint)*(count+1)));
player_glide.glider_textures[0] = vg.tex_missing;
-
mdl_async_load_glmesh( mdl, &player_glide.glider_mesh, NULL );
for( u32 i=0; i<count; i ++ ){
}
}
-static void player_glide_transition(void){
+void player_glide_transition(void)
+{
localplayer.subsystem = k_player_subsystem_glide;
localplayer.have_glider = 0;
world_static.challenge_target = NULL;
player__begin_holdout( (v3f){0,0,0} );
}
-static void render_glider_model( camera *cam, world_instance *world,
- m4x3f mmdl, enum board_shader shader ){
+void render_glider_model( vg_camera *cam, world_instance *world,
+ m4x3f mmdl, enum board_shader shader )
+{
u32 current_tex = 0xffffffff;
glActiveTexture( GL_TEXTURE0 );
* that can hold that information instead so we can save it into
* the replay
*/
-static void player_glide_render( camera *cam, world_instance *world,
- player_pose *pose ){
+void player_glide_render( vg_camera *cam, world_instance *world,
+ player_pose *pose )
+{
if( !((localplayer.subsystem == k_player_subsystem_glide) ||
(localplayer.observing_system == k_player_subsystem_glide) ||
localplayer.have_glider ||
player_glide.remote_animator.s = kf_res.s[0];
}
-static void player_glide_render_effects( camera *cam ){
+void player_glide_render_effects( vg_camera *cam )
+{
v3f co, temp;
v4f q;
rb_extrapolate( &player_glide.rb, co, q );
trail_system_render( &trails_glider[i], &skaterift.cam );
}
}
-
-#endif /* PLAYER_GLIDE_C */
-#ifndef PLAYER_GLIDE_H
-#define PLAYER_GLIDE_H
-
+#pragma once
#include "player.h"
+#include "player_render.h"
#include "trail.h"
-struct player_glide {
+struct player_glide
+{
struct skeleton_anim *anim_glide;
- struct player_glide_animator {
+ struct player_glide_animator
+ {
v3f root_co;
v4f root_q;
}
animator;
/* this sucks */
- struct remote_glider_animator {
+ struct remote_glider_animator
+ {
v3f root_co;
v4f root_q;
f32 s;
GLuint *glider_textures;
glmesh glider_mesh;
}
-static player_glide = {
- .parts = {
- {
- .co = { 1.0f, 0.5f, -1.0f },
- .euler = { VG_TAUf*0.25f, VG_TAUf*0.125f, 0.0f },
- .shape = k_rb_shape_capsule,
- .inf = { .h = 2.82842712475f, .r = 0.25f },
- },
- {
- .co = { -1.0f, 0.5f, -1.0f },
- .euler = { VG_TAUf*0.25f, -VG_TAUf*0.125f, 0.0f },
- .shape = k_rb_shape_capsule,
- .inf = { .h = 2.82842712475f, .r = 0.25f },
- },
- {
- .co = { 0.0f, 0.5f, 1.0f },
- .euler = { VG_TAUf*0.25f, VG_TAUf*0.25f, 0.0f },
- .shape = k_rb_shape_capsule,
- .inf = { .h = 6.0f, .r = 0.25f },
- },
- {
- .co = { 0.0f, -0.5f, 0.0f },
- .euler = { VG_TAUf*0.25f, VG_TAUf*0.25f, 0.0f },
- .shape = k_rb_shape_capsule,
- .inf = { .h = 2.0f, .r = 0.25f },
- .is_damage = 1,
- },
-
-#if 0
- {
- .co = { 0.0f, 0.0f, 0.0f },
- .euler = { 0.0f, 0.0f, 0.0f },
- .shape = k_rb_shape_sphere,
- .r = 0.5f
- }
-#endif
- }
-};
-
-static trail_system trails_glider[] = {
-{
- .width = 0.035f,
- .lifetime = 5.0f,
- .min_dist = 0.5f
-},
-{
- .width = 0.035f,
- .lifetime = 5.0f,
- .min_dist = 0.5f
-},
-};
-
-static void player_glide_pre_update(void);
-static void player_glide_update(void);
-static void player_glide_post_update(void);
-static void player_glide_animate(void);
-static void player_glide_pose( void *animator, player_pose *pose );
-
-static void player_glide_post_animate(void);
-static void player_glide_im_gui(void);
-static void player_glide_bind(void);
-static void player_glide_transition(void);
-static bool glider_physics( v2f steer );
-static void player_glide_animator_exchange( bitpack_ctx *ctx, void *data );
-static void player_glide_render( camera *cam, world_instance *world,
- player_pose *pose );
-static void render_glider_model( camera *cam, world_instance *world,
- m4x3f mmdl, enum board_shader shader );
-static void
-player_glide_remote_animator_exchange( bitpack_ctx *ctx, void *data );
-static void player_glide_equip_glider(void);
-
-struct player_subsystem_interface static player_subsystem_glide = {
- .pre_update = player_glide_pre_update,
- .update = player_glide_update,
- .post_update = player_glide_post_update,
- .animate = player_glide_animate,
- .pose = player_glide_pose,
- .post_animate = player_glide_post_animate,
- .network_animator_exchange = player_glide_animator_exchange,
- .im_gui = player_glide_im_gui,
- .bind = player_glide_bind,
-
- .animator_data = &player_glide.animator,
- .animator_size = sizeof(player_glide.animator),
- .name = "Glide"
-};
+extern player_glide;
+extern struct player_subsystem_interface player_subsystem_glide;
+
+void player_glide_pre_update(void);
+void player_glide_update(void);
+void player_glide_post_update(void);
+void player_glide_animate(void);
+void player_glide_pose( void *animator, player_pose *pose );
+
+void player_glide_post_animate(void);
+void player_glide_im_gui(void);
+void player_glide_bind(void);
+void player_glide_transition(void);
+bool glider_physics( v2f steer );
+void player_glide_animator_exchange( bitpack_ctx *ctx, void *data );
+void player_glide_render( vg_camera *cam, world_instance *world,
+ player_pose *pose );
+void render_glider_model( vg_camera *cam, world_instance *world,
+ m4x3f mmdl, enum board_shader shader );
+void player_glide_remote_animator_exchange( bitpack_ctx *ctx, void *data );
+void player_glide_equip_glider(void);
+void player_glide_render_effects( vg_camera *cam );
-#endif /* PLAYER_GLIDE_H */
#include "scene_rigidbody.h"
#include "player.h"
+#include "player_dead.h"
#include "audio.h"
+static float k_ragdoll_floatyiness = 20.0f,
+ k_ragdoll_floatydrag = 1.0f,
+ k_ragdoll_limit_scale = 1.0f,
+ k_ragdoll_spring = 127.0f,
+ k_ragdoll_dampening = 15.0f,
+ k_ragdoll_correction = 0.5f,
+ k_ragdoll_angular_drag = 0.08f,
+ k_ragdoll_active_threshold = 5.0f;
+
+static int k_ragdoll_div = 1,
+ ragdoll_frame = 0,
+ k_ragdoll_debug_collider = 1,
+ k_ragdoll_debug_constraints = 0;
+
static int dev_ragdoll_saveload(int argc, const char *argv[]){
if( argc != 2 ){
vg_info( "Usage: ragdoll load/save filepath\n" );
return 0;
}
-static void player_ragdoll_init(void){
+void player_ragdoll_init(void)
+{
VG_VAR_F32( k_ragdoll_active_threshold );
VG_VAR_F32( k_ragdoll_angular_drag );
VG_VAR_F32( k_ragdoll_correction );
vg_console_reg_cmd( "ragdoll", dev_ragdoll_saveload, NULL );
}
-static void player_init_ragdoll_bone_collider( struct skeleton_bone *bone,
- struct ragdoll_part *rp )
+void player_init_ragdoll_bone_collider( struct skeleton_bone *bone,
+ struct ragdoll_part *rp )
{
f32 k_density = 8.0f,
k_inertia_scale = 2.0f;
/*
* Get parent index in the ragdoll
*/
-static u32 ragdoll_bone_parent( struct player_ragdoll *rd, u32 bone_id ){
+u32 ragdoll_bone_parent( struct player_ragdoll *rd, u32 bone_id )
+{
for( u32 j=0; j<rd->part_count; j++ )
if( rd->parts[ j ].bone_id == bone_id )
return j;
/*
* Setup ragdoll colliders from skeleton
*/
-static void setup_ragdoll_from_skeleton( struct skeleton *sk,
- struct player_ragdoll *rd ){
+void setup_ragdoll_from_skeleton( struct skeleton *sk,
+ struct player_ragdoll *rd )
+{
rd->part_count = 0;
if( !sk->collider_count )
/*
* Make avatar copy the ragdoll
*/
-static void copy_ragdoll_pose_to_localplayer( struct player_ragdoll *rd ){
+void copy_ragdoll_pose_to_localplayer( struct player_ragdoll *rd )
+{
for( int i=0; i<rd->part_count; i++ ){
struct ragdoll_part *part = &rd->parts[i];
/*
* Make the ragdoll copy the player model
*/
-static void copy_localplayer_to_ragdoll( struct player_ragdoll *rd,
- enum player_die_type type ){
+void copy_localplayer_to_ragdoll( struct player_ragdoll *rd,
+ enum player_die_type type )
+{
v3f centroid;
v3f *bone_mtx = localplayer.final_mtx[localplayer.id_hip];
/*
* Ragdoll physics step
*/
-static void player_ragdoll_iter( struct player_ragdoll *rd ){
+void player_ragdoll_iter( struct player_ragdoll *rd )
+{
world_instance *world = world_current_instance();
int run_sim = 0;
#include "skeleton.h"
#include "vg/vg_rigidbody.h"
#include "vg/vg_rigidbody_constraints.h"
-#include "player_render.h"
struct player_ragdoll{
struct ragdoll_part{
int shoes[2];
};
-static float k_ragdoll_floatyiness = 20.0f,
- k_ragdoll_floatydrag = 1.0f,
- k_ragdoll_limit_scale = 1.0f,
- k_ragdoll_spring = 127.0f,
- k_ragdoll_dampening = 15.0f,
- k_ragdoll_correction = 0.5f,
- k_ragdoll_angular_drag = 0.08f,
- k_ragdoll_active_threshold = 5.0f;
-
-static int k_ragdoll_div = 1,
- ragdoll_frame = 0,
- k_ragdoll_debug_collider = 1,
- k_ragdoll_debug_constraints = 0;
-
enum player_die_type {
k_player_die_type_generic,
k_player_die_type_head,
k_player_die_type_feet
};
-static void player_ragdoll_init(void);
-static void player_init_ragdoll_bone_collider( struct skeleton_bone *bone,
- struct ragdoll_part *rp );
-static u32 ragdoll_bone_parent( struct player_ragdoll *rd, u32 bone_id );
-static void setup_ragdoll_from_skeleton( struct skeleton *sk,
- struct player_ragdoll *rd );
-static void copy_ragdoll_pose_to_localplayer( struct player_ragdoll *rd );
-static void copy_localplayer_to_ragdoll( struct player_ragdoll *rd,
- enum player_die_type type );
-
-static void player_debug_ragdoll(void);
-static void player_ragdoll_iter( struct player_ragdoll *rd );
+void player_ragdoll_init(void);
+void player_init_ragdoll_bone_collider( struct skeleton_bone *bone,
+ struct ragdoll_part *rp );
+u32 ragdoll_bone_parent( struct player_ragdoll *rd, u32 bone_id );
+void setup_ragdoll_from_skeleton( struct skeleton *sk,
+ struct player_ragdoll *rd );
+void copy_ragdoll_pose_to_localplayer( struct player_ragdoll *rd );
+void copy_localplayer_to_ragdoll( struct player_ragdoll *rd,
+ enum player_die_type type );
+
+void player_debug_ragdoll(void);
+void player_ragdoll_iter( struct player_ragdoll *rd );
#include "player_remote.h"
#include "skeleton.h"
#include "player_render.h"
+#include "player_api.h"
#include "network_common.h"
#include "addon.h"
#include "font.h"
#include "ent_miniworld.h"
#include "ent_region.h"
#include "shaders/model_entity.h"
+#include "vg/vg_steam_friends.h"
+
+struct global_netplayers netplayers;
static i32 k_show_own_name = 0;
-static void player_remote_clear( struct network_player *player ){
+static void player_remote_clear( struct network_player *player )
+{
addon_cache_unwatch( k_addon_type_player, player->playermodel_view_slot );
addon_cache_unwatch( k_addon_type_board, player->board_view_slot );
*
* Run if local worlds change
*/
-static void relink_all_remote_player_worlds(void){
+void relink_all_remote_player_worlds(void)
+{
for( u32 i=0; i<vg_list_size(netplayers.list); i++ ){
struct network_player *player = &netplayers.list[i];
if( player->active )
}
}
-static void player_remote_update_friendflags( struct network_player *remote ){
+void player_remote_update_friendflags( struct network_player *remote )
+{
ISteamFriends *hSteamFriends = SteamAPI_SteamFriends();
remote->isfriend = SteamAPI_ISteamFriends_HasFriend( hSteamFriends,
remote->steamid, k_EFriendFlagImmediate );
remote->steamid, k_EFriendFlagBlocked );
}
-static void player_remote_rx_200_300( SteamNetworkingMessage_t *msg ){
+void player_remote_rx_200_300( SteamNetworkingMessage_t *msg )
+{
netmsg_blank *tmp = msg->m_pData;
if( tmp->inetmsg_id == k_inetmsg_playerjoin ){
/*
* Write localplayer pose to network
*/
-static void remote_player_send_playerframe(void){
+void remote_player_send_playerframe(void)
+{
u8 sysid = localplayer.subsystem;
if( sysid >= k_player_subsystem_max ) return;
/*
* Updates network traffic stats
*/
-static void remote_player_debug_update(void){
+void remote_player_debug_update(void)
+{
if( (vg.time_real - netplayers.last_data_measurement) > 1.0 ){
netplayers.last_data_measurement = vg.time_real;
u32 total_down = 0;
/*
* Debugging information
*/
-static void remote_player_network_imgui( m4x4f pv ){
+void remote_player_network_imgui( m4x4f pv )
+{
if( network_client.user_intent == k_server_intent_online ){
if( !(steam_ready &&
(network_client.state == k_ESteamNetworkingConnectionState_Connected)))
/*
* animate remote player and store in final_mtx
*/
-static void animate_remote_player( u32 index ){
-
+void animate_remote_player( u32 index )
+{
/*
* Trys to keep the cursor inside the buffer
*/
/*
* Update full final_mtx for all remote players
*/
-static void animate_remote_players(void){
+void animate_remote_players(void)
+{
for( u32 i=0; i<vg_list_size(netplayers.list); i ++ ){
struct network_player *player = &netplayers.list[i];
if( !player->active ) continue;
/*
* Draw remote players
*/
-static void render_remote_players( world_instance *world, camera *cam ){
+void render_remote_players( world_instance *world, vg_camera *cam )
+{
u32 draw_list[ NETWORK_MAX_PLAYERS ],
draw_list_count = 0,
gliders = 0;
return 0;
}
-static void remote_players_init(void){
+void remote_players_init(void)
+{
vg_console_reg_cmd( "add_test_players", remote_players_randomize, NULL );
vg_console_reg_var( "k_show_own_name", &k_show_own_name,
k_var_dtype_i32, 0 );
}
}
-static void remote_sfx_pre_update(void){
+void remote_sfx_pre_update(void)
+{
for( u32 i=0; i<NETWORK_SFX_QUEUE_LENGTH; i ++ ){
struct net_sfx *si = &netplayers.sfx_queue[i];
ui_text( bottom, activity, 1, k_ui_align_middle_center, fg );
}
-static void remote_players_imgui_lobby(void){
+void remote_players_imgui_lobby(void)
+{
if( network_client.user_intent == k_server_intent_online ){
if( !(steam_ready &&
(network_client.state == k_ESteamNetworkingConnectionState_Connected)))
}
}
-static void remote_players_imgui_world( world_instance *world, m4x4f pv,
- f32 max_dist, int geo_cull ){
+void remote_players_imgui_world( world_instance *world, m4x4f pv,
+ f32 max_dist, int geo_cull )
+{
ui_flush( k_ui_shader_colour, vg.window_x, vg.window_y );
for( u32 i=0; i<NETWORK_MAX_PLAYERS; i++ ){
chat_send_message( buf );
}
-static void remote_players_chat_imgui(void){
+void remote_players_chat_imgui(void)
+{
if( netplayers.chatting == 1 ){
ui_rect box = { 0, 0, 400, 40 },
window = { 0, 0, vg.window_x, vg.window_y };
-#ifndef PLAYER_REMOTE_H
-#define PLAYER_REMOTE_H
-
+#pragma once
#include "player.h"
#include "network.h"
#include "network_common.h"
+#include "player_render.h"
#include "player_effects.h"
+#include "player_api.h"
+
+#include "player_skate.h"
+#include "player_walk.h"
+#include "player_dead.h"
+#include "player_basic_info.h"
+#include "player_glide.h"
#define NETWORK_SFX_QUEUE_LENGTH 12
-struct {
+struct global_netplayers
+{
struct network_player {
int active, isfriend, isblocked;
u64 steamid;
char chat_buffer[ NETWORK_MAX_CHAT ], chat_message[ NETWORK_MAX_CHAT ];
f64 chat_time;
}
-static netplayers;
-
-static void player_remote_rx_200_300( SteamNetworkingMessage_t *msg );
-static void remote_player_debug_update(void);
-static void remote_player_send_playerframe(void);
-static void animate_remote_player( u32 index );
-static void render_remote_players( world_instance *world, camera *cam );
-static void relink_all_remote_player_worlds(void);
-static void player_remote_update_friendflags( struct network_player *remote );
-
-#endif /* PLAYER_REMOTE_H */
+extern netplayers;
+
+void player_remote_rx_200_300( SteamNetworkingMessage_t *msg );
+void remote_player_debug_update(void);
+void remote_player_send_playerframe(void);
+void animate_remote_player( u32 index );
+void animate_remote_players(void);
+void render_remote_players( world_instance *world, vg_camera *cam );
+void relink_all_remote_player_worlds(void);
+void player_remote_update_friendflags( struct network_player *remote );
+void remote_players_init(void);
+void remote_sfx_pre_update(void);
+void remote_player_network_imgui( m4x4f pv );
+void remote_players_imgui_world( world_instance *world, m4x4f pv,
+ f32 max_dist, int geo_cull );
+void remote_players_imgui_lobby(void);
+void remote_players_chat_imgui(void);
-#ifndef PLAYER_RENDER_C
-#define PLAYER_RENDER_C
-
#include "player.h"
#include "player_render.h"
-#include "camera.h"
+#include "vg/vg_camera.h"
#include "player_model.h"
#include "ent_skateshop.h"
#include "audio.h"
#include "player_remote.h"
#include "player_glide.h"
-static void player_load_animation_reference( const char *path ){
+void player_load_animation_reference( const char *path )
+{
mdl_context *meta = &localplayer.skeleton_meta;
mdl_open( meta, path, vg_mem.rtmemory );
mdl_load_metadata_block( meta, vg_mem.rtmemory );
/* TODO: Standard model load */
-static void dynamic_model_load( mdl_context *ctx,
- struct dynamic_model_1texture *mdl,
- const char *path, u32 *fixup_table ){
+void dynamic_model_load( mdl_context *ctx,
+ struct dynamic_model_1texture *mdl,
+ const char *path, u32 *fixup_table )
+{
if( !mdl_arrcount( &ctx->textures ) )
vg_fatal_error( "No texture in model" );
mdl_async_load_glmesh( ctx, &mdl->mesh, fixup_table );
}
-static void dynamic_model_unload( struct dynamic_model_1texture *mdl ){
+void dynamic_model_unload( struct dynamic_model_1texture *mdl )
+{
mesh_free( &mdl->mesh );
glDeleteTextures( 1, &mdl->texture );
}
/* TODO: allow error handling */
-static void player_board_load( struct player_board *board,
- const char *path ){
-
+void player_board_load( struct player_board *board, const char *path )
+{
vg_linear_clear( vg_mem.scratch );
mdl_context ctx;
mdl_close( &ctx );
}
-static void player_board_unload( struct player_board *board ){
+void player_board_unload( struct player_board *board )
+{
dynamic_model_unload( &board->mdl );
}
-static void player_model_load( struct player_model *board, const char *path){
+void player_model_load( struct player_model *board, const char *path)
+{
vg_linear_clear( vg_mem.scratch );
mdl_context ctx;
mdl_close( &ctx );
}
-static void player_model_unload( struct player_model *board ){
+void player_model_unload( struct player_model *board )
+{
dynamic_model_unload( &board->mdl );
}
-static void apply_full_skeleton_pose( struct skeleton *sk, player_pose *pose,
- m4x3f *final_mtx ){
+void apply_full_skeleton_pose( struct skeleton *sk, player_pose *pose,
+ m4x3f *final_mtx ){
m4x3f transform;
q_m3x3( pose->root_q, transform );
v3_copy( pose->root_co, transform[3] );
}
}
-static void player__animate(void){
+void player__animate(void)
+{
struct player_subsystem_interface *sys =
player_subsystems[localplayer.subsystem];
}
}
-static void lerp_player_pose( player_pose *pose0, player_pose *pose1, f32 t,
- player_pose *posed ){
+void lerp_player_pose( player_pose *pose0, player_pose *pose1, f32 t,
+ player_pose *posed ){
struct skeleton *sk = &localplayer.skeleton;
v3_lerp( pose0->root_co, pose1->root_co, t, posed->root_co );
}
}
-static void player__observe_system( enum player_subsystem id ){
+void player__observe_system( enum player_subsystem id )
+{
if( id != localplayer.observing_system ){
struct player_subsystem_interface *sysm1 =
player_subsystems[ localplayer.observing_system ];
}
}
-static void player__animate_from_replay( replay_buffer *replay ){
+void player__animate_from_replay( replay_buffer *replay )
+{
replay_frame *frame = replay->cursor_frame,
*next = NULL;
if( frame ){
localplayer.final_mtx );
}
-static void player__pre_render(void){
+void player__pre_render(void)
+{
/* shadowing/ao info */
struct player_board *board =
addon_cache_item_if_loaded( k_addon_type_board,
m4x3_mulv( board_mtx, vp1, ubo->g_board_1 );
}
-static void render_board( camera *cam, world_instance *world,
- struct player_board *board, m4x3f root,
- struct player_board_pose *pose,
- enum board_shader shader )
+void render_board( vg_camera *cam, world_instance *world,
+ struct player_board *board, m4x3f root,
+ struct player_board_pose *pose,
+ enum board_shader shader )
{
if( !board )
board = &localplayer.fallback_board;
}
}
-static void render_playermodel( camera *cam, world_instance *world,
- int depth_compare,
- struct player_model *model,
- struct skeleton *skeleton,
- m4x3f *final_mtx ){
+void render_playermodel( vg_camera *cam, world_instance *world,
+ int depth_compare,
+ struct player_model *model,
+ struct skeleton *skeleton,
+ m4x3f *final_mtx )
+{
if( !model ) return;
shader_model_character_view_use();
mesh_draw( &model->mdl.mesh );
}
-static void player__render( camera *cam ){
+void player__render( vg_camera *cam )
+{
world_instance *world = world_current_instance();
SDL_AtomicLock( &addon_system.sl_cache_using_resources );
glDisable( GL_CULL_FACE );
}
-static void player_mirror_pose( mdl_keyframe pose[32],
- mdl_keyframe mirrored[32] ){
+void player_mirror_pose( mdl_keyframe pose[32], mdl_keyframe mirrored[32] )
+{
mdl_keyframe temp[32];
struct skeleton *sk = &localplayer.skeleton;
mirrored[i] = temp[i];
}
}
-#endif /* PLAYER_RENDER_C */
-#ifndef PLAYER_RENDER_H
-#define PLAYER_RENDER_H
-
+#pragma once
#include "model.h"
#include "skeleton.h"
-#include "camera.h"
+#include "vg/vg_camera.h"
#include "world.h"
+#include "player_render.h"
+#include "player_api.h"
+#include "player_replay.h"
enum eboard_truck{
k_board_truck_back = 0,
k_board_shader_entity
};
-static void dynamic_model_load( mdl_context *ctx,
- struct dynamic_model_1texture *mdl,
- const char *path, u32 *fixup_table );
-static void dynamic_model_unload( struct dynamic_model_1texture *mdl );
-
-static void player_board_load( struct player_board *mdl, const char *path );
-static void player_board_unload( struct player_board *mdl );
+void dynamic_model_load( mdl_context *ctx,
+ struct dynamic_model_1texture *mdl,
+ const char *path, u32 *fixup_table );
+void dynamic_model_unload( struct dynamic_model_1texture *mdl );
-static void player_model_load( struct player_model *board, const char *path);
-static void player_model_unload( struct player_model *board );
+void player_board_load( struct player_board *mdl, const char *path );
+void player_board_unload( struct player_board *mdl );
-static void render_board( camera *cam, world_instance *world,
- struct player_board *board, m4x3f root,
- struct player_board_pose *pose,
- enum board_shader shader );
+void player_model_load( struct player_model *board, const char *path);
+void player_model_unload( struct player_model *board );
-static void render_playermodel( camera *cam, world_instance *world,
- int depth_compare,
- struct player_model *model,
- struct skeleton *skeleton,
- m4x3f *final_mtx );
-static void apply_full_skeleton_pose( struct skeleton *sk, player_pose *pose,
- m4x3f *final_mtx );
-static void lerp_player_pose( player_pose *pose0, player_pose *pose1, f32 t,
- player_pose *posed );
-static void player_mirror_pose( mdl_keyframe pose[32],
- mdl_keyframe mirrored[32] );
-static void player__observe_system( enum player_subsystem id );
+void render_board( vg_camera *cam, world_instance *world,
+ struct player_board *board, m4x3f root,
+ struct player_board_pose *pose,
+ enum board_shader shader );
-#endif /* PLAYER_RENDER_H */
+void render_playermodel( vg_camera *cam, world_instance *world,
+ int depth_compare,
+ struct player_model *model,
+ struct skeleton *skeleton,
+ m4x3f *final_mtx );
+void apply_full_skeleton_pose( struct skeleton *sk, player_pose *pose,
+ m4x3f *final_mtx );
+void lerp_player_pose( player_pose *pose0, player_pose *pose1, f32 t,
+ player_pose *posed );
+void player_mirror_pose( mdl_keyframe pose[32],
+ mdl_keyframe mirrored[32] );
+void player__observe_system( enum player_subsystem id );
+void player_load_animation_reference( const char *path );
+void player__render( vg_camera *cam );
+void player__animate_from_replay( replay_buffer *replay );
+void player__animate(void);
+void player__pre_render(void);
-#ifndef PLAYER_REPLAY_C
-#define PLAYER_REPLAY_C
-
+#include "skaterift.h"
#include "player_replay.h"
#include "input.h"
#include "gui.h"
#include "freecam.h"
-static void replay_clear( replay_buffer *replay ){
+#include "player_walk.h"
+#include "player_skate.h"
+#include "player_dead.h"
+#include "player_glide.h"
+
+struct replay_globals player_replay;
+
+void replay_clear( replay_buffer *replay )
+{
replay->head = NULL;
replay->tail = NULL;
replay->cursor_frame = NULL;
replay->cursor = -99999.9;
}
-static
-void * replay_frame_data( replay_frame *frame, enum replay_framedata type ){
+void *replay_frame_data( replay_frame *frame, enum replay_framedata type )
+{
if( frame->data_table[type][1] == 0 )
return NULL;
}
}
-static int replay_seek( replay_buffer *replay, f64 t ){
+int replay_seek( replay_buffer *replay, f64 t )
+{
if( !replay->head ) return 0;
if( t < replay->tail->time ) t = replay->tail->time;
return 0;
}
-static replay_frame *replay_find_recent_stateframe( replay_buffer *replay ){
+replay_frame *replay_find_recent_stateframe( replay_buffer *replay )
+{
replay_frame *frame = replay->cursor_frame;
u32 i=4096;
while( i --> 0 ){
return NULL;
}
-static f32 replay_subframe_time( replay_buffer *replay ){
+f32 replay_subframe_time( replay_buffer *replay )
+{
replay_frame *frame = replay->cursor_frame;
if( !frame ) return 0.0f;
replay_frame *next = frame->r;
return 0.0f;
}
-static void replay_get_frame_camera( replay_frame *frame, camera *cam ){
+void replay_get_frame_camera( replay_frame *frame, vg_camera *cam )
+{
cam->fov = frame->cam_fov;
v3_copy( frame->cam_pos, cam->pos );
v3_copy( frame->cam_angles, cam->angles );
}
-static void replay_get_camera( replay_buffer *replay, camera *cam ){
+void replay_get_camera( replay_buffer *replay, vg_camera *cam )
+{
cam->nearz = 0.1f;
cam->farz = 100.0f;
if( replay->cursor_frame ){
replay_frame *next = replay->cursor_frame->r;
if( next ){
- camera temp;
+ vg_camera temp;
replay_get_frame_camera( replay->cursor_frame, cam );
replay_get_frame_camera( next, &temp );
- camera_lerp( cam, &temp, replay_subframe_time( replay ), cam );
+ vg_camera_lerp( cam, &temp, replay_subframe_time( replay ), cam );
}
else {
replay_get_frame_camera( replay->cursor_frame, cam );
v4f q;
};
-static void skaterift_record_frame( replay_buffer *replay,
- int force_gamestate ){
+void skaterift_record_frame( replay_buffer *replay, int force_gamestate )
+{
f64 delta = 9999999.9,
statedelta = 9999999.9;
/* chop end off replay */
frame->r = NULL;
- skaterift.replay.statehead = frame;
- skaterift.replay.head = frame;
- skaterift.replay.cursor_frame = frame;
- skaterift.replay.cursor = frame->time;
- skaterift.replay_control = k_replay_control_scrub;
+ player_replay.local.statehead = frame;
+ player_replay.local.head = frame;
+ player_replay.local.cursor_frame = frame;
+ player_replay.local.cursor = frame->time;
+ player_replay.replay_control = k_replay_control_scrub;
skaterift.activity = k_skaterift_default;
vg.time = frame->time;
}
static void skaterift_replay_resume(void){
- replay_frame *prev = replay_find_recent_stateframe(&skaterift.replay);
+ replay_frame *prev = replay_find_recent_stateframe(&player_replay.local);
if( prev ){
- skaterift.replay_control = k_replay_control_resume;
- skaterift.resume_target = prev;
- skaterift.resume_begin = skaterift.replay.cursor;
- skaterift.resume_transition = 0.0f;
+ player_replay.replay_control = k_replay_control_resume;
+ player_replay.resume_target = prev;
+ player_replay.resume_begin = player_replay.local.cursor;
+ player_replay.resume_transition = 0.0f;
}
gui_helper_clear();
static void skaterift_replay_update_helpers(void);
-static void skaterift_replay_pre_update(void){
+void skaterift_replay_pre_update(void)
+{
if( skaterift.activity != k_skaterift_replay ) return;
- if( skaterift.replay_control == k_replay_control_resume ){
- if( skaterift.replay.cursor_frame == skaterift.resume_target ||
- skaterift.replay.cursor_frame == NULL ){
- skaterift_restore_frame( skaterift.resume_target );
+ if( player_replay.replay_control == k_replay_control_resume )
+ {
+ if( player_replay.local.cursor_frame == player_replay.resume_target ||
+ player_replay.local.cursor_frame == NULL )
+ {
+ skaterift_restore_frame( player_replay.resume_target );
}
- else {
- vg_slewf( &skaterift.resume_transition, 1.0f,
+ else
+ {
+ vg_slewf( &player_replay.resume_transition, 1.0f,
vg.time_frame_delta * (1.0f/1.0f) );
- if( skaterift.resume_transition >= 1.0f )
- skaterift_restore_frame( skaterift.resume_target );
+ if( player_replay.resume_transition >= 1.0f )
+ skaterift_restore_frame( player_replay.resume_target );
else {
- f64 target = vg_lerp( skaterift.resume_begin,
- skaterift.resume_target->time,
- vg_smoothstepf( skaterift.resume_transition ) );
- if( replay_seek( &skaterift.replay, target ) )
- skaterift.track_velocity = 1.0f;
+ f64 target = vg_lerp( player_replay.resume_begin,
+ player_replay.resume_target->time,
+ vg_smoothstepf( player_replay.resume_transition ) );
+ if( replay_seek( &player_replay.local, target ) )
+ player_replay.track_velocity = 1.0f;
else
- skaterift.track_velocity = 0.0f;
+ player_replay.track_velocity = 0.0f;
}
}
}
else {
if( button_down( k_srbind_replay_play ) )
- skaterift.replay_control = k_replay_control_play;
+ player_replay.replay_control = k_replay_control_play;
if( button_down( k_srbind_replay_freecam ) ){
- skaterift.freecam = skaterift.freecam ^ 0x1;
-
- if( skaterift.freecam )
- replay_get_camera( &skaterift.replay, &skaterift.replay_freecam );
+ player_replay.freecam = player_replay.freecam ^ 0x1;
+ if( player_replay.freecam )
+ replay_get_camera( &player_replay.local,
+ &player_replay.replay_freecam );
skaterift_replay_update_helpers();
}
target_speed += -2.0;
if( fabsf(target_speed) > 0.01f )
- skaterift.replay_control = k_replay_control_scrub;
+ player_replay.replay_control = k_replay_control_scrub;
- if( skaterift.replay_control == k_replay_control_play )
+ if( player_replay.replay_control == k_replay_control_play )
target_speed = 1.0;
- vg_slewf( &skaterift.track_velocity, target_speed,
+ vg_slewf( &player_replay.track_velocity, target_speed,
18.0f*vg.time_frame_delta );
- if( fabsf( skaterift.track_velocity ) > 0.0001f ){
- f64 target = skaterift.replay.cursor;
- target += skaterift.track_velocity * vg.time_frame_delta;
+ if( fabsf( player_replay.track_velocity ) > 0.0001f )
+ {
+ f64 target = player_replay.local.cursor;
+ target += player_replay.track_velocity * vg.time_frame_delta;
- if( !replay_seek( &skaterift.replay, target ) )
- skaterift.track_velocity = 0.0f;
+ if( !replay_seek( &player_replay.local, target ) )
+ player_replay.track_velocity = 0.0f;
}
- if( button_down( k_srbind_mback ) ){
- if( skaterift.replay.statehead )
- skaterift_restore_frame( skaterift.replay.statehead );
+ if( button_down( k_srbind_mback ) )
+ {
+ if( player_replay.local.statehead )
+ skaterift_restore_frame( player_replay.local.statehead );
else
skaterift.activity = k_skaterift_default;
srinput.state = k_input_state_resume;
gui_helper_clear();
}
- if( skaterift.freecam ){
+ if( player_replay.freecam ){
//freecam_preupdate();
}
else {
}
static void skaterift_replay_update_helpers(void){
- skaterift.helper_resume->greyed = skaterift.freecam;
+ player_replay.helper_resume->greyed = player_replay.freecam;
vg_str freecam_text;
- vg_strnull( &freecam_text, skaterift.helper_freecam->text,
+ vg_strnull( &freecam_text, player_replay.helper_freecam->text,
GUI_HELPER_TEXT_LENGTH );
- vg_strcat( &freecam_text, skaterift.freecam? "exit freecam": "freecam" );
+ vg_strcat( &freecam_text, player_replay.freecam? "exit freecam": "freecam" );
}
-static void skaterift_replay_post_render(void){
+void skaterift_replay_post_render(void)
+{
#ifndef SR_ALLOW_REWIND_HUB
if( world_static.active_instance != k_world_purpose_client )
return;
#endif
/* capture the current resume frame at the very last point */
- if( button_down( k_srbind_reset ) ){
- if( skaterift.activity == k_skaterift_default ){
+ if( button_down( k_srbind_reset ) )
+ {
+ if( skaterift.activity == k_skaterift_default )
+ {
localplayer.rewinded_since_last_gate = 1;
skaterift.activity = k_skaterift_replay;
- skaterift_record_frame( &skaterift.replay, 1 );
- if( skaterift.replay.head ){
- skaterift.replay.cursor = skaterift.replay.head->time;
- skaterift.replay.cursor_frame = skaterift.replay.head;
+ skaterift_record_frame( &player_replay.local, 1 );
+ if( player_replay.local.head )
+ {
+ player_replay.local.cursor = player_replay.local.head->time;
+ player_replay.local.cursor_frame = player_replay.local.head;
}
- skaterift.replay_control = k_replay_control_scrub;
+ player_replay.replay_control = k_replay_control_scrub;
gui_helper_clear();
vg_str text;
if( gui_new_helper( input_axis_list[k_sraxis_replay_h], &text ) )
vg_strcat( &text, "scrub" );
- if( (skaterift.helper_resume = gui_new_helper(
+ if( (player_replay.helper_resume = gui_new_helper(
input_button_list[k_srbind_replay_resume], &text )) )
vg_strcat( &text, "resume" );
if( gui_new_helper( input_button_list[k_srbind_replay_play], &text ))
vg_strcat( &text, "playback" );
- skaterift.helper_freecam = gui_new_helper(
+ player_replay.helper_freecam = gui_new_helper(
input_button_list[k_srbind_replay_freecam], &text );
skaterift_replay_update_helpers();
}
}
-static void skaterift_replay_debug_info(void){
+void skaterift_replay_debug_info(void)
+{
player__debugtext( 2, "replay info" );
-
- replay_buffer *replay = &skaterift.replay;
+ replay_buffer *replay = &player_replay.local;
u32 head = 0,
tail = 0;
player__debugtext( 1, "cursor: %.2fs / %.2fs\n", cur, len );
}
-static void skaterift_replay_imgui(void){
+void skaterift_replay_imgui(void)
+{
if( skaterift.activity != k_skaterift_replay ) return;
- replay_buffer *replay = &skaterift.replay;
+ replay_buffer *replay = &player_replay.local;
f64 start = replay->cursor,
end = replay->cursor;
if( replay->tail ) start = replay->tail->time;
ui_text( bar, buffer, 1, k_ui_align_middle_left, 0 );
ui_text( bar, "0s", 1, k_ui_align_middle_right, 0 );
}
-
-#endif /* PLAYER_REPLAY_C */
-#ifndef PLAYER_REPLAY_H
-#define PLAYER_REPLAY_H
-
-#include "skaterift.h"
-#include "player.h"
+#pragma once
#include "player_render.h"
+#include "vg/vg_rigidbody.h"
typedef struct replay_buffer replay_buffer;
typedef struct replay_frame replay_frame;
u32 none;
};
-static int replay_seek( replay_buffer *replay, f64 t );
+struct replay_globals
+{
+ replay_buffer local;
+ replay_frame *resume_target;
+ f64 resume_begin;
+ f32 resume_transition;
+
+ enum replay_control {
+ k_replay_control_scrub,
+ k_replay_control_play,
+ k_replay_control_resume
+ }
+ replay_control;
+ f32 track_velocity;
+ struct gui_helper *helper_resume, *helper_freecam;
+
+ vg_camera replay_freecam;
+ i32 freecam;
+ v3f freecam_v, freecam_w;
+}
+extern player_replay;
-static replay_frame *replay_find_recent_stateframe( replay_buffer *replay );
-static void replay_get_camera( replay_buffer *replay, camera *cam );
-static void replay_get_frame_camera( replay_frame *frame, camera *cam );
-static f32 replay_subframe_time( replay_buffer *replay );
-static void replay_clear( replay_buffer *replay );
-static void *
+int replay_seek( replay_buffer *replay, f64 t );
+
+replay_frame *replay_find_recent_stateframe( replay_buffer *replay );
+void replay_get_camera( replay_buffer *replay, vg_camera *cam );
+void replay_get_frame_camera( replay_frame *frame, vg_camera *cam );
+f32 replay_subframe_time( replay_buffer *replay );
+void replay_clear( replay_buffer *replay );
+void *
replay_frame_data( replay_frame *frame, enum replay_framedata type );
-static void skaterift_replay_pre_update(void);
-static void skaterift_replay_imgui(void);
-static void skaterift_replay_debug_info(void);
-static void skaterift_record_frame( replay_buffer *replay,
+void skaterift_replay_pre_update(void);
+void skaterift_replay_imgui(void);
+void skaterift_replay_debug_info(void);
+void skaterift_record_frame( replay_buffer *replay,
int force_gamestate );
-
-#endif /* PLAYER_REPLAY_H */
+void skaterift_replay_post_render(void);
-#ifndef PLAYER_SKATE_C
-#define PLAYER_SKATE_C
-
+#include "player_skate.h"
#include "player.h"
#include "audio.h"
#include "vg/vg_perlin.h"
#include "menu.h"
#include "ent_skateshop.h"
#include "addon.h"
+#include "input.h"
+#include "ent_tornado.h"
-#include "ent_tornado.c"
#include "vg/vg_rigidbody.h"
#include "scene_rigidbody.h"
#include "player_glide.h"
+#include "player_dead.h"
+#include "player_walk.h"
+
+struct player_skate player_skate;
+struct player_subsystem_interface player_subsystem_skate =
+{
+ .system_register = player__skate_register,
+ .bind = player__skate_bind,
+ .pre_update = player__skate_pre_update,
+ .update = player__skate_update,
+ .post_update = player__skate_post_update,
+ .im_gui = player__skate_im_gui,
+ .animate = player__skate_animate,
+ .pose = player__skate_pose,
+ .effects = player__skate_effects,
+ .post_animate = player__skate_post_animate,
+ .network_animator_exchange = player__skate_animator_exchange,
+ .sfx_oneshot = player__skate_sfx_oneshot,
+ .sfx_comp = player__skate_comp_audio,
+ .sfx_kill = player__skate_kill_audio,
+
+ .animator_data = &player_skate.animator,
+ .animator_size = sizeof(player_skate.animator),
+ .name = "Skate"
+};
-static void player__skate_bind(void){
+void player__skate_bind(void){
struct skeleton *sk = &localplayer.skeleton;
rb_update_matrices( &localplayer.rb );
*bindings[i].anim = skeleton_get_anim( sk, bindings[i].name );
}
-static void player__skate_kill_audio(void){
+void player__skate_kill_audio(void){
audio_lock();
if( player_skate.aud_main ){
player_skate.aud_main =
return valid_count;
}
-static void player__approximate_best_trajectory(void){
+void player__approximate_best_trajectory(void)
+{
world_instance *world0 = world_current_instance();
float k_trace_delta = vg.time_fixed_delta * 10.0f;
(button_press( k_srbind_trick2 ) );
}
-static void player__skate_pre_update(void){
+void player__skate_pre_update(void){
struct player_skate_state *state = &player_skate.state;
if( state->activity == k_skate_activity_handplant ){
state->trick_type = k_trick_type_none;
}
-static void player__skate_comp_audio( void *_animator ){
+void player__skate_comp_audio( void *_animator ){
struct player_skate_animator *animator = _animator;
audio_lock();
f32 gate = skaterift.time_rate;
if( skaterift.activity == k_skaterift_replay ){
- gate = vg_minf( 1.0f, fabsf(skaterift.track_velocity) );
+ gate = vg_minf( 1.0f, fabsf(player_replay.track_velocity) );
}
f32
audio_unlock();
}
-static void player__skate_post_update(void){
+void player__skate_post_update(void){
struct player_skate_state *state = &player_skate.state;
for( int i=0; i<player_skate.possible_jump_count; i++ ){
return new_activity;
}
-static void player__skate_update(void){
+void player__skate_update(void){
struct player_skate_state *state = &player_skate.state;
world_instance *world = world_current_instance();
}
}
-static void player__skate_im_gui(void){
+void player__skate_im_gui(void){
struct player_skate_state *state = &player_skate.state;
player__debugtext( 1, "V: %5.2f %5.2f %5.2f",localplayer.rb.v[0],
localplayer.rb.v[1],
state->trick_euler[2] );
}
-static void player__skate_animate(void){
+void player__skate_animate(void){
struct player_skate_state *state = &player_skate.state;
struct player_skate_animator *animator = &player_skate.animator;
animator->handplant_t = state->handplant_t;
}
-static void player__skate_pose( void *_animator, player_pose *pose ){
+void player__skate_pose( void *_animator, player_pose *pose ){
struct skeleton *sk = &localplayer.skeleton;
struct player_skate_animator *animator = _animator;
#endif
}
-static void player__skate_effects( void *_animator, m4x3f *final_mtx,
+void player__skate_effects( void *_animator, m4x3f *final_mtx,
struct player_board *board,
struct player_effects_data *effect_data ){
struct skeleton *sk = &localplayer.skeleton;
}
}
-static void player__skate_post_animate(void){
+void player__skate_post_animate(void){
struct player_skate_state *state = &player_skate.state;
localplayer.cam_velocity_influence = 1.0f;
localplayer.cam_dist = 1.8f;
state->head_position, state->head_position );
}
-static void player__skate_reset_animator(void){
+void player__skate_reset_animator(void){
struct player_skate_state *state = &player_skate.state;
memset( &player_skate.animator, 0, sizeof(player_skate.animator) );
player_skate.animator.fly = 0.0f;
}
-static void player__skate_clear_mechanics(void){
+void player__skate_clear_mechanics(void){
struct player_skate_state *state = &player_skate.state;
state->jump_charge = 0.0f;
state->charging_jump = 0;
#include "network_compression.h"
-static void player__skate_animator_exchange( bitpack_ctx *ctx, void *data ){
+void player__skate_animator_exchange( bitpack_ctx *ctx, void *data ){
struct player_skate_animator *animator = data;
bitpack_qv3f( ctx, 24, -1024.0f, 1024.0f, animator->root_co );
bitpack_bytes( ctx, 1, &animator->activity );
}
-static void player__skate_sfx_oneshot( u8 id, v3f pos, f32 volume ){
+void player__skate_sfx_oneshot( u8 id, v3f pos, f32 volume ){
audio_lock();
if( id == k_player_skate_soundeffect_jump ){
audio_unlock();
}
-
-#endif /* PLAYER_SKATE_C */
-#ifndef PLAYER_SKATE_H
-#define PLAYER_SKATE_H
-
+#pragma once
+#include "vg/vg_audio.h"
#include "player.h"
#include "player_api.h"
limits[3];
u32 limit_count;
}
-static player_skate;
+extern player_skate;
+extern struct player_subsystem_interface player_subsystem_skate;
enum player_skate_soundeffect {
k_player_skate_soundeffect_jump,
VG_VAR_F32( k_anim_transition, flags=VG_VAR_CHEAT );
}
-static void player__skate_bind (void);
-static void player__skate_pre_update (void);
-static void player__skate_update (void);
-static void player__skate_post_update (void);
-static void player__skate_im_gui (void);
-static void player__skate_animate (void);
-static void player__skate_pose (void *animator, player_pose *pose);
-static void player__skate_effects( void *_animator, m4x3f *final_mtx,
- struct player_board *board,
- struct player_effects_data *effect_data );
-static void player__skate_post_animate (void);
-static void player__skate_animator_exchange( bitpack_ctx *ctx, void *data );
-static void player__skate_sfx_oneshot ( u8 id, v3f pos, f32 volume );
-
-static void player__skate_clear_mechanics(void);
-static void player__skate_reset_animator(void);
-static void player__approximate_best_trajectory(void);
-static void player__skate_comp_audio( void *animator );
-static void player__skate_kill_audio(void);
-
-struct player_subsystem_interface static player_subsystem_skate = {
- .system_register = player__skate_register,
- .bind = player__skate_bind,
- .pre_update = player__skate_pre_update,
- .update = player__skate_update,
- .post_update = player__skate_post_update,
- .im_gui = player__skate_im_gui,
- .animate = player__skate_animate,
- .pose = player__skate_pose,
- .effects = player__skate_effects,
- .post_animate = player__skate_post_animate,
- .network_animator_exchange = player__skate_animator_exchange,
- .sfx_oneshot = player__skate_sfx_oneshot,
- .sfx_comp = player__skate_comp_audio,
- .sfx_kill = player__skate_kill_audio,
-
- .animator_data = &player_skate.animator,
- .animator_size = sizeof(player_skate.animator),
- .name = "Skate"
-};
-
-#endif /* PLAYER_SKATE_H */
+void player__skate_bind (void);
+void player__skate_pre_update (void);
+void player__skate_update (void);
+void player__skate_post_update (void);
+void player__skate_im_gui (void);
+void player__skate_animate (void);
+void player__skate_pose (void *animator, player_pose *pose);
+void player__skate_effects( void *_animator, m4x3f *final_mtx,
+ struct player_board *board,
+ struct player_effects_data *effect_data );
+void player__skate_post_animate (void);
+void player__skate_animator_exchange( bitpack_ctx *ctx, void *data );
+void player__skate_sfx_oneshot ( u8 id, v3f pos, f32 volume );
+
+void player__skate_clear_mechanics(void);
+void player__skate_reset_animator(void);
+void player__approximate_best_trajectory(void);
+void player__skate_comp_audio( void *animator );
+void player__skate_kill_audio(void);
#pragma once
#include "vg/vg_rigidbody_collision.h"
-#include "scene_rigidbody.h"
+#include "skaterift.h"
+#include "player_walk.h"
+#include "player_skate.h"
+#include "player_dead.h"
#include "player.h"
#include "input.h"
#include "audio.h"
+#include "scene_rigidbody.h"
+
+struct player_walk player_walk;
+struct player_subsystem_interface player_subsystem_walk =
+{
+ .system_register = player__walk_register,
+ .bind = player__walk_bind,
+ .pre_update = player__walk_pre_update,
+ .update = player__walk_update,
+ .post_update = player__walk_post_update,
+ .im_gui = player__walk_im_gui,
+ .animate = player__walk_animate,
+ .post_animate = player__walk_post_animate,
+ .pose = player__walk_pose,
+ .network_animator_exchange = player__walk_animator_exchange,
+
+ .animator_data = &player_walk.animator,
+ .animator_size = sizeof(player_walk.animator),
+ .name = "Walk"
+};
+
static void player_walk_drop_in_vector( v3f vec ){
v3f axis, init_dir;
}
}
-static void player__walk_pre_update(void){
+void player__walk_pre_update(void){
struct player_walk *w = &player_walk;
if( localplayer.immobile ) return;
k_runspeed );
}
-static void player__walk_post_update(void){
+void player__walk_post_update(void){
struct player_walk *w = &player_walk;
m4x3f mtx;
audio_lock();
if( w->surface == k_surface_prop_concrete ){
audio_oneshot_3d(
- &audio_footsteps[vg_randu32(&vg.rand) %
- vg_list_size(audio_footsteps)],
+ &audio_footsteps[vg_randu32(&vg.rand) % 4],
localplayer.rb.co, 40.0f, 1.0f
);
}
else if( w->surface == k_surface_prop_grass ){
audio_oneshot_3d(
- &audio_footsteps_grass[ vg_randu32(&vg.rand) %
- vg_list_size(audio_footsteps_grass)],
+ &audio_footsteps_grass[ vg_randu32(&vg.rand) % 6 ],
localplayer.rb.co, 40.0f, 1.0f
);
}
else if( w->surface == k_surface_prop_wood ){
audio_oneshot_3d(
- &audio_footsteps_wood[ vg_randu32(&vg.rand) %
- vg_list_size(audio_footsteps_wood)],
+ &audio_footsteps_wood[ vg_randu32(&vg.rand) % 6 ],
localplayer.rb.co, 40.0f, 1.0f
);
}
w->state.step_phase = walk_phase;
}
-static void player__walk_update(void){
+void player__walk_update(void){
struct player_walk *w = &player_walk;
if( (w->state.activity == k_walk_activity_air) ||
q_mul( localplayer.rb.q, qrev, animator->root_q );
}
-static void player__walk_animate(void){
+void player__walk_animate(void){
struct player_walk *w = &player_walk;
player_pose *pose = &localplayer.pose;
struct player_walk_animator *animator = &w->animator;
skeleton_lerp_pose( sk, apose, bpose, blend, pose->keyframes );
}
-static void player__walk_pose( void *_animator, player_pose *pose ){
+void player__walk_pose( void *_animator, player_pose *pose ){
struct player_walk *w = &player_walk;
struct player_walk_animator *animator = _animator;
struct skeleton *sk = &localplayer.skeleton;
}
}
-static void player__walk_post_animate(void){
+void player__walk_post_animate(void){
/*
* Camera
*/
}
-static void player__walk_im_gui(void){
+void player__walk_im_gui(void){
struct player_walk *w = &player_walk;
player__debugtext( 1, "V: %5.2f %5.2f %5.2f (%5.2fm/s)",
localplayer.rb.v[0], localplayer.rb.v[1], localplayer.rb.v[2],
[w->surface] );
}
-static void player__walk_bind(void){
+void player__walk_bind(void){
struct player_walk *w = &player_walk;
struct skeleton *sk = &localplayer.skeleton;
w->anim_popoff = skeleton_get_anim( sk, "pop_off_short" );
}
-static void player__walk_transition( bool grounded, f32 board_yaw ){
+void player__walk_transition( bool grounded, f32 board_yaw ){
struct player_walk *w = &player_walk;
w->state.activity = k_walk_activity_air;
rb_update_matrices( &localplayer.rb );
}
-static void player__walk_reset(void){
+void player__walk_reset(void)
+{
struct player_walk *w = &player_walk;
w->state.activity = k_walk_activity_air;
w->state.transition_t = 0.0f;
rb_update_matrices( &localplayer.rb );
}
-static void player__walk_animator_exchange( bitpack_ctx *ctx, void *data ){
+void player__walk_animator_exchange( bitpack_ctx *ctx, void *data ){
struct player_walk_animator *animator = data;
bitpack_qv3f( ctx, 24, -1024.0f, 1024.0f, animator->root_co );
bitpack_qf32( ctx, 16, -100.0f, 100.0f, &animator->board_yaw );
}
-static void player__walk_sfx_oneshot( u8 id, v3f pos, f32 volume ){
+void player__walk_sfx_oneshot( u8 id, v3f pos, f32 volume ){
audio_lock();
if( id == k_player_walk_soundeffect_splash ){
-#ifndef PLAYER_WALK_H
-#define PLAYER_WALK_H
-
+#pragma once
#include "player.h"
#include "player_api.h"
#include "vg/vg_rigidbody.h"
#define PLAYER_JUMP_EPSILON 0.1 /* 100ms jump allowance */
-struct player_walk{
+struct player_walk
+{
rb_capsule collider;
struct player_walk_state{
}
animator;
}
-static player_walk;
+extern player_walk;
+extern struct player_subsystem_interface player_subsystem_walk;
enum player_walk_soundeffect {
k_player_walk_soundeffect_splash
VG_VAR_F32( k_walk_accel, flags=VG_VAR_CHEAT );
}
-static void player__walk_pre_update (void);
-static void player__walk_update (void);
-static void player__walk_post_update (void);
-static void player__walk_animate (void);
-static void player__walk_pose (void *animator, player_pose *pose);
-static void player__walk_post_animate(void);
-static void player__walk_im_gui (void);
-static void player__walk_bind (void);
-static void player__walk_reset (void);
-static void player__walk_restore (void);
-static void player__walk_animator_exchange( bitpack_ctx *ctx, void *data );
-static void player__walk_transition( bool grounded, f32 board_yaw );
-
-struct player_subsystem_interface static player_subsystem_walk = {
- .system_register = player__walk_register,
- .bind = player__walk_bind,
- .pre_update = player__walk_pre_update,
- .update = player__walk_update,
- .post_update = player__walk_post_update,
- .im_gui = player__walk_im_gui,
- .animate = player__walk_animate,
- .post_animate = player__walk_post_animate,
- .pose = player__walk_pose,
- .network_animator_exchange = player__walk_animator_exchange,
-
- .animator_data = &player_walk.animator,
- .animator_size = sizeof(player_walk.animator),
- .name = "Walk"
-};
-
-#endif /* PLAYER_WALK_H */
+void player__walk_pre_update (void);
+void player__walk_update (void);
+void player__walk_post_update (void);
+void player__walk_animate (void);
+void player__walk_pose (void *animator, player_pose *pose);
+void player__walk_post_animate(void);
+void player__walk_im_gui (void);
+void player__walk_bind (void);
+void player__walk_reset (void);
+void player__walk_restore (void);
+void player__walk_animator_exchange( bitpack_ctx *ctx, void *data );
+void player__walk_transition( bool grounded, f32 board_yaw );
--- /dev/null
+#include "render.h"
+
+struct framebuffer framebuffers[] =
+{
+ {
+ /*
+ * The primary draw target
+ */
+ "main",
+ .link = &gpipeline.fb_main,
+ .resolution_div = 1,
+ .attachments =
+ {
+ {
+ "colour", k_framebuffer_attachment_type_texture,
+
+ .internalformat = GL_RGB,
+ .format = GL_RGB,
+ .type = GL_UNSIGNED_BYTE,
+ .attachment = GL_COLOR_ATTACHMENT0
+ },
+ {
+ "motion", k_framebuffer_attachment_type_texture,
+
+ .quality = k_framebuffer_quality_high_only,
+ .internalformat = GL_RG16F,
+ .format = GL_RG,
+ .type = GL_FLOAT,
+ .attachment = GL_COLOR_ATTACHMENT1
+ },
+ {
+#if 0
+ "depth_stencil", k_framebuffer_attachment_type_renderbuffer,
+
+ .internalformat = GL_DEPTH24_STENCIL8,
+#else
+ "depth_stencil", k_framebuffer_attachment_type_texture_depth,
+ .internalformat = GL_DEPTH24_STENCIL8,
+ .format = GL_DEPTH_STENCIL,
+ .type = GL_UNSIGNED_INT_24_8,
+#endif
+ .attachment = GL_DEPTH_STENCIL_ATTACHMENT
+ }
+ }
+ },
+ {
+ /*
+ * Second rendered view from the perspective of the water reflection
+ */
+ "water_reflection",
+ .link = &gpipeline.fb_water_reflection,
+ .resolution_div = 2,
+ .attachments =
+ {
+ {
+ "colour", k_framebuffer_attachment_type_texture,
+ .internalformat = GL_RGB,
+ .format = GL_RGB,
+ .type = GL_UNSIGNED_BYTE,
+ .attachment = GL_COLOR_ATTACHMENT0
+ },
+ {
+ "depth_stencil", k_framebuffer_attachment_type_renderbuffer,
+
+ .internalformat = GL_DEPTH24_STENCIL8,
+ .attachment = GL_DEPTH_STENCIL_ATTACHMENT
+ }
+ }
+ },
+ {
+ /*
+ * Thid rendered view from the perspective of the camera, but just
+ * captures stuff thats under the water
+ */
+ "water_beneath",
+ .link = &gpipeline.fb_water_beneath,
+ .resolution_div = 2,
+ .attachments =
+ {
+ {
+ "colour", k_framebuffer_attachment_type_texture,
+ .internalformat = GL_RED,
+ .format = GL_RED,
+ .type = GL_UNSIGNED_BYTE,
+ .attachment = GL_COLOR_ATTACHMENT0
+ },
+ {
+ "depth_stencil", k_framebuffer_attachment_type_renderbuffer,
+
+ .internalformat = GL_DEPTH24_STENCIL8,
+ .attachment = GL_DEPTH_STENCIL_ATTACHMENT
+ }
+ }
+ },
+ {
+ "workshop_preview",
+ .link = &gpipeline.fb_workshop_preview,
+ .resolution_div = 0,
+ .fixed_w = WORKSHOP_PREVIEW_WIDTH, .fixed_h = WORKSHOP_PREVIEW_HEIGHT,
+ .attachments =
+ {
+ {
+ "colour", k_framebuffer_attachment_type_texture,
+ .internalformat = GL_RGB,
+ .format = GL_RGB,
+ .type = GL_UNSIGNED_BYTE,
+ .attachment = GL_COLOR_ATTACHMENT0
+ },
+ {
+ "depth_stencil", k_framebuffer_attachment_type_renderbuffer,
+ .internalformat = GL_DEPTH24_STENCIL8,
+ .attachment = GL_DEPTH_STENCIL_ATTACHMENT
+ }
+ }
+ },
+ {
+ "network_status_ui",
+ .link = &gpipeline.fb_network_status,
+ .resolution_div = 0,
+ .fixed_w = 128, .fixed_h = 48,
+ .attachments =
+ {
+ {
+ "colour", k_framebuffer_attachment_type_texture,
+ .internalformat = GL_RGB,
+ .format = GL_RGB,
+ .type = GL_UNSIGNED_BYTE,
+ .attachment = GL_COLOR_ATTACHMENT0
+ }
+ }
+ }
+};
+
+/*
+ * Get the current (automatically scaled or fixed) resolution of framebuffer
+ */
+void render_fb_get_current_res( struct framebuffer *fb, int *x, int *y )
+{
+ if( fb->resolution_div ){
+ *x = vg.window_x / fb->resolution_div;
+ *y = vg.window_y / fb->resolution_div;
+ }
+ else{
+ *x = fb->fixed_w;
+ *y = fb->fixed_h;
+ }
+}
+
+void render_fb_inverse_ratio( framebuffer *fb, v2f inverse )
+{
+ if( fb ){
+ int x, y;
+ render_fb_get_current_res( fb, &x, &y );
+
+ v2f render = { fb->render_w, fb->render_h },
+ original = { x, y };
+
+ v2_div( render, original, inverse );
+ }
+ else{
+ v2_div( (v2f){1.0f,1.0f}, (v2f){ vg.window_x, vg.window_y }, inverse );
+ }
+}
+
+/*
+ * Bind framebuffer for drawing to
+ */
+void render_fb_bind( framebuffer *fb, int use_scaling )
+{
+ int x, y;
+ render_fb_get_current_res( fb, &x, &y );
+
+ if( use_scaling ){
+ x = k_render_scale*(float)x;
+ y = k_render_scale*(float)y;
+
+ x = VG_MAX( 16, x );
+ y = VG_MAX( 16, y );
+
+ fb->render_w = x;
+ fb->render_h = y;
+ }
+
+ glBindFramebuffer( GL_FRAMEBUFFER, fb->fb );
+ glViewport( 0, 0, x, y );
+}
+
+/*
+ * Bind framebuffer attachment's texture
+ */
+void render_fb_bind_texture( framebuffer *fb, int attachment, int slot )
+{
+ struct framebuffer_attachment *at = &fb->attachments[attachment];
+
+ if( (at->purpose != k_framebuffer_attachment_type_texture) &&
+ (at->purpose != k_framebuffer_attachment_type_texture_depth) )
+ {
+ vg_fatal_error( "illegal operation: bind non-texture framebuffer"
+ " attachment to texture slot" );
+ }
+
+ glActiveTexture( GL_TEXTURE0 + slot );
+ glBindTexture( GL_TEXTURE_2D, fb->attachments[attachment].id );
+}
+
+
+/*
+ * Shaders
+ */
+
+#define FB_FORMAT_STR( E ) { E, #E },
+
+/*
+ * Convert OpenGL attachment ID enum to string
+ */
+static const char *render_fb_attachment_str( GLenum e )
+{
+ struct { GLenum e; const char *str; }
+ formats[] =
+ {
+ FB_FORMAT_STR(GL_COLOR_ATTACHMENT0)
+ FB_FORMAT_STR(GL_COLOR_ATTACHMENT1)
+ FB_FORMAT_STR(GL_COLOR_ATTACHMENT2)
+ FB_FORMAT_STR(GL_COLOR_ATTACHMENT3)
+ FB_FORMAT_STR(GL_COLOR_ATTACHMENT4)
+ FB_FORMAT_STR(GL_DEPTH_STENCIL_ATTACHMENT)
+ };
+
+ for( int i=0; i<vg_list_size(formats); i++ )
+ if( formats[i].e == e )
+ return formats[i].str;
+
+ return "UNDEFINED";
+}
+
+/*
+ * Convert OpenGL texture format enums from TexImage2D table 1,2 &
+ * RenderBufferStorage Table 1, into strings
+ */
+static const char *render_fb_format_str( GLenum format )
+{
+ struct { GLenum e; const char *str; }
+ formats[] =
+ {
+ /* Table 1 */
+ FB_FORMAT_STR(GL_DEPTH_COMPONENT)
+ FB_FORMAT_STR(GL_DEPTH_STENCIL)
+ FB_FORMAT_STR(GL_RED)
+ FB_FORMAT_STR(GL_RG)
+ FB_FORMAT_STR(GL_RGB)
+ FB_FORMAT_STR(GL_RGBA)
+
+ /* Render buffer formats */
+ FB_FORMAT_STR(GL_DEPTH_COMPONENT16)
+ FB_FORMAT_STR(GL_DEPTH_COMPONENT24)
+ FB_FORMAT_STR(GL_DEPTH_COMPONENT32F)
+ FB_FORMAT_STR(GL_DEPTH24_STENCIL8)
+ FB_FORMAT_STR(GL_DEPTH32F_STENCIL8)
+ FB_FORMAT_STR(GL_STENCIL_INDEX8)
+
+ /* Table 2 */
+ FB_FORMAT_STR(GL_R8)
+ FB_FORMAT_STR(GL_R8_SNORM)
+ FB_FORMAT_STR(GL_R16)
+ FB_FORMAT_STR(GL_R16_SNORM)
+ FB_FORMAT_STR(GL_RG8)
+ FB_FORMAT_STR(GL_RG8_SNORM)
+ FB_FORMAT_STR(GL_RG16)
+ FB_FORMAT_STR(GL_RG16_SNORM)
+ FB_FORMAT_STR(GL_R3_G3_B2)
+ FB_FORMAT_STR(GL_RGB4)
+ FB_FORMAT_STR(GL_RGB5)
+ FB_FORMAT_STR(GL_RGB8)
+ FB_FORMAT_STR(GL_RGB8_SNORM)
+ FB_FORMAT_STR(GL_RGB10)
+ FB_FORMAT_STR(GL_RGB12)
+ FB_FORMAT_STR(GL_RGB16_SNORM)
+ FB_FORMAT_STR(GL_RGBA2)
+ FB_FORMAT_STR(GL_RGBA4)
+ FB_FORMAT_STR(GL_RGB5_A1)
+ FB_FORMAT_STR(GL_RGBA8)
+ FB_FORMAT_STR(GL_RGBA8_SNORM)
+ FB_FORMAT_STR(GL_RGB10_A2)
+ FB_FORMAT_STR(GL_RGB10_A2UI)
+ FB_FORMAT_STR(GL_RGBA12)
+ FB_FORMAT_STR(GL_RGBA16)
+ FB_FORMAT_STR(GL_SRGB8)
+ FB_FORMAT_STR(GL_SRGB8_ALPHA8)
+ FB_FORMAT_STR(GL_R16F)
+ FB_FORMAT_STR(GL_RG16F)
+ FB_FORMAT_STR(GL_RGB16F)
+ FB_FORMAT_STR(GL_RGBA16F)
+ FB_FORMAT_STR(GL_R32F)
+ FB_FORMAT_STR(GL_RG32F)
+ FB_FORMAT_STR(GL_RGB32F)
+ FB_FORMAT_STR(GL_RGBA32F)
+ FB_FORMAT_STR(GL_R11F_G11F_B10F)
+ FB_FORMAT_STR(GL_RGB9_E5)
+ FB_FORMAT_STR(GL_R8I)
+ FB_FORMAT_STR(GL_R8UI)
+ FB_FORMAT_STR(GL_R16I)
+ FB_FORMAT_STR(GL_R16UI)
+ FB_FORMAT_STR(GL_R32I)
+ FB_FORMAT_STR(GL_R32UI)
+ FB_FORMAT_STR(GL_RG8I)
+ FB_FORMAT_STR(GL_RG8UI)
+ FB_FORMAT_STR(GL_RG16I)
+ FB_FORMAT_STR(GL_RG16UI)
+ FB_FORMAT_STR(GL_RG32I)
+ FB_FORMAT_STR(GL_RG32UI)
+ FB_FORMAT_STR(GL_RGB8I)
+ FB_FORMAT_STR(GL_RGB8UI)
+ FB_FORMAT_STR(GL_RGB16I)
+ FB_FORMAT_STR(GL_RGB16UI)
+ FB_FORMAT_STR(GL_RGB32I)
+ FB_FORMAT_STR(GL_RGB32UI)
+ FB_FORMAT_STR(GL_RGBA8I)
+ FB_FORMAT_STR(GL_RGBA8UI)
+ FB_FORMAT_STR(GL_RGBA16I)
+ FB_FORMAT_STR(GL_RGBA16UI)
+ FB_FORMAT_STR(GL_RGBA32I)
+ FB_FORMAT_STR(GL_RGBA32UI)
+ };
+
+ for( int i=0; i<vg_list_size(formats); i++ )
+ if( formats[i].e == format )
+ return formats[i].str;
+
+ return "UNDEFINED";
+}
+
+/*
+ * Bind and allocate texture for framebuffer attachment
+ */
+static void render_fb_allocate_texture( struct framebuffer *fb,
+ struct framebuffer_attachment *a )
+{
+ int rx, ry;
+ render_fb_get_current_res( fb, &rx, &ry );
+
+ if( a->purpose == k_framebuffer_attachment_type_renderbuffer ){
+ glBindRenderbuffer( GL_RENDERBUFFER, a->id );
+ glRenderbufferStorage( GL_RENDERBUFFER, a->internalformat, rx, ry );
+ }
+ else if( a->purpose == k_framebuffer_attachment_type_texture ||
+ a->purpose == k_framebuffer_attachment_type_texture_depth )
+ {
+ glBindTexture( GL_TEXTURE_2D, a->id );
+ glTexImage2D( GL_TEXTURE_2D, 0, a->internalformat, rx, ry,
+ 0, a->format, a->type, NULL );
+ }
+}
+
+/*
+ * Full allocation of a framebuffer
+ */
+void render_fb_allocate( struct framebuffer *fb )
+{
+ glGenFramebuffers( 1, &fb->fb );
+ glBindFramebuffer( GL_FRAMEBUFFER, fb->fb );
+
+ int rx, ry;
+ render_fb_get_current_res( fb, &rx, &ry );
+
+ vg_info( "allocate_framebuffer( %s, %dx%d )\n", fb->display_name, rx, ry );
+ vg_info( "{\n" );
+
+ GLenum colour_attachments[4];
+ u32 colour_count = 0;
+
+ for( int j=0; j<vg_list_size(fb->attachments); j++ ){
+ struct framebuffer_attachment *attachment = &fb->attachments[j];
+
+ if( attachment->purpose == k_framebuffer_attachment_type_none )
+ continue;
+
+ vg_info( " %s: %s\n",
+ render_fb_attachment_str( attachment->attachment ),
+ render_fb_format_str( attachment->internalformat ) );
+
+ if( attachment->purpose == k_framebuffer_attachment_type_renderbuffer ){
+ glGenRenderbuffers( 1, &attachment->id );
+ render_fb_allocate_texture( fb, attachment );
+ glFramebufferRenderbuffer( GL_FRAMEBUFFER,
+ GL_DEPTH_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER, attachment->id );
+ }
+ else if( attachment->purpose == k_framebuffer_attachment_type_texture ||
+ attachment->purpose == k_framebuffer_attachment_type_texture_depth )
+ {
+ glGenTextures( 1, &attachment->id );
+ render_fb_allocate_texture( fb, attachment );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
+
+ glFramebufferTexture2D( GL_FRAMEBUFFER, attachment->attachment,
+ GL_TEXTURE_2D, attachment->id, 0 );
+
+ if( attachment->purpose == k_framebuffer_attachment_type_texture )
+ colour_attachments[ colour_count ++ ] = attachment->attachment;
+ }
+ }
+
+ glDrawBuffers( colour_count, colour_attachments );
+
+ /*
+ * Check result
+ */
+ GLenum result = glCheckFramebufferStatus( GL_FRAMEBUFFER );
+
+ if( result == GL_FRAMEBUFFER_COMPLETE ){
+ /*
+ * Attatch to gpipeline
+ */
+ if( fb->link )
+ *fb->link = fb;
+
+ vg_success( " status: complete\n" );
+ vg_info( "}\n" );
+ }
+ else{
+ if( result == GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT )
+ vg_error( " status: Incomplete attachment" );
+ else if( result == GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT )
+ vg_error( " status: Missing attachment" );
+ else if( result == GL_FRAMEBUFFER_UNSUPPORTED )
+ vg_error( " status: Unsupported framebuffer format" );
+ else
+ vg_error( " status: Generic Error" );
+
+ vg_info( "}\n" );
+ vg_fatal_error( "Incomplete framebuffer (see logs)" );
+ }
+}
+
+/*
+ * Resize/Update all framebuffers(we know about)
+ */
+void render_fb_resize(void)
+{
+ if( !gpipeline.ready ) return;
+
+ for( int i=0; i<vg_list_size(framebuffers); i++ ){
+ struct framebuffer *fb = &framebuffers[i];
+ for( int j=0; j<vg_list_size(fb->attachments); j++ ){
+ struct framebuffer_attachment *attachment = &fb->attachments[j];
+ render_fb_allocate_texture( fb, attachment );
+ }
+ }
+}
+
+static int render_framebuffer_control( int argc, char const *argv[] );
+static void render_framebuffer_poll( int argc, char const *argv[] );
+
+static void async_render_init( void *payload, u32 size )
+{
+ /*
+ * Complete Framebuffers
+ */
+ for( int i=0; i<vg_list_size(framebuffers); i++ ){
+ struct framebuffer *fb = &framebuffers[i];
+ render_fb_allocate( fb );
+ }
+
+ f32 rh = 0x1p-4f, ih = 0.3f;
+
+ float quad[] = {
+ 0.00f,0.00f, 1.00f,1.00f, 0.00f,1.00f, /* fsquad */
+ 0.00f,0.00f, 1.00f,0.00f, 1.00f,1.00f,
+
+ 0.00f,0.00f, 1.00f,rh, 0.00f,rh, /* fsquad1 */
+ 0.00f,0.00f, 1.00f,0.00f, 1.00f,rh,
+
+ /* 9x9 debug grid */
+ /* row0 */
+ 0.00f,0.00f, 0.30f,0.30f, 0.00f,0.30f,
+ 0.00f,0.00f, 0.30f,0.00f, 0.30f,0.30f,
+ 0.30f,0.00f, 0.60f,0.30f, 0.30f,0.30f,
+ 0.30f,0.00f, 0.60f,0.00f, 0.60f,0.30f,
+ 0.60f,0.00f, 0.90f,0.30f, 0.60f,0.30f,
+ 0.60f,0.00f, 0.90f,0.00f, 0.90f,0.30f,
+ /* row1 */
+ 0.00f,0.30f, 0.30f,0.60f, 0.00f,0.60f,
+ 0.00f,0.30f, 0.30f,0.30f, 0.30f,0.60f,
+ 0.30f,0.30f, 0.60f,0.60f, 0.30f,0.60f,
+ 0.30f,0.30f, 0.60f,0.30f, 0.60f,0.60f,
+ 0.60f,0.30f, 0.90f,0.60f, 0.60f,0.60f,
+ 0.60f,0.30f, 0.90f,0.30f, 0.90f,0.60f,
+ /* row2 */
+ 0.00f,0.60f, 0.30f,0.90f, 0.00f,0.90f,
+ 0.00f,0.60f, 0.30f,0.60f, 0.30f,0.90f,
+ 0.30f,0.60f, 0.60f,0.90f, 0.30f,0.90f,
+ 0.30f,0.60f, 0.60f,0.60f, 0.60f,0.90f,
+ 0.60f,0.60f, 0.90f,0.90f, 0.60f,0.90f,
+ 0.60f,0.60f, 0.90f,0.60f, 0.90f,0.90f,
+
+ 0.00f,ih, 1.00f,ih+rh, 0.00f,ih+rh, /* fsquad2 */
+ 0.00f,ih, 1.00f,ih, 1.00f,ih+rh,
+ };
+
+ glGenVertexArrays( 1, &gpipeline.fsquad.vao );
+ glGenBuffers( 1, &gpipeline.fsquad.vbo );
+ glBindVertexArray( gpipeline.fsquad.vao );
+ glBindBuffer( GL_ARRAY_BUFFER, gpipeline.fsquad.vbo );
+ glBufferData( GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STATIC_DRAW );
+ glBindVertexArray( gpipeline.fsquad.vao );
+ glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE,
+ sizeof(float)*2, (void*)0 );
+ glEnableVertexAttribArray( 0 );
+
+ VG_CHECK_GL_ERR();
+
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ gpipeline.ready = 1;
+}
+
+void render_init(void)
+{
+ vg_console_reg_var( "blur_strength", &k_blur_strength, k_var_dtype_f32, 0 );
+ vg_console_reg_var( "render_scale", &k_render_scale,
+ k_var_dtype_f32, VG_VAR_PERSISTENT );
+ vg_console_reg_var( "fov", &k_fov, k_var_dtype_f32, VG_VAR_PERSISTENT );
+ vg_console_reg_var( "cam_height", &k_cam_height,
+ k_var_dtype_f32, VG_VAR_PERSISTENT );
+ vg_console_reg_var( "blur_effect", &k_blur_effect,
+ k_var_dtype_i32, VG_VAR_PERSISTENT );
+
+ vg_console_reg_cmd( "fb", render_framebuffer_control,
+ render_framebuffer_poll );
+
+ vg_async_call( async_render_init, NULL, 0 );
+}
+
+/*
+ * Utility
+ */
+void render_fsquad(void)
+{
+ glBindVertexArray( gpipeline.fsquad.vao );
+ glDrawArrays( GL_TRIANGLES, 0, 6 );
+}
+
+void render_fsquad1(void)
+{
+ glBindVertexArray( gpipeline.fsquad.vao );
+ glDrawArrays( GL_TRIANGLES, 6, 6 );
+}
+
+void render_fsquad2(void)
+{
+ glBindVertexArray( gpipeline.fsquad.vao );
+ glDrawArrays( GL_TRIANGLES, 66,6 );
+}
+
+/*
+ * Call this inside the UI function
+ */
+void render_view_framebuffer_ui(void)
+{
+#if 0
+ int viewing_count = 0;
+
+ glBindVertexArray( gpipeline.fsquad.vao );
+ shader_blit_use();
+ shader_blit_uTexMain( 0 );
+
+ v2f identity = { 1.0f, 1.0f };
+ shader_blit_uInverseRatio( identity );
+
+ for( int i=0; i<vg_list_size(framebuffers); i++ ){
+ struct framebuffer *fb = &framebuffers[i];
+
+ for( int j=0; j<vg_list_size(fb->attachments); j++ ){
+ struct framebuffer_attachment *at = &fb->attachments[j];
+
+ if( !at->debug_view )
+ continue;
+
+ v2f corner,
+ window = { vg.window_x, vg.window_y };
+
+ corner[0] = viewing_count % 3;
+ corner[1] = 1 + (viewing_count / 3);
+ v2_mul( corner, window, corner );
+ v2_muls( corner, 0.3f, corner );
+ corner[1] = vg.window_y - corner[1];
+
+ ui_text( (ui_rect){ corner[0], corner[1], 0.0f, 0.0f },
+ fb->display_name, 2, k_text_align_left );
+ ui_text( (ui_rect){ corner[0], corner[1] + 32, 0.0f, 0.0f, },
+ at->display_name, 1, k_text_align_left );
+
+ if( at->purpose == k_framebuffer_attachment_type_renderbuffer ){
+ v2f center;
+ v2_muladds( corner, window, 0.15f, center );
+
+ ui_text( (ui_rect){ center[0], center[1], 0.0f, 0.0f },
+ "<hardware texture>", 1, k_text_align_center );
+ }
+ else{
+ render_fb_bind_texture( fb, j, 0 );
+
+ int start = (viewing_count+2) * 6,
+ count = 6;
+ glDrawArrays( GL_TRIANGLES, start, count );
+ }
+
+ viewing_count ++;
+ }
+ }
+#endif
+}
+
+static void render_framebuffer_show( struct framebuffer *fb,
+ struct framebuffer_attachment *at,
+ int operation )
+{
+ at->debug_view = operation;
+ vg_info( "%s %s:%s\n", (operation?"shown": "hidden"),
+ fb->display_name, at->display_name );
+}
+
+/*
+ * arg0: command "show"/"hide"
+ * arg1: framebuffer name <name>/"all"
+ * arg2: subname <name>/none
+ */
+static int render_framebuffer_control( int argc, char const *argv[] )
+{
+ if( argc < 2 ){
+ vg_error( "Usage: fb \"show/hide\" <name>/\"all\" <name>/none\n" );
+ return 0;
+ }
+
+ int modify_all = 0,
+ operation = 0;
+
+ if( !strcmp( argv[0], "show" ) )
+ operation = 1;
+ else if( !strcmp( argv[0], "hide" ) )
+ operation = 0;
+ else{
+ vg_error( "Unknown framebuffer operation: '%s'\n", argv[0] );
+ return 0;
+ }
+
+ if( !strcmp( argv[1], "all" ) )
+ modify_all = 1;
+
+ for( int i=0; i<vg_list_size(framebuffers); i++ ){
+ struct framebuffer *fb = &framebuffers[i];
+
+ for( int j=0; j<vg_list_size(fb->attachments); j++ ){
+ struct framebuffer_attachment *at = &fb->attachments[j];
+
+ if( at->purpose == k_framebuffer_attachment_type_none )
+ continue;
+
+ if( modify_all ){
+ render_framebuffer_show( fb, at, operation );
+ }
+ else{
+ if( !strcmp( fb->display_name, argv[1] ) ){
+ if( argc == 2 )
+ render_framebuffer_show( fb, at, operation );
+ else if( !strcmp( at->display_name, argv[2] ) )
+ render_framebuffer_show( fb, at, operation );
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+static void render_framebuffer_poll( int argc, char const *argv[] )
+{
+ const char *term = argv[argc-1];
+
+ if( argc == 1 ){
+ console_suggest_score_text( "show", term, 0 );
+ console_suggest_score_text( "hide", term, 0 );
+ }
+ else if( argc == 2 ){
+ console_suggest_score_text( "all", term, 0 );
+
+ for( int i=0; i<vg_list_size(framebuffers); i++ ){
+ struct framebuffer *fb = &framebuffers[i];
+ console_suggest_score_text( fb->display_name, term, 0 );
+ }
+ }
+ else if( argc == 3 ){
+ int modify_all = 0;
+
+ if( !strcmp( argv[1], "all" ) )
+ modify_all = 1;
+
+ for( int i=0; i<vg_list_size(framebuffers); i++ ){
+ struct framebuffer *fb = &framebuffers[i];
+
+ for( int j=0; j<vg_list_size(fb->attachments); j++ ){
+ struct framebuffer_attachment *at = &fb->attachments[j];
+
+ if( at->purpose == k_framebuffer_attachment_type_none )
+ continue;
+
+ if( modify_all ){
+ console_suggest_score_text( at->display_name, term, 0 );
+ }
+ else if( !strcmp( fb->display_name, argv[1] ) ){
+ console_suggest_score_text( at->display_name, term, 0 );
+ }
+ }
+ }
+ }
+}
/*
* Copyright (C) 2021-2022 Mt.ZERO Software, Harry Godden - All Rights Reserved
*/
-
+#pragma once
#include "common.h"
#include "model.h"
#include "camera.h"
-#include "world.h"
#include "shaders/blit.h"
#include "shaders/blitblur.h"
#define WORKSHOP_PREVIEW_WIDTH 504
#define WORKSHOP_PREVIEW_HEIGHT 336
-#ifndef RENDER_H
-#define RENDER_H
static f32 k_render_scale = 1.0f;
static i32 k_blur_effect = 1;
GLuint fb;
framebuffer **link;
}
-framebuffers[] =
-{
- {
- /*
- * The primary draw target
- */
- "main",
- .link = &gpipeline.fb_main,
- .resolution_div = 1,
- .attachments =
- {
- {
- "colour", k_framebuffer_attachment_type_texture,
-
- .internalformat = GL_RGB,
- .format = GL_RGB,
- .type = GL_UNSIGNED_BYTE,
- .attachment = GL_COLOR_ATTACHMENT0
- },
- {
- "motion", k_framebuffer_attachment_type_texture,
-
- .quality = k_framebuffer_quality_high_only,
- .internalformat = GL_RG16F,
- .format = GL_RG,
- .type = GL_FLOAT,
- .attachment = GL_COLOR_ATTACHMENT1
- },
- {
-#if 0
- "depth_stencil", k_framebuffer_attachment_type_renderbuffer,
-
- .internalformat = GL_DEPTH24_STENCIL8,
-#else
- "depth_stencil", k_framebuffer_attachment_type_texture_depth,
- .internalformat = GL_DEPTH24_STENCIL8,
- .format = GL_DEPTH_STENCIL,
- .type = GL_UNSIGNED_INT_24_8,
-#endif
- .attachment = GL_DEPTH_STENCIL_ATTACHMENT
- }
- }
- },
- {
- /*
- * Second rendered view from the perspective of the water reflection
- */
- "water_reflection",
- .link = &gpipeline.fb_water_reflection,
- .resolution_div = 2,
- .attachments =
- {
- {
- "colour", k_framebuffer_attachment_type_texture,
- .internalformat = GL_RGB,
- .format = GL_RGB,
- .type = GL_UNSIGNED_BYTE,
- .attachment = GL_COLOR_ATTACHMENT0
- },
- {
- "depth_stencil", k_framebuffer_attachment_type_renderbuffer,
-
- .internalformat = GL_DEPTH24_STENCIL8,
- .attachment = GL_DEPTH_STENCIL_ATTACHMENT
- }
- }
- },
- {
- /*
- * Thid rendered view from the perspective of the camera, but just
- * captures stuff thats under the water
- */
- "water_beneath",
- .link = &gpipeline.fb_water_beneath,
- .resolution_div = 2,
- .attachments =
- {
- {
- "colour", k_framebuffer_attachment_type_texture,
- .internalformat = GL_RED,
- .format = GL_RED,
- .type = GL_UNSIGNED_BYTE,
- .attachment = GL_COLOR_ATTACHMENT0
- },
- {
- "depth_stencil", k_framebuffer_attachment_type_renderbuffer,
-
- .internalformat = GL_DEPTH24_STENCIL8,
- .attachment = GL_DEPTH_STENCIL_ATTACHMENT
- }
- }
- },
- {
- "workshop_preview",
- .link = &gpipeline.fb_workshop_preview,
- .resolution_div = 0,
- .fixed_w = WORKSHOP_PREVIEW_WIDTH, .fixed_h = WORKSHOP_PREVIEW_HEIGHT,
- .attachments =
- {
- {
- "colour", k_framebuffer_attachment_type_texture,
- .internalformat = GL_RGB,
- .format = GL_RGB,
- .type = GL_UNSIGNED_BYTE,
- .attachment = GL_COLOR_ATTACHMENT0
- },
- {
- "depth_stencil", k_framebuffer_attachment_type_renderbuffer,
- .internalformat = GL_DEPTH24_STENCIL8,
- .attachment = GL_DEPTH_STENCIL_ATTACHMENT
- }
- }
- },
- {
- "network_status_ui",
- .link = &gpipeline.fb_network_status,
- .resolution_div = 0,
- .fixed_w = 128, .fixed_h = 48,
- .attachments =
- {
- {
- "colour", k_framebuffer_attachment_type_texture,
- .internalformat = GL_RGB,
- .format = GL_RGB,
- .type = GL_UNSIGNED_BYTE,
- .attachment = GL_COLOR_ATTACHMENT0
- }
- }
- }
-};
-
-/*
- * Get the current (automatically scaled or fixed) resolution of framebuffer
- */
-static void render_fb_get_current_res( struct framebuffer *fb,
- int *x, int *y )
-{
- if( fb->resolution_div ){
- *x = vg.window_x / fb->resolution_div;
- *y = vg.window_y / fb->resolution_div;
- }
- else{
- *x = fb->fixed_w;
- *y = fb->fixed_h;
- }
-}
-
-static void render_fb_inverse_ratio( framebuffer *fb, v2f inverse )
-{
- if( fb ){
- int x, y;
- render_fb_get_current_res( fb, &x, &y );
-
- v2f render = { fb->render_w, fb->render_h },
- original = { x, y };
-
- v2_div( render, original, inverse );
- }
- else{
- v2_div( (v2f){1.0f,1.0f}, (v2f){ vg.window_x, vg.window_y }, inverse );
- }
-}
-
-/*
- * Bind framebuffer for drawing to
- */
-static void render_fb_bind( framebuffer *fb, int use_scaling )
-{
- int x, y;
- render_fb_get_current_res( fb, &x, &y );
-
- if( use_scaling ){
- x = k_render_scale*(float)x;
- y = k_render_scale*(float)y;
-
- x = VG_MAX( 16, x );
- y = VG_MAX( 16, y );
-
- fb->render_w = x;
- fb->render_h = y;
- }
-
- glBindFramebuffer( GL_FRAMEBUFFER, fb->fb );
- glViewport( 0, 0, x, y );
-}
-
-/*
- * Bind framebuffer attachment's texture
- */
-static void render_fb_bind_texture( framebuffer *fb,
- int attachment, int slot )
-{
- struct framebuffer_attachment *at = &fb->attachments[attachment];
-
- if( (at->purpose != k_framebuffer_attachment_type_texture) &&
- (at->purpose != k_framebuffer_attachment_type_texture_depth) )
- {
- vg_fatal_error( "illegal operation: bind non-texture framebuffer"
- " attachment to texture slot" );
- }
-
- glActiveTexture( GL_TEXTURE0 + slot );
- glBindTexture( GL_TEXTURE_2D, fb->attachments[attachment].id );
-}
-
-
-/*
- * Shaders
- */
-
-#define FB_FORMAT_STR( E ) { E, #E },
-
-/*
- * Convert OpenGL attachment ID enum to string
- */
-static const char *render_fb_attachment_str( GLenum e )
-{
- struct { GLenum e; const char *str; }
- formats[] =
- {
- FB_FORMAT_STR(GL_COLOR_ATTACHMENT0)
- FB_FORMAT_STR(GL_COLOR_ATTACHMENT1)
- FB_FORMAT_STR(GL_COLOR_ATTACHMENT2)
- FB_FORMAT_STR(GL_COLOR_ATTACHMENT3)
- FB_FORMAT_STR(GL_COLOR_ATTACHMENT4)
- FB_FORMAT_STR(GL_DEPTH_STENCIL_ATTACHMENT)
- };
-
- for( int i=0; i<vg_list_size(formats); i++ )
- if( formats[i].e == e )
- return formats[i].str;
-
- return "UNDEFINED";
-}
-
-/*
- * Convert OpenGL texture format enums from TexImage2D table 1,2 &
- * RenderBufferStorage Table 1, into strings
- */
-static const char *render_fb_format_str( GLenum format )
-{
- struct { GLenum e; const char *str; }
- formats[] =
- {
- /* Table 1 */
- FB_FORMAT_STR(GL_DEPTH_COMPONENT)
- FB_FORMAT_STR(GL_DEPTH_STENCIL)
- FB_FORMAT_STR(GL_RED)
- FB_FORMAT_STR(GL_RG)
- FB_FORMAT_STR(GL_RGB)
- FB_FORMAT_STR(GL_RGBA)
-
- /* Render buffer formats */
- FB_FORMAT_STR(GL_DEPTH_COMPONENT16)
- FB_FORMAT_STR(GL_DEPTH_COMPONENT24)
- FB_FORMAT_STR(GL_DEPTH_COMPONENT32F)
- FB_FORMAT_STR(GL_DEPTH24_STENCIL8)
- FB_FORMAT_STR(GL_DEPTH32F_STENCIL8)
- FB_FORMAT_STR(GL_STENCIL_INDEX8)
-
- /* Table 2 */
- FB_FORMAT_STR(GL_R8)
- FB_FORMAT_STR(GL_R8_SNORM)
- FB_FORMAT_STR(GL_R16)
- FB_FORMAT_STR(GL_R16_SNORM)
- FB_FORMAT_STR(GL_RG8)
- FB_FORMAT_STR(GL_RG8_SNORM)
- FB_FORMAT_STR(GL_RG16)
- FB_FORMAT_STR(GL_RG16_SNORM)
- FB_FORMAT_STR(GL_R3_G3_B2)
- FB_FORMAT_STR(GL_RGB4)
- FB_FORMAT_STR(GL_RGB5)
- FB_FORMAT_STR(GL_RGB8)
- FB_FORMAT_STR(GL_RGB8_SNORM)
- FB_FORMAT_STR(GL_RGB10)
- FB_FORMAT_STR(GL_RGB12)
- FB_FORMAT_STR(GL_RGB16_SNORM)
- FB_FORMAT_STR(GL_RGBA2)
- FB_FORMAT_STR(GL_RGBA4)
- FB_FORMAT_STR(GL_RGB5_A1)
- FB_FORMAT_STR(GL_RGBA8)
- FB_FORMAT_STR(GL_RGBA8_SNORM)
- FB_FORMAT_STR(GL_RGB10_A2)
- FB_FORMAT_STR(GL_RGB10_A2UI)
- FB_FORMAT_STR(GL_RGBA12)
- FB_FORMAT_STR(GL_RGBA16)
- FB_FORMAT_STR(GL_SRGB8)
- FB_FORMAT_STR(GL_SRGB8_ALPHA8)
- FB_FORMAT_STR(GL_R16F)
- FB_FORMAT_STR(GL_RG16F)
- FB_FORMAT_STR(GL_RGB16F)
- FB_FORMAT_STR(GL_RGBA16F)
- FB_FORMAT_STR(GL_R32F)
- FB_FORMAT_STR(GL_RG32F)
- FB_FORMAT_STR(GL_RGB32F)
- FB_FORMAT_STR(GL_RGBA32F)
- FB_FORMAT_STR(GL_R11F_G11F_B10F)
- FB_FORMAT_STR(GL_RGB9_E5)
- FB_FORMAT_STR(GL_R8I)
- FB_FORMAT_STR(GL_R8UI)
- FB_FORMAT_STR(GL_R16I)
- FB_FORMAT_STR(GL_R16UI)
- FB_FORMAT_STR(GL_R32I)
- FB_FORMAT_STR(GL_R32UI)
- FB_FORMAT_STR(GL_RG8I)
- FB_FORMAT_STR(GL_RG8UI)
- FB_FORMAT_STR(GL_RG16I)
- FB_FORMAT_STR(GL_RG16UI)
- FB_FORMAT_STR(GL_RG32I)
- FB_FORMAT_STR(GL_RG32UI)
- FB_FORMAT_STR(GL_RGB8I)
- FB_FORMAT_STR(GL_RGB8UI)
- FB_FORMAT_STR(GL_RGB16I)
- FB_FORMAT_STR(GL_RGB16UI)
- FB_FORMAT_STR(GL_RGB32I)
- FB_FORMAT_STR(GL_RGB32UI)
- FB_FORMAT_STR(GL_RGBA8I)
- FB_FORMAT_STR(GL_RGBA8UI)
- FB_FORMAT_STR(GL_RGBA16I)
- FB_FORMAT_STR(GL_RGBA16UI)
- FB_FORMAT_STR(GL_RGBA32I)
- FB_FORMAT_STR(GL_RGBA32UI)
- };
-
- for( int i=0; i<vg_list_size(formats); i++ )
- if( formats[i].e == format )
- return formats[i].str;
-
- return "UNDEFINED";
-}
-
-/*
- * Bind and allocate texture for framebuffer attachment
- */
-static void render_fb_allocate_texture( struct framebuffer *fb,
- struct framebuffer_attachment *a )
-{
- int rx, ry;
- render_fb_get_current_res( fb, &rx, &ry );
-
- if( a->purpose == k_framebuffer_attachment_type_renderbuffer ){
- glBindRenderbuffer( GL_RENDERBUFFER, a->id );
- glRenderbufferStorage( GL_RENDERBUFFER, a->internalformat, rx, ry );
- }
- else if( a->purpose == k_framebuffer_attachment_type_texture ||
- a->purpose == k_framebuffer_attachment_type_texture_depth )
- {
- glBindTexture( GL_TEXTURE_2D, a->id );
- glTexImage2D( GL_TEXTURE_2D, 0, a->internalformat, rx, ry,
- 0, a->format, a->type, NULL );
- }
-}
-
-/*
- * Full allocation of a framebuffer
- */
-static void render_fb_allocate( struct framebuffer *fb )
-{
- glGenFramebuffers( 1, &fb->fb );
- glBindFramebuffer( GL_FRAMEBUFFER, fb->fb );
-
- int rx, ry;
- render_fb_get_current_res( fb, &rx, &ry );
-
- vg_info( "allocate_framebuffer( %s, %dx%d )\n", fb->display_name, rx, ry );
- vg_info( "{\n" );
-
- GLenum colour_attachments[4];
- u32 colour_count = 0;
-
- for( int j=0; j<vg_list_size(fb->attachments); j++ ){
- struct framebuffer_attachment *attachment = &fb->attachments[j];
-
- if( attachment->purpose == k_framebuffer_attachment_type_none )
- continue;
-
- vg_info( " %s: %s\n",
- render_fb_attachment_str( attachment->attachment ),
- render_fb_format_str( attachment->internalformat ) );
-
- if( attachment->purpose == k_framebuffer_attachment_type_renderbuffer ){
- glGenRenderbuffers( 1, &attachment->id );
- render_fb_allocate_texture( fb, attachment );
- glFramebufferRenderbuffer( GL_FRAMEBUFFER,
- GL_DEPTH_STENCIL_ATTACHMENT,
- GL_RENDERBUFFER, attachment->id );
- }
- else if( attachment->purpose == k_framebuffer_attachment_type_texture ||
- attachment->purpose == k_framebuffer_attachment_type_texture_depth )
- {
- glGenTextures( 1, &attachment->id );
- render_fb_allocate_texture( fb, attachment );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
-
- glFramebufferTexture2D( GL_FRAMEBUFFER, attachment->attachment,
- GL_TEXTURE_2D, attachment->id, 0 );
-
- if( attachment->purpose == k_framebuffer_attachment_type_texture )
- colour_attachments[ colour_count ++ ] = attachment->attachment;
- }
- }
-
- glDrawBuffers( colour_count, colour_attachments );
-
- /*
- * Check result
- */
- GLenum result = glCheckFramebufferStatus( GL_FRAMEBUFFER );
-
- if( result == GL_FRAMEBUFFER_COMPLETE ){
- /*
- * Attatch to gpipeline
- */
- if( fb->link )
- *fb->link = fb;
-
- vg_success( " status: complete\n" );
- vg_info( "}\n" );
- }
- else{
- if( result == GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT )
- vg_error( " status: Incomplete attachment" );
- else if( result == GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT )
- vg_error( " status: Missing attachment" );
- else if( result == GL_FRAMEBUFFER_UNSUPPORTED )
- vg_error( " status: Unsupported framebuffer format" );
- else
- vg_error( " status: Generic Error" );
-
- vg_info( "}\n" );
- vg_fatal_error( "Incomplete framebuffer (see logs)" );
- }
-}
-
-/*
- * Resize/Update all framebuffers(we know about)
- */
-static void render_fb_resize(void)
-{
- if( !gpipeline.ready ) return;
-
- for( int i=0; i<vg_list_size(framebuffers); i++ ){
- struct framebuffer *fb = &framebuffers[i];
- for( int j=0; j<vg_list_size(fb->attachments); j++ ){
- struct framebuffer_attachment *attachment = &fb->attachments[j];
- render_fb_allocate_texture( fb, attachment );
- }
- }
-}
-
-static int render_framebuffer_control( int argc, char const *argv[] );
-static void render_framebuffer_poll( int argc, char const *argv[] );
-
-static void async_render_init( void *payload, u32 size )
-{
- /*
- * Complete Framebuffers
- */
- for( int i=0; i<vg_list_size(framebuffers); i++ ){
- struct framebuffer *fb = &framebuffers[i];
- render_fb_allocate( fb );
- }
-
- f32 rh = 0x1p-4f, ih = 0.3f;
-
- float quad[] = {
- 0.00f,0.00f, 1.00f,1.00f, 0.00f,1.00f, /* fsquad */
- 0.00f,0.00f, 1.00f,0.00f, 1.00f,1.00f,
-
- 0.00f,0.00f, 1.00f,rh, 0.00f,rh, /* fsquad1 */
- 0.00f,0.00f, 1.00f,0.00f, 1.00f,rh,
-
- /* 9x9 debug grid */
- /* row0 */
- 0.00f,0.00f, 0.30f,0.30f, 0.00f,0.30f,
- 0.00f,0.00f, 0.30f,0.00f, 0.30f,0.30f,
- 0.30f,0.00f, 0.60f,0.30f, 0.30f,0.30f,
- 0.30f,0.00f, 0.60f,0.00f, 0.60f,0.30f,
- 0.60f,0.00f, 0.90f,0.30f, 0.60f,0.30f,
- 0.60f,0.00f, 0.90f,0.00f, 0.90f,0.30f,
- /* row1 */
- 0.00f,0.30f, 0.30f,0.60f, 0.00f,0.60f,
- 0.00f,0.30f, 0.30f,0.30f, 0.30f,0.60f,
- 0.30f,0.30f, 0.60f,0.60f, 0.30f,0.60f,
- 0.30f,0.30f, 0.60f,0.30f, 0.60f,0.60f,
- 0.60f,0.30f, 0.90f,0.60f, 0.60f,0.60f,
- 0.60f,0.30f, 0.90f,0.30f, 0.90f,0.60f,
- /* row2 */
- 0.00f,0.60f, 0.30f,0.90f, 0.00f,0.90f,
- 0.00f,0.60f, 0.30f,0.60f, 0.30f,0.90f,
- 0.30f,0.60f, 0.60f,0.90f, 0.30f,0.90f,
- 0.30f,0.60f, 0.60f,0.60f, 0.60f,0.90f,
- 0.60f,0.60f, 0.90f,0.90f, 0.60f,0.90f,
- 0.60f,0.60f, 0.90f,0.60f, 0.90f,0.90f,
-
- 0.00f,ih, 1.00f,ih+rh, 0.00f,ih+rh, /* fsquad2 */
- 0.00f,ih, 1.00f,ih, 1.00f,ih+rh,
- };
-
- glGenVertexArrays( 1, &gpipeline.fsquad.vao );
- glGenBuffers( 1, &gpipeline.fsquad.vbo );
- glBindVertexArray( gpipeline.fsquad.vao );
- glBindBuffer( GL_ARRAY_BUFFER, gpipeline.fsquad.vbo );
- glBufferData( GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STATIC_DRAW );
- glBindVertexArray( gpipeline.fsquad.vao );
- glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE,
- sizeof(float)*2, (void*)0 );
- glEnableVertexAttribArray( 0 );
-
- VG_CHECK_GL_ERR();
-
- glBindFramebuffer( GL_FRAMEBUFFER, 0 );
- gpipeline.ready = 1;
-}
-
-static void render_init(void)
-{
- vg_console_reg_var( "blur_strength", &k_blur_strength, k_var_dtype_f32, 0 );
- vg_console_reg_var( "render_scale", &k_render_scale,
- k_var_dtype_f32, VG_VAR_PERSISTENT );
- vg_console_reg_var( "fov", &k_fov, k_var_dtype_f32, VG_VAR_PERSISTENT );
- vg_console_reg_var( "cam_height", &k_cam_height,
- k_var_dtype_f32, VG_VAR_PERSISTENT );
- vg_console_reg_var( "blur_effect", &k_blur_effect,
- k_var_dtype_i32, VG_VAR_PERSISTENT );
-
- vg_console_reg_cmd( "fb", render_framebuffer_control,
- render_framebuffer_poll );
-
- shader_blit_register();
- shader_blitblur_register();
- shader_blitcolour_register();
- shader_blit_transition_register();
-
- vg_async_call( async_render_init, NULL, 0 );
-}
-
-/*
- * Utility
- */
-static void render_fsquad(void)
-{
- glBindVertexArray( gpipeline.fsquad.vao );
- glDrawArrays( GL_TRIANGLES, 0, 6 );
-}
-
-static void render_fsquad1(void)
-{
- glBindVertexArray( gpipeline.fsquad.vao );
- glDrawArrays( GL_TRIANGLES, 6, 6 );
-}
-
-static void render_fsquad2(void)
-{
- glBindVertexArray( gpipeline.fsquad.vao );
- glDrawArrays( GL_TRIANGLES, 66,6 );
-}
-
-/*
- * Call this inside the UI function
- */
-static void render_view_framebuffer_ui(void)
-{
-#if 0
- int viewing_count = 0;
-
- glBindVertexArray( gpipeline.fsquad.vao );
- shader_blit_use();
- shader_blit_uTexMain( 0 );
-
- v2f identity = { 1.0f, 1.0f };
- shader_blit_uInverseRatio( identity );
-
- for( int i=0; i<vg_list_size(framebuffers); i++ ){
- struct framebuffer *fb = &framebuffers[i];
-
- for( int j=0; j<vg_list_size(fb->attachments); j++ ){
- struct framebuffer_attachment *at = &fb->attachments[j];
-
- if( !at->debug_view )
- continue;
-
- v2f corner,
- window = { vg.window_x, vg.window_y };
-
- corner[0] = viewing_count % 3;
- corner[1] = 1 + (viewing_count / 3);
- v2_mul( corner, window, corner );
- v2_muls( corner, 0.3f, corner );
- corner[1] = vg.window_y - corner[1];
-
- ui_text( (ui_rect){ corner[0], corner[1], 0.0f, 0.0f },
- fb->display_name, 2, k_text_align_left );
- ui_text( (ui_rect){ corner[0], corner[1] + 32, 0.0f, 0.0f, },
- at->display_name, 1, k_text_align_left );
-
- if( at->purpose == k_framebuffer_attachment_type_renderbuffer ){
- v2f center;
- v2_muladds( corner, window, 0.15f, center );
-
- ui_text( (ui_rect){ center[0], center[1], 0.0f, 0.0f },
- "<hardware texture>", 1, k_text_align_center );
- }
- else{
- render_fb_bind_texture( fb, j, 0 );
-
- int start = (viewing_count+2) * 6,
- count = 6;
- glDrawArrays( GL_TRIANGLES, start, count );
- }
-
- viewing_count ++;
- }
- }
-#endif
-}
-
-static void render_framebuffer_show( struct framebuffer *fb,
- struct framebuffer_attachment *at,
- int operation )
-{
- at->debug_view = operation;
- vg_info( "%s %s:%s\n", (operation?"shown": "hidden"),
- fb->display_name, at->display_name );
-}
-
-/*
- * arg0: command "show"/"hide"
- * arg1: framebuffer name <name>/"all"
- * arg2: subname <name>/none
- */
-static int render_framebuffer_control( int argc, char const *argv[] )
-{
- if( argc < 2 ){
- vg_error( "Usage: fb \"show/hide\" <name>/\"all\" <name>/none\n" );
- return 0;
- }
-
- int modify_all = 0,
- operation = 0;
-
- if( !strcmp( argv[0], "show" ) )
- operation = 1;
- else if( !strcmp( argv[0], "hide" ) )
- operation = 0;
- else{
- vg_error( "Unknown framebuffer operation: '%s'\n", argv[0] );
- return 0;
- }
-
- if( !strcmp( argv[1], "all" ) )
- modify_all = 1;
-
- for( int i=0; i<vg_list_size(framebuffers); i++ ){
- struct framebuffer *fb = &framebuffers[i];
-
- for( int j=0; j<vg_list_size(fb->attachments); j++ ){
- struct framebuffer_attachment *at = &fb->attachments[j];
-
- if( at->purpose == k_framebuffer_attachment_type_none )
- continue;
-
- if( modify_all ){
- render_framebuffer_show( fb, at, operation );
- }
- else{
- if( !strcmp( fb->display_name, argv[1] ) ){
- if( argc == 2 )
- render_framebuffer_show( fb, at, operation );
- else if( !strcmp( at->display_name, argv[2] ) )
- render_framebuffer_show( fb, at, operation );
- }
- }
- }
- }
-
- return 0;
-}
-
-static void render_framebuffer_poll( int argc, char const *argv[] )
-{
- const char *term = argv[argc-1];
-
- if( argc == 1 ){
- console_suggest_score_text( "show", term, 0 );
- console_suggest_score_text( "hide", term, 0 );
- }
- else if( argc == 2 ){
- console_suggest_score_text( "all", term, 0 );
-
- for( int i=0; i<vg_list_size(framebuffers); i++ ){
- struct framebuffer *fb = &framebuffers[i];
- console_suggest_score_text( fb->display_name, term, 0 );
- }
- }
- else if( argc == 3 ){
- int modify_all = 0;
-
- if( !strcmp( argv[1], "all" ) )
- modify_all = 1;
-
- for( int i=0; i<vg_list_size(framebuffers); i++ ){
- struct framebuffer *fb = &framebuffers[i];
-
- for( int j=0; j<vg_list_size(fb->attachments); j++ ){
- struct framebuffer_attachment *at = &fb->attachments[j];
-
- if( at->purpose == k_framebuffer_attachment_type_none )
- continue;
-
- if( modify_all ){
- console_suggest_score_text( at->display_name, term, 0 );
- }
- else if( !strcmp( fb->display_name, argv[1] ) ){
- console_suggest_score_text( at->display_name, term, 0 );
- }
- }
- }
- }
-}
-
-#endif /* RENDER_H */
+extern framebuffers[];
+
+void render_init(void);
+void render_fsquad(void);
+void render_fsquad1(void);
+void render_fsquad2(void);
+void render_view_framebuffer_ui(void);
+void render_fb_bind_texture( framebuffer *fb, int attachment, int slot );
+void render_fb_inverse_ratio( framebuffer *fb, v2f inverse );
+void render_fb_get_current_res( struct framebuffer *fb, int *x, int *y );
+void render_fb_bind( framebuffer *fb, int use_scaling );
+void render_fb_bind_texture( framebuffer *fb, int attachment, int slot );
+void render_fb_allocate( struct framebuffer *fb );
+void render_fb_resize(void);
-#ifndef SAVE_C
-#define SAVE_C
-
+#include "skaterift.h"
#include "save.h"
#include "addon.h"
#include "vg/vg_msg.h"
#include "vg/vg_loader.h"
#include "world.h"
-static void savedata_file_write( savedata_file *file ){
+static const char *str_skaterift_main_save = "save.bkv";
+static f64 last_autosave;
+
+void savedata_file_write( savedata_file *file )
+{
savedata_file *sav = file;
FILE *fp = fopen( sav->path, "wb" );
if( fp ){
}
}
-static void savedata_group_write( savedata_group *group ){
+void savedata_group_write( savedata_group *group )
+{
for( u32 i=0; i<group->file_count; i++ ){
savedata_file_write( &group->files[i] );
}
}
-static void savedata_file_read( savedata_file *file ){
+void savedata_file_read( savedata_file *file )
+{
FILE *fp = fopen( file->path, "rb" );
if( fp ){
file->len = fread( file->buf, 1, sizeof(file->buf), fp );
skaterift_write_addon_alias( msg, key, ®->alias );
}
-static void skaterift_read_addon_alias( vg_msg *msg, const char *key,
- enum addon_type type,
- addon_alias *alias ){
+void skaterift_read_addon_alias( vg_msg *msg, const char *key,
+ enum addon_type type,
+ addon_alias *alias )
+{
alias->foldername[0] = '\0';
alias->workshop_id = 0;
alias->type = type;
file->len = sav.cur.co;
}
-static void skaterift_populate_main_savedata( savedata_file *file ){
+static void skaterift_populate_main_savedata( savedata_file *file )
+{
strcpy( file->path, str_skaterift_main_save );
vg_msg sav;
file->len = sav.cur.co;
}
-static int skaterift_autosave( int async ){
+void skaterift_read_main_savedata( savedata_file *file )
+{
+ strcpy( file->path, str_skaterift_main_save );
+ savedata_file_read( file );
+}
+
+int skaterift_autosave( int async )
+{
if( async )
if( !vg_loader_availible() ) return 0;
return 1;
}
-static void skaterift_autosave_synchronous(void){
+void skaterift_autosave_synchronous(void)
+{
skaterift_autosave(0);
}
-#endif /* SAVE_C */
+void skaterift_autosave_update(void)
+{
+ if( vg.time - last_autosave > 20.0 ){
+ if( skaterift_autosave(1) ){
+ last_autosave = vg.time;
+ }
+ }
+}
-#ifndef SAVE_H
-#define SAVE_H
-
+#pragma once
#include "vg/vg_platform.h"
-
-static const char *str_skaterift_main_save = "save.bkv";
-static f64 skaterift_last_autosave = 0.0;
+#include "vg/vg_msg.h"
+#include "addon.h"
typedef struct savedata_file savedata_file;
typedef struct savedata_group savedata_group;
files[];
};
-static void savedata_file_read( savedata_file *file );
-static void savedata_file_write( savedata_file *file );
-static void savedata_group_write( savedata_group *group );
-
-//static void skaterift_read_main_save( savedata_file *sav );
-static int skaterift_autosave(int async);
+void savedata_file_read( savedata_file *file );
+void savedata_file_write( savedata_file *file );
+void savedata_group_write( savedata_group *group );
+int skaterift_autosave(int async);
+void skaterift_autosave_synchronous(void);
+void skaterift_autosave_update(void);
+void skaterift_read_addon_alias( vg_msg *msg, const char *key,
+ enum addon_type type,
+ addon_alias *alias );
-#endif /* SAVE_H */
+void skaterift_read_main_savedata( savedata_file *file );
--- /dev/null
+#include "scene.h"
+
+u32 scene_mem_required( scene_context *ctx )
+{
+ u32 vertex_length = vg_align8(ctx->max_vertices * sizeof(scene_vert)),
+ index_length = vg_align8(ctx->max_indices * sizeof(u32));
+
+ return vertex_length + index_length;
+}
+
+void scene_init( scene_context *ctx, u32 max_vertices, u32 max_indices )
+{
+ ctx->vertex_count = 0;
+ ctx->indice_count = 0;
+ ctx->max_vertices = max_vertices;
+ ctx->max_indices = max_indices;
+ ctx->arrindices = NULL; /* must be filled out by user */
+ ctx->arrvertices = NULL;
+
+ memset( &ctx->submesh, 0, sizeof(mdl_submesh) );
+
+ v3_fill( ctx->bbx[0], 999999.9f );
+ v3_fill( ctx->bbx[1], -999999.9f );
+}
+
+void scene_supply_buffer( scene_context *ctx, void *buffer )
+{
+ u32 vertex_length = vg_align8( ctx->max_vertices * sizeof(scene_vert) );
+
+ ctx->arrvertices = buffer;
+ ctx->arrindices = (u32*)(((u8*)buffer) + vertex_length);
+}
+
+void scene_vert_pack_norm( scene_vert *vert, v3f norm, f32 blend )
+{
+ v3f n;
+ v3_muls( norm, 127.0f, n );
+ v3_minv( n, (v3f){ 127.0f, 127.0f, 127.0f }, n );
+ v3_maxv( n, (v3f){ -127.0f, -127.0f, -127.0f }, n );
+ vert->norm[0] = n[0];
+ vert->norm[1] = n[1];
+ vert->norm[2] = n[2];
+ vert->norm[3] = blend * 127.0f;
+}
+
+/*
+ * Append a model into the scene with a given transform
+ */
+void scene_add_mdl_submesh( scene_context *ctx, mdl_context *mdl,
+ mdl_submesh *sm, m4x3f transform )
+{
+ if( ctx->vertex_count + sm->vertex_count > ctx->max_vertices ){
+ vg_fatal_error( "Scene vertex buffer overflow (%u exceeds %u)\n",
+ ctx->vertex_count + sm->vertex_count,
+ ctx->max_vertices );
+ }
+
+ if( ctx->indice_count + sm->indice_count > ctx->max_indices ){
+ vg_fatal_error( "Scene index buffer overflow (%u exceeds %u)\n",
+ ctx->indice_count + sm->indice_count,
+ ctx->max_indices );
+ }
+
+ mdl_vert *src_verts = mdl_arritm( &mdl->verts, sm->vertex_start );
+ scene_vert *dst_verts = &ctx->arrvertices[ ctx->vertex_count ];
+
+ u32 *src_indices = mdl_arritm( &mdl->indices, sm->indice_start ),
+ *dst_indices = &ctx->arrindices[ ctx->indice_count ];
+
+ /* Transform and place vertices */
+ boxf bbxnew;
+ box_init_inf( bbxnew );
+ m4x3_expand_aabb_aabb( transform, bbxnew, sm->bbx );
+ box_concat( ctx->bbx, bbxnew );
+
+ m3x3f normal_matrix;
+ m3x3_copy( transform, normal_matrix );
+ v3_normalize( normal_matrix[0] );
+ v3_normalize( normal_matrix[1] );
+ v3_normalize( normal_matrix[2] );
+
+ for( u32 i=0; i<sm->vertex_count; i++ ){
+ mdl_vert *src = &src_verts[i];
+ scene_vert *pvert = &dst_verts[i];
+
+ m4x3_mulv( transform, src->co, pvert->co );
+
+ v3f normal;
+ m3x3_mulv( normal_matrix, src->norm, normal );
+ scene_vert_pack_norm( pvert, normal, src->colour[0]*(1.0f/255.0f) );
+
+ v2_copy( src->uv, pvert->uv );
+ }
+
+ u32 real_indices = 0;
+ for( u32 i=0; i<sm->indice_count/3; i++ ){
+ u32 *src = &src_indices[i*3],
+ *dst = &dst_indices[real_indices];
+
+ v3f ab, ac, tn;
+ v3_sub( src_verts[src[2]].co, src_verts[src[0]].co, ab );
+ v3_sub( src_verts[src[1]].co, src_verts[src[0]].co, ac );
+ v3_cross( ac, ab, tn );
+
+#if 0
+ if( v3_length2( tn ) <= 0.00001f )
+ continue;
+#endif
+
+ dst[0] = src[0] + ctx->vertex_count;
+ dst[1] = src[1] + ctx->vertex_count;
+ dst[2] = src[2] + ctx->vertex_count;
+
+ real_indices += 3;
+ }
+
+ if( real_indices != sm->indice_count )
+ vg_warn( "Zero area triangles in model\n" );
+
+ ctx->vertex_count += sm->vertex_count;
+ ctx->indice_count += real_indices;
+}
+
+/*
+ * One by one adders for simplified access (mostly procedural stuff)
+ */
+void scene_push_tri( scene_context *ctx, u32 tri[3] )
+{
+ if( ctx->indice_count + 3 > ctx->max_indices )
+ vg_fatal_error( "Scene indice buffer overflow (%u exceeds %u)\n",
+ ctx->indice_count+3, ctx->max_indices );
+
+ u32 *dst = &ctx->arrindices[ ctx->indice_count ];
+
+ dst[0] = tri[0];
+ dst[1] = tri[1];
+ dst[2] = tri[2];
+
+ ctx->indice_count += 3;
+}
+
+void scene_push_vert( scene_context *ctx, scene_vert *v )
+{
+ if( ctx->vertex_count + 1 > ctx->max_vertices )
+ vg_fatal_error( "Scene vertex buffer overflow (%u exceeds %u)\n",
+ ctx->vertex_count+1, ctx->max_vertices );
+
+ scene_vert *dst = &ctx->arrvertices[ ctx->vertex_count ];
+ *dst = *v;
+
+ ctx->vertex_count ++;
+}
+
+void scene_copy_slice( scene_context *ctx, mdl_submesh *sm )
+{
+ sm->indice_start = ctx->submesh.indice_start;
+ sm->indice_count = ctx->indice_count - sm->indice_start;
+
+ sm->vertex_start = ctx->submesh.vertex_start;
+ sm->vertex_count = ctx->vertex_count - sm->vertex_start;
+
+ ctx->submesh.indice_start = ctx->indice_count;
+ ctx->submesh.vertex_start = ctx->vertex_count;
+}
+
+void scene_set_vertex_flags( scene_context *ctx,
+ u32 start, u32 count, u16 flags )
+{
+ for( u32 i=0; i<count; i++ )
+ ctx->arrvertices[ start + i ].flags = flags;
+}
+
+struct scene_upload_info{
+ scene_context *ctx;
+ glmesh *mesh;
+};
+
+void async_scene_upload( void *payload, u32 size )
+{
+ struct scene_upload_info *info = payload;
+
+ //assert( mesh->loaded == 0 );
+
+ glmesh *mesh = info->mesh;
+ scene_context *ctx = info->ctx;
+
+ glGenVertexArrays( 1, &mesh->vao );
+ glGenBuffers( 1, &mesh->vbo );
+ glGenBuffers( 1, &mesh->ebo );
+ glBindVertexArray( mesh->vao );
+
+ size_t stride = sizeof(scene_vert);
+
+ glBindBuffer( GL_ARRAY_BUFFER, mesh->vbo );
+ glBufferData( GL_ARRAY_BUFFER, ctx->vertex_count*stride,
+ ctx->arrvertices, GL_STATIC_DRAW );
+
+ glBindVertexArray( mesh->vao );
+ glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mesh->ebo );
+ glBufferData( GL_ELEMENT_ARRAY_BUFFER, ctx->indice_count*sizeof(u32),
+ ctx->arrindices, GL_STATIC_DRAW );
+
+ /* 0: coordinates */
+ glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, stride, (void*)0 );
+ glEnableVertexAttribArray( 0 );
+
+ /* 1: normal */
+ glVertexAttribPointer( 1, 4, GL_BYTE, GL_TRUE,
+ stride, (void *)offsetof(scene_vert, norm) );
+ glEnableVertexAttribArray( 1 );
+
+ /* 2: uv */
+ glVertexAttribPointer( 2, 2, GL_FLOAT, GL_FALSE,
+ stride, (void *)offsetof(scene_vert, uv) );
+ glEnableVertexAttribArray( 2 );
+
+ VG_CHECK_GL_ERR();
+
+ mesh->indice_count = ctx->indice_count;
+ mesh->loaded = 1;
+
+ vg_info( "Scene upload ( XYZ_f32 UV_f32 XYZW_i8 )[ u32 ]\n" );
+ vg_info( " indices:%u\n", ctx->indice_count );
+ vg_info( " verts:%u\n", ctx->vertex_count );
+}
+
+void scene_upload_async( scene_context *ctx, glmesh *mesh )
+{
+ vg_async_item *call = vg_async_alloc( sizeof(struct scene_upload_info) );
+
+ struct scene_upload_info *info = call->payload;
+ info->mesh = mesh;
+ info->ctx = ctx;
+
+ vg_async_dispatch( call, async_scene_upload );
+}
+
+vg_async_item *scene_alloc_async( scene_context *scene, glmesh *mesh,
+ u32 max_vertices, u32 max_indices )
+{
+ scene_init( scene, max_vertices, max_indices );
+ u32 buf_size = scene_mem_required( scene );
+
+ u32 hdr_size = vg_align8(sizeof(struct scene_upload_info));
+ vg_async_item *call = vg_async_alloc( hdr_size + buf_size );
+
+ struct scene_upload_info *info = call->payload;
+
+ info->mesh = mesh;
+ info->ctx = scene;
+
+ void *buffer = ((u8*)call->payload)+hdr_size;
+ scene_supply_buffer( scene, buffer );
+
+ return call;
+}
+
+
+/*
+ * BVH implementation
+ */
+
+static void scene_bh_expand_bound( void *user, boxf bound, u32 item_index )
+{
+ scene_context *s = user;
+ scene_vert *pa = &s->arrvertices[ s->arrindices[item_index*3+0] ],
+ *pb = &s->arrvertices[ s->arrindices[item_index*3+1] ],
+ *pc = &s->arrvertices[ s->arrindices[item_index*3+2] ];
+
+ box_addpt( bound, pa->co );
+ box_addpt( bound, pb->co );
+ box_addpt( bound, pc->co );
+}
+
+static float scene_bh_centroid( void *user, u32 item_index, int axis )
+{
+ scene_context *s = user;
+ scene_vert *pa = &s->arrvertices[ s->arrindices[item_index*3+0] ],
+ *pb = &s->arrvertices[ s->arrindices[item_index*3+1] ],
+ *pc = &s->arrvertices[ s->arrindices[item_index*3+2] ];
+
+ #if 0
+
+ float min, max;
+
+ min = vg_minf( pa->co[axis], pb->co[axis] );
+ max = vg_maxf( pa->co[axis], pb->co[axis] );
+ min = vg_minf( min, pc->co[axis] );
+ max = vg_maxf( max, pc->co[axis] );
+
+ return (min+max) * 0.5f;
+
+ #else
+ return (pa->co[axis] + pb->co[axis] + pc->co[axis]) * (1.0f/3.0f);
+ #endif
+}
+
+static void scene_bh_swap( void *user, u32 ia, u32 ib )
+{
+ scene_context *s = user;
+
+ u32 *ti = &s->arrindices[ia*3];
+ u32 *tj = &s->arrindices[ib*3];
+
+ u32 temp[3];
+ temp[0] = ti[0];
+ temp[1] = ti[1];
+ temp[2] = ti[2];
+
+ ti[0] = tj[0];
+ ti[1] = tj[1];
+ ti[2] = tj[2];
+
+ tj[0] = temp[0];
+ tj[1] = temp[1];
+ tj[2] = temp[2];
+}
+
+static void scene_bh_debug( void *user, u32 item_index )
+{
+ scene_context *s = user;
+ u32 idx = item_index*3;
+ scene_vert *pa = &s->arrvertices[ s->arrindices[ idx+0 ] ],
+ *pb = &s->arrvertices[ s->arrindices[ idx+1 ] ],
+ *pc = &s->arrvertices[ s->arrindices[ idx+2 ] ];
+
+ vg_line( pa->co, pb->co, 0xff0000ff );
+ vg_line( pb->co, pc->co, 0xff0000ff );
+ vg_line( pc->co, pa->co, 0xff0000ff );
+}
+
+static void scene_bh_closest( void *user, u32 index, v3f point, v3f closest )
+{
+ scene_context *s = user;
+
+ v3f positions[3];
+ u32 *tri = &s->arrindices[ index*3 ];
+ for( int i=0; i<3; i++ )
+ v3_copy( s->arrvertices[tri[i]].co, positions[i] );
+
+ closest_on_triangle_1( point, positions, closest );
+}
+
+bh_system bh_system_scene =
+{
+ .expand_bound = scene_bh_expand_bound,
+ .item_centroid = scene_bh_centroid,
+ .item_closest = scene_bh_closest,
+ .item_swap = scene_bh_swap,
+ .item_debug = scene_bh_debug,
+};
+
+/*
+ * An extra step is added onto the end to calculate the hit normal
+ */
+int scene_raycast( scene_context *s, bh_tree *bh,
+ v3f co, v3f dir, ray_hit *hit, u16 ignore )
+{
+ hit->tri = NULL;
+
+ bh_iter it;
+ bh_iter_init_ray( 0, &it, co, dir, hit->dist );
+ i32 idx;
+
+ while( bh_next( bh, &it, &idx ) ){
+ u32 *tri = &s->arrindices[ idx*3 ];
+
+ if( s->arrvertices[tri[0]].flags & ignore ) continue;
+
+ v3f vs[3];
+ for( u32 i=0; i<3; i++ )
+ v3_copy( s->arrvertices[tri[i]].co, vs[i] );
+
+ f32 t;
+ if( ray_tri( vs, co, dir, &t, 0 ) ){
+ if( t < hit->dist ){
+ hit->dist = t;
+ hit->tri = tri;
+ }
+ }
+ }
+
+ if( hit->tri ){
+ v3f v0, v1;
+
+ float *pa = s->arrvertices[hit->tri[0]].co,
+ *pb = s->arrvertices[hit->tri[1]].co,
+ *pc = s->arrvertices[hit->tri[2]].co;
+
+ v3_sub( pa, pb, v0 );
+ v3_sub( pc, pb, v1 );
+ v3_cross( v1, v0, hit->normal );
+ v3_normalize( hit->normal );
+ v3_muladds( co, dir, hit->dist, hit->pos );
+ }
+
+ return hit->tri?1:0;
+}
+
+bh_tree *scene_bh_create( void *lin_alloc, scene_context *s )
+{
+ u32 triangle_count = s->indice_count / 3;
+ return bh_create( lin_alloc, &bh_system_scene, s, triangle_count, 2 );
+}
-#ifndef SCENE_H
-#define SCENE_H
-
+#pragma once
+#include "vg/vg_bvh.h"
#include "common.h"
#include "model.h"
-#include "bvh.h"
typedef struct scene_context scene_context;
typedef struct scene_vert scene_vert;
mdl_submesh submesh;
};
-static u32 scene_mem_required( scene_context *ctx )
-{
- u32 vertex_length = vg_align8(ctx->max_vertices * sizeof(scene_vert)),
- index_length = vg_align8(ctx->max_indices * sizeof(u32));
-
- return vertex_length + index_length;
-}
-
-static
-void scene_init( scene_context *ctx, u32 max_vertices, u32 max_indices )
-{
- ctx->vertex_count = 0;
- ctx->indice_count = 0;
- ctx->max_vertices = max_vertices;
- ctx->max_indices = max_indices;
- ctx->arrindices = NULL; /* must be filled out by user */
- ctx->arrvertices = NULL;
-
- memset( &ctx->submesh, 0, sizeof(mdl_submesh) );
-
- v3_fill( ctx->bbx[0], 999999.9f );
- v3_fill( ctx->bbx[1], -999999.9f );
-}
-
-void scene_supply_buffer( scene_context *ctx, void *buffer )
-{
- u32 vertex_length = vg_align8( ctx->max_vertices * sizeof(scene_vert) );
-
- ctx->arrvertices = buffer;
- ctx->arrindices = (u32*)(((u8*)buffer) + vertex_length);
-}
-
-static void scene_vert_pack_norm( scene_vert *vert, v3f norm, f32 blend ){
- v3f n;
- v3_muls( norm, 127.0f, n );
- v3_minv( n, (v3f){ 127.0f, 127.0f, 127.0f }, n );
- v3_maxv( n, (v3f){ -127.0f, -127.0f, -127.0f }, n );
- vert->norm[0] = n[0];
- vert->norm[1] = n[1];
- vert->norm[2] = n[2];
- vert->norm[3] = blend * 127.0f;
-}
-
-/*
- * Append a model into the scene with a given transform
- */
-static void scene_add_mdl_submesh( scene_context *ctx, mdl_context *mdl,
- mdl_submesh *sm, m4x3f transform )
-{
- if( ctx->vertex_count + sm->vertex_count > ctx->max_vertices ){
- vg_fatal_error( "Scene vertex buffer overflow (%u exceeds %u)\n",
- ctx->vertex_count + sm->vertex_count,
- ctx->max_vertices );
- }
-
- if( ctx->indice_count + sm->indice_count > ctx->max_indices ){
- vg_fatal_error( "Scene index buffer overflow (%u exceeds %u)\n",
- ctx->indice_count + sm->indice_count,
- ctx->max_indices );
- }
-
- mdl_vert *src_verts = mdl_arritm( &mdl->verts, sm->vertex_start );
- scene_vert *dst_verts = &ctx->arrvertices[ ctx->vertex_count ];
-
- u32 *src_indices = mdl_arritm( &mdl->indices, sm->indice_start ),
- *dst_indices = &ctx->arrindices[ ctx->indice_count ];
-
- /* Transform and place vertices */
- boxf bbxnew;
- box_init_inf( bbxnew );
- m4x3_expand_aabb_aabb( transform, bbxnew, sm->bbx );
- box_concat( ctx->bbx, bbxnew );
-
- m3x3f normal_matrix;
- m3x3_copy( transform, normal_matrix );
- v3_normalize( normal_matrix[0] );
- v3_normalize( normal_matrix[1] );
- v3_normalize( normal_matrix[2] );
-
- for( u32 i=0; i<sm->vertex_count; i++ ){
- mdl_vert *src = &src_verts[i];
- scene_vert *pvert = &dst_verts[i];
-
- m4x3_mulv( transform, src->co, pvert->co );
-
- v3f normal;
- m3x3_mulv( normal_matrix, src->norm, normal );
- scene_vert_pack_norm( pvert, normal, src->colour[0]*(1.0f/255.0f) );
-
- v2_copy( src->uv, pvert->uv );
- }
-
- u32 real_indices = 0;
- for( u32 i=0; i<sm->indice_count/3; i++ ){
- u32 *src = &src_indices[i*3],
- *dst = &dst_indices[real_indices];
-
- v3f ab, ac, tn;
- v3_sub( src_verts[src[2]].co, src_verts[src[0]].co, ab );
- v3_sub( src_verts[src[1]].co, src_verts[src[0]].co, ac );
- v3_cross( ac, ab, tn );
-
-#if 0
- if( v3_length2( tn ) <= 0.00001f )
- continue;
-#endif
-
- dst[0] = src[0] + ctx->vertex_count;
- dst[1] = src[1] + ctx->vertex_count;
- dst[2] = src[2] + ctx->vertex_count;
-
- real_indices += 3;
- }
-
- if( real_indices != sm->indice_count )
- vg_warn( "Zero area triangles in model\n" );
-
- ctx->vertex_count += sm->vertex_count;
- ctx->indice_count += real_indices;
-}
-
-/*
- * One by one adders for simplified access (mostly procedural stuff)
- */
-static void scene_push_tri( scene_context *ctx, u32 tri[3] )
-{
- if( ctx->indice_count + 3 > ctx->max_indices )
- vg_fatal_error( "Scene indice buffer overflow (%u exceeds %u)\n",
- ctx->indice_count+3, ctx->max_indices );
-
- u32 *dst = &ctx->arrindices[ ctx->indice_count ];
-
- dst[0] = tri[0];
- dst[1] = tri[1];
- dst[2] = tri[2];
-
- ctx->indice_count += 3;
-}
-
-static void scene_push_vert( scene_context *ctx, scene_vert *v )
-{
- if( ctx->vertex_count + 1 > ctx->max_vertices )
- vg_fatal_error( "Scene vertex buffer overflow (%u exceeds %u)\n",
- ctx->vertex_count+1, ctx->max_vertices );
-
- scene_vert *dst = &ctx->arrvertices[ ctx->vertex_count ];
- *dst = *v;
-
- ctx->vertex_count ++;
-}
-
-static void scene_copy_slice( scene_context *ctx, mdl_submesh *sm )
-{
- sm->indice_start = ctx->submesh.indice_start;
- sm->indice_count = ctx->indice_count - sm->indice_start;
-
- sm->vertex_start = ctx->submesh.vertex_start;
- sm->vertex_count = ctx->vertex_count - sm->vertex_start;
-
- ctx->submesh.indice_start = ctx->indice_count;
- ctx->submesh.vertex_start = ctx->vertex_count;
-}
-
-static void scene_set_vertex_flags( scene_context *ctx,
- u32 start, u32 count, u16 flags ){
- for( u32 i=0; i<count; i++ )
- ctx->arrvertices[ start + i ].flags = flags;
-}
-
-struct scene_upload_info{
- scene_context *ctx;
- glmesh *mesh;
-};
-
-static void async_scene_upload( void *payload, u32 size )
-{
- struct scene_upload_info *info = payload;
-
- //assert( mesh->loaded == 0 );
-
- glmesh *mesh = info->mesh;
- scene_context *ctx = info->ctx;
-
- glGenVertexArrays( 1, &mesh->vao );
- glGenBuffers( 1, &mesh->vbo );
- glGenBuffers( 1, &mesh->ebo );
- glBindVertexArray( mesh->vao );
-
- size_t stride = sizeof(scene_vert);
-
- glBindBuffer( GL_ARRAY_BUFFER, mesh->vbo );
- glBufferData( GL_ARRAY_BUFFER, ctx->vertex_count*stride,
- ctx->arrvertices, GL_STATIC_DRAW );
-
- glBindVertexArray( mesh->vao );
- glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mesh->ebo );
- glBufferData( GL_ELEMENT_ARRAY_BUFFER, ctx->indice_count*sizeof(u32),
- ctx->arrindices, GL_STATIC_DRAW );
-
- /* 0: coordinates */
- glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, stride, (void*)0 );
- glEnableVertexAttribArray( 0 );
-
- /* 1: normal */
- glVertexAttribPointer( 1, 4, GL_BYTE, GL_TRUE,
- stride, (void *)offsetof(scene_vert, norm) );
- glEnableVertexAttribArray( 1 );
-
- /* 2: uv */
- glVertexAttribPointer( 2, 2, GL_FLOAT, GL_FALSE,
- stride, (void *)offsetof(scene_vert, uv) );
- glEnableVertexAttribArray( 2 );
-
- VG_CHECK_GL_ERR();
-
- mesh->indice_count = ctx->indice_count;
- mesh->loaded = 1;
-
- vg_info( "Scene upload ( XYZ_f32 UV_f32 XYZW_i8 )[ u32 ]\n" );
- vg_info( " indices:%u\n", ctx->indice_count );
- vg_info( " verts:%u\n", ctx->vertex_count );
-}
-
-static void scene_upload_async( scene_context *ctx, glmesh *mesh )
-{
- vg_async_item *call = vg_async_alloc( sizeof(struct scene_upload_info) );
-
- struct scene_upload_info *info = call->payload;
- info->mesh = mesh;
- info->ctx = ctx;
-
- vg_async_dispatch( call, async_scene_upload );
-}
-
-static
+extern bh_system bh_system_scene;
+bh_tree *scene_bh_create( void *lin_alloc, scene_context *s );
+int scene_raycast( scene_context *s, bh_tree *bh,
+ v3f co, v3f dir, ray_hit *hit, u16 ignore );
vg_async_item *scene_alloc_async( scene_context *scene, glmesh *mesh,
- u32 max_vertices, u32 max_indices )
-{
- scene_init( scene, max_vertices, max_indices );
- u32 buf_size = scene_mem_required( scene );
-
- u32 hdr_size = vg_align8(sizeof(struct scene_upload_info));
- vg_async_item *call = vg_async_alloc( hdr_size + buf_size );
-
- struct scene_upload_info *info = call->payload;
-
- info->mesh = mesh;
- info->ctx = scene;
-
- void *buffer = ((u8*)call->payload)+hdr_size;
- scene_supply_buffer( scene, buffer );
-
- return call;
-}
-
-
-/*
- * BVH implementation
- */
-
-static void scene_bh_expand_bound( void *user, boxf bound, u32 item_index )
-{
- scene_context *s = user;
- scene_vert *pa = &s->arrvertices[ s->arrindices[item_index*3+0] ],
- *pb = &s->arrvertices[ s->arrindices[item_index*3+1] ],
- *pc = &s->arrvertices[ s->arrindices[item_index*3+2] ];
-
- box_addpt( bound, pa->co );
- box_addpt( bound, pb->co );
- box_addpt( bound, pc->co );
-}
-
-static float scene_bh_centroid( void *user, u32 item_index, int axis )
-{
- scene_context *s = user;
- scene_vert *pa = &s->arrvertices[ s->arrindices[item_index*3+0] ],
- *pb = &s->arrvertices[ s->arrindices[item_index*3+1] ],
- *pc = &s->arrvertices[ s->arrindices[item_index*3+2] ];
-
- #if 0
-
- float min, max;
-
- min = vg_minf( pa->co[axis], pb->co[axis] );
- max = vg_maxf( pa->co[axis], pb->co[axis] );
- min = vg_minf( min, pc->co[axis] );
- max = vg_maxf( max, pc->co[axis] );
-
- return (min+max) * 0.5f;
-
- #else
- return (pa->co[axis] + pb->co[axis] + pc->co[axis]) * (1.0f/3.0f);
- #endif
-}
-
-static void scene_bh_swap( void *user, u32 ia, u32 ib )
-{
- scene_context *s = user;
-
- u32 *ti = &s->arrindices[ia*3];
- u32 *tj = &s->arrindices[ib*3];
-
- u32 temp[3];
- temp[0] = ti[0];
- temp[1] = ti[1];
- temp[2] = ti[2];
-
- ti[0] = tj[0];
- ti[1] = tj[1];
- ti[2] = tj[2];
-
- tj[0] = temp[0];
- tj[1] = temp[1];
- tj[2] = temp[2];
-}
-
-static void scene_bh_debug( void *user, u32 item_index )
-{
- scene_context *s = user;
- u32 idx = item_index*3;
- scene_vert *pa = &s->arrvertices[ s->arrindices[ idx+0 ] ],
- *pb = &s->arrvertices[ s->arrindices[ idx+1 ] ],
- *pc = &s->arrvertices[ s->arrindices[ idx+2 ] ];
-
- vg_line( pa->co, pb->co, 0xff0000ff );
- vg_line( pb->co, pc->co, 0xff0000ff );
- vg_line( pc->co, pa->co, 0xff0000ff );
-}
-
-static void scene_bh_closest( void *user, u32 index, v3f point, v3f closest )
-{
- scene_context *s = user;
-
- v3f positions[3];
- u32 *tri = &s->arrindices[ index*3 ];
- for( int i=0; i<3; i++ )
- v3_copy( s->arrvertices[tri[i]].co, positions[i] );
-
- closest_on_triangle_1( point, positions, closest );
-}
-
-static bh_system bh_system_scene =
-{
- .expand_bound = scene_bh_expand_bound,
- .item_centroid = scene_bh_centroid,
- .item_closest = scene_bh_closest,
- .item_swap = scene_bh_swap,
- .item_debug = scene_bh_debug,
- .system_type = 0x1
-};
-
-/*
- * An extra step is added onto the end to calculate the hit normal
- */
-static int scene_raycast( scene_context *s, bh_tree *bh,
- v3f co, v3f dir, ray_hit *hit, u16 ignore )
-{
- hit->tri = NULL;
-
- bh_iter it;
- bh_iter_init_ray( 0, &it, co, dir, hit->dist );
- i32 idx;
-
- while( bh_next( bh, &it, &idx ) ){
- u32 *tri = &s->arrindices[ idx*3 ];
-
- if( s->arrvertices[tri[0]].flags & ignore ) continue;
-
- v3f vs[3];
- for( u32 i=0; i<3; i++ )
- v3_copy( s->arrvertices[tri[i]].co, vs[i] );
-
- f32 t;
- if( ray_tri( vs, co, dir, &t, 0 ) ){
- if( t < hit->dist ){
- hit->dist = t;
- hit->tri = tri;
- }
- }
- }
-
- if( hit->tri ){
- v3f v0, v1;
-
- float *pa = s->arrvertices[hit->tri[0]].co,
- *pb = s->arrvertices[hit->tri[1]].co,
- *pc = s->arrvertices[hit->tri[2]].co;
-
- v3_sub( pa, pb, v0 );
- v3_sub( pc, pb, v1 );
- v3_cross( v1, v0, hit->normal );
- v3_normalize( hit->normal );
- v3_muladds( co, dir, hit->dist, hit->pos );
- }
-
- return hit->tri?1:0;
-}
-
-static bh_tree *scene_bh_create( void *lin_alloc, scene_context *s )
-{
- u32 triangle_count = s->indice_count / 3;
- return bh_create( lin_alloc, &bh_system_scene, s, triangle_count, 2 );
-}
-
-#endif
+ u32 max_vertices, u32 max_indices );
+void scene_copy_slice( scene_context *ctx, mdl_submesh *sm );
+void scene_push_vert( scene_context *ctx, scene_vert *v );
+void scene_vert_pack_norm( scene_vert *vert, v3f norm, f32 blend );
+void scene_push_tri( scene_context *ctx, u32 tri[3] );
+void scene_add_mdl_submesh( scene_context *ctx, mdl_context *mdl,
+ mdl_submesh *sm, m4x3f transform );
+void scene_set_vertex_flags( scene_context *ctx,
+ u32 start, u32 count, u16 flags );
+void scene_supply_buffer( scene_context *ctx, void *buffer );
+void scene_init( scene_context *ctx, u32 max_vertices, u32 max_indices );
+u32 scene_mem_required( scene_context *ctx );
+void async_scene_upload( void *payload, u32 size );
+void scene_upload_async( scene_context *ctx, glmesh *mesh );
-#ifndef SHADER_blit_H
-#define SHADER_blit_H
-static void shader_blit_link(void);
-static void shader_blit_register(void);
-static struct vg_shader _shader_blit = {
- .name = "blit",
- .link = shader_blit_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_blit;
+extern GLuint _uniform_blit_uInverseRatio;
+extern GLuint _uniform_blit_uTexMain;
+static inline void shader_blit_uInverseRatio(v2f v)
{
-.orig_file = "shaders/blit.vs",
-.static_src =
-"layout (location=0) in vec2 a_co;\n"
-"out vec2 aUv;\n"
-"\n"
-"uniform vec2 uInverseRatio;\n"
-"\n"
-"void main()\n"
-"{\n"
-" gl_Position = vec4(a_co*2.0-1.0,0.0,1.0);\n"
-" aUv = a_co * uInverseRatio;\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/blit.fs",
-.static_src =
-"out vec4 FragColor;\n"
-"uniform sampler2D uTexMain;\n"
-"\n"
-"in vec2 aUv;\n"
-"\n"
-"float kPi = 3.14159265358979;\n"
-"\n"
-"vec2 fisheye_distort(vec2 xy)\n"
-"{\n"
-" float aperture = 1350.0;\n"
-" float apertureHalf = 0.5 * aperture * (kPi / 180.0);\n"
-" float maxFactor = sin(apertureHalf);\n"
-"\n"
-" vec2 uv;\n"
-" float d = length(xy);\n"
-" if(d < (2.0-maxFactor))\n"
-" {\n"
-" d = length(xy * maxFactor);\n"
-" float z = sqrt(1.0 - d * d);\n"
-" float r = atan(d, z) / kPi;\n"
-" float phi = atan(xy.y, xy.x);\n"
-"\n"
-" uv.x = r * cos(phi) + 0.5;\n"
-" uv.y = r * sin(phi) + 0.5;\n"
-" }\n"
-" else\n"
-" {\n"
-" uv = 0.5*xy + 0.5;\n"
-" }\n"
-" \n"
-" return uv;\n"
-"}\n"
-"\n"
-"\n"
-"void main()\n"
-"{\n"
-" vec2 vwarp = 2.0*aUv - 1.0;\n"
-" vwarp = fisheye_distort( vwarp );\n"
-"\n"
-" FragColor = texture( uTexMain, aUv );\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_blit_uInverseRatio;
-static GLuint _uniform_blit_uTexMain;
-static void shader_blit_uInverseRatio(v2f v){
glUniform2fv(_uniform_blit_uInverseRatio,1,v);
}
-static void shader_blit_uTexMain(int i){
+static inline void shader_blit_uTexMain(int i)
+{
glUniform1i(_uniform_blit_uTexMain,i);
}
-static void shader_blit_register(void){
- vg_shader_register( &_shader_blit );
-}
-static void shader_blit_use(void){ glUseProgram(_shader_blit.id); }
-static void shader_blit_link(void){
- _uniform_blit_uInverseRatio = glGetUniformLocation( _shader_blit.id, "uInverseRatio" );
- _uniform_blit_uTexMain = glGetUniformLocation( _shader_blit.id, "uTexMain" );
+static inline void shader_blit_use(void);
+static inline void shader_blit_use(void)
+{
+ glUseProgram(_shader_blit.id);
}
-#endif /* SHADER_blit_H */
-#ifndef SHADER_blit_transition_H
-#define SHADER_blit_transition_H
-static void shader_blit_transition_link(void);
-static void shader_blit_transition_register(void);
-static struct vg_shader _shader_blit_transition = {
- .name = "blit_transition",
- .link = shader_blit_transition_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_blit_transition;
+extern GLuint _uniform_blit_transition_uInverseRatio;
+extern GLuint _uniform_blit_transition_uT;
+static inline void shader_blit_transition_uInverseRatio(v2f v)
{
-.orig_file = "shaders/blit.vs",
-.static_src =
-"layout (location=0) in vec2 a_co;\n"
-"out vec2 aUv;\n"
-"\n"
-"uniform vec2 uInverseRatio;\n"
-"\n"
-"void main()\n"
-"{\n"
-" gl_Position = vec4(a_co*2.0-1.0,0.0,1.0);\n"
-" aUv = a_co * uInverseRatio;\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/blit_transition.fs",
-.static_src =
-"out vec4 FragColor;\n"
-"in vec2 aUv;\n"
-"uniform float uT;\n"
-"\n"
-"void main(){\n"
-" float d = uT + distance( aUv, vec2(0.5,0.5) );\n"
-"\n"
-" vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), gl_FragCoord.xy) );\n"
-" float dither = fract( vDither.g / 71.0 ) - 0.5;\n"
-"\n"
-" if( d+dither < -0.5 )\n"
-" discard;\n"
-"\n"
-" FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_blit_transition_uInverseRatio;
-static GLuint _uniform_blit_transition_uT;
-static void shader_blit_transition_uInverseRatio(v2f v){
glUniform2fv(_uniform_blit_transition_uInverseRatio,1,v);
}
-static void shader_blit_transition_uT(float f){
+static inline void shader_blit_transition_uT(f32 f)
+{
glUniform1f(_uniform_blit_transition_uT,f);
}
-static void shader_blit_transition_register(void){
- vg_shader_register( &_shader_blit_transition );
-}
-static void shader_blit_transition_use(void){ glUseProgram(_shader_blit_transition.id); }
-static void shader_blit_transition_link(void){
- _uniform_blit_transition_uInverseRatio = glGetUniformLocation( _shader_blit_transition.id, "uInverseRatio" );
- _uniform_blit_transition_uT = glGetUniformLocation( _shader_blit_transition.id, "uT" );
+static inline void shader_blit_transition_use(void);
+static inline void shader_blit_transition_use(void)
+{
+ glUseProgram(_shader_blit_transition.id);
}
-#endif /* SHADER_blit_transition_H */
-#ifndef SHADER_blitblur_H
-#define SHADER_blitblur_H
-static void shader_blitblur_link(void);
-static void shader_blitblur_register(void);
-static struct vg_shader _shader_blitblur = {
- .name = "blitblur",
- .link = shader_blitblur_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_blitblur;
+extern GLuint _uniform_blitblur_uInverseRatio;
+extern GLuint _uniform_blitblur_uTexMain;
+extern GLuint _uniform_blitblur_uTexMotion;
+extern GLuint _uniform_blitblur_uBlurStrength;
+extern GLuint _uniform_blitblur_uOverrideDir;
+extern GLuint _uniform_blitblur_uTime;
+extern GLuint _uniform_blitblur_uGlitchStrength;
+extern GLuint _uniform_blitblur_uClampUv;
+static inline void shader_blitblur_uInverseRatio(v2f v)
{
-.orig_file = "shaders/blit.vs",
-.static_src =
-"layout (location=0) in vec2 a_co;\n"
-"out vec2 aUv;\n"
-"\n"
-"uniform vec2 uInverseRatio;\n"
-"\n"
-"void main()\n"
-"{\n"
-" gl_Position = vec4(a_co*2.0-1.0,0.0,1.0);\n"
-" aUv = a_co * uInverseRatio;\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/blitblur.fs",
-.static_src =
-"out vec4 FragColor;\n"
-"uniform sampler2D uTexMain;\n"
-"uniform sampler2D uTexMotion;\n"
-"uniform float uBlurStrength;\n"
-"uniform vec2 uOverrideDir;\n"
-"uniform float uTime;\n"
-"uniform float uGlitchStrength;\n"
-"uniform vec2 uClampUv;\n"
-"\n"
-"in vec2 aUv;\n"
-"\n"
-"vec2 rand_hash22( vec2 p ){\n"
-" vec3 p3 = fract(vec3(p.xyx) * 213.8976123);\n"
-" p3 += dot(p3, p3.yzx+19.19);\n"
-" return fract(vec2((p3.x + p3.y)*p3.z, (p3.x+p3.z)*p3.y));\n"
-"}\n"
-"\n"
-"const int NOISE_LOOP = 3;\n"
-"vec3 digital_noise( uvec3 iuv ){\n"
-" iuv *=uvec3(8,2524,7552);\n"
-" for( int i=0; i<NOISE_LOOP; i++ )\n"
-" iuv += (iuv.yzx<<2) ^ (iuv.yxz)+iuv.z;\n"
-" return vec3(iuv)*(1.0/float(0xffffffffU));\n"
-"}\n"
-"\n"
-"void main(){\n"
-" vec2 vuv = aUv; \n"
-"\n"
-" //if( uGlitchStrength > 0.0 ){\n"
-" // uvec3 p = uvec3( gl_FragCoord.xy, uint(uTime*30.0) );\n"
-" // vec2 g = digital_noise(p).xy;\n"
-" // vuv = aUv + g.xy*uGlitchStrength - uGlitchStrength*0.5;\n"
-" //}\n"
-"\n"
-" vec2 vrand = rand_hash22( vuv ) * 2.0 - vec2(1.0);\n"
-" vec2 vrand1 = rand_hash22( vrand ) * 2.0 - vec2(1.0);\n"
-" \n"
-" vec2 vdir = texture( uTexMotion, vuv ).xy * uBlurStrength + uOverrideDir;\n"
-"\n"
-" vec4 vcolour0 = texture( uTexMain, min(vuv + vdir*vrand.x,uClampUv) );\n"
-" vec4 vcolour1 = texture( uTexMain, min(vuv + vdir*vrand.y,uClampUv) );\n"
-" vec4 vcolour2 = texture( uTexMain, min(vuv + vdir*vrand1.x,uClampUv) );\n"
-" vec4 vcolour3 = texture( uTexMain, min(vuv + vdir*vrand1.y,uClampUv) );\n"
-"\n"
-" FragColor = ( vcolour0 + vcolour1 + vcolour2 + vcolour3 ) * 0.25;\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_blitblur_uInverseRatio;
-static GLuint _uniform_blitblur_uTexMain;
-static GLuint _uniform_blitblur_uTexMotion;
-static GLuint _uniform_blitblur_uBlurStrength;
-static GLuint _uniform_blitblur_uOverrideDir;
-static GLuint _uniform_blitblur_uTime;
-static GLuint _uniform_blitblur_uGlitchStrength;
-static GLuint _uniform_blitblur_uClampUv;
-static void shader_blitblur_uInverseRatio(v2f v){
glUniform2fv(_uniform_blitblur_uInverseRatio,1,v);
}
-static void shader_blitblur_uTexMain(int i){
+static inline void shader_blitblur_uTexMain(int i)
+{
glUniform1i(_uniform_blitblur_uTexMain,i);
}
-static void shader_blitblur_uTexMotion(int i){
+static inline void shader_blitblur_uTexMotion(int i)
+{
glUniform1i(_uniform_blitblur_uTexMotion,i);
}
-static void shader_blitblur_uBlurStrength(float f){
+static inline void shader_blitblur_uBlurStrength(f32 f)
+{
glUniform1f(_uniform_blitblur_uBlurStrength,f);
}
-static void shader_blitblur_uOverrideDir(v2f v){
+static inline void shader_blitblur_uOverrideDir(v2f v)
+{
glUniform2fv(_uniform_blitblur_uOverrideDir,1,v);
}
-static void shader_blitblur_uTime(float f){
+static inline void shader_blitblur_uTime(f32 f)
+{
glUniform1f(_uniform_blitblur_uTime,f);
}
-static void shader_blitblur_uGlitchStrength(float f){
+static inline void shader_blitblur_uGlitchStrength(f32 f)
+{
glUniform1f(_uniform_blitblur_uGlitchStrength,f);
}
-static void shader_blitblur_uClampUv(v2f v){
+static inline void shader_blitblur_uClampUv(v2f v)
+{
glUniform2fv(_uniform_blitblur_uClampUv,1,v);
}
-static void shader_blitblur_register(void){
- vg_shader_register( &_shader_blitblur );
-}
-static void shader_blitblur_use(void){ glUseProgram(_shader_blitblur.id); }
-static void shader_blitblur_link(void){
- _uniform_blitblur_uInverseRatio = glGetUniformLocation( _shader_blitblur.id, "uInverseRatio" );
- _uniform_blitblur_uTexMain = glGetUniformLocation( _shader_blitblur.id, "uTexMain" );
- _uniform_blitblur_uTexMotion = glGetUniformLocation( _shader_blitblur.id, "uTexMotion" );
- _uniform_blitblur_uBlurStrength = glGetUniformLocation( _shader_blitblur.id, "uBlurStrength" );
- _uniform_blitblur_uOverrideDir = glGetUniformLocation( _shader_blitblur.id, "uOverrideDir" );
- _uniform_blitblur_uTime = glGetUniformLocation( _shader_blitblur.id, "uTime" );
- _uniform_blitblur_uGlitchStrength = glGetUniformLocation( _shader_blitblur.id, "uGlitchStrength" );
- _uniform_blitblur_uClampUv = glGetUniformLocation( _shader_blitblur.id, "uClampUv" );
+static inline void shader_blitblur_use(void);
+static inline void shader_blitblur_use(void)
+{
+ glUseProgram(_shader_blitblur.id);
}
-#endif /* SHADER_blitblur_H */
-#ifndef SHADER_blitcolour_H
-#define SHADER_blitcolour_H
-static void shader_blitcolour_link(void);
-static void shader_blitcolour_register(void);
-static struct vg_shader _shader_blitcolour = {
- .name = "blitcolour",
- .link = shader_blitcolour_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_blitcolour;
+extern GLuint _uniform_blitcolour_uInverseRatio;
+extern GLuint _uniform_blitcolour_uColour;
+static inline void shader_blitcolour_uInverseRatio(v2f v)
{
-.orig_file = "shaders/blit.vs",
-.static_src =
-"layout (location=0) in vec2 a_co;\n"
-"out vec2 aUv;\n"
-"\n"
-"uniform vec2 uInverseRatio;\n"
-"\n"
-"void main()\n"
-"{\n"
-" gl_Position = vec4(a_co*2.0-1.0,0.0,1.0);\n"
-" aUv = a_co * uInverseRatio;\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/colour.fs",
-.static_src =
-"out vec4 FragColor;\n"
-"uniform vec4 uColour;\n"
-"\n"
-"in vec2 aUv;\n"
-"\n"
-"void main()\n"
-"{\n"
-" FragColor = uColour;\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_blitcolour_uInverseRatio;
-static GLuint _uniform_blitcolour_uColour;
-static void shader_blitcolour_uInverseRatio(v2f v){
glUniform2fv(_uniform_blitcolour_uInverseRatio,1,v);
}
-static void shader_blitcolour_uColour(v4f v){
+static inline void shader_blitcolour_uColour(v4f v)
+{
glUniform4fv(_uniform_blitcolour_uColour,1,v);
}
-static void shader_blitcolour_register(void){
- vg_shader_register( &_shader_blitcolour );
-}
-static void shader_blitcolour_use(void){ glUseProgram(_shader_blitcolour.id); }
-static void shader_blitcolour_link(void){
- _uniform_blitcolour_uInverseRatio = glGetUniformLocation( _shader_blitcolour.id, "uInverseRatio" );
- _uniform_blitcolour_uColour = glGetUniformLocation( _shader_blitcolour.id, "uColour" );
+static inline void shader_blitcolour_use(void);
+static inline void shader_blitcolour_use(void)
+{
+ glUseProgram(_shader_blitcolour.id);
}
-#endif /* SHADER_blitcolour_H */
--- /dev/null
+#include "shaders/scene_standard.h"
+struct vg_shader _shader_scene_standard = {
+ .name = "scene_standard",
+ .vs =
+{
+.orig_file = "shaders/scene.vs",
+.static_src =
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec4 a_norm;\n"
+"layout (location=2) in vec2 a_uv;\n"
+"\n"
+"#line 1 1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+" // This magically solves some artifacting errors!\n"
+" //\n"
+" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
+"\n"
+" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line 6 0 \n"
+"\n"
+"uniform mat4x3 uMdl;\n"
+"uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
+"\n"
+"out vec2 aUv;\n"
+"out vec4 aNorm;\n"
+"out vec3 aCo;\n"
+"out vec3 aWorldCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
+" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
+" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+" vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+" gl_Position = vproj0;\n"
+"\n"
+" aUv = a_uv;\n"
+" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
+" aCo = a_co;\n"
+" aWorldCo = world_pos0;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/scene_standard.fs",
+.static_src =
+"uniform sampler2D uTexGarbage;\n"
+"uniform sampler2D uTexMain;\n"
+"uniform vec3 uCamera;\n"
+"uniform vec4 uPlane;\n"
+"\n"
+"#line 1 1 \n"
+"// :D\n"
+"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
+"\n"
+"#line 7 0 \n"
+"#line 1 2 \n"
+"// :D\n"
+"\n"
+"in vec2 aUv;\n"
+"in vec4 aNorm;\n"
+"in vec3 aCo;\n"
+"in vec3 aWorldCo;\n"
+"\n"
+"#line 1 1 \n"
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
+"layout (std140) uniform ub_world_lighting\n"
+"{\n"
+" vec4 g_cube_min;\n"
+" vec4 g_cube_inv_range;\n"
+"\n"
+" vec4 g_water_plane;\n"
+" vec4 g_depth_bounds;\n"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+" vec4 g_board_0;\n"
+" vec4 g_board_1;\n"
+"\n"
+" float g_water_fog;\n"
+" float g_time;\n"
+" float g_realtime;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
+" int g_light_preview;\n"
+" int g_shadow_samples;\n"
+"\n"
+" int g_debug_indices;\n"
+" int g_debug_complexity;\n"
+"};\n"
+"\n"
+"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\n"
+"\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
+"\n"
+"const float SUN_ANGLE = 0.0001;\n"
+"const float PI = 3.14159265358979323846264;\n"
+"\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
+"\n"
+"vec3 rand33(vec3 p3)\n"
+"{\n"
+" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
+" p3 += dot(p3, p3.yxz+33.33);\n"
+" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
+"}\n"
+"\n"
+"float stars( vec3 rd, float rr, float size ){\n"
+" vec3 co = rd * rr;\n"
+"\n"
+" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
+"\n"
+" float spaces = 1.0 / rr;\n"
+" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
+" a -= mod(a, spaces) - spaces * 0.5;\n"
+"\n"
+" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
+" \n"
+" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
+" plane = plane - mod(plane, PI / count);\n"
+"\n"
+" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
+"\n"
+" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
+" float ydist = sqrt(rr * rr - level * level);\n"
+" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
+" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
+" float star = smoothstep(size, 0.0, distance(center, co));\n"
+" return star;\n"
+"}\n"
+"\n"
+"float luminance( vec3 v )\n"
+"{\n"
+" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
+"}\n"
+"\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
+"{\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
+" float sky_gradient = dir.y;\n"
+" \n"
+" /* Blend phase colours */\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
+" \n"
+" /* Add gradient */\n"
+" ambient -= sky_gradient * luminance(ambient);\n"
+" \n"
+" return ambient;\n"
+"}\n"
+"\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
+"{\n"
+" ray_dir.y = abs( ray_dir.y );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
+" \n"
+" /* Sun */\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
+" float sun_shape = pow( sun_size, 2000.0 );\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" \n"
+" float star = 0.0;\n"
+" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
+"\n"
+" if( star_blend > 0.001 ){\n"
+" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
+" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
+" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
+" }\n"
+" }\n"
+" \n"
+" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
+" return composite;\n"
+"}\n"
+"\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
+"{\n"
+" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
+"\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
+" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
+" ) * g_sun_colour.rgb * g_day_phase;\n"
+"\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
+"\n"
+"#line 44 0 \n"
+"\n"
+"float world_depth_sample( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" return texture( g_world_depth, depth_coord ).r;\n"
+"}\n"
+"\n"
+"float world_water_depth( vec3 pos )\n"
+"{\n"
+" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
+"}\n"
+"\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
+"\n"
+" float fdelta = height_sample - co.y;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
+"}\n"
+"\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
+" return 1.0;\n"
+" }\n"
+"\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\n"
+"\n"
+" float famt = 0.0;\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+"\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+"\n"
+" return 1.0 - famt;\n"
+"}\n"
+"\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
+"{\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
+"}\n"
+"\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_light( int light_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
+" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
+" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
+"\n"
+" vec3 light_delta = light_co.xyz-co;\n"
+" float dist2 = dot(light_delta,light_delta);\n"
+"\n"
+" light_delta = normalize( light_delta );\n"
+"\n"
+" float quadratic = dist2*100.0;\n"
+" float attenuation = 1.0/( 1.0 + quadratic );\n"
+" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
+"\n"
+" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
+"\n"
+" if( light_dir.w < 0.999999 ){\n"
+" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
+" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
+" }\n"
+"\n"
+" return light_colour.rgb * attenuation * falloff \n"
+" * step( g_day_phase, light_colour.w );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" uint light_count = packed_index & 0x3u;\n"
+"\n"
+" vec3 l = vec3(0.0);\n"
+"\n"
+" if( light_count >= 1u ){\n"
+" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
+" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
+" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
+"\n"
+" l += scene_calculate_light( index_0, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 2u ){\n"
+" l += scene_calculate_light( index_1, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 3u ){\n"
+" l += scene_calculate_light( index_2, halfview, co, normal );\n"
+" }\n"
+" }\n"
+" }\n"
+"\n"
+" return l;\n"
+"}\n"
+"\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
+"{\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
+"\n"
+" // Lighting\n"
+" vec3 halfview = uCamera - co;\n"
+" float fdist = length(halfview);\n"
+" halfview /= fdist;\n"
+"\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+"\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
+"\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" cube_coord = floor( cube_coord );\n"
+"\n"
+" if( g_debug_indices == 1 )\n"
+" {\n"
+" return rand33(cube_coord);\n"
+" }\n"
+"\n"
+" if( g_debug_complexity == 1 )\n"
+" {\n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
+" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
+" }\n"
+"\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
+" \n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.x,\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.y,\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" fog_colour += sun_colour;\n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"\n"
+"float sdLine( vec3 p, vec3 a, vec3 b )\n"
+"{\n"
+" vec3 pa = p - a;\n"
+" vec3 ba = b - a;\n"
+"\n"
+" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
+" return length( pa - ba*h );\n"
+"}\n"
+"\n"
+"float compute_board_shadow()\n"
+"{\n"
+" // player shadow\n"
+" float dist_to_player = max( 0.0, sdLine( aWorldCo, g_board_0.xyz,\n"
+" g_board_1.xyz )-0.1 );\n"
+" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
+" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
+"\n"
+" return 1.0 - player_shadow*0.8;\n"
+"}\n"
+"\n"
+"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
+"{\n"
+" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
+"}\n"
+"\n"
+"#line 8 0 \n"
+"#line 1 3 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+" // Write motion vectors\n"
+" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"\n"
+" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"\n"
+"void main()\n"
+"{\n"
+" compute_motion_vectors();\n"
+"\n"
+" vec3 vfrag = vec3(0.5,0.5,0.5);\n"
+" vec4 vsamplemain = texture( uTexMain, aUv );\n"
+" vec3 qnorm = aNorm.xyz;\n"
+"\n"
+" vfrag = vsamplemain.rgb;\n"
+"\n"
+" if( g_light_preview == 1 )\n"
+" {\n"
+" vfrag = vec3(0.5);\n"
+" }\n"
+"\n"
+" vfrag = scene_compute_lighting( vfrag, qnorm, aWorldCo );\n"
+" oColour = vec4( vfrag, 1.0 );\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_scene_standard_uMdl;
+GLuint _uniform_scene_standard_uPv;
+GLuint _uniform_scene_standard_uPvmPrev;
+GLuint _uniform_scene_standard_uTexGarbage;
+GLuint _uniform_scene_standard_uTexMain;
+GLuint _uniform_scene_standard_uCamera;
+GLuint _uniform_scene_standard_uPlane;
+GLuint _uniform_scene_standard_g_world_depth;
+GLuint _uniform_scene_standard_uLightsArray;
+GLuint _uniform_scene_standard_uLightsIndex;
+#include "shaders/scene_standard_alphatest.h"
+struct vg_shader _shader_scene_standard_alphatest = {
+ .name = "scene_standard_alphatest",
+ .vs =
+{
+.orig_file = "shaders/scene.vs",
+.static_src =
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec4 a_norm;\n"
+"layout (location=2) in vec2 a_uv;\n"
+"\n"
+"#line 1 1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+" // This magically solves some artifacting errors!\n"
+" //\n"
+" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
+"\n"
+" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line 6 0 \n"
+"\n"
+"uniform mat4x3 uMdl;\n"
+"uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
+"\n"
+"out vec2 aUv;\n"
+"out vec4 aNorm;\n"
+"out vec3 aCo;\n"
+"out vec3 aWorldCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
+" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
+" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+" vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+" gl_Position = vproj0;\n"
+"\n"
+" aUv = a_uv;\n"
+" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
+" aCo = a_co;\n"
+" aWorldCo = world_pos0;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/scene_standard_alphatest.fs",
+.static_src =
+"uniform sampler2D uTexGarbage;\n"
+"uniform sampler2D uTexMain;\n"
+"uniform vec3 uCamera;\n"
+"uniform vec4 uPlane;\n"
+"\n"
+"#line 1 1 \n"
+"// :D\n"
+"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
+"\n"
+"#line 7 0 \n"
+"#line 1 2 \n"
+"// :D\n"
+"\n"
+"in vec2 aUv;\n"
+"in vec4 aNorm;\n"
+"in vec3 aCo;\n"
+"in vec3 aWorldCo;\n"
+"\n"
+"#line 1 1 \n"
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
+"layout (std140) uniform ub_world_lighting\n"
+"{\n"
+" vec4 g_cube_min;\n"
+" vec4 g_cube_inv_range;\n"
+"\n"
+" vec4 g_water_plane;\n"
+" vec4 g_depth_bounds;\n"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+" vec4 g_board_0;\n"
+" vec4 g_board_1;\n"
+"\n"
+" float g_water_fog;\n"
+" float g_time;\n"
+" float g_realtime;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
+" int g_light_preview;\n"
+" int g_shadow_samples;\n"
+"\n"
+" int g_debug_indices;\n"
+" int g_debug_complexity;\n"
+"};\n"
+"\n"
+"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\n"
+"\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
+"\n"
+"const float SUN_ANGLE = 0.0001;\n"
+"const float PI = 3.14159265358979323846264;\n"
+"\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
+"\n"
+"vec3 rand33(vec3 p3)\n"
+"{\n"
+" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
+" p3 += dot(p3, p3.yxz+33.33);\n"
+" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
+"}\n"
+"\n"
+"float stars( vec3 rd, float rr, float size ){\n"
+" vec3 co = rd * rr;\n"
+"\n"
+" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
+"\n"
+" float spaces = 1.0 / rr;\n"
+" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
+" a -= mod(a, spaces) - spaces * 0.5;\n"
+"\n"
+" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
+" \n"
+" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
+" plane = plane - mod(plane, PI / count);\n"
+"\n"
+" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
+"\n"
+" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
+" float ydist = sqrt(rr * rr - level * level);\n"
+" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
+" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
+" float star = smoothstep(size, 0.0, distance(center, co));\n"
+" return star;\n"
+"}\n"
+"\n"
+"float luminance( vec3 v )\n"
+"{\n"
+" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
+"}\n"
+"\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
+"{\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
+" float sky_gradient = dir.y;\n"
+" \n"
+" /* Blend phase colours */\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
+" \n"
+" /* Add gradient */\n"
+" ambient -= sky_gradient * luminance(ambient);\n"
+" \n"
+" return ambient;\n"
+"}\n"
+"\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
+"{\n"
+" ray_dir.y = abs( ray_dir.y );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
+" \n"
+" /* Sun */\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
+" float sun_shape = pow( sun_size, 2000.0 );\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" \n"
+" float star = 0.0;\n"
+" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
+"\n"
+" if( star_blend > 0.001 ){\n"
+" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
+" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
+" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
+" }\n"
+" }\n"
+" \n"
+" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
+" return composite;\n"
+"}\n"
+"\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
+"{\n"
+" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
+"\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
+" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
+" ) * g_sun_colour.rgb * g_day_phase;\n"
+"\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
+"\n"
+"#line 44 0 \n"
+"\n"
+"float world_depth_sample( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" return texture( g_world_depth, depth_coord ).r;\n"
+"}\n"
+"\n"
+"float world_water_depth( vec3 pos )\n"
+"{\n"
+" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
+"}\n"
+"\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
+"\n"
+" float fdelta = height_sample - co.y;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
+"}\n"
+"\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
+" return 1.0;\n"
+" }\n"
+"\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\n"
+"\n"
+" float famt = 0.0;\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+"\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+"\n"
+" return 1.0 - famt;\n"
+"}\n"
+"\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
+"{\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
+"}\n"
+"\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_light( int light_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
+" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
+" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
+"\n"
+" vec3 light_delta = light_co.xyz-co;\n"
+" float dist2 = dot(light_delta,light_delta);\n"
+"\n"
+" light_delta = normalize( light_delta );\n"
+"\n"
+" float quadratic = dist2*100.0;\n"
+" float attenuation = 1.0/( 1.0 + quadratic );\n"
+" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
+"\n"
+" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
+"\n"
+" if( light_dir.w < 0.999999 ){\n"
+" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
+" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
+" }\n"
+"\n"
+" return light_colour.rgb * attenuation * falloff \n"
+" * step( g_day_phase, light_colour.w );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" uint light_count = packed_index & 0x3u;\n"
+"\n"
+" vec3 l = vec3(0.0);\n"
+"\n"
+" if( light_count >= 1u ){\n"
+" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
+" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
+" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
+"\n"
+" l += scene_calculate_light( index_0, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 2u ){\n"
+" l += scene_calculate_light( index_1, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 3u ){\n"
+" l += scene_calculate_light( index_2, halfview, co, normal );\n"
+" }\n"
+" }\n"
+" }\n"
+"\n"
+" return l;\n"
+"}\n"
+"\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
+"{\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
+"\n"
+" // Lighting\n"
+" vec3 halfview = uCamera - co;\n"
+" float fdist = length(halfview);\n"
+" halfview /= fdist;\n"
+"\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+"\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
+"\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" cube_coord = floor( cube_coord );\n"
+"\n"
+" if( g_debug_indices == 1 )\n"
+" {\n"
+" return rand33(cube_coord);\n"
+" }\n"
+"\n"
+" if( g_debug_complexity == 1 )\n"
+" {\n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
+" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
+" }\n"
+"\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
+" \n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.x,\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.y,\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" fog_colour += sun_colour;\n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"\n"
+"float sdLine( vec3 p, vec3 a, vec3 b )\n"
+"{\n"
+" vec3 pa = p - a;\n"
+" vec3 ba = b - a;\n"
+"\n"
+" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
+" return length( pa - ba*h );\n"
+"}\n"
+"\n"
+"float compute_board_shadow()\n"
+"{\n"
+" // player shadow\n"
+" float dist_to_player = max( 0.0, sdLine( aWorldCo, g_board_0.xyz,\n"
+" g_board_1.xyz )-0.1 );\n"
+" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
+" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
+"\n"
+" return 1.0 - player_shadow*0.8;\n"
+"}\n"
+"\n"
+"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
+"{\n"
+" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
+"}\n"
+"\n"
+"#line 8 0 \n"
+"#line 1 3 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+" // Write motion vectors\n"
+" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"\n"
+" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"\n"
+"void main()\n"
+"{\n"
+" compute_motion_vectors();\n"
+"\n"
+" vec3 vfrag = vec3(0.5,0.5,0.5);\n"
+" vec4 vsamplemain = texture( uTexMain, aUv );\n"
+" vec3 qnorm = aNorm.xyz;\n"
+"\n"
+" if( vsamplemain.a < 0.15 )\n"
+" discard;\n"
+"\n"
+" vfrag = vsamplemain.rgb;\n"
+"\n"
+" if( g_light_preview == 1 )\n"
+" {\n"
+" vfrag = vec3(0.5);\n"
+" }\n"
+"\n"
+" vfrag = scene_compute_lighting( vfrag, qnorm, aWorldCo );\n"
+" oColour = vec4(vfrag, 1.0);\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_scene_standard_alphatest_uMdl;
+GLuint _uniform_scene_standard_alphatest_uPv;
+GLuint _uniform_scene_standard_alphatest_uPvmPrev;
+GLuint _uniform_scene_standard_alphatest_uTexGarbage;
+GLuint _uniform_scene_standard_alphatest_uTexMain;
+GLuint _uniform_scene_standard_alphatest_uCamera;
+GLuint _uniform_scene_standard_alphatest_uPlane;
+GLuint _uniform_scene_standard_alphatest_g_world_depth;
+GLuint _uniform_scene_standard_alphatest_uLightsArray;
+GLuint _uniform_scene_standard_alphatest_uLightsIndex;
+#include "shaders/scene_foliage.h"
+struct vg_shader _shader_scene_foliage = {
+ .name = "scene_foliage",
+ .vs =
+{
+.orig_file = "shaders/scene_foliage.vs",
+.static_src =
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec4 a_norm;\n"
+"layout (location=2) in vec2 a_uv;\n"
+"\n"
+"#line 1 1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+" // This magically solves some artifacting errors!\n"
+" //\n"
+" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
+"\n"
+" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line 6 0 \n"
+"\n"
+"uniform mat4x3 uMdl;\n"
+"uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
+"uniform float uTime;\n"
+"\n"
+"out vec2 aUv;\n"
+"out vec4 aNorm;\n"
+"out vec3 aCo;\n"
+"out vec3 aWorldCo;\n"
+"\n"
+"void main(){\n"
+" vec4 vsine = sin(vec4(uTime + a_co.x, uTime*0.7 + a_co.z,uTime,uTime*1.3));\n"
+" vec3 co = a_co + vsine.xyz * a_norm.w * 0.5;\n"
+" \n"
+" vec3 world_pos0 = uMdl * vec4( co, 1.0 );\n"
+" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
+" vec4 vproj1 = uPvmPrev * vec4( co, 1.0 );\n"
+"\n"
+" vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+" gl_Position = vproj0;\n"
+"\n"
+" aUv = a_uv;\n"
+" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
+" aCo = a_co;\n"
+" aWorldCo = world_pos0;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/scene_foliage.fs",
+.static_src =
+"uniform sampler2D uTexGarbage;\n"
+"uniform sampler2D uTexMain;\n"
+"uniform vec3 uCamera;\n"
+"uniform vec4 uPlane;\n"
+"\n"
+"const float CLEARSKIES_LIGHT_DOT_MIN = 0.4;\n"
+"#line 1 1 \n"
+"// :D\n"
+"\n"
+"in vec2 aUv;\n"
+"in vec4 aNorm;\n"
+"in vec3 aCo;\n"
+"in vec3 aWorldCo;\n"
+"\n"
+"#line 1 1 \n"
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
+"layout (std140) uniform ub_world_lighting\n"
+"{\n"
+" vec4 g_cube_min;\n"
+" vec4 g_cube_inv_range;\n"
+"\n"
+" vec4 g_water_plane;\n"
+" vec4 g_depth_bounds;\n"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+" vec4 g_board_0;\n"
+" vec4 g_board_1;\n"
+"\n"
+" float g_water_fog;\n"
+" float g_time;\n"
+" float g_realtime;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
+" int g_light_preview;\n"
+" int g_shadow_samples;\n"
+"\n"
+" int g_debug_indices;\n"
+" int g_debug_complexity;\n"
+"};\n"
+"\n"
+"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\n"
+"\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
+"\n"
+"const float SUN_ANGLE = 0.0001;\n"
+"const float PI = 3.14159265358979323846264;\n"
+"\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
+"\n"
+"vec3 rand33(vec3 p3)\n"
+"{\n"
+" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
+" p3 += dot(p3, p3.yxz+33.33);\n"
+" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
+"}\n"
+"\n"
+"float stars( vec3 rd, float rr, float size ){\n"
+" vec3 co = rd * rr;\n"
+"\n"
+" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
+"\n"
+" float spaces = 1.0 / rr;\n"
+" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
+" a -= mod(a, spaces) - spaces * 0.5;\n"
+"\n"
+" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
+" \n"
+" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
+" plane = plane - mod(plane, PI / count);\n"
+"\n"
+" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
+"\n"
+" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
+" float ydist = sqrt(rr * rr - level * level);\n"
+" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
+" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
+" float star = smoothstep(size, 0.0, distance(center, co));\n"
+" return star;\n"
+"}\n"
+"\n"
+"float luminance( vec3 v )\n"
+"{\n"
+" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
+"}\n"
+"\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
+"{\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
+" float sky_gradient = dir.y;\n"
+" \n"
+" /* Blend phase colours */\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
+" \n"
+" /* Add gradient */\n"
+" ambient -= sky_gradient * luminance(ambient);\n"
+" \n"
+" return ambient;\n"
+"}\n"
+"\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
+"{\n"
+" ray_dir.y = abs( ray_dir.y );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
+" \n"
+" /* Sun */\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
+" float sun_shape = pow( sun_size, 2000.0 );\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" \n"
+" float star = 0.0;\n"
+" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
+"\n"
+" if( star_blend > 0.001 ){\n"
+" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
+" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
+" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
+" }\n"
+" }\n"
+" \n"
+" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
+" return composite;\n"
+"}\n"
+"\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
+"{\n"
+" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
+"\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
+" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
+" ) * g_sun_colour.rgb * g_day_phase;\n"
+"\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
+"\n"
+"#line 44 0 \n"
+"\n"
+"float world_depth_sample( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" return texture( g_world_depth, depth_coord ).r;\n"
+"}\n"
+"\n"
+"float world_water_depth( vec3 pos )\n"
+"{\n"
+" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
+"}\n"
+"\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
+"\n"
+" float fdelta = height_sample - co.y;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
+"}\n"
+"\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
+" return 1.0;\n"
+" }\n"
+"\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\n"
+"\n"
+" float famt = 0.0;\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+"\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+"\n"
+" return 1.0 - famt;\n"
+"}\n"
+"\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
+"{\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
+"}\n"
+"\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_light( int light_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
+" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
+" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
+"\n"
+" vec3 light_delta = light_co.xyz-co;\n"
+" float dist2 = dot(light_delta,light_delta);\n"
+"\n"
+" light_delta = normalize( light_delta );\n"
+"\n"
+" float quadratic = dist2*100.0;\n"
+" float attenuation = 1.0/( 1.0 + quadratic );\n"
+" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
+"\n"
+" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
+"\n"
+" if( light_dir.w < 0.999999 ){\n"
+" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
+" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
+" }\n"
+"\n"
+" return light_colour.rgb * attenuation * falloff \n"
+" * step( g_day_phase, light_colour.w );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" uint light_count = packed_index & 0x3u;\n"
+"\n"
+" vec3 l = vec3(0.0);\n"
+"\n"
+" if( light_count >= 1u ){\n"
+" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
+" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
+" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
+"\n"
+" l += scene_calculate_light( index_0, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 2u ){\n"
+" l += scene_calculate_light( index_1, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 3u ){\n"
+" l += scene_calculate_light( index_2, halfview, co, normal );\n"
+" }\n"
+" }\n"
+" }\n"
+"\n"
+" return l;\n"
+"}\n"
+"\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
+"{\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
+"\n"
+" // Lighting\n"
+" vec3 halfview = uCamera - co;\n"
+" float fdist = length(halfview);\n"
+" halfview /= fdist;\n"
+"\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+"\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
+"\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" cube_coord = floor( cube_coord );\n"
+"\n"
+" if( g_debug_indices == 1 )\n"
+" {\n"
+" return rand33(cube_coord);\n"
+" }\n"
+"\n"
+" if( g_debug_complexity == 1 )\n"
+" {\n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
+" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
+" }\n"
+"\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
+" \n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.x,\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.y,\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" fog_colour += sun_colour;\n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"\n"
+"float sdLine( vec3 p, vec3 a, vec3 b )\n"
+"{\n"
+" vec3 pa = p - a;\n"
+" vec3 ba = b - a;\n"
+"\n"
+" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
+" return length( pa - ba*h );\n"
+"}\n"
+"\n"
+"float compute_board_shadow()\n"
+"{\n"
+" // player shadow\n"
+" float dist_to_player = max( 0.0, sdLine( aWorldCo, g_board_0.xyz,\n"
+" g_board_1.xyz )-0.1 );\n"
+" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
+" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
+"\n"
+" return 1.0 - player_shadow*0.8;\n"
+"}\n"
+"\n"
+"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
+"{\n"
+" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
+"}\n"
+"\n"
+"#line 8 0 \n"
+"#line 1 2 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+" // Write motion vectors\n"
+" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"\n"
+" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"\n"
+"void main(){\n"
+" compute_motion_vectors();\n"
+"\n"
+" vec3 vfrag = vec3(0.5,0.5,0.5);\n"
+" vec4 vsamplemain = texture( uTexMain, aUv );\n"
+" vec3 qnorm = aNorm.xyz;\n"
+"\n"
+" if( vsamplemain.a < 0.15 )\n"
+" discard;\n"
+"\n"
+" vfrag = vsamplemain.rgb;\n"
+"\n"
+" if( g_light_preview == 1 ){\n"
+" vfrag = vec3(0.5);\n"
+" }\n"
+"\n"
+" vfrag = scene_compute_lighting( vfrag, qnorm, aWorldCo );\n"
+" oColour = vec4(vfrag, 1.0);\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_scene_foliage_uMdl;
+GLuint _uniform_scene_foliage_uPv;
+GLuint _uniform_scene_foliage_uPvmPrev;
+GLuint _uniform_scene_foliage_uTime;
+GLuint _uniform_scene_foliage_uTexGarbage;
+GLuint _uniform_scene_foliage_uTexMain;
+GLuint _uniform_scene_foliage_uCamera;
+GLuint _uniform_scene_foliage_uPlane;
+GLuint _uniform_scene_foliage_g_world_depth;
+GLuint _uniform_scene_foliage_uLightsArray;
+GLuint _uniform_scene_foliage_uLightsIndex;
+#include "shaders/scene_override.h"
+struct vg_shader _shader_scene_override = {
+ .name = "scene_override",
+ .vs =
+{
+.orig_file = "shaders/scene_override.vs",
+.static_src =
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec4 a_norm;\n"
+"layout (location=2) in vec2 a_uv;\n"
+"\n"
+"#line 1 1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+" // This magically solves some artifacting errors!\n"
+" //\n"
+" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
+"\n"
+" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line 6 0 \n"
+"\n"
+"uniform mat4x3 uMdl;\n"
+"uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
+"uniform mat3 uNormalMtx;\n"
+"\n"
+"out vec2 aUv;\n"
+"out vec4 aNorm;\n"
+"out vec3 aCo;\n"
+"out vec3 aWorldCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
+" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
+" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+" vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+" gl_Position = vproj0;\n"
+"\n"
+" aUv = a_uv;\n"
+" aNorm = vec4( uNormalMtx * a_norm.xyz, a_norm.w );\n"
+" aCo = a_co;\n"
+" aWorldCo = world_pos0;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/scene_override.fs",
+.static_src =
+"uniform sampler2D uTexGarbage;\n"
+"uniform sampler2D uTexMain;\n"
+"uniform vec3 uCamera;\n"
+"uniform vec4 uPlane;\n"
+"\n"
+"uniform vec4 uPlayerPos; /* w: distance to uSpawnPos */\n"
+"uniform vec4 uSpawnPos; /* w: inverse distance to uPlayerPos */\n"
+"uniform bool uAlphatest;\n"
+"uniform vec4 uMapInfo; /* x: min, y: max, z: iso line amount */\n"
+"\n"
+"#line 1 1 \n"
+"// :D\n"
+"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
+"\n"
+"#line 12 0 \n"
+"#line 1 2 \n"
+"// :D\n"
+"\n"
+"in vec2 aUv;\n"
+"in vec4 aNorm;\n"
+"in vec3 aCo;\n"
+"in vec3 aWorldCo;\n"
+"\n"
+"#line 1 1 \n"
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
+"layout (std140) uniform ub_world_lighting\n"
+"{\n"
+" vec4 g_cube_min;\n"
+" vec4 g_cube_inv_range;\n"
+"\n"
+" vec4 g_water_plane;\n"
+" vec4 g_depth_bounds;\n"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+" vec4 g_board_0;\n"
+" vec4 g_board_1;\n"
+"\n"
+" float g_water_fog;\n"
+" float g_time;\n"
+" float g_realtime;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
+" int g_light_preview;\n"
+" int g_shadow_samples;\n"
+"\n"
+" int g_debug_indices;\n"
+" int g_debug_complexity;\n"
+"};\n"
+"\n"
+"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\n"
+"\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
+"\n"
+"const float SUN_ANGLE = 0.0001;\n"
+"const float PI = 3.14159265358979323846264;\n"
+"\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
+"\n"
+"vec3 rand33(vec3 p3)\n"
+"{\n"
+" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
+" p3 += dot(p3, p3.yxz+33.33);\n"
+" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
+"}\n"
+"\n"
+"float stars( vec3 rd, float rr, float size ){\n"
+" vec3 co = rd * rr;\n"
+"\n"
+" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
+"\n"
+" float spaces = 1.0 / rr;\n"
+" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
+" a -= mod(a, spaces) - spaces * 0.5;\n"
+"\n"
+" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
+" \n"
+" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
+" plane = plane - mod(plane, PI / count);\n"
+"\n"
+" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
+"\n"
+" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
+" float ydist = sqrt(rr * rr - level * level);\n"
+" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
+" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
+" float star = smoothstep(size, 0.0, distance(center, co));\n"
+" return star;\n"
+"}\n"
+"\n"
+"float luminance( vec3 v )\n"
+"{\n"
+" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
+"}\n"
+"\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
+"{\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
+" float sky_gradient = dir.y;\n"
+" \n"
+" /* Blend phase colours */\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
+" \n"
+" /* Add gradient */\n"
+" ambient -= sky_gradient * luminance(ambient);\n"
+" \n"
+" return ambient;\n"
+"}\n"
+"\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
+"{\n"
+" ray_dir.y = abs( ray_dir.y );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
+" \n"
+" /* Sun */\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
+" float sun_shape = pow( sun_size, 2000.0 );\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" \n"
+" float star = 0.0;\n"
+" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
+"\n"
+" if( star_blend > 0.001 ){\n"
+" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
+" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
+" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
+" }\n"
+" }\n"
+" \n"
+" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
+" return composite;\n"
+"}\n"
+"\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
+"{\n"
+" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
+"\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
+" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
+" ) * g_sun_colour.rgb * g_day_phase;\n"
+"\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
+"\n"
+"#line 44 0 \n"
+"\n"
+"float world_depth_sample( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" return texture( g_world_depth, depth_coord ).r;\n"
+"}\n"
+"\n"
+"float world_water_depth( vec3 pos )\n"
+"{\n"
+" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
+"}\n"
+"\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
+"\n"
+" float fdelta = height_sample - co.y;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
+"}\n"
+"\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
+" return 1.0;\n"
+" }\n"
+"\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\n"
+"\n"
+" float famt = 0.0;\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+"\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+"\n"
+" return 1.0 - famt;\n"
+"}\n"
+"\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
+"{\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
+"}\n"
+"\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_light( int light_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
+" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
+" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
+"\n"
+" vec3 light_delta = light_co.xyz-co;\n"
+" float dist2 = dot(light_delta,light_delta);\n"
+"\n"
+" light_delta = normalize( light_delta );\n"
+"\n"
+" float quadratic = dist2*100.0;\n"
+" float attenuation = 1.0/( 1.0 + quadratic );\n"
+" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
+"\n"
+" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
+"\n"
+" if( light_dir.w < 0.999999 ){\n"
+" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
+" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
+" }\n"
+"\n"
+" return light_colour.rgb * attenuation * falloff \n"
+" * step( g_day_phase, light_colour.w );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" uint light_count = packed_index & 0x3u;\n"
+"\n"
+" vec3 l = vec3(0.0);\n"
+"\n"
+" if( light_count >= 1u ){\n"
+" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
+" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
+" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
+"\n"
+" l += scene_calculate_light( index_0, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 2u ){\n"
+" l += scene_calculate_light( index_1, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 3u ){\n"
+" l += scene_calculate_light( index_2, halfview, co, normal );\n"
+" }\n"
+" }\n"
+" }\n"
+"\n"
+" return l;\n"
+"}\n"
+"\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
+"{\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
+"\n"
+" // Lighting\n"
+" vec3 halfview = uCamera - co;\n"
+" float fdist = length(halfview);\n"
+" halfview /= fdist;\n"
+"\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+"\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
+"\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" cube_coord = floor( cube_coord );\n"
+"\n"
+" if( g_debug_indices == 1 )\n"
+" {\n"
+" return rand33(cube_coord);\n"
+" }\n"
+"\n"
+" if( g_debug_complexity == 1 )\n"
+" {\n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
+" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
+" }\n"
+"\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
+" \n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.x,\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.y,\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" fog_colour += sun_colour;\n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"\n"
+"float sdLine( vec3 p, vec3 a, vec3 b )\n"
+"{\n"
+" vec3 pa = p - a;\n"
+" vec3 ba = b - a;\n"
+"\n"
+" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
+" return length( pa - ba*h );\n"
+"}\n"
+"\n"
+"float compute_board_shadow()\n"
+"{\n"
+" // player shadow\n"
+" float dist_to_player = max( 0.0, sdLine( aWorldCo, g_board_0.xyz,\n"
+" g_board_1.xyz )-0.1 );\n"
+" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
+" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
+"\n"
+" return 1.0 - player_shadow*0.8;\n"
+"}\n"
+"\n"
+"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
+"{\n"
+" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
+"}\n"
+"\n"
+"#line 13 0 \n"
+"#line 1 3 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+" // Write motion vectors\n"
+" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"\n"
+" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
+"}\n"
+"\n"
+"#line 14 0 \n"
+"\n"
+"vec2 smin( float a, float b, float k ){\n"
+" float h = max( k-abs(a-b), 0.0 )/k;\n"
+" float m = h*h*0.5;\n"
+" float s = m*k*(1.0/2.0);\n"
+"\n"
+" if( a < b )\n"
+" return vec2(a-s,m);\n"
+" else\n"
+" return vec2(b-s,1.0-m);\n"
+"}\n"
+"\n"
+"void main(){\n"
+" vec2 ssuv = gl_FragCoord.xy;\n"
+" vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), ssuv) );\n"
+" float dither = fract( vDither.g / 71.0 ) - 0.5;\n"
+"\n"
+" float dcam = (-8.0+distance( aCo, uCamera ))/4.0;\n"
+" float dy0 = aCo.y - uMapInfo.x;\n"
+" float dy1 = uMapInfo.y - aCo.y;\n"
+"\n"
+" if( min(min(dy0,dy1)*0.5, dcam) + dither < 0.51 ) \n"
+" discard;\n"
+"\n"
+" compute_motion_vectors();\n"
+"\n"
+" vec3 vfrag = vec3(0.898,0.811,0.716);\n"
+" vec3 qnorm = aNorm.xyz;\n"
+"\n"
+" qnorm = normalize(floor(aNorm.xyz*4.0)*0.25);\n"
+" qnorm += vec3(0.001,0.0,0.0);\n"
+"\n"
+" if( uAlphatest ){\n"
+" vec4 vSample = texture( uTexMain, aUv );\n"
+" if( vSample.a < 0.5 )\n"
+" discard;\n"
+" }\n"
+" else{\n"
+" }\n"
+"\n"
+" vfrag = scene_compute_lighting( vfrag, qnorm, aWorldCo );\n"
+" \n"
+" // dots\n"
+" float d0 = distance( aCo, uPlayerPos.xyz )*2.0;\n"
+" float d1 = distance( aCo, uSpawnPos.xyz );\n"
+"\n"
+" vec2 dm = smin( d0, d1, 10.0 );\n"
+" float dd = fract(dm.x*0.2-g_realtime*0.5) * \n"
+" max(0.0,1.0-dm.x*0.04) * \n"
+" max(0.0,qnorm.y);\n"
+" vec3 emit = mix(vec3(1.0,0.0,0.0),vec3(0.0,1.0,0.0),dm.y)*dd;\n"
+"\n"
+" // line\n"
+" vec3 v0 = (uSpawnPos.xyz-uPlayerPos.xyz)*uSpawnPos.w;\n"
+" float t = clamp( dot(aCo-uPlayerPos.xyz,v0), 0.0, uPlayerPos.w );\n"
+" vec3 p0 = uPlayerPos.xyz + v0*t;\n"
+" float d3 = distance(p0,aCo);\n"
+" emit += vec3(fract(t*0.2-g_realtime+d3*0.2)*max(0.0,1.0-d3*0.2));\n"
+"\n"
+" vfrag += emit;\n"
+"\n"
+" if( uMapInfo.z > 0.0 ){\n"
+" float height = fract( aCo.y * 0.1 );\n"
+" float lg = 2.0*length(vec2(dFdx(height), dFdy(height)));\n"
+" vfrag *= 1.0f+(lg*0.2*uMapInfo.z);\n"
+" }\n"
+"\n"
+" oColour = vec4( vfrag, 1.0 );\n"
+" //oColour = vec4( vfrag, 1.0 );\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_scene_override_uMdl;
+GLuint _uniform_scene_override_uPv;
+GLuint _uniform_scene_override_uPvmPrev;
+GLuint _uniform_scene_override_uNormalMtx;
+GLuint _uniform_scene_override_uTexGarbage;
+GLuint _uniform_scene_override_uTexMain;
+GLuint _uniform_scene_override_uCamera;
+GLuint _uniform_scene_override_uPlane;
+GLuint _uniform_scene_override_uPlayerPos;
+GLuint _uniform_scene_override_uSpawnPos;
+GLuint _uniform_scene_override_uAlphatest;
+GLuint _uniform_scene_override_uMapInfo;
+GLuint _uniform_scene_override_g_world_depth;
+GLuint _uniform_scene_override_uLightsArray;
+GLuint _uniform_scene_override_uLightsIndex;
+#include "shaders/scene_fxglow.h"
+struct vg_shader _shader_scene_fxglow = {
+ .name = "scene_fxglow",
+ .vs =
+{
+.orig_file = "shaders/scene_fxglow.vs",
+.static_src =
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec4 a_norm;\n"
+"layout (location=2) in vec2 a_uv;\n"
+"\n"
+"#line 1 1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+" // This magically solves some artifacting errors!\n"
+" //\n"
+" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
+"\n"
+" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line 6 0 \n"
+"\n"
+"uniform mat4x3 uMdl;\n"
+"uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
+"uniform vec2 uUvOffset;\n"
+"\n"
+"out vec2 aUv;\n"
+"out vec4 aNorm;\n"
+"out vec3 aCo;\n"
+"out vec3 aWorldCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
+" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
+" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+" vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+" gl_Position = vproj0;\n"
+"\n"
+" aUv = a_uv + uUvOffset;\n"
+" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
+" aCo = a_co;\n"
+" aWorldCo = world_pos0;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/scene_fxglow.fs",
+.static_src =
+"uniform sampler2D uTexMain;\n"
+"uniform vec3 uCamera;\n"
+"\n"
+"#line 1 1 \n"
+"// :D\n"
+"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
+"\n"
+"#line 5 0 \n"
+"#line 1 2 \n"
+"// :D\n"
+"\n"
+"in vec2 aUv;\n"
+"in vec4 aNorm;\n"
+"in vec3 aCo;\n"
+"in vec3 aWorldCo;\n"
+"\n"
+"#line 1 1 \n"
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
+"layout (std140) uniform ub_world_lighting\n"
+"{\n"
+" vec4 g_cube_min;\n"
+" vec4 g_cube_inv_range;\n"
+"\n"
+" vec4 g_water_plane;\n"
+" vec4 g_depth_bounds;\n"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+" vec4 g_board_0;\n"
+" vec4 g_board_1;\n"
+"\n"
+" float g_water_fog;\n"
+" float g_time;\n"
+" float g_realtime;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
+" int g_light_preview;\n"
+" int g_shadow_samples;\n"
+"\n"
+" int g_debug_indices;\n"
+" int g_debug_complexity;\n"
+"};\n"
+"\n"
+"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\n"
+"\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
+"\n"
+"const float SUN_ANGLE = 0.0001;\n"
+"const float PI = 3.14159265358979323846264;\n"
+"\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
+"\n"
+"vec3 rand33(vec3 p3)\n"
+"{\n"
+" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
+" p3 += dot(p3, p3.yxz+33.33);\n"
+" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
+"}\n"
+"\n"
+"float stars( vec3 rd, float rr, float size ){\n"
+" vec3 co = rd * rr;\n"
+"\n"
+" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
+"\n"
+" float spaces = 1.0 / rr;\n"
+" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
+" a -= mod(a, spaces) - spaces * 0.5;\n"
+"\n"
+" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
+" \n"
+" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
+" plane = plane - mod(plane, PI / count);\n"
+"\n"
+" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
+"\n"
+" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
+" float ydist = sqrt(rr * rr - level * level);\n"
+" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
+" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
+" float star = smoothstep(size, 0.0, distance(center, co));\n"
+" return star;\n"
+"}\n"
+"\n"
+"float luminance( vec3 v )\n"
+"{\n"
+" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
+"}\n"
+"\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
+"{\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
+" float sky_gradient = dir.y;\n"
+" \n"
+" /* Blend phase colours */\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
+" \n"
+" /* Add gradient */\n"
+" ambient -= sky_gradient * luminance(ambient);\n"
+" \n"
+" return ambient;\n"
+"}\n"
+"\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
+"{\n"
+" ray_dir.y = abs( ray_dir.y );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
+" \n"
+" /* Sun */\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
+" float sun_shape = pow( sun_size, 2000.0 );\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" \n"
+" float star = 0.0;\n"
+" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
+"\n"
+" if( star_blend > 0.001 ){\n"
+" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
+" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
+" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
+" }\n"
+" }\n"
+" \n"
+" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
+" return composite;\n"
+"}\n"
+"\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
+"{\n"
+" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
+"\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
+" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
+" ) * g_sun_colour.rgb * g_day_phase;\n"
+"\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
+"\n"
+"#line 44 0 \n"
+"\n"
+"float world_depth_sample( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" return texture( g_world_depth, depth_coord ).r;\n"
+"}\n"
+"\n"
+"float world_water_depth( vec3 pos )\n"
+"{\n"
+" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
+"}\n"
+"\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
+"\n"
+" float fdelta = height_sample - co.y;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
+"}\n"
+"\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
+" return 1.0;\n"
+" }\n"
+"\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\n"
+"\n"
+" float famt = 0.0;\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+"\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+"\n"
+" return 1.0 - famt;\n"
+"}\n"
+"\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
+"{\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
+"}\n"
+"\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_light( int light_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
+" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
+" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
+"\n"
+" vec3 light_delta = light_co.xyz-co;\n"
+" float dist2 = dot(light_delta,light_delta);\n"
+"\n"
+" light_delta = normalize( light_delta );\n"
+"\n"
+" float quadratic = dist2*100.0;\n"
+" float attenuation = 1.0/( 1.0 + quadratic );\n"
+" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
+"\n"
+" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
+"\n"
+" if( light_dir.w < 0.999999 ){\n"
+" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
+" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
+" }\n"
+"\n"
+" return light_colour.rgb * attenuation * falloff \n"
+" * step( g_day_phase, light_colour.w );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" uint light_count = packed_index & 0x3u;\n"
+"\n"
+" vec3 l = vec3(0.0);\n"
+"\n"
+" if( light_count >= 1u ){\n"
+" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
+" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
+" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
+"\n"
+" l += scene_calculate_light( index_0, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 2u ){\n"
+" l += scene_calculate_light( index_1, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 3u ){\n"
+" l += scene_calculate_light( index_2, halfview, co, normal );\n"
+" }\n"
+" }\n"
+" }\n"
+"\n"
+" return l;\n"
+"}\n"
+"\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
+"{\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
+"\n"
+" // Lighting\n"
+" vec3 halfview = uCamera - co;\n"
+" float fdist = length(halfview);\n"
+" halfview /= fdist;\n"
+"\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+"\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
+"\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" cube_coord = floor( cube_coord );\n"
+"\n"
+" if( g_debug_indices == 1 )\n"
+" {\n"
+" return rand33(cube_coord);\n"
+" }\n"
+"\n"
+" if( g_debug_complexity == 1 )\n"
+" {\n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
+" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
+" }\n"
+"\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
+" \n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.x,\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.y,\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" fog_colour += sun_colour;\n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"\n"
+"float sdLine( vec3 p, vec3 a, vec3 b )\n"
+"{\n"
+" vec3 pa = p - a;\n"
+" vec3 ba = b - a;\n"
+"\n"
+" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
+" return length( pa - ba*h );\n"
+"}\n"
+"\n"
+"float compute_board_shadow()\n"
+"{\n"
+" // player shadow\n"
+" float dist_to_player = max( 0.0, sdLine( aWorldCo, g_board_0.xyz,\n"
+" g_board_1.xyz )-0.1 );\n"
+" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
+" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
+"\n"
+" return 1.0 - player_shadow*0.8;\n"
+"}\n"
+"\n"
+"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
+"{\n"
+" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
+"}\n"
+"\n"
+"#line 6 0 \n"
+"#line 1 3 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+" // Write motion vectors\n"
+" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"\n"
+" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
+"}\n"
+"\n"
+"#line 7 0 \n"
+"\n"
+"void main(){\n"
+" oMotionVec = vec2(0.0);\n"
+"\n"
+" vec4 vsamplemain = texture( uTexMain, aUv );\n"
+"\n"
+" vec2 ssuv = gl_FragCoord.xy;\n"
+" vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), ssuv) );\n"
+" float dither = fract( vDither.g / 71.0 ) - 0.5;\n"
+"\n"
+" if( vsamplemain.a+dither<0.5 )\n"
+" discard;\n"
+"\n"
+" oColour = vec4( vsamplemain.rgb, 1.0 );\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_scene_fxglow_uMdl;
+GLuint _uniform_scene_fxglow_uPv;
+GLuint _uniform_scene_fxglow_uPvmPrev;
+GLuint _uniform_scene_fxglow_uUvOffset;
+GLuint _uniform_scene_fxglow_uTexMain;
+GLuint _uniform_scene_fxglow_uCamera;
+GLuint _uniform_scene_fxglow_g_world_depth;
+GLuint _uniform_scene_fxglow_uLightsArray;
+GLuint _uniform_scene_fxglow_uLightsIndex;
+#include "shaders/scene_vertex_blend.h"
+struct vg_shader _shader_scene_vertex_blend = {
+ .name = "scene_vertex_blend",
+ .vs =
+{
+.orig_file = "shaders/scene.vs",
+.static_src =
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec4 a_norm;\n"
+"layout (location=2) in vec2 a_uv;\n"
+"\n"
+"#line 1 1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+" // This magically solves some artifacting errors!\n"
+" //\n"
+" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
+"\n"
+" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line 6 0 \n"
+"\n"
+"uniform mat4x3 uMdl;\n"
+"uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
+"\n"
+"out vec2 aUv;\n"
+"out vec4 aNorm;\n"
+"out vec3 aCo;\n"
+"out vec3 aWorldCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
+" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
+" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+" vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+" gl_Position = vproj0;\n"
+"\n"
+" aUv = a_uv;\n"
+" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
+" aCo = a_co;\n"
+" aWorldCo = world_pos0;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/scene_vertex_blend.fs",
+.static_src =
+"uniform sampler2D uTexGarbage;\n"
+"uniform sampler2D uTexGradients;\n"
+"uniform vec3 uCamera;\n"
+"\n"
+"#line 1 1 \n"
+"// :D\n"
+"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
+"\n"
+"#line 6 0 \n"
+"#line 1 2 \n"
+"// :D\n"
+"\n"
+"in vec2 aUv;\n"
+"in vec4 aNorm;\n"
+"in vec3 aCo;\n"
+"in vec3 aWorldCo;\n"
+"\n"
+"#line 1 1 \n"
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
+"layout (std140) uniform ub_world_lighting\n"
+"{\n"
+" vec4 g_cube_min;\n"
+" vec4 g_cube_inv_range;\n"
+"\n"
+" vec4 g_water_plane;\n"
+" vec4 g_depth_bounds;\n"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+" vec4 g_board_0;\n"
+" vec4 g_board_1;\n"
+"\n"
+" float g_water_fog;\n"
+" float g_time;\n"
+" float g_realtime;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
+" int g_light_preview;\n"
+" int g_shadow_samples;\n"
+"\n"
+" int g_debug_indices;\n"
+" int g_debug_complexity;\n"
+"};\n"
+"\n"
+"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\n"
+"\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
+"\n"
+"const float SUN_ANGLE = 0.0001;\n"
+"const float PI = 3.14159265358979323846264;\n"
+"\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
+"\n"
+"vec3 rand33(vec3 p3)\n"
+"{\n"
+" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
+" p3 += dot(p3, p3.yxz+33.33);\n"
+" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
+"}\n"
+"\n"
+"float stars( vec3 rd, float rr, float size ){\n"
+" vec3 co = rd * rr;\n"
+"\n"
+" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
+"\n"
+" float spaces = 1.0 / rr;\n"
+" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
+" a -= mod(a, spaces) - spaces * 0.5;\n"
+"\n"
+" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
+" \n"
+" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
+" plane = plane - mod(plane, PI / count);\n"
+"\n"
+" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
+"\n"
+" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
+" float ydist = sqrt(rr * rr - level * level);\n"
+" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
+" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
+" float star = smoothstep(size, 0.0, distance(center, co));\n"
+" return star;\n"
+"}\n"
+"\n"
+"float luminance( vec3 v )\n"
+"{\n"
+" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
+"}\n"
+"\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
+"{\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
+" float sky_gradient = dir.y;\n"
+" \n"
+" /* Blend phase colours */\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
+" \n"
+" /* Add gradient */\n"
+" ambient -= sky_gradient * luminance(ambient);\n"
+" \n"
+" return ambient;\n"
+"}\n"
+"\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
+"{\n"
+" ray_dir.y = abs( ray_dir.y );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
+" \n"
+" /* Sun */\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
+" float sun_shape = pow( sun_size, 2000.0 );\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" \n"
+" float star = 0.0;\n"
+" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
+"\n"
+" if( star_blend > 0.001 ){\n"
+" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
+" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
+" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
+" }\n"
+" }\n"
+" \n"
+" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
+" return composite;\n"
+"}\n"
+"\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
+"{\n"
+" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
+"\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
+" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
+" ) * g_sun_colour.rgb * g_day_phase;\n"
+"\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
+"\n"
+"#line 44 0 \n"
+"\n"
+"float world_depth_sample( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" return texture( g_world_depth, depth_coord ).r;\n"
+"}\n"
+"\n"
+"float world_water_depth( vec3 pos )\n"
+"{\n"
+" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
+"}\n"
+"\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
+"\n"
+" float fdelta = height_sample - co.y;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
+"}\n"
+"\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
+" return 1.0;\n"
+" }\n"
+"\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\n"
+"\n"
+" float famt = 0.0;\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+"\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+"\n"
+" return 1.0 - famt;\n"
+"}\n"
+"\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
+"{\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
+"}\n"
+"\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_light( int light_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
+" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
+" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
+"\n"
+" vec3 light_delta = light_co.xyz-co;\n"
+" float dist2 = dot(light_delta,light_delta);\n"
+"\n"
+" light_delta = normalize( light_delta );\n"
+"\n"
+" float quadratic = dist2*100.0;\n"
+" float attenuation = 1.0/( 1.0 + quadratic );\n"
+" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
+"\n"
+" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
+"\n"
+" if( light_dir.w < 0.999999 ){\n"
+" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
+" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
+" }\n"
+"\n"
+" return light_colour.rgb * attenuation * falloff \n"
+" * step( g_day_phase, light_colour.w );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" uint light_count = packed_index & 0x3u;\n"
+"\n"
+" vec3 l = vec3(0.0);\n"
+"\n"
+" if( light_count >= 1u ){\n"
+" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
+" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
+" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
+"\n"
+" l += scene_calculate_light( index_0, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 2u ){\n"
+" l += scene_calculate_light( index_1, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 3u ){\n"
+" l += scene_calculate_light( index_2, halfview, co, normal );\n"
+" }\n"
+" }\n"
+" }\n"
+"\n"
+" return l;\n"
+"}\n"
+"\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
+"{\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
+"\n"
+" // Lighting\n"
+" vec3 halfview = uCamera - co;\n"
+" float fdist = length(halfview);\n"
+" halfview /= fdist;\n"
+"\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+"\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
+"\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" cube_coord = floor( cube_coord );\n"
+"\n"
+" if( g_debug_indices == 1 )\n"
+" {\n"
+" return rand33(cube_coord);\n"
+" }\n"
+"\n"
+" if( g_debug_complexity == 1 )\n"
+" {\n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
+" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
+" }\n"
+"\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
+" \n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.x,\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.y,\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" fog_colour += sun_colour;\n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"\n"
+"float sdLine( vec3 p, vec3 a, vec3 b )\n"
+"{\n"
+" vec3 pa = p - a;\n"
+" vec3 ba = b - a;\n"
+"\n"
+" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
+" return length( pa - ba*h );\n"
+"}\n"
+"\n"
+"float compute_board_shadow()\n"
+"{\n"
+" // player shadow\n"
+" float dist_to_player = max( 0.0, sdLine( aWorldCo, g_board_0.xyz,\n"
+" g_board_1.xyz )-0.1 );\n"
+" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
+" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
+"\n"
+" return 1.0 - player_shadow*0.8;\n"
+"}\n"
+"\n"
+"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
+"{\n"
+" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
+"}\n"
+"\n"
+"#line 7 0 \n"
+"#line 1 3 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+" // Write motion vectors\n"
+" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"\n"
+" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
+"}\n"
+"\n"
+"#line 8 0 \n"
+"\n"
+"void main()\n"
+"{\n"
+" compute_motion_vectors();\n"
+"\n"
+" vec3 vfrag = vec3(0.5,0.5,0.5);\n"
+"\n"
+" // ws modulation\n"
+" vec4 wgarbage = vec4(0.5,0.5,0.5,1.0);\n"
+" \n"
+" // Creating normal patches\n"
+" vec3 modnorm = (wgarbage.rgb-0.4) * 1.4;\n"
+" vec3 qnorm = normalize(floor(aNorm.xyz*4.0+modnorm)*0.25);\n"
+" qnorm += vec3(0.001,0.0,0.0);\n"
+"\n"
+" vec3 tangent0 = normalize(cross(qnorm,vec3(0.0,1.0,0.0)));\n"
+" vec3 tangent1 = cross(qnorm,tangent0);\n"
+" vec2 uvdiffuse = vec2( dot(tangent0,aCo), dot(tangent1,aCo) ) * 0.160;\n"
+" \n"
+" // Patch local noise\n"
+" vec4 rgarbage = texture( uTexGarbage, uvdiffuse );\n"
+"\n"
+" // Colour blending\n"
+" float fblendclip = step(0.380,aNorm.w + (rgarbage.r-0.5)*-1.740)*0.320;\n"
+" vec2 uvgradients = aUv + vec2( fblendclip, 0.0 );\n"
+"\n"
+" vfrag = texture( uTexGradients, uvgradients ).rgb;\n"
+" vfrag -= rgarbage.a*0.04;\n"
+"\n"
+" if( g_light_preview == 1 )\n"
+" {\n"
+" vfrag = vec3(0.5);\n"
+" }\n"
+"\n"
+" vfrag = scene_compute_lighting( vfrag, qnorm, aWorldCo );\n"
+" oColour = vec4(vfrag, 1.0);\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_scene_vertex_blend_uMdl;
+GLuint _uniform_scene_vertex_blend_uPv;
+GLuint _uniform_scene_vertex_blend_uPvmPrev;
+GLuint _uniform_scene_vertex_blend_uTexGarbage;
+GLuint _uniform_scene_vertex_blend_uTexGradients;
+GLuint _uniform_scene_vertex_blend_uCamera;
+GLuint _uniform_scene_vertex_blend_g_world_depth;
+GLuint _uniform_scene_vertex_blend_uLightsArray;
+GLuint _uniform_scene_vertex_blend_uLightsIndex;
+#include "shaders/scene_terrain.h"
+struct vg_shader _shader_scene_terrain = {
+ .name = "scene_terrain",
+ .vs =
+{
+.orig_file = "shaders/scene.vs",
+.static_src =
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec4 a_norm;\n"
+"layout (location=2) in vec2 a_uv;\n"
+"\n"
+"#line 1 1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+" // This magically solves some artifacting errors!\n"
+" //\n"
+" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
+"\n"
+" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line 6 0 \n"
+"\n"
+"uniform mat4x3 uMdl;\n"
+"uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
+"\n"
+"out vec2 aUv;\n"
+"out vec4 aNorm;\n"
+"out vec3 aCo;\n"
+"out vec3 aWorldCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
+" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
+" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+" vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+" gl_Position = vproj0;\n"
+"\n"
+" aUv = a_uv;\n"
+" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
+" aCo = a_co;\n"
+" aWorldCo = world_pos0;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/scene_terrain.fs",
+.static_src =
+"uniform sampler2D uTexGarbage;\n"
+"uniform sampler2D uTexGradients;\n"
+"uniform vec3 uCamera;\n"
+"uniform vec3 uSandColour;\n"
+"uniform vec2 uBlendOffset;\n"
+"\n"
+"#line 1 1 \n"
+"// :D\n"
+"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
+"\n"
+"#line 8 0 \n"
+"#line 1 2 \n"
+"// :D\n"
+"\n"
+"in vec2 aUv;\n"
+"in vec4 aNorm;\n"
+"in vec3 aCo;\n"
+"in vec3 aWorldCo;\n"
+"\n"
+"#line 1 1 \n"
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
+"layout (std140) uniform ub_world_lighting\n"
+"{\n"
+" vec4 g_cube_min;\n"
+" vec4 g_cube_inv_range;\n"
+"\n"
+" vec4 g_water_plane;\n"
+" vec4 g_depth_bounds;\n"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+" vec4 g_board_0;\n"
+" vec4 g_board_1;\n"
+"\n"
+" float g_water_fog;\n"
+" float g_time;\n"
+" float g_realtime;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
+" int g_light_preview;\n"
+" int g_shadow_samples;\n"
+"\n"
+" int g_debug_indices;\n"
+" int g_debug_complexity;\n"
+"};\n"
+"\n"
+"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\n"
+"\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
+"\n"
+"const float SUN_ANGLE = 0.0001;\n"
+"const float PI = 3.14159265358979323846264;\n"
+"\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
+"\n"
+"vec3 rand33(vec3 p3)\n"
+"{\n"
+" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
+" p3 += dot(p3, p3.yxz+33.33);\n"
+" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
+"}\n"
+"\n"
+"float stars( vec3 rd, float rr, float size ){\n"
+" vec3 co = rd * rr;\n"
+"\n"
+" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
+"\n"
+" float spaces = 1.0 / rr;\n"
+" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
+" a -= mod(a, spaces) - spaces * 0.5;\n"
+"\n"
+" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
+" \n"
+" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
+" plane = plane - mod(plane, PI / count);\n"
+"\n"
+" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
+"\n"
+" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
+" float ydist = sqrt(rr * rr - level * level);\n"
+" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
+" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
+" float star = smoothstep(size, 0.0, distance(center, co));\n"
+" return star;\n"
+"}\n"
+"\n"
+"float luminance( vec3 v )\n"
+"{\n"
+" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
+"}\n"
+"\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
+"{\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
+" float sky_gradient = dir.y;\n"
+" \n"
+" /* Blend phase colours */\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
+" \n"
+" /* Add gradient */\n"
+" ambient -= sky_gradient * luminance(ambient);\n"
+" \n"
+" return ambient;\n"
+"}\n"
+"\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
+"{\n"
+" ray_dir.y = abs( ray_dir.y );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
+" \n"
+" /* Sun */\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
+" float sun_shape = pow( sun_size, 2000.0 );\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" \n"
+" float star = 0.0;\n"
+" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
+"\n"
+" if( star_blend > 0.001 ){\n"
+" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
+" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
+" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
+" }\n"
+" }\n"
+" \n"
+" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
+" return composite;\n"
+"}\n"
+"\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
+"{\n"
+" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
+"\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
+" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
+" ) * g_sun_colour.rgb * g_day_phase;\n"
+"\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
+"\n"
+"#line 44 0 \n"
+"\n"
+"float world_depth_sample( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" return texture( g_world_depth, depth_coord ).r;\n"
+"}\n"
+"\n"
+"float world_water_depth( vec3 pos )\n"
+"{\n"
+" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
+"}\n"
+"\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
+"\n"
+" float fdelta = height_sample - co.y;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
+"}\n"
+"\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
+" return 1.0;\n"
+" }\n"
+"\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\n"
+"\n"
+" float famt = 0.0;\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+"\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+"\n"
+" return 1.0 - famt;\n"
+"}\n"
+"\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
+"{\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
+"}\n"
+"\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_light( int light_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
+" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
+" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
+"\n"
+" vec3 light_delta = light_co.xyz-co;\n"
+" float dist2 = dot(light_delta,light_delta);\n"
+"\n"
+" light_delta = normalize( light_delta );\n"
+"\n"
+" float quadratic = dist2*100.0;\n"
+" float attenuation = 1.0/( 1.0 + quadratic );\n"
+" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
+"\n"
+" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
+"\n"
+" if( light_dir.w < 0.999999 ){\n"
+" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
+" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
+" }\n"
+"\n"
+" return light_colour.rgb * attenuation * falloff \n"
+" * step( g_day_phase, light_colour.w );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" uint light_count = packed_index & 0x3u;\n"
+"\n"
+" vec3 l = vec3(0.0);\n"
+"\n"
+" if( light_count >= 1u ){\n"
+" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
+" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
+" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
+"\n"
+" l += scene_calculate_light( index_0, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 2u ){\n"
+" l += scene_calculate_light( index_1, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 3u ){\n"
+" l += scene_calculate_light( index_2, halfview, co, normal );\n"
+" }\n"
+" }\n"
+" }\n"
+"\n"
+" return l;\n"
+"}\n"
+"\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
+"{\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
+"\n"
+" // Lighting\n"
+" vec3 halfview = uCamera - co;\n"
+" float fdist = length(halfview);\n"
+" halfview /= fdist;\n"
+"\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+"\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
+"\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" cube_coord = floor( cube_coord );\n"
+"\n"
+" if( g_debug_indices == 1 )\n"
+" {\n"
+" return rand33(cube_coord);\n"
+" }\n"
+"\n"
+" if( g_debug_complexity == 1 )\n"
+" {\n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
+" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
+" }\n"
+"\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
+" \n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.x,\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.y,\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" fog_colour += sun_colour;\n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"\n"
+"float sdLine( vec3 p, vec3 a, vec3 b )\n"
+"{\n"
+" vec3 pa = p - a;\n"
+" vec3 ba = b - a;\n"
+"\n"
+" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
+" return length( pa - ba*h );\n"
+"}\n"
+"\n"
+"float compute_board_shadow()\n"
+"{\n"
+" // player shadow\n"
+" float dist_to_player = max( 0.0, sdLine( aWorldCo, g_board_0.xyz,\n"
+" g_board_1.xyz )-0.1 );\n"
+" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
+" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
+"\n"
+" return 1.0 - player_shadow*0.8;\n"
+"}\n"
+"\n"
+"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
+"{\n"
+" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"#line 1 3 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+" // Write motion vectors\n"
+" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"\n"
+" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
+"}\n"
+"\n"
+"#line 10 0 \n"
+"\n"
+"void main()\n"
+"{\n"
+" compute_motion_vectors();\n"
+"\n"
+" // Colour\n"
+" // ------\n"
+" vec3 vfrag = vec3(0.5,0.5,0.5);\n"
+"\n"
+" // ws modulation\n"
+" vec4 wgarbage = texture( uTexGarbage, aCo.xz * 0.015 );\n"
+" \n"
+" // Creating normal patches\n"
+" vec3 modnorm = (wgarbage.rgb-0.4) * 1.4;\n"
+" vec3 qnorm = normalize(floor(aNorm.xyz*4.0+modnorm)*0.25);\n"
+" qnorm += vec3(0.001,0.0,0.0);\n"
+"\n"
+" vec2 dir = normalize(qnorm.xz);\n"
+" vec2 uvdiffuse = aCo.xz * 0.02;\n"
+" uvdiffuse = mat2(dir.y, dir.x, -dir.x, dir.y) * uvdiffuse;\n"
+" \n"
+" // Patch local noise\n"
+" vec4 rgarbage = texture( uTexGarbage, uvdiffuse );\n"
+"\n"
+" // Colour blending\n"
+" float amtgrass = step(qnorm.y,0.6);\n"
+" float amtsand = min(max((aCo.y - 10.0) * -0.1,0.0)*qnorm.y,1.0);\n"
+" vec2 uvgradients = aUv + vec2( amtgrass + rgarbage.a*0.8 )*uBlendOffset;\n"
+" vfrag = texture( uTexGradients, uvgradients ).rgb;\n"
+" vfrag = mix( vfrag, uSandColour, amtsand );\n"
+"\n"
+" qnorm = mix( qnorm, aNorm.xyz, amtsand );\n"
+" \n"
+" if( g_light_preview == 1 )\n"
+" {\n"
+" vfrag = vec3(0.5);\n"
+" }\n"
+"\n"
+" vfrag = scene_compute_lighting( vfrag, qnorm, aWorldCo );\n"
+" oColour = vec4(vfrag, 1.0);\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_scene_terrain_uMdl;
+GLuint _uniform_scene_terrain_uPv;
+GLuint _uniform_scene_terrain_uPvmPrev;
+GLuint _uniform_scene_terrain_uTexGarbage;
+GLuint _uniform_scene_terrain_uTexGradients;
+GLuint _uniform_scene_terrain_uCamera;
+GLuint _uniform_scene_terrain_uSandColour;
+GLuint _uniform_scene_terrain_uBlendOffset;
+GLuint _uniform_scene_terrain_g_world_depth;
+GLuint _uniform_scene_terrain_uLightsArray;
+GLuint _uniform_scene_terrain_uLightsIndex;
+#include "shaders/scene_route.h"
+struct vg_shader _shader_scene_route = {
+ .name = "scene_route",
+ .vs =
+{
+.orig_file = "shaders/scene_override.vs",
+.static_src =
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec4 a_norm;\n"
+"layout (location=2) in vec2 a_uv;\n"
+"\n"
+"#line 1 1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+" // This magically solves some artifacting errors!\n"
+" //\n"
+" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
+"\n"
+" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line 6 0 \n"
+"\n"
+"uniform mat4x3 uMdl;\n"
+"uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
+"uniform mat3 uNormalMtx;\n"
+"\n"
+"out vec2 aUv;\n"
+"out vec4 aNorm;\n"
+"out vec3 aCo;\n"
+"out vec3 aWorldCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
+" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
+" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+" vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+" gl_Position = vproj0;\n"
+"\n"
+" aUv = a_uv;\n"
+" aNorm = vec4( uNormalMtx * a_norm.xyz, a_norm.w );\n"
+" aCo = a_co;\n"
+" aWorldCo = world_pos0;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/scene_route.fs",
+.static_src =
+"uniform sampler2D uTexGarbage;\n"
+"uniform sampler2D uTexGradients;\n"
+"uniform vec3 uCamera;\n"
+"uniform vec4 uColour;\n"
+"\n"
+"#line 1 1 \n"
+"// :D\n"
+"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
+"\n"
+"#line 7 0 \n"
+"#line 1 2 \n"
+"// :D\n"
+"\n"
+"in vec2 aUv;\n"
+"in vec4 aNorm;\n"
+"in vec3 aCo;\n"
+"in vec3 aWorldCo;\n"
+"\n"
+"#line 1 1 \n"
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
+"layout (std140) uniform ub_world_lighting\n"
+"{\n"
+" vec4 g_cube_min;\n"
+" vec4 g_cube_inv_range;\n"
+"\n"
+" vec4 g_water_plane;\n"
+" vec4 g_depth_bounds;\n"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+" vec4 g_board_0;\n"
+" vec4 g_board_1;\n"
+"\n"
+" float g_water_fog;\n"
+" float g_time;\n"
+" float g_realtime;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
+" int g_light_preview;\n"
+" int g_shadow_samples;\n"
+"\n"
+" int g_debug_indices;\n"
+" int g_debug_complexity;\n"
+"};\n"
+"\n"
+"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\n"
+"\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
+"\n"
+"const float SUN_ANGLE = 0.0001;\n"
+"const float PI = 3.14159265358979323846264;\n"
+"\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
+"\n"
+"vec3 rand33(vec3 p3)\n"
+"{\n"
+" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
+" p3 += dot(p3, p3.yxz+33.33);\n"
+" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
+"}\n"
+"\n"
+"float stars( vec3 rd, float rr, float size ){\n"
+" vec3 co = rd * rr;\n"
+"\n"
+" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
+"\n"
+" float spaces = 1.0 / rr;\n"
+" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
+" a -= mod(a, spaces) - spaces * 0.5;\n"
+"\n"
+" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
+" \n"
+" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
+" plane = plane - mod(plane, PI / count);\n"
+"\n"
+" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
+"\n"
+" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
+" float ydist = sqrt(rr * rr - level * level);\n"
+" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
+" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
+" float star = smoothstep(size, 0.0, distance(center, co));\n"
+" return star;\n"
+"}\n"
+"\n"
+"float luminance( vec3 v )\n"
+"{\n"
+" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
+"}\n"
+"\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
+"{\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
+" float sky_gradient = dir.y;\n"
+" \n"
+" /* Blend phase colours */\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
+" \n"
+" /* Add gradient */\n"
+" ambient -= sky_gradient * luminance(ambient);\n"
+" \n"
+" return ambient;\n"
+"}\n"
+"\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
+"{\n"
+" ray_dir.y = abs( ray_dir.y );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
+" \n"
+" /* Sun */\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
+" float sun_shape = pow( sun_size, 2000.0 );\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" \n"
+" float star = 0.0;\n"
+" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
+"\n"
+" if( star_blend > 0.001 ){\n"
+" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
+" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
+" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
+" }\n"
+" }\n"
+" \n"
+" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
+" return composite;\n"
+"}\n"
+"\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
+"{\n"
+" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
+"\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
+" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
+" ) * g_sun_colour.rgb * g_day_phase;\n"
+"\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
+"\n"
+"#line 44 0 \n"
+"\n"
+"float world_depth_sample( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" return texture( g_world_depth, depth_coord ).r;\n"
+"}\n"
+"\n"
+"float world_water_depth( vec3 pos )\n"
+"{\n"
+" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
+"}\n"
+"\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
+"\n"
+" float fdelta = height_sample - co.y;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
+"}\n"
+"\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
+" return 1.0;\n"
+" }\n"
+"\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\n"
+"\n"
+" float famt = 0.0;\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+"\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+"\n"
+" return 1.0 - famt;\n"
+"}\n"
+"\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
+"{\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
+"}\n"
+"\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_light( int light_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
+" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
+" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
+"\n"
+" vec3 light_delta = light_co.xyz-co;\n"
+" float dist2 = dot(light_delta,light_delta);\n"
+"\n"
+" light_delta = normalize( light_delta );\n"
+"\n"
+" float quadratic = dist2*100.0;\n"
+" float attenuation = 1.0/( 1.0 + quadratic );\n"
+" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
+"\n"
+" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
+"\n"
+" if( light_dir.w < 0.999999 ){\n"
+" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
+" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
+" }\n"
+"\n"
+" return light_colour.rgb * attenuation * falloff \n"
+" * step( g_day_phase, light_colour.w );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" uint light_count = packed_index & 0x3u;\n"
+"\n"
+" vec3 l = vec3(0.0);\n"
+"\n"
+" if( light_count >= 1u ){\n"
+" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
+" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
+" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
+"\n"
+" l += scene_calculate_light( index_0, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 2u ){\n"
+" l += scene_calculate_light( index_1, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 3u ){\n"
+" l += scene_calculate_light( index_2, halfview, co, normal );\n"
+" }\n"
+" }\n"
+" }\n"
+"\n"
+" return l;\n"
+"}\n"
+"\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
+"{\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
+"\n"
+" // Lighting\n"
+" vec3 halfview = uCamera - co;\n"
+" float fdist = length(halfview);\n"
+" halfview /= fdist;\n"
+"\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+"\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
+"\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" cube_coord = floor( cube_coord );\n"
+"\n"
+" if( g_debug_indices == 1 )\n"
+" {\n"
+" return rand33(cube_coord);\n"
+" }\n"
+"\n"
+" if( g_debug_complexity == 1 )\n"
+" {\n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
+" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
+" }\n"
+"\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
+" \n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.x,\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.y,\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" fog_colour += sun_colour;\n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"\n"
+"float sdLine( vec3 p, vec3 a, vec3 b )\n"
+"{\n"
+" vec3 pa = p - a;\n"
+" vec3 ba = b - a;\n"
+"\n"
+" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
+" return length( pa - ba*h );\n"
+"}\n"
+"\n"
+"float compute_board_shadow()\n"
+"{\n"
+" // player shadow\n"
+" float dist_to_player = max( 0.0, sdLine( aWorldCo, g_board_0.xyz,\n"
+" g_board_1.xyz )-0.1 );\n"
+" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
+" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
+"\n"
+" return 1.0 - player_shadow*0.8;\n"
+"}\n"
+"\n"
+"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
+"{\n"
+" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
+"}\n"
+"\n"
+"#line 8 0 \n"
+"#line 1 3 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+" // Write motion vectors\n"
+" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"\n"
+" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"\n"
+"float filtered_stripe( in float p, in float ddx, in float ddy )\n"
+"{\n"
+" float w = max(abs(ddx), abs(ddy)) + 0.02;\n"
+" float i = (abs(fract((p-0.5*w)/2.0)-0.5)-abs(fract((p+0.5*w)/2.0)-0.5))/w;\n"
+" return 0.5 - i;\n"
+"}\n"
+"\n"
+"void main()\n"
+"{\n"
+" compute_motion_vectors();\n"
+"\n"
+" vec3 vfrag = vec3(0.5,0.5,0.5);\n"
+"\n"
+" // ws modulation\n"
+" vec4 wgarbage = texture( uTexGarbage, aCo.xz * 0.015 );\n"
+"\n"
+" // Creating normal patches\n"
+" vec3 modnorm = (wgarbage.rgb-0.4) * 1.4;\n"
+" vec3 qnorm = normalize(floor(aNorm.xyz*4.0+modnorm)*0.25);\n"
+" qnorm += vec3(0.001,0.0,0.0);\n"
+"\n"
+" vec3 tangent0 = normalize(cross(qnorm,vec3(0.0,1.0,0.0)));\n"
+" vec3 tangent1 = cross(qnorm,tangent0);\n"
+" vec2 uvdiffuse = vec2( dot(tangent0,aCo), dot(tangent1,aCo) ) * 0.035;\n"
+" \n"
+" // Patch local noise\n"
+" vec4 rgarbage = texture( uTexGarbage, uvdiffuse );\n"
+"\n"
+" vfrag = pow(uColour.rgb,vec3(1.0/2.2));\n"
+" vfrag -= rgarbage.a*0.1;\n"
+"\n"
+" if( wgarbage.g < 0.1 )\n"
+" discard;\n"
+"\n"
+" float movep = (aUv.x + abs(aUv.y-0.5)*0.4 - g_realtime)*2.0;\n"
+" float stripe = filtered_stripe( movep, dFdx(movep), dFdy(movep) );\n"
+" vfrag *= 0.9+stripe*uColour.a; \n"
+"\n"
+" if( g_light_preview == 1 )\n"
+" {\n"
+" vfrag = vec3(0.5);\n"
+" }\n"
+"\n"
+" // Lighting\n"
+" oColour = vec4( scene_compute_lighting( vfrag, qnorm, aWorldCo ), 1.0 );\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_scene_route_uMdl;
+GLuint _uniform_scene_route_uPv;
+GLuint _uniform_scene_route_uPvmPrev;
+GLuint _uniform_scene_route_uNormalMtx;
+GLuint _uniform_scene_route_uTexGarbage;
+GLuint _uniform_scene_route_uTexGradients;
+GLuint _uniform_scene_route_uCamera;
+GLuint _uniform_scene_route_uColour;
+GLuint _uniform_scene_route_g_world_depth;
+GLuint _uniform_scene_route_uLightsArray;
+GLuint _uniform_scene_route_uLightsIndex;
+#include "shaders/scene_depth.h"
+struct vg_shader _shader_scene_depth = {
+ .name = "scene_depth",
+ .vs =
+{
+.orig_file = "shaders/scene.vs",
+.static_src =
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec4 a_norm;\n"
+"layout (location=2) in vec2 a_uv;\n"
+"\n"
+"#line 1 1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+" // This magically solves some artifacting errors!\n"
+" //\n"
+" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
+"\n"
+" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line 6 0 \n"
+"\n"
+"uniform mat4x3 uMdl;\n"
+"uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
+"\n"
+"out vec2 aUv;\n"
+"out vec4 aNorm;\n"
+"out vec3 aCo;\n"
+"out vec3 aWorldCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
+" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
+" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+" vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+" gl_Position = vproj0;\n"
+"\n"
+" aUv = a_uv;\n"
+" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
+" aCo = a_co;\n"
+" aWorldCo = world_pos0;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/scene_depth.fs",
+.static_src =
+"out vec4 FragColor;\n"
+"\n"
+"uniform vec3 uCamera;\n"
+"uniform vec3 uBoard0;\n"
+"uniform vec3 uBoard1;\n"
+"\n"
+"#line 1 1 \n"
+"// :D\n"
+"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
+"\n"
+"#line 8 0 \n"
+"#line 1 2 \n"
+"// :D\n"
+"\n"
+"in vec2 aUv;\n"
+"in vec4 aNorm;\n"
+"in vec3 aCo;\n"
+"in vec3 aWorldCo;\n"
+"\n"
+"#line 1 1 \n"
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
+"layout (std140) uniform ub_world_lighting\n"
+"{\n"
+" vec4 g_cube_min;\n"
+" vec4 g_cube_inv_range;\n"
+"\n"
+" vec4 g_water_plane;\n"
+" vec4 g_depth_bounds;\n"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+" vec4 g_board_0;\n"
+" vec4 g_board_1;\n"
+"\n"
+" float g_water_fog;\n"
+" float g_time;\n"
+" float g_realtime;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
+" int g_light_preview;\n"
+" int g_shadow_samples;\n"
+"\n"
+" int g_debug_indices;\n"
+" int g_debug_complexity;\n"
+"};\n"
+"\n"
+"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\n"
+"\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
+"\n"
+"const float SUN_ANGLE = 0.0001;\n"
+"const float PI = 3.14159265358979323846264;\n"
+"\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
+"\n"
+"vec3 rand33(vec3 p3)\n"
+"{\n"
+" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
+" p3 += dot(p3, p3.yxz+33.33);\n"
+" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
+"}\n"
+"\n"
+"float stars( vec3 rd, float rr, float size ){\n"
+" vec3 co = rd * rr;\n"
+"\n"
+" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
+"\n"
+" float spaces = 1.0 / rr;\n"
+" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
+" a -= mod(a, spaces) - spaces * 0.5;\n"
+"\n"
+" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
+" \n"
+" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
+" plane = plane - mod(plane, PI / count);\n"
+"\n"
+" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
+"\n"
+" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
+" float ydist = sqrt(rr * rr - level * level);\n"
+" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
+" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
+" float star = smoothstep(size, 0.0, distance(center, co));\n"
+" return star;\n"
+"}\n"
+"\n"
+"float luminance( vec3 v )\n"
+"{\n"
+" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
+"}\n"
+"\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
+"{\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
+" float sky_gradient = dir.y;\n"
+" \n"
+" /* Blend phase colours */\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
+" \n"
+" /* Add gradient */\n"
+" ambient -= sky_gradient * luminance(ambient);\n"
+" \n"
+" return ambient;\n"
+"}\n"
+"\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
+"{\n"
+" ray_dir.y = abs( ray_dir.y );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
+" \n"
+" /* Sun */\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
+" float sun_shape = pow( sun_size, 2000.0 );\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" \n"
+" float star = 0.0;\n"
+" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
+"\n"
+" if( star_blend > 0.001 ){\n"
+" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
+" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
+" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
+" }\n"
+" }\n"
+" \n"
+" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
+" return composite;\n"
+"}\n"
+"\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
+"{\n"
+" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
+"\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
+" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
+" ) * g_sun_colour.rgb * g_day_phase;\n"
+"\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
+"\n"
+"#line 44 0 \n"
+"\n"
+"float world_depth_sample( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" return texture( g_world_depth, depth_coord ).r;\n"
+"}\n"
+"\n"
+"float world_water_depth( vec3 pos )\n"
+"{\n"
+" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
+"}\n"
+"\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
+"\n"
+" float fdelta = height_sample - co.y;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
+"}\n"
+"\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
+" return 1.0;\n"
+" }\n"
+"\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\n"
+"\n"
+" float famt = 0.0;\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+"\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+"\n"
+" return 1.0 - famt;\n"
+"}\n"
+"\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
+"{\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
+"}\n"
+"\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_light( int light_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
+" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
+" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
+"\n"
+" vec3 light_delta = light_co.xyz-co;\n"
+" float dist2 = dot(light_delta,light_delta);\n"
+"\n"
+" light_delta = normalize( light_delta );\n"
+"\n"
+" float quadratic = dist2*100.0;\n"
+" float attenuation = 1.0/( 1.0 + quadratic );\n"
+" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
+"\n"
+" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
+"\n"
+" if( light_dir.w < 0.999999 ){\n"
+" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
+" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
+" }\n"
+"\n"
+" return light_colour.rgb * attenuation * falloff \n"
+" * step( g_day_phase, light_colour.w );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" uint light_count = packed_index & 0x3u;\n"
+"\n"
+" vec3 l = vec3(0.0);\n"
+"\n"
+" if( light_count >= 1u ){\n"
+" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
+" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
+" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
+"\n"
+" l += scene_calculate_light( index_0, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 2u ){\n"
+" l += scene_calculate_light( index_1, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 3u ){\n"
+" l += scene_calculate_light( index_2, halfview, co, normal );\n"
+" }\n"
+" }\n"
+" }\n"
+"\n"
+" return l;\n"
+"}\n"
+"\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
+"{\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
+"\n"
+" // Lighting\n"
+" vec3 halfview = uCamera - co;\n"
+" float fdist = length(halfview);\n"
+" halfview /= fdist;\n"
+"\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+"\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
+"\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" cube_coord = floor( cube_coord );\n"
+"\n"
+" if( g_debug_indices == 1 )\n"
+" {\n"
+" return rand33(cube_coord);\n"
+" }\n"
+"\n"
+" if( g_debug_complexity == 1 )\n"
+" {\n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
+" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
+" }\n"
+"\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
+" \n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.x,\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.y,\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" fog_colour += sun_colour;\n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"\n"
+"float sdLine( vec3 p, vec3 a, vec3 b )\n"
+"{\n"
+" vec3 pa = p - a;\n"
+" vec3 ba = b - a;\n"
+"\n"
+" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
+" return length( pa - ba*h );\n"
+"}\n"
+"\n"
+"float compute_board_shadow()\n"
+"{\n"
+" // player shadow\n"
+" float dist_to_player = max( 0.0, sdLine( aWorldCo, g_board_0.xyz,\n"
+" g_board_1.xyz )-0.1 );\n"
+" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
+" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
+"\n"
+" return 1.0 - player_shadow*0.8;\n"
+"}\n"
+"\n"
+"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
+"{\n"
+" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"\n"
+"// Water blending\n"
+"// ==============\n"
+"\n"
+"float water_depth( vec3 pos, vec3 halfview )\n"
+"{\n"
+" vec3 pnorm = g_water_plane.xyz;\n"
+" float pdist = g_water_plane.w;\n"
+"\n"
+" float d = dot( pnorm, halfview );\n"
+" float t = dot((pnorm*pdist - pos), pnorm) / d;\n"
+" return t * g_water_fog;\n"
+"}\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec3 halfview = normalize( uCamera - aWorldCo );\n"
+" float depth = water_depth( aWorldCo, halfview );\n"
+" FragColor = vec4( depth, 0.0, 0.0, 0.0 );\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_scene_depth_uMdl;
+GLuint _uniform_scene_depth_uPv;
+GLuint _uniform_scene_depth_uPvmPrev;
+GLuint _uniform_scene_depth_uCamera;
+GLuint _uniform_scene_depth_uBoard0;
+GLuint _uniform_scene_depth_uBoard1;
+GLuint _uniform_scene_depth_g_world_depth;
+GLuint _uniform_scene_depth_uLightsArray;
+GLuint _uniform_scene_depth_uLightsIndex;
+#include "shaders/scene_position.h"
+struct vg_shader _shader_scene_position = {
+ .name = "scene_position",
+ .vs =
+{
+.orig_file = "shaders/scene.vs",
+.static_src =
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec4 a_norm;\n"
+"layout (location=2) in vec2 a_uv;\n"
+"\n"
+"#line 1 1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+" // This magically solves some artifacting errors!\n"
+" //\n"
+" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
+"\n"
+" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line 6 0 \n"
+"\n"
+"uniform mat4x3 uMdl;\n"
+"uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
+"\n"
+"out vec2 aUv;\n"
+"out vec4 aNorm;\n"
+"out vec3 aCo;\n"
+"out vec3 aWorldCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
+" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
+" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+" vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+" gl_Position = vproj0;\n"
+"\n"
+" aUv = a_uv;\n"
+" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
+" aCo = a_co;\n"
+" aWorldCo = world_pos0;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/scene_position.fs",
+.static_src =
+"out vec4 FragColor;\n"
+"\n"
+"uniform vec3 uCamera;\n"
+"uniform vec3 uBoard0;\n"
+"uniform vec3 uBoard1;\n"
+"\n"
+"#line 1 1 \n"
+"// :D\n"
+"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
+"\n"
+"#line 8 0 \n"
+"#line 1 2 \n"
+"// :D\n"
+"\n"
+"in vec2 aUv;\n"
+"in vec4 aNorm;\n"
+"in vec3 aCo;\n"
+"in vec3 aWorldCo;\n"
+"\n"
+"#line 1 1 \n"
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
+"layout (std140) uniform ub_world_lighting\n"
+"{\n"
+" vec4 g_cube_min;\n"
+" vec4 g_cube_inv_range;\n"
+"\n"
+" vec4 g_water_plane;\n"
+" vec4 g_depth_bounds;\n"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+" vec4 g_board_0;\n"
+" vec4 g_board_1;\n"
+"\n"
+" float g_water_fog;\n"
+" float g_time;\n"
+" float g_realtime;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
+" int g_light_preview;\n"
+" int g_shadow_samples;\n"
+"\n"
+" int g_debug_indices;\n"
+" int g_debug_complexity;\n"
+"};\n"
+"\n"
+"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\n"
+"\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
+"\n"
+"const float SUN_ANGLE = 0.0001;\n"
+"const float PI = 3.14159265358979323846264;\n"
+"\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
+"\n"
+"vec3 rand33(vec3 p3)\n"
+"{\n"
+" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
+" p3 += dot(p3, p3.yxz+33.33);\n"
+" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
+"}\n"
+"\n"
+"float stars( vec3 rd, float rr, float size ){\n"
+" vec3 co = rd * rr;\n"
+"\n"
+" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
+"\n"
+" float spaces = 1.0 / rr;\n"
+" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
+" a -= mod(a, spaces) - spaces * 0.5;\n"
+"\n"
+" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
+" \n"
+" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
+" plane = plane - mod(plane, PI / count);\n"
+"\n"
+" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
+"\n"
+" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
+" float ydist = sqrt(rr * rr - level * level);\n"
+" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
+" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
+" float star = smoothstep(size, 0.0, distance(center, co));\n"
+" return star;\n"
+"}\n"
+"\n"
+"float luminance( vec3 v )\n"
+"{\n"
+" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
+"}\n"
+"\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
+"{\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
+" float sky_gradient = dir.y;\n"
+" \n"
+" /* Blend phase colours */\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
+" \n"
+" /* Add gradient */\n"
+" ambient -= sky_gradient * luminance(ambient);\n"
+" \n"
+" return ambient;\n"
+"}\n"
+"\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
+"{\n"
+" ray_dir.y = abs( ray_dir.y );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
+" \n"
+" /* Sun */\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
+" float sun_shape = pow( sun_size, 2000.0 );\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" \n"
+" float star = 0.0;\n"
+" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
+"\n"
+" if( star_blend > 0.001 ){\n"
+" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
+" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
+" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
+" }\n"
+" }\n"
+" \n"
+" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
+" return composite;\n"
+"}\n"
+"\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
+"{\n"
+" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
+"\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
+" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
+" ) * g_sun_colour.rgb * g_day_phase;\n"
+"\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
+"\n"
+"#line 44 0 \n"
+"\n"
+"float world_depth_sample( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" return texture( g_world_depth, depth_coord ).r;\n"
+"}\n"
+"\n"
+"float world_water_depth( vec3 pos )\n"
+"{\n"
+" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
+"}\n"
+"\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
+"\n"
+" float fdelta = height_sample - co.y;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
+"}\n"
+"\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
+" return 1.0;\n"
+" }\n"
+"\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\n"
+"\n"
+" float famt = 0.0;\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+"\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+"\n"
+" return 1.0 - famt;\n"
+"}\n"
+"\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
+"{\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
+"}\n"
+"\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_light( int light_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
+" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
+" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
+"\n"
+" vec3 light_delta = light_co.xyz-co;\n"
+" float dist2 = dot(light_delta,light_delta);\n"
+"\n"
+" light_delta = normalize( light_delta );\n"
+"\n"
+" float quadratic = dist2*100.0;\n"
+" float attenuation = 1.0/( 1.0 + quadratic );\n"
+" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
+"\n"
+" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
+"\n"
+" if( light_dir.w < 0.999999 ){\n"
+" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
+" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
+" }\n"
+"\n"
+" return light_colour.rgb * attenuation * falloff \n"
+" * step( g_day_phase, light_colour.w );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" uint light_count = packed_index & 0x3u;\n"
+"\n"
+" vec3 l = vec3(0.0);\n"
+"\n"
+" if( light_count >= 1u ){\n"
+" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
+" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
+" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
+"\n"
+" l += scene_calculate_light( index_0, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 2u ){\n"
+" l += scene_calculate_light( index_1, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 3u ){\n"
+" l += scene_calculate_light( index_2, halfview, co, normal );\n"
+" }\n"
+" }\n"
+" }\n"
+"\n"
+" return l;\n"
+"}\n"
+"\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
+"{\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
+"\n"
+" // Lighting\n"
+" vec3 halfview = uCamera - co;\n"
+" float fdist = length(halfview);\n"
+" halfview /= fdist;\n"
+"\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+"\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
+"\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" cube_coord = floor( cube_coord );\n"
+"\n"
+" if( g_debug_indices == 1 )\n"
+" {\n"
+" return rand33(cube_coord);\n"
+" }\n"
+"\n"
+" if( g_debug_complexity == 1 )\n"
+" {\n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
+" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
+" }\n"
+"\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
+" \n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.x,\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.y,\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" fog_colour += sun_colour;\n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"\n"
+"float sdLine( vec3 p, vec3 a, vec3 b )\n"
+"{\n"
+" vec3 pa = p - a;\n"
+" vec3 ba = b - a;\n"
+"\n"
+" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
+" return length( pa - ba*h );\n"
+"}\n"
+"\n"
+"float compute_board_shadow()\n"
+"{\n"
+" // player shadow\n"
+" float dist_to_player = max( 0.0, sdLine( aWorldCo, g_board_0.xyz,\n"
+" g_board_1.xyz )-0.1 );\n"
+" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
+" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
+"\n"
+" return 1.0 - player_shadow*0.8;\n"
+"}\n"
+"\n"
+"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
+"{\n"
+" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"\n"
+"void main()\n"
+"{\n"
+" float height_full = aWorldCo.y;\n"
+" float height_water = height_full;\n"
+"\n"
+" if( height_water > (g_water_plane.y * g_water_plane.w) + 2.0 )\n"
+" height_water = -99999.9;\n"
+"\n"
+" FragColor = vec4( height_full, height_water, 0.0, 0.0 );\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_scene_position_uMdl;
+GLuint _uniform_scene_position_uPv;
+GLuint _uniform_scene_position_uPvmPrev;
+GLuint _uniform_scene_position_uCamera;
+GLuint _uniform_scene_position_uBoard0;
+GLuint _uniform_scene_position_uBoard1;
+GLuint _uniform_scene_position_g_world_depth;
+GLuint _uniform_scene_position_uLightsArray;
+GLuint _uniform_scene_position_uLightsIndex;
+#include "shaders/scene_cubemapped.h"
+struct vg_shader _shader_scene_cubemapped = {
+ .name = "scene_cubemapped",
+ .vs =
+{
+.orig_file = "shaders/scene.vs",
+.static_src =
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec4 a_norm;\n"
+"layout (location=2) in vec2 a_uv;\n"
+"\n"
+"#line 1 1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+" // This magically solves some artifacting errors!\n"
+" //\n"
+" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
+"\n"
+" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line 6 0 \n"
+"\n"
+"uniform mat4x3 uMdl;\n"
+"uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
+"\n"
+"out vec2 aUv;\n"
+"out vec4 aNorm;\n"
+"out vec3 aCo;\n"
+"out vec3 aWorldCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
+" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
+" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+" vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+" gl_Position = vproj0;\n"
+"\n"
+" aUv = a_uv;\n"
+" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
+" aCo = a_co;\n"
+" aWorldCo = world_pos0;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/scene_cubemapped.fs",
+.static_src =
+"uniform sampler2D uTexGarbage;\n"
+"uniform sampler2D uTexMain;\n"
+"uniform samplerCube uTexCubemap;\n"
+"uniform vec3 uCamera;\n"
+"uniform vec4 uPlane;\n"
+"uniform vec4 uColour;\n"
+"\n"
+"#line 1 1 \n"
+"// :D\n"
+"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
+"\n"
+"#line 9 0 \n"
+"#line 1 2 \n"
+"// :D\n"
+"\n"
+"in vec2 aUv;\n"
+"in vec4 aNorm;\n"
+"in vec3 aCo;\n"
+"in vec3 aWorldCo;\n"
+"\n"
+"#line 1 1 \n"
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
+"layout (std140) uniform ub_world_lighting\n"
+"{\n"
+" vec4 g_cube_min;\n"
+" vec4 g_cube_inv_range;\n"
+"\n"
+" vec4 g_water_plane;\n"
+" vec4 g_depth_bounds;\n"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+" vec4 g_board_0;\n"
+" vec4 g_board_1;\n"
+"\n"
+" float g_water_fog;\n"
+" float g_time;\n"
+" float g_realtime;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
+" int g_light_preview;\n"
+" int g_shadow_samples;\n"
+"\n"
+" int g_debug_indices;\n"
+" int g_debug_complexity;\n"
+"};\n"
+"\n"
+"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\n"
+"\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
+"\n"
+"const float SUN_ANGLE = 0.0001;\n"
+"const float PI = 3.14159265358979323846264;\n"
+"\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
+"\n"
+"vec3 rand33(vec3 p3)\n"
+"{\n"
+" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
+" p3 += dot(p3, p3.yxz+33.33);\n"
+" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
+"}\n"
+"\n"
+"float stars( vec3 rd, float rr, float size ){\n"
+" vec3 co = rd * rr;\n"
+"\n"
+" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
+"\n"
+" float spaces = 1.0 / rr;\n"
+" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
+" a -= mod(a, spaces) - spaces * 0.5;\n"
+"\n"
+" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
+" \n"
+" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
+" plane = plane - mod(plane, PI / count);\n"
+"\n"
+" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
+"\n"
+" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
+" float ydist = sqrt(rr * rr - level * level);\n"
+" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
+" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
+" float star = smoothstep(size, 0.0, distance(center, co));\n"
+" return star;\n"
+"}\n"
+"\n"
+"float luminance( vec3 v )\n"
+"{\n"
+" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
+"}\n"
+"\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
+"{\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
+" float sky_gradient = dir.y;\n"
+" \n"
+" /* Blend phase colours */\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
+" \n"
+" /* Add gradient */\n"
+" ambient -= sky_gradient * luminance(ambient);\n"
+" \n"
+" return ambient;\n"
+"}\n"
+"\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
+"{\n"
+" ray_dir.y = abs( ray_dir.y );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
+" \n"
+" /* Sun */\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
+" float sun_shape = pow( sun_size, 2000.0 );\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" \n"
+" float star = 0.0;\n"
+" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
+"\n"
+" if( star_blend > 0.001 ){\n"
+" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
+" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
+" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
+" }\n"
+" }\n"
+" \n"
+" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
+" return composite;\n"
+"}\n"
+"\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
+"{\n"
+" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
+"\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
+" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
+" ) * g_sun_colour.rgb * g_day_phase;\n"
+"\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
+"\n"
+"#line 44 0 \n"
+"\n"
+"float world_depth_sample( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" return texture( g_world_depth, depth_coord ).r;\n"
+"}\n"
+"\n"
+"float world_water_depth( vec3 pos )\n"
+"{\n"
+" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
+"}\n"
+"\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
+"\n"
+" float fdelta = height_sample - co.y;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
+"}\n"
+"\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
+" return 1.0;\n"
+" }\n"
+"\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\n"
+"\n"
+" float famt = 0.0;\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+"\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+"\n"
+" return 1.0 - famt;\n"
+"}\n"
+"\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
+"{\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
+"}\n"
+"\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_light( int light_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
+" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
+" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
+"\n"
+" vec3 light_delta = light_co.xyz-co;\n"
+" float dist2 = dot(light_delta,light_delta);\n"
+"\n"
+" light_delta = normalize( light_delta );\n"
+"\n"
+" float quadratic = dist2*100.0;\n"
+" float attenuation = 1.0/( 1.0 + quadratic );\n"
+" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
+"\n"
+" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
+"\n"
+" if( light_dir.w < 0.999999 ){\n"
+" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
+" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
+" }\n"
+"\n"
+" return light_colour.rgb * attenuation * falloff \n"
+" * step( g_day_phase, light_colour.w );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" uint light_count = packed_index & 0x3u;\n"
+"\n"
+" vec3 l = vec3(0.0);\n"
+"\n"
+" if( light_count >= 1u ){\n"
+" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
+" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
+" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
+"\n"
+" l += scene_calculate_light( index_0, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 2u ){\n"
+" l += scene_calculate_light( index_1, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 3u ){\n"
+" l += scene_calculate_light( index_2, halfview, co, normal );\n"
+" }\n"
+" }\n"
+" }\n"
+"\n"
+" return l;\n"
+"}\n"
+"\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
+"{\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
+"\n"
+" // Lighting\n"
+" vec3 halfview = uCamera - co;\n"
+" float fdist = length(halfview);\n"
+" halfview /= fdist;\n"
+"\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+"\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
+"\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" cube_coord = floor( cube_coord );\n"
+"\n"
+" if( g_debug_indices == 1 )\n"
+" {\n"
+" return rand33(cube_coord);\n"
+" }\n"
+"\n"
+" if( g_debug_complexity == 1 )\n"
+" {\n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
+" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
+" }\n"
+"\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
+" \n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.x,\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.y,\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" fog_colour += sun_colour;\n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"\n"
+"float sdLine( vec3 p, vec3 a, vec3 b )\n"
+"{\n"
+" vec3 pa = p - a;\n"
+" vec3 ba = b - a;\n"
+"\n"
+" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
+" return length( pa - ba*h );\n"
+"}\n"
+"\n"
+"float compute_board_shadow()\n"
+"{\n"
+" // player shadow\n"
+" float dist_to_player = max( 0.0, sdLine( aWorldCo, g_board_0.xyz,\n"
+" g_board_1.xyz )-0.1 );\n"
+" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
+" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
+"\n"
+" return 1.0 - player_shadow*0.8;\n"
+"}\n"
+"\n"
+"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
+"{\n"
+" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
+"}\n"
+"\n"
+"#line 10 0 \n"
+"#line 1 3 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+" // Write motion vectors\n"
+" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"\n"
+" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
+"}\n"
+"\n"
+"#line 11 0 \n"
+"\n"
+"void main()\n"
+"{\n"
+" compute_motion_vectors();\n"
+"\n"
+" vec3 vfrag = vec3(0.5,0.5,0.5);\n"
+" vec4 vsamplemain = texture( uTexMain, aUv );\n"
+" vec4 wgarbage = texture( uTexGarbage, aCo.xz * 0.0015 + aCo.yx*0.002 );\n"
+" vec3 qnorm = aNorm.xyz;\n"
+" vfrag = vsamplemain.rgb;\n"
+"\n"
+" if( g_light_preview == 1 ){\n"
+" vfrag = vec3(0.5);\n"
+" }\n"
+"\n"
+" vfrag = scene_compute_lighting( vfrag, qnorm, aWorldCo );\n"
+" oColour = vec4( vfrag, 1.0 );\n"
+"\n"
+" vec3 halfdir = normalize( aWorldCo - uCamera );\n"
+" vec3 reflectdir = reflect( halfdir, qnorm );\n"
+" oColour = mix( oColour, \n"
+" vec4(texture(uTexCubemap,reflectdir).rgb * uColour.rgb, 1.0),\n"
+" uColour.a*wgarbage.b );\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_scene_cubemapped_uMdl;
+GLuint _uniform_scene_cubemapped_uPv;
+GLuint _uniform_scene_cubemapped_uPvmPrev;
+GLuint _uniform_scene_cubemapped_uTexGarbage;
+GLuint _uniform_scene_cubemapped_uTexMain;
+GLuint _uniform_scene_cubemapped_uTexCubemap;
+GLuint _uniform_scene_cubemapped_uCamera;
+GLuint _uniform_scene_cubemapped_uPlane;
+GLuint _uniform_scene_cubemapped_uColour;
+GLuint _uniform_scene_cubemapped_g_world_depth;
+GLuint _uniform_scene_cubemapped_uLightsArray;
+GLuint _uniform_scene_cubemapped_uLightsIndex;
+#include "shaders/scene_water.h"
+struct vg_shader _shader_scene_water = {
+ .name = "scene_water",
+ .vs =
+{
+.orig_file = "shaders/scene.vs",
+.static_src =
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec4 a_norm;\n"
+"layout (location=2) in vec2 a_uv;\n"
+"\n"
+"#line 1 1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+" // This magically solves some artifacting errors!\n"
+" //\n"
+" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
+"\n"
+" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line 6 0 \n"
+"\n"
+"uniform mat4x3 uMdl;\n"
+"uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
+"\n"
+"out vec2 aUv;\n"
+"out vec4 aNorm;\n"
+"out vec3 aCo;\n"
+"out vec3 aWorldCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
+" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
+" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+" vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+" gl_Position = vproj0;\n"
+"\n"
+" aUv = a_uv;\n"
+" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
+" aCo = a_co;\n"
+" aWorldCo = world_pos0;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/scene_water.fs",
+.static_src =
+"uniform sampler2D uTexMain;\n"
+"uniform sampler2D uTexDudv;\n"
+"uniform sampler2D uTexBack;\n"
+"\n"
+"uniform vec2 uInvRes;\n"
+"uniform float uTime;\n"
+"uniform vec3 uCamera;\n"
+"uniform float uSurfaceY;\n"
+"uniform vec3 uBoard0;\n"
+"uniform vec3 uBoard1;\n"
+"\n"
+"uniform vec3 uShoreColour;\n"
+"uniform vec3 uOceanColour;\n"
+"\n"
+"#line 1 1 \n"
+"// :D\n"
+"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
+"\n"
+"#line 16 0 \n"
+"#line 1 2 \n"
+"// :D\n"
+"\n"
+"in vec2 aUv;\n"
+"in vec4 aNorm;\n"
+"in vec3 aCo;\n"
+"in vec3 aWorldCo;\n"
+"\n"
+"#line 1 1 \n"
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
+"layout (std140) uniform ub_world_lighting\n"
+"{\n"
+" vec4 g_cube_min;\n"
+" vec4 g_cube_inv_range;\n"
+"\n"
+" vec4 g_water_plane;\n"
+" vec4 g_depth_bounds;\n"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+" vec4 g_board_0;\n"
+" vec4 g_board_1;\n"
+"\n"
+" float g_water_fog;\n"
+" float g_time;\n"
+" float g_realtime;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
+" int g_light_preview;\n"
+" int g_shadow_samples;\n"
+"\n"
+" int g_debug_indices;\n"
+" int g_debug_complexity;\n"
+"};\n"
+"\n"
+"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\n"
+"\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
+"\n"
+"const float SUN_ANGLE = 0.0001;\n"
+"const float PI = 3.14159265358979323846264;\n"
+"\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
+"\n"
+"vec3 rand33(vec3 p3)\n"
+"{\n"
+" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
+" p3 += dot(p3, p3.yxz+33.33);\n"
+" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
+"}\n"
+"\n"
+"float stars( vec3 rd, float rr, float size ){\n"
+" vec3 co = rd * rr;\n"
+"\n"
+" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
+"\n"
+" float spaces = 1.0 / rr;\n"
+" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
+" a -= mod(a, spaces) - spaces * 0.5;\n"
+"\n"
+" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
+" \n"
+" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
+" plane = plane - mod(plane, PI / count);\n"
+"\n"
+" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
+"\n"
+" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
+" float ydist = sqrt(rr * rr - level * level);\n"
+" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
+" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
+" float star = smoothstep(size, 0.0, distance(center, co));\n"
+" return star;\n"
+"}\n"
+"\n"
+"float luminance( vec3 v )\n"
+"{\n"
+" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
+"}\n"
+"\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
+"{\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
+" float sky_gradient = dir.y;\n"
+" \n"
+" /* Blend phase colours */\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
+" \n"
+" /* Add gradient */\n"
+" ambient -= sky_gradient * luminance(ambient);\n"
+" \n"
+" return ambient;\n"
+"}\n"
+"\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
+"{\n"
+" ray_dir.y = abs( ray_dir.y );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
+" \n"
+" /* Sun */\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
+" float sun_shape = pow( sun_size, 2000.0 );\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" \n"
+" float star = 0.0;\n"
+" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
+"\n"
+" if( star_blend > 0.001 ){\n"
+" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
+" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
+" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
+" }\n"
+" }\n"
+" \n"
+" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
+" return composite;\n"
+"}\n"
+"\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
+"{\n"
+" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
+"\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
+" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
+" ) * g_sun_colour.rgb * g_day_phase;\n"
+"\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
+"\n"
+"#line 44 0 \n"
+"\n"
+"float world_depth_sample( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" return texture( g_world_depth, depth_coord ).r;\n"
+"}\n"
+"\n"
+"float world_water_depth( vec3 pos )\n"
+"{\n"
+" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
+"}\n"
+"\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
+"\n"
+" float fdelta = height_sample - co.y;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
+"}\n"
+"\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
+" return 1.0;\n"
+" }\n"
+"\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\n"
+"\n"
+" float famt = 0.0;\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+"\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+"\n"
+" return 1.0 - famt;\n"
+"}\n"
+"\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
+"{\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
+"}\n"
+"\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_light( int light_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
+" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
+" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
+"\n"
+" vec3 light_delta = light_co.xyz-co;\n"
+" float dist2 = dot(light_delta,light_delta);\n"
+"\n"
+" light_delta = normalize( light_delta );\n"
+"\n"
+" float quadratic = dist2*100.0;\n"
+" float attenuation = 1.0/( 1.0 + quadratic );\n"
+" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
+"\n"
+" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
+"\n"
+" if( light_dir.w < 0.999999 ){\n"
+" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
+" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
+" }\n"
+"\n"
+" return light_colour.rgb * attenuation * falloff \n"
+" * step( g_day_phase, light_colour.w );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" uint light_count = packed_index & 0x3u;\n"
+"\n"
+" vec3 l = vec3(0.0);\n"
+"\n"
+" if( light_count >= 1u ){\n"
+" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
+" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
+" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
+"\n"
+" l += scene_calculate_light( index_0, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 2u ){\n"
+" l += scene_calculate_light( index_1, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 3u ){\n"
+" l += scene_calculate_light( index_2, halfview, co, normal );\n"
+" }\n"
+" }\n"
+" }\n"
+"\n"
+" return l;\n"
+"}\n"
+"\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
+"{\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
+"\n"
+" // Lighting\n"
+" vec3 halfview = uCamera - co;\n"
+" float fdist = length(halfview);\n"
+" halfview /= fdist;\n"
+"\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+"\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
+"\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" cube_coord = floor( cube_coord );\n"
+"\n"
+" if( g_debug_indices == 1 )\n"
+" {\n"
+" return rand33(cube_coord);\n"
+" }\n"
+"\n"
+" if( g_debug_complexity == 1 )\n"
+" {\n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
+" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
+" }\n"
+"\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
+" \n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.x,\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.y,\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" fog_colour += sun_colour;\n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"\n"
+"float sdLine( vec3 p, vec3 a, vec3 b )\n"
+"{\n"
+" vec3 pa = p - a;\n"
+" vec3 ba = b - a;\n"
+"\n"
+" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
+" return length( pa - ba*h );\n"
+"}\n"
+"\n"
+"float compute_board_shadow()\n"
+"{\n"
+" // player shadow\n"
+" float dist_to_player = max( 0.0, sdLine( aWorldCo, g_board_0.xyz,\n"
+" g_board_1.xyz )-0.1 );\n"
+" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
+" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
+"\n"
+" return 1.0 - player_shadow*0.8;\n"
+"}\n"
+"\n"
+"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
+"{\n"
+" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
+"}\n"
+"\n"
+"#line 17 0 \n"
+"#line 1 3 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+" // Write motion vectors\n"
+" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"\n"
+" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
+"}\n"
+"\n"
+"#line 18 0 \n"
+"\n"
+"vec4 water_surf( vec3 halfview, vec3 vnorm, float depthvalue, \n"
+" vec4 beneath, vec4 above )\n"
+"{\n"
+" vec3 surface_tint = mix(uShoreColour, uOceanColour, depthvalue);\n"
+"\n"
+" float ffresnel = pow(1.0-dot( vnorm, halfview ),5.0);\n"
+"\n"
+" vec3 lightdir = vec3(0.95,0.0,-0.3);\n"
+" vec3 specdir = reflect( -lightdir, vnorm );\n"
+" float spec = pow(max(dot(halfview,specdir),0.0),20.0)*0.3;\n"
+" \n"
+" // Depth \n"
+" float depthblend = pow( beneath.r, 0.8 );\n"
+"\n"
+" // Composite\n"
+" vec3 vsurface = mix(surface_tint, above.rgb, ffresnel );\n"
+" //vsurface += spec;\n"
+"\n"
+" return vec4( vsurface,depthblend );\n"
+"}\n"
+"\n"
+"void main()\n"
+"{\n"
+" compute_motion_vectors();\n"
+"\n"
+" // Create texture coords\n"
+" vec2 ssuv = gl_FragCoord.xy*uInvRes;\n"
+" \n"
+" // Surface colour composite\n"
+" float depthvalue = clamp( -world_water_depth(aCo)*(1.0/25.0), 0.0,1.0 );\n"
+"\n"
+" vec2 world_coord = aCo.xz * 0.008;\n"
+" vec4 time_offsets = vec4( uTime ) * vec4( 0.008, 0.006, 0.003, 0.03 );\n"
+" vec4 dudva = texture( uTexDudv, world_coord + time_offsets.xy )-0.5;\n"
+" vec4 dudvb = texture( uTexDudv, world_coord *7.0 - time_offsets.zw )-0.5;\n"
+"\n"
+" vec3 surfnorm = dudva.rgb + dudvb.rgb;\n"
+" surfnorm = normalize(vec3(0.0,1.0,0.0) + dudva.xyz*0.4 + dudvb.xyz*0.1);\n"
+" \n"
+" // Foam\n"
+" float fband = fract( aCo.z*0.02+uTime*0.1+depthvalue*10.0 );\n"
+" fband = step( fband+dudva.a*0.8, 0.3 ) * max((1.0-depthvalue*4.0),0.0);\n"
+"\n"
+" // Lighting\n"
+" vec3 halfview = -normalize( aCo-uCamera );\n"
+"\n"
+" // Sample textures\n"
+" vec4 above = texture( uTexMain, ssuv+ surfnorm.xz*0.2 );\n"
+" vec4 beneath = texture( uTexBack, ssuv );\n"
+"\n"
+" // Fog\n"
+" float fdist = pow(length( aCo.xz-uCamera.xz ) * 0.00047, 2.6);\n"
+"\n"
+" // Composite\n"
+" vec4 vsurface = water_surf( halfview, surfnorm, depthvalue, beneath, above );\n"
+" vsurface.a -= fdist;\n"
+" oColour = mix( vsurface, vec4(1.0,1.0,1.0,0.5), fband );\n"
+" oColour.rgb = scene_compute_lighting( oColour.rgb, aNorm.xyz, aWorldCo );\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_scene_water_uMdl;
+GLuint _uniform_scene_water_uPv;
+GLuint _uniform_scene_water_uPvmPrev;
+GLuint _uniform_scene_water_uTexMain;
+GLuint _uniform_scene_water_uTexDudv;
+GLuint _uniform_scene_water_uTexBack;
+GLuint _uniform_scene_water_uInvRes;
+GLuint _uniform_scene_water_uTime;
+GLuint _uniform_scene_water_uCamera;
+GLuint _uniform_scene_water_uSurfaceY;
+GLuint _uniform_scene_water_uBoard0;
+GLuint _uniform_scene_water_uBoard1;
+GLuint _uniform_scene_water_uShoreColour;
+GLuint _uniform_scene_water_uOceanColour;
+GLuint _uniform_scene_water_g_world_depth;
+GLuint _uniform_scene_water_uLightsArray;
+GLuint _uniform_scene_water_uLightsIndex;
+#include "shaders/scene_water_fast.h"
+struct vg_shader _shader_scene_water_fast = {
+ .name = "scene_water_fast",
+ .vs =
+{
+.orig_file = "shaders/scene.vs",
+.static_src =
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec4 a_norm;\n"
+"layout (location=2) in vec2 a_uv;\n"
+"\n"
+"#line 1 1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+" // This magically solves some artifacting errors!\n"
+" //\n"
+" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
+"\n"
+" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line 6 0 \n"
+"\n"
+"uniform mat4x3 uMdl;\n"
+"uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
+"\n"
+"out vec2 aUv;\n"
+"out vec4 aNorm;\n"
+"out vec3 aCo;\n"
+"out vec3 aWorldCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
+" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
+" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+" vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+" gl_Position = vproj0;\n"
+"\n"
+" aUv = a_uv;\n"
+" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
+" aCo = a_co;\n"
+" aWorldCo = world_pos0;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/scene_water_fast.fs",
+.static_src =
+"uniform sampler2D uTexDudv;\n"
+"\n"
+"uniform float uTime;\n"
+"uniform vec3 uCamera;\n"
+"uniform float uSurfaceY;\n"
+"uniform vec3 uBoard0;\n"
+"uniform vec3 uBoard1;\n"
+"\n"
+"uniform vec3 uShoreColour;\n"
+"uniform vec3 uOceanColour;\n"
+"\n"
+"#line 1 1 \n"
+"// :D\n"
+"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
+"\n"
+"#line 13 0 \n"
+"#line 1 2 \n"
+"// :D\n"
+"\n"
+"in vec2 aUv;\n"
+"in vec4 aNorm;\n"
+"in vec3 aCo;\n"
+"in vec3 aWorldCo;\n"
+"\n"
+"#line 1 1 \n"
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
+"layout (std140) uniform ub_world_lighting\n"
+"{\n"
+" vec4 g_cube_min;\n"
+" vec4 g_cube_inv_range;\n"
+"\n"
+" vec4 g_water_plane;\n"
+" vec4 g_depth_bounds;\n"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+" vec4 g_board_0;\n"
+" vec4 g_board_1;\n"
+"\n"
+" float g_water_fog;\n"
+" float g_time;\n"
+" float g_realtime;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
+" int g_light_preview;\n"
+" int g_shadow_samples;\n"
+"\n"
+" int g_debug_indices;\n"
+" int g_debug_complexity;\n"
+"};\n"
+"\n"
+"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\n"
+"\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
+"\n"
+"const float SUN_ANGLE = 0.0001;\n"
+"const float PI = 3.14159265358979323846264;\n"
+"\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
+"\n"
+"vec3 rand33(vec3 p3)\n"
+"{\n"
+" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
+" p3 += dot(p3, p3.yxz+33.33);\n"
+" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
+"}\n"
+"\n"
+"float stars( vec3 rd, float rr, float size ){\n"
+" vec3 co = rd * rr;\n"
+"\n"
+" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
+"\n"
+" float spaces = 1.0 / rr;\n"
+" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
+" a -= mod(a, spaces) - spaces * 0.5;\n"
+"\n"
+" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
+" \n"
+" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
+" plane = plane - mod(plane, PI / count);\n"
+"\n"
+" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
+"\n"
+" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
+" float ydist = sqrt(rr * rr - level * level);\n"
+" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
+" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
+" float star = smoothstep(size, 0.0, distance(center, co));\n"
+" return star;\n"
+"}\n"
+"\n"
+"float luminance( vec3 v )\n"
+"{\n"
+" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
+"}\n"
+"\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
+"{\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
+" float sky_gradient = dir.y;\n"
+" \n"
+" /* Blend phase colours */\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
+" \n"
+" /* Add gradient */\n"
+" ambient -= sky_gradient * luminance(ambient);\n"
+" \n"
+" return ambient;\n"
+"}\n"
+"\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
+"{\n"
+" ray_dir.y = abs( ray_dir.y );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
+" \n"
+" /* Sun */\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
+" float sun_shape = pow( sun_size, 2000.0 );\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" \n"
+" float star = 0.0;\n"
+" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
+"\n"
+" if( star_blend > 0.001 ){\n"
+" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
+" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
+" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
+" }\n"
+" }\n"
+" \n"
+" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
+" return composite;\n"
+"}\n"
+"\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
+"{\n"
+" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
+"\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
+" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
+" ) * g_sun_colour.rgb * g_day_phase;\n"
+"\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
+"\n"
+"#line 44 0 \n"
+"\n"
+"float world_depth_sample( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" return texture( g_world_depth, depth_coord ).r;\n"
+"}\n"
+"\n"
+"float world_water_depth( vec3 pos )\n"
+"{\n"
+" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
+"}\n"
+"\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
+"\n"
+" float fdelta = height_sample - co.y;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
+"}\n"
+"\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
+" return 1.0;\n"
+" }\n"
+"\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\n"
+"\n"
+" float famt = 0.0;\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+"\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+"\n"
+" return 1.0 - famt;\n"
+"}\n"
+"\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
+"{\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
+"}\n"
+"\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_light( int light_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
+" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
+" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
+"\n"
+" vec3 light_delta = light_co.xyz-co;\n"
+" float dist2 = dot(light_delta,light_delta);\n"
+"\n"
+" light_delta = normalize( light_delta );\n"
+"\n"
+" float quadratic = dist2*100.0;\n"
+" float attenuation = 1.0/( 1.0 + quadratic );\n"
+" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
+"\n"
+" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
+"\n"
+" if( light_dir.w < 0.999999 ){\n"
+" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
+" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
+" }\n"
+"\n"
+" return light_colour.rgb * attenuation * falloff \n"
+" * step( g_day_phase, light_colour.w );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" uint light_count = packed_index & 0x3u;\n"
+"\n"
+" vec3 l = vec3(0.0);\n"
+"\n"
+" if( light_count >= 1u ){\n"
+" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
+" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
+" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
+"\n"
+" l += scene_calculate_light( index_0, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 2u ){\n"
+" l += scene_calculate_light( index_1, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 3u ){\n"
+" l += scene_calculate_light( index_2, halfview, co, normal );\n"
+" }\n"
+" }\n"
+" }\n"
+"\n"
+" return l;\n"
+"}\n"
+"\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
+"{\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
+"\n"
+" // Lighting\n"
+" vec3 halfview = uCamera - co;\n"
+" float fdist = length(halfview);\n"
+" halfview /= fdist;\n"
+"\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+"\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
+"\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" cube_coord = floor( cube_coord );\n"
+"\n"
+" if( g_debug_indices == 1 )\n"
+" {\n"
+" return rand33(cube_coord);\n"
+" }\n"
+"\n"
+" if( g_debug_complexity == 1 )\n"
+" {\n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
+" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
+" }\n"
+"\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
+" \n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.x,\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.y,\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" fog_colour += sun_colour;\n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"\n"
+"float sdLine( vec3 p, vec3 a, vec3 b )\n"
+"{\n"
+" vec3 pa = p - a;\n"
+" vec3 ba = b - a;\n"
+"\n"
+" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
+" return length( pa - ba*h );\n"
+"}\n"
+"\n"
+"float compute_board_shadow()\n"
+"{\n"
+" // player shadow\n"
+" float dist_to_player = max( 0.0, sdLine( aWorldCo, g_board_0.xyz,\n"
+" g_board_1.xyz )-0.1 );\n"
+" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
+" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
+"\n"
+" return 1.0 - player_shadow*0.8;\n"
+"}\n"
+"\n"
+"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
+"{\n"
+" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
+"}\n"
+"\n"
+"#line 14 0 \n"
+"#line 1 3 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+" // Write motion vectors\n"
+" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"\n"
+" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
+"}\n"
+"\n"
+"#line 15 0 \n"
+"\n"
+"vec4 water_surf( vec3 halfview, vec3 vnorm, float depthvalue )\n"
+"{\n"
+" vec3 surface_tint = mix(uShoreColour, uOceanColour, depthvalue);\n"
+"\n"
+" float ffresnel = pow(1.0-dot( vnorm, halfview ),5.0);\n"
+"\n"
+" vec3 lightdir = vec3(0.95,0.0,-0.3);\n"
+" vec3 specdir = reflect( -lightdir, vnorm );\n"
+" float spec = pow(max(dot(halfview,specdir),0.0),20.0)*0.3;\n"
+" \n"
+" return vec4( surface_tint + spec, max(min(depthvalue*4.0, 1.0),0.0) );\n"
+"}\n"
+"\n"
+"void main()\n"
+"{\n"
+" compute_motion_vectors();\n"
+"\n"
+" // Surface colour composite\n"
+" float depthvalue = clamp( -world_water_depth( aCo )*(1.0/25.0), 0.0, 1.0 );\n"
+"\n"
+" vec2 world_coord = aCo.xz * 0.008;\n"
+" vec4 time_offsets = vec4( uTime ) * vec4( 0.008, 0.006, 0.003, 0.03 );\n"
+" vec4 dudva = texture( uTexDudv, world_coord + time_offsets.xy )-0.5;\n"
+" vec4 dudvb = texture( uTexDudv, world_coord *7.0 - time_offsets.zw )-0.5;\n"
+"\n"
+" vec3 surfnorm = dudva.rgb + dudvb.rgb;\n"
+" surfnorm = normalize(vec3(0.0,1.0,0.0) + dudva.xyz*0.4 + dudvb.xyz*0.1);\n"
+" \n"
+" // Foam\n"
+" float fband = fract( aCo.z*0.02+uTime*0.1+depthvalue*10.0 );\n"
+" fband = step( fband+dudva.a*0.8, 0.3 ) * max((1.0-depthvalue*4.0),0.0);\n"
+"\n"
+" // Lighting\n"
+" vec3 halfview = -normalize( aCo-uCamera );\n"
+"\n"
+" // Fog\n"
+" float fdist = pow(length( aCo.xz-uCamera.xz ) * 0.00047, 2.6);\n"
+"\n"
+" // Composite\n"
+" vec4 vsurface = water_surf( halfview, surfnorm, depthvalue );\n"
+" vsurface.a -= fdist;\n"
+" oColour = mix( vsurface, vec4(1.0,1.0,1.0,0.5), fband );\n"
+" oColour.rgb = scene_compute_lighting( oColour.rgb, aNorm.xyz, aWorldCo );\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_scene_water_fast_uMdl;
+GLuint _uniform_scene_water_fast_uPv;
+GLuint _uniform_scene_water_fast_uPvmPrev;
+GLuint _uniform_scene_water_fast_uTexDudv;
+GLuint _uniform_scene_water_fast_uTime;
+GLuint _uniform_scene_water_fast_uCamera;
+GLuint _uniform_scene_water_fast_uSurfaceY;
+GLuint _uniform_scene_water_fast_uBoard0;
+GLuint _uniform_scene_water_fast_uBoard1;
+GLuint _uniform_scene_water_fast_uShoreColour;
+GLuint _uniform_scene_water_fast_uOceanColour;
+GLuint _uniform_scene_water_fast_g_world_depth;
+GLuint _uniform_scene_water_fast_uLightsArray;
+GLuint _uniform_scene_water_fast_uLightsIndex;
+#include "shaders/scene_scoretext.h"
+struct vg_shader _shader_scene_scoretext = {
+ .name = "scene_scoretext",
+ .vs =
+{
+.orig_file = "shaders/scene_sfd.vs",
+.static_src =
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec4 a_norm;\n"
+"layout (location=2) in vec2 a_uv;\n"
+"\n"
+"#line 1 1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+" // This magically solves some artifacting errors!\n"
+" //\n"
+" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
+"\n"
+" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line 6 0 \n"
+"\n"
+"uniform mat4x3 uMdl;\n"
+"uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
+"uniform vec3 uInfo;\n"
+"\n"
+"out vec2 aUv;\n"
+"out vec4 aNorm;\n"
+"out vec3 aCo;\n"
+"out vec3 aWorldCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" float w = ((a_norm.w)-0.5)*2.0 + fract(uInfo.z) - 0.0;\n"
+" float c = -cos(w*0.6);\n"
+" float s = -sin(w*0.6);\n"
+" float r = 0.2;\n"
+"\n"
+" float w1 = clamp( w*4.0 - a_co.y*10.0, -1.0, 1.0 ) * (3.14159265*0.5);\n"
+" float c1 = cos(w1);\n"
+" float s1 = sin(w1);\n"
+"\n"
+" float yoff = step(0.01,fract(uInfo.z))*-0.5;\n"
+"\n"
+" mat4x3 mlocal;\n"
+" mlocal[0] = vec3(c1, s1,0.0);\n"
+" mlocal[1] = vec3(-s1,c1,0.0);\n"
+" mlocal[2] = vec3(0.0,0.0,1.0);\n"
+" mlocal[3] = vec3(c*r,uInfo.y*0.875 + s*r,uInfo.x*0.5);\n"
+"\n"
+" vec3 local_pos0 = mlocal * vec4( a_co, 1.0 );\n"
+" vec3 world_pos0 = uMdl * vec4( local_pos0, 1.0 );\n"
+"\n"
+" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
+" vec4 vproj1 = uPvmPrev * vec4( local_pos0, 1.0 );\n"
+"\n"
+" vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+" gl_Position = vproj0;\n"
+"\n"
+" aUv = a_uv + vec2( floor(uInfo.z+0.5)*(1.0/64.0), yoff );\n"
+" aNorm = vec4( mat3(uMdl) * mat3(mlocal) * a_norm.xyz, a_norm.w );\n"
+" aCo = a_co;\n"
+" aWorldCo = world_pos0;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/scene_standard.fs",
+.static_src =
+"uniform sampler2D uTexGarbage;\n"
+"uniform sampler2D uTexMain;\n"
+"uniform vec3 uCamera;\n"
+"uniform vec4 uPlane;\n"
+"\n"
+"#line 1 1 \n"
+"// :D\n"
+"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
+"\n"
+"#line 7 0 \n"
+"#line 1 2 \n"
+"// :D\n"
+"\n"
+"in vec2 aUv;\n"
+"in vec4 aNorm;\n"
+"in vec3 aCo;\n"
+"in vec3 aWorldCo;\n"
+"\n"
+"#line 1 1 \n"
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
+"layout (std140) uniform ub_world_lighting\n"
+"{\n"
+" vec4 g_cube_min;\n"
+" vec4 g_cube_inv_range;\n"
+"\n"
+" vec4 g_water_plane;\n"
+" vec4 g_depth_bounds;\n"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+" vec4 g_board_0;\n"
+" vec4 g_board_1;\n"
+"\n"
+" float g_water_fog;\n"
+" float g_time;\n"
+" float g_realtime;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
+" int g_light_preview;\n"
+" int g_shadow_samples;\n"
+"\n"
+" int g_debug_indices;\n"
+" int g_debug_complexity;\n"
+"};\n"
+"\n"
+"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\n"
+"\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
+"\n"
+"const float SUN_ANGLE = 0.0001;\n"
+"const float PI = 3.14159265358979323846264;\n"
+"\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
+"\n"
+"vec3 rand33(vec3 p3)\n"
+"{\n"
+" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
+" p3 += dot(p3, p3.yxz+33.33);\n"
+" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
+"}\n"
+"\n"
+"float stars( vec3 rd, float rr, float size ){\n"
+" vec3 co = rd * rr;\n"
+"\n"
+" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
+"\n"
+" float spaces = 1.0 / rr;\n"
+" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
+" a -= mod(a, spaces) - spaces * 0.5;\n"
+"\n"
+" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
+" \n"
+" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
+" plane = plane - mod(plane, PI / count);\n"
+"\n"
+" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
+"\n"
+" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
+" float ydist = sqrt(rr * rr - level * level);\n"
+" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
+" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
+" float star = smoothstep(size, 0.0, distance(center, co));\n"
+" return star;\n"
+"}\n"
+"\n"
+"float luminance( vec3 v )\n"
+"{\n"
+" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
+"}\n"
+"\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
+"{\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
+" float sky_gradient = dir.y;\n"
+" \n"
+" /* Blend phase colours */\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
+" \n"
+" /* Add gradient */\n"
+" ambient -= sky_gradient * luminance(ambient);\n"
+" \n"
+" return ambient;\n"
+"}\n"
+"\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
+"{\n"
+" ray_dir.y = abs( ray_dir.y );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
+" \n"
+" /* Sun */\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
+" float sun_shape = pow( sun_size, 2000.0 );\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" \n"
+" float star = 0.0;\n"
+" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
+"\n"
+" if( star_blend > 0.001 ){\n"
+" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
+" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
+" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
+" }\n"
+" }\n"
+" \n"
+" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
+" return composite;\n"
+"}\n"
+"\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
+"{\n"
+" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
+"\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
+" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
+" ) * g_sun_colour.rgb * g_day_phase;\n"
+"\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
+"\n"
+"#line 44 0 \n"
+"\n"
+"float world_depth_sample( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" return texture( g_world_depth, depth_coord ).r;\n"
+"}\n"
+"\n"
+"float world_water_depth( vec3 pos )\n"
+"{\n"
+" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
+"}\n"
+"\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
+"\n"
+" float fdelta = height_sample - co.y;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
+"}\n"
+"\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
+" return 1.0;\n"
+" }\n"
+"\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\n"
+"\n"
+" float famt = 0.0;\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+"\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+"\n"
+" return 1.0 - famt;\n"
+"}\n"
+"\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
+"{\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
+"}\n"
+"\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_light( int light_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
+" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
+" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
+"\n"
+" vec3 light_delta = light_co.xyz-co;\n"
+" float dist2 = dot(light_delta,light_delta);\n"
+"\n"
+" light_delta = normalize( light_delta );\n"
+"\n"
+" float quadratic = dist2*100.0;\n"
+" float attenuation = 1.0/( 1.0 + quadratic );\n"
+" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
+"\n"
+" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
+"\n"
+" if( light_dir.w < 0.999999 ){\n"
+" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
+" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
+" }\n"
+"\n"
+" return light_colour.rgb * attenuation * falloff \n"
+" * step( g_day_phase, light_colour.w );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" uint light_count = packed_index & 0x3u;\n"
+"\n"
+" vec3 l = vec3(0.0);\n"
+"\n"
+" if( light_count >= 1u ){\n"
+" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
+" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
+" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
+"\n"
+" l += scene_calculate_light( index_0, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 2u ){\n"
+" l += scene_calculate_light( index_1, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 3u ){\n"
+" l += scene_calculate_light( index_2, halfview, co, normal );\n"
+" }\n"
+" }\n"
+" }\n"
+"\n"
+" return l;\n"
+"}\n"
+"\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
+"{\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
+"\n"
+" // Lighting\n"
+" vec3 halfview = uCamera - co;\n"
+" float fdist = length(halfview);\n"
+" halfview /= fdist;\n"
+"\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+"\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
+"\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" cube_coord = floor( cube_coord );\n"
+"\n"
+" if( g_debug_indices == 1 )\n"
+" {\n"
+" return rand33(cube_coord);\n"
+" }\n"
+"\n"
+" if( g_debug_complexity == 1 )\n"
+" {\n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
+" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
+" }\n"
+"\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
+" \n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.x,\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.y,\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" fog_colour += sun_colour;\n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"\n"
+"float sdLine( vec3 p, vec3 a, vec3 b )\n"
+"{\n"
+" vec3 pa = p - a;\n"
+" vec3 ba = b - a;\n"
+"\n"
+" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
+" return length( pa - ba*h );\n"
+"}\n"
+"\n"
+"float compute_board_shadow()\n"
+"{\n"
+" // player shadow\n"
+" float dist_to_player = max( 0.0, sdLine( aWorldCo, g_board_0.xyz,\n"
+" g_board_1.xyz )-0.1 );\n"
+" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
+" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
+"\n"
+" return 1.0 - player_shadow*0.8;\n"
+"}\n"
+"\n"
+"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
+"{\n"
+" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
+"}\n"
+"\n"
+"#line 8 0 \n"
+"#line 1 3 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+" // Write motion vectors\n"
+" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"\n"
+" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"\n"
+"void main()\n"
+"{\n"
+" compute_motion_vectors();\n"
+"\n"
+" vec3 vfrag = vec3(0.5,0.5,0.5);\n"
+" vec4 vsamplemain = texture( uTexMain, aUv );\n"
+" vec3 qnorm = aNorm.xyz;\n"
+"\n"
+" vfrag = vsamplemain.rgb;\n"
+"\n"
+" if( g_light_preview == 1 )\n"
+" {\n"
+" vfrag = vec3(0.5);\n"
+" }\n"
+"\n"
+" vfrag = scene_compute_lighting( vfrag, qnorm, aWorldCo );\n"
+" oColour = vec4( vfrag, 1.0 );\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_scene_scoretext_uMdl;
+GLuint _uniform_scene_scoretext_uPv;
+GLuint _uniform_scene_scoretext_uPvmPrev;
+GLuint _uniform_scene_scoretext_uInfo;
+GLuint _uniform_scene_scoretext_uTexGarbage;
+GLuint _uniform_scene_scoretext_uTexMain;
+GLuint _uniform_scene_scoretext_uCamera;
+GLuint _uniform_scene_scoretext_uPlane;
+GLuint _uniform_scene_scoretext_g_world_depth;
+GLuint _uniform_scene_scoretext_uLightsArray;
+GLuint _uniform_scene_scoretext_uLightsIndex;
+#include "shaders/scene_font.h"
+struct vg_shader _shader_scene_font = {
+ .name = "scene_font",
+ .vs =
+{
+.orig_file = "shaders/model_font.vs",
+.static_src =
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec3 a_norm;\n"
+"layout (location=2) in vec2 a_uv;\n"
+"\n"
+"#line 1 1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+" // This magically solves some artifacting errors!\n"
+" //\n"
+" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
+"\n"
+" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line 6 0 \n"
+"\n"
+"uniform mat4x3 uMdl;\n"
+"uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
+"uniform vec4 uOffset;\n"
+"\n"
+"out vec2 aUv;\n"
+"out vec4 aNorm;\n"
+"out vec3 aCo;\n"
+"out vec3 aWorldCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec3 co = a_co*uOffset.w+uOffset.xyz;\n"
+" vec3 world_pos0 = uMdl * vec4( co, 1.0 );\n"
+" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
+" vec4 vproj1 = uPvmPrev * vec4( co, 1.0 );\n"
+"\n"
+" vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+" gl_Position = vproj0;\n"
+"\n"
+" aUv = a_uv;\n"
+" aNorm = vec4( mat3(uMdl) * a_norm, 0.0 );\n"
+" aCo = co;\n"
+" aWorldCo = world_pos0;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/scene_font.fs",
+.static_src =
+"uniform sampler2D uTexGarbage; // unused\n"
+"uniform sampler2D uTexMain; // unused\n"
+"uniform vec3 uCamera;\n"
+"uniform float uTime;\n"
+"uniform float uOpacity;\n"
+"uniform float uColourize;\n"
+"\n"
+"#line 1 1 \n"
+"// :D\n"
+"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
+"\n"
+"#line 9 0 \n"
+"#line 1 2 \n"
+"// :D\n"
+"\n"
+"in vec2 aUv;\n"
+"in vec4 aNorm;\n"
+"in vec3 aCo;\n"
+"in vec3 aWorldCo;\n"
+"\n"
+"#line 1 1 \n"
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
+"layout (std140) uniform ub_world_lighting\n"
+"{\n"
+" vec4 g_cube_min;\n"
+" vec4 g_cube_inv_range;\n"
+"\n"
+" vec4 g_water_plane;\n"
+" vec4 g_depth_bounds;\n"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+" vec4 g_board_0;\n"
+" vec4 g_board_1;\n"
+"\n"
+" float g_water_fog;\n"
+" float g_time;\n"
+" float g_realtime;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
+" int g_light_preview;\n"
+" int g_shadow_samples;\n"
+"\n"
+" int g_debug_indices;\n"
+" int g_debug_complexity;\n"
+"};\n"
+"\n"
+"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\n"
+"\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
+"\n"
+"const float SUN_ANGLE = 0.0001;\n"
+"const float PI = 3.14159265358979323846264;\n"
+"\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
+"\n"
+"vec3 rand33(vec3 p3)\n"
+"{\n"
+" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
+" p3 += dot(p3, p3.yxz+33.33);\n"
+" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
+"}\n"
+"\n"
+"float stars( vec3 rd, float rr, float size ){\n"
+" vec3 co = rd * rr;\n"
+"\n"
+" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
+"\n"
+" float spaces = 1.0 / rr;\n"
+" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
+" a -= mod(a, spaces) - spaces * 0.5;\n"
+"\n"
+" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
+" \n"
+" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
+" plane = plane - mod(plane, PI / count);\n"
+"\n"
+" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
+"\n"
+" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
+" float ydist = sqrt(rr * rr - level * level);\n"
+" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
+" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
+" float star = smoothstep(size, 0.0, distance(center, co));\n"
+" return star;\n"
+"}\n"
+"\n"
+"float luminance( vec3 v )\n"
+"{\n"
+" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
+"}\n"
+"\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
+"{\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
+" float sky_gradient = dir.y;\n"
+" \n"
+" /* Blend phase colours */\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
+" \n"
+" /* Add gradient */\n"
+" ambient -= sky_gradient * luminance(ambient);\n"
+" \n"
+" return ambient;\n"
+"}\n"
+"\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
+"{\n"
+" ray_dir.y = abs( ray_dir.y );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
+" \n"
+" /* Sun */\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
+" float sun_shape = pow( sun_size, 2000.0 );\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" \n"
+" float star = 0.0;\n"
+" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
+"\n"
+" if( star_blend > 0.001 ){\n"
+" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
+" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
+" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
+" }\n"
+" }\n"
+" \n"
+" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
+" return composite;\n"
+"}\n"
+"\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
+"{\n"
+" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
+"\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
+" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
+" ) * g_sun_colour.rgb * g_day_phase;\n"
+"\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
+"\n"
+"#line 44 0 \n"
+"\n"
+"float world_depth_sample( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" return texture( g_world_depth, depth_coord ).r;\n"
+"}\n"
+"\n"
+"float world_water_depth( vec3 pos )\n"
+"{\n"
+" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
+"}\n"
+"\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
+"\n"
+" float fdelta = height_sample - co.y;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
+"}\n"
+"\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
+" return 1.0;\n"
+" }\n"
+"\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\n"
+"\n"
+" float famt = 0.0;\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+"\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+"\n"
+" return 1.0 - famt;\n"
+"}\n"
+"\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
+"{\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
+"}\n"
+"\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_light( int light_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
+" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
+" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
+"\n"
+" vec3 light_delta = light_co.xyz-co;\n"
+" float dist2 = dot(light_delta,light_delta);\n"
+"\n"
+" light_delta = normalize( light_delta );\n"
+"\n"
+" float quadratic = dist2*100.0;\n"
+" float attenuation = 1.0/( 1.0 + quadratic );\n"
+" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
+"\n"
+" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
+"\n"
+" if( light_dir.w < 0.999999 ){\n"
+" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
+" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
+" }\n"
+"\n"
+" return light_colour.rgb * attenuation * falloff \n"
+" * step( g_day_phase, light_colour.w );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" uint light_count = packed_index & 0x3u;\n"
+"\n"
+" vec3 l = vec3(0.0);\n"
+"\n"
+" if( light_count >= 1u ){\n"
+" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
+" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
+" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
+"\n"
+" l += scene_calculate_light( index_0, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 2u ){\n"
+" l += scene_calculate_light( index_1, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 3u ){\n"
+" l += scene_calculate_light( index_2, halfview, co, normal );\n"
+" }\n"
+" }\n"
+" }\n"
+"\n"
+" return l;\n"
+"}\n"
+"\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
+"{\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
+"\n"
+" // Lighting\n"
+" vec3 halfview = uCamera - co;\n"
+" float fdist = length(halfview);\n"
+" halfview /= fdist;\n"
+"\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+"\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
+"\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" cube_coord = floor( cube_coord );\n"
+"\n"
+" if( g_debug_indices == 1 )\n"
+" {\n"
+" return rand33(cube_coord);\n"
+" }\n"
+"\n"
+" if( g_debug_complexity == 1 )\n"
+" {\n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
+" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
+" }\n"
+"\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
+" \n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.x,\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.y,\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" fog_colour += sun_colour;\n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"\n"
+"float sdLine( vec3 p, vec3 a, vec3 b )\n"
+"{\n"
+" vec3 pa = p - a;\n"
+" vec3 ba = b - a;\n"
+"\n"
+" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
+" return length( pa - ba*h );\n"
+"}\n"
+"\n"
+"float compute_board_shadow()\n"
+"{\n"
+" // player shadow\n"
+" float dist_to_player = max( 0.0, sdLine( aWorldCo, g_board_0.xyz,\n"
+" g_board_1.xyz )-0.1 );\n"
+" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
+" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
+"\n"
+" return 1.0 - player_shadow*0.8;\n"
+"}\n"
+"\n"
+"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
+"{\n"
+" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
+"}\n"
+"\n"
+"#line 10 0 \n"
+"#line 1 3 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+" // Write motion vectors\n"
+" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"\n"
+" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
+"}\n"
+"\n"
+"#line 11 0 \n"
+"\n"
+"vec3 pal( float t ){\n"
+" vec3 a = vec3(0.30,0.3,0.3);\n"
+" vec3 b = vec3(0.8);\n"
+" vec3 c = vec3(0.28,0.3,0.4);\n"
+" vec3 d = vec3(0.00,0.1,0.1);\n"
+" return a + b*cos( 6.28318*(c*t+d) );\n"
+"}\n"
+"\n"
+"void main(){\n"
+" compute_motion_vectors();\n"
+" vec3 vfrag = vec3(0.5,0.5,0.5);\n"
+" vec3 qnorm = aNorm.xyz;\n"
+"\n"
+" //vec4 vsamplemain = texture( uTexMain, aUv );\n"
+" //vfrag = vsamplemain.rgb;\n"
+"\n"
+" vec4 spread0 = uTime*0.0002*vec4( 17.3,-19.6, 23.2,-47.7 );\n"
+" vec4 spread1 = uTime*0.0002*vec4( -13.3, 12.6,-28.2, 14.7 );\n"
+"\n"
+" vec2 p = aCo.xy + vec2(0.3);\n"
+" float a = atan( p.y/p.x );\n"
+" vec4 v0 = step( vec4(0.5), fract(vec4(a) + spread0) );\n"
+" vec4 v1 = step( vec4(0.5), fract(vec4(a) + spread1) );\n"
+"\n"
+" float d = ( v0.x+v0.y+v0.z+v0.w +\n"
+" v1.x+v1.y+v1.z+v1.w ) * 0.125;\n"
+" \n"
+" float dither = fract(dot(vec2(171.0,231.0),gl_FragCoord.xy)/71.0);\n"
+" float x = d*0.8+length(p)*0.3;\n"
+" x = (floor(x*8.0) + step(dither, fract(x * 8.0))) / 8.0;\n"
+"\n"
+" if( x + (uOpacity*2.0-1.0) < 0.5 ) \n"
+" discard;\n"
+"\n"
+" vfrag = mix( vec3(x), pal( x ), uColourize );\n"
+"\n"
+" if( g_light_preview == 1 ){\n"
+" vfrag = vec3(0.5);\n"
+" }\n"
+"\n"
+" vfrag = scene_compute_lighting( vfrag, qnorm, aWorldCo );\n"
+" oColour = vec4( vfrag, 1.0 );\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_scene_font_uMdl;
+GLuint _uniform_scene_font_uPv;
+GLuint _uniform_scene_font_uPvmPrev;
+GLuint _uniform_scene_font_uOffset;
+GLuint _uniform_scene_font_uTexGarbage;
+GLuint _uniform_scene_font_uTexMain;
+GLuint _uniform_scene_font_uCamera;
+GLuint _uniform_scene_font_uTime;
+GLuint _uniform_scene_font_uOpacity;
+GLuint _uniform_scene_font_uColourize;
+GLuint _uniform_scene_font_g_world_depth;
+GLuint _uniform_scene_font_uLightsArray;
+GLuint _uniform_scene_font_uLightsIndex;
+#include "shaders/model_sky.h"
+struct vg_shader _shader_model_sky = {
+ .name = "model_sky",
+ .vs =
+{
+.orig_file = "shaders/model.vs",
+.static_src =
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec3 a_norm;\n"
+"layout (location=2) in vec2 a_uv;\n"
+"layout (location=3) in vec4 a_colour;\n"
+"layout (location=4) in vec4 a_weights;\n"
+"layout (location=5) in ivec4 a_groups;\n"
+"\n"
+"#line 1 1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+" // This magically solves some artifacting errors!\n"
+" //\n"
+" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
+"\n"
+" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"\n"
+"uniform mat4x3 uMdl;\n"
+"uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
+"\n"
+"out vec4 aColour;\n"
+"out vec2 aUv;\n"
+"out vec3 aNorm;\n"
+"out vec3 aCo;\n"
+"out vec3 aWorldCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
+" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
+" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+" vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+" gl_Position = vproj0;\n"
+" aWorldCo = world_pos0;\n"
+" aColour = a_colour;\n"
+" aUv = a_uv;\n"
+" aNorm = normalize( mat3(uMdl) * a_norm );\n"
+" aCo = a_co;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/model_sky.fs",
+.static_src =
+"uniform sampler2D uTexGarbage;\n"
+"\n"
+"in vec4 aColour;\n"
+"in vec2 aUv;\n"
+"in vec3 aNorm;\n"
+"in vec3 aCo;\n"
+"in vec3 aWorldCo;\n"
+"\n"
+"// Spooky!\n"
+"const vec3 uCamera = vec3(0.0);\n"
+"\n"
+"#line 1 1 \n"
+"// :D\n"
+"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
+"\n"
+"#line 13 0 \n"
+"#line 1 2 \n"
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
+"layout (std140) uniform ub_world_lighting\n"
+"{\n"
+" vec4 g_cube_min;\n"
+" vec4 g_cube_inv_range;\n"
+"\n"
+" vec4 g_water_plane;\n"
+" vec4 g_depth_bounds;\n"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+" vec4 g_board_0;\n"
+" vec4 g_board_1;\n"
+"\n"
+" float g_water_fog;\n"
+" float g_time;\n"
+" float g_realtime;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
+" int g_light_preview;\n"
+" int g_shadow_samples;\n"
+"\n"
+" int g_debug_indices;\n"
+" int g_debug_complexity;\n"
+"};\n"
+"\n"
+"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\n"
+"\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
+"\n"
+"const float SUN_ANGLE = 0.0001;\n"
+"const float PI = 3.14159265358979323846264;\n"
+"\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
+"\n"
+"vec3 rand33(vec3 p3)\n"
+"{\n"
+" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
+" p3 += dot(p3, p3.yxz+33.33);\n"
+" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
+"}\n"
+"\n"
+"float stars( vec3 rd, float rr, float size ){\n"
+" vec3 co = rd * rr;\n"
+"\n"
+" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
+"\n"
+" float spaces = 1.0 / rr;\n"
+" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
+" a -= mod(a, spaces) - spaces * 0.5;\n"
+"\n"
+" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
+" \n"
+" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
+" plane = plane - mod(plane, PI / count);\n"
+"\n"
+" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
+"\n"
+" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
+" float ydist = sqrt(rr * rr - level * level);\n"
+" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
+" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
+" float star = smoothstep(size, 0.0, distance(center, co));\n"
+" return star;\n"
+"}\n"
+"\n"
+"float luminance( vec3 v )\n"
+"{\n"
+" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
+"}\n"
+"\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
+"{\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
+" float sky_gradient = dir.y;\n"
+" \n"
+" /* Blend phase colours */\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
+" \n"
+" /* Add gradient */\n"
+" ambient -= sky_gradient * luminance(ambient);\n"
+" \n"
+" return ambient;\n"
+"}\n"
+"\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
+"{\n"
+" ray_dir.y = abs( ray_dir.y );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
+" \n"
+" /* Sun */\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
+" float sun_shape = pow( sun_size, 2000.0 );\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" \n"
+" float star = 0.0;\n"
+" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
+"\n"
+" if( star_blend > 0.001 ){\n"
+" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
+" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
+" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
+" }\n"
+" }\n"
+" \n"
+" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
+" return composite;\n"
+"}\n"
+"\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
+"{\n"
+" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
+"\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
+" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
+" ) * g_sun_colour.rgb * g_day_phase;\n"
+"\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
+"\n"
+"#line 44 0 \n"
+"\n"
+"float world_depth_sample( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" return texture( g_world_depth, depth_coord ).r;\n"
+"}\n"
+"\n"
+"float world_water_depth( vec3 pos )\n"
+"{\n"
+" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
+"}\n"
+"\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
+"\n"
+" float fdelta = height_sample - co.y;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
+"}\n"
+"\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
+" return 1.0;\n"
+" }\n"
+"\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\n"
+"\n"
+" float famt = 0.0;\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+"\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+"\n"
+" return 1.0 - famt;\n"
+"}\n"
+"\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
+"{\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
+"}\n"
+"\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_light( int light_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
+" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
+" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
+"\n"
+" vec3 light_delta = light_co.xyz-co;\n"
+" float dist2 = dot(light_delta,light_delta);\n"
+"\n"
+" light_delta = normalize( light_delta );\n"
+"\n"
+" float quadratic = dist2*100.0;\n"
+" float attenuation = 1.0/( 1.0 + quadratic );\n"
+" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
+"\n"
+" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
+"\n"
+" if( light_dir.w < 0.999999 ){\n"
+" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
+" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
+" }\n"
+"\n"
+" return light_colour.rgb * attenuation * falloff \n"
+" * step( g_day_phase, light_colour.w );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" uint light_count = packed_index & 0x3u;\n"
+"\n"
+" vec3 l = vec3(0.0);\n"
+"\n"
+" if( light_count >= 1u ){\n"
+" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
+" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
+" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
+"\n"
+" l += scene_calculate_light( index_0, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 2u ){\n"
+" l += scene_calculate_light( index_1, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 3u ){\n"
+" l += scene_calculate_light( index_2, halfview, co, normal );\n"
+" }\n"
+" }\n"
+" }\n"
+"\n"
+" return l;\n"
+"}\n"
+"\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
+"{\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
+"\n"
+" // Lighting\n"
+" vec3 halfview = uCamera - co;\n"
+" float fdist = length(halfview);\n"
+" halfview /= fdist;\n"
+"\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+"\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
+"\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" cube_coord = floor( cube_coord );\n"
+"\n"
+" if( g_debug_indices == 1 )\n"
+" {\n"
+" return rand33(cube_coord);\n"
+" }\n"
+"\n"
+" if( g_debug_complexity == 1 )\n"
+" {\n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
+" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
+" }\n"
+"\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
+" \n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.x,\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.y,\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" fog_colour += sun_colour;\n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
+"}\n"
+"\n"
+"#line 14 0 \n"
+"#line 1 3 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+" // Write motion vectors\n"
+" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"\n"
+" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
+"}\n"
+"\n"
+"#line 15 0 \n"
+"\n"
+"void main()\n"
+"{\n"
+" compute_motion_vectors();\n"
+"\n"
+" vec3 rd = normalize(aNorm);\n"
+"\n"
+" float fmove = g_time * 5.0;\n"
+" vec2 cloudplane = (rd.xz / (rd.y*sign(rd.y))) * 0.025;\n"
+" vec4 clouds1 = texture( uTexGarbage, cloudplane + vec2(0.1,0.4)*fmove*2.0 );\n"
+" vec4 clouds2 = texture( uTexGarbage, cloudplane*2.0 + vec2(0.3,0.1)*fmove );\n"
+"\n"
+" float cloud_d = max(clouds1.b*clouds2.r -0.2 - clouds2.g*0.4,0.0);\n"
+" float cloud_e = pow(cloud_d,1.5)*pow(abs(rd.y),0.3)*2.0;\n"
+"\n"
+" oColour = vec4( clearskies_sky( -rd ) ,1.0);\n"
+"\n"
+" vec3 cloud_colour = mix( mix(g_nightsky_colour.rgb,vec3(1.0),g_day_phase), \n"
+" g_sunset_colour.rgb, g_sunset_phase );\n"
+"\n"
+" oColour.rgb = mix( oColour.rgb, cloud_colour, cloud_e );\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_model_sky_uMdl;
+GLuint _uniform_model_sky_uPv;
+GLuint _uniform_model_sky_uPvmPrev;
+GLuint _uniform_model_sky_uTexGarbage;
+GLuint _uniform_model_sky_g_world_depth;
+GLuint _uniform_model_sky_uLightsArray;
+GLuint _uniform_model_sky_uLightsIndex;
+#include "shaders/model_sky_space.h"
+struct vg_shader _shader_model_sky_space = {
+ .name = "model_sky_space",
+ .vs =
+{
+.orig_file = "shaders/model.vs",
+.static_src =
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec3 a_norm;\n"
+"layout (location=2) in vec2 a_uv;\n"
+"layout (location=3) in vec4 a_colour;\n"
+"layout (location=4) in vec4 a_weights;\n"
+"layout (location=5) in ivec4 a_groups;\n"
+"\n"
+"#line 1 1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+" // This magically solves some artifacting errors!\n"
+" //\n"
+" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
+"\n"
+" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"\n"
+"uniform mat4x3 uMdl;\n"
+"uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
+"\n"
+"out vec4 aColour;\n"
+"out vec2 aUv;\n"
+"out vec3 aNorm;\n"
+"out vec3 aCo;\n"
+"out vec3 aWorldCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
+" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
+" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+" vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+" gl_Position = vproj0;\n"
+" aWorldCo = world_pos0;\n"
+" aColour = a_colour;\n"
+" aUv = a_uv;\n"
+" aNorm = normalize( mat3(uMdl) * a_norm );\n"
+" aCo = a_co;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/model_sky_space.fs",
+.static_src =
+"uniform sampler2D uTexGarbage;\n"
+"\n"
+"in vec4 aColour;\n"
+"in vec2 aUv;\n"
+"in vec3 aNorm;\n"
+"in vec3 aCo;\n"
+"in vec3 aWorldCo;\n"
+"\n"
+"// Spooky!\n"
+"const vec3 uCamera = vec3(0.0);\n"
+"\n"
+"#line 1 1 \n"
+"// :D\n"
+"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
+"\n"
+"#line 13 0 \n"
+"#line 1 2 \n"
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
+"layout (std140) uniform ub_world_lighting\n"
+"{\n"
+" vec4 g_cube_min;\n"
+" vec4 g_cube_inv_range;\n"
+"\n"
+" vec4 g_water_plane;\n"
+" vec4 g_depth_bounds;\n"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+" vec4 g_board_0;\n"
+" vec4 g_board_1;\n"
+"\n"
+" float g_water_fog;\n"
+" float g_time;\n"
+" float g_realtime;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
+" int g_light_preview;\n"
+" int g_shadow_samples;\n"
+"\n"
+" int g_debug_indices;\n"
+" int g_debug_complexity;\n"
+"};\n"
+"\n"
+"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\n"
+"\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
+"\n"
+"const float SUN_ANGLE = 0.0001;\n"
+"const float PI = 3.14159265358979323846264;\n"
+"\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
+"\n"
+"vec3 rand33(vec3 p3)\n"
+"{\n"
+" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
+" p3 += dot(p3, p3.yxz+33.33);\n"
+" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
+"}\n"
+"\n"
+"float stars( vec3 rd, float rr, float size ){\n"
+" vec3 co = rd * rr;\n"
+"\n"
+" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
+"\n"
+" float spaces = 1.0 / rr;\n"
+" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
+" a -= mod(a, spaces) - spaces * 0.5;\n"
+"\n"
+" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
+" \n"
+" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
+" plane = plane - mod(plane, PI / count);\n"
+"\n"
+" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
+"\n"
+" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
+" float ydist = sqrt(rr * rr - level * level);\n"
+" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
+" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
+" float star = smoothstep(size, 0.0, distance(center, co));\n"
+" return star;\n"
+"}\n"
+"\n"
+"float luminance( vec3 v )\n"
+"{\n"
+" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
+"}\n"
+"\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
+"{\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
+" float sky_gradient = dir.y;\n"
+" \n"
+" /* Blend phase colours */\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
+" \n"
+" /* Add gradient */\n"
+" ambient -= sky_gradient * luminance(ambient);\n"
+" \n"
+" return ambient;\n"
+"}\n"
+"\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
+"{\n"
+" ray_dir.y = abs( ray_dir.y );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
+" \n"
+" /* Sun */\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
+" float sun_shape = pow( sun_size, 2000.0 );\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" \n"
+" float star = 0.0;\n"
+" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
+"\n"
+" if( star_blend > 0.001 ){\n"
+" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
+" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
+" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
+" }\n"
+" }\n"
+" \n"
+" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
+" return composite;\n"
+"}\n"
+"\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
+"{\n"
+" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
+"\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
+" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
+" ) * g_sun_colour.rgb * g_day_phase;\n"
+"\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
+"\n"
+"#line 44 0 \n"
+"\n"
+"float world_depth_sample( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" return texture( g_world_depth, depth_coord ).r;\n"
+"}\n"
+"\n"
+"float world_water_depth( vec3 pos )\n"
+"{\n"
+" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
+"}\n"
+"\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
+"\n"
+" float fdelta = height_sample - co.y;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
+"}\n"
+"\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
+" return 1.0;\n"
+" }\n"
+"\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\n"
+"\n"
+" float famt = 0.0;\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+"\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+"\n"
+" return 1.0 - famt;\n"
+"}\n"
+"\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
+"{\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
+"}\n"
+"\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_light( int light_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
+" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
+" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
+"\n"
+" vec3 light_delta = light_co.xyz-co;\n"
+" float dist2 = dot(light_delta,light_delta);\n"
+"\n"
+" light_delta = normalize( light_delta );\n"
+"\n"
+" float quadratic = dist2*100.0;\n"
+" float attenuation = 1.0/( 1.0 + quadratic );\n"
+" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
+"\n"
+" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
+"\n"
+" if( light_dir.w < 0.999999 ){\n"
+" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
+" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
+" }\n"
+"\n"
+" return light_colour.rgb * attenuation * falloff \n"
+" * step( g_day_phase, light_colour.w );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" uint light_count = packed_index & 0x3u;\n"
+"\n"
+" vec3 l = vec3(0.0);\n"
+"\n"
+" if( light_count >= 1u ){\n"
+" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
+" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
+" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
+"\n"
+" l += scene_calculate_light( index_0, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 2u ){\n"
+" l += scene_calculate_light( index_1, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 3u ){\n"
+" l += scene_calculate_light( index_2, halfview, co, normal );\n"
+" }\n"
+" }\n"
+" }\n"
+"\n"
+" return l;\n"
+"}\n"
+"\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
+"{\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
+"\n"
+" // Lighting\n"
+" vec3 halfview = uCamera - co;\n"
+" float fdist = length(halfview);\n"
+" halfview /= fdist;\n"
+"\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+"\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
+"\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" cube_coord = floor( cube_coord );\n"
+"\n"
+" if( g_debug_indices == 1 )\n"
+" {\n"
+" return rand33(cube_coord);\n"
+" }\n"
+"\n"
+" if( g_debug_complexity == 1 )\n"
+" {\n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
+" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
+" }\n"
+"\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
+" \n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.x,\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.y,\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" fog_colour += sun_colour;\n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
+"}\n"
+"\n"
+"#line 14 0 \n"
+"#line 1 3 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+" // Write motion vectors\n"
+" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"\n"
+" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
+"}\n"
+"\n"
+"#line 15 0 \n"
+"\n"
+"float stars1( vec3 rd, float rr, float size ){\n"
+" vec3 co = rd * rr;\n"
+"\n"
+" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
+"\n"
+" float spaces = 1.0 / rr;\n"
+" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
+" a -= mod(a, spaces) - spaces * 0.5;\n"
+"\n"
+" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
+" \n"
+" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
+" plane = plane - mod(plane, PI / count);\n"
+"\n"
+" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
+"\n"
+" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
+" float ydist = sqrt(rr * rr - level * level);\n"
+" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
+" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
+" float star = smoothstep(size, 0.0, distance(center, co));\n"
+" return star;\n"
+"}\n"
+"\n"
+"void main(){\n"
+" compute_motion_vectors();\n"
+"\n"
+" vec3 rd = -normalize(aNorm);\n"
+"\n"
+" float star = 0.0;\n"
+" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
+" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
+" star += stars( rd, 1.94 * pow( 1.64, j ), m ) * (1.0 / pow(4.0, j));\n"
+" }\n"
+"\n"
+" oColour = vec4( vec3(star*20.0), 1.0);\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_model_sky_space_uMdl;
+GLuint _uniform_model_sky_space_uPv;
+GLuint _uniform_model_sky_space_uPvmPrev;
+GLuint _uniform_model_sky_space_uTexGarbage;
+GLuint _uniform_model_sky_space_g_world_depth;
+GLuint _uniform_model_sky_space_uLightsArray;
+GLuint _uniform_model_sky_space_uLightsIndex;
+#include "shaders/model_menu.h"
+struct vg_shader _shader_model_menu = {
+ .name = "model_menu",
+ .vs =
+{
+.orig_file = "shaders/model.vs",
+.static_src =
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec3 a_norm;\n"
+"layout (location=2) in vec2 a_uv;\n"
+"layout (location=3) in vec4 a_colour;\n"
+"layout (location=4) in vec4 a_weights;\n"
+"layout (location=5) in ivec4 a_groups;\n"
+"\n"
+"#line 1 1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+" // This magically solves some artifacting errors!\n"
+" //\n"
+" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
+"\n"
+" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"\n"
+"uniform mat4x3 uMdl;\n"
+"uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
+"\n"
+"out vec4 aColour;\n"
+"out vec2 aUv;\n"
+"out vec3 aNorm;\n"
+"out vec3 aCo;\n"
+"out vec3 aWorldCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
+" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
+" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+" vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+" gl_Position = vproj0;\n"
+" aWorldCo = world_pos0;\n"
+" aColour = a_colour;\n"
+" aUv = a_uv;\n"
+" aNorm = normalize( mat3(uMdl) * a_norm );\n"
+" aCo = a_co;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/model_menu.fs",
+.static_src =
+"out vec4 FragColor;\n"
+"\n"
+"uniform sampler2D uTexMain;\n"
+"uniform vec4 uColour;\n"
+"\n"
+"in vec4 aColour;\n"
+"in vec2 aUv;\n"
+"in vec3 aNorm;\n"
+"in vec3 aCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec4 diffuse = texture( uTexMain, aUv );\n"
+"\n"
+" if( diffuse.a < 0.5 )\n"
+" discard;\n"
+"\n"
+" FragColor = vec4( diffuse.rgb, 1.0 ) * uColour;\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_model_menu_uMdl;
+GLuint _uniform_model_menu_uPv;
+GLuint _uniform_model_menu_uPvmPrev;
+GLuint _uniform_model_menu_uTexMain;
+GLuint _uniform_model_menu_uColour;
+#include "shaders/model_character_view.h"
+struct vg_shader _shader_model_character_view = {
+ .name = "model_character_view",
+ .vs =
+{
+.orig_file = "shaders/model_skinned.vs",
+.static_src =
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec3 a_norm;\n"
+"layout (location=2) in vec2 a_uv;\n"
+"layout (location=3) in vec4 a_colour;\n"
+"layout (location=4) in vec4 a_weights;\n"
+"layout (location=5) in ivec4 a_groups;\n"
+"\n"
+"#line 1 1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+" // This magically solves some artifacting errors!\n"
+" //\n"
+" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
+"\n"
+" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"\n"
+"uniform mat4 uPv;\n"
+"uniform mat4x3 uTransforms[32];\n"
+"\n"
+"out vec4 aColour;\n"
+"out vec2 aUv;\n"
+"out vec3 aNorm;\n"
+"out vec3 aCo;\n"
+"out vec3 aWorldCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec4 co_local = vec4( a_co, 1.0 );\n"
+" vec3 co0 = uTransforms[ a_groups[0] ] * co_local;\n"
+" vec3 co1 = uTransforms[ a_groups[1] ] * co_local;\n"
+" vec3 co2 = uTransforms[ a_groups[2] ] * co_local;\n"
+" vec3 n0 = mat3(uTransforms[ a_groups[0] ]) * a_norm;\n"
+" vec3 n1 = mat3(uTransforms[ a_groups[1] ]) * a_norm;\n"
+" vec3 n2 = mat3(uTransforms[ a_groups[2] ]) * a_norm;\n"
+"\n"
+" vec3 world_pos = co0*a_weights[0] + co1*a_weights[1] + co2*a_weights[2];\n"
+" vec3 world_normal = n0*a_weights[0] + n1*a_weights[1] + n2*a_weights[2];\n"
+" \n"
+" gl_Position = uPv * vec4( world_pos, 1.0 );\n"
+" aColour = a_colour;\n"
+" aUv = a_uv;\n"
+" aNorm = world_normal;\n"
+" aCo = a_co;\n"
+" aWorldCo = world_pos;\n"
+"\n"
+" // TODO: motion vectors\n"
+" aMotionVec0 = vec3(1.0);\n"
+" aMotionVec1 = vec3(1.0);\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/model_character_view.fs",
+.static_src =
+"uniform sampler2D uTexMain;\n"
+"uniform vec3 uCamera;\n"
+"\n"
+"in vec4 aColour;\n"
+"in vec2 aUv;\n"
+"in vec3 aNorm;\n"
+"in vec3 aCo;\n"
+"in vec3 aWorldCo;\n"
+"\n"
+"#line 1 1 \n"
+"// :D\n"
+"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
+"\n"
+"#line 11 0 \n"
+"#line 1 2 \n"
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
+"layout (std140) uniform ub_world_lighting\n"
+"{\n"
+" vec4 g_cube_min;\n"
+" vec4 g_cube_inv_range;\n"
+"\n"
+" vec4 g_water_plane;\n"
+" vec4 g_depth_bounds;\n"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+" vec4 g_board_0;\n"
+" vec4 g_board_1;\n"
+"\n"
+" float g_water_fog;\n"
+" float g_time;\n"
+" float g_realtime;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
+" int g_light_preview;\n"
+" int g_shadow_samples;\n"
+"\n"
+" int g_debug_indices;\n"
+" int g_debug_complexity;\n"
+"};\n"
+"\n"
+"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\n"
+"\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
+"\n"
+"const float SUN_ANGLE = 0.0001;\n"
+"const float PI = 3.14159265358979323846264;\n"
+"\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
+"\n"
+"vec3 rand33(vec3 p3)\n"
+"{\n"
+" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
+" p3 += dot(p3, p3.yxz+33.33);\n"
+" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
+"}\n"
+"\n"
+"float stars( vec3 rd, float rr, float size ){\n"
+" vec3 co = rd * rr;\n"
+"\n"
+" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
+"\n"
+" float spaces = 1.0 / rr;\n"
+" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
+" a -= mod(a, spaces) - spaces * 0.5;\n"
+"\n"
+" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
+" \n"
+" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
+" plane = plane - mod(plane, PI / count);\n"
+"\n"
+" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
+"\n"
+" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
+" float ydist = sqrt(rr * rr - level * level);\n"
+" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
+" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
+" float star = smoothstep(size, 0.0, distance(center, co));\n"
+" return star;\n"
+"}\n"
+"\n"
+"float luminance( vec3 v )\n"
+"{\n"
+" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
+"}\n"
+"\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
+"{\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
+" float sky_gradient = dir.y;\n"
+" \n"
+" /* Blend phase colours */\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
+" \n"
+" /* Add gradient */\n"
+" ambient -= sky_gradient * luminance(ambient);\n"
+" \n"
+" return ambient;\n"
+"}\n"
+"\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
+"{\n"
+" ray_dir.y = abs( ray_dir.y );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
+" \n"
+" /* Sun */\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
+" float sun_shape = pow( sun_size, 2000.0 );\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" \n"
+" float star = 0.0;\n"
+" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
+"\n"
+" if( star_blend > 0.001 ){\n"
+" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
+" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
+" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
+" }\n"
+" }\n"
+" \n"
+" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
+" return composite;\n"
+"}\n"
+"\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
+"{\n"
+" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
+"\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
+" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
+" ) * g_sun_colour.rgb * g_day_phase;\n"
+"\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
+"\n"
+"#line 44 0 \n"
+"\n"
+"float world_depth_sample( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" return texture( g_world_depth, depth_coord ).r;\n"
+"}\n"
+"\n"
+"float world_water_depth( vec3 pos )\n"
+"{\n"
+" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
+"}\n"
+"\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
+"\n"
+" float fdelta = height_sample - co.y;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
+"}\n"
+"\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
+" return 1.0;\n"
+" }\n"
+"\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\n"
+"\n"
+" float famt = 0.0;\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+"\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+"\n"
+" return 1.0 - famt;\n"
+"}\n"
+"\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
+"{\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
+"}\n"
+"\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_light( int light_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
+" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
+" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
+"\n"
+" vec3 light_delta = light_co.xyz-co;\n"
+" float dist2 = dot(light_delta,light_delta);\n"
+"\n"
+" light_delta = normalize( light_delta );\n"
+"\n"
+" float quadratic = dist2*100.0;\n"
+" float attenuation = 1.0/( 1.0 + quadratic );\n"
+" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
+"\n"
+" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
+"\n"
+" if( light_dir.w < 0.999999 ){\n"
+" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
+" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
+" }\n"
+"\n"
+" return light_colour.rgb * attenuation * falloff \n"
+" * step( g_day_phase, light_colour.w );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" uint light_count = packed_index & 0x3u;\n"
+"\n"
+" vec3 l = vec3(0.0);\n"
+"\n"
+" if( light_count >= 1u ){\n"
+" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
+" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
+" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
+"\n"
+" l += scene_calculate_light( index_0, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 2u ){\n"
+" l += scene_calculate_light( index_1, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 3u ){\n"
+" l += scene_calculate_light( index_2, halfview, co, normal );\n"
+" }\n"
+" }\n"
+" }\n"
+"\n"
+" return l;\n"
+"}\n"
+"\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
+"{\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
+"\n"
+" // Lighting\n"
+" vec3 halfview = uCamera - co;\n"
+" float fdist = length(halfview);\n"
+" halfview /= fdist;\n"
+"\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+"\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
+"\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" cube_coord = floor( cube_coord );\n"
+"\n"
+" if( g_debug_indices == 1 )\n"
+" {\n"
+" return rand33(cube_coord);\n"
+" }\n"
+"\n"
+" if( g_debug_complexity == 1 )\n"
+" {\n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
+" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
+" }\n"
+"\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
+" \n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.x,\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.y,\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" fog_colour += sun_colour;\n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
+"}\n"
+"\n"
+"#line 12 0 \n"
+"#line 1 3 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+" // Write motion vectors\n"
+" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"\n"
+" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
+"}\n"
+"\n"
+"#line 13 0 \n"
+"#line 1 4 \n"
+"uniform sampler2D uTexSceneDepth;\n"
+"uniform vec3 uInverseRatioDepth;\n"
+"uniform vec3 uInverseRatioMain;\n"
+"uniform bool uDepthCompare;\n"
+"\n"
+"float linear_depth( float depth, float near, float far ) {\n"
+" float z = depth * 2.0 - 1.0;\n"
+" return (2.0 * near * far) / (far + near - z * (far - near)); \n"
+"}\n"
+"\n"
+"void depth_compare_dither(){\n"
+" if( uDepthCompare ){\n"
+" vec2 back_coord = gl_FragCoord.xy * uInverseRatioMain.xy \n"
+" * uInverseRatioDepth.xy;\n"
+" float back_depth = texture( uTexSceneDepth, back_coord ).r;\n"
+" float front_depth = gl_FragCoord.z/gl_FragCoord.w;\n"
+"\n"
+" back_depth = linear_depth( back_depth, 0.1, 2100.0 );\n"
+" float diff = back_depth - front_depth;\n"
+"\n"
+" vec2 ssuv = gl_FragCoord.xy;\n"
+" vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), ssuv) );\n"
+" float dither = fract( vDither.g / 71.0 ) - 0.5;\n"
+"\n"
+" if( step(0.0,diff)+dither<0.3 )\n"
+" discard;\n"
+" }\n"
+"}\n"
+"\n"
+"#line 14 0 \n"
+"\n"
+"vec3 character_clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
+"{\n"
+" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
+"\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+"\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max(0.0, dot(normal,g_sun_dir.xyz)*0.5+0.5) \n"
+" * g_sun_colour.rgb * g_day_phase;\n"
+"\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
+"\n"
+"vec3 character_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
+"{\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
+"\n"
+" // Lighting\n"
+" vec3 halfview = uCamera - co;\n"
+" float fdist = length(halfview);\n"
+" halfview /= fdist;\n"
+"\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+"\n"
+" vec3 total_light = character_clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
+"\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" cube_coord = floor( cube_coord );\n"
+"\n"
+" if( g_debug_indices == 1 )\n"
+" {\n"
+" return rand33(cube_coord);\n"
+" }\n"
+"\n"
+" if( g_debug_complexity == 1 )\n"
+" {\n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
+" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
+" }\n"
+"\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
+" \n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.x,\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.y,\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" fog_colour += sun_colour;\n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
+"}\n"
+"\n"
+"void main(){\n"
+" depth_compare_dither();\n"
+" compute_motion_vectors();\n"
+"\n"
+" vec3 qnorm = aNorm;\n"
+" vec3 diffuse = texture( uTexMain, aUv ).rgb;\n"
+" vec3 composite = character_compute_lighting( diffuse, qnorm, aWorldCo, 1.0 );\n"
+"\n"
+" float dist = distance( aWorldCo, uCamera ) - 0.08;\n"
+" float opacity = clamp( dist*dist, 0.0, 1.0 );\n"
+"\n"
+" oColour = vec4( composite, opacity );\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_model_character_view_uPv;
+GLuint _uniform_model_character_view_uTransforms;
+GLuint _uniform_model_character_view_uTexMain;
+GLuint _uniform_model_character_view_uCamera;
+GLuint _uniform_model_character_view_g_world_depth;
+GLuint _uniform_model_character_view_uLightsArray;
+GLuint _uniform_model_character_view_uLightsIndex;
+GLuint _uniform_model_character_view_uTexSceneDepth;
+GLuint _uniform_model_character_view_uInverseRatioDepth;
+GLuint _uniform_model_character_view_uInverseRatioMain;
+GLuint _uniform_model_character_view_uDepthCompare;
+#include "shaders/model_board_view.h"
+struct vg_shader _shader_model_board_view = {
+ .name = "model_board_view",
+ .vs =
+{
+.orig_file = "shaders/model.vs",
+.static_src =
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec3 a_norm;\n"
+"layout (location=2) in vec2 a_uv;\n"
+"layout (location=3) in vec4 a_colour;\n"
+"layout (location=4) in vec4 a_weights;\n"
+"layout (location=5) in ivec4 a_groups;\n"
+"\n"
+"#line 1 1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+" // This magically solves some artifacting errors!\n"
+" //\n"
+" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
+"\n"
+" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"\n"
+"uniform mat4x3 uMdl;\n"
+"uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
+"\n"
+"out vec4 aColour;\n"
+"out vec2 aUv;\n"
+"out vec3 aNorm;\n"
+"out vec3 aCo;\n"
+"out vec3 aWorldCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
+" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
+" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+" vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+" gl_Position = vproj0;\n"
+" aWorldCo = world_pos0;\n"
+" aColour = a_colour;\n"
+" aUv = a_uv;\n"
+" aNorm = normalize( mat3(uMdl) * a_norm );\n"
+" aCo = a_co;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/model_character_view.fs",
+.static_src =
+"uniform sampler2D uTexMain;\n"
+"uniform vec3 uCamera;\n"
+"\n"
+"in vec4 aColour;\n"
+"in vec2 aUv;\n"
+"in vec3 aNorm;\n"
+"in vec3 aCo;\n"
+"in vec3 aWorldCo;\n"
+"\n"
+"#line 1 1 \n"
+"// :D\n"
+"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
+"\n"
+"#line 11 0 \n"
+"#line 1 2 \n"
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
+"layout (std140) uniform ub_world_lighting\n"
+"{\n"
+" vec4 g_cube_min;\n"
+" vec4 g_cube_inv_range;\n"
+"\n"
+" vec4 g_water_plane;\n"
+" vec4 g_depth_bounds;\n"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+" vec4 g_board_0;\n"
+" vec4 g_board_1;\n"
+"\n"
+" float g_water_fog;\n"
+" float g_time;\n"
+" float g_realtime;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
+" int g_light_preview;\n"
+" int g_shadow_samples;\n"
+"\n"
+" int g_debug_indices;\n"
+" int g_debug_complexity;\n"
+"};\n"
+"\n"
+"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\n"
+"\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
+"\n"
+"const float SUN_ANGLE = 0.0001;\n"
+"const float PI = 3.14159265358979323846264;\n"
+"\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
+"\n"
+"vec3 rand33(vec3 p3)\n"
+"{\n"
+" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
+" p3 += dot(p3, p3.yxz+33.33);\n"
+" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
+"}\n"
+"\n"
+"float stars( vec3 rd, float rr, float size ){\n"
+" vec3 co = rd * rr;\n"
+"\n"
+" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
+"\n"
+" float spaces = 1.0 / rr;\n"
+" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
+" a -= mod(a, spaces) - spaces * 0.5;\n"
+"\n"
+" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
+" \n"
+" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
+" plane = plane - mod(plane, PI / count);\n"
+"\n"
+" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
+"\n"
+" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
+" float ydist = sqrt(rr * rr - level * level);\n"
+" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
+" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
+" float star = smoothstep(size, 0.0, distance(center, co));\n"
+" return star;\n"
+"}\n"
+"\n"
+"float luminance( vec3 v )\n"
+"{\n"
+" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
+"}\n"
+"\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
+"{\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
+" float sky_gradient = dir.y;\n"
+" \n"
+" /* Blend phase colours */\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
+" \n"
+" /* Add gradient */\n"
+" ambient -= sky_gradient * luminance(ambient);\n"
+" \n"
+" return ambient;\n"
+"}\n"
+"\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
+"{\n"
+" ray_dir.y = abs( ray_dir.y );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
+" \n"
+" /* Sun */\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
+" float sun_shape = pow( sun_size, 2000.0 );\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" \n"
+" float star = 0.0;\n"
+" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
+"\n"
+" if( star_blend > 0.001 ){\n"
+" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
+" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
+" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
+" }\n"
+" }\n"
+" \n"
+" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
+" return composite;\n"
+"}\n"
+"\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
+"{\n"
+" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
+"\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
+" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
+" ) * g_sun_colour.rgb * g_day_phase;\n"
+"\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
+"\n"
+"#line 44 0 \n"
+"\n"
+"float world_depth_sample( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" return texture( g_world_depth, depth_coord ).r;\n"
+"}\n"
+"\n"
+"float world_water_depth( vec3 pos )\n"
+"{\n"
+" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
+"}\n"
+"\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
+"\n"
+" float fdelta = height_sample - co.y;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
+"}\n"
+"\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
+" return 1.0;\n"
+" }\n"
+"\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\n"
+"\n"
+" float famt = 0.0;\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+"\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+"\n"
+" return 1.0 - famt;\n"
+"}\n"
+"\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
+"{\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
+"}\n"
+"\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_light( int light_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
+" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
+" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
+"\n"
+" vec3 light_delta = light_co.xyz-co;\n"
+" float dist2 = dot(light_delta,light_delta);\n"
+"\n"
+" light_delta = normalize( light_delta );\n"
+"\n"
+" float quadratic = dist2*100.0;\n"
+" float attenuation = 1.0/( 1.0 + quadratic );\n"
+" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
+"\n"
+" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
+"\n"
+" if( light_dir.w < 0.999999 ){\n"
+" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
+" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
+" }\n"
+"\n"
+" return light_colour.rgb * attenuation * falloff \n"
+" * step( g_day_phase, light_colour.w );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" uint light_count = packed_index & 0x3u;\n"
+"\n"
+" vec3 l = vec3(0.0);\n"
+"\n"
+" if( light_count >= 1u ){\n"
+" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
+" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
+" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
+"\n"
+" l += scene_calculate_light( index_0, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 2u ){\n"
+" l += scene_calculate_light( index_1, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 3u ){\n"
+" l += scene_calculate_light( index_2, halfview, co, normal );\n"
+" }\n"
+" }\n"
+" }\n"
+"\n"
+" return l;\n"
+"}\n"
+"\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
+"{\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
+"\n"
+" // Lighting\n"
+" vec3 halfview = uCamera - co;\n"
+" float fdist = length(halfview);\n"
+" halfview /= fdist;\n"
+"\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+"\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
+"\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" cube_coord = floor( cube_coord );\n"
+"\n"
+" if( g_debug_indices == 1 )\n"
+" {\n"
+" return rand33(cube_coord);\n"
+" }\n"
+"\n"
+" if( g_debug_complexity == 1 )\n"
+" {\n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
+" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
+" }\n"
+"\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
+" \n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.x,\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.y,\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" fog_colour += sun_colour;\n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
+"}\n"
+"\n"
+"#line 12 0 \n"
+"#line 1 3 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+" // Write motion vectors\n"
+" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"\n"
+" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
+"}\n"
+"\n"
+"#line 13 0 \n"
+"#line 1 4 \n"
+"uniform sampler2D uTexSceneDepth;\n"
+"uniform vec3 uInverseRatioDepth;\n"
+"uniform vec3 uInverseRatioMain;\n"
+"uniform bool uDepthCompare;\n"
+"\n"
+"float linear_depth( float depth, float near, float far ) {\n"
+" float z = depth * 2.0 - 1.0;\n"
+" return (2.0 * near * far) / (far + near - z * (far - near)); \n"
+"}\n"
+"\n"
+"void depth_compare_dither(){\n"
+" if( uDepthCompare ){\n"
+" vec2 back_coord = gl_FragCoord.xy * uInverseRatioMain.xy \n"
+" * uInverseRatioDepth.xy;\n"
+" float back_depth = texture( uTexSceneDepth, back_coord ).r;\n"
+" float front_depth = gl_FragCoord.z/gl_FragCoord.w;\n"
+"\n"
+" back_depth = linear_depth( back_depth, 0.1, 2100.0 );\n"
+" float diff = back_depth - front_depth;\n"
+"\n"
+" vec2 ssuv = gl_FragCoord.xy;\n"
+" vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), ssuv) );\n"
+" float dither = fract( vDither.g / 71.0 ) - 0.5;\n"
+"\n"
+" if( step(0.0,diff)+dither<0.3 )\n"
+" discard;\n"
+" }\n"
+"}\n"
+"\n"
+"#line 14 0 \n"
+"\n"
+"vec3 character_clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
+"{\n"
+" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
+"\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+"\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max(0.0, dot(normal,g_sun_dir.xyz)*0.5+0.5) \n"
+" * g_sun_colour.rgb * g_day_phase;\n"
+"\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
+"\n"
+"vec3 character_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
+"{\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
+"\n"
+" // Lighting\n"
+" vec3 halfview = uCamera - co;\n"
+" float fdist = length(halfview);\n"
+" halfview /= fdist;\n"
+"\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+"\n"
+" vec3 total_light = character_clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
+"\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" cube_coord = floor( cube_coord );\n"
+"\n"
+" if( g_debug_indices == 1 )\n"
+" {\n"
+" return rand33(cube_coord);\n"
+" }\n"
+"\n"
+" if( g_debug_complexity == 1 )\n"
+" {\n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
+" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
+" }\n"
+"\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
+" \n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.x,\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.y,\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" fog_colour += sun_colour;\n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
+"}\n"
+"\n"
+"void main(){\n"
+" depth_compare_dither();\n"
+" compute_motion_vectors();\n"
+"\n"
+" vec3 qnorm = aNorm;\n"
+" vec3 diffuse = texture( uTexMain, aUv ).rgb;\n"
+" vec3 composite = character_compute_lighting( diffuse, qnorm, aWorldCo, 1.0 );\n"
+"\n"
+" float dist = distance( aWorldCo, uCamera ) - 0.08;\n"
+" float opacity = clamp( dist*dist, 0.0, 1.0 );\n"
+"\n"
+" oColour = vec4( composite, opacity );\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_model_board_view_uMdl;
+GLuint _uniform_model_board_view_uPv;
+GLuint _uniform_model_board_view_uPvmPrev;
+GLuint _uniform_model_board_view_uTexMain;
+GLuint _uniform_model_board_view_uCamera;
+GLuint _uniform_model_board_view_g_world_depth;
+GLuint _uniform_model_board_view_uLightsArray;
+GLuint _uniform_model_board_view_uLightsIndex;
+GLuint _uniform_model_board_view_uTexSceneDepth;
+GLuint _uniform_model_board_view_uInverseRatioDepth;
+GLuint _uniform_model_board_view_uInverseRatioMain;
+GLuint _uniform_model_board_view_uDepthCompare;
+#include "shaders/model_entity.h"
+struct vg_shader _shader_model_entity = {
+ .name = "model_entity",
+ .vs =
+{
+.orig_file = "shaders/model.vs",
+.static_src =
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec3 a_norm;\n"
+"layout (location=2) in vec2 a_uv;\n"
+"layout (location=3) in vec4 a_colour;\n"
+"layout (location=4) in vec4 a_weights;\n"
+"layout (location=5) in ivec4 a_groups;\n"
+"\n"
+"#line 1 1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+" // This magically solves some artifacting errors!\n"
+" //\n"
+" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
+"\n"
+" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"\n"
+"uniform mat4x3 uMdl;\n"
+"uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
+"\n"
+"out vec4 aColour;\n"
+"out vec2 aUv;\n"
+"out vec3 aNorm;\n"
+"out vec3 aCo;\n"
+"out vec3 aWorldCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
+" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
+" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+" vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+" gl_Position = vproj0;\n"
+" aWorldCo = world_pos0;\n"
+" aColour = a_colour;\n"
+" aUv = a_uv;\n"
+" aNorm = normalize( mat3(uMdl) * a_norm );\n"
+" aCo = a_co;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/model_entity.fs",
+.static_src =
+"uniform sampler2D uTexMain;\n"
+"uniform vec3 uCamera;\n"
+"\n"
+"in vec4 aColour;\n"
+"in vec2 aUv;\n"
+"in vec3 aNorm;\n"
+"in vec3 aCo;\n"
+"in vec3 aWorldCo;\n"
+"\n"
+"#line 1 1 \n"
+"// :D\n"
+"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
+"\n"
+"#line 11 0 \n"
+"#line 1 2 \n"
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
+"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
+"layout (std140) uniform ub_world_lighting\n"
+"{\n"
+" vec4 g_cube_min;\n"
+" vec4 g_cube_inv_range;\n"
+"\n"
+" vec4 g_water_plane;\n"
+" vec4 g_depth_bounds;\n"
+"\n"
+" vec4 g_daysky_colour;\n"
+" vec4 g_nightsky_colour;\n"
+" vec4 g_sunset_colour;\n"
+" vec4 g_ambient_colour;\n"
+" vec4 g_sunset_ambient;\n"
+" vec4 g_sun_colour;\n"
+" vec4 g_sun_dir;\n"
+" vec4 g_board_0;\n"
+" vec4 g_board_1;\n"
+"\n"
+" float g_water_fog;\n"
+" float g_time;\n"
+" float g_realtime;\n"
+" float g_shadow_length;\n"
+" float g_shadow_spread;\n"
+"\n"
+" float g_time_of_day;\n"
+" float g_day_phase;\n"
+" float g_sunset_phase;\n"
+"\n"
+" int g_light_preview;\n"
+" int g_shadow_samples;\n"
+"\n"
+" int g_debug_indices;\n"
+" int g_debug_complexity;\n"
+"};\n"
+"\n"
+"uniform sampler2D g_world_depth;\n"
+"uniform samplerBuffer uLightsArray;\n"
+"uniform usampler3D uLightsIndex;\n"
+"\n"
+"#line 1 1 \n"
+"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
+"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
+"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
+"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
+"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
+"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
+"\n"
+"const float SUN_ANGLE = 0.0001;\n"
+"const float PI = 3.14159265358979323846264;\n"
+"\n"
+"//struct world_info\n"
+"//{\n"
+"// float time,\n"
+"// time_of_day,\n"
+"// day_phase,\n"
+"// sunset_phase;\n"
+"// \n"
+"// vec3 sun_dir;\n"
+"//};\n"
+"\n"
+"vec3 rand33(vec3 p3)\n"
+"{\n"
+" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
+" p3 += dot(p3, p3.yxz+33.33);\n"
+" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
+"}\n"
+"\n"
+"float stars( vec3 rd, float rr, float size ){\n"
+" vec3 co = rd * rr;\n"
+"\n"
+" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
+"\n"
+" float spaces = 1.0 / rr;\n"
+" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
+" a -= mod(a, spaces) - spaces * 0.5;\n"
+"\n"
+" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
+" \n"
+" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
+" plane = plane - mod(plane, PI / count);\n"
+"\n"
+" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
+"\n"
+" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
+" float ydist = sqrt(rr * rr - level * level);\n"
+" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
+" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
+" float star = smoothstep(size, 0.0, distance(center, co));\n"
+" return star;\n"
+"}\n"
+"\n"
+"float luminance( vec3 v )\n"
+"{\n"
+" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
+"}\n"
+"\n"
+"vec3 clearskies_ambient( vec3 dir )\n"
+"{\n"
+" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
+" float sky_gradient = dir.y;\n"
+" \n"
+" /* Blend phase colours */\n"
+" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
+" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
+" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
+" \n"
+" /* Add gradient */\n"
+" ambient -= sky_gradient * luminance(ambient);\n"
+" \n"
+" return ambient;\n"
+"}\n"
+"\n"
+"vec3 clearskies_sky( vec3 ray_dir )\n"
+"{\n"
+" ray_dir.y = abs( ray_dir.y );\n"
+" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
+" \n"
+" /* Sun */\n"
+" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
+" float sun_shape = pow( sun_size, 2000.0 );\n"
+" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" \n"
+" float star = 0.0;\n"
+" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
+"\n"
+" if( star_blend > 0.001 ){\n"
+" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
+" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
+" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
+" }\n"
+" }\n"
+" \n"
+" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
+" return composite;\n"
+"}\n"
+"\n"
+"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
+"{\n"
+" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
+"\n"
+" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
+" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
+" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
+" ) * g_sun_colour.rgb * g_day_phase;\n"
+"\n"
+" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
+" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
+" g_sunset_phase );\n"
+"\n"
+" return ambient + (light_sun + sky_reflection) * shadow;\n"
+"}\n"
+"\n"
+"#line 44 0 \n"
+"\n"
+"float world_depth_sample( vec3 pos )\n"
+"{\n"
+" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
+" return texture( g_world_depth, depth_coord ).r;\n"
+"}\n"
+"\n"
+"float world_water_depth( vec3 pos )\n"
+"{\n"
+" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
+" return world_depth_sample( pos ) - ref_depth;\n"
+"}\n"
+"\n"
+"float shadow_sample( vec3 co ){\n"
+" float height_sample = world_depth_sample( co );\n"
+"\n"
+" float fdelta = height_sample - co.y;\n"
+" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
+"}\n"
+"\n"
+"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
+" if( g_shadow_samples == 0 ){\n"
+" return 1.0;\n"
+" }\n"
+"\n"
+" float fspread = g_shadow_spread;\n"
+" float flength = g_shadow_length;\n"
+"\n"
+" float famt = 0.0;\n"
+" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
+" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
+" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
+"\n"
+" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
+" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
+"\n"
+" return 1.0 - famt;\n"
+"}\n"
+"\n"
+"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
+"{\n"
+" vec3 specdir = reflect( -dir, wnormal );\n"
+" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
+"}\n"
+"\n"
+"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
+" float dist = pow(fdist*0.0010,0.78);\n"
+" return mix( vfrag, colour, min( 1.0, dist ) );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_light( int light_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
+" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
+" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
+"\n"
+" vec3 light_delta = light_co.xyz-co;\n"
+" float dist2 = dot(light_delta,light_delta);\n"
+"\n"
+" light_delta = normalize( light_delta );\n"
+"\n"
+" float quadratic = dist2*100.0;\n"
+" float attenuation = 1.0/( 1.0 + quadratic );\n"
+" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
+"\n"
+" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
+"\n"
+" if( light_dir.w < 0.999999 ){\n"
+" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
+" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
+" }\n"
+"\n"
+" return light_colour.rgb * attenuation * falloff \n"
+" * step( g_day_phase, light_colour.w );\n"
+"}\n"
+"\n"
+"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
+" vec3 halfview, vec3 co, vec3 normal )\n"
+"{\n"
+" uint light_count = packed_index & 0x3u;\n"
+"\n"
+" vec3 l = vec3(0.0);\n"
+"\n"
+" if( light_count >= 1u ){\n"
+" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
+" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
+" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
+"\n"
+" l += scene_calculate_light( index_0, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 2u ){\n"
+" l += scene_calculate_light( index_1, halfview, co, normal );\n"
+"\n"
+" if( light_count >= 3u ){\n"
+" l += scene_calculate_light( index_2, halfview, co, normal );\n"
+" }\n"
+" }\n"
+" }\n"
+"\n"
+" return l;\n"
+"}\n"
+"\n"
+"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
+" float light_mask )\n"
+"{\n"
+" if( g_light_preview == 1 )\n"
+" diffuse = vec3(0.75);\n"
+"\n"
+" // Lighting\n"
+" vec3 halfview = uCamera - co;\n"
+" float fdist = length(halfview);\n"
+" halfview /= fdist;\n"
+"\n"
+" float world_shadow = newlight_compute_sun_shadow( \n"
+" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
+"\n"
+" vec3 total_light = clearskies_lighting( \n"
+" normal, min( light_mask, world_shadow ), halfview );\n"
+"\n"
+" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
+" cube_coord = floor( cube_coord );\n"
+"\n"
+" if( g_debug_indices == 1 )\n"
+" {\n"
+" return rand33(cube_coord);\n"
+" }\n"
+"\n"
+" if( g_debug_complexity == 1 )\n"
+" {\n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
+" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
+" }\n"
+"\n"
+" // FIXME: this coord should absolutely must be clamped!\n"
+" \n"
+" ivec3 coord = ivec3( cube_coord );\n"
+" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
+"\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.x,\n"
+" halfview, co, normal ) \n"
+" * light_mask;\n"
+" total_light += \n"
+" scene_calculate_packed_light_patch( index_sample.y,\n"
+" halfview, co, normal )\n"
+" * light_mask;\n"
+"\n"
+" // Take a section of the sky function to give us a matching fog colour\n"
+"\n"
+" vec3 fog_colour = clearskies_ambient( -halfview );\n"
+" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
+" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
+" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
+" \n"
+" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
+" sun_colour *= sun_shape;\n"
+"\n"
+" fog_colour += sun_colour;\n"
+" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
+"}\n"
+"\n"
+"#line 12 0 \n"
+"#line 1 3 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+" // Write motion vectors\n"
+" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"\n"
+" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
+"}\n"
+"\n"
+"#line 13 0 \n"
+"\n"
+"void main()\n"
+"{\n"
+" compute_motion_vectors();\n"
+"\n"
+" vec3 qnorm = normalize(floor(aNorm*2.0)*0.5) + vec3(0.001,0.0,0.0);\n"
+" vec3 diffuse = texture( uTexMain, aUv ).rgb;\n"
+" vec3 composite = world_compute_lighting( diffuse, qnorm, aWorldCo, 1.0 );\n"
+"\n"
+" oColour = vec4( composite, 1.0 );\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_model_entity_uMdl;
+GLuint _uniform_model_entity_uPv;
+GLuint _uniform_model_entity_uPvmPrev;
+GLuint _uniform_model_entity_uTexMain;
+GLuint _uniform_model_entity_uCamera;
+GLuint _uniform_model_entity_g_world_depth;
+GLuint _uniform_model_entity_uLightsArray;
+GLuint _uniform_model_entity_uLightsIndex;
+#include "shaders/model_gate.h"
+struct vg_shader _shader_model_gate = {
+ .name = "model_gate",
+ .vs =
+{
+.orig_file = "shaders/model.vs",
+.static_src =
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec3 a_norm;\n"
+"layout (location=2) in vec2 a_uv;\n"
+"layout (location=3) in vec4 a_colour;\n"
+"layout (location=4) in vec4 a_weights;\n"
+"layout (location=5) in ivec4 a_groups;\n"
+"\n"
+"#line 1 1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+" // This magically solves some artifacting errors!\n"
+" //\n"
+" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
+"\n"
+" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"\n"
+"uniform mat4x3 uMdl;\n"
+"uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
+"\n"
+"out vec4 aColour;\n"
+"out vec2 aUv;\n"
+"out vec3 aNorm;\n"
+"out vec3 aCo;\n"
+"out vec3 aWorldCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
+" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
+" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+" vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+" gl_Position = vproj0;\n"
+" aWorldCo = world_pos0;\n"
+" aColour = a_colour;\n"
+" aUv = a_uv;\n"
+" aNorm = normalize( mat3(uMdl) * a_norm );\n"
+" aCo = a_co;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/model_gate_lq.fs",
+.static_src =
+"out vec4 FragColor;\n"
+"\n"
+"uniform float uTime;\n"
+"uniform vec3 uCam;\n"
+"uniform vec2 uInvRes;\n"
+"uniform vec4 uColour;\n"
+"\n"
+"in vec3 aNorm;\n"
+"in vec2 aUv;\n"
+"in vec3 aCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec2 ssuv = gl_FragCoord.xy;\n"
+" float opacity = 1.0-smoothstep(0.0,1.0,aUv.y+uColour.a);\n"
+" \n"
+" vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), ssuv) );\n"
+" float dither = fract( vDither.g / 71.0 ) - 0.5;\n"
+"\n"
+" if( opacity+dither<0.5 )\n"
+" discard;\n"
+"\n"
+" FragColor = uColour;\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_model_gate_uMdl;
+GLuint _uniform_model_gate_uPv;
+GLuint _uniform_model_gate_uPvmPrev;
+GLuint _uniform_model_gate_uTime;
+GLuint _uniform_model_gate_uCam;
+GLuint _uniform_model_gate_uInvRes;
+GLuint _uniform_model_gate_uColour;
+#include "shaders/model_gate_unlinked.h"
+struct vg_shader _shader_model_gate_unlinked = {
+ .name = "model_gate_unlinked",
+ .vs =
+{
+.orig_file = "shaders/model.vs",
+.static_src =
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec3 a_norm;\n"
+"layout (location=2) in vec2 a_uv;\n"
+"layout (location=3) in vec4 a_colour;\n"
+"layout (location=4) in vec4 a_weights;\n"
+"layout (location=5) in ivec4 a_groups;\n"
+"\n"
+"#line 1 1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+" // This magically solves some artifacting errors!\n"
+" //\n"
+" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
+"\n"
+" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line 9 0 \n"
+"\n"
+"uniform mat4x3 uMdl;\n"
+"uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
+"\n"
+"out vec4 aColour;\n"
+"out vec2 aUv;\n"
+"out vec3 aNorm;\n"
+"out vec3 aCo;\n"
+"out vec3 aWorldCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
+" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
+" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
+"\n"
+" vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+" gl_Position = vproj0;\n"
+" aWorldCo = world_pos0;\n"
+" aColour = a_colour;\n"
+" aUv = a_uv;\n"
+" aNorm = normalize( mat3(uMdl) * a_norm );\n"
+" aCo = a_co;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/model_gate_unlinked.fs",
+.static_src =
+"out vec4 FragColor;\n"
+"\n"
+"uniform float uTime;\n"
+"uniform vec3 uCam;\n"
+"uniform vec4 uColour;\n"
+"\n"
+"in vec3 aNorm;\n"
+"in vec2 aUv;\n"
+"in vec3 aCo;\n"
+"\n"
+"#line 1 1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+" // Write motion vectors\n"
+" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"\n"
+" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
+"}\n"
+"\n"
+"#line 12 0 \n"
+"\n"
+"const int NOISE_LOOP = 3;\n"
+"vec3 digital_noise( uvec3 iuv ){\n"
+" iuv *=uvec3(8,2524,7552);\n"
+" for( int i=0; i<NOISE_LOOP; i++ )\n"
+" iuv += (iuv.yzx<<2) ^ (iuv.yxz)+iuv.z;\n"
+" return vec3(iuv)*(1.0/float(0xffffffffU));\n"
+"}\n"
+"\n"
+"vec2 rand_hash22( vec2 p ){\n"
+" vec3 p3 = fract(vec3(p.xyx) * 213.8976123);\n"
+" p3 += dot(p3, p3.yzx+19.19);\n"
+" return fract(vec2((p3.x + p3.y)*p3.z, (p3.x+p3.z)*p3.y));\n"
+"}\n"
+"\n"
+"void main(){\n"
+" compute_motion_vectors();\n"
+"\n"
+" vec2 ssuv = gl_FragCoord.xy;\n"
+" float grad = 1.0-aUv.y*0.1;\n"
+" float opacity = rand_hash22( vec2(floor(aUv.y*100.0),floor(aCo.z*10.0+uTime*40.0)) ).r*grad;\n"
+" \n"
+" vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), ssuv) );\n"
+" float dither = fract( vDither.g / 71.0 ) - 0.5;\n"
+"\n"
+" if( opacity<0.9 )\n"
+" discard;\n"
+"\n"
+" FragColor = vec4(0.7,0.5,0.5,1.0);\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_model_gate_unlinked_uMdl;
+GLuint _uniform_model_gate_unlinked_uPv;
+GLuint _uniform_model_gate_unlinked_uPvmPrev;
+GLuint _uniform_model_gate_unlinked_uTime;
+GLuint _uniform_model_gate_unlinked_uCam;
+GLuint _uniform_model_gate_unlinked_uColour;
+#include "shaders/model_font.h"
+struct vg_shader _shader_model_font = {
+ .name = "model_font",
+ .vs =
+{
+.orig_file = "shaders/model_font.vs",
+.static_src =
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec3 a_norm;\n"
+"layout (location=2) in vec2 a_uv;\n"
+"\n"
+"#line 1 1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+" // This magically solves some artifacting errors!\n"
+" //\n"
+" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
+"\n"
+" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line 6 0 \n"
+"\n"
+"uniform mat4x3 uMdl;\n"
+"uniform mat4 uPv;\n"
+"uniform mat4 uPvmPrev;\n"
+"uniform vec4 uOffset;\n"
+"\n"
+"out vec2 aUv;\n"
+"out vec4 aNorm;\n"
+"out vec3 aCo;\n"
+"out vec3 aWorldCo;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec3 co = a_co*uOffset.w+uOffset.xyz;\n"
+" vec3 world_pos0 = uMdl * vec4( co, 1.0 );\n"
+" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
+" vec4 vproj1 = uPvmPrev * vec4( co, 1.0 );\n"
+"\n"
+" vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+" gl_Position = vproj0;\n"
+"\n"
+" aUv = a_uv;\n"
+" aNorm = vec4( mat3(uMdl) * a_norm, 0.0 );\n"
+" aCo = co;\n"
+" aWorldCo = world_pos0;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/model_font.fs",
+.static_src =
+"layout (location = 0) out vec4 oColour;\n"
+"\n"
+"uniform sampler2D uTexMain;\n"
+"uniform vec4 uColour;\n"
+"\n"
+"in vec2 aUv;\n"
+"in vec4 aNorm;\n"
+"in vec3 aCo;\n"
+"\n"
+"#line 1 1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+" // Write motion vectors\n"
+" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"\n"
+" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
+"}\n"
+"\n"
+"#line 11 0 \n"
+"#line 1 2 \n"
+"uniform sampler2D uTexSceneDepth;\n"
+"uniform vec3 uInverseRatioDepth;\n"
+"uniform vec3 uInverseRatioMain;\n"
+"uniform bool uDepthCompare;\n"
+"\n"
+"float linear_depth( float depth, float near, float far ) {\n"
+" float z = depth * 2.0 - 1.0;\n"
+" return (2.0 * near * far) / (far + near - z * (far - near)); \n"
+"}\n"
+"\n"
+"void depth_compare_dither(){\n"
+" if( uDepthCompare ){\n"
+" vec2 back_coord = gl_FragCoord.xy * uInverseRatioMain.xy \n"
+" * uInverseRatioDepth.xy;\n"
+" float back_depth = texture( uTexSceneDepth, back_coord ).r;\n"
+" float front_depth = gl_FragCoord.z/gl_FragCoord.w;\n"
+"\n"
+" back_depth = linear_depth( back_depth, 0.1, 2100.0 );\n"
+" float diff = back_depth - front_depth;\n"
+"\n"
+" vec2 ssuv = gl_FragCoord.xy;\n"
+" vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), ssuv) );\n"
+" float dither = fract( vDither.g / 71.0 ) - 0.5;\n"
+"\n"
+" if( step(0.0,diff)+dither<0.3 )\n"
+" discard;\n"
+" }\n"
+"}\n"
+"\n"
+"#line 12 0 \n"
+"\n"
+"void main(){\n"
+" depth_compare_dither();\n"
+" compute_motion_vectors();\n"
+" oColour = texture( uTexMain, aUv ) * uColour;\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_model_font_uMdl;
+GLuint _uniform_model_font_uPv;
+GLuint _uniform_model_font_uPvmPrev;
+GLuint _uniform_model_font_uOffset;
+GLuint _uniform_model_font_uTexMain;
+GLuint _uniform_model_font_uColour;
+GLuint _uniform_model_font_uTexSceneDepth;
+GLuint _uniform_model_font_uInverseRatioDepth;
+GLuint _uniform_model_font_uInverseRatioMain;
+GLuint _uniform_model_font_uDepthCompare;
+#include "shaders/particle.h"
+struct vg_shader _shader_particle = {
+ .name = "particle",
+ .vs =
+{
+.orig_file = "shaders/particle.vs",
+.static_src =
+"layout (location=0) in vec3 a_co;\n"
+"layout (location=1) in vec4 a_colour;\n"
+"\n"
+"#line 1 1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+" // This magically solves some artifacting errors!\n"
+" //\n"
+" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
+"\n"
+" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line 5 0 \n"
+"\n"
+"uniform mat4 uPv;\n"
+"uniform mat4 uPvPrev;\n"
+"\n"
+"out vec4 aColour;\n"
+"\n"
+"void main(){\n"
+" vec4 vproj0 = uPv * vec4( a_co, 1.0 );\n"
+" vec4 vproj1 = uPvPrev * vec4( a_co, 1.0 );\n"
+" vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+" gl_Position = vproj0;\n"
+" aColour = a_colour;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/particle.fs",
+.static_src =
+"layout (location = 0) out vec4 oColour;\n"
+"in vec4 aColour;\n"
+"\n"
+"#line 1 1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+" // Write motion vectors\n"
+" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"\n"
+" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
+"}\n"
+"\n"
+"#line 5 0 \n"
+"\n"
+"void main(){\n"
+" compute_motion_vectors();\n"
+"\n"
+" //vec2 ssuv = gl_FragCoord.xy;\n"
+" //vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), ssuv) );\n"
+" //float dither = fract( vDither.g / 71.0 ) - 0.5;\n"
+"\n"
+" //if( vsamplemain.a+dither<0.5 )\n"
+" // discard;\n"
+"\n"
+" oColour = aColour;\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_particle_uPv;
+GLuint _uniform_particle_uPvPrev;
+#include "shaders/trail.h"
+struct vg_shader _shader_trail = {
+ .name = "trail",
+ .vs =
+{
+.orig_file = "shaders/trail.vs",
+.static_src =
+"layout (location=0) in vec4 a_co;\n"
+"\n"
+"#line 1 1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"out vec3 aMotionVec0;\n"
+"out vec3 aMotionVec1;\n"
+"\n"
+"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
+"{\n"
+" // This magically solves some artifacting errors!\n"
+" //\n"
+" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
+"\n"
+" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
+" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
+"}\n"
+"\n"
+"#line 4 0 \n"
+"\n"
+"uniform mat4 uPv;\n"
+"uniform mat4 uPvPrev;\n"
+"\n"
+"out float aAlpha;\n"
+"\n"
+"void main(){\n"
+" vec4 vproj0 = uPv * vec4( a_co.xyz, 1.0 );\n"
+" vec4 vproj1 = uPvPrev * vec4( a_co.xyz, 1.0 );\n"
+" vs_motion_out( vproj0, vproj1 );\n"
+"\n"
+" gl_Position = vproj0;\n"
+" aAlpha = a_co.w;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/trail.fs",
+.static_src =
+"layout (location = 0) out vec4 oColour;\n"
+"in float aAlpha;\n"
+"uniform vec4 uColour;\n"
+"\n"
+"#line 1 1 \n"
+"const float k_motion_lerp_amount = 0.01;\n"
+"\n"
+"#line 2 0 \n"
+"\n"
+"layout (location = 1) out vec2 oMotionVec;\n"
+"\n"
+"in vec3 aMotionVec0;\n"
+"in vec3 aMotionVec1;\n"
+"\n"
+"void compute_motion_vectors()\n"
+"{\n"
+" // Write motion vectors\n"
+" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
+" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
+"\n"
+" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
+"}\n"
+"\n"
+"#line 6 0 \n"
+"\n"
+"void main(){\n"
+" compute_motion_vectors();\n"
+"\n"
+" vec2 ssuv = gl_FragCoord.xy;\n"
+" vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), ssuv) );\n"
+" float dither = fract( vDither.g / 71.0 ) - 0.5;\n"
+"\n"
+" if( aAlpha+dither<0.5 )\n"
+" discard;\n"
+"\n"
+" oColour = vec4( uColour.rgb, uColour.a * aAlpha );\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_trail_uPv;
+GLuint _uniform_trail_uPvPrev;
+GLuint _uniform_trail_uColour;
+#include "shaders/blit.h"
+struct vg_shader _shader_blit = {
+ .name = "blit",
+ .vs =
+{
+.orig_file = "shaders/blit.vs",
+.static_src =
+"layout (location=0) in vec2 a_co;\n"
+"out vec2 aUv;\n"
+"\n"
+"uniform vec2 uInverseRatio;\n"
+"\n"
+"void main()\n"
+"{\n"
+" gl_Position = vec4(a_co*2.0-1.0,0.0,1.0);\n"
+" aUv = a_co * uInverseRatio;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/blit.fs",
+.static_src =
+"out vec4 FragColor;\n"
+"uniform sampler2D uTexMain;\n"
+"\n"
+"in vec2 aUv;\n"
+"\n"
+"float kPi = 3.14159265358979;\n"
+"\n"
+"vec2 fisheye_distort(vec2 xy)\n"
+"{\n"
+" float aperture = 1350.0;\n"
+" float apertureHalf = 0.5 * aperture * (kPi / 180.0);\n"
+" float maxFactor = sin(apertureHalf);\n"
+"\n"
+" vec2 uv;\n"
+" float d = length(xy);\n"
+" if(d < (2.0-maxFactor))\n"
+" {\n"
+" d = length(xy * maxFactor);\n"
+" float z = sqrt(1.0 - d * d);\n"
+" float r = atan(d, z) / kPi;\n"
+" float phi = atan(xy.y, xy.x);\n"
+"\n"
+" uv.x = r * cos(phi) + 0.5;\n"
+" uv.y = r * sin(phi) + 0.5;\n"
+" }\n"
+" else\n"
+" {\n"
+" uv = 0.5*xy + 0.5;\n"
+" }\n"
+" \n"
+" return uv;\n"
+"}\n"
+"\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec2 vwarp = 2.0*aUv - 1.0;\n"
+" vwarp = fisheye_distort( vwarp );\n"
+"\n"
+" FragColor = texture( uTexMain, aUv );\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_blit_uInverseRatio;
+GLuint _uniform_blit_uTexMain;
+#include "shaders/blitblur.h"
+struct vg_shader _shader_blitblur = {
+ .name = "blitblur",
+ .vs =
+{
+.orig_file = "shaders/blit.vs",
+.static_src =
+"layout (location=0) in vec2 a_co;\n"
+"out vec2 aUv;\n"
+"\n"
+"uniform vec2 uInverseRatio;\n"
+"\n"
+"void main()\n"
+"{\n"
+" gl_Position = vec4(a_co*2.0-1.0,0.0,1.0);\n"
+" aUv = a_co * uInverseRatio;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/blitblur.fs",
+.static_src =
+"out vec4 FragColor;\n"
+"uniform sampler2D uTexMain;\n"
+"uniform sampler2D uTexMotion;\n"
+"uniform float uBlurStrength;\n"
+"uniform vec2 uOverrideDir;\n"
+"uniform float uTime;\n"
+"uniform float uGlitchStrength;\n"
+"uniform vec2 uClampUv;\n"
+"\n"
+"in vec2 aUv;\n"
+"\n"
+"vec2 rand_hash22( vec2 p ){\n"
+" vec3 p3 = fract(vec3(p.xyx) * 213.8976123);\n"
+" p3 += dot(p3, p3.yzx+19.19);\n"
+" return fract(vec2((p3.x + p3.y)*p3.z, (p3.x+p3.z)*p3.y));\n"
+"}\n"
+"\n"
+"const int NOISE_LOOP = 3;\n"
+"vec3 digital_noise( uvec3 iuv ){\n"
+" iuv *=uvec3(8,2524,7552);\n"
+" for( int i=0; i<NOISE_LOOP; i++ )\n"
+" iuv += (iuv.yzx<<2) ^ (iuv.yxz)+iuv.z;\n"
+" return vec3(iuv)*(1.0/float(0xffffffffU));\n"
+"}\n"
+"\n"
+"void main(){\n"
+" vec2 vuv = aUv; \n"
+"\n"
+" //if( uGlitchStrength > 0.0 ){\n"
+" // uvec3 p = uvec3( gl_FragCoord.xy, uint(uTime*30.0) );\n"
+" // vec2 g = digital_noise(p).xy;\n"
+" // vuv = aUv + g.xy*uGlitchStrength - uGlitchStrength*0.5;\n"
+" //}\n"
+"\n"
+" vec2 vrand = rand_hash22( vuv ) * 2.0 - vec2(1.0);\n"
+" vec2 vrand1 = rand_hash22( vrand ) * 2.0 - vec2(1.0);\n"
+" \n"
+" vec2 vdir = texture( uTexMotion, vuv ).xy * uBlurStrength + uOverrideDir;\n"
+"\n"
+" vec4 vcolour0 = texture( uTexMain, min(vuv + vdir*vrand.x,uClampUv) );\n"
+" vec4 vcolour1 = texture( uTexMain, min(vuv + vdir*vrand.y,uClampUv) );\n"
+" vec4 vcolour2 = texture( uTexMain, min(vuv + vdir*vrand1.x,uClampUv) );\n"
+" vec4 vcolour3 = texture( uTexMain, min(vuv + vdir*vrand1.y,uClampUv) );\n"
+"\n"
+" FragColor = ( vcolour0 + vcolour1 + vcolour2 + vcolour3 ) * 0.25;\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_blitblur_uInverseRatio;
+GLuint _uniform_blitblur_uTexMain;
+GLuint _uniform_blitblur_uTexMotion;
+GLuint _uniform_blitblur_uBlurStrength;
+GLuint _uniform_blitblur_uOverrideDir;
+GLuint _uniform_blitblur_uTime;
+GLuint _uniform_blitblur_uGlitchStrength;
+GLuint _uniform_blitblur_uClampUv;
+#include "shaders/blitcolour.h"
+struct vg_shader _shader_blitcolour = {
+ .name = "blitcolour",
+ .vs =
+{
+.orig_file = "shaders/blit.vs",
+.static_src =
+"layout (location=0) in vec2 a_co;\n"
+"out vec2 aUv;\n"
+"\n"
+"uniform vec2 uInverseRatio;\n"
+"\n"
+"void main()\n"
+"{\n"
+" gl_Position = vec4(a_co*2.0-1.0,0.0,1.0);\n"
+" aUv = a_co * uInverseRatio;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/colour.fs",
+.static_src =
+"out vec4 FragColor;\n"
+"uniform vec4 uColour;\n"
+"\n"
+"in vec2 aUv;\n"
+"\n"
+"void main()\n"
+"{\n"
+" FragColor = uColour;\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_blitcolour_uInverseRatio;
+GLuint _uniform_blitcolour_uColour;
+#include "shaders/blit_transition.h"
+struct vg_shader _shader_blit_transition = {
+ .name = "blit_transition",
+ .vs =
+{
+.orig_file = "shaders/blit.vs",
+.static_src =
+"layout (location=0) in vec2 a_co;\n"
+"out vec2 aUv;\n"
+"\n"
+"uniform vec2 uInverseRatio;\n"
+"\n"
+"void main()\n"
+"{\n"
+" gl_Position = vec4(a_co*2.0-1.0,0.0,1.0);\n"
+" aUv = a_co * uInverseRatio;\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/blit_transition.fs",
+.static_src =
+"out vec4 FragColor;\n"
+"in vec2 aUv;\n"
+"uniform float uT;\n"
+"\n"
+"void main(){\n"
+" float d = uT + distance( aUv, vec2(0.5,0.5) );\n"
+"\n"
+" vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), gl_FragCoord.xy) );\n"
+" float dither = fract( vDither.g / 71.0 ) - 0.5;\n"
+"\n"
+" if( d+dither < -0.5 )\n"
+" discard;\n"
+"\n"
+" FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_blit_transition_uInverseRatio;
+GLuint _uniform_blit_transition_uT;
+#include "shaders/routeui.h"
+struct vg_shader _shader_routeui = {
+ .name = "routeui",
+ .vs =
+{
+.orig_file = "shaders/routeui.vs",
+.static_src =
+"layout (location=0) in vec2 a_co;\n"
+"\n"
+"uniform vec4 uOffset;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec2 vpos = a_co * uOffset.zw + uOffset.xy;\n"
+" gl_Position = vec4(vpos,0.0,1.0);\n"
+"}\n"
+""},
+ .fs =
+{
+.orig_file = "shaders/routeui.fs",
+.static_src =
+"out vec4 FragColor;\n"
+"\n"
+"uniform vec4 uColour;\n"
+"\n"
+"void main()\n"
+"{\n"
+" FragColor = uColour;\n"
+"}\n"
+""},
+};
+
+GLuint _uniform_routeui_uOffset;
+GLuint _uniform_routeui_uColour;
+
+
+void vg_auto_shader_link(void)
+{
+ _uniform_scene_standard_uMdl = glGetUniformLocation( _shader_scene_standard.id, "uMdl" );
+ _uniform_scene_standard_uPv = glGetUniformLocation( _shader_scene_standard.id, "uPv" );
+ _uniform_scene_standard_uPvmPrev = glGetUniformLocation( _shader_scene_standard.id, "uPvmPrev" );
+ _uniform_scene_standard_uTexGarbage = glGetUniformLocation( _shader_scene_standard.id, "uTexGarbage" );
+ _uniform_scene_standard_uTexMain = glGetUniformLocation( _shader_scene_standard.id, "uTexMain" );
+ _uniform_scene_standard_uCamera = glGetUniformLocation( _shader_scene_standard.id, "uCamera" );
+ _uniform_scene_standard_uPlane = glGetUniformLocation( _shader_scene_standard.id, "uPlane" );
+ _uniform_scene_standard_g_world_depth = glGetUniformLocation( _shader_scene_standard.id, "g_world_depth" );
+ _uniform_scene_standard_uLightsArray = glGetUniformLocation( _shader_scene_standard.id, "uLightsArray" );
+ _uniform_scene_standard_uLightsIndex = glGetUniformLocation( _shader_scene_standard.id, "uLightsIndex" );
+ _uniform_scene_standard_alphatest_uMdl = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uMdl" );
+ _uniform_scene_standard_alphatest_uPv = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uPv" );
+ _uniform_scene_standard_alphatest_uPvmPrev = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uPvmPrev" );
+ _uniform_scene_standard_alphatest_uTexGarbage = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uTexGarbage" );
+ _uniform_scene_standard_alphatest_uTexMain = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uTexMain" );
+ _uniform_scene_standard_alphatest_uCamera = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uCamera" );
+ _uniform_scene_standard_alphatest_uPlane = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uPlane" );
+ _uniform_scene_standard_alphatest_g_world_depth = glGetUniformLocation( _shader_scene_standard_alphatest.id, "g_world_depth" );
+ _uniform_scene_standard_alphatest_uLightsArray = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uLightsArray" );
+ _uniform_scene_standard_alphatest_uLightsIndex = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uLightsIndex" );
+ _uniform_scene_foliage_uMdl = glGetUniformLocation( _shader_scene_foliage.id, "uMdl" );
+ _uniform_scene_foliage_uPv = glGetUniformLocation( _shader_scene_foliage.id, "uPv" );
+ _uniform_scene_foliage_uPvmPrev = glGetUniformLocation( _shader_scene_foliage.id, "uPvmPrev" );
+ _uniform_scene_foliage_uTime = glGetUniformLocation( _shader_scene_foliage.id, "uTime" );
+ _uniform_scene_foliage_uTexGarbage = glGetUniformLocation( _shader_scene_foliage.id, "uTexGarbage" );
+ _uniform_scene_foliage_uTexMain = glGetUniformLocation( _shader_scene_foliage.id, "uTexMain" );
+ _uniform_scene_foliage_uCamera = glGetUniformLocation( _shader_scene_foliage.id, "uCamera" );
+ _uniform_scene_foliage_uPlane = glGetUniformLocation( _shader_scene_foliage.id, "uPlane" );
+ _uniform_scene_foliage_g_world_depth = glGetUniformLocation( _shader_scene_foliage.id, "g_world_depth" );
+ _uniform_scene_foliage_uLightsArray = glGetUniformLocation( _shader_scene_foliage.id, "uLightsArray" );
+ _uniform_scene_foliage_uLightsIndex = glGetUniformLocation( _shader_scene_foliage.id, "uLightsIndex" );
+ _uniform_scene_override_uMdl = glGetUniformLocation( _shader_scene_override.id, "uMdl" );
+ _uniform_scene_override_uPv = glGetUniformLocation( _shader_scene_override.id, "uPv" );
+ _uniform_scene_override_uPvmPrev = glGetUniformLocation( _shader_scene_override.id, "uPvmPrev" );
+ _uniform_scene_override_uNormalMtx = glGetUniformLocation( _shader_scene_override.id, "uNormalMtx" );
+ _uniform_scene_override_uTexGarbage = glGetUniformLocation( _shader_scene_override.id, "uTexGarbage" );
+ _uniform_scene_override_uTexMain = glGetUniformLocation( _shader_scene_override.id, "uTexMain" );
+ _uniform_scene_override_uCamera = glGetUniformLocation( _shader_scene_override.id, "uCamera" );
+ _uniform_scene_override_uPlane = glGetUniformLocation( _shader_scene_override.id, "uPlane" );
+ _uniform_scene_override_uPlayerPos = glGetUniformLocation( _shader_scene_override.id, "uPlayerPos" );
+ _uniform_scene_override_uSpawnPos = glGetUniformLocation( _shader_scene_override.id, "uSpawnPos" );
+ _uniform_scene_override_uAlphatest = glGetUniformLocation( _shader_scene_override.id, "uAlphatest" );
+ _uniform_scene_override_uMapInfo = glGetUniformLocation( _shader_scene_override.id, "uMapInfo" );
+ _uniform_scene_override_g_world_depth = glGetUniformLocation( _shader_scene_override.id, "g_world_depth" );
+ _uniform_scene_override_uLightsArray = glGetUniformLocation( _shader_scene_override.id, "uLightsArray" );
+ _uniform_scene_override_uLightsIndex = glGetUniformLocation( _shader_scene_override.id, "uLightsIndex" );
+ _uniform_scene_fxglow_uMdl = glGetUniformLocation( _shader_scene_fxglow.id, "uMdl" );
+ _uniform_scene_fxglow_uPv = glGetUniformLocation( _shader_scene_fxglow.id, "uPv" );
+ _uniform_scene_fxglow_uPvmPrev = glGetUniformLocation( _shader_scene_fxglow.id, "uPvmPrev" );
+ _uniform_scene_fxglow_uUvOffset = glGetUniformLocation( _shader_scene_fxglow.id, "uUvOffset" );
+ _uniform_scene_fxglow_uTexMain = glGetUniformLocation( _shader_scene_fxglow.id, "uTexMain" );
+ _uniform_scene_fxglow_uCamera = glGetUniformLocation( _shader_scene_fxglow.id, "uCamera" );
+ _uniform_scene_fxglow_g_world_depth = glGetUniformLocation( _shader_scene_fxglow.id, "g_world_depth" );
+ _uniform_scene_fxglow_uLightsArray = glGetUniformLocation( _shader_scene_fxglow.id, "uLightsArray" );
+ _uniform_scene_fxglow_uLightsIndex = glGetUniformLocation( _shader_scene_fxglow.id, "uLightsIndex" );
+ _uniform_scene_vertex_blend_uMdl = glGetUniformLocation( _shader_scene_vertex_blend.id, "uMdl" );
+ _uniform_scene_vertex_blend_uPv = glGetUniformLocation( _shader_scene_vertex_blend.id, "uPv" );
+ _uniform_scene_vertex_blend_uPvmPrev = glGetUniformLocation( _shader_scene_vertex_blend.id, "uPvmPrev" );
+ _uniform_scene_vertex_blend_uTexGarbage = glGetUniformLocation( _shader_scene_vertex_blend.id, "uTexGarbage" );
+ _uniform_scene_vertex_blend_uTexGradients = glGetUniformLocation( _shader_scene_vertex_blend.id, "uTexGradients" );
+ _uniform_scene_vertex_blend_uCamera = glGetUniformLocation( _shader_scene_vertex_blend.id, "uCamera" );
+ _uniform_scene_vertex_blend_g_world_depth = glGetUniformLocation( _shader_scene_vertex_blend.id, "g_world_depth" );
+ _uniform_scene_vertex_blend_uLightsArray = glGetUniformLocation( _shader_scene_vertex_blend.id, "uLightsArray" );
+ _uniform_scene_vertex_blend_uLightsIndex = glGetUniformLocation( _shader_scene_vertex_blend.id, "uLightsIndex" );
+ _uniform_scene_terrain_uMdl = glGetUniformLocation( _shader_scene_terrain.id, "uMdl" );
+ _uniform_scene_terrain_uPv = glGetUniformLocation( _shader_scene_terrain.id, "uPv" );
+ _uniform_scene_terrain_uPvmPrev = glGetUniformLocation( _shader_scene_terrain.id, "uPvmPrev" );
+ _uniform_scene_terrain_uTexGarbage = glGetUniformLocation( _shader_scene_terrain.id, "uTexGarbage" );
+ _uniform_scene_terrain_uTexGradients = glGetUniformLocation( _shader_scene_terrain.id, "uTexGradients" );
+ _uniform_scene_terrain_uCamera = glGetUniformLocation( _shader_scene_terrain.id, "uCamera" );
+ _uniform_scene_terrain_uSandColour = glGetUniformLocation( _shader_scene_terrain.id, "uSandColour" );
+ _uniform_scene_terrain_uBlendOffset = glGetUniformLocation( _shader_scene_terrain.id, "uBlendOffset" );
+ _uniform_scene_terrain_g_world_depth = glGetUniformLocation( _shader_scene_terrain.id, "g_world_depth" );
+ _uniform_scene_terrain_uLightsArray = glGetUniformLocation( _shader_scene_terrain.id, "uLightsArray" );
+ _uniform_scene_terrain_uLightsIndex = glGetUniformLocation( _shader_scene_terrain.id, "uLightsIndex" );
+ _uniform_scene_route_uMdl = glGetUniformLocation( _shader_scene_route.id, "uMdl" );
+ _uniform_scene_route_uPv = glGetUniformLocation( _shader_scene_route.id, "uPv" );
+ _uniform_scene_route_uPvmPrev = glGetUniformLocation( _shader_scene_route.id, "uPvmPrev" );
+ _uniform_scene_route_uNormalMtx = glGetUniformLocation( _shader_scene_route.id, "uNormalMtx" );
+ _uniform_scene_route_uTexGarbage = glGetUniformLocation( _shader_scene_route.id, "uTexGarbage" );
+ _uniform_scene_route_uTexGradients = glGetUniformLocation( _shader_scene_route.id, "uTexGradients" );
+ _uniform_scene_route_uCamera = glGetUniformLocation( _shader_scene_route.id, "uCamera" );
+ _uniform_scene_route_uColour = glGetUniformLocation( _shader_scene_route.id, "uColour" );
+ _uniform_scene_route_g_world_depth = glGetUniformLocation( _shader_scene_route.id, "g_world_depth" );
+ _uniform_scene_route_uLightsArray = glGetUniformLocation( _shader_scene_route.id, "uLightsArray" );
+ _uniform_scene_route_uLightsIndex = glGetUniformLocation( _shader_scene_route.id, "uLightsIndex" );
+ _uniform_scene_depth_uMdl = glGetUniformLocation( _shader_scene_depth.id, "uMdl" );
+ _uniform_scene_depth_uPv = glGetUniformLocation( _shader_scene_depth.id, "uPv" );
+ _uniform_scene_depth_uPvmPrev = glGetUniformLocation( _shader_scene_depth.id, "uPvmPrev" );
+ _uniform_scene_depth_uCamera = glGetUniformLocation( _shader_scene_depth.id, "uCamera" );
+ _uniform_scene_depth_uBoard0 = glGetUniformLocation( _shader_scene_depth.id, "uBoard0" );
+ _uniform_scene_depth_uBoard1 = glGetUniformLocation( _shader_scene_depth.id, "uBoard1" );
+ _uniform_scene_depth_g_world_depth = glGetUniformLocation( _shader_scene_depth.id, "g_world_depth" );
+ _uniform_scene_depth_uLightsArray = glGetUniformLocation( _shader_scene_depth.id, "uLightsArray" );
+ _uniform_scene_depth_uLightsIndex = glGetUniformLocation( _shader_scene_depth.id, "uLightsIndex" );
+ _uniform_scene_position_uMdl = glGetUniformLocation( _shader_scene_position.id, "uMdl" );
+ _uniform_scene_position_uPv = glGetUniformLocation( _shader_scene_position.id, "uPv" );
+ _uniform_scene_position_uPvmPrev = glGetUniformLocation( _shader_scene_position.id, "uPvmPrev" );
+ _uniform_scene_position_uCamera = glGetUniformLocation( _shader_scene_position.id, "uCamera" );
+ _uniform_scene_position_uBoard0 = glGetUniformLocation( _shader_scene_position.id, "uBoard0" );
+ _uniform_scene_position_uBoard1 = glGetUniformLocation( _shader_scene_position.id, "uBoard1" );
+ _uniform_scene_position_g_world_depth = glGetUniformLocation( _shader_scene_position.id, "g_world_depth" );
+ _uniform_scene_position_uLightsArray = glGetUniformLocation( _shader_scene_position.id, "uLightsArray" );
+ _uniform_scene_position_uLightsIndex = glGetUniformLocation( _shader_scene_position.id, "uLightsIndex" );
+ _uniform_scene_cubemapped_uMdl = glGetUniformLocation( _shader_scene_cubemapped.id, "uMdl" );
+ _uniform_scene_cubemapped_uPv = glGetUniformLocation( _shader_scene_cubemapped.id, "uPv" );
+ _uniform_scene_cubemapped_uPvmPrev = glGetUniformLocation( _shader_scene_cubemapped.id, "uPvmPrev" );
+ _uniform_scene_cubemapped_uTexGarbage = glGetUniformLocation( _shader_scene_cubemapped.id, "uTexGarbage" );
+ _uniform_scene_cubemapped_uTexMain = glGetUniformLocation( _shader_scene_cubemapped.id, "uTexMain" );
+ _uniform_scene_cubemapped_uTexCubemap = glGetUniformLocation( _shader_scene_cubemapped.id, "uTexCubemap" );
+ _uniform_scene_cubemapped_uCamera = glGetUniformLocation( _shader_scene_cubemapped.id, "uCamera" );
+ _uniform_scene_cubemapped_uPlane = glGetUniformLocation( _shader_scene_cubemapped.id, "uPlane" );
+ _uniform_scene_cubemapped_uColour = glGetUniformLocation( _shader_scene_cubemapped.id, "uColour" );
+ _uniform_scene_cubemapped_g_world_depth = glGetUniformLocation( _shader_scene_cubemapped.id, "g_world_depth" );
+ _uniform_scene_cubemapped_uLightsArray = glGetUniformLocation( _shader_scene_cubemapped.id, "uLightsArray" );
+ _uniform_scene_cubemapped_uLightsIndex = glGetUniformLocation( _shader_scene_cubemapped.id, "uLightsIndex" );
+ _uniform_scene_water_uMdl = glGetUniformLocation( _shader_scene_water.id, "uMdl" );
+ _uniform_scene_water_uPv = glGetUniformLocation( _shader_scene_water.id, "uPv" );
+ _uniform_scene_water_uPvmPrev = glGetUniformLocation( _shader_scene_water.id, "uPvmPrev" );
+ _uniform_scene_water_uTexMain = glGetUniformLocation( _shader_scene_water.id, "uTexMain" );
+ _uniform_scene_water_uTexDudv = glGetUniformLocation( _shader_scene_water.id, "uTexDudv" );
+ _uniform_scene_water_uTexBack = glGetUniformLocation( _shader_scene_water.id, "uTexBack" );
+ _uniform_scene_water_uInvRes = glGetUniformLocation( _shader_scene_water.id, "uInvRes" );
+ _uniform_scene_water_uTime = glGetUniformLocation( _shader_scene_water.id, "uTime" );
+ _uniform_scene_water_uCamera = glGetUniformLocation( _shader_scene_water.id, "uCamera" );
+ _uniform_scene_water_uSurfaceY = glGetUniformLocation( _shader_scene_water.id, "uSurfaceY" );
+ _uniform_scene_water_uBoard0 = glGetUniformLocation( _shader_scene_water.id, "uBoard0" );
+ _uniform_scene_water_uBoard1 = glGetUniformLocation( _shader_scene_water.id, "uBoard1" );
+ _uniform_scene_water_uShoreColour = glGetUniformLocation( _shader_scene_water.id, "uShoreColour" );
+ _uniform_scene_water_uOceanColour = glGetUniformLocation( _shader_scene_water.id, "uOceanColour" );
+ _uniform_scene_water_g_world_depth = glGetUniformLocation( _shader_scene_water.id, "g_world_depth" );
+ _uniform_scene_water_uLightsArray = glGetUniformLocation( _shader_scene_water.id, "uLightsArray" );
+ _uniform_scene_water_uLightsIndex = glGetUniformLocation( _shader_scene_water.id, "uLightsIndex" );
+ _uniform_scene_water_fast_uMdl = glGetUniformLocation( _shader_scene_water_fast.id, "uMdl" );
+ _uniform_scene_water_fast_uPv = glGetUniformLocation( _shader_scene_water_fast.id, "uPv" );
+ _uniform_scene_water_fast_uPvmPrev = glGetUniformLocation( _shader_scene_water_fast.id, "uPvmPrev" );
+ _uniform_scene_water_fast_uTexDudv = glGetUniformLocation( _shader_scene_water_fast.id, "uTexDudv" );
+ _uniform_scene_water_fast_uTime = glGetUniformLocation( _shader_scene_water_fast.id, "uTime" );
+ _uniform_scene_water_fast_uCamera = glGetUniformLocation( _shader_scene_water_fast.id, "uCamera" );
+ _uniform_scene_water_fast_uSurfaceY = glGetUniformLocation( _shader_scene_water_fast.id, "uSurfaceY" );
+ _uniform_scene_water_fast_uBoard0 = glGetUniformLocation( _shader_scene_water_fast.id, "uBoard0" );
+ _uniform_scene_water_fast_uBoard1 = glGetUniformLocation( _shader_scene_water_fast.id, "uBoard1" );
+ _uniform_scene_water_fast_uShoreColour = glGetUniformLocation( _shader_scene_water_fast.id, "uShoreColour" );
+ _uniform_scene_water_fast_uOceanColour = glGetUniformLocation( _shader_scene_water_fast.id, "uOceanColour" );
+ _uniform_scene_water_fast_g_world_depth = glGetUniformLocation( _shader_scene_water_fast.id, "g_world_depth" );
+ _uniform_scene_water_fast_uLightsArray = glGetUniformLocation( _shader_scene_water_fast.id, "uLightsArray" );
+ _uniform_scene_water_fast_uLightsIndex = glGetUniformLocation( _shader_scene_water_fast.id, "uLightsIndex" );
+ _uniform_scene_scoretext_uMdl = glGetUniformLocation( _shader_scene_scoretext.id, "uMdl" );
+ _uniform_scene_scoretext_uPv = glGetUniformLocation( _shader_scene_scoretext.id, "uPv" );
+ _uniform_scene_scoretext_uPvmPrev = glGetUniformLocation( _shader_scene_scoretext.id, "uPvmPrev" );
+ _uniform_scene_scoretext_uInfo = glGetUniformLocation( _shader_scene_scoretext.id, "uInfo" );
+ _uniform_scene_scoretext_uTexGarbage = glGetUniformLocation( _shader_scene_scoretext.id, "uTexGarbage" );
+ _uniform_scene_scoretext_uTexMain = glGetUniformLocation( _shader_scene_scoretext.id, "uTexMain" );
+ _uniform_scene_scoretext_uCamera = glGetUniformLocation( _shader_scene_scoretext.id, "uCamera" );
+ _uniform_scene_scoretext_uPlane = glGetUniformLocation( _shader_scene_scoretext.id, "uPlane" );
+ _uniform_scene_scoretext_g_world_depth = glGetUniformLocation( _shader_scene_scoretext.id, "g_world_depth" );
+ _uniform_scene_scoretext_uLightsArray = glGetUniformLocation( _shader_scene_scoretext.id, "uLightsArray" );
+ _uniform_scene_scoretext_uLightsIndex = glGetUniformLocation( _shader_scene_scoretext.id, "uLightsIndex" );
+ _uniform_scene_font_uMdl = glGetUniformLocation( _shader_scene_font.id, "uMdl" );
+ _uniform_scene_font_uPv = glGetUniformLocation( _shader_scene_font.id, "uPv" );
+ _uniform_scene_font_uPvmPrev = glGetUniformLocation( _shader_scene_font.id, "uPvmPrev" );
+ _uniform_scene_font_uOffset = glGetUniformLocation( _shader_scene_font.id, "uOffset" );
+ _uniform_scene_font_uTexGarbage = glGetUniformLocation( _shader_scene_font.id, "uTexGarbage" );
+ _uniform_scene_font_uTexMain = glGetUniformLocation( _shader_scene_font.id, "uTexMain" );
+ _uniform_scene_font_uCamera = glGetUniformLocation( _shader_scene_font.id, "uCamera" );
+ _uniform_scene_font_uTime = glGetUniformLocation( _shader_scene_font.id, "uTime" );
+ _uniform_scene_font_uOpacity = glGetUniformLocation( _shader_scene_font.id, "uOpacity" );
+ _uniform_scene_font_uColourize = glGetUniformLocation( _shader_scene_font.id, "uColourize" );
+ _uniform_scene_font_g_world_depth = glGetUniformLocation( _shader_scene_font.id, "g_world_depth" );
+ _uniform_scene_font_uLightsArray = glGetUniformLocation( _shader_scene_font.id, "uLightsArray" );
+ _uniform_scene_font_uLightsIndex = glGetUniformLocation( _shader_scene_font.id, "uLightsIndex" );
+ _uniform_model_sky_uMdl = glGetUniformLocation( _shader_model_sky.id, "uMdl" );
+ _uniform_model_sky_uPv = glGetUniformLocation( _shader_model_sky.id, "uPv" );
+ _uniform_model_sky_uPvmPrev = glGetUniformLocation( _shader_model_sky.id, "uPvmPrev" );
+ _uniform_model_sky_uTexGarbage = glGetUniformLocation( _shader_model_sky.id, "uTexGarbage" );
+ _uniform_model_sky_g_world_depth = glGetUniformLocation( _shader_model_sky.id, "g_world_depth" );
+ _uniform_model_sky_uLightsArray = glGetUniformLocation( _shader_model_sky.id, "uLightsArray" );
+ _uniform_model_sky_uLightsIndex = glGetUniformLocation( _shader_model_sky.id, "uLightsIndex" );
+ _uniform_model_sky_space_uMdl = glGetUniformLocation( _shader_model_sky_space.id, "uMdl" );
+ _uniform_model_sky_space_uPv = glGetUniformLocation( _shader_model_sky_space.id, "uPv" );
+ _uniform_model_sky_space_uPvmPrev = glGetUniformLocation( _shader_model_sky_space.id, "uPvmPrev" );
+ _uniform_model_sky_space_uTexGarbage = glGetUniformLocation( _shader_model_sky_space.id, "uTexGarbage" );
+ _uniform_model_sky_space_g_world_depth = glGetUniformLocation( _shader_model_sky_space.id, "g_world_depth" );
+ _uniform_model_sky_space_uLightsArray = glGetUniformLocation( _shader_model_sky_space.id, "uLightsArray" );
+ _uniform_model_sky_space_uLightsIndex = glGetUniformLocation( _shader_model_sky_space.id, "uLightsIndex" );
+ _uniform_model_menu_uMdl = glGetUniformLocation( _shader_model_menu.id, "uMdl" );
+ _uniform_model_menu_uPv = glGetUniformLocation( _shader_model_menu.id, "uPv" );
+ _uniform_model_menu_uPvmPrev = glGetUniformLocation( _shader_model_menu.id, "uPvmPrev" );
+ _uniform_model_menu_uTexMain = glGetUniformLocation( _shader_model_menu.id, "uTexMain" );
+ _uniform_model_menu_uColour = glGetUniformLocation( _shader_model_menu.id, "uColour" );
+ _uniform_model_character_view_uPv = glGetUniformLocation( _shader_model_character_view.id, "uPv" );
+ _uniform_model_character_view_uTransforms = glGetUniformLocation( _shader_model_character_view.id, "uTransforms" );
+ _uniform_model_character_view_uTexMain = glGetUniformLocation( _shader_model_character_view.id, "uTexMain" );
+ _uniform_model_character_view_uCamera = glGetUniformLocation( _shader_model_character_view.id, "uCamera" );
+ _uniform_model_character_view_g_world_depth = glGetUniformLocation( _shader_model_character_view.id, "g_world_depth" );
+ _uniform_model_character_view_uLightsArray = glGetUniformLocation( _shader_model_character_view.id, "uLightsArray" );
+ _uniform_model_character_view_uLightsIndex = glGetUniformLocation( _shader_model_character_view.id, "uLightsIndex" );
+ _uniform_model_character_view_uTexSceneDepth = glGetUniformLocation( _shader_model_character_view.id, "uTexSceneDepth" );
+ _uniform_model_character_view_uInverseRatioDepth = glGetUniformLocation( _shader_model_character_view.id, "uInverseRatioDepth" );
+ _uniform_model_character_view_uInverseRatioMain = glGetUniformLocation( _shader_model_character_view.id, "uInverseRatioMain" );
+ _uniform_model_character_view_uDepthCompare = glGetUniformLocation( _shader_model_character_view.id, "uDepthCompare" );
+ _uniform_model_board_view_uMdl = glGetUniformLocation( _shader_model_board_view.id, "uMdl" );
+ _uniform_model_board_view_uPv = glGetUniformLocation( _shader_model_board_view.id, "uPv" );
+ _uniform_model_board_view_uPvmPrev = glGetUniformLocation( _shader_model_board_view.id, "uPvmPrev" );
+ _uniform_model_board_view_uTexMain = glGetUniformLocation( _shader_model_board_view.id, "uTexMain" );
+ _uniform_model_board_view_uCamera = glGetUniformLocation( _shader_model_board_view.id, "uCamera" );
+ _uniform_model_board_view_g_world_depth = glGetUniformLocation( _shader_model_board_view.id, "g_world_depth" );
+ _uniform_model_board_view_uLightsArray = glGetUniformLocation( _shader_model_board_view.id, "uLightsArray" );
+ _uniform_model_board_view_uLightsIndex = glGetUniformLocation( _shader_model_board_view.id, "uLightsIndex" );
+ _uniform_model_board_view_uTexSceneDepth = glGetUniformLocation( _shader_model_board_view.id, "uTexSceneDepth" );
+ _uniform_model_board_view_uInverseRatioDepth = glGetUniformLocation( _shader_model_board_view.id, "uInverseRatioDepth" );
+ _uniform_model_board_view_uInverseRatioMain = glGetUniformLocation( _shader_model_board_view.id, "uInverseRatioMain" );
+ _uniform_model_board_view_uDepthCompare = glGetUniformLocation( _shader_model_board_view.id, "uDepthCompare" );
+ _uniform_model_entity_uMdl = glGetUniformLocation( _shader_model_entity.id, "uMdl" );
+ _uniform_model_entity_uPv = glGetUniformLocation( _shader_model_entity.id, "uPv" );
+ _uniform_model_entity_uPvmPrev = glGetUniformLocation( _shader_model_entity.id, "uPvmPrev" );
+ _uniform_model_entity_uTexMain = glGetUniformLocation( _shader_model_entity.id, "uTexMain" );
+ _uniform_model_entity_uCamera = glGetUniformLocation( _shader_model_entity.id, "uCamera" );
+ _uniform_model_entity_g_world_depth = glGetUniformLocation( _shader_model_entity.id, "g_world_depth" );
+ _uniform_model_entity_uLightsArray = glGetUniformLocation( _shader_model_entity.id, "uLightsArray" );
+ _uniform_model_entity_uLightsIndex = glGetUniformLocation( _shader_model_entity.id, "uLightsIndex" );
+ _uniform_model_gate_uMdl = glGetUniformLocation( _shader_model_gate.id, "uMdl" );
+ _uniform_model_gate_uPv = glGetUniformLocation( _shader_model_gate.id, "uPv" );
+ _uniform_model_gate_uPvmPrev = glGetUniformLocation( _shader_model_gate.id, "uPvmPrev" );
+ _uniform_model_gate_uTime = glGetUniformLocation( _shader_model_gate.id, "uTime" );
+ _uniform_model_gate_uCam = glGetUniformLocation( _shader_model_gate.id, "uCam" );
+ _uniform_model_gate_uInvRes = glGetUniformLocation( _shader_model_gate.id, "uInvRes" );
+ _uniform_model_gate_uColour = glGetUniformLocation( _shader_model_gate.id, "uColour" );
+ _uniform_model_gate_unlinked_uMdl = glGetUniformLocation( _shader_model_gate_unlinked.id, "uMdl" );
+ _uniform_model_gate_unlinked_uPv = glGetUniformLocation( _shader_model_gate_unlinked.id, "uPv" );
+ _uniform_model_gate_unlinked_uPvmPrev = glGetUniformLocation( _shader_model_gate_unlinked.id, "uPvmPrev" );
+ _uniform_model_gate_unlinked_uTime = glGetUniformLocation( _shader_model_gate_unlinked.id, "uTime" );
+ _uniform_model_gate_unlinked_uCam = glGetUniformLocation( _shader_model_gate_unlinked.id, "uCam" );
+ _uniform_model_gate_unlinked_uColour = glGetUniformLocation( _shader_model_gate_unlinked.id, "uColour" );
+ _uniform_model_font_uMdl = glGetUniformLocation( _shader_model_font.id, "uMdl" );
+ _uniform_model_font_uPv = glGetUniformLocation( _shader_model_font.id, "uPv" );
+ _uniform_model_font_uPvmPrev = glGetUniformLocation( _shader_model_font.id, "uPvmPrev" );
+ _uniform_model_font_uOffset = glGetUniformLocation( _shader_model_font.id, "uOffset" );
+ _uniform_model_font_uTexMain = glGetUniformLocation( _shader_model_font.id, "uTexMain" );
+ _uniform_model_font_uColour = glGetUniformLocation( _shader_model_font.id, "uColour" );
+ _uniform_model_font_uTexSceneDepth = glGetUniformLocation( _shader_model_font.id, "uTexSceneDepth" );
+ _uniform_model_font_uInverseRatioDepth = glGetUniformLocation( _shader_model_font.id, "uInverseRatioDepth" );
+ _uniform_model_font_uInverseRatioMain = glGetUniformLocation( _shader_model_font.id, "uInverseRatioMain" );
+ _uniform_model_font_uDepthCompare = glGetUniformLocation( _shader_model_font.id, "uDepthCompare" );
+ _uniform_particle_uPv = glGetUniformLocation( _shader_particle.id, "uPv" );
+ _uniform_particle_uPvPrev = glGetUniformLocation( _shader_particle.id, "uPvPrev" );
+ _uniform_trail_uPv = glGetUniformLocation( _shader_trail.id, "uPv" );
+ _uniform_trail_uPvPrev = glGetUniformLocation( _shader_trail.id, "uPvPrev" );
+ _uniform_trail_uColour = glGetUniformLocation( _shader_trail.id, "uColour" );
+ _uniform_blit_uInverseRatio = glGetUniformLocation( _shader_blit.id, "uInverseRatio" );
+ _uniform_blit_uTexMain = glGetUniformLocation( _shader_blit.id, "uTexMain" );
+ _uniform_blitblur_uInverseRatio = glGetUniformLocation( _shader_blitblur.id, "uInverseRatio" );
+ _uniform_blitblur_uTexMain = glGetUniformLocation( _shader_blitblur.id, "uTexMain" );
+ _uniform_blitblur_uTexMotion = glGetUniformLocation( _shader_blitblur.id, "uTexMotion" );
+ _uniform_blitblur_uBlurStrength = glGetUniformLocation( _shader_blitblur.id, "uBlurStrength" );
+ _uniform_blitblur_uOverrideDir = glGetUniformLocation( _shader_blitblur.id, "uOverrideDir" );
+ _uniform_blitblur_uTime = glGetUniformLocation( _shader_blitblur.id, "uTime" );
+ _uniform_blitblur_uGlitchStrength = glGetUniformLocation( _shader_blitblur.id, "uGlitchStrength" );
+ _uniform_blitblur_uClampUv = glGetUniformLocation( _shader_blitblur.id, "uClampUv" );
+ _uniform_blitcolour_uInverseRatio = glGetUniformLocation( _shader_blitcolour.id, "uInverseRatio" );
+ _uniform_blitcolour_uColour = glGetUniformLocation( _shader_blitcolour.id, "uColour" );
+ _uniform_blit_transition_uInverseRatio = glGetUniformLocation( _shader_blit_transition.id, "uInverseRatio" );
+ _uniform_blit_transition_uT = glGetUniformLocation( _shader_blit_transition.id, "uT" );
+ _uniform_routeui_uOffset = glGetUniformLocation( _shader_routeui.id, "uOffset" );
+ _uniform_routeui_uColour = glGetUniformLocation( _shader_routeui.id, "uColour" );
+}
+
+void vg_auto_shader_register(void)
+{
+ vg_shader_register( &_shader_scene_standard );
+ vg_shader_register( &_shader_scene_standard_alphatest );
+ vg_shader_register( &_shader_scene_foliage );
+ vg_shader_register( &_shader_scene_override );
+ vg_shader_register( &_shader_scene_fxglow );
+ vg_shader_register( &_shader_scene_vertex_blend );
+ vg_shader_register( &_shader_scene_terrain );
+ vg_shader_register( &_shader_scene_route );
+ vg_shader_register( &_shader_scene_depth );
+ vg_shader_register( &_shader_scene_position );
+ vg_shader_register( &_shader_scene_cubemapped );
+ vg_shader_register( &_shader_scene_water );
+ vg_shader_register( &_shader_scene_water_fast );
+ vg_shader_register( &_shader_scene_scoretext );
+ vg_shader_register( &_shader_scene_font );
+ vg_shader_register( &_shader_model_sky );
+ vg_shader_register( &_shader_model_sky_space );
+ vg_shader_register( &_shader_model_menu );
+ vg_shader_register( &_shader_model_character_view );
+ vg_shader_register( &_shader_model_board_view );
+ vg_shader_register( &_shader_model_entity );
+ vg_shader_register( &_shader_model_gate );
+ vg_shader_register( &_shader_model_gate_unlinked );
+ vg_shader_register( &_shader_model_font );
+ vg_shader_register( &_shader_particle );
+ vg_shader_register( &_shader_trail );
+ vg_shader_register( &_shader_blit );
+ vg_shader_register( &_shader_blitblur );
+ vg_shader_register( &_shader_blitcolour );
+ vg_shader_register( &_shader_blit_transition );
+ vg_shader_register( &_shader_routeui );
+}
+
-#ifndef SHADER_model_board_view_H
-#define SHADER_model_board_view_H
-static void shader_model_board_view_link(void);
-static void shader_model_board_view_register(void);
-static struct vg_shader _shader_model_board_view = {
- .name = "model_board_view",
- .link = shader_model_board_view_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_model_board_view;
+extern GLuint _uniform_model_board_view_uMdl;
+extern GLuint _uniform_model_board_view_uPv;
+extern GLuint _uniform_model_board_view_uPvmPrev;
+extern GLuint _uniform_model_board_view_uTexMain;
+extern GLuint _uniform_model_board_view_uCamera;
+extern GLuint _uniform_model_board_view_g_world_depth;
+extern GLuint _uniform_model_board_view_uLightsArray;
+extern GLuint _uniform_model_board_view_uLightsIndex;
+extern GLuint _uniform_model_board_view_uTexSceneDepth;
+extern GLuint _uniform_model_board_view_uInverseRatioDepth;
+extern GLuint _uniform_model_board_view_uInverseRatioMain;
+extern GLuint _uniform_model_board_view_uDepthCompare;
+static inline void shader_model_board_view_uMdl(m4x3f m)
{
-.orig_file = "shaders/model.vs",
-.static_src =
-"layout (location=0) in vec3 a_co;\n"
-"layout (location=1) in vec3 a_norm;\n"
-"layout (location=2) in vec2 a_uv;\n"
-"layout (location=3) in vec4 a_colour;\n"
-"layout (location=4) in vec4 a_weights;\n"
-"layout (location=5) in ivec4 a_groups;\n"
-"\n"
-"#line 1 1 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"out vec3 aMotionVec0;\n"
-"out vec3 aMotionVec1;\n"
-"\n"
-"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
-"{\n"
-" // This magically solves some artifacting errors!\n"
-" //\n"
-" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
-"\n"
-" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
-" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"\n"
-"uniform mat4x3 uMdl;\n"
-"uniform mat4 uPv;\n"
-"uniform mat4 uPvmPrev;\n"
-"\n"
-"out vec4 aColour;\n"
-"out vec2 aUv;\n"
-"out vec3 aNorm;\n"
-"out vec3 aCo;\n"
-"out vec3 aWorldCo;\n"
-"\n"
-"void main()\n"
-"{\n"
-" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
-" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
-" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
-"\n"
-" vs_motion_out( vproj0, vproj1 );\n"
-"\n"
-" gl_Position = vproj0;\n"
-" aWorldCo = world_pos0;\n"
-" aColour = a_colour;\n"
-" aUv = a_uv;\n"
-" aNorm = normalize( mat3(uMdl) * a_norm );\n"
-" aCo = a_co;\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/model_character_view.fs",
-.static_src =
-"uniform sampler2D uTexMain;\n"
-"uniform vec3 uCamera;\n"
-"\n"
-"in vec4 aColour;\n"
-"in vec2 aUv;\n"
-"in vec3 aNorm;\n"
-"in vec3 aCo;\n"
-"in vec3 aWorldCo;\n"
-"\n"
-"#line 1 1 \n"
-"// :D\n"
-"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
-"\n"
-"#line 11 0 \n"
-"#line 1 2 \n"
-"layout (location = 0) out vec4 oColour;\n"
-"\n"
-"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
-"layout (std140) uniform ub_world_lighting\n"
-"{\n"
-" vec4 g_cube_min;\n"
-" vec4 g_cube_inv_range;\n"
-"\n"
-" vec4 g_water_plane;\n"
-" vec4 g_depth_bounds;\n"
-"\n"
-" vec4 g_daysky_colour;\n"
-" vec4 g_nightsky_colour;\n"
-" vec4 g_sunset_colour;\n"
-" vec4 g_ambient_colour;\n"
-" vec4 g_sunset_ambient;\n"
-" vec4 g_sun_colour;\n"
-" vec4 g_sun_dir;\n"
-" vec4 g_board_0;\n"
-" vec4 g_board_1;\n"
-"\n"
-" float g_water_fog;\n"
-" float g_time;\n"
-" float g_realtime;\n"
-" float g_shadow_length;\n"
-" float g_shadow_spread;\n"
-"\n"
-" float g_time_of_day;\n"
-" float g_day_phase;\n"
-" float g_sunset_phase;\n"
-"\n"
-" int g_light_preview;\n"
-" int g_shadow_samples;\n"
-"\n"
-" int g_debug_indices;\n"
-" int g_debug_complexity;\n"
-"};\n"
-"\n"
-"uniform sampler2D g_world_depth;\n"
-"uniform samplerBuffer uLightsArray;\n"
-"uniform usampler3D uLightsIndex;\n"
-"\n"
-"#line 1 1 \n"
-"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
-"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
-"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
-"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
-"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
-"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
-"\n"
-"const float SUN_ANGLE = 0.0001;\n"
-"const float PI = 3.14159265358979323846264;\n"
-"\n"
-"//struct world_info\n"
-"//{\n"
-"// float time,\n"
-"// time_of_day,\n"
-"// day_phase,\n"
-"// sunset_phase;\n"
-"// \n"
-"// vec3 sun_dir;\n"
-"//};\n"
-"\n"
-"vec3 rand33(vec3 p3)\n"
-"{\n"
-" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
-" p3 += dot(p3, p3.yxz+33.33);\n"
-" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
-"}\n"
-"\n"
-"float stars( vec3 rd, float rr, float size ){\n"
-" vec3 co = rd * rr;\n"
-"\n"
-" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
-"\n"
-" float spaces = 1.0 / rr;\n"
-" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
-" a -= mod(a, spaces) - spaces * 0.5;\n"
-"\n"
-" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
-" \n"
-" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
-" plane = plane - mod(plane, PI / count);\n"
-"\n"
-" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
-"\n"
-" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
-" float ydist = sqrt(rr * rr - level * level);\n"
-" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
-" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
-" float star = smoothstep(size, 0.0, distance(center, co));\n"
-" return star;\n"
-"}\n"
-"\n"
-"float luminance( vec3 v )\n"
-"{\n"
-" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
-"}\n"
-"\n"
-"vec3 clearskies_ambient( vec3 dir )\n"
-"{\n"
-" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
-" float sky_gradient = dir.y;\n"
-" \n"
-" /* Blend phase colours */\n"
-" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
-" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
-" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
-" \n"
-" /* Add gradient */\n"
-" ambient -= sky_gradient * luminance(ambient);\n"
-" \n"
-" return ambient;\n"
-"}\n"
-"\n"
-"vec3 clearskies_sky( vec3 ray_dir )\n"
-"{\n"
-" ray_dir.y = abs( ray_dir.y );\n"
-" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
-" \n"
-" /* Sun */\n"
-" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
-" float sun_shape = pow( sun_size, 2000.0 );\n"
-" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" \n"
-" float star = 0.0;\n"
-" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
-"\n"
-" if( star_blend > 0.001 ){\n"
-" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
-" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
-" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
-" }\n"
-" }\n"
-" \n"
-" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
-" return composite;\n"
-"}\n"
-"\n"
-"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
-"{\n"
-" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
-"\n"
-" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
-" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
-" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
-" ) * g_sun_colour.rgb * g_day_phase;\n"
-"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
-" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" return ambient + (light_sun + sky_reflection) * shadow;\n"
-"}\n"
-"\n"
-"#line 44 0 \n"
-"\n"
-"float world_depth_sample( vec3 pos )\n"
-"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
-" return texture( g_world_depth, depth_coord ).r;\n"
-"}\n"
-"\n"
-"float world_water_depth( vec3 pos )\n"
-"{\n"
-" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return world_depth_sample( pos ) - ref_depth;\n"
-"}\n"
-"\n"
-"float shadow_sample( vec3 co ){\n"
-" float height_sample = world_depth_sample( co );\n"
-"\n"
-" float fdelta = height_sample - co.y;\n"
-" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
-"}\n"
-"\n"
-"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
-" if( g_shadow_samples == 0 ){\n"
-" return 1.0;\n"
-" }\n"
-"\n"
-" float fspread = g_shadow_spread;\n"
-" float flength = g_shadow_length;\n"
-"\n"
-" float famt = 0.0;\n"
-" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
-"\n"
-" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
-"\n"
-" return 1.0 - famt;\n"
-"}\n"
-"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
-"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
-"}\n"
-"\n"
-"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
-" float dist = pow(fdist*0.0010,0.78);\n"
-" return mix( vfrag, colour, min( 1.0, dist ) );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_light( int light_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
-" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
-" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
-"\n"
-" vec3 light_delta = light_co.xyz-co;\n"
-" float dist2 = dot(light_delta,light_delta);\n"
-"\n"
-" light_delta = normalize( light_delta );\n"
-"\n"
-" float quadratic = dist2*100.0;\n"
-" float attenuation = 1.0/( 1.0 + quadratic );\n"
-" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
-"\n"
-" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
-"\n"
-" if( light_dir.w < 0.999999 ){\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
-" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
-" }\n"
-"\n"
-" return light_colour.rgb * attenuation * falloff \n"
-" * step( g_day_phase, light_colour.w );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" uint light_count = packed_index & 0x3u;\n"
-"\n"
-" vec3 l = vec3(0.0);\n"
-"\n"
-" if( light_count >= 1u ){\n"
-" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
-" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
-" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
-"\n"
-" l += scene_calculate_light( index_0, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 2u ){\n"
-" l += scene_calculate_light( index_1, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 3u ){\n"
-" l += scene_calculate_light( index_2, halfview, co, normal );\n"
-" }\n"
-" }\n"
-" }\n"
-"\n"
-" return l;\n"
-"}\n"
-"\n"
-"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
-" float light_mask )\n"
-"{\n"
-" if( g_light_preview == 1 )\n"
-" diffuse = vec3(0.75);\n"
-"\n"
-" // Lighting\n"
-" vec3 halfview = uCamera - co;\n"
-" float fdist = length(halfview);\n"
-" halfview /= fdist;\n"
-"\n"
-" float world_shadow = newlight_compute_sun_shadow( \n"
-" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
-"\n"
-" vec3 total_light = clearskies_lighting( \n"
-" normal, min( light_mask, world_shadow ), halfview );\n"
-"\n"
-" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
-" cube_coord = floor( cube_coord );\n"
-"\n"
-" if( g_debug_indices == 1 )\n"
-" {\n"
-" return rand33(cube_coord);\n"
-" }\n"
-"\n"
-" if( g_debug_complexity == 1 )\n"
-" {\n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
-" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
-" }\n"
-"\n"
-" // FIXME: this coord should absolutely must be clamped!\n"
-" \n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, co, normal ) \n"
-" * light_mask;\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, co, normal )\n"
-" * light_mask;\n"
-"\n"
-" // Take a section of the sky function to give us a matching fog colour\n"
-"\n"
-" vec3 fog_colour = clearskies_ambient( -halfview );\n"
-" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
-" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" fog_colour += sun_colour;\n"
-" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
-"}\n"
-"\n"
-"#line 12 0 \n"
-"#line 1 3 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"layout (location = 1) out vec2 oMotionVec;\n"
-"\n"
-"in vec3 aMotionVec0;\n"
-"in vec3 aMotionVec1;\n"
-"\n"
-"void compute_motion_vectors()\n"
-"{\n"
-" // Write motion vectors\n"
-" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
-" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
-"\n"
-" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
-"}\n"
-"\n"
-"#line 13 0 \n"
-"#line 1 4 \n"
-"uniform sampler2D uTexSceneDepth;\n"
-"uniform vec3 uInverseRatioDepth;\n"
-"uniform vec3 uInverseRatioMain;\n"
-"uniform bool uDepthCompare;\n"
-"\n"
-"float linear_depth( float depth, float near, float far ) {\n"
-" float z = depth * 2.0 - 1.0;\n"
-" return (2.0 * near * far) / (far + near - z * (far - near)); \n"
-"}\n"
-"\n"
-"void depth_compare_dither(){\n"
-" if( uDepthCompare ){\n"
-" vec2 back_coord = gl_FragCoord.xy * uInverseRatioMain.xy \n"
-" * uInverseRatioDepth.xy;\n"
-" float back_depth = texture( uTexSceneDepth, back_coord ).r;\n"
-" float front_depth = gl_FragCoord.z/gl_FragCoord.w;\n"
-"\n"
-" back_depth = linear_depth( back_depth, 0.1, 2100.0 );\n"
-" float diff = back_depth - front_depth;\n"
-"\n"
-" vec2 ssuv = gl_FragCoord.xy;\n"
-" vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), ssuv) );\n"
-" float dither = fract( vDither.g / 71.0 ) - 0.5;\n"
-"\n"
-" if( step(0.0,diff)+dither<0.3 )\n"
-" discard;\n"
-" }\n"
-"}\n"
-"\n"
-"#line 14 0 \n"
-"\n"
-"vec3 character_clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
-"{\n"
-" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
-"\n"
-" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-"\n"
-" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
-" vec3 light_sun = max(0.0, dot(normal,g_sun_dir.xyz)*0.5+0.5) \n"
-" * g_sun_colour.rgb * g_day_phase;\n"
-"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
-" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" return ambient + (light_sun + sky_reflection) * shadow;\n"
-"}\n"
-"\n"
-"vec3 character_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
-" float light_mask )\n"
-"{\n"
-" if( g_light_preview == 1 )\n"
-" diffuse = vec3(0.75);\n"
-"\n"
-" // Lighting\n"
-" vec3 halfview = uCamera - co;\n"
-" float fdist = length(halfview);\n"
-" halfview /= fdist;\n"
-"\n"
-" float world_shadow = newlight_compute_sun_shadow( \n"
-" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
-"\n"
-" vec3 total_light = character_clearskies_lighting( \n"
-" normal, min( light_mask, world_shadow ), halfview );\n"
-"\n"
-" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
-" cube_coord = floor( cube_coord );\n"
-"\n"
-" if( g_debug_indices == 1 )\n"
-" {\n"
-" return rand33(cube_coord);\n"
-" }\n"
-"\n"
-" if( g_debug_complexity == 1 )\n"
-" {\n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
-" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
-" }\n"
-"\n"
-" // FIXME: this coord should absolutely must be clamped!\n"
-" \n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, co, normal ) \n"
-" * light_mask;\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, co, normal )\n"
-" * light_mask;\n"
-"\n"
-" // Take a section of the sky function to give us a matching fog colour\n"
-"\n"
-" vec3 fog_colour = clearskies_ambient( -halfview );\n"
-" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
-" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" fog_colour += sun_colour;\n"
-" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
-"}\n"
-"\n"
-"void main(){\n"
-" depth_compare_dither();\n"
-" compute_motion_vectors();\n"
-"\n"
-" vec3 qnorm = aNorm;\n"
-" vec3 diffuse = texture( uTexMain, aUv ).rgb;\n"
-" vec3 composite = character_compute_lighting( diffuse, qnorm, aWorldCo, 1.0 );\n"
-"\n"
-" float dist = distance( aWorldCo, uCamera ) - 0.08;\n"
-" float opacity = clamp( dist*dist, 0.0, 1.0 );\n"
-"\n"
-" oColour = vec4( composite, opacity );\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_model_board_view_uMdl;
-static GLuint _uniform_model_board_view_uPv;
-static GLuint _uniform_model_board_view_uPvmPrev;
-static GLuint _uniform_model_board_view_uTexMain;
-static GLuint _uniform_model_board_view_uCamera;
-static GLuint _uniform_model_board_view_g_world_depth;
-static GLuint _uniform_model_board_view_uLightsArray;
-static GLuint _uniform_model_board_view_uLightsIndex;
-static GLuint _uniform_model_board_view_uTexSceneDepth;
-static GLuint _uniform_model_board_view_uInverseRatioDepth;
-static GLuint _uniform_model_board_view_uInverseRatioMain;
-static GLuint _uniform_model_board_view_uDepthCompare;
-static void shader_model_board_view_uMdl(m4x3f m){
- glUniformMatrix4x3fv(_uniform_model_board_view_uMdl,1,GL_FALSE,(float*)m);
+ glUniformMatrix4x3fv(_uniform_model_board_view_uMdl,1,GL_FALSE,(f32*)m);
}
-static void shader_model_board_view_uPv(m4x4f m){
- glUniformMatrix4fv(_uniform_model_board_view_uPv,1,GL_FALSE,(float*)m);
+static inline void shader_model_board_view_uPv(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_model_board_view_uPv,1,GL_FALSE,(f32*)m);
}
-static void shader_model_board_view_uPvmPrev(m4x4f m){
- glUniformMatrix4fv(_uniform_model_board_view_uPvmPrev,1,GL_FALSE,(float*)m);
+static inline void shader_model_board_view_uPvmPrev(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_model_board_view_uPvmPrev,1,GL_FALSE,(f32*)m);
}
-static void shader_model_board_view_uTexMain(int i){
+static inline void shader_model_board_view_uTexMain(int i)
+{
glUniform1i(_uniform_model_board_view_uTexMain,i);
}
-static void shader_model_board_view_uCamera(v3f v){
+static inline void shader_model_board_view_uCamera(v3f v)
+{
glUniform3fv(_uniform_model_board_view_uCamera,1,v);
}
-static void shader_model_board_view_g_world_depth(int i){
+static inline void shader_model_board_view_g_world_depth(int i)
+{
glUniform1i(_uniform_model_board_view_g_world_depth,i);
}
-static void shader_model_board_view_uTexSceneDepth(int i){
+static inline void shader_model_board_view_uTexSceneDepth(int i)
+{
glUniform1i(_uniform_model_board_view_uTexSceneDepth,i);
}
-static void shader_model_board_view_uInverseRatioDepth(v3f v){
+static inline void shader_model_board_view_uInverseRatioDepth(v3f v)
+{
glUniform3fv(_uniform_model_board_view_uInverseRatioDepth,1,v);
}
-static void shader_model_board_view_uInverseRatioMain(v3f v){
+static inline void shader_model_board_view_uInverseRatioMain(v3f v)
+{
glUniform3fv(_uniform_model_board_view_uInverseRatioMain,1,v);
}
-static void shader_model_board_view_uDepthCompare(int b){
+static inline void shader_model_board_view_uDepthCompare(int b)
+{
glUniform1i(_uniform_model_board_view_uDepthCompare,b);
}
-static void shader_model_board_view_register(void){
- vg_shader_register( &_shader_model_board_view );
-}
-static void shader_model_board_view_use(void){ glUseProgram(_shader_model_board_view.id); }
-static void shader_model_board_view_link(void){
- _uniform_model_board_view_uMdl = glGetUniformLocation( _shader_model_board_view.id, "uMdl" );
- _uniform_model_board_view_uPv = glGetUniformLocation( _shader_model_board_view.id, "uPv" );
- _uniform_model_board_view_uPvmPrev = glGetUniformLocation( _shader_model_board_view.id, "uPvmPrev" );
- _uniform_model_board_view_uTexMain = glGetUniformLocation( _shader_model_board_view.id, "uTexMain" );
- _uniform_model_board_view_uCamera = glGetUniformLocation( _shader_model_board_view.id, "uCamera" );
- _uniform_model_board_view_g_world_depth = glGetUniformLocation( _shader_model_board_view.id, "g_world_depth" );
- _uniform_model_board_view_uLightsArray = glGetUniformLocation( _shader_model_board_view.id, "uLightsArray" );
- _uniform_model_board_view_uLightsIndex = glGetUniformLocation( _shader_model_board_view.id, "uLightsIndex" );
- _uniform_model_board_view_uTexSceneDepth = glGetUniformLocation( _shader_model_board_view.id, "uTexSceneDepth" );
- _uniform_model_board_view_uInverseRatioDepth = glGetUniformLocation( _shader_model_board_view.id, "uInverseRatioDepth" );
- _uniform_model_board_view_uInverseRatioMain = glGetUniformLocation( _shader_model_board_view.id, "uInverseRatioMain" );
- _uniform_model_board_view_uDepthCompare = glGetUniformLocation( _shader_model_board_view.id, "uDepthCompare" );
+static inline void shader_model_board_view_use(void);
+static inline void shader_model_board_view_use(void)
+{
+ glUseProgram(_shader_model_board_view.id);
}
-#endif /* SHADER_model_board_view_H */
-#ifndef SHADER_model_character_view_H
-#define SHADER_model_character_view_H
-static void shader_model_character_view_link(void);
-static void shader_model_character_view_register(void);
-static struct vg_shader _shader_model_character_view = {
- .name = "model_character_view",
- .link = shader_model_character_view_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_model_character_view;
+extern GLuint _uniform_model_character_view_uPv;
+extern GLuint _uniform_model_character_view_uTransforms;
+extern GLuint _uniform_model_character_view_uTexMain;
+extern GLuint _uniform_model_character_view_uCamera;
+extern GLuint _uniform_model_character_view_g_world_depth;
+extern GLuint _uniform_model_character_view_uLightsArray;
+extern GLuint _uniform_model_character_view_uLightsIndex;
+extern GLuint _uniform_model_character_view_uTexSceneDepth;
+extern GLuint _uniform_model_character_view_uInverseRatioDepth;
+extern GLuint _uniform_model_character_view_uInverseRatioMain;
+extern GLuint _uniform_model_character_view_uDepthCompare;
+static inline void shader_model_character_view_uPv(m4x4f m)
{
-.orig_file = "shaders/model_skinned.vs",
-.static_src =
-"layout (location=0) in vec3 a_co;\n"
-"layout (location=1) in vec3 a_norm;\n"
-"layout (location=2) in vec2 a_uv;\n"
-"layout (location=3) in vec4 a_colour;\n"
-"layout (location=4) in vec4 a_weights;\n"
-"layout (location=5) in ivec4 a_groups;\n"
-"\n"
-"#line 1 1 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"out vec3 aMotionVec0;\n"
-"out vec3 aMotionVec1;\n"
-"\n"
-"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
-"{\n"
-" // This magically solves some artifacting errors!\n"
-" //\n"
-" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
-"\n"
-" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
-" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"\n"
-"uniform mat4 uPv;\n"
-"uniform mat4x3 uTransforms[32];\n"
-"\n"
-"out vec4 aColour;\n"
-"out vec2 aUv;\n"
-"out vec3 aNorm;\n"
-"out vec3 aCo;\n"
-"out vec3 aWorldCo;\n"
-"\n"
-"void main()\n"
-"{\n"
-" vec4 co_local = vec4( a_co, 1.0 );\n"
-" vec3 co0 = uTransforms[ a_groups[0] ] * co_local;\n"
-" vec3 co1 = uTransforms[ a_groups[1] ] * co_local;\n"
-" vec3 co2 = uTransforms[ a_groups[2] ] * co_local;\n"
-" vec3 n0 = mat3(uTransforms[ a_groups[0] ]) * a_norm;\n"
-" vec3 n1 = mat3(uTransforms[ a_groups[1] ]) * a_norm;\n"
-" vec3 n2 = mat3(uTransforms[ a_groups[2] ]) * a_norm;\n"
-"\n"
-" vec3 world_pos = co0*a_weights[0] + co1*a_weights[1] + co2*a_weights[2];\n"
-" vec3 world_normal = n0*a_weights[0] + n1*a_weights[1] + n2*a_weights[2];\n"
-" \n"
-" gl_Position = uPv * vec4( world_pos, 1.0 );\n"
-" aColour = a_colour;\n"
-" aUv = a_uv;\n"
-" aNorm = world_normal;\n"
-" aCo = a_co;\n"
-" aWorldCo = world_pos;\n"
-"\n"
-" // TODO: motion vectors\n"
-" aMotionVec0 = vec3(1.0);\n"
-" aMotionVec1 = vec3(1.0);\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/model_character_view.fs",
-.static_src =
-"uniform sampler2D uTexMain;\n"
-"uniform vec3 uCamera;\n"
-"\n"
-"in vec4 aColour;\n"
-"in vec2 aUv;\n"
-"in vec3 aNorm;\n"
-"in vec3 aCo;\n"
-"in vec3 aWorldCo;\n"
-"\n"
-"#line 1 1 \n"
-"// :D\n"
-"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
-"\n"
-"#line 11 0 \n"
-"#line 1 2 \n"
-"layout (location = 0) out vec4 oColour;\n"
-"\n"
-"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
-"layout (std140) uniform ub_world_lighting\n"
-"{\n"
-" vec4 g_cube_min;\n"
-" vec4 g_cube_inv_range;\n"
-"\n"
-" vec4 g_water_plane;\n"
-" vec4 g_depth_bounds;\n"
-"\n"
-" vec4 g_daysky_colour;\n"
-" vec4 g_nightsky_colour;\n"
-" vec4 g_sunset_colour;\n"
-" vec4 g_ambient_colour;\n"
-" vec4 g_sunset_ambient;\n"
-" vec4 g_sun_colour;\n"
-" vec4 g_sun_dir;\n"
-" vec4 g_board_0;\n"
-" vec4 g_board_1;\n"
-"\n"
-" float g_water_fog;\n"
-" float g_time;\n"
-" float g_realtime;\n"
-" float g_shadow_length;\n"
-" float g_shadow_spread;\n"
-"\n"
-" float g_time_of_day;\n"
-" float g_day_phase;\n"
-" float g_sunset_phase;\n"
-"\n"
-" int g_light_preview;\n"
-" int g_shadow_samples;\n"
-"\n"
-" int g_debug_indices;\n"
-" int g_debug_complexity;\n"
-"};\n"
-"\n"
-"uniform sampler2D g_world_depth;\n"
-"uniform samplerBuffer uLightsArray;\n"
-"uniform usampler3D uLightsIndex;\n"
-"\n"
-"#line 1 1 \n"
-"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
-"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
-"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
-"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
-"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
-"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
-"\n"
-"const float SUN_ANGLE = 0.0001;\n"
-"const float PI = 3.14159265358979323846264;\n"
-"\n"
-"//struct world_info\n"
-"//{\n"
-"// float time,\n"
-"// time_of_day,\n"
-"// day_phase,\n"
-"// sunset_phase;\n"
-"// \n"
-"// vec3 sun_dir;\n"
-"//};\n"
-"\n"
-"vec3 rand33(vec3 p3)\n"
-"{\n"
-" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
-" p3 += dot(p3, p3.yxz+33.33);\n"
-" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
-"}\n"
-"\n"
-"float stars( vec3 rd, float rr, float size ){\n"
-" vec3 co = rd * rr;\n"
-"\n"
-" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
-"\n"
-" float spaces = 1.0 / rr;\n"
-" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
-" a -= mod(a, spaces) - spaces * 0.5;\n"
-"\n"
-" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
-" \n"
-" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
-" plane = plane - mod(plane, PI / count);\n"
-"\n"
-" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
-"\n"
-" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
-" float ydist = sqrt(rr * rr - level * level);\n"
-" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
-" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
-" float star = smoothstep(size, 0.0, distance(center, co));\n"
-" return star;\n"
-"}\n"
-"\n"
-"float luminance( vec3 v )\n"
-"{\n"
-" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
-"}\n"
-"\n"
-"vec3 clearskies_ambient( vec3 dir )\n"
-"{\n"
-" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
-" float sky_gradient = dir.y;\n"
-" \n"
-" /* Blend phase colours */\n"
-" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
-" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
-" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
-" \n"
-" /* Add gradient */\n"
-" ambient -= sky_gradient * luminance(ambient);\n"
-" \n"
-" return ambient;\n"
-"}\n"
-"\n"
-"vec3 clearskies_sky( vec3 ray_dir )\n"
-"{\n"
-" ray_dir.y = abs( ray_dir.y );\n"
-" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
-" \n"
-" /* Sun */\n"
-" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
-" float sun_shape = pow( sun_size, 2000.0 );\n"
-" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" \n"
-" float star = 0.0;\n"
-" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
-"\n"
-" if( star_blend > 0.001 ){\n"
-" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
-" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
-" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
-" }\n"
-" }\n"
-" \n"
-" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
-" return composite;\n"
-"}\n"
-"\n"
-"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
-"{\n"
-" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
-"\n"
-" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
-" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
-" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
-" ) * g_sun_colour.rgb * g_day_phase;\n"
-"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
-" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" return ambient + (light_sun + sky_reflection) * shadow;\n"
-"}\n"
-"\n"
-"#line 44 0 \n"
-"\n"
-"float world_depth_sample( vec3 pos )\n"
-"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
-" return texture( g_world_depth, depth_coord ).r;\n"
-"}\n"
-"\n"
-"float world_water_depth( vec3 pos )\n"
-"{\n"
-" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return world_depth_sample( pos ) - ref_depth;\n"
-"}\n"
-"\n"
-"float shadow_sample( vec3 co ){\n"
-" float height_sample = world_depth_sample( co );\n"
-"\n"
-" float fdelta = height_sample - co.y;\n"
-" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
-"}\n"
-"\n"
-"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
-" if( g_shadow_samples == 0 ){\n"
-" return 1.0;\n"
-" }\n"
-"\n"
-" float fspread = g_shadow_spread;\n"
-" float flength = g_shadow_length;\n"
-"\n"
-" float famt = 0.0;\n"
-" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
-"\n"
-" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
-"\n"
-" return 1.0 - famt;\n"
-"}\n"
-"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
-"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
-"}\n"
-"\n"
-"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
-" float dist = pow(fdist*0.0010,0.78);\n"
-" return mix( vfrag, colour, min( 1.0, dist ) );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_light( int light_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
-" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
-" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
-"\n"
-" vec3 light_delta = light_co.xyz-co;\n"
-" float dist2 = dot(light_delta,light_delta);\n"
-"\n"
-" light_delta = normalize( light_delta );\n"
-"\n"
-" float quadratic = dist2*100.0;\n"
-" float attenuation = 1.0/( 1.0 + quadratic );\n"
-" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
-"\n"
-" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
-"\n"
-" if( light_dir.w < 0.999999 ){\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
-" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
-" }\n"
-"\n"
-" return light_colour.rgb * attenuation * falloff \n"
-" * step( g_day_phase, light_colour.w );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" uint light_count = packed_index & 0x3u;\n"
-"\n"
-" vec3 l = vec3(0.0);\n"
-"\n"
-" if( light_count >= 1u ){\n"
-" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
-" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
-" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
-"\n"
-" l += scene_calculate_light( index_0, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 2u ){\n"
-" l += scene_calculate_light( index_1, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 3u ){\n"
-" l += scene_calculate_light( index_2, halfview, co, normal );\n"
-" }\n"
-" }\n"
-" }\n"
-"\n"
-" return l;\n"
-"}\n"
-"\n"
-"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
-" float light_mask )\n"
-"{\n"
-" if( g_light_preview == 1 )\n"
-" diffuse = vec3(0.75);\n"
-"\n"
-" // Lighting\n"
-" vec3 halfview = uCamera - co;\n"
-" float fdist = length(halfview);\n"
-" halfview /= fdist;\n"
-"\n"
-" float world_shadow = newlight_compute_sun_shadow( \n"
-" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
-"\n"
-" vec3 total_light = clearskies_lighting( \n"
-" normal, min( light_mask, world_shadow ), halfview );\n"
-"\n"
-" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
-" cube_coord = floor( cube_coord );\n"
-"\n"
-" if( g_debug_indices == 1 )\n"
-" {\n"
-" return rand33(cube_coord);\n"
-" }\n"
-"\n"
-" if( g_debug_complexity == 1 )\n"
-" {\n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
-" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
-" }\n"
-"\n"
-" // FIXME: this coord should absolutely must be clamped!\n"
-" \n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, co, normal ) \n"
-" * light_mask;\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, co, normal )\n"
-" * light_mask;\n"
-"\n"
-" // Take a section of the sky function to give us a matching fog colour\n"
-"\n"
-" vec3 fog_colour = clearskies_ambient( -halfview );\n"
-" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
-" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" fog_colour += sun_colour;\n"
-" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
-"}\n"
-"\n"
-"#line 12 0 \n"
-"#line 1 3 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"layout (location = 1) out vec2 oMotionVec;\n"
-"\n"
-"in vec3 aMotionVec0;\n"
-"in vec3 aMotionVec1;\n"
-"\n"
-"void compute_motion_vectors()\n"
-"{\n"
-" // Write motion vectors\n"
-" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
-" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
-"\n"
-" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
-"}\n"
-"\n"
-"#line 13 0 \n"
-"#line 1 4 \n"
-"uniform sampler2D uTexSceneDepth;\n"
-"uniform vec3 uInverseRatioDepth;\n"
-"uniform vec3 uInverseRatioMain;\n"
-"uniform bool uDepthCompare;\n"
-"\n"
-"float linear_depth( float depth, float near, float far ) {\n"
-" float z = depth * 2.0 - 1.0;\n"
-" return (2.0 * near * far) / (far + near - z * (far - near)); \n"
-"}\n"
-"\n"
-"void depth_compare_dither(){\n"
-" if( uDepthCompare ){\n"
-" vec2 back_coord = gl_FragCoord.xy * uInverseRatioMain.xy \n"
-" * uInverseRatioDepth.xy;\n"
-" float back_depth = texture( uTexSceneDepth, back_coord ).r;\n"
-" float front_depth = gl_FragCoord.z/gl_FragCoord.w;\n"
-"\n"
-" back_depth = linear_depth( back_depth, 0.1, 2100.0 );\n"
-" float diff = back_depth - front_depth;\n"
-"\n"
-" vec2 ssuv = gl_FragCoord.xy;\n"
-" vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), ssuv) );\n"
-" float dither = fract( vDither.g / 71.0 ) - 0.5;\n"
-"\n"
-" if( step(0.0,diff)+dither<0.3 )\n"
-" discard;\n"
-" }\n"
-"}\n"
-"\n"
-"#line 14 0 \n"
-"\n"
-"vec3 character_clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
-"{\n"
-" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
-"\n"
-" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-"\n"
-" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
-" vec3 light_sun = max(0.0, dot(normal,g_sun_dir.xyz)*0.5+0.5) \n"
-" * g_sun_colour.rgb * g_day_phase;\n"
-"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
-" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" return ambient + (light_sun + sky_reflection) * shadow;\n"
-"}\n"
-"\n"
-"vec3 character_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
-" float light_mask )\n"
-"{\n"
-" if( g_light_preview == 1 )\n"
-" diffuse = vec3(0.75);\n"
-"\n"
-" // Lighting\n"
-" vec3 halfview = uCamera - co;\n"
-" float fdist = length(halfview);\n"
-" halfview /= fdist;\n"
-"\n"
-" float world_shadow = newlight_compute_sun_shadow( \n"
-" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
-"\n"
-" vec3 total_light = character_clearskies_lighting( \n"
-" normal, min( light_mask, world_shadow ), halfview );\n"
-"\n"
-" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
-" cube_coord = floor( cube_coord );\n"
-"\n"
-" if( g_debug_indices == 1 )\n"
-" {\n"
-" return rand33(cube_coord);\n"
-" }\n"
-"\n"
-" if( g_debug_complexity == 1 )\n"
-" {\n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
-" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
-" }\n"
-"\n"
-" // FIXME: this coord should absolutely must be clamped!\n"
-" \n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, co, normal ) \n"
-" * light_mask;\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, co, normal )\n"
-" * light_mask;\n"
-"\n"
-" // Take a section of the sky function to give us a matching fog colour\n"
-"\n"
-" vec3 fog_colour = clearskies_ambient( -halfview );\n"
-" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
-" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" fog_colour += sun_colour;\n"
-" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
-"}\n"
-"\n"
-"void main(){\n"
-" depth_compare_dither();\n"
-" compute_motion_vectors();\n"
-"\n"
-" vec3 qnorm = aNorm;\n"
-" vec3 diffuse = texture( uTexMain, aUv ).rgb;\n"
-" vec3 composite = character_compute_lighting( diffuse, qnorm, aWorldCo, 1.0 );\n"
-"\n"
-" float dist = distance( aWorldCo, uCamera ) - 0.08;\n"
-" float opacity = clamp( dist*dist, 0.0, 1.0 );\n"
-"\n"
-" oColour = vec4( composite, opacity );\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_model_character_view_uPv;
-static GLuint _uniform_model_character_view_uTransforms;
-static GLuint _uniform_model_character_view_uTexMain;
-static GLuint _uniform_model_character_view_uCamera;
-static GLuint _uniform_model_character_view_g_world_depth;
-static GLuint _uniform_model_character_view_uLightsArray;
-static GLuint _uniform_model_character_view_uLightsIndex;
-static GLuint _uniform_model_character_view_uTexSceneDepth;
-static GLuint _uniform_model_character_view_uInverseRatioDepth;
-static GLuint _uniform_model_character_view_uInverseRatioMain;
-static GLuint _uniform_model_character_view_uDepthCompare;
-static void shader_model_character_view_uPv(m4x4f m){
- glUniformMatrix4fv(_uniform_model_character_view_uPv,1,GL_FALSE,(float*)m);
+ glUniformMatrix4fv(_uniform_model_character_view_uPv,1,GL_FALSE,(f32*)m);
}
-static void shader_model_character_view_uTexMain(int i){
+static inline void shader_model_character_view_uTexMain(int i)
+{
glUniform1i(_uniform_model_character_view_uTexMain,i);
}
-static void shader_model_character_view_uCamera(v3f v){
+static inline void shader_model_character_view_uCamera(v3f v)
+{
glUniform3fv(_uniform_model_character_view_uCamera,1,v);
}
-static void shader_model_character_view_g_world_depth(int i){
+static inline void shader_model_character_view_g_world_depth(int i)
+{
glUniform1i(_uniform_model_character_view_g_world_depth,i);
}
-static void shader_model_character_view_uTexSceneDepth(int i){
+static inline void shader_model_character_view_uTexSceneDepth(int i)
+{
glUniform1i(_uniform_model_character_view_uTexSceneDepth,i);
}
-static void shader_model_character_view_uInverseRatioDepth(v3f v){
+static inline void shader_model_character_view_uInverseRatioDepth(v3f v)
+{
glUniform3fv(_uniform_model_character_view_uInverseRatioDepth,1,v);
}
-static void shader_model_character_view_uInverseRatioMain(v3f v){
+static inline void shader_model_character_view_uInverseRatioMain(v3f v)
+{
glUniform3fv(_uniform_model_character_view_uInverseRatioMain,1,v);
}
-static void shader_model_character_view_uDepthCompare(int b){
+static inline void shader_model_character_view_uDepthCompare(int b)
+{
glUniform1i(_uniform_model_character_view_uDepthCompare,b);
}
-static void shader_model_character_view_register(void){
- vg_shader_register( &_shader_model_character_view );
-}
-static void shader_model_character_view_use(void){ glUseProgram(_shader_model_character_view.id); }
-static void shader_model_character_view_link(void){
- _uniform_model_character_view_uPv = glGetUniformLocation( _shader_model_character_view.id, "uPv" );
- _uniform_model_character_view_uTransforms = glGetUniformLocation( _shader_model_character_view.id, "uTransforms" );
- _uniform_model_character_view_uTexMain = glGetUniformLocation( _shader_model_character_view.id, "uTexMain" );
- _uniform_model_character_view_uCamera = glGetUniformLocation( _shader_model_character_view.id, "uCamera" );
- _uniform_model_character_view_g_world_depth = glGetUniformLocation( _shader_model_character_view.id, "g_world_depth" );
- _uniform_model_character_view_uLightsArray = glGetUniformLocation( _shader_model_character_view.id, "uLightsArray" );
- _uniform_model_character_view_uLightsIndex = glGetUniformLocation( _shader_model_character_view.id, "uLightsIndex" );
- _uniform_model_character_view_uTexSceneDepth = glGetUniformLocation( _shader_model_character_view.id, "uTexSceneDepth" );
- _uniform_model_character_view_uInverseRatioDepth = glGetUniformLocation( _shader_model_character_view.id, "uInverseRatioDepth" );
- _uniform_model_character_view_uInverseRatioMain = glGetUniformLocation( _shader_model_character_view.id, "uInverseRatioMain" );
- _uniform_model_character_view_uDepthCompare = glGetUniformLocation( _shader_model_character_view.id, "uDepthCompare" );
+static inline void shader_model_character_view_use(void);
+static inline void shader_model_character_view_use(void)
+{
+ glUseProgram(_shader_model_character_view.id);
}
-#endif /* SHADER_model_character_view_H */
-#ifndef SHADER_model_entity_H
-#define SHADER_model_entity_H
-static void shader_model_entity_link(void);
-static void shader_model_entity_register(void);
-static struct vg_shader _shader_model_entity = {
- .name = "model_entity",
- .link = shader_model_entity_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_model_entity;
+extern GLuint _uniform_model_entity_uMdl;
+extern GLuint _uniform_model_entity_uPv;
+extern GLuint _uniform_model_entity_uPvmPrev;
+extern GLuint _uniform_model_entity_uTexMain;
+extern GLuint _uniform_model_entity_uCamera;
+extern GLuint _uniform_model_entity_g_world_depth;
+extern GLuint _uniform_model_entity_uLightsArray;
+extern GLuint _uniform_model_entity_uLightsIndex;
+static inline void shader_model_entity_uMdl(m4x3f m)
{
-.orig_file = "shaders/model.vs",
-.static_src =
-"layout (location=0) in vec3 a_co;\n"
-"layout (location=1) in vec3 a_norm;\n"
-"layout (location=2) in vec2 a_uv;\n"
-"layout (location=3) in vec4 a_colour;\n"
-"layout (location=4) in vec4 a_weights;\n"
-"layout (location=5) in ivec4 a_groups;\n"
-"\n"
-"#line 1 1 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"out vec3 aMotionVec0;\n"
-"out vec3 aMotionVec1;\n"
-"\n"
-"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
-"{\n"
-" // This magically solves some artifacting errors!\n"
-" //\n"
-" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
-"\n"
-" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
-" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"\n"
-"uniform mat4x3 uMdl;\n"
-"uniform mat4 uPv;\n"
-"uniform mat4 uPvmPrev;\n"
-"\n"
-"out vec4 aColour;\n"
-"out vec2 aUv;\n"
-"out vec3 aNorm;\n"
-"out vec3 aCo;\n"
-"out vec3 aWorldCo;\n"
-"\n"
-"void main()\n"
-"{\n"
-" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
-" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
-" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
-"\n"
-" vs_motion_out( vproj0, vproj1 );\n"
-"\n"
-" gl_Position = vproj0;\n"
-" aWorldCo = world_pos0;\n"
-" aColour = a_colour;\n"
-" aUv = a_uv;\n"
-" aNorm = normalize( mat3(uMdl) * a_norm );\n"
-" aCo = a_co;\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/model_entity.fs",
-.static_src =
-"uniform sampler2D uTexMain;\n"
-"uniform vec3 uCamera;\n"
-"\n"
-"in vec4 aColour;\n"
-"in vec2 aUv;\n"
-"in vec3 aNorm;\n"
-"in vec3 aCo;\n"
-"in vec3 aWorldCo;\n"
-"\n"
-"#line 1 1 \n"
-"// :D\n"
-"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
-"\n"
-"#line 11 0 \n"
-"#line 1 2 \n"
-"layout (location = 0) out vec4 oColour;\n"
-"\n"
-"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
-"layout (std140) uniform ub_world_lighting\n"
-"{\n"
-" vec4 g_cube_min;\n"
-" vec4 g_cube_inv_range;\n"
-"\n"
-" vec4 g_water_plane;\n"
-" vec4 g_depth_bounds;\n"
-"\n"
-" vec4 g_daysky_colour;\n"
-" vec4 g_nightsky_colour;\n"
-" vec4 g_sunset_colour;\n"
-" vec4 g_ambient_colour;\n"
-" vec4 g_sunset_ambient;\n"
-" vec4 g_sun_colour;\n"
-" vec4 g_sun_dir;\n"
-" vec4 g_board_0;\n"
-" vec4 g_board_1;\n"
-"\n"
-" float g_water_fog;\n"
-" float g_time;\n"
-" float g_realtime;\n"
-" float g_shadow_length;\n"
-" float g_shadow_spread;\n"
-"\n"
-" float g_time_of_day;\n"
-" float g_day_phase;\n"
-" float g_sunset_phase;\n"
-"\n"
-" int g_light_preview;\n"
-" int g_shadow_samples;\n"
-"\n"
-" int g_debug_indices;\n"
-" int g_debug_complexity;\n"
-"};\n"
-"\n"
-"uniform sampler2D g_world_depth;\n"
-"uniform samplerBuffer uLightsArray;\n"
-"uniform usampler3D uLightsIndex;\n"
-"\n"
-"#line 1 1 \n"
-"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
-"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
-"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
-"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
-"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
-"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
-"\n"
-"const float SUN_ANGLE = 0.0001;\n"
-"const float PI = 3.14159265358979323846264;\n"
-"\n"
-"//struct world_info\n"
-"//{\n"
-"// float time,\n"
-"// time_of_day,\n"
-"// day_phase,\n"
-"// sunset_phase;\n"
-"// \n"
-"// vec3 sun_dir;\n"
-"//};\n"
-"\n"
-"vec3 rand33(vec3 p3)\n"
-"{\n"
-" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
-" p3 += dot(p3, p3.yxz+33.33);\n"
-" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
-"}\n"
-"\n"
-"float stars( vec3 rd, float rr, float size ){\n"
-" vec3 co = rd * rr;\n"
-"\n"
-" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
-"\n"
-" float spaces = 1.0 / rr;\n"
-" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
-" a -= mod(a, spaces) - spaces * 0.5;\n"
-"\n"
-" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
-" \n"
-" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
-" plane = plane - mod(plane, PI / count);\n"
-"\n"
-" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
-"\n"
-" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
-" float ydist = sqrt(rr * rr - level * level);\n"
-" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
-" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
-" float star = smoothstep(size, 0.0, distance(center, co));\n"
-" return star;\n"
-"}\n"
-"\n"
-"float luminance( vec3 v )\n"
-"{\n"
-" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
-"}\n"
-"\n"
-"vec3 clearskies_ambient( vec3 dir )\n"
-"{\n"
-" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
-" float sky_gradient = dir.y;\n"
-" \n"
-" /* Blend phase colours */\n"
-" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
-" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
-" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
-" \n"
-" /* Add gradient */\n"
-" ambient -= sky_gradient * luminance(ambient);\n"
-" \n"
-" return ambient;\n"
-"}\n"
-"\n"
-"vec3 clearskies_sky( vec3 ray_dir )\n"
-"{\n"
-" ray_dir.y = abs( ray_dir.y );\n"
-" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
-" \n"
-" /* Sun */\n"
-" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
-" float sun_shape = pow( sun_size, 2000.0 );\n"
-" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" \n"
-" float star = 0.0;\n"
-" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
-"\n"
-" if( star_blend > 0.001 ){\n"
-" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
-" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
-" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
-" }\n"
-" }\n"
-" \n"
-" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
-" return composite;\n"
-"}\n"
-"\n"
-"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
-"{\n"
-" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
-"\n"
-" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
-" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
-" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
-" ) * g_sun_colour.rgb * g_day_phase;\n"
-"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
-" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" return ambient + (light_sun + sky_reflection) * shadow;\n"
-"}\n"
-"\n"
-"#line 44 0 \n"
-"\n"
-"float world_depth_sample( vec3 pos )\n"
-"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
-" return texture( g_world_depth, depth_coord ).r;\n"
-"}\n"
-"\n"
-"float world_water_depth( vec3 pos )\n"
-"{\n"
-" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return world_depth_sample( pos ) - ref_depth;\n"
-"}\n"
-"\n"
-"float shadow_sample( vec3 co ){\n"
-" float height_sample = world_depth_sample( co );\n"
-"\n"
-" float fdelta = height_sample - co.y;\n"
-" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
-"}\n"
-"\n"
-"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
-" if( g_shadow_samples == 0 ){\n"
-" return 1.0;\n"
-" }\n"
-"\n"
-" float fspread = g_shadow_spread;\n"
-" float flength = g_shadow_length;\n"
-"\n"
-" float famt = 0.0;\n"
-" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
-"\n"
-" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
-"\n"
-" return 1.0 - famt;\n"
-"}\n"
-"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
-"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
-"}\n"
-"\n"
-"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
-" float dist = pow(fdist*0.0010,0.78);\n"
-" return mix( vfrag, colour, min( 1.0, dist ) );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_light( int light_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
-" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
-" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
-"\n"
-" vec3 light_delta = light_co.xyz-co;\n"
-" float dist2 = dot(light_delta,light_delta);\n"
-"\n"
-" light_delta = normalize( light_delta );\n"
-"\n"
-" float quadratic = dist2*100.0;\n"
-" float attenuation = 1.0/( 1.0 + quadratic );\n"
-" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
-"\n"
-" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
-"\n"
-" if( light_dir.w < 0.999999 ){\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
-" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
-" }\n"
-"\n"
-" return light_colour.rgb * attenuation * falloff \n"
-" * step( g_day_phase, light_colour.w );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" uint light_count = packed_index & 0x3u;\n"
-"\n"
-" vec3 l = vec3(0.0);\n"
-"\n"
-" if( light_count >= 1u ){\n"
-" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
-" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
-" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
-"\n"
-" l += scene_calculate_light( index_0, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 2u ){\n"
-" l += scene_calculate_light( index_1, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 3u ){\n"
-" l += scene_calculate_light( index_2, halfview, co, normal );\n"
-" }\n"
-" }\n"
-" }\n"
-"\n"
-" return l;\n"
-"}\n"
-"\n"
-"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
-" float light_mask )\n"
-"{\n"
-" if( g_light_preview == 1 )\n"
-" diffuse = vec3(0.75);\n"
-"\n"
-" // Lighting\n"
-" vec3 halfview = uCamera - co;\n"
-" float fdist = length(halfview);\n"
-" halfview /= fdist;\n"
-"\n"
-" float world_shadow = newlight_compute_sun_shadow( \n"
-" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
-"\n"
-" vec3 total_light = clearskies_lighting( \n"
-" normal, min( light_mask, world_shadow ), halfview );\n"
-"\n"
-" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
-" cube_coord = floor( cube_coord );\n"
-"\n"
-" if( g_debug_indices == 1 )\n"
-" {\n"
-" return rand33(cube_coord);\n"
-" }\n"
-"\n"
-" if( g_debug_complexity == 1 )\n"
-" {\n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
-" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
-" }\n"
-"\n"
-" // FIXME: this coord should absolutely must be clamped!\n"
-" \n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, co, normal ) \n"
-" * light_mask;\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, co, normal )\n"
-" * light_mask;\n"
-"\n"
-" // Take a section of the sky function to give us a matching fog colour\n"
-"\n"
-" vec3 fog_colour = clearskies_ambient( -halfview );\n"
-" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
-" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" fog_colour += sun_colour;\n"
-" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
-"}\n"
-"\n"
-"#line 12 0 \n"
-"#line 1 3 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"layout (location = 1) out vec2 oMotionVec;\n"
-"\n"
-"in vec3 aMotionVec0;\n"
-"in vec3 aMotionVec1;\n"
-"\n"
-"void compute_motion_vectors()\n"
-"{\n"
-" // Write motion vectors\n"
-" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
-" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
-"\n"
-" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
-"}\n"
-"\n"
-"#line 13 0 \n"
-"\n"
-"void main()\n"
-"{\n"
-" compute_motion_vectors();\n"
-"\n"
-" vec3 qnorm = normalize(floor(aNorm*2.0)*0.5) + vec3(0.001,0.0,0.0);\n"
-" vec3 diffuse = texture( uTexMain, aUv ).rgb;\n"
-" vec3 composite = world_compute_lighting( diffuse, qnorm, aWorldCo, 1.0 );\n"
-"\n"
-" oColour = vec4( composite, 1.0 );\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_model_entity_uMdl;
-static GLuint _uniform_model_entity_uPv;
-static GLuint _uniform_model_entity_uPvmPrev;
-static GLuint _uniform_model_entity_uTexMain;
-static GLuint _uniform_model_entity_uCamera;
-static GLuint _uniform_model_entity_g_world_depth;
-static GLuint _uniform_model_entity_uLightsArray;
-static GLuint _uniform_model_entity_uLightsIndex;
-static void shader_model_entity_uMdl(m4x3f m){
- glUniformMatrix4x3fv(_uniform_model_entity_uMdl,1,GL_FALSE,(float*)m);
+ glUniformMatrix4x3fv(_uniform_model_entity_uMdl,1,GL_FALSE,(f32*)m);
}
-static void shader_model_entity_uPv(m4x4f m){
- glUniformMatrix4fv(_uniform_model_entity_uPv,1,GL_FALSE,(float*)m);
+static inline void shader_model_entity_uPv(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_model_entity_uPv,1,GL_FALSE,(f32*)m);
}
-static void shader_model_entity_uPvmPrev(m4x4f m){
- glUniformMatrix4fv(_uniform_model_entity_uPvmPrev,1,GL_FALSE,(float*)m);
+static inline void shader_model_entity_uPvmPrev(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_model_entity_uPvmPrev,1,GL_FALSE,(f32*)m);
}
-static void shader_model_entity_uTexMain(int i){
+static inline void shader_model_entity_uTexMain(int i)
+{
glUniform1i(_uniform_model_entity_uTexMain,i);
}
-static void shader_model_entity_uCamera(v3f v){
+static inline void shader_model_entity_uCamera(v3f v)
+{
glUniform3fv(_uniform_model_entity_uCamera,1,v);
}
-static void shader_model_entity_g_world_depth(int i){
+static inline void shader_model_entity_g_world_depth(int i)
+{
glUniform1i(_uniform_model_entity_g_world_depth,i);
}
-static void shader_model_entity_register(void){
- vg_shader_register( &_shader_model_entity );
-}
-static void shader_model_entity_use(void){ glUseProgram(_shader_model_entity.id); }
-static void shader_model_entity_link(void){
- _uniform_model_entity_uMdl = glGetUniformLocation( _shader_model_entity.id, "uMdl" );
- _uniform_model_entity_uPv = glGetUniformLocation( _shader_model_entity.id, "uPv" );
- _uniform_model_entity_uPvmPrev = glGetUniformLocation( _shader_model_entity.id, "uPvmPrev" );
- _uniform_model_entity_uTexMain = glGetUniformLocation( _shader_model_entity.id, "uTexMain" );
- _uniform_model_entity_uCamera = glGetUniformLocation( _shader_model_entity.id, "uCamera" );
- _uniform_model_entity_g_world_depth = glGetUniformLocation( _shader_model_entity.id, "g_world_depth" );
- _uniform_model_entity_uLightsArray = glGetUniformLocation( _shader_model_entity.id, "uLightsArray" );
- _uniform_model_entity_uLightsIndex = glGetUniformLocation( _shader_model_entity.id, "uLightsIndex" );
+static inline void shader_model_entity_use(void);
+static inline void shader_model_entity_use(void)
+{
+ glUseProgram(_shader_model_entity.id);
}
-#endif /* SHADER_model_entity_H */
-#ifndef SHADER_model_font_H
-#define SHADER_model_font_H
-static void shader_model_font_link(void);
-static void shader_model_font_register(void);
-static struct vg_shader _shader_model_font = {
- .name = "model_font",
- .link = shader_model_font_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_model_font;
+extern GLuint _uniform_model_font_uMdl;
+extern GLuint _uniform_model_font_uPv;
+extern GLuint _uniform_model_font_uPvmPrev;
+extern GLuint _uniform_model_font_uOffset;
+extern GLuint _uniform_model_font_uTexMain;
+extern GLuint _uniform_model_font_uColour;
+extern GLuint _uniform_model_font_uTexSceneDepth;
+extern GLuint _uniform_model_font_uInverseRatioDepth;
+extern GLuint _uniform_model_font_uInverseRatioMain;
+extern GLuint _uniform_model_font_uDepthCompare;
+static inline void shader_model_font_uMdl(m4x3f m)
{
-.orig_file = "shaders/model_font.vs",
-.static_src =
-"layout (location=0) in vec3 a_co;\n"
-"layout (location=1) in vec3 a_norm;\n"
-"layout (location=2) in vec2 a_uv;\n"
-"\n"
-"#line 1 1 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"out vec3 aMotionVec0;\n"
-"out vec3 aMotionVec1;\n"
-"\n"
-"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
-"{\n"
-" // This magically solves some artifacting errors!\n"
-" //\n"
-" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
-"\n"
-" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
-" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
-"}\n"
-"\n"
-"#line 6 0 \n"
-"\n"
-"uniform mat4x3 uMdl;\n"
-"uniform mat4 uPv;\n"
-"uniform mat4 uPvmPrev;\n"
-"uniform vec4 uOffset;\n"
-"\n"
-"out vec2 aUv;\n"
-"out vec4 aNorm;\n"
-"out vec3 aCo;\n"
-"out vec3 aWorldCo;\n"
-"\n"
-"void main()\n"
-"{\n"
-" vec3 co = a_co*uOffset.w+uOffset.xyz;\n"
-" vec3 world_pos0 = uMdl * vec4( co, 1.0 );\n"
-" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
-" vec4 vproj1 = uPvmPrev * vec4( co, 1.0 );\n"
-"\n"
-" vs_motion_out( vproj0, vproj1 );\n"
-"\n"
-" gl_Position = vproj0;\n"
-"\n"
-" aUv = a_uv;\n"
-" aNorm = vec4( mat3(uMdl) * a_norm, 0.0 );\n"
-" aCo = co;\n"
-" aWorldCo = world_pos0;\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/model_font.fs",
-.static_src =
-"layout (location = 0) out vec4 oColour;\n"
-"\n"
-"uniform sampler2D uTexMain;\n"
-"uniform vec4 uColour;\n"
-"\n"
-"in vec2 aUv;\n"
-"in vec4 aNorm;\n"
-"in vec3 aCo;\n"
-"\n"
-"#line 1 1 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"layout (location = 1) out vec2 oMotionVec;\n"
-"\n"
-"in vec3 aMotionVec0;\n"
-"in vec3 aMotionVec1;\n"
-"\n"
-"void compute_motion_vectors()\n"
-"{\n"
-" // Write motion vectors\n"
-" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
-" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
-"\n"
-" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
-"}\n"
-"\n"
-"#line 11 0 \n"
-"#line 1 2 \n"
-"uniform sampler2D uTexSceneDepth;\n"
-"uniform vec3 uInverseRatioDepth;\n"
-"uniform vec3 uInverseRatioMain;\n"
-"uniform bool uDepthCompare;\n"
-"\n"
-"float linear_depth( float depth, float near, float far ) {\n"
-" float z = depth * 2.0 - 1.0;\n"
-" return (2.0 * near * far) / (far + near - z * (far - near)); \n"
-"}\n"
-"\n"
-"void depth_compare_dither(){\n"
-" if( uDepthCompare ){\n"
-" vec2 back_coord = gl_FragCoord.xy * uInverseRatioMain.xy \n"
-" * uInverseRatioDepth.xy;\n"
-" float back_depth = texture( uTexSceneDepth, back_coord ).r;\n"
-" float front_depth = gl_FragCoord.z/gl_FragCoord.w;\n"
-"\n"
-" back_depth = linear_depth( back_depth, 0.1, 2100.0 );\n"
-" float diff = back_depth - front_depth;\n"
-"\n"
-" vec2 ssuv = gl_FragCoord.xy;\n"
-" vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), ssuv) );\n"
-" float dither = fract( vDither.g / 71.0 ) - 0.5;\n"
-"\n"
-" if( step(0.0,diff)+dither<0.3 )\n"
-" discard;\n"
-" }\n"
-"}\n"
-"\n"
-"#line 12 0 \n"
-"\n"
-"void main(){\n"
-" depth_compare_dither();\n"
-" compute_motion_vectors();\n"
-" oColour = texture( uTexMain, aUv ) * uColour;\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_model_font_uMdl;
-static GLuint _uniform_model_font_uPv;
-static GLuint _uniform_model_font_uPvmPrev;
-static GLuint _uniform_model_font_uOffset;
-static GLuint _uniform_model_font_uTexMain;
-static GLuint _uniform_model_font_uColour;
-static GLuint _uniform_model_font_uTexSceneDepth;
-static GLuint _uniform_model_font_uInverseRatioDepth;
-static GLuint _uniform_model_font_uInverseRatioMain;
-static GLuint _uniform_model_font_uDepthCompare;
-static void shader_model_font_uMdl(m4x3f m){
- glUniformMatrix4x3fv(_uniform_model_font_uMdl,1,GL_FALSE,(float*)m);
+ glUniformMatrix4x3fv(_uniform_model_font_uMdl,1,GL_FALSE,(f32*)m);
}
-static void shader_model_font_uPv(m4x4f m){
- glUniformMatrix4fv(_uniform_model_font_uPv,1,GL_FALSE,(float*)m);
+static inline void shader_model_font_uPv(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_model_font_uPv,1,GL_FALSE,(f32*)m);
}
-static void shader_model_font_uPvmPrev(m4x4f m){
- glUniformMatrix4fv(_uniform_model_font_uPvmPrev,1,GL_FALSE,(float*)m);
+static inline void shader_model_font_uPvmPrev(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_model_font_uPvmPrev,1,GL_FALSE,(f32*)m);
}
-static void shader_model_font_uOffset(v4f v){
+static inline void shader_model_font_uOffset(v4f v)
+{
glUniform4fv(_uniform_model_font_uOffset,1,v);
}
-static void shader_model_font_uTexMain(int i){
+static inline void shader_model_font_uTexMain(int i)
+{
glUniform1i(_uniform_model_font_uTexMain,i);
}
-static void shader_model_font_uColour(v4f v){
+static inline void shader_model_font_uColour(v4f v)
+{
glUniform4fv(_uniform_model_font_uColour,1,v);
}
-static void shader_model_font_uTexSceneDepth(int i){
+static inline void shader_model_font_uTexSceneDepth(int i)
+{
glUniform1i(_uniform_model_font_uTexSceneDepth,i);
}
-static void shader_model_font_uInverseRatioDepth(v3f v){
+static inline void shader_model_font_uInverseRatioDepth(v3f v)
+{
glUniform3fv(_uniform_model_font_uInverseRatioDepth,1,v);
}
-static void shader_model_font_uInverseRatioMain(v3f v){
+static inline void shader_model_font_uInverseRatioMain(v3f v)
+{
glUniform3fv(_uniform_model_font_uInverseRatioMain,1,v);
}
-static void shader_model_font_uDepthCompare(int b){
+static inline void shader_model_font_uDepthCompare(int b)
+{
glUniform1i(_uniform_model_font_uDepthCompare,b);
}
-static void shader_model_font_register(void){
- vg_shader_register( &_shader_model_font );
-}
-static void shader_model_font_use(void){ glUseProgram(_shader_model_font.id); }
-static void shader_model_font_link(void){
- _uniform_model_font_uMdl = glGetUniformLocation( _shader_model_font.id, "uMdl" );
- _uniform_model_font_uPv = glGetUniformLocation( _shader_model_font.id, "uPv" );
- _uniform_model_font_uPvmPrev = glGetUniformLocation( _shader_model_font.id, "uPvmPrev" );
- _uniform_model_font_uOffset = glGetUniformLocation( _shader_model_font.id, "uOffset" );
- _uniform_model_font_uTexMain = glGetUniformLocation( _shader_model_font.id, "uTexMain" );
- _uniform_model_font_uColour = glGetUniformLocation( _shader_model_font.id, "uColour" );
- _uniform_model_font_uTexSceneDepth = glGetUniformLocation( _shader_model_font.id, "uTexSceneDepth" );
- _uniform_model_font_uInverseRatioDepth = glGetUniformLocation( _shader_model_font.id, "uInverseRatioDepth" );
- _uniform_model_font_uInverseRatioMain = glGetUniformLocation( _shader_model_font.id, "uInverseRatioMain" );
- _uniform_model_font_uDepthCompare = glGetUniformLocation( _shader_model_font.id, "uDepthCompare" );
+static inline void shader_model_font_use(void);
+static inline void shader_model_font_use(void)
+{
+ glUseProgram(_shader_model_font.id);
}
-#endif /* SHADER_model_font_H */
-#ifndef SHADER_model_gate_H
-#define SHADER_model_gate_H
-static void shader_model_gate_link(void);
-static void shader_model_gate_register(void);
-static struct vg_shader _shader_model_gate = {
- .name = "model_gate",
- .link = shader_model_gate_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_model_gate;
+extern GLuint _uniform_model_gate_uMdl;
+extern GLuint _uniform_model_gate_uPv;
+extern GLuint _uniform_model_gate_uPvmPrev;
+extern GLuint _uniform_model_gate_uTime;
+extern GLuint _uniform_model_gate_uCam;
+extern GLuint _uniform_model_gate_uInvRes;
+extern GLuint _uniform_model_gate_uColour;
+static inline void shader_model_gate_uMdl(m4x3f m)
{
-.orig_file = "shaders/model.vs",
-.static_src =
-"layout (location=0) in vec3 a_co;\n"
-"layout (location=1) in vec3 a_norm;\n"
-"layout (location=2) in vec2 a_uv;\n"
-"layout (location=3) in vec4 a_colour;\n"
-"layout (location=4) in vec4 a_weights;\n"
-"layout (location=5) in ivec4 a_groups;\n"
-"\n"
-"#line 1 1 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"out vec3 aMotionVec0;\n"
-"out vec3 aMotionVec1;\n"
-"\n"
-"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
-"{\n"
-" // This magically solves some artifacting errors!\n"
-" //\n"
-" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
-"\n"
-" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
-" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"\n"
-"uniform mat4x3 uMdl;\n"
-"uniform mat4 uPv;\n"
-"uniform mat4 uPvmPrev;\n"
-"\n"
-"out vec4 aColour;\n"
-"out vec2 aUv;\n"
-"out vec3 aNorm;\n"
-"out vec3 aCo;\n"
-"out vec3 aWorldCo;\n"
-"\n"
-"void main()\n"
-"{\n"
-" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
-" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
-" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
-"\n"
-" vs_motion_out( vproj0, vproj1 );\n"
-"\n"
-" gl_Position = vproj0;\n"
-" aWorldCo = world_pos0;\n"
-" aColour = a_colour;\n"
-" aUv = a_uv;\n"
-" aNorm = normalize( mat3(uMdl) * a_norm );\n"
-" aCo = a_co;\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/model_gate_lq.fs",
-.static_src =
-"out vec4 FragColor;\n"
-"\n"
-"uniform float uTime;\n"
-"uniform vec3 uCam;\n"
-"uniform vec2 uInvRes;\n"
-"uniform vec4 uColour;\n"
-"\n"
-"in vec3 aNorm;\n"
-"in vec2 aUv;\n"
-"in vec3 aCo;\n"
-"\n"
-"void main()\n"
-"{\n"
-" vec2 ssuv = gl_FragCoord.xy;\n"
-" float opacity = 1.0-smoothstep(0.0,1.0,aUv.y+uColour.a);\n"
-" \n"
-" vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), ssuv) );\n"
-" float dither = fract( vDither.g / 71.0 ) - 0.5;\n"
-"\n"
-" if( opacity+dither<0.5 )\n"
-" discard;\n"
-"\n"
-" FragColor = uColour;\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_model_gate_uMdl;
-static GLuint _uniform_model_gate_uPv;
-static GLuint _uniform_model_gate_uPvmPrev;
-static GLuint _uniform_model_gate_uTime;
-static GLuint _uniform_model_gate_uCam;
-static GLuint _uniform_model_gate_uInvRes;
-static GLuint _uniform_model_gate_uColour;
-static void shader_model_gate_uMdl(m4x3f m){
- glUniformMatrix4x3fv(_uniform_model_gate_uMdl,1,GL_FALSE,(float*)m);
+ glUniformMatrix4x3fv(_uniform_model_gate_uMdl,1,GL_FALSE,(f32*)m);
}
-static void shader_model_gate_uPv(m4x4f m){
- glUniformMatrix4fv(_uniform_model_gate_uPv,1,GL_FALSE,(float*)m);
+static inline void shader_model_gate_uPv(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_model_gate_uPv,1,GL_FALSE,(f32*)m);
}
-static void shader_model_gate_uPvmPrev(m4x4f m){
- glUniformMatrix4fv(_uniform_model_gate_uPvmPrev,1,GL_FALSE,(float*)m);
+static inline void shader_model_gate_uPvmPrev(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_model_gate_uPvmPrev,1,GL_FALSE,(f32*)m);
}
-static void shader_model_gate_uTime(float f){
+static inline void shader_model_gate_uTime(f32 f)
+{
glUniform1f(_uniform_model_gate_uTime,f);
}
-static void shader_model_gate_uCam(v3f v){
+static inline void shader_model_gate_uCam(v3f v)
+{
glUniform3fv(_uniform_model_gate_uCam,1,v);
}
-static void shader_model_gate_uInvRes(v2f v){
+static inline void shader_model_gate_uInvRes(v2f v)
+{
glUniform2fv(_uniform_model_gate_uInvRes,1,v);
}
-static void shader_model_gate_uColour(v4f v){
+static inline void shader_model_gate_uColour(v4f v)
+{
glUniform4fv(_uniform_model_gate_uColour,1,v);
}
-static void shader_model_gate_register(void){
- vg_shader_register( &_shader_model_gate );
-}
-static void shader_model_gate_use(void){ glUseProgram(_shader_model_gate.id); }
-static void shader_model_gate_link(void){
- _uniform_model_gate_uMdl = glGetUniformLocation( _shader_model_gate.id, "uMdl" );
- _uniform_model_gate_uPv = glGetUniformLocation( _shader_model_gate.id, "uPv" );
- _uniform_model_gate_uPvmPrev = glGetUniformLocation( _shader_model_gate.id, "uPvmPrev" );
- _uniform_model_gate_uTime = glGetUniformLocation( _shader_model_gate.id, "uTime" );
- _uniform_model_gate_uCam = glGetUniformLocation( _shader_model_gate.id, "uCam" );
- _uniform_model_gate_uInvRes = glGetUniformLocation( _shader_model_gate.id, "uInvRes" );
- _uniform_model_gate_uColour = glGetUniformLocation( _shader_model_gate.id, "uColour" );
+static inline void shader_model_gate_use(void);
+static inline void shader_model_gate_use(void)
+{
+ glUseProgram(_shader_model_gate.id);
}
-#endif /* SHADER_model_gate_H */
-#ifndef SHADER_model_gate_unlinked_H
-#define SHADER_model_gate_unlinked_H
-static void shader_model_gate_unlinked_link(void);
-static void shader_model_gate_unlinked_register(void);
-static struct vg_shader _shader_model_gate_unlinked = {
- .name = "model_gate_unlinked",
- .link = shader_model_gate_unlinked_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_model_gate_unlinked;
+extern GLuint _uniform_model_gate_unlinked_uMdl;
+extern GLuint _uniform_model_gate_unlinked_uPv;
+extern GLuint _uniform_model_gate_unlinked_uPvmPrev;
+extern GLuint _uniform_model_gate_unlinked_uTime;
+extern GLuint _uniform_model_gate_unlinked_uCam;
+extern GLuint _uniform_model_gate_unlinked_uColour;
+static inline void shader_model_gate_unlinked_uMdl(m4x3f m)
{
-.orig_file = "shaders/model.vs",
-.static_src =
-"layout (location=0) in vec3 a_co;\n"
-"layout (location=1) in vec3 a_norm;\n"
-"layout (location=2) in vec2 a_uv;\n"
-"layout (location=3) in vec4 a_colour;\n"
-"layout (location=4) in vec4 a_weights;\n"
-"layout (location=5) in ivec4 a_groups;\n"
-"\n"
-"#line 1 1 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"out vec3 aMotionVec0;\n"
-"out vec3 aMotionVec1;\n"
-"\n"
-"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
-"{\n"
-" // This magically solves some artifacting errors!\n"
-" //\n"
-" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
-"\n"
-" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
-" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"\n"
-"uniform mat4x3 uMdl;\n"
-"uniform mat4 uPv;\n"
-"uniform mat4 uPvmPrev;\n"
-"\n"
-"out vec4 aColour;\n"
-"out vec2 aUv;\n"
-"out vec3 aNorm;\n"
-"out vec3 aCo;\n"
-"out vec3 aWorldCo;\n"
-"\n"
-"void main()\n"
-"{\n"
-" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
-" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
-" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
-"\n"
-" vs_motion_out( vproj0, vproj1 );\n"
-"\n"
-" gl_Position = vproj0;\n"
-" aWorldCo = world_pos0;\n"
-" aColour = a_colour;\n"
-" aUv = a_uv;\n"
-" aNorm = normalize( mat3(uMdl) * a_norm );\n"
-" aCo = a_co;\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/model_gate_unlinked.fs",
-.static_src =
-"out vec4 FragColor;\n"
-"\n"
-"uniform float uTime;\n"
-"uniform vec3 uCam;\n"
-"uniform vec4 uColour;\n"
-"\n"
-"in vec3 aNorm;\n"
-"in vec2 aUv;\n"
-"in vec3 aCo;\n"
-"\n"
-"#line 1 1 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"layout (location = 1) out vec2 oMotionVec;\n"
-"\n"
-"in vec3 aMotionVec0;\n"
-"in vec3 aMotionVec1;\n"
-"\n"
-"void compute_motion_vectors()\n"
-"{\n"
-" // Write motion vectors\n"
-" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
-" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
-"\n"
-" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
-"}\n"
-"\n"
-"#line 12 0 \n"
-"\n"
-"const int NOISE_LOOP = 3;\n"
-"vec3 digital_noise( uvec3 iuv ){\n"
-" iuv *=uvec3(8,2524,7552);\n"
-" for( int i=0; i<NOISE_LOOP; i++ )\n"
-" iuv += (iuv.yzx<<2) ^ (iuv.yxz)+iuv.z;\n"
-" return vec3(iuv)*(1.0/float(0xffffffffU));\n"
-"}\n"
-"\n"
-"vec2 rand_hash22( vec2 p ){\n"
-" vec3 p3 = fract(vec3(p.xyx) * 213.8976123);\n"
-" p3 += dot(p3, p3.yzx+19.19);\n"
-" return fract(vec2((p3.x + p3.y)*p3.z, (p3.x+p3.z)*p3.y));\n"
-"}\n"
-"\n"
-"void main(){\n"
-" compute_motion_vectors();\n"
-"\n"
-" vec2 ssuv = gl_FragCoord.xy;\n"
-" float grad = 1.0-aUv.y*0.1;\n"
-" float opacity = rand_hash22( vec2(floor(aUv.y*100.0),floor(aCo.z*10.0+uTime*40.0)) ).r*grad;\n"
-" \n"
-" vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), ssuv) );\n"
-" float dither = fract( vDither.g / 71.0 ) - 0.5;\n"
-"\n"
-" if( opacity<0.9 )\n"
-" discard;\n"
-"\n"
-" FragColor = vec4(0.7,0.5,0.5,1.0);\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_model_gate_unlinked_uMdl;
-static GLuint _uniform_model_gate_unlinked_uPv;
-static GLuint _uniform_model_gate_unlinked_uPvmPrev;
-static GLuint _uniform_model_gate_unlinked_uTime;
-static GLuint _uniform_model_gate_unlinked_uCam;
-static GLuint _uniform_model_gate_unlinked_uColour;
-static void shader_model_gate_unlinked_uMdl(m4x3f m){
- glUniformMatrix4x3fv(_uniform_model_gate_unlinked_uMdl,1,GL_FALSE,(float*)m);
+ glUniformMatrix4x3fv(_uniform_model_gate_unlinked_uMdl,1,GL_FALSE,(f32*)m);
}
-static void shader_model_gate_unlinked_uPv(m4x4f m){
- glUniformMatrix4fv(_uniform_model_gate_unlinked_uPv,1,GL_FALSE,(float*)m);
+static inline void shader_model_gate_unlinked_uPv(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_model_gate_unlinked_uPv,1,GL_FALSE,(f32*)m);
}
-static void shader_model_gate_unlinked_uPvmPrev(m4x4f m){
- glUniformMatrix4fv(_uniform_model_gate_unlinked_uPvmPrev,1,GL_FALSE,(float*)m);
+static inline void shader_model_gate_unlinked_uPvmPrev(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_model_gate_unlinked_uPvmPrev,1,GL_FALSE,(f32*)m);
}
-static void shader_model_gate_unlinked_uTime(float f){
+static inline void shader_model_gate_unlinked_uTime(f32 f)
+{
glUniform1f(_uniform_model_gate_unlinked_uTime,f);
}
-static void shader_model_gate_unlinked_uCam(v3f v){
+static inline void shader_model_gate_unlinked_uCam(v3f v)
+{
glUniform3fv(_uniform_model_gate_unlinked_uCam,1,v);
}
-static void shader_model_gate_unlinked_uColour(v4f v){
+static inline void shader_model_gate_unlinked_uColour(v4f v)
+{
glUniform4fv(_uniform_model_gate_unlinked_uColour,1,v);
}
-static void shader_model_gate_unlinked_register(void){
- vg_shader_register( &_shader_model_gate_unlinked );
-}
-static void shader_model_gate_unlinked_use(void){ glUseProgram(_shader_model_gate_unlinked.id); }
-static void shader_model_gate_unlinked_link(void){
- _uniform_model_gate_unlinked_uMdl = glGetUniformLocation( _shader_model_gate_unlinked.id, "uMdl" );
- _uniform_model_gate_unlinked_uPv = glGetUniformLocation( _shader_model_gate_unlinked.id, "uPv" );
- _uniform_model_gate_unlinked_uPvmPrev = glGetUniformLocation( _shader_model_gate_unlinked.id, "uPvmPrev" );
- _uniform_model_gate_unlinked_uTime = glGetUniformLocation( _shader_model_gate_unlinked.id, "uTime" );
- _uniform_model_gate_unlinked_uCam = glGetUniformLocation( _shader_model_gate_unlinked.id, "uCam" );
- _uniform_model_gate_unlinked_uColour = glGetUniformLocation( _shader_model_gate_unlinked.id, "uColour" );
+static inline void shader_model_gate_unlinked_use(void);
+static inline void shader_model_gate_unlinked_use(void)
+{
+ glUseProgram(_shader_model_gate_unlinked.id);
}
-#endif /* SHADER_model_gate_unlinked_H */
-#ifndef SHADER_model_menu_H
-#define SHADER_model_menu_H
-static void shader_model_menu_link(void);
-static void shader_model_menu_register(void);
-static struct vg_shader _shader_model_menu = {
- .name = "model_menu",
- .link = shader_model_menu_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_model_menu;
+extern GLuint _uniform_model_menu_uMdl;
+extern GLuint _uniform_model_menu_uPv;
+extern GLuint _uniform_model_menu_uPvmPrev;
+extern GLuint _uniform_model_menu_uTexMain;
+extern GLuint _uniform_model_menu_uColour;
+static inline void shader_model_menu_uMdl(m4x3f m)
{
-.orig_file = "shaders/model.vs",
-.static_src =
-"layout (location=0) in vec3 a_co;\n"
-"layout (location=1) in vec3 a_norm;\n"
-"layout (location=2) in vec2 a_uv;\n"
-"layout (location=3) in vec4 a_colour;\n"
-"layout (location=4) in vec4 a_weights;\n"
-"layout (location=5) in ivec4 a_groups;\n"
-"\n"
-"#line 1 1 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"out vec3 aMotionVec0;\n"
-"out vec3 aMotionVec1;\n"
-"\n"
-"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
-"{\n"
-" // This magically solves some artifacting errors!\n"
-" //\n"
-" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
-"\n"
-" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
-" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"\n"
-"uniform mat4x3 uMdl;\n"
-"uniform mat4 uPv;\n"
-"uniform mat4 uPvmPrev;\n"
-"\n"
-"out vec4 aColour;\n"
-"out vec2 aUv;\n"
-"out vec3 aNorm;\n"
-"out vec3 aCo;\n"
-"out vec3 aWorldCo;\n"
-"\n"
-"void main()\n"
-"{\n"
-" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
-" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
-" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
-"\n"
-" vs_motion_out( vproj0, vproj1 );\n"
-"\n"
-" gl_Position = vproj0;\n"
-" aWorldCo = world_pos0;\n"
-" aColour = a_colour;\n"
-" aUv = a_uv;\n"
-" aNorm = normalize( mat3(uMdl) * a_norm );\n"
-" aCo = a_co;\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/model_menu.fs",
-.static_src =
-"out vec4 FragColor;\n"
-"\n"
-"uniform sampler2D uTexMain;\n"
-"uniform vec4 uColour;\n"
-"\n"
-"in vec4 aColour;\n"
-"in vec2 aUv;\n"
-"in vec3 aNorm;\n"
-"in vec3 aCo;\n"
-"\n"
-"void main()\n"
-"{\n"
-" vec4 diffuse = texture( uTexMain, aUv );\n"
-"\n"
-" if( diffuse.a < 0.5 )\n"
-" discard;\n"
-"\n"
-" FragColor = vec4( diffuse.rgb, 1.0 ) * uColour;\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_model_menu_uMdl;
-static GLuint _uniform_model_menu_uPv;
-static GLuint _uniform_model_menu_uPvmPrev;
-static GLuint _uniform_model_menu_uTexMain;
-static GLuint _uniform_model_menu_uColour;
-static void shader_model_menu_uMdl(m4x3f m){
- glUniformMatrix4x3fv(_uniform_model_menu_uMdl,1,GL_FALSE,(float*)m);
+ glUniformMatrix4x3fv(_uniform_model_menu_uMdl,1,GL_FALSE,(f32*)m);
}
-static void shader_model_menu_uPv(m4x4f m){
- glUniformMatrix4fv(_uniform_model_menu_uPv,1,GL_FALSE,(float*)m);
+static inline void shader_model_menu_uPv(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_model_menu_uPv,1,GL_FALSE,(f32*)m);
}
-static void shader_model_menu_uPvmPrev(m4x4f m){
- glUniformMatrix4fv(_uniform_model_menu_uPvmPrev,1,GL_FALSE,(float*)m);
+static inline void shader_model_menu_uPvmPrev(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_model_menu_uPvmPrev,1,GL_FALSE,(f32*)m);
}
-static void shader_model_menu_uTexMain(int i){
+static inline void shader_model_menu_uTexMain(int i)
+{
glUniform1i(_uniform_model_menu_uTexMain,i);
}
-static void shader_model_menu_uColour(v4f v){
+static inline void shader_model_menu_uColour(v4f v)
+{
glUniform4fv(_uniform_model_menu_uColour,1,v);
}
-static void shader_model_menu_register(void){
- vg_shader_register( &_shader_model_menu );
-}
-static void shader_model_menu_use(void){ glUseProgram(_shader_model_menu.id); }
-static void shader_model_menu_link(void){
- _uniform_model_menu_uMdl = glGetUniformLocation( _shader_model_menu.id, "uMdl" );
- _uniform_model_menu_uPv = glGetUniformLocation( _shader_model_menu.id, "uPv" );
- _uniform_model_menu_uPvmPrev = glGetUniformLocation( _shader_model_menu.id, "uPvmPrev" );
- _uniform_model_menu_uTexMain = glGetUniformLocation( _shader_model_menu.id, "uTexMain" );
- _uniform_model_menu_uColour = glGetUniformLocation( _shader_model_menu.id, "uColour" );
+static inline void shader_model_menu_use(void);
+static inline void shader_model_menu_use(void)
+{
+ glUseProgram(_shader_model_menu.id);
}
-#endif /* SHADER_model_menu_H */
-#ifndef SHADER_model_sky_H
-#define SHADER_model_sky_H
-static void shader_model_sky_link(void);
-static void shader_model_sky_register(void);
-static struct vg_shader _shader_model_sky = {
- .name = "model_sky",
- .link = shader_model_sky_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_model_sky;
+extern GLuint _uniform_model_sky_uMdl;
+extern GLuint _uniform_model_sky_uPv;
+extern GLuint _uniform_model_sky_uPvmPrev;
+extern GLuint _uniform_model_sky_uTexGarbage;
+extern GLuint _uniform_model_sky_g_world_depth;
+extern GLuint _uniform_model_sky_uLightsArray;
+extern GLuint _uniform_model_sky_uLightsIndex;
+static inline void shader_model_sky_uMdl(m4x3f m)
{
-.orig_file = "shaders/model.vs",
-.static_src =
-"layout (location=0) in vec3 a_co;\n"
-"layout (location=1) in vec3 a_norm;\n"
-"layout (location=2) in vec2 a_uv;\n"
-"layout (location=3) in vec4 a_colour;\n"
-"layout (location=4) in vec4 a_weights;\n"
-"layout (location=5) in ivec4 a_groups;\n"
-"\n"
-"#line 1 1 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"out vec3 aMotionVec0;\n"
-"out vec3 aMotionVec1;\n"
-"\n"
-"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
-"{\n"
-" // This magically solves some artifacting errors!\n"
-" //\n"
-" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
-"\n"
-" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
-" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"\n"
-"uniform mat4x3 uMdl;\n"
-"uniform mat4 uPv;\n"
-"uniform mat4 uPvmPrev;\n"
-"\n"
-"out vec4 aColour;\n"
-"out vec2 aUv;\n"
-"out vec3 aNorm;\n"
-"out vec3 aCo;\n"
-"out vec3 aWorldCo;\n"
-"\n"
-"void main()\n"
-"{\n"
-" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
-" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
-" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
-"\n"
-" vs_motion_out( vproj0, vproj1 );\n"
-"\n"
-" gl_Position = vproj0;\n"
-" aWorldCo = world_pos0;\n"
-" aColour = a_colour;\n"
-" aUv = a_uv;\n"
-" aNorm = normalize( mat3(uMdl) * a_norm );\n"
-" aCo = a_co;\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/model_sky.fs",
-.static_src =
-"uniform sampler2D uTexGarbage;\n"
-"\n"
-"in vec4 aColour;\n"
-"in vec2 aUv;\n"
-"in vec3 aNorm;\n"
-"in vec3 aCo;\n"
-"in vec3 aWorldCo;\n"
-"\n"
-"// Spooky!\n"
-"const vec3 uCamera = vec3(0.0);\n"
-"\n"
-"#line 1 1 \n"
-"// :D\n"
-"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
-"\n"
-"#line 13 0 \n"
-"#line 1 2 \n"
-"layout (location = 0) out vec4 oColour;\n"
-"\n"
-"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
-"layout (std140) uniform ub_world_lighting\n"
-"{\n"
-" vec4 g_cube_min;\n"
-" vec4 g_cube_inv_range;\n"
-"\n"
-" vec4 g_water_plane;\n"
-" vec4 g_depth_bounds;\n"
-"\n"
-" vec4 g_daysky_colour;\n"
-" vec4 g_nightsky_colour;\n"
-" vec4 g_sunset_colour;\n"
-" vec4 g_ambient_colour;\n"
-" vec4 g_sunset_ambient;\n"
-" vec4 g_sun_colour;\n"
-" vec4 g_sun_dir;\n"
-" vec4 g_board_0;\n"
-" vec4 g_board_1;\n"
-"\n"
-" float g_water_fog;\n"
-" float g_time;\n"
-" float g_realtime;\n"
-" float g_shadow_length;\n"
-" float g_shadow_spread;\n"
-"\n"
-" float g_time_of_day;\n"
-" float g_day_phase;\n"
-" float g_sunset_phase;\n"
-"\n"
-" int g_light_preview;\n"
-" int g_shadow_samples;\n"
-"\n"
-" int g_debug_indices;\n"
-" int g_debug_complexity;\n"
-"};\n"
-"\n"
-"uniform sampler2D g_world_depth;\n"
-"uniform samplerBuffer uLightsArray;\n"
-"uniform usampler3D uLightsIndex;\n"
-"\n"
-"#line 1 1 \n"
-"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
-"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
-"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
-"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
-"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
-"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
-"\n"
-"const float SUN_ANGLE = 0.0001;\n"
-"const float PI = 3.14159265358979323846264;\n"
-"\n"
-"//struct world_info\n"
-"//{\n"
-"// float time,\n"
-"// time_of_day,\n"
-"// day_phase,\n"
-"// sunset_phase;\n"
-"// \n"
-"// vec3 sun_dir;\n"
-"//};\n"
-"\n"
-"vec3 rand33(vec3 p3)\n"
-"{\n"
-" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
-" p3 += dot(p3, p3.yxz+33.33);\n"
-" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
-"}\n"
-"\n"
-"float stars( vec3 rd, float rr, float size ){\n"
-" vec3 co = rd * rr;\n"
-"\n"
-" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
-"\n"
-" float spaces = 1.0 / rr;\n"
-" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
-" a -= mod(a, spaces) - spaces * 0.5;\n"
-"\n"
-" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
-" \n"
-" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
-" plane = plane - mod(plane, PI / count);\n"
-"\n"
-" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
-"\n"
-" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
-" float ydist = sqrt(rr * rr - level * level);\n"
-" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
-" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
-" float star = smoothstep(size, 0.0, distance(center, co));\n"
-" return star;\n"
-"}\n"
-"\n"
-"float luminance( vec3 v )\n"
-"{\n"
-" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
-"}\n"
-"\n"
-"vec3 clearskies_ambient( vec3 dir )\n"
-"{\n"
-" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
-" float sky_gradient = dir.y;\n"
-" \n"
-" /* Blend phase colours */\n"
-" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
-" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
-" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
-" \n"
-" /* Add gradient */\n"
-" ambient -= sky_gradient * luminance(ambient);\n"
-" \n"
-" return ambient;\n"
-"}\n"
-"\n"
-"vec3 clearskies_sky( vec3 ray_dir )\n"
-"{\n"
-" ray_dir.y = abs( ray_dir.y );\n"
-" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
-" \n"
-" /* Sun */\n"
-" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
-" float sun_shape = pow( sun_size, 2000.0 );\n"
-" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" \n"
-" float star = 0.0;\n"
-" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
-"\n"
-" if( star_blend > 0.001 ){\n"
-" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
-" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
-" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
-" }\n"
-" }\n"
-" \n"
-" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
-" return composite;\n"
-"}\n"
-"\n"
-"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
-"{\n"
-" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
-"\n"
-" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
-" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
-" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
-" ) * g_sun_colour.rgb * g_day_phase;\n"
-"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
-" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" return ambient + (light_sun + sky_reflection) * shadow;\n"
-"}\n"
-"\n"
-"#line 44 0 \n"
-"\n"
-"float world_depth_sample( vec3 pos )\n"
-"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
-" return texture( g_world_depth, depth_coord ).r;\n"
-"}\n"
-"\n"
-"float world_water_depth( vec3 pos )\n"
-"{\n"
-" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return world_depth_sample( pos ) - ref_depth;\n"
-"}\n"
-"\n"
-"float shadow_sample( vec3 co ){\n"
-" float height_sample = world_depth_sample( co );\n"
-"\n"
-" float fdelta = height_sample - co.y;\n"
-" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
-"}\n"
-"\n"
-"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
-" if( g_shadow_samples == 0 ){\n"
-" return 1.0;\n"
-" }\n"
-"\n"
-" float fspread = g_shadow_spread;\n"
-" float flength = g_shadow_length;\n"
-"\n"
-" float famt = 0.0;\n"
-" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
-"\n"
-" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
-"\n"
-" return 1.0 - famt;\n"
-"}\n"
-"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
-"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
-"}\n"
-"\n"
-"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
-" float dist = pow(fdist*0.0010,0.78);\n"
-" return mix( vfrag, colour, min( 1.0, dist ) );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_light( int light_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
-" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
-" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
-"\n"
-" vec3 light_delta = light_co.xyz-co;\n"
-" float dist2 = dot(light_delta,light_delta);\n"
-"\n"
-" light_delta = normalize( light_delta );\n"
-"\n"
-" float quadratic = dist2*100.0;\n"
-" float attenuation = 1.0/( 1.0 + quadratic );\n"
-" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
-"\n"
-" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
-"\n"
-" if( light_dir.w < 0.999999 ){\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
-" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
-" }\n"
-"\n"
-" return light_colour.rgb * attenuation * falloff \n"
-" * step( g_day_phase, light_colour.w );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" uint light_count = packed_index & 0x3u;\n"
-"\n"
-" vec3 l = vec3(0.0);\n"
-"\n"
-" if( light_count >= 1u ){\n"
-" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
-" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
-" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
-"\n"
-" l += scene_calculate_light( index_0, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 2u ){\n"
-" l += scene_calculate_light( index_1, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 3u ){\n"
-" l += scene_calculate_light( index_2, halfview, co, normal );\n"
-" }\n"
-" }\n"
-" }\n"
-"\n"
-" return l;\n"
-"}\n"
-"\n"
-"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
-" float light_mask )\n"
-"{\n"
-" if( g_light_preview == 1 )\n"
-" diffuse = vec3(0.75);\n"
-"\n"
-" // Lighting\n"
-" vec3 halfview = uCamera - co;\n"
-" float fdist = length(halfview);\n"
-" halfview /= fdist;\n"
-"\n"
-" float world_shadow = newlight_compute_sun_shadow( \n"
-" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
-"\n"
-" vec3 total_light = clearskies_lighting( \n"
-" normal, min( light_mask, world_shadow ), halfview );\n"
-"\n"
-" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
-" cube_coord = floor( cube_coord );\n"
-"\n"
-" if( g_debug_indices == 1 )\n"
-" {\n"
-" return rand33(cube_coord);\n"
-" }\n"
-"\n"
-" if( g_debug_complexity == 1 )\n"
-" {\n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
-" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
-" }\n"
-"\n"
-" // FIXME: this coord should absolutely must be clamped!\n"
-" \n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, co, normal ) \n"
-" * light_mask;\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, co, normal )\n"
-" * light_mask;\n"
-"\n"
-" // Take a section of the sky function to give us a matching fog colour\n"
-"\n"
-" vec3 fog_colour = clearskies_ambient( -halfview );\n"
-" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
-" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" fog_colour += sun_colour;\n"
-" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
-"}\n"
-"\n"
-"#line 14 0 \n"
-"#line 1 3 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"layout (location = 1) out vec2 oMotionVec;\n"
-"\n"
-"in vec3 aMotionVec0;\n"
-"in vec3 aMotionVec1;\n"
-"\n"
-"void compute_motion_vectors()\n"
-"{\n"
-" // Write motion vectors\n"
-" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
-" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
-"\n"
-" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
-"}\n"
-"\n"
-"#line 15 0 \n"
-"\n"
-"void main()\n"
-"{\n"
-" compute_motion_vectors();\n"
-"\n"
-" vec3 rd = normalize(aNorm);\n"
-"\n"
-" float fmove = g_time * 5.0;\n"
-" vec2 cloudplane = (rd.xz / (rd.y*sign(rd.y))) * 0.025;\n"
-" vec4 clouds1 = texture( uTexGarbage, cloudplane + vec2(0.1,0.4)*fmove*2.0 );\n"
-" vec4 clouds2 = texture( uTexGarbage, cloudplane*2.0 + vec2(0.3,0.1)*fmove );\n"
-"\n"
-" float cloud_d = max(clouds1.b*clouds2.r -0.2 - clouds2.g*0.4,0.0);\n"
-" float cloud_e = pow(cloud_d,1.5)*pow(abs(rd.y),0.3)*2.0;\n"
-"\n"
-" oColour = vec4( clearskies_sky( -rd ) ,1.0);\n"
-"\n"
-" vec3 cloud_colour = mix( mix(g_nightsky_colour.rgb,vec3(1.0),g_day_phase), \n"
-" g_sunset_colour.rgb, g_sunset_phase );\n"
-"\n"
-" oColour.rgb = mix( oColour.rgb, cloud_colour, cloud_e );\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_model_sky_uMdl;
-static GLuint _uniform_model_sky_uPv;
-static GLuint _uniform_model_sky_uPvmPrev;
-static GLuint _uniform_model_sky_uTexGarbage;
-static GLuint _uniform_model_sky_g_world_depth;
-static GLuint _uniform_model_sky_uLightsArray;
-static GLuint _uniform_model_sky_uLightsIndex;
-static void shader_model_sky_uMdl(m4x3f m){
- glUniformMatrix4x3fv(_uniform_model_sky_uMdl,1,GL_FALSE,(float*)m);
+ glUniformMatrix4x3fv(_uniform_model_sky_uMdl,1,GL_FALSE,(f32*)m);
}
-static void shader_model_sky_uPv(m4x4f m){
- glUniformMatrix4fv(_uniform_model_sky_uPv,1,GL_FALSE,(float*)m);
+static inline void shader_model_sky_uPv(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_model_sky_uPv,1,GL_FALSE,(f32*)m);
}
-static void shader_model_sky_uPvmPrev(m4x4f m){
- glUniformMatrix4fv(_uniform_model_sky_uPvmPrev,1,GL_FALSE,(float*)m);
+static inline void shader_model_sky_uPvmPrev(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_model_sky_uPvmPrev,1,GL_FALSE,(f32*)m);
}
-static void shader_model_sky_uTexGarbage(int i){
+static inline void shader_model_sky_uTexGarbage(int i)
+{
glUniform1i(_uniform_model_sky_uTexGarbage,i);
}
-static void shader_model_sky_g_world_depth(int i){
+static inline void shader_model_sky_g_world_depth(int i)
+{
glUniform1i(_uniform_model_sky_g_world_depth,i);
}
-static void shader_model_sky_register(void){
- vg_shader_register( &_shader_model_sky );
-}
-static void shader_model_sky_use(void){ glUseProgram(_shader_model_sky.id); }
-static void shader_model_sky_link(void){
- _uniform_model_sky_uMdl = glGetUniformLocation( _shader_model_sky.id, "uMdl" );
- _uniform_model_sky_uPv = glGetUniformLocation( _shader_model_sky.id, "uPv" );
- _uniform_model_sky_uPvmPrev = glGetUniformLocation( _shader_model_sky.id, "uPvmPrev" );
- _uniform_model_sky_uTexGarbage = glGetUniformLocation( _shader_model_sky.id, "uTexGarbage" );
- _uniform_model_sky_g_world_depth = glGetUniformLocation( _shader_model_sky.id, "g_world_depth" );
- _uniform_model_sky_uLightsArray = glGetUniformLocation( _shader_model_sky.id, "uLightsArray" );
- _uniform_model_sky_uLightsIndex = glGetUniformLocation( _shader_model_sky.id, "uLightsIndex" );
+static inline void shader_model_sky_use(void);
+static inline void shader_model_sky_use(void)
+{
+ glUseProgram(_shader_model_sky.id);
}
-#endif /* SHADER_model_sky_H */
-#ifndef SHADER_model_sky_space_H
-#define SHADER_model_sky_space_H
-static void shader_model_sky_space_link(void);
-static void shader_model_sky_space_register(void);
-static struct vg_shader _shader_model_sky_space = {
- .name = "model_sky_space",
- .link = shader_model_sky_space_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_model_sky_space;
+extern GLuint _uniform_model_sky_space_uMdl;
+extern GLuint _uniform_model_sky_space_uPv;
+extern GLuint _uniform_model_sky_space_uPvmPrev;
+extern GLuint _uniform_model_sky_space_uTexGarbage;
+extern GLuint _uniform_model_sky_space_g_world_depth;
+extern GLuint _uniform_model_sky_space_uLightsArray;
+extern GLuint _uniform_model_sky_space_uLightsIndex;
+static inline void shader_model_sky_space_uMdl(m4x3f m)
{
-.orig_file = "shaders/model.vs",
-.static_src =
-"layout (location=0) in vec3 a_co;\n"
-"layout (location=1) in vec3 a_norm;\n"
-"layout (location=2) in vec2 a_uv;\n"
-"layout (location=3) in vec4 a_colour;\n"
-"layout (location=4) in vec4 a_weights;\n"
-"layout (location=5) in ivec4 a_groups;\n"
-"\n"
-"#line 1 1 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"out vec3 aMotionVec0;\n"
-"out vec3 aMotionVec1;\n"
-"\n"
-"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
-"{\n"
-" // This magically solves some artifacting errors!\n"
-" //\n"
-" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
-"\n"
-" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
-" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"\n"
-"uniform mat4x3 uMdl;\n"
-"uniform mat4 uPv;\n"
-"uniform mat4 uPvmPrev;\n"
-"\n"
-"out vec4 aColour;\n"
-"out vec2 aUv;\n"
-"out vec3 aNorm;\n"
-"out vec3 aCo;\n"
-"out vec3 aWorldCo;\n"
-"\n"
-"void main()\n"
-"{\n"
-" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
-" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
-" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
-"\n"
-" vs_motion_out( vproj0, vproj1 );\n"
-"\n"
-" gl_Position = vproj0;\n"
-" aWorldCo = world_pos0;\n"
-" aColour = a_colour;\n"
-" aUv = a_uv;\n"
-" aNorm = normalize( mat3(uMdl) * a_norm );\n"
-" aCo = a_co;\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/model_sky_space.fs",
-.static_src =
-"uniform sampler2D uTexGarbage;\n"
-"\n"
-"in vec4 aColour;\n"
-"in vec2 aUv;\n"
-"in vec3 aNorm;\n"
-"in vec3 aCo;\n"
-"in vec3 aWorldCo;\n"
-"\n"
-"// Spooky!\n"
-"const vec3 uCamera = vec3(0.0);\n"
-"\n"
-"#line 1 1 \n"
-"// :D\n"
-"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
-"\n"
-"#line 13 0 \n"
-"#line 1 2 \n"
-"layout (location = 0) out vec4 oColour;\n"
-"\n"
-"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
-"layout (std140) uniform ub_world_lighting\n"
-"{\n"
-" vec4 g_cube_min;\n"
-" vec4 g_cube_inv_range;\n"
-"\n"
-" vec4 g_water_plane;\n"
-" vec4 g_depth_bounds;\n"
-"\n"
-" vec4 g_daysky_colour;\n"
-" vec4 g_nightsky_colour;\n"
-" vec4 g_sunset_colour;\n"
-" vec4 g_ambient_colour;\n"
-" vec4 g_sunset_ambient;\n"
-" vec4 g_sun_colour;\n"
-" vec4 g_sun_dir;\n"
-" vec4 g_board_0;\n"
-" vec4 g_board_1;\n"
-"\n"
-" float g_water_fog;\n"
-" float g_time;\n"
-" float g_realtime;\n"
-" float g_shadow_length;\n"
-" float g_shadow_spread;\n"
-"\n"
-" float g_time_of_day;\n"
-" float g_day_phase;\n"
-" float g_sunset_phase;\n"
-"\n"
-" int g_light_preview;\n"
-" int g_shadow_samples;\n"
-"\n"
-" int g_debug_indices;\n"
-" int g_debug_complexity;\n"
-"};\n"
-"\n"
-"uniform sampler2D g_world_depth;\n"
-"uniform samplerBuffer uLightsArray;\n"
-"uniform usampler3D uLightsIndex;\n"
-"\n"
-"#line 1 1 \n"
-"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
-"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
-"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
-"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
-"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
-"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
-"\n"
-"const float SUN_ANGLE = 0.0001;\n"
-"const float PI = 3.14159265358979323846264;\n"
-"\n"
-"//struct world_info\n"
-"//{\n"
-"// float time,\n"
-"// time_of_day,\n"
-"// day_phase,\n"
-"// sunset_phase;\n"
-"// \n"
-"// vec3 sun_dir;\n"
-"//};\n"
-"\n"
-"vec3 rand33(vec3 p3)\n"
-"{\n"
-" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
-" p3 += dot(p3, p3.yxz+33.33);\n"
-" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
-"}\n"
-"\n"
-"float stars( vec3 rd, float rr, float size ){\n"
-" vec3 co = rd * rr;\n"
-"\n"
-" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
-"\n"
-" float spaces = 1.0 / rr;\n"
-" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
-" a -= mod(a, spaces) - spaces * 0.5;\n"
-"\n"
-" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
-" \n"
-" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
-" plane = plane - mod(plane, PI / count);\n"
-"\n"
-" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
-"\n"
-" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
-" float ydist = sqrt(rr * rr - level * level);\n"
-" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
-" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
-" float star = smoothstep(size, 0.0, distance(center, co));\n"
-" return star;\n"
-"}\n"
-"\n"
-"float luminance( vec3 v )\n"
-"{\n"
-" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
-"}\n"
-"\n"
-"vec3 clearskies_ambient( vec3 dir )\n"
-"{\n"
-" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
-" float sky_gradient = dir.y;\n"
-" \n"
-" /* Blend phase colours */\n"
-" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
-" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
-" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
-" \n"
-" /* Add gradient */\n"
-" ambient -= sky_gradient * luminance(ambient);\n"
-" \n"
-" return ambient;\n"
-"}\n"
-"\n"
-"vec3 clearskies_sky( vec3 ray_dir )\n"
-"{\n"
-" ray_dir.y = abs( ray_dir.y );\n"
-" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
-" \n"
-" /* Sun */\n"
-" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
-" float sun_shape = pow( sun_size, 2000.0 );\n"
-" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" \n"
-" float star = 0.0;\n"
-" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
-"\n"
-" if( star_blend > 0.001 ){\n"
-" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
-" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
-" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
-" }\n"
-" }\n"
-" \n"
-" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
-" return composite;\n"
-"}\n"
-"\n"
-"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
-"{\n"
-" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
-"\n"
-" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
-" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
-" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
-" ) * g_sun_colour.rgb * g_day_phase;\n"
-"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
-" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" return ambient + (light_sun + sky_reflection) * shadow;\n"
-"}\n"
-"\n"
-"#line 44 0 \n"
-"\n"
-"float world_depth_sample( vec3 pos )\n"
-"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
-" return texture( g_world_depth, depth_coord ).r;\n"
-"}\n"
-"\n"
-"float world_water_depth( vec3 pos )\n"
-"{\n"
-" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return world_depth_sample( pos ) - ref_depth;\n"
-"}\n"
-"\n"
-"float shadow_sample( vec3 co ){\n"
-" float height_sample = world_depth_sample( co );\n"
-"\n"
-" float fdelta = height_sample - co.y;\n"
-" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
-"}\n"
-"\n"
-"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
-" if( g_shadow_samples == 0 ){\n"
-" return 1.0;\n"
-" }\n"
-"\n"
-" float fspread = g_shadow_spread;\n"
-" float flength = g_shadow_length;\n"
-"\n"
-" float famt = 0.0;\n"
-" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
-"\n"
-" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
-"\n"
-" return 1.0 - famt;\n"
-"}\n"
-"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
-"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
-"}\n"
-"\n"
-"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
-" float dist = pow(fdist*0.0010,0.78);\n"
-" return mix( vfrag, colour, min( 1.0, dist ) );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_light( int light_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
-" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
-" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
-"\n"
-" vec3 light_delta = light_co.xyz-co;\n"
-" float dist2 = dot(light_delta,light_delta);\n"
-"\n"
-" light_delta = normalize( light_delta );\n"
-"\n"
-" float quadratic = dist2*100.0;\n"
-" float attenuation = 1.0/( 1.0 + quadratic );\n"
-" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
-"\n"
-" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
-"\n"
-" if( light_dir.w < 0.999999 ){\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
-" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
-" }\n"
-"\n"
-" return light_colour.rgb * attenuation * falloff \n"
-" * step( g_day_phase, light_colour.w );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" uint light_count = packed_index & 0x3u;\n"
-"\n"
-" vec3 l = vec3(0.0);\n"
-"\n"
-" if( light_count >= 1u ){\n"
-" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
-" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
-" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
-"\n"
-" l += scene_calculate_light( index_0, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 2u ){\n"
-" l += scene_calculate_light( index_1, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 3u ){\n"
-" l += scene_calculate_light( index_2, halfview, co, normal );\n"
-" }\n"
-" }\n"
-" }\n"
-"\n"
-" return l;\n"
-"}\n"
-"\n"
-"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
-" float light_mask )\n"
-"{\n"
-" if( g_light_preview == 1 )\n"
-" diffuse = vec3(0.75);\n"
-"\n"
-" // Lighting\n"
-" vec3 halfview = uCamera - co;\n"
-" float fdist = length(halfview);\n"
-" halfview /= fdist;\n"
-"\n"
-" float world_shadow = newlight_compute_sun_shadow( \n"
-" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
-"\n"
-" vec3 total_light = clearskies_lighting( \n"
-" normal, min( light_mask, world_shadow ), halfview );\n"
-"\n"
-" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
-" cube_coord = floor( cube_coord );\n"
-"\n"
-" if( g_debug_indices == 1 )\n"
-" {\n"
-" return rand33(cube_coord);\n"
-" }\n"
-"\n"
-" if( g_debug_complexity == 1 )\n"
-" {\n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
-" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
-" }\n"
-"\n"
-" // FIXME: this coord should absolutely must be clamped!\n"
-" \n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, co, normal ) \n"
-" * light_mask;\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, co, normal )\n"
-" * light_mask;\n"
-"\n"
-" // Take a section of the sky function to give us a matching fog colour\n"
-"\n"
-" vec3 fog_colour = clearskies_ambient( -halfview );\n"
-" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
-" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" fog_colour += sun_colour;\n"
-" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
-"}\n"
-"\n"
-"#line 14 0 \n"
-"#line 1 3 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"layout (location = 1) out vec2 oMotionVec;\n"
-"\n"
-"in vec3 aMotionVec0;\n"
-"in vec3 aMotionVec1;\n"
-"\n"
-"void compute_motion_vectors()\n"
-"{\n"
-" // Write motion vectors\n"
-" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
-" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
-"\n"
-" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
-"}\n"
-"\n"
-"#line 15 0 \n"
-"\n"
-"float stars1( vec3 rd, float rr, float size ){\n"
-" vec3 co = rd * rr;\n"
-"\n"
-" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
-"\n"
-" float spaces = 1.0 / rr;\n"
-" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
-" a -= mod(a, spaces) - spaces * 0.5;\n"
-"\n"
-" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
-" \n"
-" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
-" plane = plane - mod(plane, PI / count);\n"
-"\n"
-" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
-"\n"
-" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
-" float ydist = sqrt(rr * rr - level * level);\n"
-" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
-" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
-" float star = smoothstep(size, 0.0, distance(center, co));\n"
-" return star;\n"
-"}\n"
-"\n"
-"void main(){\n"
-" compute_motion_vectors();\n"
-"\n"
-" vec3 rd = -normalize(aNorm);\n"
-"\n"
-" float star = 0.0;\n"
-" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
-" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
-" star += stars( rd, 1.94 * pow( 1.64, j ), m ) * (1.0 / pow(4.0, j));\n"
-" }\n"
-"\n"
-" oColour = vec4( vec3(star*20.0), 1.0);\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_model_sky_space_uMdl;
-static GLuint _uniform_model_sky_space_uPv;
-static GLuint _uniform_model_sky_space_uPvmPrev;
-static GLuint _uniform_model_sky_space_uTexGarbage;
-static GLuint _uniform_model_sky_space_g_world_depth;
-static GLuint _uniform_model_sky_space_uLightsArray;
-static GLuint _uniform_model_sky_space_uLightsIndex;
-static void shader_model_sky_space_uMdl(m4x3f m){
- glUniformMatrix4x3fv(_uniform_model_sky_space_uMdl,1,GL_FALSE,(float*)m);
+ glUniformMatrix4x3fv(_uniform_model_sky_space_uMdl,1,GL_FALSE,(f32*)m);
}
-static void shader_model_sky_space_uPv(m4x4f m){
- glUniformMatrix4fv(_uniform_model_sky_space_uPv,1,GL_FALSE,(float*)m);
+static inline void shader_model_sky_space_uPv(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_model_sky_space_uPv,1,GL_FALSE,(f32*)m);
}
-static void shader_model_sky_space_uPvmPrev(m4x4f m){
- glUniformMatrix4fv(_uniform_model_sky_space_uPvmPrev,1,GL_FALSE,(float*)m);
+static inline void shader_model_sky_space_uPvmPrev(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_model_sky_space_uPvmPrev,1,GL_FALSE,(f32*)m);
}
-static void shader_model_sky_space_uTexGarbage(int i){
+static inline void shader_model_sky_space_uTexGarbage(int i)
+{
glUniform1i(_uniform_model_sky_space_uTexGarbage,i);
}
-static void shader_model_sky_space_g_world_depth(int i){
+static inline void shader_model_sky_space_g_world_depth(int i)
+{
glUniform1i(_uniform_model_sky_space_g_world_depth,i);
}
-static void shader_model_sky_space_register(void){
- vg_shader_register( &_shader_model_sky_space );
-}
-static void shader_model_sky_space_use(void){ glUseProgram(_shader_model_sky_space.id); }
-static void shader_model_sky_space_link(void){
- _uniform_model_sky_space_uMdl = glGetUniformLocation( _shader_model_sky_space.id, "uMdl" );
- _uniform_model_sky_space_uPv = glGetUniformLocation( _shader_model_sky_space.id, "uPv" );
- _uniform_model_sky_space_uPvmPrev = glGetUniformLocation( _shader_model_sky_space.id, "uPvmPrev" );
- _uniform_model_sky_space_uTexGarbage = glGetUniformLocation( _shader_model_sky_space.id, "uTexGarbage" );
- _uniform_model_sky_space_g_world_depth = glGetUniformLocation( _shader_model_sky_space.id, "g_world_depth" );
- _uniform_model_sky_space_uLightsArray = glGetUniformLocation( _shader_model_sky_space.id, "uLightsArray" );
- _uniform_model_sky_space_uLightsIndex = glGetUniformLocation( _shader_model_sky_space.id, "uLightsIndex" );
+static inline void shader_model_sky_space_use(void);
+static inline void shader_model_sky_space_use(void)
+{
+ glUseProgram(_shader_model_sky_space.id);
}
-#endif /* SHADER_model_sky_space_H */
-#ifndef SHADER_particle_H
-#define SHADER_particle_H
-static void shader_particle_link(void);
-static void shader_particle_register(void);
-static struct vg_shader _shader_particle = {
- .name = "particle",
- .link = shader_particle_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_particle;
+extern GLuint _uniform_particle_uPv;
+extern GLuint _uniform_particle_uPvPrev;
+static inline void shader_particle_uPv(m4x4f m)
{
-.orig_file = "shaders/particle.vs",
-.static_src =
-"layout (location=0) in vec3 a_co;\n"
-"layout (location=1) in vec4 a_colour;\n"
-"\n"
-"#line 1 1 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"out vec3 aMotionVec0;\n"
-"out vec3 aMotionVec1;\n"
-"\n"
-"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
-"{\n"
-" // This magically solves some artifacting errors!\n"
-" //\n"
-" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
-"\n"
-" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
-" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
-"}\n"
-"\n"
-"#line 5 0 \n"
-"\n"
-"uniform mat4 uPv;\n"
-"uniform mat4 uPvPrev;\n"
-"\n"
-"out vec4 aColour;\n"
-"\n"
-"void main(){\n"
-" vec4 vproj0 = uPv * vec4( a_co, 1.0 );\n"
-" vec4 vproj1 = uPvPrev * vec4( a_co, 1.0 );\n"
-" vs_motion_out( vproj0, vproj1 );\n"
-"\n"
-" gl_Position = vproj0;\n"
-" aColour = a_colour;\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/particle.fs",
-.static_src =
-"layout (location = 0) out vec4 oColour;\n"
-"in vec4 aColour;\n"
-"\n"
-"#line 1 1 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"layout (location = 1) out vec2 oMotionVec;\n"
-"\n"
-"in vec3 aMotionVec0;\n"
-"in vec3 aMotionVec1;\n"
-"\n"
-"void compute_motion_vectors()\n"
-"{\n"
-" // Write motion vectors\n"
-" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
-" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
-"\n"
-" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
-"}\n"
-"\n"
-"#line 5 0 \n"
-"\n"
-"void main(){\n"
-" compute_motion_vectors();\n"
-"\n"
-" //vec2 ssuv = gl_FragCoord.xy;\n"
-" //vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), ssuv) );\n"
-" //float dither = fract( vDither.g / 71.0 ) - 0.5;\n"
-"\n"
-" //if( vsamplemain.a+dither<0.5 )\n"
-" // discard;\n"
-"\n"
-" oColour = aColour;\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_particle_uPv;
-static GLuint _uniform_particle_uPvPrev;
-static void shader_particle_uPv(m4x4f m){
- glUniformMatrix4fv(_uniform_particle_uPv,1,GL_FALSE,(float*)m);
-}
-static void shader_particle_uPvPrev(m4x4f m){
- glUniformMatrix4fv(_uniform_particle_uPvPrev,1,GL_FALSE,(float*)m);
+ glUniformMatrix4fv(_uniform_particle_uPv,1,GL_FALSE,(f32*)m);
}
-static void shader_particle_register(void){
- vg_shader_register( &_shader_particle );
+static inline void shader_particle_uPvPrev(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_particle_uPvPrev,1,GL_FALSE,(f32*)m);
}
-static void shader_particle_use(void){ glUseProgram(_shader_particle.id); }
-static void shader_particle_link(void){
- _uniform_particle_uPv = glGetUniformLocation( _shader_particle.id, "uPv" );
- _uniform_particle_uPvPrev = glGetUniformLocation( _shader_particle.id, "uPvPrev" );
+static inline void shader_particle_use(void);
+static inline void shader_particle_use(void)
+{
+ glUseProgram(_shader_particle.id);
}
-#endif /* SHADER_particle_H */
-#ifndef SHADER_routeui_H
-#define SHADER_routeui_H
-static void shader_routeui_link(void);
-static void shader_routeui_register(void);
-static struct vg_shader _shader_routeui = {
- .name = "routeui",
- .link = shader_routeui_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_routeui;
+extern GLuint _uniform_routeui_uOffset;
+extern GLuint _uniform_routeui_uColour;
+static inline void shader_routeui_uOffset(v4f v)
{
-.orig_file = "shaders/routeui.vs",
-.static_src =
-"layout (location=0) in vec2 a_co;\n"
-"\n"
-"uniform vec4 uOffset;\n"
-"\n"
-"void main()\n"
-"{\n"
-" vec2 vpos = a_co * uOffset.zw + uOffset.xy;\n"
-" gl_Position = vec4(vpos,0.0,1.0);\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/routeui.fs",
-.static_src =
-"out vec4 FragColor;\n"
-"\n"
-"uniform vec4 uColour;\n"
-"\n"
-"void main()\n"
-"{\n"
-" FragColor = uColour;\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_routeui_uOffset;
-static GLuint _uniform_routeui_uColour;
-static void shader_routeui_uOffset(v4f v){
glUniform4fv(_uniform_routeui_uOffset,1,v);
}
-static void shader_routeui_uColour(v4f v){
+static inline void shader_routeui_uColour(v4f v)
+{
glUniform4fv(_uniform_routeui_uColour,1,v);
}
-static void shader_routeui_register(void){
- vg_shader_register( &_shader_routeui );
-}
-static void shader_routeui_use(void){ glUseProgram(_shader_routeui.id); }
-static void shader_routeui_link(void){
- _uniform_routeui_uOffset = glGetUniformLocation( _shader_routeui.id, "uOffset" );
- _uniform_routeui_uColour = glGetUniformLocation( _shader_routeui.id, "uColour" );
+static inline void shader_routeui_use(void);
+static inline void shader_routeui_use(void)
+{
+ glUseProgram(_shader_routeui.id);
}
-#endif /* SHADER_routeui_H */
-#ifndef SHADER_scene_cubemapped_H
-#define SHADER_scene_cubemapped_H
-static void shader_scene_cubemapped_link(void);
-static void shader_scene_cubemapped_register(void);
-static struct vg_shader _shader_scene_cubemapped = {
- .name = "scene_cubemapped",
- .link = shader_scene_cubemapped_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_scene_cubemapped;
+extern GLuint _uniform_scene_cubemapped_uMdl;
+extern GLuint _uniform_scene_cubemapped_uPv;
+extern GLuint _uniform_scene_cubemapped_uPvmPrev;
+extern GLuint _uniform_scene_cubemapped_uTexGarbage;
+extern GLuint _uniform_scene_cubemapped_uTexMain;
+extern GLuint _uniform_scene_cubemapped_uTexCubemap;
+extern GLuint _uniform_scene_cubemapped_uCamera;
+extern GLuint _uniform_scene_cubemapped_uPlane;
+extern GLuint _uniform_scene_cubemapped_uColour;
+extern GLuint _uniform_scene_cubemapped_g_world_depth;
+extern GLuint _uniform_scene_cubemapped_uLightsArray;
+extern GLuint _uniform_scene_cubemapped_uLightsIndex;
+static inline void shader_scene_cubemapped_uMdl(m4x3f m)
{
-.orig_file = "shaders/scene.vs",
-.static_src =
-"layout (location=0) in vec3 a_co;\n"
-"layout (location=1) in vec4 a_norm;\n"
-"layout (location=2) in vec2 a_uv;\n"
-"\n"
-"#line 1 1 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"out vec3 aMotionVec0;\n"
-"out vec3 aMotionVec1;\n"
-"\n"
-"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
-"{\n"
-" // This magically solves some artifacting errors!\n"
-" //\n"
-" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
-"\n"
-" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
-" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
-"}\n"
-"\n"
-"#line 6 0 \n"
-"\n"
-"uniform mat4x3 uMdl;\n"
-"uniform mat4 uPv;\n"
-"uniform mat4 uPvmPrev;\n"
-"\n"
-"out vec2 aUv;\n"
-"out vec4 aNorm;\n"
-"out vec3 aCo;\n"
-"out vec3 aWorldCo;\n"
-"\n"
-"void main()\n"
-"{\n"
-" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
-" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
-" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
-"\n"
-" vs_motion_out( vproj0, vproj1 );\n"
-"\n"
-" gl_Position = vproj0;\n"
-"\n"
-" aUv = a_uv;\n"
-" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
-" aCo = a_co;\n"
-" aWorldCo = world_pos0;\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/scene_cubemapped.fs",
-.static_src =
-"uniform sampler2D uTexGarbage;\n"
-"uniform sampler2D uTexMain;\n"
-"uniform samplerCube uTexCubemap;\n"
-"uniform vec3 uCamera;\n"
-"uniform vec4 uPlane;\n"
-"uniform vec4 uColour;\n"
-"\n"
-"#line 1 1 \n"
-"// :D\n"
-"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
-"\n"
-"#line 9 0 \n"
-"#line 1 2 \n"
-"// :D\n"
-"\n"
-"in vec2 aUv;\n"
-"in vec4 aNorm;\n"
-"in vec3 aCo;\n"
-"in vec3 aWorldCo;\n"
-"\n"
-"#line 1 1 \n"
-"layout (location = 0) out vec4 oColour;\n"
-"\n"
-"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
-"layout (std140) uniform ub_world_lighting\n"
-"{\n"
-" vec4 g_cube_min;\n"
-" vec4 g_cube_inv_range;\n"
-"\n"
-" vec4 g_water_plane;\n"
-" vec4 g_depth_bounds;\n"
-"\n"
-" vec4 g_daysky_colour;\n"
-" vec4 g_nightsky_colour;\n"
-" vec4 g_sunset_colour;\n"
-" vec4 g_ambient_colour;\n"
-" vec4 g_sunset_ambient;\n"
-" vec4 g_sun_colour;\n"
-" vec4 g_sun_dir;\n"
-" vec4 g_board_0;\n"
-" vec4 g_board_1;\n"
-"\n"
-" float g_water_fog;\n"
-" float g_time;\n"
-" float g_realtime;\n"
-" float g_shadow_length;\n"
-" float g_shadow_spread;\n"
-"\n"
-" float g_time_of_day;\n"
-" float g_day_phase;\n"
-" float g_sunset_phase;\n"
-"\n"
-" int g_light_preview;\n"
-" int g_shadow_samples;\n"
-"\n"
-" int g_debug_indices;\n"
-" int g_debug_complexity;\n"
-"};\n"
-"\n"
-"uniform sampler2D g_world_depth;\n"
-"uniform samplerBuffer uLightsArray;\n"
-"uniform usampler3D uLightsIndex;\n"
-"\n"
-"#line 1 1 \n"
-"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
-"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
-"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
-"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
-"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
-"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
-"\n"
-"const float SUN_ANGLE = 0.0001;\n"
-"const float PI = 3.14159265358979323846264;\n"
-"\n"
-"//struct world_info\n"
-"//{\n"
-"// float time,\n"
-"// time_of_day,\n"
-"// day_phase,\n"
-"// sunset_phase;\n"
-"// \n"
-"// vec3 sun_dir;\n"
-"//};\n"
-"\n"
-"vec3 rand33(vec3 p3)\n"
-"{\n"
-" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
-" p3 += dot(p3, p3.yxz+33.33);\n"
-" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
-"}\n"
-"\n"
-"float stars( vec3 rd, float rr, float size ){\n"
-" vec3 co = rd * rr;\n"
-"\n"
-" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
-"\n"
-" float spaces = 1.0 / rr;\n"
-" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
-" a -= mod(a, spaces) - spaces * 0.5;\n"
-"\n"
-" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
-" \n"
-" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
-" plane = plane - mod(plane, PI / count);\n"
-"\n"
-" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
-"\n"
-" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
-" float ydist = sqrt(rr * rr - level * level);\n"
-" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
-" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
-" float star = smoothstep(size, 0.0, distance(center, co));\n"
-" return star;\n"
-"}\n"
-"\n"
-"float luminance( vec3 v )\n"
-"{\n"
-" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
-"}\n"
-"\n"
-"vec3 clearskies_ambient( vec3 dir )\n"
-"{\n"
-" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
-" float sky_gradient = dir.y;\n"
-" \n"
-" /* Blend phase colours */\n"
-" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
-" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
-" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
-" \n"
-" /* Add gradient */\n"
-" ambient -= sky_gradient * luminance(ambient);\n"
-" \n"
-" return ambient;\n"
-"}\n"
-"\n"
-"vec3 clearskies_sky( vec3 ray_dir )\n"
-"{\n"
-" ray_dir.y = abs( ray_dir.y );\n"
-" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
-" \n"
-" /* Sun */\n"
-" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
-" float sun_shape = pow( sun_size, 2000.0 );\n"
-" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" \n"
-" float star = 0.0;\n"
-" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
-"\n"
-" if( star_blend > 0.001 ){\n"
-" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
-" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
-" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
-" }\n"
-" }\n"
-" \n"
-" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
-" return composite;\n"
-"}\n"
-"\n"
-"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
-"{\n"
-" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
-"\n"
-" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
-" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
-" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
-" ) * g_sun_colour.rgb * g_day_phase;\n"
-"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
-" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" return ambient + (light_sun + sky_reflection) * shadow;\n"
-"}\n"
-"\n"
-"#line 44 0 \n"
-"\n"
-"float world_depth_sample( vec3 pos )\n"
-"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
-" return texture( g_world_depth, depth_coord ).r;\n"
-"}\n"
-"\n"
-"float world_water_depth( vec3 pos )\n"
-"{\n"
-" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return world_depth_sample( pos ) - ref_depth;\n"
-"}\n"
-"\n"
-"float shadow_sample( vec3 co ){\n"
-" float height_sample = world_depth_sample( co );\n"
-"\n"
-" float fdelta = height_sample - co.y;\n"
-" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
-"}\n"
-"\n"
-"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
-" if( g_shadow_samples == 0 ){\n"
-" return 1.0;\n"
-" }\n"
-"\n"
-" float fspread = g_shadow_spread;\n"
-" float flength = g_shadow_length;\n"
-"\n"
-" float famt = 0.0;\n"
-" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
-"\n"
-" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
-"\n"
-" return 1.0 - famt;\n"
-"}\n"
-"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
-"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
-"}\n"
-"\n"
-"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
-" float dist = pow(fdist*0.0010,0.78);\n"
-" return mix( vfrag, colour, min( 1.0, dist ) );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_light( int light_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
-" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
-" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
-"\n"
-" vec3 light_delta = light_co.xyz-co;\n"
-" float dist2 = dot(light_delta,light_delta);\n"
-"\n"
-" light_delta = normalize( light_delta );\n"
-"\n"
-" float quadratic = dist2*100.0;\n"
-" float attenuation = 1.0/( 1.0 + quadratic );\n"
-" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
-"\n"
-" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
-"\n"
-" if( light_dir.w < 0.999999 ){\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
-" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
-" }\n"
-"\n"
-" return light_colour.rgb * attenuation * falloff \n"
-" * step( g_day_phase, light_colour.w );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" uint light_count = packed_index & 0x3u;\n"
-"\n"
-" vec3 l = vec3(0.0);\n"
-"\n"
-" if( light_count >= 1u ){\n"
-" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
-" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
-" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
-"\n"
-" l += scene_calculate_light( index_0, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 2u ){\n"
-" l += scene_calculate_light( index_1, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 3u ){\n"
-" l += scene_calculate_light( index_2, halfview, co, normal );\n"
-" }\n"
-" }\n"
-" }\n"
-"\n"
-" return l;\n"
-"}\n"
-"\n"
-"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
-" float light_mask )\n"
-"{\n"
-" if( g_light_preview == 1 )\n"
-" diffuse = vec3(0.75);\n"
-"\n"
-" // Lighting\n"
-" vec3 halfview = uCamera - co;\n"
-" float fdist = length(halfview);\n"
-" halfview /= fdist;\n"
-"\n"
-" float world_shadow = newlight_compute_sun_shadow( \n"
-" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
-"\n"
-" vec3 total_light = clearskies_lighting( \n"
-" normal, min( light_mask, world_shadow ), halfview );\n"
-"\n"
-" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
-" cube_coord = floor( cube_coord );\n"
-"\n"
-" if( g_debug_indices == 1 )\n"
-" {\n"
-" return rand33(cube_coord);\n"
-" }\n"
-"\n"
-" if( g_debug_complexity == 1 )\n"
-" {\n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
-" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
-" }\n"
-"\n"
-" // FIXME: this coord should absolutely must be clamped!\n"
-" \n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, co, normal ) \n"
-" * light_mask;\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, co, normal )\n"
-" * light_mask;\n"
-"\n"
-" // Take a section of the sky function to give us a matching fog colour\n"
-"\n"
-" vec3 fog_colour = clearskies_ambient( -halfview );\n"
-" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
-" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" fog_colour += sun_colour;\n"
-" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"\n"
-"float sdLine( vec3 p, vec3 a, vec3 b )\n"
-"{\n"
-" vec3 pa = p - a;\n"
-" vec3 ba = b - a;\n"
-"\n"
-" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
-" return length( pa - ba*h );\n"
-"}\n"
-"\n"
-"float compute_board_shadow()\n"
-"{\n"
-" // player shadow\n"
-" float dist_to_player = max( 0.0, sdLine( aWorldCo, g_board_0.xyz,\n"
-" g_board_1.xyz )-0.1 );\n"
-" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
-" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
-"\n"
-" return 1.0 - player_shadow*0.8;\n"
-"}\n"
-"\n"
-"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
-"{\n"
-" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
-"}\n"
-"\n"
-"#line 10 0 \n"
-"#line 1 3 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"layout (location = 1) out vec2 oMotionVec;\n"
-"\n"
-"in vec3 aMotionVec0;\n"
-"in vec3 aMotionVec1;\n"
-"\n"
-"void compute_motion_vectors()\n"
-"{\n"
-" // Write motion vectors\n"
-" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
-" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
-"\n"
-" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
-"}\n"
-"\n"
-"#line 11 0 \n"
-"\n"
-"void main()\n"
-"{\n"
-" compute_motion_vectors();\n"
-"\n"
-" vec3 vfrag = vec3(0.5,0.5,0.5);\n"
-" vec4 vsamplemain = texture( uTexMain, aUv );\n"
-" vec4 wgarbage = texture( uTexGarbage, aCo.xz * 0.0015 + aCo.yx*0.002 );\n"
-" vec3 qnorm = aNorm.xyz;\n"
-" vfrag = vsamplemain.rgb;\n"
-"\n"
-" if( g_light_preview == 1 ){\n"
-" vfrag = vec3(0.5);\n"
-" }\n"
-"\n"
-" vfrag = scene_compute_lighting( vfrag, qnorm, aWorldCo );\n"
-" oColour = vec4( vfrag, 1.0 );\n"
-"\n"
-" vec3 halfdir = normalize( aWorldCo - uCamera );\n"
-" vec3 reflectdir = reflect( halfdir, qnorm );\n"
-" oColour = mix( oColour, \n"
-" vec4(texture(uTexCubemap,reflectdir).rgb * uColour.rgb, 1.0),\n"
-" uColour.a*wgarbage.b );\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_scene_cubemapped_uMdl;
-static GLuint _uniform_scene_cubemapped_uPv;
-static GLuint _uniform_scene_cubemapped_uPvmPrev;
-static GLuint _uniform_scene_cubemapped_uTexGarbage;
-static GLuint _uniform_scene_cubemapped_uTexMain;
-static GLuint _uniform_scene_cubemapped_uTexCubemap;
-static GLuint _uniform_scene_cubemapped_uCamera;
-static GLuint _uniform_scene_cubemapped_uPlane;
-static GLuint _uniform_scene_cubemapped_uColour;
-static GLuint _uniform_scene_cubemapped_g_world_depth;
-static GLuint _uniform_scene_cubemapped_uLightsArray;
-static GLuint _uniform_scene_cubemapped_uLightsIndex;
-static void shader_scene_cubemapped_uMdl(m4x3f m){
- glUniformMatrix4x3fv(_uniform_scene_cubemapped_uMdl,1,GL_FALSE,(float*)m);
+ glUniformMatrix4x3fv(_uniform_scene_cubemapped_uMdl,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_cubemapped_uPv(m4x4f m){
- glUniformMatrix4fv(_uniform_scene_cubemapped_uPv,1,GL_FALSE,(float*)m);
+static inline void shader_scene_cubemapped_uPv(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_scene_cubemapped_uPv,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_cubemapped_uPvmPrev(m4x4f m){
- glUniformMatrix4fv(_uniform_scene_cubemapped_uPvmPrev,1,GL_FALSE,(float*)m);
+static inline void shader_scene_cubemapped_uPvmPrev(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_scene_cubemapped_uPvmPrev,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_cubemapped_uTexGarbage(int i){
+static inline void shader_scene_cubemapped_uTexGarbage(int i)
+{
glUniform1i(_uniform_scene_cubemapped_uTexGarbage,i);
}
-static void shader_scene_cubemapped_uTexMain(int i){
+static inline void shader_scene_cubemapped_uTexMain(int i)
+{
glUniform1i(_uniform_scene_cubemapped_uTexMain,i);
}
-static void shader_scene_cubemapped_uTexCubemap(int i){
+static inline void shader_scene_cubemapped_uTexCubemap(int i)
+{
glUniform1i(_uniform_scene_cubemapped_uTexCubemap,i);
}
-static void shader_scene_cubemapped_uCamera(v3f v){
+static inline void shader_scene_cubemapped_uCamera(v3f v)
+{
glUniform3fv(_uniform_scene_cubemapped_uCamera,1,v);
}
-static void shader_scene_cubemapped_uPlane(v4f v){
+static inline void shader_scene_cubemapped_uPlane(v4f v)
+{
glUniform4fv(_uniform_scene_cubemapped_uPlane,1,v);
}
-static void shader_scene_cubemapped_uColour(v4f v){
+static inline void shader_scene_cubemapped_uColour(v4f v)
+{
glUniform4fv(_uniform_scene_cubemapped_uColour,1,v);
}
-static void shader_scene_cubemapped_g_world_depth(int i){
+static inline void shader_scene_cubemapped_g_world_depth(int i)
+{
glUniform1i(_uniform_scene_cubemapped_g_world_depth,i);
}
-static void shader_scene_cubemapped_register(void){
- vg_shader_register( &_shader_scene_cubemapped );
-}
-static void shader_scene_cubemapped_use(void){ glUseProgram(_shader_scene_cubemapped.id); }
-static void shader_scene_cubemapped_link(void){
- _uniform_scene_cubemapped_uMdl = glGetUniformLocation( _shader_scene_cubemapped.id, "uMdl" );
- _uniform_scene_cubemapped_uPv = glGetUniformLocation( _shader_scene_cubemapped.id, "uPv" );
- _uniform_scene_cubemapped_uPvmPrev = glGetUniformLocation( _shader_scene_cubemapped.id, "uPvmPrev" );
- _uniform_scene_cubemapped_uTexGarbage = glGetUniformLocation( _shader_scene_cubemapped.id, "uTexGarbage" );
- _uniform_scene_cubemapped_uTexMain = glGetUniformLocation( _shader_scene_cubemapped.id, "uTexMain" );
- _uniform_scene_cubemapped_uTexCubemap = glGetUniformLocation( _shader_scene_cubemapped.id, "uTexCubemap" );
- _uniform_scene_cubemapped_uCamera = glGetUniformLocation( _shader_scene_cubemapped.id, "uCamera" );
- _uniform_scene_cubemapped_uPlane = glGetUniformLocation( _shader_scene_cubemapped.id, "uPlane" );
- _uniform_scene_cubemapped_uColour = glGetUniformLocation( _shader_scene_cubemapped.id, "uColour" );
- _uniform_scene_cubemapped_g_world_depth = glGetUniformLocation( _shader_scene_cubemapped.id, "g_world_depth" );
- _uniform_scene_cubemapped_uLightsArray = glGetUniformLocation( _shader_scene_cubemapped.id, "uLightsArray" );
- _uniform_scene_cubemapped_uLightsIndex = glGetUniformLocation( _shader_scene_cubemapped.id, "uLightsIndex" );
+static inline void shader_scene_cubemapped_use(void);
+static inline void shader_scene_cubemapped_use(void)
+{
+ glUseProgram(_shader_scene_cubemapped.id);
}
-#endif /* SHADER_scene_cubemapped_H */
-#ifndef SHADER_scene_depth_H
-#define SHADER_scene_depth_H
-static void shader_scene_depth_link(void);
-static void shader_scene_depth_register(void);
-static struct vg_shader _shader_scene_depth = {
- .name = "scene_depth",
- .link = shader_scene_depth_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_scene_depth;
+extern GLuint _uniform_scene_depth_uMdl;
+extern GLuint _uniform_scene_depth_uPv;
+extern GLuint _uniform_scene_depth_uPvmPrev;
+extern GLuint _uniform_scene_depth_uCamera;
+extern GLuint _uniform_scene_depth_uBoard0;
+extern GLuint _uniform_scene_depth_uBoard1;
+extern GLuint _uniform_scene_depth_g_world_depth;
+extern GLuint _uniform_scene_depth_uLightsArray;
+extern GLuint _uniform_scene_depth_uLightsIndex;
+static inline void shader_scene_depth_uMdl(m4x3f m)
{
-.orig_file = "shaders/scene.vs",
-.static_src =
-"layout (location=0) in vec3 a_co;\n"
-"layout (location=1) in vec4 a_norm;\n"
-"layout (location=2) in vec2 a_uv;\n"
-"\n"
-"#line 1 1 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"out vec3 aMotionVec0;\n"
-"out vec3 aMotionVec1;\n"
-"\n"
-"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
-"{\n"
-" // This magically solves some artifacting errors!\n"
-" //\n"
-" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
-"\n"
-" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
-" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
-"}\n"
-"\n"
-"#line 6 0 \n"
-"\n"
-"uniform mat4x3 uMdl;\n"
-"uniform mat4 uPv;\n"
-"uniform mat4 uPvmPrev;\n"
-"\n"
-"out vec2 aUv;\n"
-"out vec4 aNorm;\n"
-"out vec3 aCo;\n"
-"out vec3 aWorldCo;\n"
-"\n"
-"void main()\n"
-"{\n"
-" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
-" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
-" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
-"\n"
-" vs_motion_out( vproj0, vproj1 );\n"
-"\n"
-" gl_Position = vproj0;\n"
-"\n"
-" aUv = a_uv;\n"
-" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
-" aCo = a_co;\n"
-" aWorldCo = world_pos0;\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/scene_depth.fs",
-.static_src =
-"out vec4 FragColor;\n"
-"\n"
-"uniform vec3 uCamera;\n"
-"uniform vec3 uBoard0;\n"
-"uniform vec3 uBoard1;\n"
-"\n"
-"#line 1 1 \n"
-"// :D\n"
-"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
-"\n"
-"#line 8 0 \n"
-"#line 1 2 \n"
-"// :D\n"
-"\n"
-"in vec2 aUv;\n"
-"in vec4 aNorm;\n"
-"in vec3 aCo;\n"
-"in vec3 aWorldCo;\n"
-"\n"
-"#line 1 1 \n"
-"layout (location = 0) out vec4 oColour;\n"
-"\n"
-"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
-"layout (std140) uniform ub_world_lighting\n"
-"{\n"
-" vec4 g_cube_min;\n"
-" vec4 g_cube_inv_range;\n"
-"\n"
-" vec4 g_water_plane;\n"
-" vec4 g_depth_bounds;\n"
-"\n"
-" vec4 g_daysky_colour;\n"
-" vec4 g_nightsky_colour;\n"
-" vec4 g_sunset_colour;\n"
-" vec4 g_ambient_colour;\n"
-" vec4 g_sunset_ambient;\n"
-" vec4 g_sun_colour;\n"
-" vec4 g_sun_dir;\n"
-" vec4 g_board_0;\n"
-" vec4 g_board_1;\n"
-"\n"
-" float g_water_fog;\n"
-" float g_time;\n"
-" float g_realtime;\n"
-" float g_shadow_length;\n"
-" float g_shadow_spread;\n"
-"\n"
-" float g_time_of_day;\n"
-" float g_day_phase;\n"
-" float g_sunset_phase;\n"
-"\n"
-" int g_light_preview;\n"
-" int g_shadow_samples;\n"
-"\n"
-" int g_debug_indices;\n"
-" int g_debug_complexity;\n"
-"};\n"
-"\n"
-"uniform sampler2D g_world_depth;\n"
-"uniform samplerBuffer uLightsArray;\n"
-"uniform usampler3D uLightsIndex;\n"
-"\n"
-"#line 1 1 \n"
-"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
-"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
-"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
-"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
-"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
-"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
-"\n"
-"const float SUN_ANGLE = 0.0001;\n"
-"const float PI = 3.14159265358979323846264;\n"
-"\n"
-"//struct world_info\n"
-"//{\n"
-"// float time,\n"
-"// time_of_day,\n"
-"// day_phase,\n"
-"// sunset_phase;\n"
-"// \n"
-"// vec3 sun_dir;\n"
-"//};\n"
-"\n"
-"vec3 rand33(vec3 p3)\n"
-"{\n"
-" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
-" p3 += dot(p3, p3.yxz+33.33);\n"
-" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
-"}\n"
-"\n"
-"float stars( vec3 rd, float rr, float size ){\n"
-" vec3 co = rd * rr;\n"
-"\n"
-" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
-"\n"
-" float spaces = 1.0 / rr;\n"
-" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
-" a -= mod(a, spaces) - spaces * 0.5;\n"
-"\n"
-" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
-" \n"
-" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
-" plane = plane - mod(plane, PI / count);\n"
-"\n"
-" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
-"\n"
-" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
-" float ydist = sqrt(rr * rr - level * level);\n"
-" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
-" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
-" float star = smoothstep(size, 0.0, distance(center, co));\n"
-" return star;\n"
-"}\n"
-"\n"
-"float luminance( vec3 v )\n"
-"{\n"
-" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
-"}\n"
-"\n"
-"vec3 clearskies_ambient( vec3 dir )\n"
-"{\n"
-" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
-" float sky_gradient = dir.y;\n"
-" \n"
-" /* Blend phase colours */\n"
-" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
-" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
-" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
-" \n"
-" /* Add gradient */\n"
-" ambient -= sky_gradient * luminance(ambient);\n"
-" \n"
-" return ambient;\n"
-"}\n"
-"\n"
-"vec3 clearskies_sky( vec3 ray_dir )\n"
-"{\n"
-" ray_dir.y = abs( ray_dir.y );\n"
-" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
-" \n"
-" /* Sun */\n"
-" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
-" float sun_shape = pow( sun_size, 2000.0 );\n"
-" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" \n"
-" float star = 0.0;\n"
-" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
-"\n"
-" if( star_blend > 0.001 ){\n"
-" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
-" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
-" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
-" }\n"
-" }\n"
-" \n"
-" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
-" return composite;\n"
-"}\n"
-"\n"
-"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
-"{\n"
-" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
-"\n"
-" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
-" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
-" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
-" ) * g_sun_colour.rgb * g_day_phase;\n"
-"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
-" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" return ambient + (light_sun + sky_reflection) * shadow;\n"
-"}\n"
-"\n"
-"#line 44 0 \n"
-"\n"
-"float world_depth_sample( vec3 pos )\n"
-"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
-" return texture( g_world_depth, depth_coord ).r;\n"
-"}\n"
-"\n"
-"float world_water_depth( vec3 pos )\n"
-"{\n"
-" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return world_depth_sample( pos ) - ref_depth;\n"
-"}\n"
-"\n"
-"float shadow_sample( vec3 co ){\n"
-" float height_sample = world_depth_sample( co );\n"
-"\n"
-" float fdelta = height_sample - co.y;\n"
-" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
-"}\n"
-"\n"
-"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
-" if( g_shadow_samples == 0 ){\n"
-" return 1.0;\n"
-" }\n"
-"\n"
-" float fspread = g_shadow_spread;\n"
-" float flength = g_shadow_length;\n"
-"\n"
-" float famt = 0.0;\n"
-" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
-"\n"
-" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
-"\n"
-" return 1.0 - famt;\n"
-"}\n"
-"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
-"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
-"}\n"
-"\n"
-"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
-" float dist = pow(fdist*0.0010,0.78);\n"
-" return mix( vfrag, colour, min( 1.0, dist ) );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_light( int light_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
-" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
-" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
-"\n"
-" vec3 light_delta = light_co.xyz-co;\n"
-" float dist2 = dot(light_delta,light_delta);\n"
-"\n"
-" light_delta = normalize( light_delta );\n"
-"\n"
-" float quadratic = dist2*100.0;\n"
-" float attenuation = 1.0/( 1.0 + quadratic );\n"
-" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
-"\n"
-" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
-"\n"
-" if( light_dir.w < 0.999999 ){\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
-" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
-" }\n"
-"\n"
-" return light_colour.rgb * attenuation * falloff \n"
-" * step( g_day_phase, light_colour.w );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" uint light_count = packed_index & 0x3u;\n"
-"\n"
-" vec3 l = vec3(0.0);\n"
-"\n"
-" if( light_count >= 1u ){\n"
-" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
-" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
-" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
-"\n"
-" l += scene_calculate_light( index_0, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 2u ){\n"
-" l += scene_calculate_light( index_1, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 3u ){\n"
-" l += scene_calculate_light( index_2, halfview, co, normal );\n"
-" }\n"
-" }\n"
-" }\n"
-"\n"
-" return l;\n"
-"}\n"
-"\n"
-"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
-" float light_mask )\n"
-"{\n"
-" if( g_light_preview == 1 )\n"
-" diffuse = vec3(0.75);\n"
-"\n"
-" // Lighting\n"
-" vec3 halfview = uCamera - co;\n"
-" float fdist = length(halfview);\n"
-" halfview /= fdist;\n"
-"\n"
-" float world_shadow = newlight_compute_sun_shadow( \n"
-" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
-"\n"
-" vec3 total_light = clearskies_lighting( \n"
-" normal, min( light_mask, world_shadow ), halfview );\n"
-"\n"
-" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
-" cube_coord = floor( cube_coord );\n"
-"\n"
-" if( g_debug_indices == 1 )\n"
-" {\n"
-" return rand33(cube_coord);\n"
-" }\n"
-"\n"
-" if( g_debug_complexity == 1 )\n"
-" {\n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
-" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
-" }\n"
-"\n"
-" // FIXME: this coord should absolutely must be clamped!\n"
-" \n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, co, normal ) \n"
-" * light_mask;\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, co, normal )\n"
-" * light_mask;\n"
-"\n"
-" // Take a section of the sky function to give us a matching fog colour\n"
-"\n"
-" vec3 fog_colour = clearskies_ambient( -halfview );\n"
-" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
-" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" fog_colour += sun_colour;\n"
-" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"\n"
-"float sdLine( vec3 p, vec3 a, vec3 b )\n"
-"{\n"
-" vec3 pa = p - a;\n"
-" vec3 ba = b - a;\n"
-"\n"
-" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
-" return length( pa - ba*h );\n"
-"}\n"
-"\n"
-"float compute_board_shadow()\n"
-"{\n"
-" // player shadow\n"
-" float dist_to_player = max( 0.0, sdLine( aWorldCo, g_board_0.xyz,\n"
-" g_board_1.xyz )-0.1 );\n"
-" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
-" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
-"\n"
-" return 1.0 - player_shadow*0.8;\n"
-"}\n"
-"\n"
-"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
-"{\n"
-" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"\n"
-"// Water blending\n"
-"// ==============\n"
-"\n"
-"float water_depth( vec3 pos, vec3 halfview )\n"
-"{\n"
-" vec3 pnorm = g_water_plane.xyz;\n"
-" float pdist = g_water_plane.w;\n"
-"\n"
-" float d = dot( pnorm, halfview );\n"
-" float t = dot((pnorm*pdist - pos), pnorm) / d;\n"
-" return t * g_water_fog;\n"
-"}\n"
-"\n"
-"void main()\n"
-"{\n"
-" vec3 halfview = normalize( uCamera - aWorldCo );\n"
-" float depth = water_depth( aWorldCo, halfview );\n"
-" FragColor = vec4( depth, 0.0, 0.0, 0.0 );\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_scene_depth_uMdl;
-static GLuint _uniform_scene_depth_uPv;
-static GLuint _uniform_scene_depth_uPvmPrev;
-static GLuint _uniform_scene_depth_uCamera;
-static GLuint _uniform_scene_depth_uBoard0;
-static GLuint _uniform_scene_depth_uBoard1;
-static GLuint _uniform_scene_depth_g_world_depth;
-static GLuint _uniform_scene_depth_uLightsArray;
-static GLuint _uniform_scene_depth_uLightsIndex;
-static void shader_scene_depth_uMdl(m4x3f m){
- glUniformMatrix4x3fv(_uniform_scene_depth_uMdl,1,GL_FALSE,(float*)m);
+ glUniformMatrix4x3fv(_uniform_scene_depth_uMdl,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_depth_uPv(m4x4f m){
- glUniformMatrix4fv(_uniform_scene_depth_uPv,1,GL_FALSE,(float*)m);
+static inline void shader_scene_depth_uPv(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_scene_depth_uPv,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_depth_uPvmPrev(m4x4f m){
- glUniformMatrix4fv(_uniform_scene_depth_uPvmPrev,1,GL_FALSE,(float*)m);
+static inline void shader_scene_depth_uPvmPrev(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_scene_depth_uPvmPrev,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_depth_uCamera(v3f v){
+static inline void shader_scene_depth_uCamera(v3f v)
+{
glUniform3fv(_uniform_scene_depth_uCamera,1,v);
}
-static void shader_scene_depth_uBoard0(v3f v){
+static inline void shader_scene_depth_uBoard0(v3f v)
+{
glUniform3fv(_uniform_scene_depth_uBoard0,1,v);
}
-static void shader_scene_depth_uBoard1(v3f v){
+static inline void shader_scene_depth_uBoard1(v3f v)
+{
glUniform3fv(_uniform_scene_depth_uBoard1,1,v);
}
-static void shader_scene_depth_g_world_depth(int i){
+static inline void shader_scene_depth_g_world_depth(int i)
+{
glUniform1i(_uniform_scene_depth_g_world_depth,i);
}
-static void shader_scene_depth_register(void){
- vg_shader_register( &_shader_scene_depth );
-}
-static void shader_scene_depth_use(void){ glUseProgram(_shader_scene_depth.id); }
-static void shader_scene_depth_link(void){
- _uniform_scene_depth_uMdl = glGetUniformLocation( _shader_scene_depth.id, "uMdl" );
- _uniform_scene_depth_uPv = glGetUniformLocation( _shader_scene_depth.id, "uPv" );
- _uniform_scene_depth_uPvmPrev = glGetUniformLocation( _shader_scene_depth.id, "uPvmPrev" );
- _uniform_scene_depth_uCamera = glGetUniformLocation( _shader_scene_depth.id, "uCamera" );
- _uniform_scene_depth_uBoard0 = glGetUniformLocation( _shader_scene_depth.id, "uBoard0" );
- _uniform_scene_depth_uBoard1 = glGetUniformLocation( _shader_scene_depth.id, "uBoard1" );
- _uniform_scene_depth_g_world_depth = glGetUniformLocation( _shader_scene_depth.id, "g_world_depth" );
- _uniform_scene_depth_uLightsArray = glGetUniformLocation( _shader_scene_depth.id, "uLightsArray" );
- _uniform_scene_depth_uLightsIndex = glGetUniformLocation( _shader_scene_depth.id, "uLightsIndex" );
+static inline void shader_scene_depth_use(void);
+static inline void shader_scene_depth_use(void)
+{
+ glUseProgram(_shader_scene_depth.id);
}
-#endif /* SHADER_scene_depth_H */
-#ifndef SHADER_scene_foliage_H
-#define SHADER_scene_foliage_H
-static void shader_scene_foliage_link(void);
-static void shader_scene_foliage_register(void);
-static struct vg_shader _shader_scene_foliage = {
- .name = "scene_foliage",
- .link = shader_scene_foliage_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_scene_foliage;
+extern GLuint _uniform_scene_foliage_uMdl;
+extern GLuint _uniform_scene_foliage_uPv;
+extern GLuint _uniform_scene_foliage_uPvmPrev;
+extern GLuint _uniform_scene_foliage_uTime;
+extern GLuint _uniform_scene_foliage_uTexGarbage;
+extern GLuint _uniform_scene_foliage_uTexMain;
+extern GLuint _uniform_scene_foliage_uCamera;
+extern GLuint _uniform_scene_foliage_uPlane;
+extern GLuint _uniform_scene_foliage_g_world_depth;
+extern GLuint _uniform_scene_foliage_uLightsArray;
+extern GLuint _uniform_scene_foliage_uLightsIndex;
+static inline void shader_scene_foliage_uMdl(m4x3f m)
{
-.orig_file = "shaders/scene_foliage.vs",
-.static_src =
-"layout (location=0) in vec3 a_co;\n"
-"layout (location=1) in vec4 a_norm;\n"
-"layout (location=2) in vec2 a_uv;\n"
-"\n"
-"#line 1 1 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"out vec3 aMotionVec0;\n"
-"out vec3 aMotionVec1;\n"
-"\n"
-"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
-"{\n"
-" // This magically solves some artifacting errors!\n"
-" //\n"
-" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
-"\n"
-" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
-" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
-"}\n"
-"\n"
-"#line 6 0 \n"
-"\n"
-"uniform mat4x3 uMdl;\n"
-"uniform mat4 uPv;\n"
-"uniform mat4 uPvmPrev;\n"
-"uniform float uTime;\n"
-"\n"
-"out vec2 aUv;\n"
-"out vec4 aNorm;\n"
-"out vec3 aCo;\n"
-"out vec3 aWorldCo;\n"
-"\n"
-"void main(){\n"
-" vec4 vsine = sin(vec4(uTime + a_co.x, uTime*0.7 + a_co.z,uTime,uTime*1.3));\n"
-" vec3 co = a_co + vsine.xyz * a_norm.w * 0.5;\n"
-" \n"
-" vec3 world_pos0 = uMdl * vec4( co, 1.0 );\n"
-" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
-" vec4 vproj1 = uPvmPrev * vec4( co, 1.0 );\n"
-"\n"
-" vs_motion_out( vproj0, vproj1 );\n"
-"\n"
-" gl_Position = vproj0;\n"
-"\n"
-" aUv = a_uv;\n"
-" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
-" aCo = a_co;\n"
-" aWorldCo = world_pos0;\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/scene_foliage.fs",
-.static_src =
-"uniform sampler2D uTexGarbage;\n"
-"uniform sampler2D uTexMain;\n"
-"uniform vec3 uCamera;\n"
-"uniform vec4 uPlane;\n"
-"\n"
-"const float CLEARSKIES_LIGHT_DOT_MIN = 0.4;\n"
-"#line 1 1 \n"
-"// :D\n"
-"\n"
-"in vec2 aUv;\n"
-"in vec4 aNorm;\n"
-"in vec3 aCo;\n"
-"in vec3 aWorldCo;\n"
-"\n"
-"#line 1 1 \n"
-"layout (location = 0) out vec4 oColour;\n"
-"\n"
-"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
-"layout (std140) uniform ub_world_lighting\n"
-"{\n"
-" vec4 g_cube_min;\n"
-" vec4 g_cube_inv_range;\n"
-"\n"
-" vec4 g_water_plane;\n"
-" vec4 g_depth_bounds;\n"
-"\n"
-" vec4 g_daysky_colour;\n"
-" vec4 g_nightsky_colour;\n"
-" vec4 g_sunset_colour;\n"
-" vec4 g_ambient_colour;\n"
-" vec4 g_sunset_ambient;\n"
-" vec4 g_sun_colour;\n"
-" vec4 g_sun_dir;\n"
-" vec4 g_board_0;\n"
-" vec4 g_board_1;\n"
-"\n"
-" float g_water_fog;\n"
-" float g_time;\n"
-" float g_realtime;\n"
-" float g_shadow_length;\n"
-" float g_shadow_spread;\n"
-"\n"
-" float g_time_of_day;\n"
-" float g_day_phase;\n"
-" float g_sunset_phase;\n"
-"\n"
-" int g_light_preview;\n"
-" int g_shadow_samples;\n"
-"\n"
-" int g_debug_indices;\n"
-" int g_debug_complexity;\n"
-"};\n"
-"\n"
-"uniform sampler2D g_world_depth;\n"
-"uniform samplerBuffer uLightsArray;\n"
-"uniform usampler3D uLightsIndex;\n"
-"\n"
-"#line 1 1 \n"
-"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
-"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
-"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
-"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
-"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
-"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
-"\n"
-"const float SUN_ANGLE = 0.0001;\n"
-"const float PI = 3.14159265358979323846264;\n"
-"\n"
-"//struct world_info\n"
-"//{\n"
-"// float time,\n"
-"// time_of_day,\n"
-"// day_phase,\n"
-"// sunset_phase;\n"
-"// \n"
-"// vec3 sun_dir;\n"
-"//};\n"
-"\n"
-"vec3 rand33(vec3 p3)\n"
-"{\n"
-" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
-" p3 += dot(p3, p3.yxz+33.33);\n"
-" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
-"}\n"
-"\n"
-"float stars( vec3 rd, float rr, float size ){\n"
-" vec3 co = rd * rr;\n"
-"\n"
-" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
-"\n"
-" float spaces = 1.0 / rr;\n"
-" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
-" a -= mod(a, spaces) - spaces * 0.5;\n"
-"\n"
-" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
-" \n"
-" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
-" plane = plane - mod(plane, PI / count);\n"
-"\n"
-" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
-"\n"
-" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
-" float ydist = sqrt(rr * rr - level * level);\n"
-" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
-" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
-" float star = smoothstep(size, 0.0, distance(center, co));\n"
-" return star;\n"
-"}\n"
-"\n"
-"float luminance( vec3 v )\n"
-"{\n"
-" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
-"}\n"
-"\n"
-"vec3 clearskies_ambient( vec3 dir )\n"
-"{\n"
-" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
-" float sky_gradient = dir.y;\n"
-" \n"
-" /* Blend phase colours */\n"
-" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
-" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
-" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
-" \n"
-" /* Add gradient */\n"
-" ambient -= sky_gradient * luminance(ambient);\n"
-" \n"
-" return ambient;\n"
-"}\n"
-"\n"
-"vec3 clearskies_sky( vec3 ray_dir )\n"
-"{\n"
-" ray_dir.y = abs( ray_dir.y );\n"
-" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
-" \n"
-" /* Sun */\n"
-" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
-" float sun_shape = pow( sun_size, 2000.0 );\n"
-" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" \n"
-" float star = 0.0;\n"
-" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
-"\n"
-" if( star_blend > 0.001 ){\n"
-" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
-" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
-" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
-" }\n"
-" }\n"
-" \n"
-" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
-" return composite;\n"
-"}\n"
-"\n"
-"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
-"{\n"
-" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
-"\n"
-" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
-" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
-" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
-" ) * g_sun_colour.rgb * g_day_phase;\n"
-"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
-" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" return ambient + (light_sun + sky_reflection) * shadow;\n"
-"}\n"
-"\n"
-"#line 44 0 \n"
-"\n"
-"float world_depth_sample( vec3 pos )\n"
-"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
-" return texture( g_world_depth, depth_coord ).r;\n"
-"}\n"
-"\n"
-"float world_water_depth( vec3 pos )\n"
-"{\n"
-" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return world_depth_sample( pos ) - ref_depth;\n"
-"}\n"
-"\n"
-"float shadow_sample( vec3 co ){\n"
-" float height_sample = world_depth_sample( co );\n"
-"\n"
-" float fdelta = height_sample - co.y;\n"
-" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
-"}\n"
-"\n"
-"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
-" if( g_shadow_samples == 0 ){\n"
-" return 1.0;\n"
-" }\n"
-"\n"
-" float fspread = g_shadow_spread;\n"
-" float flength = g_shadow_length;\n"
-"\n"
-" float famt = 0.0;\n"
-" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
-"\n"
-" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
-"\n"
-" return 1.0 - famt;\n"
-"}\n"
-"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
-"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
-"}\n"
-"\n"
-"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
-" float dist = pow(fdist*0.0010,0.78);\n"
-" return mix( vfrag, colour, min( 1.0, dist ) );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_light( int light_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
-" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
-" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
-"\n"
-" vec3 light_delta = light_co.xyz-co;\n"
-" float dist2 = dot(light_delta,light_delta);\n"
-"\n"
-" light_delta = normalize( light_delta );\n"
-"\n"
-" float quadratic = dist2*100.0;\n"
-" float attenuation = 1.0/( 1.0 + quadratic );\n"
-" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
-"\n"
-" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
-"\n"
-" if( light_dir.w < 0.999999 ){\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
-" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
-" }\n"
-"\n"
-" return light_colour.rgb * attenuation * falloff \n"
-" * step( g_day_phase, light_colour.w );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" uint light_count = packed_index & 0x3u;\n"
-"\n"
-" vec3 l = vec3(0.0);\n"
-"\n"
-" if( light_count >= 1u ){\n"
-" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
-" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
-" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
-"\n"
-" l += scene_calculate_light( index_0, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 2u ){\n"
-" l += scene_calculate_light( index_1, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 3u ){\n"
-" l += scene_calculate_light( index_2, halfview, co, normal );\n"
-" }\n"
-" }\n"
-" }\n"
-"\n"
-" return l;\n"
-"}\n"
-"\n"
-"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
-" float light_mask )\n"
-"{\n"
-" if( g_light_preview == 1 )\n"
-" diffuse = vec3(0.75);\n"
-"\n"
-" // Lighting\n"
-" vec3 halfview = uCamera - co;\n"
-" float fdist = length(halfview);\n"
-" halfview /= fdist;\n"
-"\n"
-" float world_shadow = newlight_compute_sun_shadow( \n"
-" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
-"\n"
-" vec3 total_light = clearskies_lighting( \n"
-" normal, min( light_mask, world_shadow ), halfview );\n"
-"\n"
-" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
-" cube_coord = floor( cube_coord );\n"
-"\n"
-" if( g_debug_indices == 1 )\n"
-" {\n"
-" return rand33(cube_coord);\n"
-" }\n"
-"\n"
-" if( g_debug_complexity == 1 )\n"
-" {\n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
-" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
-" }\n"
-"\n"
-" // FIXME: this coord should absolutely must be clamped!\n"
-" \n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, co, normal ) \n"
-" * light_mask;\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, co, normal )\n"
-" * light_mask;\n"
-"\n"
-" // Take a section of the sky function to give us a matching fog colour\n"
-"\n"
-" vec3 fog_colour = clearskies_ambient( -halfview );\n"
-" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
-" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" fog_colour += sun_colour;\n"
-" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"\n"
-"float sdLine( vec3 p, vec3 a, vec3 b )\n"
-"{\n"
-" vec3 pa = p - a;\n"
-" vec3 ba = b - a;\n"
-"\n"
-" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
-" return length( pa - ba*h );\n"
-"}\n"
-"\n"
-"float compute_board_shadow()\n"
-"{\n"
-" // player shadow\n"
-" float dist_to_player = max( 0.0, sdLine( aWorldCo, g_board_0.xyz,\n"
-" g_board_1.xyz )-0.1 );\n"
-" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
-" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
-"\n"
-" return 1.0 - player_shadow*0.8;\n"
-"}\n"
-"\n"
-"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
-"{\n"
-" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
-"}\n"
-"\n"
-"#line 8 0 \n"
-"#line 1 2 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"layout (location = 1) out vec2 oMotionVec;\n"
-"\n"
-"in vec3 aMotionVec0;\n"
-"in vec3 aMotionVec1;\n"
-"\n"
-"void compute_motion_vectors()\n"
-"{\n"
-" // Write motion vectors\n"
-" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
-" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
-"\n"
-" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"\n"
-"void main(){\n"
-" compute_motion_vectors();\n"
-"\n"
-" vec3 vfrag = vec3(0.5,0.5,0.5);\n"
-" vec4 vsamplemain = texture( uTexMain, aUv );\n"
-" vec3 qnorm = aNorm.xyz;\n"
-"\n"
-" if( vsamplemain.a < 0.15 )\n"
-" discard;\n"
-"\n"
-" vfrag = vsamplemain.rgb;\n"
-"\n"
-" if( g_light_preview == 1 ){\n"
-" vfrag = vec3(0.5);\n"
-" }\n"
-"\n"
-" vfrag = scene_compute_lighting( vfrag, qnorm, aWorldCo );\n"
-" oColour = vec4(vfrag, 1.0);\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_scene_foliage_uMdl;
-static GLuint _uniform_scene_foliage_uPv;
-static GLuint _uniform_scene_foliage_uPvmPrev;
-static GLuint _uniform_scene_foliage_uTime;
-static GLuint _uniform_scene_foliage_uTexGarbage;
-static GLuint _uniform_scene_foliage_uTexMain;
-static GLuint _uniform_scene_foliage_uCamera;
-static GLuint _uniform_scene_foliage_uPlane;
-static GLuint _uniform_scene_foliage_g_world_depth;
-static GLuint _uniform_scene_foliage_uLightsArray;
-static GLuint _uniform_scene_foliage_uLightsIndex;
-static void shader_scene_foliage_uMdl(m4x3f m){
- glUniformMatrix4x3fv(_uniform_scene_foliage_uMdl,1,GL_FALSE,(float*)m);
+ glUniformMatrix4x3fv(_uniform_scene_foliage_uMdl,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_foliage_uPv(m4x4f m){
- glUniformMatrix4fv(_uniform_scene_foliage_uPv,1,GL_FALSE,(float*)m);
+static inline void shader_scene_foliage_uPv(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_scene_foliage_uPv,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_foliage_uPvmPrev(m4x4f m){
- glUniformMatrix4fv(_uniform_scene_foliage_uPvmPrev,1,GL_FALSE,(float*)m);
+static inline void shader_scene_foliage_uPvmPrev(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_scene_foliage_uPvmPrev,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_foliage_uTime(float f){
+static inline void shader_scene_foliage_uTime(f32 f)
+{
glUniform1f(_uniform_scene_foliage_uTime,f);
}
-static void shader_scene_foliage_uTexGarbage(int i){
+static inline void shader_scene_foliage_uTexGarbage(int i)
+{
glUniform1i(_uniform_scene_foliage_uTexGarbage,i);
}
-static void shader_scene_foliage_uTexMain(int i){
+static inline void shader_scene_foliage_uTexMain(int i)
+{
glUniform1i(_uniform_scene_foliage_uTexMain,i);
}
-static void shader_scene_foliage_uCamera(v3f v){
+static inline void shader_scene_foliage_uCamera(v3f v)
+{
glUniform3fv(_uniform_scene_foliage_uCamera,1,v);
}
-static void shader_scene_foliage_uPlane(v4f v){
+static inline void shader_scene_foliage_uPlane(v4f v)
+{
glUniform4fv(_uniform_scene_foliage_uPlane,1,v);
}
-static void shader_scene_foliage_g_world_depth(int i){
+static inline void shader_scene_foliage_g_world_depth(int i)
+{
glUniform1i(_uniform_scene_foliage_g_world_depth,i);
}
-static void shader_scene_foliage_register(void){
- vg_shader_register( &_shader_scene_foliage );
-}
-static void shader_scene_foliage_use(void){ glUseProgram(_shader_scene_foliage.id); }
-static void shader_scene_foliage_link(void){
- _uniform_scene_foliage_uMdl = glGetUniformLocation( _shader_scene_foliage.id, "uMdl" );
- _uniform_scene_foliage_uPv = glGetUniformLocation( _shader_scene_foliage.id, "uPv" );
- _uniform_scene_foliage_uPvmPrev = glGetUniformLocation( _shader_scene_foliage.id, "uPvmPrev" );
- _uniform_scene_foliage_uTime = glGetUniformLocation( _shader_scene_foliage.id, "uTime" );
- _uniform_scene_foliage_uTexGarbage = glGetUniformLocation( _shader_scene_foliage.id, "uTexGarbage" );
- _uniform_scene_foliage_uTexMain = glGetUniformLocation( _shader_scene_foliage.id, "uTexMain" );
- _uniform_scene_foliage_uCamera = glGetUniformLocation( _shader_scene_foliage.id, "uCamera" );
- _uniform_scene_foliage_uPlane = glGetUniformLocation( _shader_scene_foliage.id, "uPlane" );
- _uniform_scene_foliage_g_world_depth = glGetUniformLocation( _shader_scene_foliage.id, "g_world_depth" );
- _uniform_scene_foliage_uLightsArray = glGetUniformLocation( _shader_scene_foliage.id, "uLightsArray" );
- _uniform_scene_foliage_uLightsIndex = glGetUniformLocation( _shader_scene_foliage.id, "uLightsIndex" );
+static inline void shader_scene_foliage_use(void);
+static inline void shader_scene_foliage_use(void)
+{
+ glUseProgram(_shader_scene_foliage.id);
}
-#endif /* SHADER_scene_foliage_H */
-#ifndef SHADER_scene_font_H
-#define SHADER_scene_font_H
-static void shader_scene_font_link(void);
-static void shader_scene_font_register(void);
-static struct vg_shader _shader_scene_font = {
- .name = "scene_font",
- .link = shader_scene_font_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_scene_font;
+extern GLuint _uniform_scene_font_uMdl;
+extern GLuint _uniform_scene_font_uPv;
+extern GLuint _uniform_scene_font_uPvmPrev;
+extern GLuint _uniform_scene_font_uOffset;
+extern GLuint _uniform_scene_font_uTexGarbage;
+extern GLuint _uniform_scene_font_uTexMain;
+extern GLuint _uniform_scene_font_uCamera;
+extern GLuint _uniform_scene_font_uTime;
+extern GLuint _uniform_scene_font_uOpacity;
+extern GLuint _uniform_scene_font_uColourize;
+extern GLuint _uniform_scene_font_g_world_depth;
+extern GLuint _uniform_scene_font_uLightsArray;
+extern GLuint _uniform_scene_font_uLightsIndex;
+static inline void shader_scene_font_uMdl(m4x3f m)
{
-.orig_file = "shaders/model_font.vs",
-.static_src =
-"layout (location=0) in vec3 a_co;\n"
-"layout (location=1) in vec3 a_norm;\n"
-"layout (location=2) in vec2 a_uv;\n"
-"\n"
-"#line 1 1 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"out vec3 aMotionVec0;\n"
-"out vec3 aMotionVec1;\n"
-"\n"
-"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
-"{\n"
-" // This magically solves some artifacting errors!\n"
-" //\n"
-" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
-"\n"
-" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
-" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
-"}\n"
-"\n"
-"#line 6 0 \n"
-"\n"
-"uniform mat4x3 uMdl;\n"
-"uniform mat4 uPv;\n"
-"uniform mat4 uPvmPrev;\n"
-"uniform vec4 uOffset;\n"
-"\n"
-"out vec2 aUv;\n"
-"out vec4 aNorm;\n"
-"out vec3 aCo;\n"
-"out vec3 aWorldCo;\n"
-"\n"
-"void main()\n"
-"{\n"
-" vec3 co = a_co*uOffset.w+uOffset.xyz;\n"
-" vec3 world_pos0 = uMdl * vec4( co, 1.0 );\n"
-" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
-" vec4 vproj1 = uPvmPrev * vec4( co, 1.0 );\n"
-"\n"
-" vs_motion_out( vproj0, vproj1 );\n"
-"\n"
-" gl_Position = vproj0;\n"
-"\n"
-" aUv = a_uv;\n"
-" aNorm = vec4( mat3(uMdl) * a_norm, 0.0 );\n"
-" aCo = co;\n"
-" aWorldCo = world_pos0;\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/scene_font.fs",
-.static_src =
-"uniform sampler2D uTexGarbage; // unused\n"
-"uniform sampler2D uTexMain; // unused\n"
-"uniform vec3 uCamera;\n"
-"uniform float uTime;\n"
-"uniform float uOpacity;\n"
-"uniform float uColourize;\n"
-"\n"
-"#line 1 1 \n"
-"// :D\n"
-"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
-"\n"
-"#line 9 0 \n"
-"#line 1 2 \n"
-"// :D\n"
-"\n"
-"in vec2 aUv;\n"
-"in vec4 aNorm;\n"
-"in vec3 aCo;\n"
-"in vec3 aWorldCo;\n"
-"\n"
-"#line 1 1 \n"
-"layout (location = 0) out vec4 oColour;\n"
-"\n"
-"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
-"layout (std140) uniform ub_world_lighting\n"
-"{\n"
-" vec4 g_cube_min;\n"
-" vec4 g_cube_inv_range;\n"
-"\n"
-" vec4 g_water_plane;\n"
-" vec4 g_depth_bounds;\n"
-"\n"
-" vec4 g_daysky_colour;\n"
-" vec4 g_nightsky_colour;\n"
-" vec4 g_sunset_colour;\n"
-" vec4 g_ambient_colour;\n"
-" vec4 g_sunset_ambient;\n"
-" vec4 g_sun_colour;\n"
-" vec4 g_sun_dir;\n"
-" vec4 g_board_0;\n"
-" vec4 g_board_1;\n"
-"\n"
-" float g_water_fog;\n"
-" float g_time;\n"
-" float g_realtime;\n"
-" float g_shadow_length;\n"
-" float g_shadow_spread;\n"
-"\n"
-" float g_time_of_day;\n"
-" float g_day_phase;\n"
-" float g_sunset_phase;\n"
-"\n"
-" int g_light_preview;\n"
-" int g_shadow_samples;\n"
-"\n"
-" int g_debug_indices;\n"
-" int g_debug_complexity;\n"
-"};\n"
-"\n"
-"uniform sampler2D g_world_depth;\n"
-"uniform samplerBuffer uLightsArray;\n"
-"uniform usampler3D uLightsIndex;\n"
-"\n"
-"#line 1 1 \n"
-"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
-"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
-"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
-"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
-"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
-"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
-"\n"
-"const float SUN_ANGLE = 0.0001;\n"
-"const float PI = 3.14159265358979323846264;\n"
-"\n"
-"//struct world_info\n"
-"//{\n"
-"// float time,\n"
-"// time_of_day,\n"
-"// day_phase,\n"
-"// sunset_phase;\n"
-"// \n"
-"// vec3 sun_dir;\n"
-"//};\n"
-"\n"
-"vec3 rand33(vec3 p3)\n"
-"{\n"
-" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
-" p3 += dot(p3, p3.yxz+33.33);\n"
-" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
-"}\n"
-"\n"
-"float stars( vec3 rd, float rr, float size ){\n"
-" vec3 co = rd * rr;\n"
-"\n"
-" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
-"\n"
-" float spaces = 1.0 / rr;\n"
-" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
-" a -= mod(a, spaces) - spaces * 0.5;\n"
-"\n"
-" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
-" \n"
-" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
-" plane = plane - mod(plane, PI / count);\n"
-"\n"
-" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
-"\n"
-" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
-" float ydist = sqrt(rr * rr - level * level);\n"
-" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
-" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
-" float star = smoothstep(size, 0.0, distance(center, co));\n"
-" return star;\n"
-"}\n"
-"\n"
-"float luminance( vec3 v )\n"
-"{\n"
-" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
-"}\n"
-"\n"
-"vec3 clearskies_ambient( vec3 dir )\n"
-"{\n"
-" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
-" float sky_gradient = dir.y;\n"
-" \n"
-" /* Blend phase colours */\n"
-" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
-" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
-" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
-" \n"
-" /* Add gradient */\n"
-" ambient -= sky_gradient * luminance(ambient);\n"
-" \n"
-" return ambient;\n"
-"}\n"
-"\n"
-"vec3 clearskies_sky( vec3 ray_dir )\n"
-"{\n"
-" ray_dir.y = abs( ray_dir.y );\n"
-" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
-" \n"
-" /* Sun */\n"
-" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
-" float sun_shape = pow( sun_size, 2000.0 );\n"
-" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" \n"
-" float star = 0.0;\n"
-" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
-"\n"
-" if( star_blend > 0.001 ){\n"
-" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
-" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
-" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
-" }\n"
-" }\n"
-" \n"
-" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
-" return composite;\n"
-"}\n"
-"\n"
-"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
-"{\n"
-" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
-"\n"
-" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
-" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
-" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
-" ) * g_sun_colour.rgb * g_day_phase;\n"
-"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
-" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" return ambient + (light_sun + sky_reflection) * shadow;\n"
-"}\n"
-"\n"
-"#line 44 0 \n"
-"\n"
-"float world_depth_sample( vec3 pos )\n"
-"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
-" return texture( g_world_depth, depth_coord ).r;\n"
-"}\n"
-"\n"
-"float world_water_depth( vec3 pos )\n"
-"{\n"
-" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return world_depth_sample( pos ) - ref_depth;\n"
-"}\n"
-"\n"
-"float shadow_sample( vec3 co ){\n"
-" float height_sample = world_depth_sample( co );\n"
-"\n"
-" float fdelta = height_sample - co.y;\n"
-" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
-"}\n"
-"\n"
-"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
-" if( g_shadow_samples == 0 ){\n"
-" return 1.0;\n"
-" }\n"
-"\n"
-" float fspread = g_shadow_spread;\n"
-" float flength = g_shadow_length;\n"
-"\n"
-" float famt = 0.0;\n"
-" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
-"\n"
-" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
-"\n"
-" return 1.0 - famt;\n"
-"}\n"
-"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
-"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
-"}\n"
-"\n"
-"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
-" float dist = pow(fdist*0.0010,0.78);\n"
-" return mix( vfrag, colour, min( 1.0, dist ) );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_light( int light_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
-" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
-" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
-"\n"
-" vec3 light_delta = light_co.xyz-co;\n"
-" float dist2 = dot(light_delta,light_delta);\n"
-"\n"
-" light_delta = normalize( light_delta );\n"
-"\n"
-" float quadratic = dist2*100.0;\n"
-" float attenuation = 1.0/( 1.0 + quadratic );\n"
-" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
-"\n"
-" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
-"\n"
-" if( light_dir.w < 0.999999 ){\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
-" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
-" }\n"
-"\n"
-" return light_colour.rgb * attenuation * falloff \n"
-" * step( g_day_phase, light_colour.w );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" uint light_count = packed_index & 0x3u;\n"
-"\n"
-" vec3 l = vec3(0.0);\n"
-"\n"
-" if( light_count >= 1u ){\n"
-" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
-" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
-" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
-"\n"
-" l += scene_calculate_light( index_0, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 2u ){\n"
-" l += scene_calculate_light( index_1, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 3u ){\n"
-" l += scene_calculate_light( index_2, halfview, co, normal );\n"
-" }\n"
-" }\n"
-" }\n"
-"\n"
-" return l;\n"
-"}\n"
-"\n"
-"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
-" float light_mask )\n"
-"{\n"
-" if( g_light_preview == 1 )\n"
-" diffuse = vec3(0.75);\n"
-"\n"
-" // Lighting\n"
-" vec3 halfview = uCamera - co;\n"
-" float fdist = length(halfview);\n"
-" halfview /= fdist;\n"
-"\n"
-" float world_shadow = newlight_compute_sun_shadow( \n"
-" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
-"\n"
-" vec3 total_light = clearskies_lighting( \n"
-" normal, min( light_mask, world_shadow ), halfview );\n"
-"\n"
-" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
-" cube_coord = floor( cube_coord );\n"
-"\n"
-" if( g_debug_indices == 1 )\n"
-" {\n"
-" return rand33(cube_coord);\n"
-" }\n"
-"\n"
-" if( g_debug_complexity == 1 )\n"
-" {\n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
-" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
-" }\n"
-"\n"
-" // FIXME: this coord should absolutely must be clamped!\n"
-" \n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, co, normal ) \n"
-" * light_mask;\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, co, normal )\n"
-" * light_mask;\n"
-"\n"
-" // Take a section of the sky function to give us a matching fog colour\n"
-"\n"
-" vec3 fog_colour = clearskies_ambient( -halfview );\n"
-" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
-" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" fog_colour += sun_colour;\n"
-" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"\n"
-"float sdLine( vec3 p, vec3 a, vec3 b )\n"
-"{\n"
-" vec3 pa = p - a;\n"
-" vec3 ba = b - a;\n"
-"\n"
-" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
-" return length( pa - ba*h );\n"
-"}\n"
-"\n"
-"float compute_board_shadow()\n"
-"{\n"
-" // player shadow\n"
-" float dist_to_player = max( 0.0, sdLine( aWorldCo, g_board_0.xyz,\n"
-" g_board_1.xyz )-0.1 );\n"
-" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
-" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
-"\n"
-" return 1.0 - player_shadow*0.8;\n"
-"}\n"
-"\n"
-"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
-"{\n"
-" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
-"}\n"
-"\n"
-"#line 10 0 \n"
-"#line 1 3 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"layout (location = 1) out vec2 oMotionVec;\n"
-"\n"
-"in vec3 aMotionVec0;\n"
-"in vec3 aMotionVec1;\n"
-"\n"
-"void compute_motion_vectors()\n"
-"{\n"
-" // Write motion vectors\n"
-" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
-" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
-"\n"
-" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
-"}\n"
-"\n"
-"#line 11 0 \n"
-"\n"
-"vec3 pal( float t ){\n"
-" vec3 a = vec3(0.30,0.3,0.3);\n"
-" vec3 b = vec3(0.8);\n"
-" vec3 c = vec3(0.28,0.3,0.4);\n"
-" vec3 d = vec3(0.00,0.1,0.1);\n"
-" return a + b*cos( 6.28318*(c*t+d) );\n"
-"}\n"
-"\n"
-"void main(){\n"
-" compute_motion_vectors();\n"
-" vec3 vfrag = vec3(0.5,0.5,0.5);\n"
-" vec3 qnorm = aNorm.xyz;\n"
-"\n"
-" //vec4 vsamplemain = texture( uTexMain, aUv );\n"
-" //vfrag = vsamplemain.rgb;\n"
-"\n"
-" vec4 spread0 = uTime*0.0002*vec4( 17.3,-19.6, 23.2,-47.7 );\n"
-" vec4 spread1 = uTime*0.0002*vec4( -13.3, 12.6,-28.2, 14.7 );\n"
-"\n"
-" vec2 p = aCo.xy + vec2(0.3);\n"
-" float a = atan( p.y/p.x );\n"
-" vec4 v0 = step( vec4(0.5), fract(vec4(a) + spread0) );\n"
-" vec4 v1 = step( vec4(0.5), fract(vec4(a) + spread1) );\n"
-"\n"
-" float d = ( v0.x+v0.y+v0.z+v0.w +\n"
-" v1.x+v1.y+v1.z+v1.w ) * 0.125;\n"
-" \n"
-" float dither = fract(dot(vec2(171.0,231.0),gl_FragCoord.xy)/71.0);\n"
-" float x = d*0.8+length(p)*0.3;\n"
-" x = (floor(x*8.0) + step(dither, fract(x * 8.0))) / 8.0;\n"
-"\n"
-" if( x + (uOpacity*2.0-1.0) < 0.5 ) \n"
-" discard;\n"
-"\n"
-" vfrag = mix( vec3(x), pal( x ), uColourize );\n"
-"\n"
-" if( g_light_preview == 1 ){\n"
-" vfrag = vec3(0.5);\n"
-" }\n"
-"\n"
-" vfrag = scene_compute_lighting( vfrag, qnorm, aWorldCo );\n"
-" oColour = vec4( vfrag, 1.0 );\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_scene_font_uMdl;
-static GLuint _uniform_scene_font_uPv;
-static GLuint _uniform_scene_font_uPvmPrev;
-static GLuint _uniform_scene_font_uOffset;
-static GLuint _uniform_scene_font_uTexGarbage;
-static GLuint _uniform_scene_font_uTexMain;
-static GLuint _uniform_scene_font_uCamera;
-static GLuint _uniform_scene_font_uTime;
-static GLuint _uniform_scene_font_uOpacity;
-static GLuint _uniform_scene_font_uColourize;
-static GLuint _uniform_scene_font_g_world_depth;
-static GLuint _uniform_scene_font_uLightsArray;
-static GLuint _uniform_scene_font_uLightsIndex;
-static void shader_scene_font_uMdl(m4x3f m){
- glUniformMatrix4x3fv(_uniform_scene_font_uMdl,1,GL_FALSE,(float*)m);
+ glUniformMatrix4x3fv(_uniform_scene_font_uMdl,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_font_uPv(m4x4f m){
- glUniformMatrix4fv(_uniform_scene_font_uPv,1,GL_FALSE,(float*)m);
+static inline void shader_scene_font_uPv(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_scene_font_uPv,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_font_uPvmPrev(m4x4f m){
- glUniformMatrix4fv(_uniform_scene_font_uPvmPrev,1,GL_FALSE,(float*)m);
+static inline void shader_scene_font_uPvmPrev(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_scene_font_uPvmPrev,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_font_uOffset(v4f v){
+static inline void shader_scene_font_uOffset(v4f v)
+{
glUniform4fv(_uniform_scene_font_uOffset,1,v);
}
-static void shader_scene_font_uTexGarbage(int i){
+static inline void shader_scene_font_uTexGarbage(int i)
+{
glUniform1i(_uniform_scene_font_uTexGarbage,i);
}
-static void shader_scene_font_uTexMain(int i){
+static inline void shader_scene_font_uTexMain(int i)
+{
glUniform1i(_uniform_scene_font_uTexMain,i);
}
-static void shader_scene_font_uCamera(v3f v){
+static inline void shader_scene_font_uCamera(v3f v)
+{
glUniform3fv(_uniform_scene_font_uCamera,1,v);
}
-static void shader_scene_font_uTime(float f){
+static inline void shader_scene_font_uTime(f32 f)
+{
glUniform1f(_uniform_scene_font_uTime,f);
}
-static void shader_scene_font_uOpacity(float f){
+static inline void shader_scene_font_uOpacity(f32 f)
+{
glUniform1f(_uniform_scene_font_uOpacity,f);
}
-static void shader_scene_font_uColourize(float f){
+static inline void shader_scene_font_uColourize(f32 f)
+{
glUniform1f(_uniform_scene_font_uColourize,f);
}
-static void shader_scene_font_g_world_depth(int i){
+static inline void shader_scene_font_g_world_depth(int i)
+{
glUniform1i(_uniform_scene_font_g_world_depth,i);
}
-static void shader_scene_font_register(void){
- vg_shader_register( &_shader_scene_font );
-}
-static void shader_scene_font_use(void){ glUseProgram(_shader_scene_font.id); }
-static void shader_scene_font_link(void){
- _uniform_scene_font_uMdl = glGetUniformLocation( _shader_scene_font.id, "uMdl" );
- _uniform_scene_font_uPv = glGetUniformLocation( _shader_scene_font.id, "uPv" );
- _uniform_scene_font_uPvmPrev = glGetUniformLocation( _shader_scene_font.id, "uPvmPrev" );
- _uniform_scene_font_uOffset = glGetUniformLocation( _shader_scene_font.id, "uOffset" );
- _uniform_scene_font_uTexGarbage = glGetUniformLocation( _shader_scene_font.id, "uTexGarbage" );
- _uniform_scene_font_uTexMain = glGetUniformLocation( _shader_scene_font.id, "uTexMain" );
- _uniform_scene_font_uCamera = glGetUniformLocation( _shader_scene_font.id, "uCamera" );
- _uniform_scene_font_uTime = glGetUniformLocation( _shader_scene_font.id, "uTime" );
- _uniform_scene_font_uOpacity = glGetUniformLocation( _shader_scene_font.id, "uOpacity" );
- _uniform_scene_font_uColourize = glGetUniformLocation( _shader_scene_font.id, "uColourize" );
- _uniform_scene_font_g_world_depth = glGetUniformLocation( _shader_scene_font.id, "g_world_depth" );
- _uniform_scene_font_uLightsArray = glGetUniformLocation( _shader_scene_font.id, "uLightsArray" );
- _uniform_scene_font_uLightsIndex = glGetUniformLocation( _shader_scene_font.id, "uLightsIndex" );
+static inline void shader_scene_font_use(void);
+static inline void shader_scene_font_use(void)
+{
+ glUseProgram(_shader_scene_font.id);
}
-#endif /* SHADER_scene_font_H */
-#ifndef SHADER_scene_fxglow_H
-#define SHADER_scene_fxglow_H
-static void shader_scene_fxglow_link(void);
-static void shader_scene_fxglow_register(void);
-static struct vg_shader _shader_scene_fxglow = {
- .name = "scene_fxglow",
- .link = shader_scene_fxglow_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_scene_fxglow;
+extern GLuint _uniform_scene_fxglow_uMdl;
+extern GLuint _uniform_scene_fxglow_uPv;
+extern GLuint _uniform_scene_fxglow_uPvmPrev;
+extern GLuint _uniform_scene_fxglow_uUvOffset;
+extern GLuint _uniform_scene_fxglow_uTexMain;
+extern GLuint _uniform_scene_fxglow_uCamera;
+extern GLuint _uniform_scene_fxglow_g_world_depth;
+extern GLuint _uniform_scene_fxglow_uLightsArray;
+extern GLuint _uniform_scene_fxglow_uLightsIndex;
+static inline void shader_scene_fxglow_uMdl(m4x3f m)
{
-.orig_file = "shaders/scene_fxglow.vs",
-.static_src =
-"layout (location=0) in vec3 a_co;\n"
-"layout (location=1) in vec4 a_norm;\n"
-"layout (location=2) in vec2 a_uv;\n"
-"\n"
-"#line 1 1 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"out vec3 aMotionVec0;\n"
-"out vec3 aMotionVec1;\n"
-"\n"
-"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
-"{\n"
-" // This magically solves some artifacting errors!\n"
-" //\n"
-" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
-"\n"
-" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
-" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
-"}\n"
-"\n"
-"#line 6 0 \n"
-"\n"
-"uniform mat4x3 uMdl;\n"
-"uniform mat4 uPv;\n"
-"uniform mat4 uPvmPrev;\n"
-"uniform vec2 uUvOffset;\n"
-"\n"
-"out vec2 aUv;\n"
-"out vec4 aNorm;\n"
-"out vec3 aCo;\n"
-"out vec3 aWorldCo;\n"
-"\n"
-"void main()\n"
-"{\n"
-" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
-" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
-" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
-"\n"
-" vs_motion_out( vproj0, vproj1 );\n"
-"\n"
-" gl_Position = vproj0;\n"
-"\n"
-" aUv = a_uv + uUvOffset;\n"
-" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
-" aCo = a_co;\n"
-" aWorldCo = world_pos0;\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/scene_fxglow.fs",
-.static_src =
-"uniform sampler2D uTexMain;\n"
-"uniform vec3 uCamera;\n"
-"\n"
-"#line 1 1 \n"
-"// :D\n"
-"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
-"\n"
-"#line 5 0 \n"
-"#line 1 2 \n"
-"// :D\n"
-"\n"
-"in vec2 aUv;\n"
-"in vec4 aNorm;\n"
-"in vec3 aCo;\n"
-"in vec3 aWorldCo;\n"
-"\n"
-"#line 1 1 \n"
-"layout (location = 0) out vec4 oColour;\n"
-"\n"
-"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
-"layout (std140) uniform ub_world_lighting\n"
-"{\n"
-" vec4 g_cube_min;\n"
-" vec4 g_cube_inv_range;\n"
-"\n"
-" vec4 g_water_plane;\n"
-" vec4 g_depth_bounds;\n"
-"\n"
-" vec4 g_daysky_colour;\n"
-" vec4 g_nightsky_colour;\n"
-" vec4 g_sunset_colour;\n"
-" vec4 g_ambient_colour;\n"
-" vec4 g_sunset_ambient;\n"
-" vec4 g_sun_colour;\n"
-" vec4 g_sun_dir;\n"
-" vec4 g_board_0;\n"
-" vec4 g_board_1;\n"
-"\n"
-" float g_water_fog;\n"
-" float g_time;\n"
-" float g_realtime;\n"
-" float g_shadow_length;\n"
-" float g_shadow_spread;\n"
-"\n"
-" float g_time_of_day;\n"
-" float g_day_phase;\n"
-" float g_sunset_phase;\n"
-"\n"
-" int g_light_preview;\n"
-" int g_shadow_samples;\n"
-"\n"
-" int g_debug_indices;\n"
-" int g_debug_complexity;\n"
-"};\n"
-"\n"
-"uniform sampler2D g_world_depth;\n"
-"uniform samplerBuffer uLightsArray;\n"
-"uniform usampler3D uLightsIndex;\n"
-"\n"
-"#line 1 1 \n"
-"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
-"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
-"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
-"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
-"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
-"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
-"\n"
-"const float SUN_ANGLE = 0.0001;\n"
-"const float PI = 3.14159265358979323846264;\n"
-"\n"
-"//struct world_info\n"
-"//{\n"
-"// float time,\n"
-"// time_of_day,\n"
-"// day_phase,\n"
-"// sunset_phase;\n"
-"// \n"
-"// vec3 sun_dir;\n"
-"//};\n"
-"\n"
-"vec3 rand33(vec3 p3)\n"
-"{\n"
-" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
-" p3 += dot(p3, p3.yxz+33.33);\n"
-" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
-"}\n"
-"\n"
-"float stars( vec3 rd, float rr, float size ){\n"
-" vec3 co = rd * rr;\n"
-"\n"
-" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
-"\n"
-" float spaces = 1.0 / rr;\n"
-" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
-" a -= mod(a, spaces) - spaces * 0.5;\n"
-"\n"
-" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
-" \n"
-" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
-" plane = plane - mod(plane, PI / count);\n"
-"\n"
-" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
-"\n"
-" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
-" float ydist = sqrt(rr * rr - level * level);\n"
-" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
-" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
-" float star = smoothstep(size, 0.0, distance(center, co));\n"
-" return star;\n"
-"}\n"
-"\n"
-"float luminance( vec3 v )\n"
-"{\n"
-" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
-"}\n"
-"\n"
-"vec3 clearskies_ambient( vec3 dir )\n"
-"{\n"
-" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
-" float sky_gradient = dir.y;\n"
-" \n"
-" /* Blend phase colours */\n"
-" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
-" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
-" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
-" \n"
-" /* Add gradient */\n"
-" ambient -= sky_gradient * luminance(ambient);\n"
-" \n"
-" return ambient;\n"
-"}\n"
-"\n"
-"vec3 clearskies_sky( vec3 ray_dir )\n"
-"{\n"
-" ray_dir.y = abs( ray_dir.y );\n"
-" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
-" \n"
-" /* Sun */\n"
-" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
-" float sun_shape = pow( sun_size, 2000.0 );\n"
-" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" \n"
-" float star = 0.0;\n"
-" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
-"\n"
-" if( star_blend > 0.001 ){\n"
-" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
-" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
-" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
-" }\n"
-" }\n"
-" \n"
-" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
-" return composite;\n"
-"}\n"
-"\n"
-"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
-"{\n"
-" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
-"\n"
-" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
-" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
-" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
-" ) * g_sun_colour.rgb * g_day_phase;\n"
-"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
-" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" return ambient + (light_sun + sky_reflection) * shadow;\n"
-"}\n"
-"\n"
-"#line 44 0 \n"
-"\n"
-"float world_depth_sample( vec3 pos )\n"
-"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
-" return texture( g_world_depth, depth_coord ).r;\n"
-"}\n"
-"\n"
-"float world_water_depth( vec3 pos )\n"
-"{\n"
-" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return world_depth_sample( pos ) - ref_depth;\n"
-"}\n"
-"\n"
-"float shadow_sample( vec3 co ){\n"
-" float height_sample = world_depth_sample( co );\n"
-"\n"
-" float fdelta = height_sample - co.y;\n"
-" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
-"}\n"
-"\n"
-"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
-" if( g_shadow_samples == 0 ){\n"
-" return 1.0;\n"
-" }\n"
-"\n"
-" float fspread = g_shadow_spread;\n"
-" float flength = g_shadow_length;\n"
-"\n"
-" float famt = 0.0;\n"
-" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
-"\n"
-" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
-"\n"
-" return 1.0 - famt;\n"
-"}\n"
-"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
-"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
-"}\n"
-"\n"
-"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
-" float dist = pow(fdist*0.0010,0.78);\n"
-" return mix( vfrag, colour, min( 1.0, dist ) );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_light( int light_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
-" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
-" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
-"\n"
-" vec3 light_delta = light_co.xyz-co;\n"
-" float dist2 = dot(light_delta,light_delta);\n"
-"\n"
-" light_delta = normalize( light_delta );\n"
-"\n"
-" float quadratic = dist2*100.0;\n"
-" float attenuation = 1.0/( 1.0 + quadratic );\n"
-" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
-"\n"
-" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
-"\n"
-" if( light_dir.w < 0.999999 ){\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
-" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
-" }\n"
-"\n"
-" return light_colour.rgb * attenuation * falloff \n"
-" * step( g_day_phase, light_colour.w );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" uint light_count = packed_index & 0x3u;\n"
-"\n"
-" vec3 l = vec3(0.0);\n"
-"\n"
-" if( light_count >= 1u ){\n"
-" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
-" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
-" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
-"\n"
-" l += scene_calculate_light( index_0, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 2u ){\n"
-" l += scene_calculate_light( index_1, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 3u ){\n"
-" l += scene_calculate_light( index_2, halfview, co, normal );\n"
-" }\n"
-" }\n"
-" }\n"
-"\n"
-" return l;\n"
-"}\n"
-"\n"
-"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
-" float light_mask )\n"
-"{\n"
-" if( g_light_preview == 1 )\n"
-" diffuse = vec3(0.75);\n"
-"\n"
-" // Lighting\n"
-" vec3 halfview = uCamera - co;\n"
-" float fdist = length(halfview);\n"
-" halfview /= fdist;\n"
-"\n"
-" float world_shadow = newlight_compute_sun_shadow( \n"
-" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
-"\n"
-" vec3 total_light = clearskies_lighting( \n"
-" normal, min( light_mask, world_shadow ), halfview );\n"
-"\n"
-" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
-" cube_coord = floor( cube_coord );\n"
-"\n"
-" if( g_debug_indices == 1 )\n"
-" {\n"
-" return rand33(cube_coord);\n"
-" }\n"
-"\n"
-" if( g_debug_complexity == 1 )\n"
-" {\n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
-" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
-" }\n"
-"\n"
-" // FIXME: this coord should absolutely must be clamped!\n"
-" \n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, co, normal ) \n"
-" * light_mask;\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, co, normal )\n"
-" * light_mask;\n"
-"\n"
-" // Take a section of the sky function to give us a matching fog colour\n"
-"\n"
-" vec3 fog_colour = clearskies_ambient( -halfview );\n"
-" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
-" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" fog_colour += sun_colour;\n"
-" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"\n"
-"float sdLine( vec3 p, vec3 a, vec3 b )\n"
-"{\n"
-" vec3 pa = p - a;\n"
-" vec3 ba = b - a;\n"
-"\n"
-" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
-" return length( pa - ba*h );\n"
-"}\n"
-"\n"
-"float compute_board_shadow()\n"
-"{\n"
-" // player shadow\n"
-" float dist_to_player = max( 0.0, sdLine( aWorldCo, g_board_0.xyz,\n"
-" g_board_1.xyz )-0.1 );\n"
-" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
-" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
-"\n"
-" return 1.0 - player_shadow*0.8;\n"
-"}\n"
-"\n"
-"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
-"{\n"
-" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
-"}\n"
-"\n"
-"#line 6 0 \n"
-"#line 1 3 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"layout (location = 1) out vec2 oMotionVec;\n"
-"\n"
-"in vec3 aMotionVec0;\n"
-"in vec3 aMotionVec1;\n"
-"\n"
-"void compute_motion_vectors()\n"
-"{\n"
-" // Write motion vectors\n"
-" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
-" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
-"\n"
-" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
-"}\n"
-"\n"
-"#line 7 0 \n"
-"\n"
-"void main(){\n"
-" oMotionVec = vec2(0.0);\n"
-"\n"
-" vec4 vsamplemain = texture( uTexMain, aUv );\n"
-"\n"
-" vec2 ssuv = gl_FragCoord.xy;\n"
-" vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), ssuv) );\n"
-" float dither = fract( vDither.g / 71.0 ) - 0.5;\n"
-"\n"
-" if( vsamplemain.a+dither<0.5 )\n"
-" discard;\n"
-"\n"
-" oColour = vec4( vsamplemain.rgb, 1.0 );\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_scene_fxglow_uMdl;
-static GLuint _uniform_scene_fxglow_uPv;
-static GLuint _uniform_scene_fxglow_uPvmPrev;
-static GLuint _uniform_scene_fxglow_uUvOffset;
-static GLuint _uniform_scene_fxglow_uTexMain;
-static GLuint _uniform_scene_fxglow_uCamera;
-static GLuint _uniform_scene_fxglow_g_world_depth;
-static GLuint _uniform_scene_fxglow_uLightsArray;
-static GLuint _uniform_scene_fxglow_uLightsIndex;
-static void shader_scene_fxglow_uMdl(m4x3f m){
- glUniformMatrix4x3fv(_uniform_scene_fxglow_uMdl,1,GL_FALSE,(float*)m);
+ glUniformMatrix4x3fv(_uniform_scene_fxglow_uMdl,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_fxglow_uPv(m4x4f m){
- glUniformMatrix4fv(_uniform_scene_fxglow_uPv,1,GL_FALSE,(float*)m);
+static inline void shader_scene_fxglow_uPv(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_scene_fxglow_uPv,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_fxglow_uPvmPrev(m4x4f m){
- glUniformMatrix4fv(_uniform_scene_fxglow_uPvmPrev,1,GL_FALSE,(float*)m);
+static inline void shader_scene_fxglow_uPvmPrev(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_scene_fxglow_uPvmPrev,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_fxglow_uUvOffset(v2f v){
+static inline void shader_scene_fxglow_uUvOffset(v2f v)
+{
glUniform2fv(_uniform_scene_fxglow_uUvOffset,1,v);
}
-static void shader_scene_fxglow_uTexMain(int i){
+static inline void shader_scene_fxglow_uTexMain(int i)
+{
glUniform1i(_uniform_scene_fxglow_uTexMain,i);
}
-static void shader_scene_fxglow_uCamera(v3f v){
+static inline void shader_scene_fxglow_uCamera(v3f v)
+{
glUniform3fv(_uniform_scene_fxglow_uCamera,1,v);
}
-static void shader_scene_fxglow_g_world_depth(int i){
+static inline void shader_scene_fxglow_g_world_depth(int i)
+{
glUniform1i(_uniform_scene_fxglow_g_world_depth,i);
}
-static void shader_scene_fxglow_register(void){
- vg_shader_register( &_shader_scene_fxglow );
-}
-static void shader_scene_fxglow_use(void){ glUseProgram(_shader_scene_fxglow.id); }
-static void shader_scene_fxglow_link(void){
- _uniform_scene_fxglow_uMdl = glGetUniformLocation( _shader_scene_fxglow.id, "uMdl" );
- _uniform_scene_fxglow_uPv = glGetUniformLocation( _shader_scene_fxglow.id, "uPv" );
- _uniform_scene_fxglow_uPvmPrev = glGetUniformLocation( _shader_scene_fxglow.id, "uPvmPrev" );
- _uniform_scene_fxglow_uUvOffset = glGetUniformLocation( _shader_scene_fxglow.id, "uUvOffset" );
- _uniform_scene_fxglow_uTexMain = glGetUniformLocation( _shader_scene_fxglow.id, "uTexMain" );
- _uniform_scene_fxglow_uCamera = glGetUniformLocation( _shader_scene_fxglow.id, "uCamera" );
- _uniform_scene_fxglow_g_world_depth = glGetUniformLocation( _shader_scene_fxglow.id, "g_world_depth" );
- _uniform_scene_fxglow_uLightsArray = glGetUniformLocation( _shader_scene_fxglow.id, "uLightsArray" );
- _uniform_scene_fxglow_uLightsIndex = glGetUniformLocation( _shader_scene_fxglow.id, "uLightsIndex" );
+static inline void shader_scene_fxglow_use(void);
+static inline void shader_scene_fxglow_use(void)
+{
+ glUseProgram(_shader_scene_fxglow.id);
}
-#endif /* SHADER_scene_fxglow_H */
-#ifndef SHADER_scene_override_H
-#define SHADER_scene_override_H
-static void shader_scene_override_link(void);
-static void shader_scene_override_register(void);
-static struct vg_shader _shader_scene_override = {
- .name = "scene_override",
- .link = shader_scene_override_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_scene_override;
+extern GLuint _uniform_scene_override_uMdl;
+extern GLuint _uniform_scene_override_uPv;
+extern GLuint _uniform_scene_override_uPvmPrev;
+extern GLuint _uniform_scene_override_uNormalMtx;
+extern GLuint _uniform_scene_override_uTexGarbage;
+extern GLuint _uniform_scene_override_uTexMain;
+extern GLuint _uniform_scene_override_uCamera;
+extern GLuint _uniform_scene_override_uPlane;
+extern GLuint _uniform_scene_override_uPlayerPos;
+extern GLuint _uniform_scene_override_uSpawnPos;
+extern GLuint _uniform_scene_override_uAlphatest;
+extern GLuint _uniform_scene_override_uMapInfo;
+extern GLuint _uniform_scene_override_g_world_depth;
+extern GLuint _uniform_scene_override_uLightsArray;
+extern GLuint _uniform_scene_override_uLightsIndex;
+static inline void shader_scene_override_uMdl(m4x3f m)
{
-.orig_file = "shaders/scene_override.vs",
-.static_src =
-"layout (location=0) in vec3 a_co;\n"
-"layout (location=1) in vec4 a_norm;\n"
-"layout (location=2) in vec2 a_uv;\n"
-"\n"
-"#line 1 1 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"out vec3 aMotionVec0;\n"
-"out vec3 aMotionVec1;\n"
-"\n"
-"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
-"{\n"
-" // This magically solves some artifacting errors!\n"
-" //\n"
-" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
-"\n"
-" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
-" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
-"}\n"
-"\n"
-"#line 6 0 \n"
-"\n"
-"uniform mat4x3 uMdl;\n"
-"uniform mat4 uPv;\n"
-"uniform mat4 uPvmPrev;\n"
-"uniform mat3 uNormalMtx;\n"
-"\n"
-"out vec2 aUv;\n"
-"out vec4 aNorm;\n"
-"out vec3 aCo;\n"
-"out vec3 aWorldCo;\n"
-"\n"
-"void main()\n"
-"{\n"
-" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
-" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
-" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
-"\n"
-" vs_motion_out( vproj0, vproj1 );\n"
-"\n"
-" gl_Position = vproj0;\n"
-"\n"
-" aUv = a_uv;\n"
-" aNorm = vec4( uNormalMtx * a_norm.xyz, a_norm.w );\n"
-" aCo = a_co;\n"
-" aWorldCo = world_pos0;\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/scene_override.fs",
-.static_src =
-"uniform sampler2D uTexGarbage;\n"
-"uniform sampler2D uTexMain;\n"
-"uniform vec3 uCamera;\n"
-"uniform vec4 uPlane;\n"
-"\n"
-"uniform vec4 uPlayerPos; /* w: distance to uSpawnPos */\n"
-"uniform vec4 uSpawnPos; /* w: inverse distance to uPlayerPos */\n"
-"uniform bool uAlphatest;\n"
-"uniform vec4 uMapInfo; /* x: min, y: max, z: iso line amount */\n"
-"\n"
-"#line 1 1 \n"
-"// :D\n"
-"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
-"\n"
-"#line 12 0 \n"
-"#line 1 2 \n"
-"// :D\n"
-"\n"
-"in vec2 aUv;\n"
-"in vec4 aNorm;\n"
-"in vec3 aCo;\n"
-"in vec3 aWorldCo;\n"
-"\n"
-"#line 1 1 \n"
-"layout (location = 0) out vec4 oColour;\n"
-"\n"
-"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
-"layout (std140) uniform ub_world_lighting\n"
-"{\n"
-" vec4 g_cube_min;\n"
-" vec4 g_cube_inv_range;\n"
-"\n"
-" vec4 g_water_plane;\n"
-" vec4 g_depth_bounds;\n"
-"\n"
-" vec4 g_daysky_colour;\n"
-" vec4 g_nightsky_colour;\n"
-" vec4 g_sunset_colour;\n"
-" vec4 g_ambient_colour;\n"
-" vec4 g_sunset_ambient;\n"
-" vec4 g_sun_colour;\n"
-" vec4 g_sun_dir;\n"
-" vec4 g_board_0;\n"
-" vec4 g_board_1;\n"
-"\n"
-" float g_water_fog;\n"
-" float g_time;\n"
-" float g_realtime;\n"
-" float g_shadow_length;\n"
-" float g_shadow_spread;\n"
-"\n"
-" float g_time_of_day;\n"
-" float g_day_phase;\n"
-" float g_sunset_phase;\n"
-"\n"
-" int g_light_preview;\n"
-" int g_shadow_samples;\n"
-"\n"
-" int g_debug_indices;\n"
-" int g_debug_complexity;\n"
-"};\n"
-"\n"
-"uniform sampler2D g_world_depth;\n"
-"uniform samplerBuffer uLightsArray;\n"
-"uniform usampler3D uLightsIndex;\n"
-"\n"
-"#line 1 1 \n"
-"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
-"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
-"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
-"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
-"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
-"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
-"\n"
-"const float SUN_ANGLE = 0.0001;\n"
-"const float PI = 3.14159265358979323846264;\n"
-"\n"
-"//struct world_info\n"
-"//{\n"
-"// float time,\n"
-"// time_of_day,\n"
-"// day_phase,\n"
-"// sunset_phase;\n"
-"// \n"
-"// vec3 sun_dir;\n"
-"//};\n"
-"\n"
-"vec3 rand33(vec3 p3)\n"
-"{\n"
-" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
-" p3 += dot(p3, p3.yxz+33.33);\n"
-" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
-"}\n"
-"\n"
-"float stars( vec3 rd, float rr, float size ){\n"
-" vec3 co = rd * rr;\n"
-"\n"
-" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
-"\n"
-" float spaces = 1.0 / rr;\n"
-" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
-" a -= mod(a, spaces) - spaces * 0.5;\n"
-"\n"
-" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
-" \n"
-" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
-" plane = plane - mod(plane, PI / count);\n"
-"\n"
-" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
-"\n"
-" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
-" float ydist = sqrt(rr * rr - level * level);\n"
-" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
-" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
-" float star = smoothstep(size, 0.0, distance(center, co));\n"
-" return star;\n"
-"}\n"
-"\n"
-"float luminance( vec3 v )\n"
-"{\n"
-" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
-"}\n"
-"\n"
-"vec3 clearskies_ambient( vec3 dir )\n"
-"{\n"
-" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
-" float sky_gradient = dir.y;\n"
-" \n"
-" /* Blend phase colours */\n"
-" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
-" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
-" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
-" \n"
-" /* Add gradient */\n"
-" ambient -= sky_gradient * luminance(ambient);\n"
-" \n"
-" return ambient;\n"
-"}\n"
-"\n"
-"vec3 clearskies_sky( vec3 ray_dir )\n"
-"{\n"
-" ray_dir.y = abs( ray_dir.y );\n"
-" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
-" \n"
-" /* Sun */\n"
-" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
-" float sun_shape = pow( sun_size, 2000.0 );\n"
-" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" \n"
-" float star = 0.0;\n"
-" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
-"\n"
-" if( star_blend > 0.001 ){\n"
-" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
-" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
-" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
-" }\n"
-" }\n"
-" \n"
-" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
-" return composite;\n"
-"}\n"
-"\n"
-"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
-"{\n"
-" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
-"\n"
-" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
-" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
-" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
-" ) * g_sun_colour.rgb * g_day_phase;\n"
-"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
-" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" return ambient + (light_sun + sky_reflection) * shadow;\n"
-"}\n"
-"\n"
-"#line 44 0 \n"
-"\n"
-"float world_depth_sample( vec3 pos )\n"
-"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
-" return texture( g_world_depth, depth_coord ).r;\n"
-"}\n"
-"\n"
-"float world_water_depth( vec3 pos )\n"
-"{\n"
-" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return world_depth_sample( pos ) - ref_depth;\n"
-"}\n"
-"\n"
-"float shadow_sample( vec3 co ){\n"
-" float height_sample = world_depth_sample( co );\n"
-"\n"
-" float fdelta = height_sample - co.y;\n"
-" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
-"}\n"
-"\n"
-"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
-" if( g_shadow_samples == 0 ){\n"
-" return 1.0;\n"
-" }\n"
-"\n"
-" float fspread = g_shadow_spread;\n"
-" float flength = g_shadow_length;\n"
-"\n"
-" float famt = 0.0;\n"
-" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
-"\n"
-" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
-"\n"
-" return 1.0 - famt;\n"
-"}\n"
-"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
-"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
-"}\n"
-"\n"
-"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
-" float dist = pow(fdist*0.0010,0.78);\n"
-" return mix( vfrag, colour, min( 1.0, dist ) );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_light( int light_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
-" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
-" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
-"\n"
-" vec3 light_delta = light_co.xyz-co;\n"
-" float dist2 = dot(light_delta,light_delta);\n"
-"\n"
-" light_delta = normalize( light_delta );\n"
-"\n"
-" float quadratic = dist2*100.0;\n"
-" float attenuation = 1.0/( 1.0 + quadratic );\n"
-" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
-"\n"
-" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
-"\n"
-" if( light_dir.w < 0.999999 ){\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
-" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
-" }\n"
-"\n"
-" return light_colour.rgb * attenuation * falloff \n"
-" * step( g_day_phase, light_colour.w );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" uint light_count = packed_index & 0x3u;\n"
-"\n"
-" vec3 l = vec3(0.0);\n"
-"\n"
-" if( light_count >= 1u ){\n"
-" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
-" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
-" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
-"\n"
-" l += scene_calculate_light( index_0, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 2u ){\n"
-" l += scene_calculate_light( index_1, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 3u ){\n"
-" l += scene_calculate_light( index_2, halfview, co, normal );\n"
-" }\n"
-" }\n"
-" }\n"
-"\n"
-" return l;\n"
-"}\n"
-"\n"
-"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
-" float light_mask )\n"
-"{\n"
-" if( g_light_preview == 1 )\n"
-" diffuse = vec3(0.75);\n"
-"\n"
-" // Lighting\n"
-" vec3 halfview = uCamera - co;\n"
-" float fdist = length(halfview);\n"
-" halfview /= fdist;\n"
-"\n"
-" float world_shadow = newlight_compute_sun_shadow( \n"
-" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
-"\n"
-" vec3 total_light = clearskies_lighting( \n"
-" normal, min( light_mask, world_shadow ), halfview );\n"
-"\n"
-" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
-" cube_coord = floor( cube_coord );\n"
-"\n"
-" if( g_debug_indices == 1 )\n"
-" {\n"
-" return rand33(cube_coord);\n"
-" }\n"
-"\n"
-" if( g_debug_complexity == 1 )\n"
-" {\n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
-" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
-" }\n"
-"\n"
-" // FIXME: this coord should absolutely must be clamped!\n"
-" \n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, co, normal ) \n"
-" * light_mask;\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, co, normal )\n"
-" * light_mask;\n"
-"\n"
-" // Take a section of the sky function to give us a matching fog colour\n"
-"\n"
-" vec3 fog_colour = clearskies_ambient( -halfview );\n"
-" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
-" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" fog_colour += sun_colour;\n"
-" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"\n"
-"float sdLine( vec3 p, vec3 a, vec3 b )\n"
-"{\n"
-" vec3 pa = p - a;\n"
-" vec3 ba = b - a;\n"
-"\n"
-" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
-" return length( pa - ba*h );\n"
-"}\n"
-"\n"
-"float compute_board_shadow()\n"
-"{\n"
-" // player shadow\n"
-" float dist_to_player = max( 0.0, sdLine( aWorldCo, g_board_0.xyz,\n"
-" g_board_1.xyz )-0.1 );\n"
-" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
-" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
-"\n"
-" return 1.0 - player_shadow*0.8;\n"
-"}\n"
-"\n"
-"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
-"{\n"
-" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
-"}\n"
-"\n"
-"#line 13 0 \n"
-"#line 1 3 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"layout (location = 1) out vec2 oMotionVec;\n"
-"\n"
-"in vec3 aMotionVec0;\n"
-"in vec3 aMotionVec1;\n"
-"\n"
-"void compute_motion_vectors()\n"
-"{\n"
-" // Write motion vectors\n"
-" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
-" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
-"\n"
-" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
-"}\n"
-"\n"
-"#line 14 0 \n"
-"\n"
-"vec2 smin( float a, float b, float k ){\n"
-" float h = max( k-abs(a-b), 0.0 )/k;\n"
-" float m = h*h*0.5;\n"
-" float s = m*k*(1.0/2.0);\n"
-"\n"
-" if( a < b )\n"
-" return vec2(a-s,m);\n"
-" else\n"
-" return vec2(b-s,1.0-m);\n"
-"}\n"
-"\n"
-"void main(){\n"
-" vec2 ssuv = gl_FragCoord.xy;\n"
-" vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), ssuv) );\n"
-" float dither = fract( vDither.g / 71.0 ) - 0.5;\n"
-"\n"
-" float dcam = (-8.0+distance( aCo, uCamera ))/4.0;\n"
-" float dy0 = aCo.y - uMapInfo.x;\n"
-" float dy1 = uMapInfo.y - aCo.y;\n"
-"\n"
-" if( min(min(dy0,dy1)*0.5, dcam) + dither < 0.51 ) \n"
-" discard;\n"
-"\n"
-" compute_motion_vectors();\n"
-"\n"
-" vec3 vfrag = vec3(0.898,0.811,0.716);\n"
-" vec3 qnorm = aNorm.xyz;\n"
-"\n"
-" qnorm = normalize(floor(aNorm.xyz*4.0)*0.25);\n"
-" qnorm += vec3(0.001,0.0,0.0);\n"
-"\n"
-" if( uAlphatest ){\n"
-" vec4 vSample = texture( uTexMain, aUv );\n"
-" if( vSample.a < 0.5 )\n"
-" discard;\n"
-" }\n"
-" else{\n"
-" }\n"
-"\n"
-" vfrag = scene_compute_lighting( vfrag, qnorm, aWorldCo );\n"
-" \n"
-" // dots\n"
-" float d0 = distance( aCo, uPlayerPos.xyz )*2.0;\n"
-" float d1 = distance( aCo, uSpawnPos.xyz );\n"
-"\n"
-" vec2 dm = smin( d0, d1, 10.0 );\n"
-" float dd = fract(dm.x*0.2-g_realtime*0.5) * \n"
-" max(0.0,1.0-dm.x*0.04) * \n"
-" max(0.0,qnorm.y);\n"
-" vec3 emit = mix(vec3(1.0,0.0,0.0),vec3(0.0,1.0,0.0),dm.y)*dd;\n"
-"\n"
-" // line\n"
-" vec3 v0 = (uSpawnPos.xyz-uPlayerPos.xyz)*uSpawnPos.w;\n"
-" float t = clamp( dot(aCo-uPlayerPos.xyz,v0), 0.0, uPlayerPos.w );\n"
-" vec3 p0 = uPlayerPos.xyz + v0*t;\n"
-" float d3 = distance(p0,aCo);\n"
-" emit += vec3(fract(t*0.2-g_realtime+d3*0.2)*max(0.0,1.0-d3*0.2));\n"
-"\n"
-" vfrag += emit;\n"
-"\n"
-" if( uMapInfo.z > 0.0 ){\n"
-" float height = fract( aCo.y * 0.1 );\n"
-" float lg = 2.0*length(vec2(dFdx(height), dFdy(height)));\n"
-" vfrag *= 1.0f+(lg*0.2*uMapInfo.z);\n"
-" }\n"
-"\n"
-" oColour = vec4( vfrag, 1.0 );\n"
-" //oColour = vec4( vfrag, 1.0 );\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_scene_override_uMdl;
-static GLuint _uniform_scene_override_uPv;
-static GLuint _uniform_scene_override_uPvmPrev;
-static GLuint _uniform_scene_override_uNormalMtx;
-static GLuint _uniform_scene_override_uTexGarbage;
-static GLuint _uniform_scene_override_uTexMain;
-static GLuint _uniform_scene_override_uCamera;
-static GLuint _uniform_scene_override_uPlane;
-static GLuint _uniform_scene_override_uPlayerPos;
-static GLuint _uniform_scene_override_uSpawnPos;
-static GLuint _uniform_scene_override_uAlphatest;
-static GLuint _uniform_scene_override_uMapInfo;
-static GLuint _uniform_scene_override_g_world_depth;
-static GLuint _uniform_scene_override_uLightsArray;
-static GLuint _uniform_scene_override_uLightsIndex;
-static void shader_scene_override_uMdl(m4x3f m){
- glUniformMatrix4x3fv(_uniform_scene_override_uMdl,1,GL_FALSE,(float*)m);
+ glUniformMatrix4x3fv(_uniform_scene_override_uMdl,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_override_uPv(m4x4f m){
- glUniformMatrix4fv(_uniform_scene_override_uPv,1,GL_FALSE,(float*)m);
+static inline void shader_scene_override_uPv(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_scene_override_uPv,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_override_uPvmPrev(m4x4f m){
- glUniformMatrix4fv(_uniform_scene_override_uPvmPrev,1,GL_FALSE,(float*)m);
+static inline void shader_scene_override_uPvmPrev(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_scene_override_uPvmPrev,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_override_uNormalMtx(m3x3f m){
- glUniformMatrix3fv(_uniform_scene_override_uNormalMtx,1,GL_FALSE,(float*)m);
+static inline void shader_scene_override_uNormalMtx(m3x3f m)
+{
+ glUniformMatrix3fv(_uniform_scene_override_uNormalMtx,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_override_uTexGarbage(int i){
+static inline void shader_scene_override_uTexGarbage(int i)
+{
glUniform1i(_uniform_scene_override_uTexGarbage,i);
}
-static void shader_scene_override_uTexMain(int i){
+static inline void shader_scene_override_uTexMain(int i)
+{
glUniform1i(_uniform_scene_override_uTexMain,i);
}
-static void shader_scene_override_uCamera(v3f v){
+static inline void shader_scene_override_uCamera(v3f v)
+{
glUniform3fv(_uniform_scene_override_uCamera,1,v);
}
-static void shader_scene_override_uPlane(v4f v){
+static inline void shader_scene_override_uPlane(v4f v)
+{
glUniform4fv(_uniform_scene_override_uPlane,1,v);
}
-static void shader_scene_override_uPlayerPos(v4f v){
+static inline void shader_scene_override_uPlayerPos(v4f v)
+{
glUniform4fv(_uniform_scene_override_uPlayerPos,1,v);
}
-static void shader_scene_override_uSpawnPos(v4f v){
+static inline void shader_scene_override_uSpawnPos(v4f v)
+{
glUniform4fv(_uniform_scene_override_uSpawnPos,1,v);
}
-static void shader_scene_override_uAlphatest(int b){
+static inline void shader_scene_override_uAlphatest(int b)
+{
glUniform1i(_uniform_scene_override_uAlphatest,b);
}
-static void shader_scene_override_uMapInfo(v4f v){
+static inline void shader_scene_override_uMapInfo(v4f v)
+{
glUniform4fv(_uniform_scene_override_uMapInfo,1,v);
}
-static void shader_scene_override_g_world_depth(int i){
+static inline void shader_scene_override_g_world_depth(int i)
+{
glUniform1i(_uniform_scene_override_g_world_depth,i);
}
-static void shader_scene_override_register(void){
- vg_shader_register( &_shader_scene_override );
-}
-static void shader_scene_override_use(void){ glUseProgram(_shader_scene_override.id); }
-static void shader_scene_override_link(void){
- _uniform_scene_override_uMdl = glGetUniformLocation( _shader_scene_override.id, "uMdl" );
- _uniform_scene_override_uPv = glGetUniformLocation( _shader_scene_override.id, "uPv" );
- _uniform_scene_override_uPvmPrev = glGetUniformLocation( _shader_scene_override.id, "uPvmPrev" );
- _uniform_scene_override_uNormalMtx = glGetUniformLocation( _shader_scene_override.id, "uNormalMtx" );
- _uniform_scene_override_uTexGarbage = glGetUniformLocation( _shader_scene_override.id, "uTexGarbage" );
- _uniform_scene_override_uTexMain = glGetUniformLocation( _shader_scene_override.id, "uTexMain" );
- _uniform_scene_override_uCamera = glGetUniformLocation( _shader_scene_override.id, "uCamera" );
- _uniform_scene_override_uPlane = glGetUniformLocation( _shader_scene_override.id, "uPlane" );
- _uniform_scene_override_uPlayerPos = glGetUniformLocation( _shader_scene_override.id, "uPlayerPos" );
- _uniform_scene_override_uSpawnPos = glGetUniformLocation( _shader_scene_override.id, "uSpawnPos" );
- _uniform_scene_override_uAlphatest = glGetUniformLocation( _shader_scene_override.id, "uAlphatest" );
- _uniform_scene_override_uMapInfo = glGetUniformLocation( _shader_scene_override.id, "uMapInfo" );
- _uniform_scene_override_g_world_depth = glGetUniformLocation( _shader_scene_override.id, "g_world_depth" );
- _uniform_scene_override_uLightsArray = glGetUniformLocation( _shader_scene_override.id, "uLightsArray" );
- _uniform_scene_override_uLightsIndex = glGetUniformLocation( _shader_scene_override.id, "uLightsIndex" );
+static inline void shader_scene_override_use(void);
+static inline void shader_scene_override_use(void)
+{
+ glUseProgram(_shader_scene_override.id);
}
-#endif /* SHADER_scene_override_H */
-#ifndef SHADER_scene_position_H
-#define SHADER_scene_position_H
-static void shader_scene_position_link(void);
-static void shader_scene_position_register(void);
-static struct vg_shader _shader_scene_position = {
- .name = "scene_position",
- .link = shader_scene_position_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_scene_position;
+extern GLuint _uniform_scene_position_uMdl;
+extern GLuint _uniform_scene_position_uPv;
+extern GLuint _uniform_scene_position_uPvmPrev;
+extern GLuint _uniform_scene_position_uCamera;
+extern GLuint _uniform_scene_position_uBoard0;
+extern GLuint _uniform_scene_position_uBoard1;
+extern GLuint _uniform_scene_position_g_world_depth;
+extern GLuint _uniform_scene_position_uLightsArray;
+extern GLuint _uniform_scene_position_uLightsIndex;
+static inline void shader_scene_position_uMdl(m4x3f m)
{
-.orig_file = "shaders/scene.vs",
-.static_src =
-"layout (location=0) in vec3 a_co;\n"
-"layout (location=1) in vec4 a_norm;\n"
-"layout (location=2) in vec2 a_uv;\n"
-"\n"
-"#line 1 1 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"out vec3 aMotionVec0;\n"
-"out vec3 aMotionVec1;\n"
-"\n"
-"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
-"{\n"
-" // This magically solves some artifacting errors!\n"
-" //\n"
-" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
-"\n"
-" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
-" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
-"}\n"
-"\n"
-"#line 6 0 \n"
-"\n"
-"uniform mat4x3 uMdl;\n"
-"uniform mat4 uPv;\n"
-"uniform mat4 uPvmPrev;\n"
-"\n"
-"out vec2 aUv;\n"
-"out vec4 aNorm;\n"
-"out vec3 aCo;\n"
-"out vec3 aWorldCo;\n"
-"\n"
-"void main()\n"
-"{\n"
-" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
-" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
-" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
-"\n"
-" vs_motion_out( vproj0, vproj1 );\n"
-"\n"
-" gl_Position = vproj0;\n"
-"\n"
-" aUv = a_uv;\n"
-" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
-" aCo = a_co;\n"
-" aWorldCo = world_pos0;\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/scene_position.fs",
-.static_src =
-"out vec4 FragColor;\n"
-"\n"
-"uniform vec3 uCamera;\n"
-"uniform vec3 uBoard0;\n"
-"uniform vec3 uBoard1;\n"
-"\n"
-"#line 1 1 \n"
-"// :D\n"
-"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
-"\n"
-"#line 8 0 \n"
-"#line 1 2 \n"
-"// :D\n"
-"\n"
-"in vec2 aUv;\n"
-"in vec4 aNorm;\n"
-"in vec3 aCo;\n"
-"in vec3 aWorldCo;\n"
-"\n"
-"#line 1 1 \n"
-"layout (location = 0) out vec4 oColour;\n"
-"\n"
-"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
-"layout (std140) uniform ub_world_lighting\n"
-"{\n"
-" vec4 g_cube_min;\n"
-" vec4 g_cube_inv_range;\n"
-"\n"
-" vec4 g_water_plane;\n"
-" vec4 g_depth_bounds;\n"
-"\n"
-" vec4 g_daysky_colour;\n"
-" vec4 g_nightsky_colour;\n"
-" vec4 g_sunset_colour;\n"
-" vec4 g_ambient_colour;\n"
-" vec4 g_sunset_ambient;\n"
-" vec4 g_sun_colour;\n"
-" vec4 g_sun_dir;\n"
-" vec4 g_board_0;\n"
-" vec4 g_board_1;\n"
-"\n"
-" float g_water_fog;\n"
-" float g_time;\n"
-" float g_realtime;\n"
-" float g_shadow_length;\n"
-" float g_shadow_spread;\n"
-"\n"
-" float g_time_of_day;\n"
-" float g_day_phase;\n"
-" float g_sunset_phase;\n"
-"\n"
-" int g_light_preview;\n"
-" int g_shadow_samples;\n"
-"\n"
-" int g_debug_indices;\n"
-" int g_debug_complexity;\n"
-"};\n"
-"\n"
-"uniform sampler2D g_world_depth;\n"
-"uniform samplerBuffer uLightsArray;\n"
-"uniform usampler3D uLightsIndex;\n"
-"\n"
-"#line 1 1 \n"
-"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
-"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
-"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
-"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
-"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
-"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
-"\n"
-"const float SUN_ANGLE = 0.0001;\n"
-"const float PI = 3.14159265358979323846264;\n"
-"\n"
-"//struct world_info\n"
-"//{\n"
-"// float time,\n"
-"// time_of_day,\n"
-"// day_phase,\n"
-"// sunset_phase;\n"
-"// \n"
-"// vec3 sun_dir;\n"
-"//};\n"
-"\n"
-"vec3 rand33(vec3 p3)\n"
-"{\n"
-" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
-" p3 += dot(p3, p3.yxz+33.33);\n"
-" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
-"}\n"
-"\n"
-"float stars( vec3 rd, float rr, float size ){\n"
-" vec3 co = rd * rr;\n"
-"\n"
-" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
-"\n"
-" float spaces = 1.0 / rr;\n"
-" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
-" a -= mod(a, spaces) - spaces * 0.5;\n"
-"\n"
-" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
-" \n"
-" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
-" plane = plane - mod(plane, PI / count);\n"
-"\n"
-" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
-"\n"
-" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
-" float ydist = sqrt(rr * rr - level * level);\n"
-" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
-" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
-" float star = smoothstep(size, 0.0, distance(center, co));\n"
-" return star;\n"
-"}\n"
-"\n"
-"float luminance( vec3 v )\n"
-"{\n"
-" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
-"}\n"
-"\n"
-"vec3 clearskies_ambient( vec3 dir )\n"
-"{\n"
-" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
-" float sky_gradient = dir.y;\n"
-" \n"
-" /* Blend phase colours */\n"
-" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
-" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
-" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
-" \n"
-" /* Add gradient */\n"
-" ambient -= sky_gradient * luminance(ambient);\n"
-" \n"
-" return ambient;\n"
-"}\n"
-"\n"
-"vec3 clearskies_sky( vec3 ray_dir )\n"
-"{\n"
-" ray_dir.y = abs( ray_dir.y );\n"
-" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
-" \n"
-" /* Sun */\n"
-" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
-" float sun_shape = pow( sun_size, 2000.0 );\n"
-" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" \n"
-" float star = 0.0;\n"
-" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
-"\n"
-" if( star_blend > 0.001 ){\n"
-" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
-" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
-" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
-" }\n"
-" }\n"
-" \n"
-" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
-" return composite;\n"
-"}\n"
-"\n"
-"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
-"{\n"
-" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
-"\n"
-" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
-" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
-" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
-" ) * g_sun_colour.rgb * g_day_phase;\n"
-"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
-" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" return ambient + (light_sun + sky_reflection) * shadow;\n"
-"}\n"
-"\n"
-"#line 44 0 \n"
-"\n"
-"float world_depth_sample( vec3 pos )\n"
-"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
-" return texture( g_world_depth, depth_coord ).r;\n"
-"}\n"
-"\n"
-"float world_water_depth( vec3 pos )\n"
-"{\n"
-" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return world_depth_sample( pos ) - ref_depth;\n"
-"}\n"
-"\n"
-"float shadow_sample( vec3 co ){\n"
-" float height_sample = world_depth_sample( co );\n"
-"\n"
-" float fdelta = height_sample - co.y;\n"
-" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
-"}\n"
-"\n"
-"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
-" if( g_shadow_samples == 0 ){\n"
-" return 1.0;\n"
-" }\n"
-"\n"
-" float fspread = g_shadow_spread;\n"
-" float flength = g_shadow_length;\n"
-"\n"
-" float famt = 0.0;\n"
-" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
-"\n"
-" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
-"\n"
-" return 1.0 - famt;\n"
-"}\n"
-"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
-"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
-"}\n"
-"\n"
-"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
-" float dist = pow(fdist*0.0010,0.78);\n"
-" return mix( vfrag, colour, min( 1.0, dist ) );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_light( int light_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
-" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
-" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
-"\n"
-" vec3 light_delta = light_co.xyz-co;\n"
-" float dist2 = dot(light_delta,light_delta);\n"
-"\n"
-" light_delta = normalize( light_delta );\n"
-"\n"
-" float quadratic = dist2*100.0;\n"
-" float attenuation = 1.0/( 1.0 + quadratic );\n"
-" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
-"\n"
-" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
-"\n"
-" if( light_dir.w < 0.999999 ){\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
-" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
-" }\n"
-"\n"
-" return light_colour.rgb * attenuation * falloff \n"
-" * step( g_day_phase, light_colour.w );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" uint light_count = packed_index & 0x3u;\n"
-"\n"
-" vec3 l = vec3(0.0);\n"
-"\n"
-" if( light_count >= 1u ){\n"
-" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
-" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
-" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
-"\n"
-" l += scene_calculate_light( index_0, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 2u ){\n"
-" l += scene_calculate_light( index_1, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 3u ){\n"
-" l += scene_calculate_light( index_2, halfview, co, normal );\n"
-" }\n"
-" }\n"
-" }\n"
-"\n"
-" return l;\n"
-"}\n"
-"\n"
-"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
-" float light_mask )\n"
-"{\n"
-" if( g_light_preview == 1 )\n"
-" diffuse = vec3(0.75);\n"
-"\n"
-" // Lighting\n"
-" vec3 halfview = uCamera - co;\n"
-" float fdist = length(halfview);\n"
-" halfview /= fdist;\n"
-"\n"
-" float world_shadow = newlight_compute_sun_shadow( \n"
-" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
-"\n"
-" vec3 total_light = clearskies_lighting( \n"
-" normal, min( light_mask, world_shadow ), halfview );\n"
-"\n"
-" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
-" cube_coord = floor( cube_coord );\n"
-"\n"
-" if( g_debug_indices == 1 )\n"
-" {\n"
-" return rand33(cube_coord);\n"
-" }\n"
-"\n"
-" if( g_debug_complexity == 1 )\n"
-" {\n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
-" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
-" }\n"
-"\n"
-" // FIXME: this coord should absolutely must be clamped!\n"
-" \n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, co, normal ) \n"
-" * light_mask;\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, co, normal )\n"
-" * light_mask;\n"
-"\n"
-" // Take a section of the sky function to give us a matching fog colour\n"
-"\n"
-" vec3 fog_colour = clearskies_ambient( -halfview );\n"
-" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
-" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" fog_colour += sun_colour;\n"
-" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"\n"
-"float sdLine( vec3 p, vec3 a, vec3 b )\n"
-"{\n"
-" vec3 pa = p - a;\n"
-" vec3 ba = b - a;\n"
-"\n"
-" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
-" return length( pa - ba*h );\n"
-"}\n"
-"\n"
-"float compute_board_shadow()\n"
-"{\n"
-" // player shadow\n"
-" float dist_to_player = max( 0.0, sdLine( aWorldCo, g_board_0.xyz,\n"
-" g_board_1.xyz )-0.1 );\n"
-" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
-" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
-"\n"
-" return 1.0 - player_shadow*0.8;\n"
-"}\n"
-"\n"
-"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
-"{\n"
-" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"\n"
-"void main()\n"
-"{\n"
-" float height_full = aWorldCo.y;\n"
-" float height_water = height_full;\n"
-"\n"
-" if( height_water > (g_water_plane.y * g_water_plane.w) + 2.0 )\n"
-" height_water = -99999.9;\n"
-"\n"
-" FragColor = vec4( height_full, height_water, 0.0, 0.0 );\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_scene_position_uMdl;
-static GLuint _uniform_scene_position_uPv;
-static GLuint _uniform_scene_position_uPvmPrev;
-static GLuint _uniform_scene_position_uCamera;
-static GLuint _uniform_scene_position_uBoard0;
-static GLuint _uniform_scene_position_uBoard1;
-static GLuint _uniform_scene_position_g_world_depth;
-static GLuint _uniform_scene_position_uLightsArray;
-static GLuint _uniform_scene_position_uLightsIndex;
-static void shader_scene_position_uMdl(m4x3f m){
- glUniformMatrix4x3fv(_uniform_scene_position_uMdl,1,GL_FALSE,(float*)m);
+ glUniformMatrix4x3fv(_uniform_scene_position_uMdl,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_position_uPv(m4x4f m){
- glUniformMatrix4fv(_uniform_scene_position_uPv,1,GL_FALSE,(float*)m);
+static inline void shader_scene_position_uPv(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_scene_position_uPv,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_position_uPvmPrev(m4x4f m){
- glUniformMatrix4fv(_uniform_scene_position_uPvmPrev,1,GL_FALSE,(float*)m);
+static inline void shader_scene_position_uPvmPrev(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_scene_position_uPvmPrev,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_position_uCamera(v3f v){
+static inline void shader_scene_position_uCamera(v3f v)
+{
glUniform3fv(_uniform_scene_position_uCamera,1,v);
}
-static void shader_scene_position_uBoard0(v3f v){
+static inline void shader_scene_position_uBoard0(v3f v)
+{
glUniform3fv(_uniform_scene_position_uBoard0,1,v);
}
-static void shader_scene_position_uBoard1(v3f v){
+static inline void shader_scene_position_uBoard1(v3f v)
+{
glUniform3fv(_uniform_scene_position_uBoard1,1,v);
}
-static void shader_scene_position_g_world_depth(int i){
+static inline void shader_scene_position_g_world_depth(int i)
+{
glUniform1i(_uniform_scene_position_g_world_depth,i);
}
-static void shader_scene_position_register(void){
- vg_shader_register( &_shader_scene_position );
-}
-static void shader_scene_position_use(void){ glUseProgram(_shader_scene_position.id); }
-static void shader_scene_position_link(void){
- _uniform_scene_position_uMdl = glGetUniformLocation( _shader_scene_position.id, "uMdl" );
- _uniform_scene_position_uPv = glGetUniformLocation( _shader_scene_position.id, "uPv" );
- _uniform_scene_position_uPvmPrev = glGetUniformLocation( _shader_scene_position.id, "uPvmPrev" );
- _uniform_scene_position_uCamera = glGetUniformLocation( _shader_scene_position.id, "uCamera" );
- _uniform_scene_position_uBoard0 = glGetUniformLocation( _shader_scene_position.id, "uBoard0" );
- _uniform_scene_position_uBoard1 = glGetUniformLocation( _shader_scene_position.id, "uBoard1" );
- _uniform_scene_position_g_world_depth = glGetUniformLocation( _shader_scene_position.id, "g_world_depth" );
- _uniform_scene_position_uLightsArray = glGetUniformLocation( _shader_scene_position.id, "uLightsArray" );
- _uniform_scene_position_uLightsIndex = glGetUniformLocation( _shader_scene_position.id, "uLightsIndex" );
+static inline void shader_scene_position_use(void);
+static inline void shader_scene_position_use(void)
+{
+ glUseProgram(_shader_scene_position.id);
}
-#endif /* SHADER_scene_position_H */
-#ifndef SHADER_scene_route_H
-#define SHADER_scene_route_H
-static void shader_scene_route_link(void);
-static void shader_scene_route_register(void);
-static struct vg_shader _shader_scene_route = {
- .name = "scene_route",
- .link = shader_scene_route_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_scene_route;
+extern GLuint _uniform_scene_route_uMdl;
+extern GLuint _uniform_scene_route_uPv;
+extern GLuint _uniform_scene_route_uPvmPrev;
+extern GLuint _uniform_scene_route_uNormalMtx;
+extern GLuint _uniform_scene_route_uTexGarbage;
+extern GLuint _uniform_scene_route_uTexGradients;
+extern GLuint _uniform_scene_route_uCamera;
+extern GLuint _uniform_scene_route_uColour;
+extern GLuint _uniform_scene_route_g_world_depth;
+extern GLuint _uniform_scene_route_uLightsArray;
+extern GLuint _uniform_scene_route_uLightsIndex;
+static inline void shader_scene_route_uMdl(m4x3f m)
{
-.orig_file = "shaders/scene_override.vs",
-.static_src =
-"layout (location=0) in vec3 a_co;\n"
-"layout (location=1) in vec4 a_norm;\n"
-"layout (location=2) in vec2 a_uv;\n"
-"\n"
-"#line 1 1 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"out vec3 aMotionVec0;\n"
-"out vec3 aMotionVec1;\n"
-"\n"
-"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
-"{\n"
-" // This magically solves some artifacting errors!\n"
-" //\n"
-" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
-"\n"
-" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
-" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
-"}\n"
-"\n"
-"#line 6 0 \n"
-"\n"
-"uniform mat4x3 uMdl;\n"
-"uniform mat4 uPv;\n"
-"uniform mat4 uPvmPrev;\n"
-"uniform mat3 uNormalMtx;\n"
-"\n"
-"out vec2 aUv;\n"
-"out vec4 aNorm;\n"
-"out vec3 aCo;\n"
-"out vec3 aWorldCo;\n"
-"\n"
-"void main()\n"
-"{\n"
-" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
-" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
-" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
-"\n"
-" vs_motion_out( vproj0, vproj1 );\n"
-"\n"
-" gl_Position = vproj0;\n"
-"\n"
-" aUv = a_uv;\n"
-" aNorm = vec4( uNormalMtx * a_norm.xyz, a_norm.w );\n"
-" aCo = a_co;\n"
-" aWorldCo = world_pos0;\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/scene_route.fs",
-.static_src =
-"uniform sampler2D uTexGarbage;\n"
-"uniform sampler2D uTexGradients;\n"
-"uniform vec3 uCamera;\n"
-"uniform vec4 uColour;\n"
-"\n"
-"#line 1 1 \n"
-"// :D\n"
-"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
-"\n"
-"#line 7 0 \n"
-"#line 1 2 \n"
-"// :D\n"
-"\n"
-"in vec2 aUv;\n"
-"in vec4 aNorm;\n"
-"in vec3 aCo;\n"
-"in vec3 aWorldCo;\n"
-"\n"
-"#line 1 1 \n"
-"layout (location = 0) out vec4 oColour;\n"
-"\n"
-"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
-"layout (std140) uniform ub_world_lighting\n"
-"{\n"
-" vec4 g_cube_min;\n"
-" vec4 g_cube_inv_range;\n"
-"\n"
-" vec4 g_water_plane;\n"
-" vec4 g_depth_bounds;\n"
-"\n"
-" vec4 g_daysky_colour;\n"
-" vec4 g_nightsky_colour;\n"
-" vec4 g_sunset_colour;\n"
-" vec4 g_ambient_colour;\n"
-" vec4 g_sunset_ambient;\n"
-" vec4 g_sun_colour;\n"
-" vec4 g_sun_dir;\n"
-" vec4 g_board_0;\n"
-" vec4 g_board_1;\n"
-"\n"
-" float g_water_fog;\n"
-" float g_time;\n"
-" float g_realtime;\n"
-" float g_shadow_length;\n"
-" float g_shadow_spread;\n"
-"\n"
-" float g_time_of_day;\n"
-" float g_day_phase;\n"
-" float g_sunset_phase;\n"
-"\n"
-" int g_light_preview;\n"
-" int g_shadow_samples;\n"
-"\n"
-" int g_debug_indices;\n"
-" int g_debug_complexity;\n"
-"};\n"
-"\n"
-"uniform sampler2D g_world_depth;\n"
-"uniform samplerBuffer uLightsArray;\n"
-"uniform usampler3D uLightsIndex;\n"
-"\n"
-"#line 1 1 \n"
-"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
-"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
-"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
-"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
-"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
-"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
-"\n"
-"const float SUN_ANGLE = 0.0001;\n"
-"const float PI = 3.14159265358979323846264;\n"
-"\n"
-"//struct world_info\n"
-"//{\n"
-"// float time,\n"
-"// time_of_day,\n"
-"// day_phase,\n"
-"// sunset_phase;\n"
-"// \n"
-"// vec3 sun_dir;\n"
-"//};\n"
-"\n"
-"vec3 rand33(vec3 p3)\n"
-"{\n"
-" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
-" p3 += dot(p3, p3.yxz+33.33);\n"
-" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
-"}\n"
-"\n"
-"float stars( vec3 rd, float rr, float size ){\n"
-" vec3 co = rd * rr;\n"
-"\n"
-" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
-"\n"
-" float spaces = 1.0 / rr;\n"
-" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
-" a -= mod(a, spaces) - spaces * 0.5;\n"
-"\n"
-" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
-" \n"
-" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
-" plane = plane - mod(plane, PI / count);\n"
-"\n"
-" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
-"\n"
-" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
-" float ydist = sqrt(rr * rr - level * level);\n"
-" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
-" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
-" float star = smoothstep(size, 0.0, distance(center, co));\n"
-" return star;\n"
-"}\n"
-"\n"
-"float luminance( vec3 v )\n"
-"{\n"
-" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
-"}\n"
-"\n"
-"vec3 clearskies_ambient( vec3 dir )\n"
-"{\n"
-" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
-" float sky_gradient = dir.y;\n"
-" \n"
-" /* Blend phase colours */\n"
-" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
-" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
-" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
-" \n"
-" /* Add gradient */\n"
-" ambient -= sky_gradient * luminance(ambient);\n"
-" \n"
-" return ambient;\n"
-"}\n"
-"\n"
-"vec3 clearskies_sky( vec3 ray_dir )\n"
-"{\n"
-" ray_dir.y = abs( ray_dir.y );\n"
-" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
-" \n"
-" /* Sun */\n"
-" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
-" float sun_shape = pow( sun_size, 2000.0 );\n"
-" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" \n"
-" float star = 0.0;\n"
-" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
-"\n"
-" if( star_blend > 0.001 ){\n"
-" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
-" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
-" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
-" }\n"
-" }\n"
-" \n"
-" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
-" return composite;\n"
-"}\n"
-"\n"
-"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
-"{\n"
-" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
-"\n"
-" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
-" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
-" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
-" ) * g_sun_colour.rgb * g_day_phase;\n"
-"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
-" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" return ambient + (light_sun + sky_reflection) * shadow;\n"
-"}\n"
-"\n"
-"#line 44 0 \n"
-"\n"
-"float world_depth_sample( vec3 pos )\n"
-"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
-" return texture( g_world_depth, depth_coord ).r;\n"
-"}\n"
-"\n"
-"float world_water_depth( vec3 pos )\n"
-"{\n"
-" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return world_depth_sample( pos ) - ref_depth;\n"
-"}\n"
-"\n"
-"float shadow_sample( vec3 co ){\n"
-" float height_sample = world_depth_sample( co );\n"
-"\n"
-" float fdelta = height_sample - co.y;\n"
-" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
-"}\n"
-"\n"
-"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
-" if( g_shadow_samples == 0 ){\n"
-" return 1.0;\n"
-" }\n"
-"\n"
-" float fspread = g_shadow_spread;\n"
-" float flength = g_shadow_length;\n"
-"\n"
-" float famt = 0.0;\n"
-" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
-"\n"
-" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
-"\n"
-" return 1.0 - famt;\n"
-"}\n"
-"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
-"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
-"}\n"
-"\n"
-"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
-" float dist = pow(fdist*0.0010,0.78);\n"
-" return mix( vfrag, colour, min( 1.0, dist ) );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_light( int light_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
-" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
-" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
-"\n"
-" vec3 light_delta = light_co.xyz-co;\n"
-" float dist2 = dot(light_delta,light_delta);\n"
-"\n"
-" light_delta = normalize( light_delta );\n"
-"\n"
-" float quadratic = dist2*100.0;\n"
-" float attenuation = 1.0/( 1.0 + quadratic );\n"
-" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
-"\n"
-" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
-"\n"
-" if( light_dir.w < 0.999999 ){\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
-" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
-" }\n"
-"\n"
-" return light_colour.rgb * attenuation * falloff \n"
-" * step( g_day_phase, light_colour.w );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" uint light_count = packed_index & 0x3u;\n"
-"\n"
-" vec3 l = vec3(0.0);\n"
-"\n"
-" if( light_count >= 1u ){\n"
-" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
-" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
-" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
-"\n"
-" l += scene_calculate_light( index_0, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 2u ){\n"
-" l += scene_calculate_light( index_1, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 3u ){\n"
-" l += scene_calculate_light( index_2, halfview, co, normal );\n"
-" }\n"
-" }\n"
-" }\n"
-"\n"
-" return l;\n"
-"}\n"
-"\n"
-"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
-" float light_mask )\n"
-"{\n"
-" if( g_light_preview == 1 )\n"
-" diffuse = vec3(0.75);\n"
-"\n"
-" // Lighting\n"
-" vec3 halfview = uCamera - co;\n"
-" float fdist = length(halfview);\n"
-" halfview /= fdist;\n"
-"\n"
-" float world_shadow = newlight_compute_sun_shadow( \n"
-" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
-"\n"
-" vec3 total_light = clearskies_lighting( \n"
-" normal, min( light_mask, world_shadow ), halfview );\n"
-"\n"
-" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
-" cube_coord = floor( cube_coord );\n"
-"\n"
-" if( g_debug_indices == 1 )\n"
-" {\n"
-" return rand33(cube_coord);\n"
-" }\n"
-"\n"
-" if( g_debug_complexity == 1 )\n"
-" {\n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
-" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
-" }\n"
-"\n"
-" // FIXME: this coord should absolutely must be clamped!\n"
-" \n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, co, normal ) \n"
-" * light_mask;\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, co, normal )\n"
-" * light_mask;\n"
-"\n"
-" // Take a section of the sky function to give us a matching fog colour\n"
-"\n"
-" vec3 fog_colour = clearskies_ambient( -halfview );\n"
-" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
-" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" fog_colour += sun_colour;\n"
-" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"\n"
-"float sdLine( vec3 p, vec3 a, vec3 b )\n"
-"{\n"
-" vec3 pa = p - a;\n"
-" vec3 ba = b - a;\n"
-"\n"
-" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
-" return length( pa - ba*h );\n"
-"}\n"
-"\n"
-"float compute_board_shadow()\n"
-"{\n"
-" // player shadow\n"
-" float dist_to_player = max( 0.0, sdLine( aWorldCo, g_board_0.xyz,\n"
-" g_board_1.xyz )-0.1 );\n"
-" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
-" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
-"\n"
-" return 1.0 - player_shadow*0.8;\n"
-"}\n"
-"\n"
-"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
-"{\n"
-" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
-"}\n"
-"\n"
-"#line 8 0 \n"
-"#line 1 3 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"layout (location = 1) out vec2 oMotionVec;\n"
-"\n"
-"in vec3 aMotionVec0;\n"
-"in vec3 aMotionVec1;\n"
-"\n"
-"void compute_motion_vectors()\n"
-"{\n"
-" // Write motion vectors\n"
-" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
-" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
-"\n"
-" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"\n"
-"float filtered_stripe( in float p, in float ddx, in float ddy )\n"
-"{\n"
-" float w = max(abs(ddx), abs(ddy)) + 0.02;\n"
-" float i = (abs(fract((p-0.5*w)/2.0)-0.5)-abs(fract((p+0.5*w)/2.0)-0.5))/w;\n"
-" return 0.5 - i;\n"
-"}\n"
-"\n"
-"void main()\n"
-"{\n"
-" compute_motion_vectors();\n"
-"\n"
-" vec3 vfrag = vec3(0.5,0.5,0.5);\n"
-"\n"
-" // ws modulation\n"
-" vec4 wgarbage = texture( uTexGarbage, aCo.xz * 0.015 );\n"
-"\n"
-" // Creating normal patches\n"
-" vec3 modnorm = (wgarbage.rgb-0.4) * 1.4;\n"
-" vec3 qnorm = normalize(floor(aNorm.xyz*4.0+modnorm)*0.25);\n"
-" qnorm += vec3(0.001,0.0,0.0);\n"
-"\n"
-" vec3 tangent0 = normalize(cross(qnorm,vec3(0.0,1.0,0.0)));\n"
-" vec3 tangent1 = cross(qnorm,tangent0);\n"
-" vec2 uvdiffuse = vec2( dot(tangent0,aCo), dot(tangent1,aCo) ) * 0.035;\n"
-" \n"
-" // Patch local noise\n"
-" vec4 rgarbage = texture( uTexGarbage, uvdiffuse );\n"
-"\n"
-" vfrag = pow(uColour.rgb,vec3(1.0/2.2));\n"
-" vfrag -= rgarbage.a*0.1;\n"
-"\n"
-" if( wgarbage.g < 0.1 )\n"
-" discard;\n"
-"\n"
-" float movep = (aUv.x + abs(aUv.y-0.5)*0.4 - g_realtime)*2.0;\n"
-" float stripe = filtered_stripe( movep, dFdx(movep), dFdy(movep) );\n"
-" vfrag *= 0.9+stripe*uColour.a; \n"
-"\n"
-" if( g_light_preview == 1 )\n"
-" {\n"
-" vfrag = vec3(0.5);\n"
-" }\n"
-"\n"
-" // Lighting\n"
-" oColour = vec4( scene_compute_lighting( vfrag, qnorm, aWorldCo ), 1.0 );\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_scene_route_uMdl;
-static GLuint _uniform_scene_route_uPv;
-static GLuint _uniform_scene_route_uPvmPrev;
-static GLuint _uniform_scene_route_uNormalMtx;
-static GLuint _uniform_scene_route_uTexGarbage;
-static GLuint _uniform_scene_route_uTexGradients;
-static GLuint _uniform_scene_route_uCamera;
-static GLuint _uniform_scene_route_uColour;
-static GLuint _uniform_scene_route_g_world_depth;
-static GLuint _uniform_scene_route_uLightsArray;
-static GLuint _uniform_scene_route_uLightsIndex;
-static void shader_scene_route_uMdl(m4x3f m){
- glUniformMatrix4x3fv(_uniform_scene_route_uMdl,1,GL_FALSE,(float*)m);
+ glUniformMatrix4x3fv(_uniform_scene_route_uMdl,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_route_uPv(m4x4f m){
- glUniformMatrix4fv(_uniform_scene_route_uPv,1,GL_FALSE,(float*)m);
+static inline void shader_scene_route_uPv(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_scene_route_uPv,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_route_uPvmPrev(m4x4f m){
- glUniformMatrix4fv(_uniform_scene_route_uPvmPrev,1,GL_FALSE,(float*)m);
+static inline void shader_scene_route_uPvmPrev(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_scene_route_uPvmPrev,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_route_uNormalMtx(m3x3f m){
- glUniformMatrix3fv(_uniform_scene_route_uNormalMtx,1,GL_FALSE,(float*)m);
+static inline void shader_scene_route_uNormalMtx(m3x3f m)
+{
+ glUniformMatrix3fv(_uniform_scene_route_uNormalMtx,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_route_uTexGarbage(int i){
+static inline void shader_scene_route_uTexGarbage(int i)
+{
glUniform1i(_uniform_scene_route_uTexGarbage,i);
}
-static void shader_scene_route_uTexGradients(int i){
+static inline void shader_scene_route_uTexGradients(int i)
+{
glUniform1i(_uniform_scene_route_uTexGradients,i);
}
-static void shader_scene_route_uCamera(v3f v){
+static inline void shader_scene_route_uCamera(v3f v)
+{
glUniform3fv(_uniform_scene_route_uCamera,1,v);
}
-static void shader_scene_route_uColour(v4f v){
+static inline void shader_scene_route_uColour(v4f v)
+{
glUniform4fv(_uniform_scene_route_uColour,1,v);
}
-static void shader_scene_route_g_world_depth(int i){
+static inline void shader_scene_route_g_world_depth(int i)
+{
glUniform1i(_uniform_scene_route_g_world_depth,i);
}
-static void shader_scene_route_register(void){
- vg_shader_register( &_shader_scene_route );
-}
-static void shader_scene_route_use(void){ glUseProgram(_shader_scene_route.id); }
-static void shader_scene_route_link(void){
- _uniform_scene_route_uMdl = glGetUniformLocation( _shader_scene_route.id, "uMdl" );
- _uniform_scene_route_uPv = glGetUniformLocation( _shader_scene_route.id, "uPv" );
- _uniform_scene_route_uPvmPrev = glGetUniformLocation( _shader_scene_route.id, "uPvmPrev" );
- _uniform_scene_route_uNormalMtx = glGetUniformLocation( _shader_scene_route.id, "uNormalMtx" );
- _uniform_scene_route_uTexGarbage = glGetUniformLocation( _shader_scene_route.id, "uTexGarbage" );
- _uniform_scene_route_uTexGradients = glGetUniformLocation( _shader_scene_route.id, "uTexGradients" );
- _uniform_scene_route_uCamera = glGetUniformLocation( _shader_scene_route.id, "uCamera" );
- _uniform_scene_route_uColour = glGetUniformLocation( _shader_scene_route.id, "uColour" );
- _uniform_scene_route_g_world_depth = glGetUniformLocation( _shader_scene_route.id, "g_world_depth" );
- _uniform_scene_route_uLightsArray = glGetUniformLocation( _shader_scene_route.id, "uLightsArray" );
- _uniform_scene_route_uLightsIndex = glGetUniformLocation( _shader_scene_route.id, "uLightsIndex" );
+static inline void shader_scene_route_use(void);
+static inline void shader_scene_route_use(void)
+{
+ glUseProgram(_shader_scene_route.id);
}
-#endif /* SHADER_scene_route_H */
-#ifndef SHADER_scene_scoretext_H
-#define SHADER_scene_scoretext_H
-static void shader_scene_scoretext_link(void);
-static void shader_scene_scoretext_register(void);
-static struct vg_shader _shader_scene_scoretext = {
- .name = "scene_scoretext",
- .link = shader_scene_scoretext_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_scene_scoretext;
+extern GLuint _uniform_scene_scoretext_uMdl;
+extern GLuint _uniform_scene_scoretext_uPv;
+extern GLuint _uniform_scene_scoretext_uPvmPrev;
+extern GLuint _uniform_scene_scoretext_uInfo;
+extern GLuint _uniform_scene_scoretext_uTexGarbage;
+extern GLuint _uniform_scene_scoretext_uTexMain;
+extern GLuint _uniform_scene_scoretext_uCamera;
+extern GLuint _uniform_scene_scoretext_uPlane;
+extern GLuint _uniform_scene_scoretext_g_world_depth;
+extern GLuint _uniform_scene_scoretext_uLightsArray;
+extern GLuint _uniform_scene_scoretext_uLightsIndex;
+static inline void shader_scene_scoretext_uMdl(m4x3f m)
{
-.orig_file = "shaders/scene_sfd.vs",
-.static_src =
-"layout (location=0) in vec3 a_co;\n"
-"layout (location=1) in vec4 a_norm;\n"
-"layout (location=2) in vec2 a_uv;\n"
-"\n"
-"#line 1 1 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"out vec3 aMotionVec0;\n"
-"out vec3 aMotionVec1;\n"
-"\n"
-"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
-"{\n"
-" // This magically solves some artifacting errors!\n"
-" //\n"
-" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
-"\n"
-" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
-" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
-"}\n"
-"\n"
-"#line 6 0 \n"
-"\n"
-"uniform mat4x3 uMdl;\n"
-"uniform mat4 uPv;\n"
-"uniform mat4 uPvmPrev;\n"
-"uniform vec3 uInfo;\n"
-"\n"
-"out vec2 aUv;\n"
-"out vec4 aNorm;\n"
-"out vec3 aCo;\n"
-"out vec3 aWorldCo;\n"
-"\n"
-"void main()\n"
-"{\n"
-" float w = ((a_norm.w)-0.5)*2.0 + fract(uInfo.z) - 0.0;\n"
-" float c = -cos(w*0.6);\n"
-" float s = -sin(w*0.6);\n"
-" float r = 0.2;\n"
-"\n"
-" float w1 = clamp( w*4.0 - a_co.y*10.0, -1.0, 1.0 ) * (3.14159265*0.5);\n"
-" float c1 = cos(w1);\n"
-" float s1 = sin(w1);\n"
-"\n"
-" float yoff = step(0.01,fract(uInfo.z))*-0.5;\n"
-"\n"
-" mat4x3 mlocal;\n"
-" mlocal[0] = vec3(c1, s1,0.0);\n"
-" mlocal[1] = vec3(-s1,c1,0.0);\n"
-" mlocal[2] = vec3(0.0,0.0,1.0);\n"
-" mlocal[3] = vec3(c*r,uInfo.y*0.875 + s*r,uInfo.x*0.5);\n"
-"\n"
-" vec3 local_pos0 = mlocal * vec4( a_co, 1.0 );\n"
-" vec3 world_pos0 = uMdl * vec4( local_pos0, 1.0 );\n"
-"\n"
-" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
-" vec4 vproj1 = uPvmPrev * vec4( local_pos0, 1.0 );\n"
-"\n"
-" vs_motion_out( vproj0, vproj1 );\n"
-"\n"
-" gl_Position = vproj0;\n"
-"\n"
-" aUv = a_uv + vec2( floor(uInfo.z+0.5)*(1.0/64.0), yoff );\n"
-" aNorm = vec4( mat3(uMdl) * mat3(mlocal) * a_norm.xyz, a_norm.w );\n"
-" aCo = a_co;\n"
-" aWorldCo = world_pos0;\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/scene_standard.fs",
-.static_src =
-"uniform sampler2D uTexGarbage;\n"
-"uniform sampler2D uTexMain;\n"
-"uniform vec3 uCamera;\n"
-"uniform vec4 uPlane;\n"
-"\n"
-"#line 1 1 \n"
-"// :D\n"
-"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
-"\n"
-"#line 7 0 \n"
-"#line 1 2 \n"
-"// :D\n"
-"\n"
-"in vec2 aUv;\n"
-"in vec4 aNorm;\n"
-"in vec3 aCo;\n"
-"in vec3 aWorldCo;\n"
-"\n"
-"#line 1 1 \n"
-"layout (location = 0) out vec4 oColour;\n"
-"\n"
-"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
-"layout (std140) uniform ub_world_lighting\n"
-"{\n"
-" vec4 g_cube_min;\n"
-" vec4 g_cube_inv_range;\n"
-"\n"
-" vec4 g_water_plane;\n"
-" vec4 g_depth_bounds;\n"
-"\n"
-" vec4 g_daysky_colour;\n"
-" vec4 g_nightsky_colour;\n"
-" vec4 g_sunset_colour;\n"
-" vec4 g_ambient_colour;\n"
-" vec4 g_sunset_ambient;\n"
-" vec4 g_sun_colour;\n"
-" vec4 g_sun_dir;\n"
-" vec4 g_board_0;\n"
-" vec4 g_board_1;\n"
-"\n"
-" float g_water_fog;\n"
-" float g_time;\n"
-" float g_realtime;\n"
-" float g_shadow_length;\n"
-" float g_shadow_spread;\n"
-"\n"
-" float g_time_of_day;\n"
-" float g_day_phase;\n"
-" float g_sunset_phase;\n"
-"\n"
-" int g_light_preview;\n"
-" int g_shadow_samples;\n"
-"\n"
-" int g_debug_indices;\n"
-" int g_debug_complexity;\n"
-"};\n"
-"\n"
-"uniform sampler2D g_world_depth;\n"
-"uniform samplerBuffer uLightsArray;\n"
-"uniform usampler3D uLightsIndex;\n"
-"\n"
-"#line 1 1 \n"
-"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
-"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
-"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
-"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
-"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
-"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
-"\n"
-"const float SUN_ANGLE = 0.0001;\n"
-"const float PI = 3.14159265358979323846264;\n"
-"\n"
-"//struct world_info\n"
-"//{\n"
-"// float time,\n"
-"// time_of_day,\n"
-"// day_phase,\n"
-"// sunset_phase;\n"
-"// \n"
-"// vec3 sun_dir;\n"
-"//};\n"
-"\n"
-"vec3 rand33(vec3 p3)\n"
-"{\n"
-" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
-" p3 += dot(p3, p3.yxz+33.33);\n"
-" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
-"}\n"
-"\n"
-"float stars( vec3 rd, float rr, float size ){\n"
-" vec3 co = rd * rr;\n"
-"\n"
-" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
-"\n"
-" float spaces = 1.0 / rr;\n"
-" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
-" a -= mod(a, spaces) - spaces * 0.5;\n"
-"\n"
-" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
-" \n"
-" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
-" plane = plane - mod(plane, PI / count);\n"
-"\n"
-" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
-"\n"
-" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
-" float ydist = sqrt(rr * rr - level * level);\n"
-" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
-" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
-" float star = smoothstep(size, 0.0, distance(center, co));\n"
-" return star;\n"
-"}\n"
-"\n"
-"float luminance( vec3 v )\n"
-"{\n"
-" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
-"}\n"
-"\n"
-"vec3 clearskies_ambient( vec3 dir )\n"
-"{\n"
-" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
-" float sky_gradient = dir.y;\n"
-" \n"
-" /* Blend phase colours */\n"
-" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
-" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
-" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
-" \n"
-" /* Add gradient */\n"
-" ambient -= sky_gradient * luminance(ambient);\n"
-" \n"
-" return ambient;\n"
-"}\n"
-"\n"
-"vec3 clearskies_sky( vec3 ray_dir )\n"
-"{\n"
-" ray_dir.y = abs( ray_dir.y );\n"
-" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
-" \n"
-" /* Sun */\n"
-" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
-" float sun_shape = pow( sun_size, 2000.0 );\n"
-" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" \n"
-" float star = 0.0;\n"
-" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
-"\n"
-" if( star_blend > 0.001 ){\n"
-" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
-" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
-" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
-" }\n"
-" }\n"
-" \n"
-" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
-" return composite;\n"
-"}\n"
-"\n"
-"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
-"{\n"
-" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
-"\n"
-" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
-" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
-" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
-" ) * g_sun_colour.rgb * g_day_phase;\n"
-"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
-" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" return ambient + (light_sun + sky_reflection) * shadow;\n"
-"}\n"
-"\n"
-"#line 44 0 \n"
-"\n"
-"float world_depth_sample( vec3 pos )\n"
-"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
-" return texture( g_world_depth, depth_coord ).r;\n"
-"}\n"
-"\n"
-"float world_water_depth( vec3 pos )\n"
-"{\n"
-" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return world_depth_sample( pos ) - ref_depth;\n"
-"}\n"
-"\n"
-"float shadow_sample( vec3 co ){\n"
-" float height_sample = world_depth_sample( co );\n"
-"\n"
-" float fdelta = height_sample - co.y;\n"
-" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
-"}\n"
-"\n"
-"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
-" if( g_shadow_samples == 0 ){\n"
-" return 1.0;\n"
-" }\n"
-"\n"
-" float fspread = g_shadow_spread;\n"
-" float flength = g_shadow_length;\n"
-"\n"
-" float famt = 0.0;\n"
-" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
-"\n"
-" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
-"\n"
-" return 1.0 - famt;\n"
-"}\n"
-"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
-"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
-"}\n"
-"\n"
-"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
-" float dist = pow(fdist*0.0010,0.78);\n"
-" return mix( vfrag, colour, min( 1.0, dist ) );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_light( int light_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
-" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
-" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
-"\n"
-" vec3 light_delta = light_co.xyz-co;\n"
-" float dist2 = dot(light_delta,light_delta);\n"
-"\n"
-" light_delta = normalize( light_delta );\n"
-"\n"
-" float quadratic = dist2*100.0;\n"
-" float attenuation = 1.0/( 1.0 + quadratic );\n"
-" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
-"\n"
-" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
-"\n"
-" if( light_dir.w < 0.999999 ){\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
-" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
-" }\n"
-"\n"
-" return light_colour.rgb * attenuation * falloff \n"
-" * step( g_day_phase, light_colour.w );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" uint light_count = packed_index & 0x3u;\n"
-"\n"
-" vec3 l = vec3(0.0);\n"
-"\n"
-" if( light_count >= 1u ){\n"
-" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
-" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
-" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
-"\n"
-" l += scene_calculate_light( index_0, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 2u ){\n"
-" l += scene_calculate_light( index_1, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 3u ){\n"
-" l += scene_calculate_light( index_2, halfview, co, normal );\n"
-" }\n"
-" }\n"
-" }\n"
-"\n"
-" return l;\n"
-"}\n"
-"\n"
-"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
-" float light_mask )\n"
-"{\n"
-" if( g_light_preview == 1 )\n"
-" diffuse = vec3(0.75);\n"
-"\n"
-" // Lighting\n"
-" vec3 halfview = uCamera - co;\n"
-" float fdist = length(halfview);\n"
-" halfview /= fdist;\n"
-"\n"
-" float world_shadow = newlight_compute_sun_shadow( \n"
-" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
-"\n"
-" vec3 total_light = clearskies_lighting( \n"
-" normal, min( light_mask, world_shadow ), halfview );\n"
-"\n"
-" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
-" cube_coord = floor( cube_coord );\n"
-"\n"
-" if( g_debug_indices == 1 )\n"
-" {\n"
-" return rand33(cube_coord);\n"
-" }\n"
-"\n"
-" if( g_debug_complexity == 1 )\n"
-" {\n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
-" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
-" }\n"
-"\n"
-" // FIXME: this coord should absolutely must be clamped!\n"
-" \n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, co, normal ) \n"
-" * light_mask;\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, co, normal )\n"
-" * light_mask;\n"
-"\n"
-" // Take a section of the sky function to give us a matching fog colour\n"
-"\n"
-" vec3 fog_colour = clearskies_ambient( -halfview );\n"
-" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
-" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" fog_colour += sun_colour;\n"
-" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"\n"
-"float sdLine( vec3 p, vec3 a, vec3 b )\n"
-"{\n"
-" vec3 pa = p - a;\n"
-" vec3 ba = b - a;\n"
-"\n"
-" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
-" return length( pa - ba*h );\n"
-"}\n"
-"\n"
-"float compute_board_shadow()\n"
-"{\n"
-" // player shadow\n"
-" float dist_to_player = max( 0.0, sdLine( aWorldCo, g_board_0.xyz,\n"
-" g_board_1.xyz )-0.1 );\n"
-" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
-" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
-"\n"
-" return 1.0 - player_shadow*0.8;\n"
-"}\n"
-"\n"
-"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
-"{\n"
-" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
-"}\n"
-"\n"
-"#line 8 0 \n"
-"#line 1 3 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"layout (location = 1) out vec2 oMotionVec;\n"
-"\n"
-"in vec3 aMotionVec0;\n"
-"in vec3 aMotionVec1;\n"
-"\n"
-"void compute_motion_vectors()\n"
-"{\n"
-" // Write motion vectors\n"
-" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
-" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
-"\n"
-" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"\n"
-"void main()\n"
-"{\n"
-" compute_motion_vectors();\n"
-"\n"
-" vec3 vfrag = vec3(0.5,0.5,0.5);\n"
-" vec4 vsamplemain = texture( uTexMain, aUv );\n"
-" vec3 qnorm = aNorm.xyz;\n"
-"\n"
-" vfrag = vsamplemain.rgb;\n"
-"\n"
-" if( g_light_preview == 1 )\n"
-" {\n"
-" vfrag = vec3(0.5);\n"
-" }\n"
-"\n"
-" vfrag = scene_compute_lighting( vfrag, qnorm, aWorldCo );\n"
-" oColour = vec4( vfrag, 1.0 );\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_scene_scoretext_uMdl;
-static GLuint _uniform_scene_scoretext_uPv;
-static GLuint _uniform_scene_scoretext_uPvmPrev;
-static GLuint _uniform_scene_scoretext_uInfo;
-static GLuint _uniform_scene_scoretext_uTexGarbage;
-static GLuint _uniform_scene_scoretext_uTexMain;
-static GLuint _uniform_scene_scoretext_uCamera;
-static GLuint _uniform_scene_scoretext_uPlane;
-static GLuint _uniform_scene_scoretext_g_world_depth;
-static GLuint _uniform_scene_scoretext_uLightsArray;
-static GLuint _uniform_scene_scoretext_uLightsIndex;
-static void shader_scene_scoretext_uMdl(m4x3f m){
- glUniformMatrix4x3fv(_uniform_scene_scoretext_uMdl,1,GL_FALSE,(float*)m);
+ glUniformMatrix4x3fv(_uniform_scene_scoretext_uMdl,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_scoretext_uPv(m4x4f m){
- glUniformMatrix4fv(_uniform_scene_scoretext_uPv,1,GL_FALSE,(float*)m);
+static inline void shader_scene_scoretext_uPv(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_scene_scoretext_uPv,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_scoretext_uPvmPrev(m4x4f m){
- glUniformMatrix4fv(_uniform_scene_scoretext_uPvmPrev,1,GL_FALSE,(float*)m);
+static inline void shader_scene_scoretext_uPvmPrev(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_scene_scoretext_uPvmPrev,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_scoretext_uInfo(v3f v){
+static inline void shader_scene_scoretext_uInfo(v3f v)
+{
glUniform3fv(_uniform_scene_scoretext_uInfo,1,v);
}
-static void shader_scene_scoretext_uTexGarbage(int i){
+static inline void shader_scene_scoretext_uTexGarbage(int i)
+{
glUniform1i(_uniform_scene_scoretext_uTexGarbage,i);
}
-static void shader_scene_scoretext_uTexMain(int i){
+static inline void shader_scene_scoretext_uTexMain(int i)
+{
glUniform1i(_uniform_scene_scoretext_uTexMain,i);
}
-static void shader_scene_scoretext_uCamera(v3f v){
+static inline void shader_scene_scoretext_uCamera(v3f v)
+{
glUniform3fv(_uniform_scene_scoretext_uCamera,1,v);
}
-static void shader_scene_scoretext_uPlane(v4f v){
+static inline void shader_scene_scoretext_uPlane(v4f v)
+{
glUniform4fv(_uniform_scene_scoretext_uPlane,1,v);
}
-static void shader_scene_scoretext_g_world_depth(int i){
+static inline void shader_scene_scoretext_g_world_depth(int i)
+{
glUniform1i(_uniform_scene_scoretext_g_world_depth,i);
}
-static void shader_scene_scoretext_register(void){
- vg_shader_register( &_shader_scene_scoretext );
-}
-static void shader_scene_scoretext_use(void){ glUseProgram(_shader_scene_scoretext.id); }
-static void shader_scene_scoretext_link(void){
- _uniform_scene_scoretext_uMdl = glGetUniformLocation( _shader_scene_scoretext.id, "uMdl" );
- _uniform_scene_scoretext_uPv = glGetUniformLocation( _shader_scene_scoretext.id, "uPv" );
- _uniform_scene_scoretext_uPvmPrev = glGetUniformLocation( _shader_scene_scoretext.id, "uPvmPrev" );
- _uniform_scene_scoretext_uInfo = glGetUniformLocation( _shader_scene_scoretext.id, "uInfo" );
- _uniform_scene_scoretext_uTexGarbage = glGetUniformLocation( _shader_scene_scoretext.id, "uTexGarbage" );
- _uniform_scene_scoretext_uTexMain = glGetUniformLocation( _shader_scene_scoretext.id, "uTexMain" );
- _uniform_scene_scoretext_uCamera = glGetUniformLocation( _shader_scene_scoretext.id, "uCamera" );
- _uniform_scene_scoretext_uPlane = glGetUniformLocation( _shader_scene_scoretext.id, "uPlane" );
- _uniform_scene_scoretext_g_world_depth = glGetUniformLocation( _shader_scene_scoretext.id, "g_world_depth" );
- _uniform_scene_scoretext_uLightsArray = glGetUniformLocation( _shader_scene_scoretext.id, "uLightsArray" );
- _uniform_scene_scoretext_uLightsIndex = glGetUniformLocation( _shader_scene_scoretext.id, "uLightsIndex" );
+static inline void shader_scene_scoretext_use(void);
+static inline void shader_scene_scoretext_use(void)
+{
+ glUseProgram(_shader_scene_scoretext.id);
}
-#endif /* SHADER_scene_scoretext_H */
-#ifndef SHADER_scene_standard_H
-#define SHADER_scene_standard_H
-static void shader_scene_standard_link(void);
-static void shader_scene_standard_register(void);
-static struct vg_shader _shader_scene_standard = {
- .name = "scene_standard",
- .link = shader_scene_standard_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_scene_standard;
+extern GLuint _uniform_scene_standard_uMdl;
+extern GLuint _uniform_scene_standard_uPv;
+extern GLuint _uniform_scene_standard_uPvmPrev;
+extern GLuint _uniform_scene_standard_uTexGarbage;
+extern GLuint _uniform_scene_standard_uTexMain;
+extern GLuint _uniform_scene_standard_uCamera;
+extern GLuint _uniform_scene_standard_uPlane;
+extern GLuint _uniform_scene_standard_g_world_depth;
+extern GLuint _uniform_scene_standard_uLightsArray;
+extern GLuint _uniform_scene_standard_uLightsIndex;
+static inline void shader_scene_standard_uMdl(m4x3f m)
{
-.orig_file = "shaders/scene.vs",
-.static_src =
-"layout (location=0) in vec3 a_co;\n"
-"layout (location=1) in vec4 a_norm;\n"
-"layout (location=2) in vec2 a_uv;\n"
-"\n"
-"#line 1 1 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"out vec3 aMotionVec0;\n"
-"out vec3 aMotionVec1;\n"
-"\n"
-"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
-"{\n"
-" // This magically solves some artifacting errors!\n"
-" //\n"
-" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
-"\n"
-" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
-" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
-"}\n"
-"\n"
-"#line 6 0 \n"
-"\n"
-"uniform mat4x3 uMdl;\n"
-"uniform mat4 uPv;\n"
-"uniform mat4 uPvmPrev;\n"
-"\n"
-"out vec2 aUv;\n"
-"out vec4 aNorm;\n"
-"out vec3 aCo;\n"
-"out vec3 aWorldCo;\n"
-"\n"
-"void main()\n"
-"{\n"
-" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
-" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
-" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
-"\n"
-" vs_motion_out( vproj0, vproj1 );\n"
-"\n"
-" gl_Position = vproj0;\n"
-"\n"
-" aUv = a_uv;\n"
-" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
-" aCo = a_co;\n"
-" aWorldCo = world_pos0;\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/scene_standard.fs",
-.static_src =
-"uniform sampler2D uTexGarbage;\n"
-"uniform sampler2D uTexMain;\n"
-"uniform vec3 uCamera;\n"
-"uniform vec4 uPlane;\n"
-"\n"
-"#line 1 1 \n"
-"// :D\n"
-"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
-"\n"
-"#line 7 0 \n"
-"#line 1 2 \n"
-"// :D\n"
-"\n"
-"in vec2 aUv;\n"
-"in vec4 aNorm;\n"
-"in vec3 aCo;\n"
-"in vec3 aWorldCo;\n"
-"\n"
-"#line 1 1 \n"
-"layout (location = 0) out vec4 oColour;\n"
-"\n"
-"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
-"layout (std140) uniform ub_world_lighting\n"
-"{\n"
-" vec4 g_cube_min;\n"
-" vec4 g_cube_inv_range;\n"
-"\n"
-" vec4 g_water_plane;\n"
-" vec4 g_depth_bounds;\n"
-"\n"
-" vec4 g_daysky_colour;\n"
-" vec4 g_nightsky_colour;\n"
-" vec4 g_sunset_colour;\n"
-" vec4 g_ambient_colour;\n"
-" vec4 g_sunset_ambient;\n"
-" vec4 g_sun_colour;\n"
-" vec4 g_sun_dir;\n"
-" vec4 g_board_0;\n"
-" vec4 g_board_1;\n"
-"\n"
-" float g_water_fog;\n"
-" float g_time;\n"
-" float g_realtime;\n"
-" float g_shadow_length;\n"
-" float g_shadow_spread;\n"
-"\n"
-" float g_time_of_day;\n"
-" float g_day_phase;\n"
-" float g_sunset_phase;\n"
-"\n"
-" int g_light_preview;\n"
-" int g_shadow_samples;\n"
-"\n"
-" int g_debug_indices;\n"
-" int g_debug_complexity;\n"
-"};\n"
-"\n"
-"uniform sampler2D g_world_depth;\n"
-"uniform samplerBuffer uLightsArray;\n"
-"uniform usampler3D uLightsIndex;\n"
-"\n"
-"#line 1 1 \n"
-"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
-"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
-"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
-"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
-"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
-"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
-"\n"
-"const float SUN_ANGLE = 0.0001;\n"
-"const float PI = 3.14159265358979323846264;\n"
-"\n"
-"//struct world_info\n"
-"//{\n"
-"// float time,\n"
-"// time_of_day,\n"
-"// day_phase,\n"
-"// sunset_phase;\n"
-"// \n"
-"// vec3 sun_dir;\n"
-"//};\n"
-"\n"
-"vec3 rand33(vec3 p3)\n"
-"{\n"
-" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
-" p3 += dot(p3, p3.yxz+33.33);\n"
-" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
-"}\n"
-"\n"
-"float stars( vec3 rd, float rr, float size ){\n"
-" vec3 co = rd * rr;\n"
-"\n"
-" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
-"\n"
-" float spaces = 1.0 / rr;\n"
-" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
-" a -= mod(a, spaces) - spaces * 0.5;\n"
-"\n"
-" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
-" \n"
-" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
-" plane = plane - mod(plane, PI / count);\n"
-"\n"
-" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
-"\n"
-" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
-" float ydist = sqrt(rr * rr - level * level);\n"
-" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
-" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
-" float star = smoothstep(size, 0.0, distance(center, co));\n"
-" return star;\n"
-"}\n"
-"\n"
-"float luminance( vec3 v )\n"
-"{\n"
-" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
-"}\n"
-"\n"
-"vec3 clearskies_ambient( vec3 dir )\n"
-"{\n"
-" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
-" float sky_gradient = dir.y;\n"
-" \n"
-" /* Blend phase colours */\n"
-" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
-" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
-" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
-" \n"
-" /* Add gradient */\n"
-" ambient -= sky_gradient * luminance(ambient);\n"
-" \n"
-" return ambient;\n"
-"}\n"
-"\n"
-"vec3 clearskies_sky( vec3 ray_dir )\n"
-"{\n"
-" ray_dir.y = abs( ray_dir.y );\n"
-" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
-" \n"
-" /* Sun */\n"
-" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
-" float sun_shape = pow( sun_size, 2000.0 );\n"
-" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" \n"
-" float star = 0.0;\n"
-" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
-"\n"
-" if( star_blend > 0.001 ){\n"
-" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
-" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
-" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
-" }\n"
-" }\n"
-" \n"
-" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
-" return composite;\n"
-"}\n"
-"\n"
-"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
-"{\n"
-" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
-"\n"
-" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
-" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
-" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
-" ) * g_sun_colour.rgb * g_day_phase;\n"
-"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
-" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" return ambient + (light_sun + sky_reflection) * shadow;\n"
-"}\n"
-"\n"
-"#line 44 0 \n"
-"\n"
-"float world_depth_sample( vec3 pos )\n"
-"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
-" return texture( g_world_depth, depth_coord ).r;\n"
-"}\n"
-"\n"
-"float world_water_depth( vec3 pos )\n"
-"{\n"
-" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return world_depth_sample( pos ) - ref_depth;\n"
-"}\n"
-"\n"
-"float shadow_sample( vec3 co ){\n"
-" float height_sample = world_depth_sample( co );\n"
-"\n"
-" float fdelta = height_sample - co.y;\n"
-" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
-"}\n"
-"\n"
-"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
-" if( g_shadow_samples == 0 ){\n"
-" return 1.0;\n"
-" }\n"
-"\n"
-" float fspread = g_shadow_spread;\n"
-" float flength = g_shadow_length;\n"
-"\n"
-" float famt = 0.0;\n"
-" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
-"\n"
-" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
-"\n"
-" return 1.0 - famt;\n"
-"}\n"
-"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
-"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
-"}\n"
-"\n"
-"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
-" float dist = pow(fdist*0.0010,0.78);\n"
-" return mix( vfrag, colour, min( 1.0, dist ) );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_light( int light_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
-" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
-" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
-"\n"
-" vec3 light_delta = light_co.xyz-co;\n"
-" float dist2 = dot(light_delta,light_delta);\n"
-"\n"
-" light_delta = normalize( light_delta );\n"
-"\n"
-" float quadratic = dist2*100.0;\n"
-" float attenuation = 1.0/( 1.0 + quadratic );\n"
-" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
-"\n"
-" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
-"\n"
-" if( light_dir.w < 0.999999 ){\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
-" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
-" }\n"
-"\n"
-" return light_colour.rgb * attenuation * falloff \n"
-" * step( g_day_phase, light_colour.w );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" uint light_count = packed_index & 0x3u;\n"
-"\n"
-" vec3 l = vec3(0.0);\n"
-"\n"
-" if( light_count >= 1u ){\n"
-" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
-" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
-" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
-"\n"
-" l += scene_calculate_light( index_0, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 2u ){\n"
-" l += scene_calculate_light( index_1, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 3u ){\n"
-" l += scene_calculate_light( index_2, halfview, co, normal );\n"
-" }\n"
-" }\n"
-" }\n"
-"\n"
-" return l;\n"
-"}\n"
-"\n"
-"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
-" float light_mask )\n"
-"{\n"
-" if( g_light_preview == 1 )\n"
-" diffuse = vec3(0.75);\n"
-"\n"
-" // Lighting\n"
-" vec3 halfview = uCamera - co;\n"
-" float fdist = length(halfview);\n"
-" halfview /= fdist;\n"
-"\n"
-" float world_shadow = newlight_compute_sun_shadow( \n"
-" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
-"\n"
-" vec3 total_light = clearskies_lighting( \n"
-" normal, min( light_mask, world_shadow ), halfview );\n"
-"\n"
-" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
-" cube_coord = floor( cube_coord );\n"
-"\n"
-" if( g_debug_indices == 1 )\n"
-" {\n"
-" return rand33(cube_coord);\n"
-" }\n"
-"\n"
-" if( g_debug_complexity == 1 )\n"
-" {\n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
-" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
-" }\n"
-"\n"
-" // FIXME: this coord should absolutely must be clamped!\n"
-" \n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, co, normal ) \n"
-" * light_mask;\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, co, normal )\n"
-" * light_mask;\n"
-"\n"
-" // Take a section of the sky function to give us a matching fog colour\n"
-"\n"
-" vec3 fog_colour = clearskies_ambient( -halfview );\n"
-" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
-" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" fog_colour += sun_colour;\n"
-" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"\n"
-"float sdLine( vec3 p, vec3 a, vec3 b )\n"
-"{\n"
-" vec3 pa = p - a;\n"
-" vec3 ba = b - a;\n"
-"\n"
-" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
-" return length( pa - ba*h );\n"
-"}\n"
-"\n"
-"float compute_board_shadow()\n"
-"{\n"
-" // player shadow\n"
-" float dist_to_player = max( 0.0, sdLine( aWorldCo, g_board_0.xyz,\n"
-" g_board_1.xyz )-0.1 );\n"
-" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
-" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
-"\n"
-" return 1.0 - player_shadow*0.8;\n"
-"}\n"
-"\n"
-"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
-"{\n"
-" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
-"}\n"
-"\n"
-"#line 8 0 \n"
-"#line 1 3 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"layout (location = 1) out vec2 oMotionVec;\n"
-"\n"
-"in vec3 aMotionVec0;\n"
-"in vec3 aMotionVec1;\n"
-"\n"
-"void compute_motion_vectors()\n"
-"{\n"
-" // Write motion vectors\n"
-" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
-" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
-"\n"
-" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"\n"
-"void main()\n"
-"{\n"
-" compute_motion_vectors();\n"
-"\n"
-" vec3 vfrag = vec3(0.5,0.5,0.5);\n"
-" vec4 vsamplemain = texture( uTexMain, aUv );\n"
-" vec3 qnorm = aNorm.xyz;\n"
-"\n"
-" vfrag = vsamplemain.rgb;\n"
-"\n"
-" if( g_light_preview == 1 )\n"
-" {\n"
-" vfrag = vec3(0.5);\n"
-" }\n"
-"\n"
-" vfrag = scene_compute_lighting( vfrag, qnorm, aWorldCo );\n"
-" oColour = vec4( vfrag, 1.0 );\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_scene_standard_uMdl;
-static GLuint _uniform_scene_standard_uPv;
-static GLuint _uniform_scene_standard_uPvmPrev;
-static GLuint _uniform_scene_standard_uTexGarbage;
-static GLuint _uniform_scene_standard_uTexMain;
-static GLuint _uniform_scene_standard_uCamera;
-static GLuint _uniform_scene_standard_uPlane;
-static GLuint _uniform_scene_standard_g_world_depth;
-static GLuint _uniform_scene_standard_uLightsArray;
-static GLuint _uniform_scene_standard_uLightsIndex;
-static void shader_scene_standard_uMdl(m4x3f m){
- glUniformMatrix4x3fv(_uniform_scene_standard_uMdl,1,GL_FALSE,(float*)m);
+ glUniformMatrix4x3fv(_uniform_scene_standard_uMdl,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_standard_uPv(m4x4f m){
- glUniformMatrix4fv(_uniform_scene_standard_uPv,1,GL_FALSE,(float*)m);
+static inline void shader_scene_standard_uPv(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_scene_standard_uPv,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_standard_uPvmPrev(m4x4f m){
- glUniformMatrix4fv(_uniform_scene_standard_uPvmPrev,1,GL_FALSE,(float*)m);
+static inline void shader_scene_standard_uPvmPrev(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_scene_standard_uPvmPrev,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_standard_uTexGarbage(int i){
+static inline void shader_scene_standard_uTexGarbage(int i)
+{
glUniform1i(_uniform_scene_standard_uTexGarbage,i);
}
-static void shader_scene_standard_uTexMain(int i){
+static inline void shader_scene_standard_uTexMain(int i)
+{
glUniform1i(_uniform_scene_standard_uTexMain,i);
}
-static void shader_scene_standard_uCamera(v3f v){
+static inline void shader_scene_standard_uCamera(v3f v)
+{
glUniform3fv(_uniform_scene_standard_uCamera,1,v);
}
-static void shader_scene_standard_uPlane(v4f v){
+static inline void shader_scene_standard_uPlane(v4f v)
+{
glUniform4fv(_uniform_scene_standard_uPlane,1,v);
}
-static void shader_scene_standard_g_world_depth(int i){
+static inline void shader_scene_standard_g_world_depth(int i)
+{
glUniform1i(_uniform_scene_standard_g_world_depth,i);
}
-static void shader_scene_standard_register(void){
- vg_shader_register( &_shader_scene_standard );
-}
-static void shader_scene_standard_use(void){ glUseProgram(_shader_scene_standard.id); }
-static void shader_scene_standard_link(void){
- _uniform_scene_standard_uMdl = glGetUniformLocation( _shader_scene_standard.id, "uMdl" );
- _uniform_scene_standard_uPv = glGetUniformLocation( _shader_scene_standard.id, "uPv" );
- _uniform_scene_standard_uPvmPrev = glGetUniformLocation( _shader_scene_standard.id, "uPvmPrev" );
- _uniform_scene_standard_uTexGarbage = glGetUniformLocation( _shader_scene_standard.id, "uTexGarbage" );
- _uniform_scene_standard_uTexMain = glGetUniformLocation( _shader_scene_standard.id, "uTexMain" );
- _uniform_scene_standard_uCamera = glGetUniformLocation( _shader_scene_standard.id, "uCamera" );
- _uniform_scene_standard_uPlane = glGetUniformLocation( _shader_scene_standard.id, "uPlane" );
- _uniform_scene_standard_g_world_depth = glGetUniformLocation( _shader_scene_standard.id, "g_world_depth" );
- _uniform_scene_standard_uLightsArray = glGetUniformLocation( _shader_scene_standard.id, "uLightsArray" );
- _uniform_scene_standard_uLightsIndex = glGetUniformLocation( _shader_scene_standard.id, "uLightsIndex" );
+static inline void shader_scene_standard_use(void);
+static inline void shader_scene_standard_use(void)
+{
+ glUseProgram(_shader_scene_standard.id);
}
-#endif /* SHADER_scene_standard_H */
-#ifndef SHADER_scene_standard_alphatest_H
-#define SHADER_scene_standard_alphatest_H
-static void shader_scene_standard_alphatest_link(void);
-static void shader_scene_standard_alphatest_register(void);
-static struct vg_shader _shader_scene_standard_alphatest = {
- .name = "scene_standard_alphatest",
- .link = shader_scene_standard_alphatest_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_scene_standard_alphatest;
+extern GLuint _uniform_scene_standard_alphatest_uMdl;
+extern GLuint _uniform_scene_standard_alphatest_uPv;
+extern GLuint _uniform_scene_standard_alphatest_uPvmPrev;
+extern GLuint _uniform_scene_standard_alphatest_uTexGarbage;
+extern GLuint _uniform_scene_standard_alphatest_uTexMain;
+extern GLuint _uniform_scene_standard_alphatest_uCamera;
+extern GLuint _uniform_scene_standard_alphatest_uPlane;
+extern GLuint _uniform_scene_standard_alphatest_g_world_depth;
+extern GLuint _uniform_scene_standard_alphatest_uLightsArray;
+extern GLuint _uniform_scene_standard_alphatest_uLightsIndex;
+static inline void shader_scene_standard_alphatest_uMdl(m4x3f m)
{
-.orig_file = "shaders/scene.vs",
-.static_src =
-"layout (location=0) in vec3 a_co;\n"
-"layout (location=1) in vec4 a_norm;\n"
-"layout (location=2) in vec2 a_uv;\n"
-"\n"
-"#line 1 1 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"out vec3 aMotionVec0;\n"
-"out vec3 aMotionVec1;\n"
-"\n"
-"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
-"{\n"
-" // This magically solves some artifacting errors!\n"
-" //\n"
-" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
-"\n"
-" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
-" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
-"}\n"
-"\n"
-"#line 6 0 \n"
-"\n"
-"uniform mat4x3 uMdl;\n"
-"uniform mat4 uPv;\n"
-"uniform mat4 uPvmPrev;\n"
-"\n"
-"out vec2 aUv;\n"
-"out vec4 aNorm;\n"
-"out vec3 aCo;\n"
-"out vec3 aWorldCo;\n"
-"\n"
-"void main()\n"
-"{\n"
-" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
-" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
-" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
-"\n"
-" vs_motion_out( vproj0, vproj1 );\n"
-"\n"
-" gl_Position = vproj0;\n"
-"\n"
-" aUv = a_uv;\n"
-" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
-" aCo = a_co;\n"
-" aWorldCo = world_pos0;\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/scene_standard_alphatest.fs",
-.static_src =
-"uniform sampler2D uTexGarbage;\n"
-"uniform sampler2D uTexMain;\n"
-"uniform vec3 uCamera;\n"
-"uniform vec4 uPlane;\n"
-"\n"
-"#line 1 1 \n"
-"// :D\n"
-"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
-"\n"
-"#line 7 0 \n"
-"#line 1 2 \n"
-"// :D\n"
-"\n"
-"in vec2 aUv;\n"
-"in vec4 aNorm;\n"
-"in vec3 aCo;\n"
-"in vec3 aWorldCo;\n"
-"\n"
-"#line 1 1 \n"
-"layout (location = 0) out vec4 oColour;\n"
-"\n"
-"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
-"layout (std140) uniform ub_world_lighting\n"
-"{\n"
-" vec4 g_cube_min;\n"
-" vec4 g_cube_inv_range;\n"
-"\n"
-" vec4 g_water_plane;\n"
-" vec4 g_depth_bounds;\n"
-"\n"
-" vec4 g_daysky_colour;\n"
-" vec4 g_nightsky_colour;\n"
-" vec4 g_sunset_colour;\n"
-" vec4 g_ambient_colour;\n"
-" vec4 g_sunset_ambient;\n"
-" vec4 g_sun_colour;\n"
-" vec4 g_sun_dir;\n"
-" vec4 g_board_0;\n"
-" vec4 g_board_1;\n"
-"\n"
-" float g_water_fog;\n"
-" float g_time;\n"
-" float g_realtime;\n"
-" float g_shadow_length;\n"
-" float g_shadow_spread;\n"
-"\n"
-" float g_time_of_day;\n"
-" float g_day_phase;\n"
-" float g_sunset_phase;\n"
-"\n"
-" int g_light_preview;\n"
-" int g_shadow_samples;\n"
-"\n"
-" int g_debug_indices;\n"
-" int g_debug_complexity;\n"
-"};\n"
-"\n"
-"uniform sampler2D g_world_depth;\n"
-"uniform samplerBuffer uLightsArray;\n"
-"uniform usampler3D uLightsIndex;\n"
-"\n"
-"#line 1 1 \n"
-"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
-"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
-"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
-"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
-"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
-"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
-"\n"
-"const float SUN_ANGLE = 0.0001;\n"
-"const float PI = 3.14159265358979323846264;\n"
-"\n"
-"//struct world_info\n"
-"//{\n"
-"// float time,\n"
-"// time_of_day,\n"
-"// day_phase,\n"
-"// sunset_phase;\n"
-"// \n"
-"// vec3 sun_dir;\n"
-"//};\n"
-"\n"
-"vec3 rand33(vec3 p3)\n"
-"{\n"
-" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
-" p3 += dot(p3, p3.yxz+33.33);\n"
-" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
-"}\n"
-"\n"
-"float stars( vec3 rd, float rr, float size ){\n"
-" vec3 co = rd * rr;\n"
-"\n"
-" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
-"\n"
-" float spaces = 1.0 / rr;\n"
-" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
-" a -= mod(a, spaces) - spaces * 0.5;\n"
-"\n"
-" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
-" \n"
-" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
-" plane = plane - mod(plane, PI / count);\n"
-"\n"
-" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
-"\n"
-" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
-" float ydist = sqrt(rr * rr - level * level);\n"
-" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
-" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
-" float star = smoothstep(size, 0.0, distance(center, co));\n"
-" return star;\n"
-"}\n"
-"\n"
-"float luminance( vec3 v )\n"
-"{\n"
-" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
-"}\n"
-"\n"
-"vec3 clearskies_ambient( vec3 dir )\n"
-"{\n"
-" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
-" float sky_gradient = dir.y;\n"
-" \n"
-" /* Blend phase colours */\n"
-" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
-" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
-" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
-" \n"
-" /* Add gradient */\n"
-" ambient -= sky_gradient * luminance(ambient);\n"
-" \n"
-" return ambient;\n"
-"}\n"
-"\n"
-"vec3 clearskies_sky( vec3 ray_dir )\n"
-"{\n"
-" ray_dir.y = abs( ray_dir.y );\n"
-" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
-" \n"
-" /* Sun */\n"
-" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
-" float sun_shape = pow( sun_size, 2000.0 );\n"
-" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" \n"
-" float star = 0.0;\n"
-" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
-"\n"
-" if( star_blend > 0.001 ){\n"
-" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
-" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
-" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
-" }\n"
-" }\n"
-" \n"
-" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
-" return composite;\n"
-"}\n"
-"\n"
-"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
-"{\n"
-" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
-"\n"
-" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
-" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
-" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
-" ) * g_sun_colour.rgb * g_day_phase;\n"
-"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
-" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" return ambient + (light_sun + sky_reflection) * shadow;\n"
-"}\n"
-"\n"
-"#line 44 0 \n"
-"\n"
-"float world_depth_sample( vec3 pos )\n"
-"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
-" return texture( g_world_depth, depth_coord ).r;\n"
-"}\n"
-"\n"
-"float world_water_depth( vec3 pos )\n"
-"{\n"
-" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return world_depth_sample( pos ) - ref_depth;\n"
-"}\n"
-"\n"
-"float shadow_sample( vec3 co ){\n"
-" float height_sample = world_depth_sample( co );\n"
-"\n"
-" float fdelta = height_sample - co.y;\n"
-" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
-"}\n"
-"\n"
-"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
-" if( g_shadow_samples == 0 ){\n"
-" return 1.0;\n"
-" }\n"
-"\n"
-" float fspread = g_shadow_spread;\n"
-" float flength = g_shadow_length;\n"
-"\n"
-" float famt = 0.0;\n"
-" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
-"\n"
-" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
-"\n"
-" return 1.0 - famt;\n"
-"}\n"
-"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
-"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
-"}\n"
-"\n"
-"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
-" float dist = pow(fdist*0.0010,0.78);\n"
-" return mix( vfrag, colour, min( 1.0, dist ) );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_light( int light_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
-" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
-" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
-"\n"
-" vec3 light_delta = light_co.xyz-co;\n"
-" float dist2 = dot(light_delta,light_delta);\n"
-"\n"
-" light_delta = normalize( light_delta );\n"
-"\n"
-" float quadratic = dist2*100.0;\n"
-" float attenuation = 1.0/( 1.0 + quadratic );\n"
-" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
-"\n"
-" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
-"\n"
-" if( light_dir.w < 0.999999 ){\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
-" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
-" }\n"
-"\n"
-" return light_colour.rgb * attenuation * falloff \n"
-" * step( g_day_phase, light_colour.w );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" uint light_count = packed_index & 0x3u;\n"
-"\n"
-" vec3 l = vec3(0.0);\n"
-"\n"
-" if( light_count >= 1u ){\n"
-" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
-" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
-" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
-"\n"
-" l += scene_calculate_light( index_0, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 2u ){\n"
-" l += scene_calculate_light( index_1, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 3u ){\n"
-" l += scene_calculate_light( index_2, halfview, co, normal );\n"
-" }\n"
-" }\n"
-" }\n"
-"\n"
-" return l;\n"
-"}\n"
-"\n"
-"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
-" float light_mask )\n"
-"{\n"
-" if( g_light_preview == 1 )\n"
-" diffuse = vec3(0.75);\n"
-"\n"
-" // Lighting\n"
-" vec3 halfview = uCamera - co;\n"
-" float fdist = length(halfview);\n"
-" halfview /= fdist;\n"
-"\n"
-" float world_shadow = newlight_compute_sun_shadow( \n"
-" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
-"\n"
-" vec3 total_light = clearskies_lighting( \n"
-" normal, min( light_mask, world_shadow ), halfview );\n"
-"\n"
-" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
-" cube_coord = floor( cube_coord );\n"
-"\n"
-" if( g_debug_indices == 1 )\n"
-" {\n"
-" return rand33(cube_coord);\n"
-" }\n"
-"\n"
-" if( g_debug_complexity == 1 )\n"
-" {\n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
-" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
-" }\n"
-"\n"
-" // FIXME: this coord should absolutely must be clamped!\n"
-" \n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, co, normal ) \n"
-" * light_mask;\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, co, normal )\n"
-" * light_mask;\n"
-"\n"
-" // Take a section of the sky function to give us a matching fog colour\n"
-"\n"
-" vec3 fog_colour = clearskies_ambient( -halfview );\n"
-" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
-" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" fog_colour += sun_colour;\n"
-" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"\n"
-"float sdLine( vec3 p, vec3 a, vec3 b )\n"
-"{\n"
-" vec3 pa = p - a;\n"
-" vec3 ba = b - a;\n"
-"\n"
-" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
-" return length( pa - ba*h );\n"
-"}\n"
-"\n"
-"float compute_board_shadow()\n"
-"{\n"
-" // player shadow\n"
-" float dist_to_player = max( 0.0, sdLine( aWorldCo, g_board_0.xyz,\n"
-" g_board_1.xyz )-0.1 );\n"
-" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
-" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
-"\n"
-" return 1.0 - player_shadow*0.8;\n"
-"}\n"
-"\n"
-"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
-"{\n"
-" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
-"}\n"
-"\n"
-"#line 8 0 \n"
-"#line 1 3 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"layout (location = 1) out vec2 oMotionVec;\n"
-"\n"
-"in vec3 aMotionVec0;\n"
-"in vec3 aMotionVec1;\n"
-"\n"
-"void compute_motion_vectors()\n"
-"{\n"
-" // Write motion vectors\n"
-" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
-" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
-"\n"
-" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"\n"
-"void main()\n"
-"{\n"
-" compute_motion_vectors();\n"
-"\n"
-" vec3 vfrag = vec3(0.5,0.5,0.5);\n"
-" vec4 vsamplemain = texture( uTexMain, aUv );\n"
-" vec3 qnorm = aNorm.xyz;\n"
-"\n"
-" if( vsamplemain.a < 0.15 )\n"
-" discard;\n"
-"\n"
-" vfrag = vsamplemain.rgb;\n"
-"\n"
-" if( g_light_preview == 1 )\n"
-" {\n"
-" vfrag = vec3(0.5);\n"
-" }\n"
-"\n"
-" vfrag = scene_compute_lighting( vfrag, qnorm, aWorldCo );\n"
-" oColour = vec4(vfrag, 1.0);\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_scene_standard_alphatest_uMdl;
-static GLuint _uniform_scene_standard_alphatest_uPv;
-static GLuint _uniform_scene_standard_alphatest_uPvmPrev;
-static GLuint _uniform_scene_standard_alphatest_uTexGarbage;
-static GLuint _uniform_scene_standard_alphatest_uTexMain;
-static GLuint _uniform_scene_standard_alphatest_uCamera;
-static GLuint _uniform_scene_standard_alphatest_uPlane;
-static GLuint _uniform_scene_standard_alphatest_g_world_depth;
-static GLuint _uniform_scene_standard_alphatest_uLightsArray;
-static GLuint _uniform_scene_standard_alphatest_uLightsIndex;
-static void shader_scene_standard_alphatest_uMdl(m4x3f m){
- glUniformMatrix4x3fv(_uniform_scene_standard_alphatest_uMdl,1,GL_FALSE,(float*)m);
+ glUniformMatrix4x3fv(_uniform_scene_standard_alphatest_uMdl,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_standard_alphatest_uPv(m4x4f m){
- glUniformMatrix4fv(_uniform_scene_standard_alphatest_uPv,1,GL_FALSE,(float*)m);
+static inline void shader_scene_standard_alphatest_uPv(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_scene_standard_alphatest_uPv,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_standard_alphatest_uPvmPrev(m4x4f m){
- glUniformMatrix4fv(_uniform_scene_standard_alphatest_uPvmPrev,1,GL_FALSE,(float*)m);
+static inline void shader_scene_standard_alphatest_uPvmPrev(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_scene_standard_alphatest_uPvmPrev,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_standard_alphatest_uTexGarbage(int i){
+static inline void shader_scene_standard_alphatest_uTexGarbage(int i)
+{
glUniform1i(_uniform_scene_standard_alphatest_uTexGarbage,i);
}
-static void shader_scene_standard_alphatest_uTexMain(int i){
+static inline void shader_scene_standard_alphatest_uTexMain(int i)
+{
glUniform1i(_uniform_scene_standard_alphatest_uTexMain,i);
}
-static void shader_scene_standard_alphatest_uCamera(v3f v){
+static inline void shader_scene_standard_alphatest_uCamera(v3f v)
+{
glUniform3fv(_uniform_scene_standard_alphatest_uCamera,1,v);
}
-static void shader_scene_standard_alphatest_uPlane(v4f v){
+static inline void shader_scene_standard_alphatest_uPlane(v4f v)
+{
glUniform4fv(_uniform_scene_standard_alphatest_uPlane,1,v);
}
-static void shader_scene_standard_alphatest_g_world_depth(int i){
+static inline void shader_scene_standard_alphatest_g_world_depth(int i)
+{
glUniform1i(_uniform_scene_standard_alphatest_g_world_depth,i);
}
-static void shader_scene_standard_alphatest_register(void){
- vg_shader_register( &_shader_scene_standard_alphatest );
-}
-static void shader_scene_standard_alphatest_use(void){ glUseProgram(_shader_scene_standard_alphatest.id); }
-static void shader_scene_standard_alphatest_link(void){
- _uniform_scene_standard_alphatest_uMdl = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uMdl" );
- _uniform_scene_standard_alphatest_uPv = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uPv" );
- _uniform_scene_standard_alphatest_uPvmPrev = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uPvmPrev" );
- _uniform_scene_standard_alphatest_uTexGarbage = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uTexGarbage" );
- _uniform_scene_standard_alphatest_uTexMain = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uTexMain" );
- _uniform_scene_standard_alphatest_uCamera = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uCamera" );
- _uniform_scene_standard_alphatest_uPlane = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uPlane" );
- _uniform_scene_standard_alphatest_g_world_depth = glGetUniformLocation( _shader_scene_standard_alphatest.id, "g_world_depth" );
- _uniform_scene_standard_alphatest_uLightsArray = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uLightsArray" );
- _uniform_scene_standard_alphatest_uLightsIndex = glGetUniformLocation( _shader_scene_standard_alphatest.id, "uLightsIndex" );
+static inline void shader_scene_standard_alphatest_use(void);
+static inline void shader_scene_standard_alphatest_use(void)
+{
+ glUseProgram(_shader_scene_standard_alphatest.id);
}
-#endif /* SHADER_scene_standard_alphatest_H */
-#ifndef SHADER_scene_terrain_H
-#define SHADER_scene_terrain_H
-static void shader_scene_terrain_link(void);
-static void shader_scene_terrain_register(void);
-static struct vg_shader _shader_scene_terrain = {
- .name = "scene_terrain",
- .link = shader_scene_terrain_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_scene_terrain;
+extern GLuint _uniform_scene_terrain_uMdl;
+extern GLuint _uniform_scene_terrain_uPv;
+extern GLuint _uniform_scene_terrain_uPvmPrev;
+extern GLuint _uniform_scene_terrain_uTexGarbage;
+extern GLuint _uniform_scene_terrain_uTexGradients;
+extern GLuint _uniform_scene_terrain_uCamera;
+extern GLuint _uniform_scene_terrain_uSandColour;
+extern GLuint _uniform_scene_terrain_uBlendOffset;
+extern GLuint _uniform_scene_terrain_g_world_depth;
+extern GLuint _uniform_scene_terrain_uLightsArray;
+extern GLuint _uniform_scene_terrain_uLightsIndex;
+static inline void shader_scene_terrain_uMdl(m4x3f m)
{
-.orig_file = "shaders/scene.vs",
-.static_src =
-"layout (location=0) in vec3 a_co;\n"
-"layout (location=1) in vec4 a_norm;\n"
-"layout (location=2) in vec2 a_uv;\n"
-"\n"
-"#line 1 1 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"out vec3 aMotionVec0;\n"
-"out vec3 aMotionVec1;\n"
-"\n"
-"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
-"{\n"
-" // This magically solves some artifacting errors!\n"
-" //\n"
-" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
-"\n"
-" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
-" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
-"}\n"
-"\n"
-"#line 6 0 \n"
-"\n"
-"uniform mat4x3 uMdl;\n"
-"uniform mat4 uPv;\n"
-"uniform mat4 uPvmPrev;\n"
-"\n"
-"out vec2 aUv;\n"
-"out vec4 aNorm;\n"
-"out vec3 aCo;\n"
-"out vec3 aWorldCo;\n"
-"\n"
-"void main()\n"
-"{\n"
-" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
-" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
-" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
-"\n"
-" vs_motion_out( vproj0, vproj1 );\n"
-"\n"
-" gl_Position = vproj0;\n"
-"\n"
-" aUv = a_uv;\n"
-" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
-" aCo = a_co;\n"
-" aWorldCo = world_pos0;\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/scene_terrain.fs",
-.static_src =
-"uniform sampler2D uTexGarbage;\n"
-"uniform sampler2D uTexGradients;\n"
-"uniform vec3 uCamera;\n"
-"uniform vec3 uSandColour;\n"
-"uniform vec2 uBlendOffset;\n"
-"\n"
-"#line 1 1 \n"
-"// :D\n"
-"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
-"\n"
-"#line 8 0 \n"
-"#line 1 2 \n"
-"// :D\n"
-"\n"
-"in vec2 aUv;\n"
-"in vec4 aNorm;\n"
-"in vec3 aCo;\n"
-"in vec3 aWorldCo;\n"
-"\n"
-"#line 1 1 \n"
-"layout (location = 0) out vec4 oColour;\n"
-"\n"
-"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
-"layout (std140) uniform ub_world_lighting\n"
-"{\n"
-" vec4 g_cube_min;\n"
-" vec4 g_cube_inv_range;\n"
-"\n"
-" vec4 g_water_plane;\n"
-" vec4 g_depth_bounds;\n"
-"\n"
-" vec4 g_daysky_colour;\n"
-" vec4 g_nightsky_colour;\n"
-" vec4 g_sunset_colour;\n"
-" vec4 g_ambient_colour;\n"
-" vec4 g_sunset_ambient;\n"
-" vec4 g_sun_colour;\n"
-" vec4 g_sun_dir;\n"
-" vec4 g_board_0;\n"
-" vec4 g_board_1;\n"
-"\n"
-" float g_water_fog;\n"
-" float g_time;\n"
-" float g_realtime;\n"
-" float g_shadow_length;\n"
-" float g_shadow_spread;\n"
-"\n"
-" float g_time_of_day;\n"
-" float g_day_phase;\n"
-" float g_sunset_phase;\n"
-"\n"
-" int g_light_preview;\n"
-" int g_shadow_samples;\n"
-"\n"
-" int g_debug_indices;\n"
-" int g_debug_complexity;\n"
-"};\n"
-"\n"
-"uniform sampler2D g_world_depth;\n"
-"uniform samplerBuffer uLightsArray;\n"
-"uniform usampler3D uLightsIndex;\n"
-"\n"
-"#line 1 1 \n"
-"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
-"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
-"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
-"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
-"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
-"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
-"\n"
-"const float SUN_ANGLE = 0.0001;\n"
-"const float PI = 3.14159265358979323846264;\n"
-"\n"
-"//struct world_info\n"
-"//{\n"
-"// float time,\n"
-"// time_of_day,\n"
-"// day_phase,\n"
-"// sunset_phase;\n"
-"// \n"
-"// vec3 sun_dir;\n"
-"//};\n"
-"\n"
-"vec3 rand33(vec3 p3)\n"
-"{\n"
-" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
-" p3 += dot(p3, p3.yxz+33.33);\n"
-" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
-"}\n"
-"\n"
-"float stars( vec3 rd, float rr, float size ){\n"
-" vec3 co = rd * rr;\n"
-"\n"
-" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
-"\n"
-" float spaces = 1.0 / rr;\n"
-" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
-" a -= mod(a, spaces) - spaces * 0.5;\n"
-"\n"
-" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
-" \n"
-" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
-" plane = plane - mod(plane, PI / count);\n"
-"\n"
-" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
-"\n"
-" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
-" float ydist = sqrt(rr * rr - level * level);\n"
-" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
-" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
-" float star = smoothstep(size, 0.0, distance(center, co));\n"
-" return star;\n"
-"}\n"
-"\n"
-"float luminance( vec3 v )\n"
-"{\n"
-" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
-"}\n"
-"\n"
-"vec3 clearskies_ambient( vec3 dir )\n"
-"{\n"
-" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
-" float sky_gradient = dir.y;\n"
-" \n"
-" /* Blend phase colours */\n"
-" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
-" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
-" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
-" \n"
-" /* Add gradient */\n"
-" ambient -= sky_gradient * luminance(ambient);\n"
-" \n"
-" return ambient;\n"
-"}\n"
-"\n"
-"vec3 clearskies_sky( vec3 ray_dir )\n"
-"{\n"
-" ray_dir.y = abs( ray_dir.y );\n"
-" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
-" \n"
-" /* Sun */\n"
-" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
-" float sun_shape = pow( sun_size, 2000.0 );\n"
-" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" \n"
-" float star = 0.0;\n"
-" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
-"\n"
-" if( star_blend > 0.001 ){\n"
-" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
-" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
-" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
-" }\n"
-" }\n"
-" \n"
-" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
-" return composite;\n"
-"}\n"
-"\n"
-"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
-"{\n"
-" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
-"\n"
-" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
-" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
-" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
-" ) * g_sun_colour.rgb * g_day_phase;\n"
-"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
-" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" return ambient + (light_sun + sky_reflection) * shadow;\n"
-"}\n"
-"\n"
-"#line 44 0 \n"
-"\n"
-"float world_depth_sample( vec3 pos )\n"
-"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
-" return texture( g_world_depth, depth_coord ).r;\n"
-"}\n"
-"\n"
-"float world_water_depth( vec3 pos )\n"
-"{\n"
-" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return world_depth_sample( pos ) - ref_depth;\n"
-"}\n"
-"\n"
-"float shadow_sample( vec3 co ){\n"
-" float height_sample = world_depth_sample( co );\n"
-"\n"
-" float fdelta = height_sample - co.y;\n"
-" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
-"}\n"
-"\n"
-"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
-" if( g_shadow_samples == 0 ){\n"
-" return 1.0;\n"
-" }\n"
-"\n"
-" float fspread = g_shadow_spread;\n"
-" float flength = g_shadow_length;\n"
-"\n"
-" float famt = 0.0;\n"
-" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
-"\n"
-" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
-"\n"
-" return 1.0 - famt;\n"
-"}\n"
-"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
-"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
-"}\n"
-"\n"
-"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
-" float dist = pow(fdist*0.0010,0.78);\n"
-" return mix( vfrag, colour, min( 1.0, dist ) );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_light( int light_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
-" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
-" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
-"\n"
-" vec3 light_delta = light_co.xyz-co;\n"
-" float dist2 = dot(light_delta,light_delta);\n"
-"\n"
-" light_delta = normalize( light_delta );\n"
-"\n"
-" float quadratic = dist2*100.0;\n"
-" float attenuation = 1.0/( 1.0 + quadratic );\n"
-" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
-"\n"
-" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
-"\n"
-" if( light_dir.w < 0.999999 ){\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
-" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
-" }\n"
-"\n"
-" return light_colour.rgb * attenuation * falloff \n"
-" * step( g_day_phase, light_colour.w );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" uint light_count = packed_index & 0x3u;\n"
-"\n"
-" vec3 l = vec3(0.0);\n"
-"\n"
-" if( light_count >= 1u ){\n"
-" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
-" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
-" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
-"\n"
-" l += scene_calculate_light( index_0, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 2u ){\n"
-" l += scene_calculate_light( index_1, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 3u ){\n"
-" l += scene_calculate_light( index_2, halfview, co, normal );\n"
-" }\n"
-" }\n"
-" }\n"
-"\n"
-" return l;\n"
-"}\n"
-"\n"
-"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
-" float light_mask )\n"
-"{\n"
-" if( g_light_preview == 1 )\n"
-" diffuse = vec3(0.75);\n"
-"\n"
-" // Lighting\n"
-" vec3 halfview = uCamera - co;\n"
-" float fdist = length(halfview);\n"
-" halfview /= fdist;\n"
-"\n"
-" float world_shadow = newlight_compute_sun_shadow( \n"
-" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
-"\n"
-" vec3 total_light = clearskies_lighting( \n"
-" normal, min( light_mask, world_shadow ), halfview );\n"
-"\n"
-" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
-" cube_coord = floor( cube_coord );\n"
-"\n"
-" if( g_debug_indices == 1 )\n"
-" {\n"
-" return rand33(cube_coord);\n"
-" }\n"
-"\n"
-" if( g_debug_complexity == 1 )\n"
-" {\n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
-" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
-" }\n"
-"\n"
-" // FIXME: this coord should absolutely must be clamped!\n"
-" \n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, co, normal ) \n"
-" * light_mask;\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, co, normal )\n"
-" * light_mask;\n"
-"\n"
-" // Take a section of the sky function to give us a matching fog colour\n"
-"\n"
-" vec3 fog_colour = clearskies_ambient( -halfview );\n"
-" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
-" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" fog_colour += sun_colour;\n"
-" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"\n"
-"float sdLine( vec3 p, vec3 a, vec3 b )\n"
-"{\n"
-" vec3 pa = p - a;\n"
-" vec3 ba = b - a;\n"
-"\n"
-" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
-" return length( pa - ba*h );\n"
-"}\n"
-"\n"
-"float compute_board_shadow()\n"
-"{\n"
-" // player shadow\n"
-" float dist_to_player = max( 0.0, sdLine( aWorldCo, g_board_0.xyz,\n"
-" g_board_1.xyz )-0.1 );\n"
-" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
-" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
-"\n"
-" return 1.0 - player_shadow*0.8;\n"
-"}\n"
-"\n"
-"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
-"{\n"
-" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"#line 1 3 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"layout (location = 1) out vec2 oMotionVec;\n"
-"\n"
-"in vec3 aMotionVec0;\n"
-"in vec3 aMotionVec1;\n"
-"\n"
-"void compute_motion_vectors()\n"
-"{\n"
-" // Write motion vectors\n"
-" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
-" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
-"\n"
-" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
-"}\n"
-"\n"
-"#line 10 0 \n"
-"\n"
-"void main()\n"
-"{\n"
-" compute_motion_vectors();\n"
-"\n"
-" // Colour\n"
-" // ------\n"
-" vec3 vfrag = vec3(0.5,0.5,0.5);\n"
-"\n"
-" // ws modulation\n"
-" vec4 wgarbage = texture( uTexGarbage, aCo.xz * 0.015 );\n"
-" \n"
-" // Creating normal patches\n"
-" vec3 modnorm = (wgarbage.rgb-0.4) * 1.4;\n"
-" vec3 qnorm = normalize(floor(aNorm.xyz*4.0+modnorm)*0.25);\n"
-" qnorm += vec3(0.001,0.0,0.0);\n"
-"\n"
-" vec2 dir = normalize(qnorm.xz);\n"
-" vec2 uvdiffuse = aCo.xz * 0.02;\n"
-" uvdiffuse = mat2(dir.y, dir.x, -dir.x, dir.y) * uvdiffuse;\n"
-" \n"
-" // Patch local noise\n"
-" vec4 rgarbage = texture( uTexGarbage, uvdiffuse );\n"
-"\n"
-" // Colour blending\n"
-" float amtgrass = step(qnorm.y,0.6);\n"
-" float amtsand = min(max((aCo.y - 10.0) * -0.1,0.0)*qnorm.y,1.0);\n"
-" vec2 uvgradients = aUv + vec2( amtgrass + rgarbage.a*0.8 )*uBlendOffset;\n"
-" vfrag = texture( uTexGradients, uvgradients ).rgb;\n"
-" vfrag = mix( vfrag, uSandColour, amtsand );\n"
-"\n"
-" qnorm = mix( qnorm, aNorm.xyz, amtsand );\n"
-" \n"
-" if( g_light_preview == 1 )\n"
-" {\n"
-" vfrag = vec3(0.5);\n"
-" }\n"
-"\n"
-" vfrag = scene_compute_lighting( vfrag, qnorm, aWorldCo );\n"
-" oColour = vec4(vfrag, 1.0);\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_scene_terrain_uMdl;
-static GLuint _uniform_scene_terrain_uPv;
-static GLuint _uniform_scene_terrain_uPvmPrev;
-static GLuint _uniform_scene_terrain_uTexGarbage;
-static GLuint _uniform_scene_terrain_uTexGradients;
-static GLuint _uniform_scene_terrain_uCamera;
-static GLuint _uniform_scene_terrain_uSandColour;
-static GLuint _uniform_scene_terrain_uBlendOffset;
-static GLuint _uniform_scene_terrain_g_world_depth;
-static GLuint _uniform_scene_terrain_uLightsArray;
-static GLuint _uniform_scene_terrain_uLightsIndex;
-static void shader_scene_terrain_uMdl(m4x3f m){
- glUniformMatrix4x3fv(_uniform_scene_terrain_uMdl,1,GL_FALSE,(float*)m);
+ glUniformMatrix4x3fv(_uniform_scene_terrain_uMdl,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_terrain_uPv(m4x4f m){
- glUniformMatrix4fv(_uniform_scene_terrain_uPv,1,GL_FALSE,(float*)m);
+static inline void shader_scene_terrain_uPv(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_scene_terrain_uPv,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_terrain_uPvmPrev(m4x4f m){
- glUniformMatrix4fv(_uniform_scene_terrain_uPvmPrev,1,GL_FALSE,(float*)m);
+static inline void shader_scene_terrain_uPvmPrev(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_scene_terrain_uPvmPrev,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_terrain_uTexGarbage(int i){
+static inline void shader_scene_terrain_uTexGarbage(int i)
+{
glUniform1i(_uniform_scene_terrain_uTexGarbage,i);
}
-static void shader_scene_terrain_uTexGradients(int i){
+static inline void shader_scene_terrain_uTexGradients(int i)
+{
glUniform1i(_uniform_scene_terrain_uTexGradients,i);
}
-static void shader_scene_terrain_uCamera(v3f v){
+static inline void shader_scene_terrain_uCamera(v3f v)
+{
glUniform3fv(_uniform_scene_terrain_uCamera,1,v);
}
-static void shader_scene_terrain_uSandColour(v3f v){
+static inline void shader_scene_terrain_uSandColour(v3f v)
+{
glUniform3fv(_uniform_scene_terrain_uSandColour,1,v);
}
-static void shader_scene_terrain_uBlendOffset(v2f v){
+static inline void shader_scene_terrain_uBlendOffset(v2f v)
+{
glUniform2fv(_uniform_scene_terrain_uBlendOffset,1,v);
}
-static void shader_scene_terrain_g_world_depth(int i){
+static inline void shader_scene_terrain_g_world_depth(int i)
+{
glUniform1i(_uniform_scene_terrain_g_world_depth,i);
}
-static void shader_scene_terrain_register(void){
- vg_shader_register( &_shader_scene_terrain );
-}
-static void shader_scene_terrain_use(void){ glUseProgram(_shader_scene_terrain.id); }
-static void shader_scene_terrain_link(void){
- _uniform_scene_terrain_uMdl = glGetUniformLocation( _shader_scene_terrain.id, "uMdl" );
- _uniform_scene_terrain_uPv = glGetUniformLocation( _shader_scene_terrain.id, "uPv" );
- _uniform_scene_terrain_uPvmPrev = glGetUniformLocation( _shader_scene_terrain.id, "uPvmPrev" );
- _uniform_scene_terrain_uTexGarbage = glGetUniformLocation( _shader_scene_terrain.id, "uTexGarbage" );
- _uniform_scene_terrain_uTexGradients = glGetUniformLocation( _shader_scene_terrain.id, "uTexGradients" );
- _uniform_scene_terrain_uCamera = glGetUniformLocation( _shader_scene_terrain.id, "uCamera" );
- _uniform_scene_terrain_uSandColour = glGetUniformLocation( _shader_scene_terrain.id, "uSandColour" );
- _uniform_scene_terrain_uBlendOffset = glGetUniformLocation( _shader_scene_terrain.id, "uBlendOffset" );
- _uniform_scene_terrain_g_world_depth = glGetUniformLocation( _shader_scene_terrain.id, "g_world_depth" );
- _uniform_scene_terrain_uLightsArray = glGetUniformLocation( _shader_scene_terrain.id, "uLightsArray" );
- _uniform_scene_terrain_uLightsIndex = glGetUniformLocation( _shader_scene_terrain.id, "uLightsIndex" );
+static inline void shader_scene_terrain_use(void);
+static inline void shader_scene_terrain_use(void)
+{
+ glUseProgram(_shader_scene_terrain.id);
}
-#endif /* SHADER_scene_terrain_H */
-#ifndef SHADER_scene_vertex_blend_H
-#define SHADER_scene_vertex_blend_H
-static void shader_scene_vertex_blend_link(void);
-static void shader_scene_vertex_blend_register(void);
-static struct vg_shader _shader_scene_vertex_blend = {
- .name = "scene_vertex_blend",
- .link = shader_scene_vertex_blend_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_scene_vertex_blend;
+extern GLuint _uniform_scene_vertex_blend_uMdl;
+extern GLuint _uniform_scene_vertex_blend_uPv;
+extern GLuint _uniform_scene_vertex_blend_uPvmPrev;
+extern GLuint _uniform_scene_vertex_blend_uTexGarbage;
+extern GLuint _uniform_scene_vertex_blend_uTexGradients;
+extern GLuint _uniform_scene_vertex_blend_uCamera;
+extern GLuint _uniform_scene_vertex_blend_g_world_depth;
+extern GLuint _uniform_scene_vertex_blend_uLightsArray;
+extern GLuint _uniform_scene_vertex_blend_uLightsIndex;
+static inline void shader_scene_vertex_blend_uMdl(m4x3f m)
{
-.orig_file = "shaders/scene.vs",
-.static_src =
-"layout (location=0) in vec3 a_co;\n"
-"layout (location=1) in vec4 a_norm;\n"
-"layout (location=2) in vec2 a_uv;\n"
-"\n"
-"#line 1 1 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"out vec3 aMotionVec0;\n"
-"out vec3 aMotionVec1;\n"
-"\n"
-"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
-"{\n"
-" // This magically solves some artifacting errors!\n"
-" //\n"
-" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
-"\n"
-" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
-" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
-"}\n"
-"\n"
-"#line 6 0 \n"
-"\n"
-"uniform mat4x3 uMdl;\n"
-"uniform mat4 uPv;\n"
-"uniform mat4 uPvmPrev;\n"
-"\n"
-"out vec2 aUv;\n"
-"out vec4 aNorm;\n"
-"out vec3 aCo;\n"
-"out vec3 aWorldCo;\n"
-"\n"
-"void main()\n"
-"{\n"
-" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
-" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
-" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
-"\n"
-" vs_motion_out( vproj0, vproj1 );\n"
-"\n"
-" gl_Position = vproj0;\n"
-"\n"
-" aUv = a_uv;\n"
-" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
-" aCo = a_co;\n"
-" aWorldCo = world_pos0;\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/scene_vertex_blend.fs",
-.static_src =
-"uniform sampler2D uTexGarbage;\n"
-"uniform sampler2D uTexGradients;\n"
-"uniform vec3 uCamera;\n"
-"\n"
-"#line 1 1 \n"
-"// :D\n"
-"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
-"\n"
-"#line 6 0 \n"
-"#line 1 2 \n"
-"// :D\n"
-"\n"
-"in vec2 aUv;\n"
-"in vec4 aNorm;\n"
-"in vec3 aCo;\n"
-"in vec3 aWorldCo;\n"
-"\n"
-"#line 1 1 \n"
-"layout (location = 0) out vec4 oColour;\n"
-"\n"
-"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
-"layout (std140) uniform ub_world_lighting\n"
-"{\n"
-" vec4 g_cube_min;\n"
-" vec4 g_cube_inv_range;\n"
-"\n"
-" vec4 g_water_plane;\n"
-" vec4 g_depth_bounds;\n"
-"\n"
-" vec4 g_daysky_colour;\n"
-" vec4 g_nightsky_colour;\n"
-" vec4 g_sunset_colour;\n"
-" vec4 g_ambient_colour;\n"
-" vec4 g_sunset_ambient;\n"
-" vec4 g_sun_colour;\n"
-" vec4 g_sun_dir;\n"
-" vec4 g_board_0;\n"
-" vec4 g_board_1;\n"
-"\n"
-" float g_water_fog;\n"
-" float g_time;\n"
-" float g_realtime;\n"
-" float g_shadow_length;\n"
-" float g_shadow_spread;\n"
-"\n"
-" float g_time_of_day;\n"
-" float g_day_phase;\n"
-" float g_sunset_phase;\n"
-"\n"
-" int g_light_preview;\n"
-" int g_shadow_samples;\n"
-"\n"
-" int g_debug_indices;\n"
-" int g_debug_complexity;\n"
-"};\n"
-"\n"
-"uniform sampler2D g_world_depth;\n"
-"uniform samplerBuffer uLightsArray;\n"
-"uniform usampler3D uLightsIndex;\n"
-"\n"
-"#line 1 1 \n"
-"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
-"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
-"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
-"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
-"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
-"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
-"\n"
-"const float SUN_ANGLE = 0.0001;\n"
-"const float PI = 3.14159265358979323846264;\n"
-"\n"
-"//struct world_info\n"
-"//{\n"
-"// float time,\n"
-"// time_of_day,\n"
-"// day_phase,\n"
-"// sunset_phase;\n"
-"// \n"
-"// vec3 sun_dir;\n"
-"//};\n"
-"\n"
-"vec3 rand33(vec3 p3)\n"
-"{\n"
-" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
-" p3 += dot(p3, p3.yxz+33.33);\n"
-" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
-"}\n"
-"\n"
-"float stars( vec3 rd, float rr, float size ){\n"
-" vec3 co = rd * rr;\n"
-"\n"
-" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
-"\n"
-" float spaces = 1.0 / rr;\n"
-" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
-" a -= mod(a, spaces) - spaces * 0.5;\n"
-"\n"
-" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
-" \n"
-" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
-" plane = plane - mod(plane, PI / count);\n"
-"\n"
-" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
-"\n"
-" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
-" float ydist = sqrt(rr * rr - level * level);\n"
-" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
-" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
-" float star = smoothstep(size, 0.0, distance(center, co));\n"
-" return star;\n"
-"}\n"
-"\n"
-"float luminance( vec3 v )\n"
-"{\n"
-" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
-"}\n"
-"\n"
-"vec3 clearskies_ambient( vec3 dir )\n"
-"{\n"
-" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
-" float sky_gradient = dir.y;\n"
-" \n"
-" /* Blend phase colours */\n"
-" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
-" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
-" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
-" \n"
-" /* Add gradient */\n"
-" ambient -= sky_gradient * luminance(ambient);\n"
-" \n"
-" return ambient;\n"
-"}\n"
-"\n"
-"vec3 clearskies_sky( vec3 ray_dir )\n"
-"{\n"
-" ray_dir.y = abs( ray_dir.y );\n"
-" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
-" \n"
-" /* Sun */\n"
-" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
-" float sun_shape = pow( sun_size, 2000.0 );\n"
-" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" \n"
-" float star = 0.0;\n"
-" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
-"\n"
-" if( star_blend > 0.001 ){\n"
-" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
-" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
-" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
-" }\n"
-" }\n"
-" \n"
-" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
-" return composite;\n"
-"}\n"
-"\n"
-"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
-"{\n"
-" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
-"\n"
-" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
-" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
-" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
-" ) * g_sun_colour.rgb * g_day_phase;\n"
-"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
-" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" return ambient + (light_sun + sky_reflection) * shadow;\n"
-"}\n"
-"\n"
-"#line 44 0 \n"
-"\n"
-"float world_depth_sample( vec3 pos )\n"
-"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
-" return texture( g_world_depth, depth_coord ).r;\n"
-"}\n"
-"\n"
-"float world_water_depth( vec3 pos )\n"
-"{\n"
-" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return world_depth_sample( pos ) - ref_depth;\n"
-"}\n"
-"\n"
-"float shadow_sample( vec3 co ){\n"
-" float height_sample = world_depth_sample( co );\n"
-"\n"
-" float fdelta = height_sample - co.y;\n"
-" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
-"}\n"
-"\n"
-"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
-" if( g_shadow_samples == 0 ){\n"
-" return 1.0;\n"
-" }\n"
-"\n"
-" float fspread = g_shadow_spread;\n"
-" float flength = g_shadow_length;\n"
-"\n"
-" float famt = 0.0;\n"
-" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
-"\n"
-" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
-"\n"
-" return 1.0 - famt;\n"
-"}\n"
-"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
-"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
-"}\n"
-"\n"
-"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
-" float dist = pow(fdist*0.0010,0.78);\n"
-" return mix( vfrag, colour, min( 1.0, dist ) );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_light( int light_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
-" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
-" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
-"\n"
-" vec3 light_delta = light_co.xyz-co;\n"
-" float dist2 = dot(light_delta,light_delta);\n"
-"\n"
-" light_delta = normalize( light_delta );\n"
-"\n"
-" float quadratic = dist2*100.0;\n"
-" float attenuation = 1.0/( 1.0 + quadratic );\n"
-" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
-"\n"
-" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
-"\n"
-" if( light_dir.w < 0.999999 ){\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
-" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
-" }\n"
-"\n"
-" return light_colour.rgb * attenuation * falloff \n"
-" * step( g_day_phase, light_colour.w );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" uint light_count = packed_index & 0x3u;\n"
-"\n"
-" vec3 l = vec3(0.0);\n"
-"\n"
-" if( light_count >= 1u ){\n"
-" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
-" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
-" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
-"\n"
-" l += scene_calculate_light( index_0, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 2u ){\n"
-" l += scene_calculate_light( index_1, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 3u ){\n"
-" l += scene_calculate_light( index_2, halfview, co, normal );\n"
-" }\n"
-" }\n"
-" }\n"
-"\n"
-" return l;\n"
-"}\n"
-"\n"
-"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
-" float light_mask )\n"
-"{\n"
-" if( g_light_preview == 1 )\n"
-" diffuse = vec3(0.75);\n"
-"\n"
-" // Lighting\n"
-" vec3 halfview = uCamera - co;\n"
-" float fdist = length(halfview);\n"
-" halfview /= fdist;\n"
-"\n"
-" float world_shadow = newlight_compute_sun_shadow( \n"
-" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
-"\n"
-" vec3 total_light = clearskies_lighting( \n"
-" normal, min( light_mask, world_shadow ), halfview );\n"
-"\n"
-" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
-" cube_coord = floor( cube_coord );\n"
-"\n"
-" if( g_debug_indices == 1 )\n"
-" {\n"
-" return rand33(cube_coord);\n"
-" }\n"
-"\n"
-" if( g_debug_complexity == 1 )\n"
-" {\n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
-" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
-" }\n"
-"\n"
-" // FIXME: this coord should absolutely must be clamped!\n"
-" \n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, co, normal ) \n"
-" * light_mask;\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, co, normal )\n"
-" * light_mask;\n"
-"\n"
-" // Take a section of the sky function to give us a matching fog colour\n"
-"\n"
-" vec3 fog_colour = clearskies_ambient( -halfview );\n"
-" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
-" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" fog_colour += sun_colour;\n"
-" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"\n"
-"float sdLine( vec3 p, vec3 a, vec3 b )\n"
-"{\n"
-" vec3 pa = p - a;\n"
-" vec3 ba = b - a;\n"
-"\n"
-" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
-" return length( pa - ba*h );\n"
-"}\n"
-"\n"
-"float compute_board_shadow()\n"
-"{\n"
-" // player shadow\n"
-" float dist_to_player = max( 0.0, sdLine( aWorldCo, g_board_0.xyz,\n"
-" g_board_1.xyz )-0.1 );\n"
-" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
-" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
-"\n"
-" return 1.0 - player_shadow*0.8;\n"
-"}\n"
-"\n"
-"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
-"{\n"
-" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
-"}\n"
-"\n"
-"#line 7 0 \n"
-"#line 1 3 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"layout (location = 1) out vec2 oMotionVec;\n"
-"\n"
-"in vec3 aMotionVec0;\n"
-"in vec3 aMotionVec1;\n"
-"\n"
-"void compute_motion_vectors()\n"
-"{\n"
-" // Write motion vectors\n"
-" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
-" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
-"\n"
-" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
-"}\n"
-"\n"
-"#line 8 0 \n"
-"\n"
-"void main()\n"
-"{\n"
-" compute_motion_vectors();\n"
-"\n"
-" vec3 vfrag = vec3(0.5,0.5,0.5);\n"
-"\n"
-" // ws modulation\n"
-" vec4 wgarbage = vec4(0.5,0.5,0.5,1.0);\n"
-" \n"
-" // Creating normal patches\n"
-" vec3 modnorm = (wgarbage.rgb-0.4) * 1.4;\n"
-" vec3 qnorm = normalize(floor(aNorm.xyz*4.0+modnorm)*0.25);\n"
-" qnorm += vec3(0.001,0.0,0.0);\n"
-"\n"
-" vec3 tangent0 = normalize(cross(qnorm,vec3(0.0,1.0,0.0)));\n"
-" vec3 tangent1 = cross(qnorm,tangent0);\n"
-" vec2 uvdiffuse = vec2( dot(tangent0,aCo), dot(tangent1,aCo) ) * 0.160;\n"
-" \n"
-" // Patch local noise\n"
-" vec4 rgarbage = texture( uTexGarbage, uvdiffuse );\n"
-"\n"
-" // Colour blending\n"
-" float fblendclip = step(0.380,aNorm.w + (rgarbage.r-0.5)*-1.740)*0.320;\n"
-" vec2 uvgradients = aUv + vec2( fblendclip, 0.0 );\n"
-"\n"
-" vfrag = texture( uTexGradients, uvgradients ).rgb;\n"
-" vfrag -= rgarbage.a*0.04;\n"
-"\n"
-" if( g_light_preview == 1 )\n"
-" {\n"
-" vfrag = vec3(0.5);\n"
-" }\n"
-"\n"
-" vfrag = scene_compute_lighting( vfrag, qnorm, aWorldCo );\n"
-" oColour = vec4(vfrag, 1.0);\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_scene_vertex_blend_uMdl;
-static GLuint _uniform_scene_vertex_blend_uPv;
-static GLuint _uniform_scene_vertex_blend_uPvmPrev;
-static GLuint _uniform_scene_vertex_blend_uTexGarbage;
-static GLuint _uniform_scene_vertex_blend_uTexGradients;
-static GLuint _uniform_scene_vertex_blend_uCamera;
-static GLuint _uniform_scene_vertex_blend_g_world_depth;
-static GLuint _uniform_scene_vertex_blend_uLightsArray;
-static GLuint _uniform_scene_vertex_blend_uLightsIndex;
-static void shader_scene_vertex_blend_uMdl(m4x3f m){
- glUniformMatrix4x3fv(_uniform_scene_vertex_blend_uMdl,1,GL_FALSE,(float*)m);
+ glUniformMatrix4x3fv(_uniform_scene_vertex_blend_uMdl,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_vertex_blend_uPv(m4x4f m){
- glUniformMatrix4fv(_uniform_scene_vertex_blend_uPv,1,GL_FALSE,(float*)m);
+static inline void shader_scene_vertex_blend_uPv(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_scene_vertex_blend_uPv,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_vertex_blend_uPvmPrev(m4x4f m){
- glUniformMatrix4fv(_uniform_scene_vertex_blend_uPvmPrev,1,GL_FALSE,(float*)m);
+static inline void shader_scene_vertex_blend_uPvmPrev(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_scene_vertex_blend_uPvmPrev,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_vertex_blend_uTexGarbage(int i){
+static inline void shader_scene_vertex_blend_uTexGarbage(int i)
+{
glUniform1i(_uniform_scene_vertex_blend_uTexGarbage,i);
}
-static void shader_scene_vertex_blend_uTexGradients(int i){
+static inline void shader_scene_vertex_blend_uTexGradients(int i)
+{
glUniform1i(_uniform_scene_vertex_blend_uTexGradients,i);
}
-static void shader_scene_vertex_blend_uCamera(v3f v){
+static inline void shader_scene_vertex_blend_uCamera(v3f v)
+{
glUniform3fv(_uniform_scene_vertex_blend_uCamera,1,v);
}
-static void shader_scene_vertex_blend_g_world_depth(int i){
+static inline void shader_scene_vertex_blend_g_world_depth(int i)
+{
glUniform1i(_uniform_scene_vertex_blend_g_world_depth,i);
}
-static void shader_scene_vertex_blend_register(void){
- vg_shader_register( &_shader_scene_vertex_blend );
-}
-static void shader_scene_vertex_blend_use(void){ glUseProgram(_shader_scene_vertex_blend.id); }
-static void shader_scene_vertex_blend_link(void){
- _uniform_scene_vertex_blend_uMdl = glGetUniformLocation( _shader_scene_vertex_blend.id, "uMdl" );
- _uniform_scene_vertex_blend_uPv = glGetUniformLocation( _shader_scene_vertex_blend.id, "uPv" );
- _uniform_scene_vertex_blend_uPvmPrev = glGetUniformLocation( _shader_scene_vertex_blend.id, "uPvmPrev" );
- _uniform_scene_vertex_blend_uTexGarbage = glGetUniformLocation( _shader_scene_vertex_blend.id, "uTexGarbage" );
- _uniform_scene_vertex_blend_uTexGradients = glGetUniformLocation( _shader_scene_vertex_blend.id, "uTexGradients" );
- _uniform_scene_vertex_blend_uCamera = glGetUniformLocation( _shader_scene_vertex_blend.id, "uCamera" );
- _uniform_scene_vertex_blend_g_world_depth = glGetUniformLocation( _shader_scene_vertex_blend.id, "g_world_depth" );
- _uniform_scene_vertex_blend_uLightsArray = glGetUniformLocation( _shader_scene_vertex_blend.id, "uLightsArray" );
- _uniform_scene_vertex_blend_uLightsIndex = glGetUniformLocation( _shader_scene_vertex_blend.id, "uLightsIndex" );
+static inline void shader_scene_vertex_blend_use(void);
+static inline void shader_scene_vertex_blend_use(void)
+{
+ glUseProgram(_shader_scene_vertex_blend.id);
}
-#endif /* SHADER_scene_vertex_blend_H */
-#ifndef SHADER_scene_water_H
-#define SHADER_scene_water_H
-static void shader_scene_water_link(void);
-static void shader_scene_water_register(void);
-static struct vg_shader _shader_scene_water = {
- .name = "scene_water",
- .link = shader_scene_water_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_scene_water;
+extern GLuint _uniform_scene_water_uMdl;
+extern GLuint _uniform_scene_water_uPv;
+extern GLuint _uniform_scene_water_uPvmPrev;
+extern GLuint _uniform_scene_water_uTexMain;
+extern GLuint _uniform_scene_water_uTexDudv;
+extern GLuint _uniform_scene_water_uTexBack;
+extern GLuint _uniform_scene_water_uInvRes;
+extern GLuint _uniform_scene_water_uTime;
+extern GLuint _uniform_scene_water_uCamera;
+extern GLuint _uniform_scene_water_uSurfaceY;
+extern GLuint _uniform_scene_water_uBoard0;
+extern GLuint _uniform_scene_water_uBoard1;
+extern GLuint _uniform_scene_water_uShoreColour;
+extern GLuint _uniform_scene_water_uOceanColour;
+extern GLuint _uniform_scene_water_g_world_depth;
+extern GLuint _uniform_scene_water_uLightsArray;
+extern GLuint _uniform_scene_water_uLightsIndex;
+static inline void shader_scene_water_uMdl(m4x3f m)
{
-.orig_file = "shaders/scene.vs",
-.static_src =
-"layout (location=0) in vec3 a_co;\n"
-"layout (location=1) in vec4 a_norm;\n"
-"layout (location=2) in vec2 a_uv;\n"
-"\n"
-"#line 1 1 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"out vec3 aMotionVec0;\n"
-"out vec3 aMotionVec1;\n"
-"\n"
-"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
-"{\n"
-" // This magically solves some artifacting errors!\n"
-" //\n"
-" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
-"\n"
-" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
-" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
-"}\n"
-"\n"
-"#line 6 0 \n"
-"\n"
-"uniform mat4x3 uMdl;\n"
-"uniform mat4 uPv;\n"
-"uniform mat4 uPvmPrev;\n"
-"\n"
-"out vec2 aUv;\n"
-"out vec4 aNorm;\n"
-"out vec3 aCo;\n"
-"out vec3 aWorldCo;\n"
-"\n"
-"void main()\n"
-"{\n"
-" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
-" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
-" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
-"\n"
-" vs_motion_out( vproj0, vproj1 );\n"
-"\n"
-" gl_Position = vproj0;\n"
-"\n"
-" aUv = a_uv;\n"
-" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
-" aCo = a_co;\n"
-" aWorldCo = world_pos0;\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/scene_water.fs",
-.static_src =
-"uniform sampler2D uTexMain;\n"
-"uniform sampler2D uTexDudv;\n"
-"uniform sampler2D uTexBack;\n"
-"\n"
-"uniform vec2 uInvRes;\n"
-"uniform float uTime;\n"
-"uniform vec3 uCamera;\n"
-"uniform float uSurfaceY;\n"
-"uniform vec3 uBoard0;\n"
-"uniform vec3 uBoard1;\n"
-"\n"
-"uniform vec3 uShoreColour;\n"
-"uniform vec3 uOceanColour;\n"
-"\n"
-"#line 1 1 \n"
-"// :D\n"
-"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
-"\n"
-"#line 16 0 \n"
-"#line 1 2 \n"
-"// :D\n"
-"\n"
-"in vec2 aUv;\n"
-"in vec4 aNorm;\n"
-"in vec3 aCo;\n"
-"in vec3 aWorldCo;\n"
-"\n"
-"#line 1 1 \n"
-"layout (location = 0) out vec4 oColour;\n"
-"\n"
-"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
-"layout (std140) uniform ub_world_lighting\n"
-"{\n"
-" vec4 g_cube_min;\n"
-" vec4 g_cube_inv_range;\n"
-"\n"
-" vec4 g_water_plane;\n"
-" vec4 g_depth_bounds;\n"
-"\n"
-" vec4 g_daysky_colour;\n"
-" vec4 g_nightsky_colour;\n"
-" vec4 g_sunset_colour;\n"
-" vec4 g_ambient_colour;\n"
-" vec4 g_sunset_ambient;\n"
-" vec4 g_sun_colour;\n"
-" vec4 g_sun_dir;\n"
-" vec4 g_board_0;\n"
-" vec4 g_board_1;\n"
-"\n"
-" float g_water_fog;\n"
-" float g_time;\n"
-" float g_realtime;\n"
-" float g_shadow_length;\n"
-" float g_shadow_spread;\n"
-"\n"
-" float g_time_of_day;\n"
-" float g_day_phase;\n"
-" float g_sunset_phase;\n"
-"\n"
-" int g_light_preview;\n"
-" int g_shadow_samples;\n"
-"\n"
-" int g_debug_indices;\n"
-" int g_debug_complexity;\n"
-"};\n"
-"\n"
-"uniform sampler2D g_world_depth;\n"
-"uniform samplerBuffer uLightsArray;\n"
-"uniform usampler3D uLightsIndex;\n"
-"\n"
-"#line 1 1 \n"
-"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
-"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
-"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
-"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
-"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
-"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
-"\n"
-"const float SUN_ANGLE = 0.0001;\n"
-"const float PI = 3.14159265358979323846264;\n"
-"\n"
-"//struct world_info\n"
-"//{\n"
-"// float time,\n"
-"// time_of_day,\n"
-"// day_phase,\n"
-"// sunset_phase;\n"
-"// \n"
-"// vec3 sun_dir;\n"
-"//};\n"
-"\n"
-"vec3 rand33(vec3 p3)\n"
-"{\n"
-" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
-" p3 += dot(p3, p3.yxz+33.33);\n"
-" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
-"}\n"
-"\n"
-"float stars( vec3 rd, float rr, float size ){\n"
-" vec3 co = rd * rr;\n"
-"\n"
-" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
-"\n"
-" float spaces = 1.0 / rr;\n"
-" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
-" a -= mod(a, spaces) - spaces * 0.5;\n"
-"\n"
-" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
-" \n"
-" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
-" plane = plane - mod(plane, PI / count);\n"
-"\n"
-" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
-"\n"
-" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
-" float ydist = sqrt(rr * rr - level * level);\n"
-" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
-" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
-" float star = smoothstep(size, 0.0, distance(center, co));\n"
-" return star;\n"
-"}\n"
-"\n"
-"float luminance( vec3 v )\n"
-"{\n"
-" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
-"}\n"
-"\n"
-"vec3 clearskies_ambient( vec3 dir )\n"
-"{\n"
-" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
-" float sky_gradient = dir.y;\n"
-" \n"
-" /* Blend phase colours */\n"
-" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
-" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
-" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
-" \n"
-" /* Add gradient */\n"
-" ambient -= sky_gradient * luminance(ambient);\n"
-" \n"
-" return ambient;\n"
-"}\n"
-"\n"
-"vec3 clearskies_sky( vec3 ray_dir )\n"
-"{\n"
-" ray_dir.y = abs( ray_dir.y );\n"
-" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
-" \n"
-" /* Sun */\n"
-" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
-" float sun_shape = pow( sun_size, 2000.0 );\n"
-" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" \n"
-" float star = 0.0;\n"
-" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
-"\n"
-" if( star_blend > 0.001 ){\n"
-" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
-" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
-" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
-" }\n"
-" }\n"
-" \n"
-" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
-" return composite;\n"
-"}\n"
-"\n"
-"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
-"{\n"
-" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
-"\n"
-" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
-" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
-" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
-" ) * g_sun_colour.rgb * g_day_phase;\n"
-"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
-" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" return ambient + (light_sun + sky_reflection) * shadow;\n"
-"}\n"
-"\n"
-"#line 44 0 \n"
-"\n"
-"float world_depth_sample( vec3 pos )\n"
-"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
-" return texture( g_world_depth, depth_coord ).r;\n"
-"}\n"
-"\n"
-"float world_water_depth( vec3 pos )\n"
-"{\n"
-" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return world_depth_sample( pos ) - ref_depth;\n"
-"}\n"
-"\n"
-"float shadow_sample( vec3 co ){\n"
-" float height_sample = world_depth_sample( co );\n"
-"\n"
-" float fdelta = height_sample - co.y;\n"
-" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
-"}\n"
-"\n"
-"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
-" if( g_shadow_samples == 0 ){\n"
-" return 1.0;\n"
-" }\n"
-"\n"
-" float fspread = g_shadow_spread;\n"
-" float flength = g_shadow_length;\n"
-"\n"
-" float famt = 0.0;\n"
-" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
-"\n"
-" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
-"\n"
-" return 1.0 - famt;\n"
-"}\n"
-"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
-"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
-"}\n"
-"\n"
-"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
-" float dist = pow(fdist*0.0010,0.78);\n"
-" return mix( vfrag, colour, min( 1.0, dist ) );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_light( int light_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
-" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
-" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
-"\n"
-" vec3 light_delta = light_co.xyz-co;\n"
-" float dist2 = dot(light_delta,light_delta);\n"
-"\n"
-" light_delta = normalize( light_delta );\n"
-"\n"
-" float quadratic = dist2*100.0;\n"
-" float attenuation = 1.0/( 1.0 + quadratic );\n"
-" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
-"\n"
-" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
-"\n"
-" if( light_dir.w < 0.999999 ){\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
-" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
-" }\n"
-"\n"
-" return light_colour.rgb * attenuation * falloff \n"
-" * step( g_day_phase, light_colour.w );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" uint light_count = packed_index & 0x3u;\n"
-"\n"
-" vec3 l = vec3(0.0);\n"
-"\n"
-" if( light_count >= 1u ){\n"
-" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
-" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
-" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
-"\n"
-" l += scene_calculate_light( index_0, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 2u ){\n"
-" l += scene_calculate_light( index_1, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 3u ){\n"
-" l += scene_calculate_light( index_2, halfview, co, normal );\n"
-" }\n"
-" }\n"
-" }\n"
-"\n"
-" return l;\n"
-"}\n"
-"\n"
-"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
-" float light_mask )\n"
-"{\n"
-" if( g_light_preview == 1 )\n"
-" diffuse = vec3(0.75);\n"
-"\n"
-" // Lighting\n"
-" vec3 halfview = uCamera - co;\n"
-" float fdist = length(halfview);\n"
-" halfview /= fdist;\n"
-"\n"
-" float world_shadow = newlight_compute_sun_shadow( \n"
-" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
-"\n"
-" vec3 total_light = clearskies_lighting( \n"
-" normal, min( light_mask, world_shadow ), halfview );\n"
-"\n"
-" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
-" cube_coord = floor( cube_coord );\n"
-"\n"
-" if( g_debug_indices == 1 )\n"
-" {\n"
-" return rand33(cube_coord);\n"
-" }\n"
-"\n"
-" if( g_debug_complexity == 1 )\n"
-" {\n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
-" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
-" }\n"
-"\n"
-" // FIXME: this coord should absolutely must be clamped!\n"
-" \n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, co, normal ) \n"
-" * light_mask;\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, co, normal )\n"
-" * light_mask;\n"
-"\n"
-" // Take a section of the sky function to give us a matching fog colour\n"
-"\n"
-" vec3 fog_colour = clearskies_ambient( -halfview );\n"
-" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
-" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" fog_colour += sun_colour;\n"
-" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"\n"
-"float sdLine( vec3 p, vec3 a, vec3 b )\n"
-"{\n"
-" vec3 pa = p - a;\n"
-" vec3 ba = b - a;\n"
-"\n"
-" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
-" return length( pa - ba*h );\n"
-"}\n"
-"\n"
-"float compute_board_shadow()\n"
-"{\n"
-" // player shadow\n"
-" float dist_to_player = max( 0.0, sdLine( aWorldCo, g_board_0.xyz,\n"
-" g_board_1.xyz )-0.1 );\n"
-" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
-" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
-"\n"
-" return 1.0 - player_shadow*0.8;\n"
-"}\n"
-"\n"
-"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
-"{\n"
-" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
-"}\n"
-"\n"
-"#line 17 0 \n"
-"#line 1 3 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"layout (location = 1) out vec2 oMotionVec;\n"
-"\n"
-"in vec3 aMotionVec0;\n"
-"in vec3 aMotionVec1;\n"
-"\n"
-"void compute_motion_vectors()\n"
-"{\n"
-" // Write motion vectors\n"
-" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
-" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
-"\n"
-" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
-"}\n"
-"\n"
-"#line 18 0 \n"
-"\n"
-"vec4 water_surf( vec3 halfview, vec3 vnorm, float depthvalue, \n"
-" vec4 beneath, vec4 above )\n"
-"{\n"
-" vec3 surface_tint = mix(uShoreColour, uOceanColour, depthvalue);\n"
-"\n"
-" float ffresnel = pow(1.0-dot( vnorm, halfview ),5.0);\n"
-"\n"
-" vec3 lightdir = vec3(0.95,0.0,-0.3);\n"
-" vec3 specdir = reflect( -lightdir, vnorm );\n"
-" float spec = pow(max(dot(halfview,specdir),0.0),20.0)*0.3;\n"
-" \n"
-" // Depth \n"
-" float depthblend = pow( beneath.r, 0.8 );\n"
-"\n"
-" // Composite\n"
-" vec3 vsurface = mix(surface_tint, above.rgb, ffresnel );\n"
-" //vsurface += spec;\n"
-"\n"
-" return vec4( vsurface,depthblend );\n"
-"}\n"
-"\n"
-"void main()\n"
-"{\n"
-" compute_motion_vectors();\n"
-"\n"
-" // Create texture coords\n"
-" vec2 ssuv = gl_FragCoord.xy*uInvRes;\n"
-" \n"
-" // Surface colour composite\n"
-" float depthvalue = clamp( -world_water_depth(aCo)*(1.0/25.0), 0.0,1.0 );\n"
-"\n"
-" vec2 world_coord = aCo.xz * 0.008;\n"
-" vec4 time_offsets = vec4( uTime ) * vec4( 0.008, 0.006, 0.003, 0.03 );\n"
-" vec4 dudva = texture( uTexDudv, world_coord + time_offsets.xy )-0.5;\n"
-" vec4 dudvb = texture( uTexDudv, world_coord *7.0 - time_offsets.zw )-0.5;\n"
-"\n"
-" vec3 surfnorm = dudva.rgb + dudvb.rgb;\n"
-" surfnorm = normalize(vec3(0.0,1.0,0.0) + dudva.xyz*0.4 + dudvb.xyz*0.1);\n"
-" \n"
-" // Foam\n"
-" float fband = fract( aCo.z*0.02+uTime*0.1+depthvalue*10.0 );\n"
-" fband = step( fband+dudva.a*0.8, 0.3 ) * max((1.0-depthvalue*4.0),0.0);\n"
-"\n"
-" // Lighting\n"
-" vec3 halfview = -normalize( aCo-uCamera );\n"
-"\n"
-" // Sample textures\n"
-" vec4 above = texture( uTexMain, ssuv+ surfnorm.xz*0.2 );\n"
-" vec4 beneath = texture( uTexBack, ssuv );\n"
-"\n"
-" // Fog\n"
-" float fdist = pow(length( aCo.xz-uCamera.xz ) * 0.00047, 2.6);\n"
-"\n"
-" // Composite\n"
-" vec4 vsurface = water_surf( halfview, surfnorm, depthvalue, beneath, above );\n"
-" vsurface.a -= fdist;\n"
-" oColour = mix( vsurface, vec4(1.0,1.0,1.0,0.5), fband );\n"
-" oColour.rgb = scene_compute_lighting( oColour.rgb, aNorm.xyz, aWorldCo );\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_scene_water_uMdl;
-static GLuint _uniform_scene_water_uPv;
-static GLuint _uniform_scene_water_uPvmPrev;
-static GLuint _uniform_scene_water_uTexMain;
-static GLuint _uniform_scene_water_uTexDudv;
-static GLuint _uniform_scene_water_uTexBack;
-static GLuint _uniform_scene_water_uInvRes;
-static GLuint _uniform_scene_water_uTime;
-static GLuint _uniform_scene_water_uCamera;
-static GLuint _uniform_scene_water_uSurfaceY;
-static GLuint _uniform_scene_water_uBoard0;
-static GLuint _uniform_scene_water_uBoard1;
-static GLuint _uniform_scene_water_uShoreColour;
-static GLuint _uniform_scene_water_uOceanColour;
-static GLuint _uniform_scene_water_g_world_depth;
-static GLuint _uniform_scene_water_uLightsArray;
-static GLuint _uniform_scene_water_uLightsIndex;
-static void shader_scene_water_uMdl(m4x3f m){
- glUniformMatrix4x3fv(_uniform_scene_water_uMdl,1,GL_FALSE,(float*)m);
+ glUniformMatrix4x3fv(_uniform_scene_water_uMdl,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_water_uPv(m4x4f m){
- glUniformMatrix4fv(_uniform_scene_water_uPv,1,GL_FALSE,(float*)m);
+static inline void shader_scene_water_uPv(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_scene_water_uPv,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_water_uPvmPrev(m4x4f m){
- glUniformMatrix4fv(_uniform_scene_water_uPvmPrev,1,GL_FALSE,(float*)m);
+static inline void shader_scene_water_uPvmPrev(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_scene_water_uPvmPrev,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_water_uTexMain(int i){
+static inline void shader_scene_water_uTexMain(int i)
+{
glUniform1i(_uniform_scene_water_uTexMain,i);
}
-static void shader_scene_water_uTexDudv(int i){
+static inline void shader_scene_water_uTexDudv(int i)
+{
glUniform1i(_uniform_scene_water_uTexDudv,i);
}
-static void shader_scene_water_uTexBack(int i){
+static inline void shader_scene_water_uTexBack(int i)
+{
glUniform1i(_uniform_scene_water_uTexBack,i);
}
-static void shader_scene_water_uInvRes(v2f v){
+static inline void shader_scene_water_uInvRes(v2f v)
+{
glUniform2fv(_uniform_scene_water_uInvRes,1,v);
}
-static void shader_scene_water_uTime(float f){
+static inline void shader_scene_water_uTime(f32 f)
+{
glUniform1f(_uniform_scene_water_uTime,f);
}
-static void shader_scene_water_uCamera(v3f v){
+static inline void shader_scene_water_uCamera(v3f v)
+{
glUniform3fv(_uniform_scene_water_uCamera,1,v);
}
-static void shader_scene_water_uSurfaceY(float f){
+static inline void shader_scene_water_uSurfaceY(f32 f)
+{
glUniform1f(_uniform_scene_water_uSurfaceY,f);
}
-static void shader_scene_water_uBoard0(v3f v){
+static inline void shader_scene_water_uBoard0(v3f v)
+{
glUniform3fv(_uniform_scene_water_uBoard0,1,v);
}
-static void shader_scene_water_uBoard1(v3f v){
+static inline void shader_scene_water_uBoard1(v3f v)
+{
glUniform3fv(_uniform_scene_water_uBoard1,1,v);
}
-static void shader_scene_water_uShoreColour(v3f v){
+static inline void shader_scene_water_uShoreColour(v3f v)
+{
glUniform3fv(_uniform_scene_water_uShoreColour,1,v);
}
-static void shader_scene_water_uOceanColour(v3f v){
+static inline void shader_scene_water_uOceanColour(v3f v)
+{
glUniform3fv(_uniform_scene_water_uOceanColour,1,v);
}
-static void shader_scene_water_g_world_depth(int i){
+static inline void shader_scene_water_g_world_depth(int i)
+{
glUniform1i(_uniform_scene_water_g_world_depth,i);
}
-static void shader_scene_water_register(void){
- vg_shader_register( &_shader_scene_water );
-}
-static void shader_scene_water_use(void){ glUseProgram(_shader_scene_water.id); }
-static void shader_scene_water_link(void){
- _uniform_scene_water_uMdl = glGetUniformLocation( _shader_scene_water.id, "uMdl" );
- _uniform_scene_water_uPv = glGetUniformLocation( _shader_scene_water.id, "uPv" );
- _uniform_scene_water_uPvmPrev = glGetUniformLocation( _shader_scene_water.id, "uPvmPrev" );
- _uniform_scene_water_uTexMain = glGetUniformLocation( _shader_scene_water.id, "uTexMain" );
- _uniform_scene_water_uTexDudv = glGetUniformLocation( _shader_scene_water.id, "uTexDudv" );
- _uniform_scene_water_uTexBack = glGetUniformLocation( _shader_scene_water.id, "uTexBack" );
- _uniform_scene_water_uInvRes = glGetUniformLocation( _shader_scene_water.id, "uInvRes" );
- _uniform_scene_water_uTime = glGetUniformLocation( _shader_scene_water.id, "uTime" );
- _uniform_scene_water_uCamera = glGetUniformLocation( _shader_scene_water.id, "uCamera" );
- _uniform_scene_water_uSurfaceY = glGetUniformLocation( _shader_scene_water.id, "uSurfaceY" );
- _uniform_scene_water_uBoard0 = glGetUniformLocation( _shader_scene_water.id, "uBoard0" );
- _uniform_scene_water_uBoard1 = glGetUniformLocation( _shader_scene_water.id, "uBoard1" );
- _uniform_scene_water_uShoreColour = glGetUniformLocation( _shader_scene_water.id, "uShoreColour" );
- _uniform_scene_water_uOceanColour = glGetUniformLocation( _shader_scene_water.id, "uOceanColour" );
- _uniform_scene_water_g_world_depth = glGetUniformLocation( _shader_scene_water.id, "g_world_depth" );
- _uniform_scene_water_uLightsArray = glGetUniformLocation( _shader_scene_water.id, "uLightsArray" );
- _uniform_scene_water_uLightsIndex = glGetUniformLocation( _shader_scene_water.id, "uLightsIndex" );
+static inline void shader_scene_water_use(void);
+static inline void shader_scene_water_use(void)
+{
+ glUseProgram(_shader_scene_water.id);
}
-#endif /* SHADER_scene_water_H */
-#ifndef SHADER_scene_water_fast_H
-#define SHADER_scene_water_fast_H
-static void shader_scene_water_fast_link(void);
-static void shader_scene_water_fast_register(void);
-static struct vg_shader _shader_scene_water_fast = {
- .name = "scene_water_fast",
- .link = shader_scene_water_fast_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_scene_water_fast;
+extern GLuint _uniform_scene_water_fast_uMdl;
+extern GLuint _uniform_scene_water_fast_uPv;
+extern GLuint _uniform_scene_water_fast_uPvmPrev;
+extern GLuint _uniform_scene_water_fast_uTexDudv;
+extern GLuint _uniform_scene_water_fast_uTime;
+extern GLuint _uniform_scene_water_fast_uCamera;
+extern GLuint _uniform_scene_water_fast_uSurfaceY;
+extern GLuint _uniform_scene_water_fast_uBoard0;
+extern GLuint _uniform_scene_water_fast_uBoard1;
+extern GLuint _uniform_scene_water_fast_uShoreColour;
+extern GLuint _uniform_scene_water_fast_uOceanColour;
+extern GLuint _uniform_scene_water_fast_g_world_depth;
+extern GLuint _uniform_scene_water_fast_uLightsArray;
+extern GLuint _uniform_scene_water_fast_uLightsIndex;
+static inline void shader_scene_water_fast_uMdl(m4x3f m)
{
-.orig_file = "shaders/scene.vs",
-.static_src =
-"layout (location=0) in vec3 a_co;\n"
-"layout (location=1) in vec4 a_norm;\n"
-"layout (location=2) in vec2 a_uv;\n"
-"\n"
-"#line 1 1 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"out vec3 aMotionVec0;\n"
-"out vec3 aMotionVec1;\n"
-"\n"
-"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
-"{\n"
-" // This magically solves some artifacting errors!\n"
-" //\n"
-" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
-"\n"
-" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
-" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
-"}\n"
-"\n"
-"#line 6 0 \n"
-"\n"
-"uniform mat4x3 uMdl;\n"
-"uniform mat4 uPv;\n"
-"uniform mat4 uPvmPrev;\n"
-"\n"
-"out vec2 aUv;\n"
-"out vec4 aNorm;\n"
-"out vec3 aCo;\n"
-"out vec3 aWorldCo;\n"
-"\n"
-"void main()\n"
-"{\n"
-" vec3 world_pos0 = uMdl * vec4( a_co, 1.0 );\n"
-" vec4 vproj0 = uPv * vec4( world_pos0, 1.0 );\n"
-" vec4 vproj1 = uPvmPrev * vec4( a_co, 1.0 );\n"
-"\n"
-" vs_motion_out( vproj0, vproj1 );\n"
-"\n"
-" gl_Position = vproj0;\n"
-"\n"
-" aUv = a_uv;\n"
-" aNorm = vec4( mat3(uMdl) * a_norm.xyz, a_norm.w );\n"
-" aCo = a_co;\n"
-" aWorldCo = world_pos0;\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/scene_water_fast.fs",
-.static_src =
-"uniform sampler2D uTexDudv;\n"
-"\n"
-"uniform float uTime;\n"
-"uniform vec3 uCamera;\n"
-"uniform float uSurfaceY;\n"
-"uniform vec3 uBoard0;\n"
-"uniform vec3 uBoard1;\n"
-"\n"
-"uniform vec3 uShoreColour;\n"
-"uniform vec3 uOceanColour;\n"
-"\n"
-"#line 1 1 \n"
-"// :D\n"
-"const float CLEARSKIES_LIGHT_DOT_MIN = 0.0;\n"
-"\n"
-"#line 13 0 \n"
-"#line 1 2 \n"
-"// :D\n"
-"\n"
-"in vec2 aUv;\n"
-"in vec4 aNorm;\n"
-"in vec3 aCo;\n"
-"in vec3 aWorldCo;\n"
-"\n"
-"#line 1 1 \n"
-"layout (location = 0) out vec4 oColour;\n"
-"\n"
-"// OpenGL wiki: Recommends do not use vec3 because of drivers. hence the v4s...\n"
-"layout (std140) uniform ub_world_lighting\n"
-"{\n"
-" vec4 g_cube_min;\n"
-" vec4 g_cube_inv_range;\n"
-"\n"
-" vec4 g_water_plane;\n"
-" vec4 g_depth_bounds;\n"
-"\n"
-" vec4 g_daysky_colour;\n"
-" vec4 g_nightsky_colour;\n"
-" vec4 g_sunset_colour;\n"
-" vec4 g_ambient_colour;\n"
-" vec4 g_sunset_ambient;\n"
-" vec4 g_sun_colour;\n"
-" vec4 g_sun_dir;\n"
-" vec4 g_board_0;\n"
-" vec4 g_board_1;\n"
-"\n"
-" float g_water_fog;\n"
-" float g_time;\n"
-" float g_realtime;\n"
-" float g_shadow_length;\n"
-" float g_shadow_spread;\n"
-"\n"
-" float g_time_of_day;\n"
-" float g_day_phase;\n"
-" float g_sunset_phase;\n"
-"\n"
-" int g_light_preview;\n"
-" int g_shadow_samples;\n"
-"\n"
-" int g_debug_indices;\n"
-" int g_debug_complexity;\n"
-"};\n"
-"\n"
-"uniform sampler2D g_world_depth;\n"
-"uniform samplerBuffer uLightsArray;\n"
-"uniform usampler3D uLightsIndex;\n"
-"\n"
-"#line 1 1 \n"
-"//const vec3 DAYSKY_COLOUR = vec3( 0.37, 0.54, 0.97 );\n"
-"//const vec3 NIGHTSKY_COLOUR = vec3( 0.03, 0.05, 0.20 );\n"
-"//const vec3 SUNSET_COLOUR = vec3( 1.00, 0.32, 0.01 );\n"
-"//const vec3 AMBIENT_COLOUR = vec3( 0.13, 0.17, 0.35 );\n"
-"//const vec3 SUNSET_AMBIENT = vec3( 0.25, 0.17, 0.51 );\n"
-"//const vec3 SUN_COLOUR = vec3( 1.10, 0.89, 0.35 );\n"
-"\n"
-"const float SUN_ANGLE = 0.0001;\n"
-"const float PI = 3.14159265358979323846264;\n"
-"\n"
-"//struct world_info\n"
-"//{\n"
-"// float time,\n"
-"// time_of_day,\n"
-"// day_phase,\n"
-"// sunset_phase;\n"
-"// \n"
-"// vec3 sun_dir;\n"
-"//};\n"
-"\n"
-"vec3 rand33(vec3 p3)\n"
-"{\n"
-" p3 = fract(p3 * vec3(.1031, .1030, .0973));\n"
-" p3 += dot(p3, p3.yxz+33.33);\n"
-" return fract((p3.xxy + p3.yxx)*p3.zyx);\n"
-"}\n"
-"\n"
-"float stars( vec3 rd, float rr, float size ){\n"
-" vec3 co = rd * rr;\n"
-"\n"
-" float a = atan(co.y, length(co.xz)) + 4.0 * PI;\n"
-"\n"
-" float spaces = 1.0 / rr;\n"
-" size = (rr * 0.0015) * fwidth(a) * 1000.0 * size;\n"
-" a -= mod(a, spaces) - spaces * 0.5;\n"
-"\n"
-" float count = floor(sqrt(pow(rr, 2.0) * (1.0 - pow(sin(a), 2.0))) * 3.0);\n"
-" \n"
-" float plane = atan(co.z, co.x) + 4.0 * PI;\n"
-" plane = plane - mod(plane, PI / count);\n"
-"\n"
-" vec2 delta = rand33(vec3(plane, a, 0.0)).xy;\n"
-"\n"
-" float level = sin(a + spaces * (delta.y - 0.5) * (1.0 - size)) * rr;\n"
-" float ydist = sqrt(rr * rr - level * level);\n"
-" float angle = plane + (PI * (delta.x * (1.0-size) + size * 0.5) / count);\n"
-" vec3 center = vec3(cos(angle) * ydist, level, sin(angle) * ydist);\n"
-" float star = smoothstep(size, 0.0, distance(center, co));\n"
-" return star;\n"
-"}\n"
-"\n"
-"float luminance( vec3 v )\n"
-"{\n"
-" return dot( v, vec3(0.2126, 0.7152, 0.0722) );\n"
-"}\n"
-"\n"
-"vec3 clearskies_ambient( vec3 dir )\n"
-"{\n"
-" float sun_azimuth = g_sunset_phase * (dot( dir.xz, g_sun_dir.xz )*0.4+0.6);\n"
-" float sky_gradient = dir.y;\n"
-" \n"
-" /* Blend phase colours */\n"
-" vec3 ambient = g_daysky_colour.rgb * (g_day_phase-g_sunset_phase*0.1);\n"
-" ambient += g_sunset_colour.rgb * (1.0-dir.y*0.5)*sun_azimuth;\n"
-" ambient += g_nightsky_colour.rgb * (1.0-g_day_phase);\n"
-" \n"
-" /* Add gradient */\n"
-" ambient -= sky_gradient * luminance(ambient);\n"
-" \n"
-" return ambient;\n"
-"}\n"
-"\n"
-"vec3 clearskies_sky( vec3 ray_dir )\n"
-"{\n"
-" ray_dir.y = abs( ray_dir.y );\n"
-" vec3 sky_colour = clearskies_ambient( ray_dir );\n"
-" \n"
-" /* Sun */\n"
-" float sun_theta = dot( ray_dir, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 + SUN_ANGLE );\n"
-" float sun_shape = pow( sun_size, 2000.0 );\n"
-" sun_shape += sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" \n"
-" float star = 0.0;\n"
-" float star_blend = 10.0*max(0.0,(1.0-g_day_phase*2.0));\n"
-"\n"
-" if( star_blend > 0.001 ){\n"
-" for( float j = 1.0; j <= 4.1; j += 1.0 ){\n"
-" float m = mix(0.6, 0.9, smoothstep(1.0, 2.0, j));\n"
-" star += stars( ray_dir, 1.94 * pow( 1.64, j ), m ) * (1.0/pow(4.0, j));\n"
-" }\n"
-" }\n"
-" \n"
-" vec3 composite = sky_colour + sun_colour + star*star_blend;\n"
-" return composite;\n"
-"}\n"
-"\n"
-"vec3 clearskies_lighting( vec3 normal, float shadow, vec3 halfview )\n"
-"{\n"
-" float fresnel = 1.0 - abs(dot(normal,halfview));\n"
-"\n"
-" vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" vec3 sky_reflection = 0.5 * fresnel * reflect_colour;\n"
-" vec3 light_sun = max( CLEARSKIES_LIGHT_DOT_MIN, \n"
-" dot(normal,g_sun_dir.xyz)*0.75+0.25\n"
-" ) * g_sun_colour.rgb * g_day_phase;\n"
-"\n"
-" float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) );\n"
-" vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, \n"
-" g_sunset_phase );\n"
-"\n"
-" return ambient + (light_sun + sky_reflection) * shadow;\n"
-"}\n"
-"\n"
-"#line 44 0 \n"
-"\n"
-"float world_depth_sample( vec3 pos )\n"
-"{\n"
-" vec2 depth_coord = (pos.xz - g_depth_bounds.xy) * g_depth_bounds.zw; \n"
-" return texture( g_world_depth, depth_coord ).r;\n"
-"}\n"
-"\n"
-"float world_water_depth( vec3 pos )\n"
-"{\n"
-" float ref_depth = g_water_plane.y*g_water_plane.w;\n"
-" return world_depth_sample( pos ) - ref_depth;\n"
-"}\n"
-"\n"
-"float shadow_sample( vec3 co ){\n"
-" float height_sample = world_depth_sample( co );\n"
-"\n"
-" float fdelta = height_sample - co.y;\n"
-" return clamp( fdelta, 0.2, 0.4 )-0.2;\n"
-"}\n"
-"\n"
-"float newlight_compute_sun_shadow( vec3 co, vec3 dir ){\n"
-" if( g_shadow_samples == 0 ){\n"
-" return 1.0;\n"
-" }\n"
-"\n"
-" float fspread = g_shadow_spread;\n"
-" float flength = g_shadow_length;\n"
-"\n"
-" float famt = 0.0;\n"
-" famt += shadow_sample(co+(dir+vec3(-0.56,0.55, 0.30)*fspread)*flength*0.1);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.80,0.68, 0.34)*fspread)*flength*0.2);\n"
-" famt += shadow_sample(co+(dir+vec3( 0.78,0.07,-0.06)*fspread)*flength*0.3);\n"
-" famt += shadow_sample(co+(dir+vec3(-0.59,0.07,-0.42)*fspread)*flength*0.4);\n"
-"\n"
-" //famt+=shadow_sample(co+(dir+vec3(-0.790,-0.933,-0.875)*fspread)*flength*0.5);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.807,-0.690, 0.472)*fspread)*flength*0.6);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.522,-0.379, 0.350)*fspread)*flength*0.7);\n"
-" //famt+=shadow_sample(co+(dir+vec3( 0.483, 0.201, 0.306)*fspread)*flength*0.8);\n"
-"\n"
-" return 1.0 - famt;\n"
-"}\n"
-"\n"
-"float newlight_specular( vec3 wnormal, vec3 dir, vec3 halfview, float exponent )\n"
-"{\n"
-" vec3 specdir = reflect( -dir, wnormal );\n"
-" return pow(max(dot( halfview, specdir ), 0.0), exponent);\n"
-"}\n"
-"\n"
-"vec3 scene_apply_fog( vec3 vfrag, vec3 colour, float fdist ){\n"
-" float dist = pow(fdist*0.0010,0.78);\n"
-" return mix( vfrag, colour, min( 1.0, dist ) );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_light( int light_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" vec4 light_colour = texelFetch( uLightsArray, light_index+0 );\n"
-" vec4 light_co = texelFetch( uLightsArray, light_index+1 );\n"
-" vec4 light_dir = texelFetch( uLightsArray, light_index+2 );\n"
-"\n"
-" vec3 light_delta = light_co.xyz-co;\n"
-" float dist2 = dot(light_delta,light_delta);\n"
-"\n"
-" light_delta = normalize( light_delta );\n"
-"\n"
-" float quadratic = dist2*100.0;\n"
-" float attenuation = 1.0/( 1.0 + quadratic );\n"
-" attenuation *= max( dot( light_delta, normal ), 0.0 );\n"
-"\n"
-" float falloff = max( 0.0, 1.0-(dist2*light_co.w) );\n"
-"\n"
-" if( light_dir.w < 0.999999 ){\n"
-" float spot_theta = max( 0.0, dot( light_delta, -light_dir.xyz ) );\n"
-" falloff *= max( 0.0, (spot_theta - light_dir.w) / (1.0-light_dir.w) );\n"
-" }\n"
-"\n"
-" return light_colour.rgb * attenuation * falloff \n"
-" * step( g_day_phase, light_colour.w );\n"
-"}\n"
-"\n"
-"vec3 scene_calculate_packed_light_patch( uint packed_index, \n"
-" vec3 halfview, vec3 co, vec3 normal )\n"
-"{\n"
-" uint light_count = packed_index & 0x3u;\n"
-"\n"
-" vec3 l = vec3(0.0);\n"
-"\n"
-" if( light_count >= 1u ){\n"
-" int index_0 = int( ((packed_index >> 2u) & 0x3ffu) * 3u );\n"
-" int index_1 = int( ((packed_index >> 12u) & 0x3ffu) * 3u );\n"
-" int index_2 = int( ((packed_index >> 22u) & 0x3ffu) * 3u );\n"
-"\n"
-" l += scene_calculate_light( index_0, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 2u ){\n"
-" l += scene_calculate_light( index_1, halfview, co, normal );\n"
-"\n"
-" if( light_count >= 3u ){\n"
-" l += scene_calculate_light( index_2, halfview, co, normal );\n"
-" }\n"
-" }\n"
-" }\n"
-"\n"
-" return l;\n"
-"}\n"
-"\n"
-"vec3 world_compute_lighting( vec3 diffuse, vec3 normal, vec3 co,\n"
-" float light_mask )\n"
-"{\n"
-" if( g_light_preview == 1 )\n"
-" diffuse = vec3(0.75);\n"
-"\n"
-" // Lighting\n"
-" vec3 halfview = uCamera - co;\n"
-" float fdist = length(halfview);\n"
-" halfview /= fdist;\n"
-"\n"
-" float world_shadow = newlight_compute_sun_shadow( \n"
-" co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) );\n"
-"\n"
-" vec3 total_light = clearskies_lighting( \n"
-" normal, min( light_mask, world_shadow ), halfview );\n"
-"\n"
-" vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz;\n"
-" cube_coord = floor( cube_coord );\n"
-"\n"
-" if( g_debug_indices == 1 )\n"
-" {\n"
-" return rand33(cube_coord);\n"
-" }\n"
-"\n"
-" if( g_debug_complexity == 1 )\n"
-" {\n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" uint light_count = (index_sample.x & 0x3u) + (index_sample.y & 0x3u);\n"
-" return vec3( float(light_count)*(1.0/6.0), 0.0, 0.5 );\n"
-" }\n"
-"\n"
-" // FIXME: this coord should absolutely must be clamped!\n"
-" \n"
-" ivec3 coord = ivec3( cube_coord );\n"
-" uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 );\n"
-"\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.x,\n"
-" halfview, co, normal ) \n"
-" * light_mask;\n"
-" total_light += \n"
-" scene_calculate_packed_light_patch( index_sample.y,\n"
-" halfview, co, normal )\n"
-" * light_mask;\n"
-"\n"
-" // Take a section of the sky function to give us a matching fog colour\n"
-"\n"
-" vec3 fog_colour = clearskies_ambient( -halfview );\n"
-" float sun_theta = dot( -halfview, g_sun_dir.xyz );\n"
-" float sun_size = max( 0.0, sun_theta * 0.5 + 0.5 );\n"
-" float sun_shape = sun_size * max(g_sun_dir.y,0.0) * 0.5;\n"
-" \n"
-" vec3 sun_colour = mix( vec3(1.0), g_sunset_colour.rgb, g_sunset_phase*0.5 );\n"
-" sun_colour *= sun_shape;\n"
-"\n"
-" fog_colour += sun_colour;\n"
-" return scene_apply_fog( diffuse * total_light, fog_colour, fdist );\n"
-"}\n"
-"\n"
-"#line 9 0 \n"
-"\n"
-"float sdLine( vec3 p, vec3 a, vec3 b )\n"
-"{\n"
-" vec3 pa = p - a;\n"
-" vec3 ba = b - a;\n"
-"\n"
-" float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );\n"
-" return length( pa - ba*h );\n"
-"}\n"
-"\n"
-"float compute_board_shadow()\n"
-"{\n"
-" // player shadow\n"
-" float dist_to_player = max( 0.0, sdLine( aWorldCo, g_board_0.xyz,\n"
-" g_board_1.xyz )-0.1 );\n"
-" float player_shadow = max( 1.0-dist_to_player*2.7, 0.0 );\n"
-" player_shadow *= player_shadow*player_shadow*player_shadow;\n"
-"\n"
-" return 1.0 - player_shadow*0.8;\n"
-"}\n"
-"\n"
-"vec3 scene_compute_lighting( vec3 diffuse, vec3 normal, vec3 co )\n"
-"{\n"
-" return world_compute_lighting( diffuse, normal, co, compute_board_shadow() );\n"
-"}\n"
-"\n"
-"#line 14 0 \n"
-"#line 1 3 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"layout (location = 1) out vec2 oMotionVec;\n"
-"\n"
-"in vec3 aMotionVec0;\n"
-"in vec3 aMotionVec1;\n"
-"\n"
-"void compute_motion_vectors()\n"
-"{\n"
-" // Write motion vectors\n"
-" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
-" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
-"\n"
-" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
-"}\n"
-"\n"
-"#line 15 0 \n"
-"\n"
-"vec4 water_surf( vec3 halfview, vec3 vnorm, float depthvalue )\n"
-"{\n"
-" vec3 surface_tint = mix(uShoreColour, uOceanColour, depthvalue);\n"
-"\n"
-" float ffresnel = pow(1.0-dot( vnorm, halfview ),5.0);\n"
-"\n"
-" vec3 lightdir = vec3(0.95,0.0,-0.3);\n"
-" vec3 specdir = reflect( -lightdir, vnorm );\n"
-" float spec = pow(max(dot(halfview,specdir),0.0),20.0)*0.3;\n"
-" \n"
-" return vec4( surface_tint + spec, max(min(depthvalue*4.0, 1.0),0.0) );\n"
-"}\n"
-"\n"
-"void main()\n"
-"{\n"
-" compute_motion_vectors();\n"
-"\n"
-" // Surface colour composite\n"
-" float depthvalue = clamp( -world_water_depth( aCo )*(1.0/25.0), 0.0, 1.0 );\n"
-"\n"
-" vec2 world_coord = aCo.xz * 0.008;\n"
-" vec4 time_offsets = vec4( uTime ) * vec4( 0.008, 0.006, 0.003, 0.03 );\n"
-" vec4 dudva = texture( uTexDudv, world_coord + time_offsets.xy )-0.5;\n"
-" vec4 dudvb = texture( uTexDudv, world_coord *7.0 - time_offsets.zw )-0.5;\n"
-"\n"
-" vec3 surfnorm = dudva.rgb + dudvb.rgb;\n"
-" surfnorm = normalize(vec3(0.0,1.0,0.0) + dudva.xyz*0.4 + dudvb.xyz*0.1);\n"
-" \n"
-" // Foam\n"
-" float fband = fract( aCo.z*0.02+uTime*0.1+depthvalue*10.0 );\n"
-" fband = step( fband+dudva.a*0.8, 0.3 ) * max((1.0-depthvalue*4.0),0.0);\n"
-"\n"
-" // Lighting\n"
-" vec3 halfview = -normalize( aCo-uCamera );\n"
-"\n"
-" // Fog\n"
-" float fdist = pow(length( aCo.xz-uCamera.xz ) * 0.00047, 2.6);\n"
-"\n"
-" // Composite\n"
-" vec4 vsurface = water_surf( halfview, surfnorm, depthvalue );\n"
-" vsurface.a -= fdist;\n"
-" oColour = mix( vsurface, vec4(1.0,1.0,1.0,0.5), fband );\n"
-" oColour.rgb = scene_compute_lighting( oColour.rgb, aNorm.xyz, aWorldCo );\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_scene_water_fast_uMdl;
-static GLuint _uniform_scene_water_fast_uPv;
-static GLuint _uniform_scene_water_fast_uPvmPrev;
-static GLuint _uniform_scene_water_fast_uTexDudv;
-static GLuint _uniform_scene_water_fast_uTime;
-static GLuint _uniform_scene_water_fast_uCamera;
-static GLuint _uniform_scene_water_fast_uSurfaceY;
-static GLuint _uniform_scene_water_fast_uBoard0;
-static GLuint _uniform_scene_water_fast_uBoard1;
-static GLuint _uniform_scene_water_fast_uShoreColour;
-static GLuint _uniform_scene_water_fast_uOceanColour;
-static GLuint _uniform_scene_water_fast_g_world_depth;
-static GLuint _uniform_scene_water_fast_uLightsArray;
-static GLuint _uniform_scene_water_fast_uLightsIndex;
-static void shader_scene_water_fast_uMdl(m4x3f m){
- glUniformMatrix4x3fv(_uniform_scene_water_fast_uMdl,1,GL_FALSE,(float*)m);
+ glUniformMatrix4x3fv(_uniform_scene_water_fast_uMdl,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_water_fast_uPv(m4x4f m){
- glUniformMatrix4fv(_uniform_scene_water_fast_uPv,1,GL_FALSE,(float*)m);
+static inline void shader_scene_water_fast_uPv(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_scene_water_fast_uPv,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_water_fast_uPvmPrev(m4x4f m){
- glUniformMatrix4fv(_uniform_scene_water_fast_uPvmPrev,1,GL_FALSE,(float*)m);
+static inline void shader_scene_water_fast_uPvmPrev(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_scene_water_fast_uPvmPrev,1,GL_FALSE,(f32*)m);
}
-static void shader_scene_water_fast_uTexDudv(int i){
+static inline void shader_scene_water_fast_uTexDudv(int i)
+{
glUniform1i(_uniform_scene_water_fast_uTexDudv,i);
}
-static void shader_scene_water_fast_uTime(float f){
+static inline void shader_scene_water_fast_uTime(f32 f)
+{
glUniform1f(_uniform_scene_water_fast_uTime,f);
}
-static void shader_scene_water_fast_uCamera(v3f v){
+static inline void shader_scene_water_fast_uCamera(v3f v)
+{
glUniform3fv(_uniform_scene_water_fast_uCamera,1,v);
}
-static void shader_scene_water_fast_uSurfaceY(float f){
+static inline void shader_scene_water_fast_uSurfaceY(f32 f)
+{
glUniform1f(_uniform_scene_water_fast_uSurfaceY,f);
}
-static void shader_scene_water_fast_uBoard0(v3f v){
+static inline void shader_scene_water_fast_uBoard0(v3f v)
+{
glUniform3fv(_uniform_scene_water_fast_uBoard0,1,v);
}
-static void shader_scene_water_fast_uBoard1(v3f v){
+static inline void shader_scene_water_fast_uBoard1(v3f v)
+{
glUniform3fv(_uniform_scene_water_fast_uBoard1,1,v);
}
-static void shader_scene_water_fast_uShoreColour(v3f v){
+static inline void shader_scene_water_fast_uShoreColour(v3f v)
+{
glUniform3fv(_uniform_scene_water_fast_uShoreColour,1,v);
}
-static void shader_scene_water_fast_uOceanColour(v3f v){
+static inline void shader_scene_water_fast_uOceanColour(v3f v)
+{
glUniform3fv(_uniform_scene_water_fast_uOceanColour,1,v);
}
-static void shader_scene_water_fast_g_world_depth(int i){
+static inline void shader_scene_water_fast_g_world_depth(int i)
+{
glUniform1i(_uniform_scene_water_fast_g_world_depth,i);
}
-static void shader_scene_water_fast_register(void){
- vg_shader_register( &_shader_scene_water_fast );
-}
-static void shader_scene_water_fast_use(void){ glUseProgram(_shader_scene_water_fast.id); }
-static void shader_scene_water_fast_link(void){
- _uniform_scene_water_fast_uMdl = glGetUniformLocation( _shader_scene_water_fast.id, "uMdl" );
- _uniform_scene_water_fast_uPv = glGetUniformLocation( _shader_scene_water_fast.id, "uPv" );
- _uniform_scene_water_fast_uPvmPrev = glGetUniformLocation( _shader_scene_water_fast.id, "uPvmPrev" );
- _uniform_scene_water_fast_uTexDudv = glGetUniformLocation( _shader_scene_water_fast.id, "uTexDudv" );
- _uniform_scene_water_fast_uTime = glGetUniformLocation( _shader_scene_water_fast.id, "uTime" );
- _uniform_scene_water_fast_uCamera = glGetUniformLocation( _shader_scene_water_fast.id, "uCamera" );
- _uniform_scene_water_fast_uSurfaceY = glGetUniformLocation( _shader_scene_water_fast.id, "uSurfaceY" );
- _uniform_scene_water_fast_uBoard0 = glGetUniformLocation( _shader_scene_water_fast.id, "uBoard0" );
- _uniform_scene_water_fast_uBoard1 = glGetUniformLocation( _shader_scene_water_fast.id, "uBoard1" );
- _uniform_scene_water_fast_uShoreColour = glGetUniformLocation( _shader_scene_water_fast.id, "uShoreColour" );
- _uniform_scene_water_fast_uOceanColour = glGetUniformLocation( _shader_scene_water_fast.id, "uOceanColour" );
- _uniform_scene_water_fast_g_world_depth = glGetUniformLocation( _shader_scene_water_fast.id, "g_world_depth" );
- _uniform_scene_water_fast_uLightsArray = glGetUniformLocation( _shader_scene_water_fast.id, "uLightsArray" );
- _uniform_scene_water_fast_uLightsIndex = glGetUniformLocation( _shader_scene_water_fast.id, "uLightsIndex" );
+static inline void shader_scene_water_fast_use(void);
+static inline void shader_scene_water_fast_use(void)
+{
+ glUseProgram(_shader_scene_water_fast.id);
}
-#endif /* SHADER_scene_water_fast_H */
-#ifndef SHADER_trail_H
-#define SHADER_trail_H
-static void shader_trail_link(void);
-static void shader_trail_register(void);
-static struct vg_shader _shader_trail = {
- .name = "trail",
- .link = shader_trail_link,
- .vs =
+#pragma once
+#include "vg/vg_engine.h"
+extern struct vg_shader _shader_trail;
+extern GLuint _uniform_trail_uPv;
+extern GLuint _uniform_trail_uPvPrev;
+extern GLuint _uniform_trail_uColour;
+static inline void shader_trail_uPv(m4x4f m)
{
-.orig_file = "shaders/trail.vs",
-.static_src =
-"layout (location=0) in vec4 a_co;\n"
-"\n"
-"#line 1 1 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"out vec3 aMotionVec0;\n"
-"out vec3 aMotionVec1;\n"
-"\n"
-"void vs_motion_out( vec4 vproj0, vec4 vproj1 )\n"
-"{\n"
-" // This magically solves some artifacting errors!\n"
-" //\n"
-" vproj1 = vproj0*(1.0-k_motion_lerp_amount) + vproj1*k_motion_lerp_amount;\n"
-"\n"
-" aMotionVec0 = vec3( vproj0.xy, vproj0.w );\n"
-" aMotionVec1 = vec3( vproj1.xy, vproj1.w );\n"
-"}\n"
-"\n"
-"#line 4 0 \n"
-"\n"
-"uniform mat4 uPv;\n"
-"uniform mat4 uPvPrev;\n"
-"\n"
-"out float aAlpha;\n"
-"\n"
-"void main(){\n"
-" vec4 vproj0 = uPv * vec4( a_co.xyz, 1.0 );\n"
-" vec4 vproj1 = uPvPrev * vec4( a_co.xyz, 1.0 );\n"
-" vs_motion_out( vproj0, vproj1 );\n"
-"\n"
-" gl_Position = vproj0;\n"
-" aAlpha = a_co.w;\n"
-"}\n"
-""},
- .fs =
-{
-.orig_file = "shaders/trail.fs",
-.static_src =
-"layout (location = 0) out vec4 oColour;\n"
-"in float aAlpha;\n"
-"uniform vec4 uColour;\n"
-"\n"
-"#line 1 1 \n"
-"const float k_motion_lerp_amount = 0.01;\n"
-"\n"
-"#line 2 0 \n"
-"\n"
-"layout (location = 1) out vec2 oMotionVec;\n"
-"\n"
-"in vec3 aMotionVec0;\n"
-"in vec3 aMotionVec1;\n"
-"\n"
-"void compute_motion_vectors()\n"
-"{\n"
-" // Write motion vectors\n"
-" vec2 vmotion0 = aMotionVec0.xy / aMotionVec0.z;\n"
-" vec2 vmotion1 = aMotionVec1.xy / aMotionVec1.z;\n"
-"\n"
-" oMotionVec = (vmotion1-vmotion0) * (1.0/k_motion_lerp_amount);\n"
-"}\n"
-"\n"
-"#line 6 0 \n"
-"\n"
-"void main(){\n"
-" compute_motion_vectors();\n"
-"\n"
-" vec2 ssuv = gl_FragCoord.xy;\n"
-" vec3 vDither = vec3( dot( vec2( 171.0, 231.0 ), ssuv) );\n"
-" float dither = fract( vDither.g / 71.0 ) - 0.5;\n"
-"\n"
-" if( aAlpha+dither<0.5 )\n"
-" discard;\n"
-"\n"
-" oColour = vec4( uColour.rgb, uColour.a * aAlpha );\n"
-"}\n"
-""},
-};
-
-static GLuint _uniform_trail_uPv;
-static GLuint _uniform_trail_uPvPrev;
-static GLuint _uniform_trail_uColour;
-static void shader_trail_uPv(m4x4f m){
- glUniformMatrix4fv(_uniform_trail_uPv,1,GL_FALSE,(float*)m);
+ glUniformMatrix4fv(_uniform_trail_uPv,1,GL_FALSE,(f32*)m);
}
-static void shader_trail_uPvPrev(m4x4f m){
- glUniformMatrix4fv(_uniform_trail_uPvPrev,1,GL_FALSE,(float*)m);
+static inline void shader_trail_uPvPrev(m4x4f m)
+{
+ glUniformMatrix4fv(_uniform_trail_uPvPrev,1,GL_FALSE,(f32*)m);
}
-static void shader_trail_uColour(v4f v){
+static inline void shader_trail_uColour(v4f v)
+{
glUniform4fv(_uniform_trail_uColour,1,v);
}
-static void shader_trail_register(void){
- vg_shader_register( &_shader_trail );
-}
-static void shader_trail_use(void){ glUseProgram(_shader_trail.id); }
-static void shader_trail_link(void){
- _uniform_trail_uPv = glGetUniformLocation( _shader_trail.id, "uPv" );
- _uniform_trail_uPvPrev = glGetUniformLocation( _shader_trail.id, "uPvPrev" );
- _uniform_trail_uColour = glGetUniformLocation( _shader_trail.id, "uColour" );
+static inline void shader_trail_use(void);
+static inline void shader_trail_use(void)
+{
+ glUseProgram(_shader_trail.id);
}
-#endif /* SHADER_trail_H */
#include "skaterift.h"
#include "steam.h"
#include "render.h"
-#include "audio.h"
#include "vg/vg_opt.h"
+#include "vg/vg_loader.h"
#include "world.h"
#include "vehicle.h"
#include "save.h"
#include "player_remote.h"
-
-/* unity build
- * ----------------- */
-
-#include "world.c"
-#include "player.c"
-#include "vehicle.c"
-#include "entity.c"
-#include "workshop.c"
-#include "addon.c"
-#include "save.c"
-#include "world_map.c"
-#include "network.c"
-#include "player_remote.c"
-#include "vg/vg_audio_dsp.h"
-#include "world_routes_ui.c"
-#include "particle.c"
-#include "player_effects.c"
-#include "freecam.c"
-#include "testing.c"
+#include "particle.h"
#include "trail.h"
-#include "trail.c"
+#include "freecam.h"
+#include "ent_tornado.h"
+#include "ent_miniworld.h"
+#include "ent_skateshop.h"
+#include "world_map.h"
+#include "gui.h"
+#include "workshop.h"
+#include "audio.h"
+#include "player_render.h"
+
+struct skaterift_globals skaterift =
+{
+ .op = k_async_op_clientloading, .time_rate = 1.0f, .demo_mode = 1,
+ .hub_world = "maps/dev_hub",
+};
static int k_tools_mode = 0;
skaterift.op = k_async_op_none;
}
-static void skaterift_restore_state(void){
+static void skaterift_restore_state(void)
+{
savedata_file sav;
- strcpy( sav.path, str_skaterift_main_save );
- savedata_file_read( &sav );
+ skaterift_read_main_savedata( &sav );
vg_msg kvsav;
vg_msg_init( &kvsav, sav.buf, sizeof(sav.buf) );
static void skaterift_load_player_content(void){
u32 bytes = 1024*1024*10;
- skaterift.replay.data = vg_linear_alloc( vg_mem.rtmemory, bytes );
- skaterift.replay.size = bytes;
- replay_clear( &skaterift.replay );
+ player_replay.local.data = vg_linear_alloc( vg_mem.rtmemory, bytes );
+ player_replay.local.size = bytes;
+ replay_clear( &player_replay.local );
particle_alloc( &particles_grind, 300 );
particle_alloc( &particles_env, 200 );
vg_audio.always_keep_compressed = 1;
vg_console_reg_cmd( "load_world", skaterift_load_world_command, NULL );
- vg_console_reg_cmd( "switch_active_instance",
- skaterift_switch_instance_cmd, NULL );
vg_console_reg_cmd( "fc", freecam_cmd, NULL );
vg_console_reg_var( "immobile", &localplayer.immobile, k_var_dtype_i32, 0 );
vg_loader_step( menu_init, NULL );
vg_loader_step( world_init, NULL );
vg_loader_step( vehicle_init, NULL );
- vg_loader_step( font3d_init, NULL );
vg_loader_step( gui_init, NULL );
vg_loader_step( player_init, NULL );
vg_loader_step( workshop_init, NULL );
vg_loader_step( skateshop_init, NULL );
vg_loader_step( ent_tornado_init, NULL );
- vg_loader_step( testing_init, NULL );
- vg_loader_step( trail_init, NULL );
- vg_loader_step( particle_init, NULL );
-
vg_loader_step( skaterift_load_player_content, NULL );
/* --------------------- */
vg_line( (v3f){ 0.0f, 0.0f, 0.0f }, (v3f){ 0.0f, 1.0f, 0.0f }, 0xff00ff00 );
vg_line( (v3f){ 0.0f, 0.0f, 0.0f }, (v3f){ 0.0f, 0.0f, 1.0f }, 0xff0000ff );
}
-static void skaterift_change_client_world_preupdate(void);
+void skaterift_change_client_world_preupdate(void);
/*
* UPDATE LOOP
world_routes_fixedupdate( world_current_instance() );
player__update();
vehicle_update_fixed();
- testing_update();
}
void vg_post_update(void)
audio_unlock();
vehicle_update_post();
-
- if( vg.time - skaterift.last_autosave > 20.0 ){
- if( skaterift_autosave(1) ){
- skaterift.last_autosave = vg.time;
- }
- }
+ skaterift_autosave_update();
}
/*
f32 glitch_strength = 0.0f;
if( skaterift.activity == k_skaterift_replay ){
glitch_strength = 0.005f;
- if( skaterift.replay_control == k_replay_control_play )
+ if( player_replay.replay_control == k_replay_control_play )
glitch_strength = 0.005f;
else
- glitch_strength += 0.005f*skaterift.track_velocity;
+ glitch_strength += 0.005f*player_replay.track_velocity;
}
shader_blitblur_uGlitchStrength( glitch_strength );
}
static void render_player_transparent(void){
- static camera small_cam; /* DOES NOT NEED TO BE STATIC BUT MINGW
+ static vg_camera small_cam; /* DOES NOT NEED TO BE STATIC BUT MINGW
SAIS OTHERWISE */
m4x3_copy( skaterift.cam.transform, small_cam.transform );
small_cam.nearz = 0.05f;
small_cam.farz = 60.0f;
- camera_update_view( &small_cam );
- camera_update_projection( &small_cam );
- camera_finalize( &small_cam );
+ vg_camera_update_view( &small_cam );
+ vg_camera_update_projection( &small_cam );
+ vg_camera_finalize( &small_cam );
/* Draw player to window buffer and blend background ontop */
player__render( &small_cam );
}
static void skaterift_composite_maincamera(void){
- camera_lerp( &localplayer.cam, &world_static.focus_cam,
+ vg_camera_lerp( &localplayer.cam, &world_static.focus_cam,
vg_smoothstepf(world_static.focus_strength), &skaterift.cam );
- if( skaterift.freecam ){
+ if( player_replay.freecam ){
freecam_preupdate();
- v3_copy( skaterift.replay_freecam.pos, skaterift.cam.pos );
- v3_copy( skaterift.replay_freecam.angles, skaterift.cam.angles );
- skaterift.cam.fov = skaterift.replay_freecam.fov;
+ v3_copy( player_replay.replay_freecam.pos, skaterift.cam.pos );
+ v3_copy( player_replay.replay_freecam.angles, skaterift.cam.angles );
+ skaterift.cam.fov = player_replay.replay_freecam.fov;
}
else {
if( skaterift.activity == k_skaterift_replay ){
- replay_get_camera( &skaterift.replay, &skaterift.cam );
+ replay_get_camera( &player_replay.local, &skaterift.cam );
}
}
skaterift.cam.farz = 2100.0f;
if( skaterift.activity == k_skaterift_world_map ){
- camera_copy( &world_map.cam, &skaterift.cam );
+ vg_camera_copy( &world_map.cam, &skaterift.cam );
skaterift.cam.nearz = 4.0f;
skaterift.cam.farz = 3100.0f;
}
}
}
- camera_update_transform( &skaterift.cam );
- camera_update_view( &skaterift.cam );
- camera_update_projection( &skaterift.cam );
- camera_finalize( &skaterift.cam );
+ vg_camera_update_transform( &skaterift.cam );
+ vg_camera_update_view( &skaterift.cam );
+ vg_camera_update_projection( &skaterift.cam );
+ vg_camera_finalize( &skaterift.cam );
}
static void render_main_game(void){
if( skaterift.activity == k_skaterift_replay ){
- player__animate_from_replay( &skaterift.replay );
+ player__animate_from_replay( &player_replay.local );
}
else{
player__animate();
- skaterift_record_frame( &skaterift.replay,
+ skaterift_record_frame( &player_replay.local,
localplayer.deferred_frame_record );
localplayer.deferred_frame_record = 0;
}
/* composite */
present_view_with_post_processing();
-
skaterift_replay_post_render();
}
remote_players_imgui_world( world_current_instance(), vg.pv, 100.0f, 1 );
}
}
+
+#include "addon.c"
+#include "addon_types.c"
+#include "audio.c"
+#include "ent_challenge.c"
+#include "ent_glider.c"
+#include "entity.c"
+#include "ent_miniworld.c"
+#include "ent_objective.c"
+#include "ent_region.c"
+#include "ent_relay.c"
+#include "ent_route.c"
+#include "ent_skateshop.c"
+#include "ent_tornado.c"
+#include "ent_traffic.c"
+#include "freecam.c"
+#include "menu.c"
+#include "network.c"
+#include "particle.c"
+#include "player_basic_info.c"
+#include "player.c"
+#include "player_common.c"
+#include "player_dead.c"
+#include "player_drive.c"
+#include "player_effects.c"
+#include "player_glide.c"
+#include "player_ragdoll.c"
+#include "player_remote.c"
+#include "player_render.c"
+#include "player_replay.c"
+#include "player_skate.c"
+#include "player_walk.c"
+#include "render.c"
+#include "save.c"
+#include "scene.c"
+#include "steam.c"
+#include "trail.c"
+#include "vehicle.c"
+#include "workshop.c"
+#include "world_audio.c"
+#include "world.c"
+#include "world_entity.c"
+#include "world_gate.c"
+#include "world_gen.c"
+#include "world_load.c"
+#include "world_map.c"
+#include "world_physics.c"
+#include "world_render.c"
+#include "world_routes.c"
+#include "world_routes_ui.c"
+#include "world_sfd.c"
+#include "world_volumes.c"
+#include "world_water.c"
-#ifndef SKATERIFT_H
-#define SKATERIFT_H
-
+#pragma once
#define SKATERIFT_APPID 2103940
-
#include "vg/vg_engine.h"
-#include "world.h"
-#include "addon.h"
-#include "trail.h"
+#include "vg/vg_camera.h"
-enum skaterift_rt {
+enum skaterift_rt
+{
k_skaterift_rt_workshop_preview,
k_skaterift_rt_server_status,
k_skaterift_rt_max
};
-struct{
- enum async_operation{
+struct skaterift_globals
+{
+ enum async_operation
+ {
k_async_op_none,
k_async_op_clientloading,
k_async_op_world_scan,
op;
f32 time_rate;
- camera cam;
+ vg_camera cam;
- replay_buffer replay;
- replay_frame *resume_target;
- f64 resume_begin;
- f32 resume_transition;
-
- enum replay_control {
- k_replay_control_scrub,
- k_replay_control_play,
- k_replay_control_resume
- }
- replay_control;
- f32 track_velocity;
- struct gui_helper *helper_resume, *helper_freecam;
-
- camera replay_freecam;
- i32 freecam;
- v3f freecam_v, freecam_w;
-
enum skaterift_activity {
k_skaterift_default = 0x00,
k_skaterift_replay = 0x01,
k_skaterift_world_map = 0x08,
}
activity;
-
- f64 last_autosave;
GLuint rt_textures[k_skaterift_rt_max];
u32 achievements;
int demo_mode;
- audio_channel *aud_air;
const char *hub_world;
-
- struct trail_system test_trail;
}
-static skaterift = {
- .op = k_async_op_clientloading, .time_rate = 1.0f, .demo_mode = 1,
- .hub_world = "maps/dev_hub",
- .test_trail = {
- .max = 80
- }
-};
-
-/* Skaterift api */
-static void skaterift_change_world_start( addon_reg *reg );
-static int skaterift_change_world_command( int argc, const char *argv[] );
-
-#endif /* SKATERIFT_H */
+extern skaterift;
* Copyright (C) 2021-2022 Mt.ZERO Software, Harry Godden - All Rights Reserved
*/
-#ifndef SKELETON_H
-#define SKELETON_H
-
+#pragma once
+#include "vg/vg_lines.h"
#include "model.h"
struct skeleton
vg_line( p0, p1, 0xff00ffff );
}
}
-
-#endif /* SKELETON_H */
--- /dev/null
+#include "vg/vg_steam.h"
+#include "vg/vg_steam_utils.h"
+#include "vg/vg_steam_networking.h"
+#include "vg/vg_steam_auth.h"
+#include "vg/vg_steam_http.h"
+#include "vg/vg_steam_friends.h"
+#include "vg/vg_steam_user_stats.h"
+#include "submodules/anyascii/impl/c/anyascii.c"
+#include "skaterift.h"
+#include <string.h>
+
+/*
+ * We only want to use steamworks if building for the networked version,
+ * theres not much point otherwise. We mainly want steamworks for setting
+ * achievements etc.. so that includes our own server too.
+ *
+ * This file also wraps the functions and interfaces that we want to use to
+ * make them a bit easier to read, since they are the flat API they have very
+ * long names. in non-networked builds they will return default errors or do
+ * nothing.
+ */
+
+char steam_username_at_startup[128] = "Unassigned";
+
+static void recv_steam_warning( int severity, const char *msg )
+{
+ if( severity == 0 )
+ vg_low( "%s\n", msg );
+ else
+ vg_info( "%s\n", msg );
+}
+
+int steam_ready = 0,
+ steam_stats_ready = 0;
+
+void *hSteamNetworkingSockets, *hSteamUser, *hSteamUserStats;
+static HSteamPipe hSteamClientPipe;
+
+static const char *steam_achievement_names[] =
+{
+ "ALBERT", "MARC", "JANET", "BERNADETTA",
+ "ROUTE_MPY", "ROUTE_MPG", "ROUTE_MPB", "ROUTE_MPR",
+ "ROUTE_TO", "ROUTE_TC", "CITY_COMPLETE", "MTZERO_SILVER", "MTZERO_GOLD",
+ "80FT"
+};
+
+void steam_store_achievements(void)
+{
+ if( steam_ready && steam_stats_ready ){
+ SteamAPI_ISteamUserStats_StoreStats( hSteamUserStats );
+ }
+}
+
+void update_ach_models(void);
+void steam_set_achievement( const char *name )
+{
+ if( skaterift.demo_mode )
+ return;
+
+ /* hack lol */
+ if( !strcmp(name,"MARC") ) skaterift.achievements |= 0x1;
+ if( !strcmp(name,"ALBERT") ) skaterift.achievements |= 0x2;
+ if( !strcmp(name,"JANET") ) skaterift.achievements |= 0x4;
+ if( !strcmp(name,"BERNADETTA") ) skaterift.achievements |= 0x8;
+ update_ach_models();
+
+ if( steam_ready && steam_stats_ready ){
+ if( SteamAPI_ISteamUserStats_SetAchievement( hSteamUserStats, name ) ){
+ vg_success( "Achievement set! '%s'\n", name );
+
+ }
+ else{
+ vg_warn( "Failed to set achievement: %s\n", name );
+ }
+ }
+ else{
+ vg_warn( "Failed to set achievement (steam not ready): %s\n", name );
+ }
+}
+
+void steam_clear_achievement( const char *name )
+{
+ if( steam_ready && steam_stats_ready ){
+ if( SteamAPI_ISteamUserStats_ClearAchievement( hSteamUserStats, name ) ){
+ vg_info( "Achievement cleared: '%s'\n", name );
+ }
+ else{
+ vg_warn( "Failed to clear achievement: %s\n", name );
+ }
+ }
+ else{
+ vg_warn( "Failed to clear achievement (steam not ready): %s\n", name );
+ }
+}
+
+
+void steam_print_all_achievements(void)
+{
+ vg_info( "Achievements: \n" );
+
+ if( steam_ready && steam_stats_ready ){
+ for( int i=0; i<vg_list_size(steam_achievement_names); i++ ){
+ steamapi_bool set = 0;
+ const char *name = steam_achievement_names[i];
+
+ if( SteamAPI_ISteamUserStats_GetAchievement(
+ hSteamUserStats, name, &set ) )
+ {
+ vg_info( " %s %s\n", (set? "[YES]": "[ ]"), name );
+ }
+ else{
+ vg_warn( " Error while fetching achievement status '%s'\n", name );
+ }
+ }
+ }
+ else{
+ vg_warn( " Steam is not initialized, no results\n" );
+ }
+}
+
+int steam_achievement_ccmd( int argc, char const *argv[] )
+{
+ if( !(steam_ready && steam_stats_ready) ) return 1;
+
+ if( argc == 1 ){
+ if( !strcmp( argv[0], "list" ) ){
+ steam_print_all_achievements();
+ return 0;
+ }
+ else if( !strcmp( argv[0], "clearall" )){
+ for( int i=0; i<vg_list_size(steam_achievement_names); i++ )
+ steam_clear_achievement( steam_achievement_names[i] );
+
+ steam_store_achievements();
+ }
+ }
+
+ if( argc == 2 ){
+ if( !strcmp( argv[0], "set" ) ){
+ steam_set_achievement( argv[1] );
+ steam_store_achievements();
+ return 0;
+ }
+ else if( strcmp( argv[0], "clear" ) ){
+ steam_clear_achievement( argv[1] );
+ steam_store_achievements();
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static void steam_on_recieve_current_stats( CallbackMsg_t *msg )
+{
+ UserStatsReceived_t *rec = (UserStatsReceived_t *)msg->m_pubParam;
+
+ if( rec->m_eResult == k_EResultOK ){
+ vg_info( "Recieved stats for: %lu (user: %lu)\n", rec->m_nGameID,
+ rec->m_steamIDUser );
+ steam_stats_ready = 1;
+
+ steamapi_bool set = 0;
+ if( SteamAPI_ISteamUserStats_GetAchievement(
+ hSteamUserStats, "MARC", &set ) ){
+ if( set ) skaterift.achievements |= 0x1;
+ }
+ if( SteamAPI_ISteamUserStats_GetAchievement(
+ hSteamUserStats, "ALBERT", &set ) ){
+ if( set ) skaterift.achievements |= 0x2;
+ }
+ if( SteamAPI_ISteamUserStats_GetAchievement(
+ hSteamUserStats, "JANET", &set ) ){
+ if( set ) skaterift.achievements |= 0x4;
+ }
+ if( SteamAPI_ISteamUserStats_GetAchievement(
+ hSteamUserStats, "BERNADETTA", &set ) ){
+ if( set ) skaterift.achievements |= 0x8;
+ }
+ update_ach_models();
+ }
+ else{
+ vg_error( "Error recieveing stats for user (%u)\n", rec->m_eResult );
+ }
+}
+
+static u32 utf8_byte0_byte_count( u8 char0 )
+{
+ for( u32 k=2; k<4; k++ ){
+ if( !(char0 & (0x80 >> k)) )
+ return k;
+ }
+
+ return 0;
+}
+
+u32 str_utf8_collapse( const char *str, char *buf, u32 length )
+{
+ u8 *ustr = (u8 *)str;
+ u32 utf32_code = 0x00000000;
+ u32 i=0, j=0, utf32_byte_ct=0;
+
+ for(;j < length-1;){
+ if( ustr[i] == 0x00 )
+ break;
+
+ if( ustr[i] & 0x80 ){
+ if( utf32_byte_ct ){
+ utf32_byte_ct --;
+ utf32_code |= (ustr[i] & 0x3F) << (utf32_byte_ct*6);
+
+ if( !utf32_byte_ct ){
+ const char *match;
+ size_t chars = anyascii( utf32_code, &match );
+
+ for( u32 k=0; k<VG_MIN(chars, length-1-j); k++ ){
+ buf[ j++ ] = (u8)match[k];
+ }
+ }
+ }
+ else{
+ utf32_byte_ct = utf8_byte0_byte_count( ustr[i] )-1;
+ utf32_code = ustr[i] & (0x3F >> utf32_byte_ct);
+ utf32_code <<= utf32_byte_ct*6;
+ }
+ }
+ else{
+ utf32_byte_ct = 0x00;
+ buf[j ++] = str[i];
+ }
+
+ i++;
+ }
+
+ buf[j] = 0x00;
+ return j;
+}
+
+int steam_init(void)
+{
+ const char *username = "offline player";
+
+ vg_info( "Initializing steamworks\n" );
+
+ if( !SteamAPI_Init() ){
+ printf("\n");
+ vg_error( "Steamworks failed to initialize\n" );
+ return 1;
+ }
+
+ steam_ready = 1;
+
+ SteamAPI_ManualDispatch_Init();
+
+ /* Connect interfaces */
+ hSteamClientPipe = SteamAPI_GetHSteamPipe();
+ hSteamNetworkingSockets = SteamAPI_SteamNetworkingSockets_SteamAPI();
+ hSteamUser = SteamAPI_SteamUser();
+
+ ISteamUtils *utils = SteamAPI_SteamUtils();
+ SteamAPI_ISteamUtils_SetWarningMessageHook( utils, recv_steam_warning );
+
+ printf("\n");
+ vg_success( "\nSteamworks API running\n" );
+
+ ISteamFriends *hSteamFriends = SteamAPI_SteamFriends();
+ username = SteamAPI_ISteamFriends_GetPersonaName( hSteamFriends );
+
+ /*
+ * Request stats
+ * --------------------------------------------------------
+ */
+ hSteamUserStats = SteamAPI_SteamUserStats();
+ steam_register_callback( k_iUserStatsReceived,
+ steam_on_recieve_current_stats );
+
+ if( !SteamAPI_ISteamUserStats_RequestCurrentStats( hSteamUserStats ) )
+ vg_warn( "No Steam Logon: Cannot request stats\n" );
+
+
+ vg_console_reg_cmd( "ach", steam_achievement_ccmd, NULL );
+
+ /* TODO: On username update callback */
+ str_utf8_collapse( username, steam_username_at_startup,
+ vg_list_size(steam_username_at_startup) );
+
+ return 1;
+}
+
+void steam_update(void)
+{
+ if( steam_ready ){
+ steamworks_event_loop( hSteamClientPipe );
+ }
+}
+
+void steam_end(void)
+{
+ if( steam_ready ){
+ vg_info( "Shutting down\n..." );
+ SteamAPI_Shutdown();
+ }
+}
* All trademarks are property of their respective owners
*/
#pragma once
-#include "vg/vg_steam.h"
-#include "vg/vg_steam_utils.h"
-#include "vg/vg_steam_networking.h"
-#include "vg/vg_steam_auth.h"
-#include "vg/vg_steam_http.h"
-#include "vg/vg_steam_friends.h"
-#include "vg/vg_steam_user_stats.h"
-#include "submodules/anyascii/impl/c/anyascii.c"
-/*
- * We only want to use steamworks if building for the networked version,
- * theres not much point otherwise. We mainly want steamworks for setting
- * achievements etc.. so that includes our own server too.
- *
- * This file also wraps the functions and interfaces that we want to use to
- * make them a bit easier to read, since they are the flat API they have very
- * long names. in non-networked builds they will return default errors or do
- * nothing.
- */
-
-static char steam_username_at_startup[128] = "Unassigned";
-
-static void recv_steam_warning( int severity, const char *msg )
-{
- if( severity == 0 )
- vg_low( "%s\n", msg );
- else
- vg_info( "%s\n", msg );
-}
-
-static int steam_ready = 0,
- steam_stats_ready = 0;
-
-static void *hSteamNetworkingSockets,
- *hSteamUser;
-
-static ISteamUserStats *hSteamUserStats;
-static HSteamPipe hSteamClientPipe;
-
-static const char *steam_achievement_names[] =
-{
- "ALBERT", "MARC", "JANET", "BERNADETTA",
- "ROUTE_MPY", "ROUTE_MPG", "ROUTE_MPB", "ROUTE_MPR",
- "ROUTE_TO", "ROUTE_TC", "CITY_COMPLETE", "MTZERO_SILVER", "MTZERO_GOLD",
- "80FT"
-};
-
-static void steam_store_achievements(void)
-{
- if( steam_ready && steam_stats_ready ){
- SteamAPI_ISteamUserStats_StoreStats( hSteamUserStats );
- }
-}
-
-static void update_ach_models(void);
-static void steam_set_achievement( const char *name ){
- if( skaterift.demo_mode )
- return;
-
- /* hack lol */
- if( !strcmp(name,"MARC") ) skaterift.achievements |= 0x1;
- if( !strcmp(name,"ALBERT") ) skaterift.achievements |= 0x2;
- if( !strcmp(name,"JANET") ) skaterift.achievements |= 0x4;
- if( !strcmp(name,"BERNADETTA") ) skaterift.achievements |= 0x8;
- update_ach_models();
-
- if( steam_ready && steam_stats_ready ){
- if( SteamAPI_ISteamUserStats_SetAchievement( hSteamUserStats, name ) ){
- vg_success( "Achievement set! '%s'\n", name );
-
- }
- else{
- vg_warn( "Failed to set achievement: %s\n", name );
- }
- }
- else{
- vg_warn( "Failed to set achievement (steam not ready): %s\n", name );
- }
-}
-
-static void steam_clear_achievement( const char *name )
-{
- if( steam_ready && steam_stats_ready ){
- if( SteamAPI_ISteamUserStats_ClearAchievement( hSteamUserStats, name ) ){
- vg_info( "Achievement cleared: '%s'\n", name );
- }
- else{
- vg_warn( "Failed to clear achievement: %s\n", name );
- }
- }
- else{
- vg_warn( "Failed to clear achievement (steam not ready): %s\n", name );
- }
-}
-
-
-static void steam_print_all_achievements(void){
- vg_info( "Achievements: \n" );
-
- if( steam_ready && steam_stats_ready ){
- for( int i=0; i<vg_list_size(steam_achievement_names); i++ ){
- steamapi_bool set = 0;
- const char *name = steam_achievement_names[i];
-
- if( SteamAPI_ISteamUserStats_GetAchievement(
- hSteamUserStats, name, &set ) )
- {
- vg_info( " %s %s\n", (set? "[YES]": "[ ]"), name );
- }
- else{
- vg_warn( " Error while fetching achievement status '%s'\n", name );
- }
- }
- }
- else{
- vg_warn( " Steam is not initialized, no results\n" );
- }
-}
-
-static int steam_achievement_ccmd( int argc, char const *argv[] )
-{
- if( !(steam_ready && steam_stats_ready) ) return 1;
-
- if( argc == 1 ){
- if( !strcmp( argv[0], "list" ) ){
- steam_print_all_achievements();
- return 0;
- }
- else if( !strcmp( argv[0], "clearall" )){
- for( int i=0; i<vg_list_size(steam_achievement_names); i++ )
- steam_clear_achievement( steam_achievement_names[i] );
-
- steam_store_achievements();
- }
- }
-
- if( argc == 2 ){
- if( !strcmp( argv[0], "set" ) ){
- steam_set_achievement( argv[1] );
- steam_store_achievements();
- return 0;
- }
- else if( strcmp( argv[0], "clear" ) ){
- steam_clear_achievement( argv[1] );
- steam_store_achievements();
- return 0;
- }
- }
-
- return 1;
-}
-
-static void steam_on_recieve_current_stats( CallbackMsg_t *msg )
-{
- UserStatsReceived_t *rec = (UserStatsReceived_t *)msg->m_pubParam;
-
- if( rec->m_eResult == k_EResultOK ){
- vg_info( "Recieved stats for: %lu (user: %lu)\n", rec->m_nGameID,
- rec->m_steamIDUser );
- steam_stats_ready = 1;
-
- steamapi_bool set = 0;
- if( SteamAPI_ISteamUserStats_GetAchievement(
- hSteamUserStats, "MARC", &set ) ){
- if( set ) skaterift.achievements |= 0x1;
- }
- if( SteamAPI_ISteamUserStats_GetAchievement(
- hSteamUserStats, "ALBERT", &set ) ){
- if( set ) skaterift.achievements |= 0x2;
- }
- if( SteamAPI_ISteamUserStats_GetAchievement(
- hSteamUserStats, "JANET", &set ) ){
- if( set ) skaterift.achievements |= 0x4;
- }
- if( SteamAPI_ISteamUserStats_GetAchievement(
- hSteamUserStats, "BERNADETTA", &set ) ){
- if( set ) skaterift.achievements |= 0x8;
- }
- update_ach_models();
- }
- else{
- vg_error( "Error recieveing stats for user (%u)\n", rec->m_eResult );
- }
-}
-
-static u32 utf8_byte0_byte_count( u8 char0 )
-{
- for( u32 k=2; k<4; k++ ){
- if( !(char0 & (0x80 >> k)) )
- return k;
- }
-
- return 0;
-}
-
-static u32 str_utf8_collapse( const char *str, char *buf, u32 length ){
- u8 *ustr = (u8 *)str;
- u32 utf32_code = 0x00000000;
- u32 i=0, j=0, utf32_byte_ct=0;
-
- for(;j < length-1;){
- if( ustr[i] == 0x00 )
- break;
-
- if( ustr[i] & 0x80 ){
- if( utf32_byte_ct ){
- utf32_byte_ct --;
- utf32_code |= (ustr[i] & 0x3F) << (utf32_byte_ct*6);
-
- if( !utf32_byte_ct ){
- const char *match;
- size_t chars = anyascii( utf32_code, &match );
-
- for( u32 k=0; k<VG_MIN(chars, length-1-j); k++ ){
- buf[ j++ ] = (u8)match[k];
- }
- }
- }
- else{
- utf32_byte_ct = utf8_byte0_byte_count( ustr[i] )-1;
- utf32_code = ustr[i] & (0x3F >> utf32_byte_ct);
- utf32_code <<= utf32_byte_ct*6;
- }
- }
- else{
- utf32_byte_ct = 0x00;
- buf[j ++] = str[i];
- }
-
- i++;
- }
-
- buf[j] = 0x00;
- return j;
-}
-
-static int steam_init(void){
- const char *username = "offline player";
-
- vg_info( "Initializing steamworks\n" );
-
- if( !SteamAPI_Init() ){
- printf("\n");
- vg_error( "Steamworks failed to initialize\n" );
- return 1;
- }
-
- steam_ready = 1;
-
- SteamAPI_ManualDispatch_Init();
-
- /* Connect interfaces */
- hSteamClientPipe = SteamAPI_GetHSteamPipe();
- hSteamNetworkingSockets = SteamAPI_SteamNetworkingSockets_SteamAPI();
- hSteamUser = SteamAPI_SteamUser();
-
- ISteamUtils *utils = SteamAPI_SteamUtils();
- SteamAPI_ISteamUtils_SetWarningMessageHook( utils, recv_steam_warning );
-
- printf("\n");
- vg_success( "\nSteamworks API running\n" );
-
- ISteamFriends *hSteamFriends = SteamAPI_SteamFriends();
- username = SteamAPI_ISteamFriends_GetPersonaName( hSteamFriends );
-
- /*
- * Request stats
- * --------------------------------------------------------
- */
- hSteamUserStats = SteamAPI_SteamUserStats();
- steam_register_callback( k_iUserStatsReceived,
- steam_on_recieve_current_stats );
-
- if( !SteamAPI_ISteamUserStats_RequestCurrentStats( hSteamUserStats ) )
- vg_warn( "No Steam Logon: Cannot request stats\n" );
-
-
- vg_console_reg_cmd( "ach", steam_achievement_ccmd, NULL );
-
- /* TODO: On username update callback */
- str_utf8_collapse( username, steam_username_at_startup,
- vg_list_size(steam_username_at_startup) );
-
- return 1;
-}
-
-static void steam_update(void)
-{
- if( steam_ready ){
- steamworks_event_loop( hSteamClientPipe );
- }
-}
-
-static void steam_end(void)
-{
- if( steam_ready ){
- vg_info( "Shutting down\n..." );
- SteamAPI_Shutdown();
- }
-}
+extern int steam_ready, steam_stats_ready;
+extern void *hSteamNetworkingSockets, *hSteamUser, *hSteamUserStats;
+extern char steam_username_at_startup[128];
+
+int steam_init(void);
+void steam_update(void);
+void steam_end(void);
+u32 str_utf8_collapse( const char *str, char *buf, u32 length );
+int steam_achievement_ccmd( int argc, char const *argv[] );
+void steam_print_all_achievements(void);
+void steam_clear_achievement( const char *name );
+void steam_set_achievement( const char *name );
+void steam_store_achievements(void);
+++ /dev/null
-#pragma once
-#include "vg/vg_m.h"
-#include "vg/vg_rigidbody.h"
-#include "vg/vg_input.h"
-#include "scene_rigidbody.h"
-
-struct {
- rigidbody rb;
- boxf box;
-}
-static baller = {
- .rb.q = { 0,0,0,1 },
- .box = {{ -0.1f, -0.2f, -0.1f },
- { 0.1f, 1.0f, 0.1f }},
-};
-
-static void testing_update(void){
- if( !vg_console.cheats )
- return;
-
- if( vg_getkey( SDLK_9 ) ){
- v3_add( localplayer.rb.co, (v3f){0,1,0}, baller.rb.co );
- v3_zero( baller.rb.w );
- v3_zero( baller.rb.v );
- q_identity( baller.rb.q );
- rb_update_matrices( &baller.rb );
- }
-
- if( vg_getkey( SDLK_8 ) ){
- localplayer.have_glider = 1;
- localplayer.glider_orphan = 0;
- player_glide.t = -1.0f;
- }
-
- vg_line_boxf_transformed( baller.rb.to_world, baller.box, VG__RED );
-
- world_instance *world = world_current_instance();
-
- rigidbody _null = {0};
- _null.inv_mass = 0.0f;
- m3x3_zero( _null.iI );
-
- rb_solver_reset();
- rb_ct *buf = rb_global_buffer();
- rb_contact_count += rb_box__scene( baller.rb.to_world, baller.box,
- NULL, world->geo_bh, buf,
- k_material_flag_ghosts );
- for( u32 j=0; j<rb_contact_count; j++ ){
- buf[j].rba = &baller.rb;
- buf[j].rbb = &_null;
- }
-
- rb_presolve_contacts( rb_contact_buffer,
- vg.time_fixed_delta, rb_contact_count );
-
- for( u32 i=0; i<8; i ++ )
- rb_solve_contacts( rb_contact_buffer, rb_contact_count );
-
- rb_iter( &baller.rb );
- rb_update_matrices( &baller.rb );
-}
-
-static void testing_init(void){
- rb_setbody_box( &baller.rb, baller.box, 8.0f, 1.0f );
-}
#pragma once
+#include "vg/vg_engine.h"
+#include "vg/vg_platform.h"
+#include "vg/vg_m.h"
+#include "vg/vg_lines.h"
+#include "vg/vg_async.h"
+#include "vg/vg_camera.h"
#include "trail.h"
#include "shaders/particle.h"
#include "shaders/trail.h"
sys->count ++;
}
-static void trail_system_update( trail_system *sys, f32 dt,
- v3f co, v3f normal, f32 alpha ){
+void trail_system_update( trail_system *sys, f32 dt,
+ v3f co, v3f normal, f32 alpha )
+{
/* update existing points and clip dead ones */
bool clip_allowed = 1;
for( i32 i=0; i<sys->count; i ++ ){
pdest->alpha = alpha;
}
-static void trail_system_debug( trail_system *sys ){
+void trail_system_debug( trail_system *sys )
+{
for( i32 i=0; i<sys->count; i ++ ){
i32 i0 = sys->head - sys->count + i;
if( i0 < 0 ) i0 += sys->max;
trail_system *sys;
};
-static void async_trail_init( void *payload, u32 size ){
+void async_trail_init( void *payload, u32 size )
+{
struct trail_init_args *args = payload;
trail_system *sys = args->sys;
VG_CHECK_GL_ERR();
}
-static void trail_alloc( trail_system *sys, u32 max ){
+void trail_alloc( trail_system *sys, u32 max )
+{
size_t stride = sizeof(trail_vert);
sys->max = max;
sys->array = vg_linear_alloc( vg_mem.rtmemory, max*sizeof(trail_point) );
vg_async_dispatch( call, async_trail_init );
}
-static void trail_system_prerender( trail_system *sys ){
+void trail_system_prerender( trail_system *sys )
+{
if( sys->count < 2 ) return;
for( i32 i=0; i<sys->count; i ++ ){
glBufferSubData( GL_ARRAY_BUFFER, 0, sys->count*stride*2, sys->vertices );
}
-static void trail_system_render( trail_system *sys, camera *cam ){
+void trail_system_render( trail_system *sys, vg_camera *cam )
+{
if( sys->count < 2 ) return;
glDisable( GL_CULL_FACE );
glEnable( GL_DEPTH_TEST );
glBindVertexArray( sys->vao );
glDrawArrays( GL_TRIANGLE_STRIP, 0, sys->count*2 );
}
-
-static void trail_init( void ){
- shader_trail_register();
-}
-#ifndef TRAIL_H
-#define TRAIL_H
-
-#include "skaterift.h"
+#pragma once
typedef struct trail_system trail_system;
typedef struct trail_point trail_point;
f32 width, lifetime, min_dist;
};
-static void trail_alloc( trail_system *sys, u32 max );
-static void trail_system_update( trail_system *sys, f32 dt,
- v3f co, v3f normal, f32 alpha );
-static void trail_system_debug( trail_system *sys );
-static void trail_system_prerender( trail_system *sys );
-static void trail_system_render( trail_system *sys, camera *cam );
-
-#endif /* TRAIL_H */
+void trail_alloc( trail_system *sys, u32 max );
+void trail_system_update( trail_system *sys, f32 dt, v3f co,
+ v3f normal, f32 alpha );
+void trail_system_debug( trail_system *sys );
+void trail_system_prerender( trail_system *sys );
+void trail_system_render( trail_system *sys, vg_camera *cam );
-#ifndef VEHICLE_C
-#define VEHICLE_C
-
+#include "skaterift.h"
#include "vehicle.h"
#include "scene_rigidbody.h"
-static int spawn_car( int argc, const char *argv[] ){
+struct drivable_vehicle gzoomer =
+{
+ .rb.co = {-2000,-2000,-2000}
+};
+
+int spawn_car( int argc, const char *argv[] )
+{
v3f ra, rb, rx;
v3_copy( skaterift.cam.pos, ra );
v3_muladds( ra, skaterift.cam.transform[2], -10.0f, rb );
return 0;
}
-static void vehicle_init(void){
+void vehicle_init(void)
+{
q_identity( gzoomer.rb.q );
v3_zero( gzoomer.rb.w );
v3_zero( gzoomer.rb.v );
v3_copy((v3f){ 1.0f, -0.25f, 1.5f }, gzoomer.wheels_local[3] );
}
-static void vehicle_wheel_force( int index ){
+void vehicle_wheel_force( int index )
+{
v3f pa, pb, n;
m4x3_mulv( gzoomer.rb.to_world, gzoomer.wheels_local[index], pa );
v3_muladds( pa, gzoomer.rb.to_world[1], -k_car_spring_length, pb );
}
}
-static void vehicle_solve_friction(void){
+void vehicle_solve_friction(void)
+{
rigidbody *rb = &gzoomer.rb;
for( int i=0; i<4; i++ ){
v3f raW;
}
}
-static void vehicle_update_fixed(void)
+void vehicle_update_fixed(void)
{
if( !gzoomer.alive )
return;
rb_update_matrices( rb );
}
-static void vehicle_update_post(void){
+void vehicle_update_post(void)
+{
if( !gzoomer.alive )
return;
vg_line( p0, py, VG__GREEN );
}
}
-
-#endif /* VEHICLE_H */
-#ifndef VEHICLE_H
-#define VEHICLE_H
-
-#include "skaterift.h"
+#pragma once
#include "vg/vg_rigidbody.h"
#include "player.h"
#include "world.h"
v3f tangent_vectors[4][2];
v3f wheels_local[4];
}
-static gzoomer =
-{
- .rb.co = {-2000,-2000,-2000}
-};
-
-static int spawn_car( int argc, const char *argv[] );
-static void vehicle_init(void);
-static void vehicle_wheel_force( int index );
-static void vehicle_solve_friction(void);
-static void vehicle_update_fixed(void);
-static void vehicle_update_post(void);
-
-#endif /* VEHICLE_H */
+extern gzoomer;
+
+int spawn_car( int argc, const char *argv[] );
+void vehicle_init(void);
+void vehicle_wheel_force( int index );
+void vehicle_solve_friction(void);
+void vehicle_update_fixed(void);
+void vehicle_update_post(void);
-#include "workshop.h"
+#include "vg/vg_engine.h"
#include "vg/vg_tex.h"
+#include "vg/vg_image.h"
#include "vg/vg_msg.h"
#include "vg/vg_binstr.h"
#include "vg/vg_loader.h"
#include "vg/vg_steam_ugc.h"
#include "vg/vg_steam_friends.h"
#include "steam.h"
+#include "workshop.h"
+
+struct workshop_form workshop_form;
static struct ui_enum_opt workshop_form_visibility_opts[] = {
{ k_ERemoteStoragePublishedFileVisibilityPublic, "Public" },
/*
* Console command to open the workshop publisher
*/
-static int workshop_submit_command( int argc, const char *argv[] )
+int workshop_submit_command( int argc, const char *argv[] )
{
if( !steam_ready ){
ui_start_modal( "Steam API is not initialized\n", UI_MODAL_BAD );
return 0;
}
-static void workshop_init(void)
+void workshop_init(void)
{
vg_console_reg_cmd( "workshop_submit", workshop_submit_command, NULL );
}
skeleton_apply_inverses( sk, localplayer.final_mtx );
skeleton_apply_transform( sk, transform, localplayer.final_mtx );
- camera cam;
+ vg_camera cam;
v3_copy( (v3f){ 0.0f, 201.7f, 1.2f }, cam.pos );
cam.nearz = 0.01f;
cam.fov = 57.0f;
v3_zero( cam.angles );
- camera_update_transform( &cam );
- camera_update_view( &cam );
- camera_update_projection( &cam );
- camera_finalize( &cam );
+ vg_camera_update_transform( &cam );
+ vg_camera_update_view( &cam );
+ vg_camera_update_projection( &cam );
+ vg_camera_finalize( &cam );
render_playermodel( &cam, world_current_instance(), 0,
&workshop_form.player_model, sk, localplayer.final_mtx );
v3_add( display->transform.co, display1->transform.co, baseco );
v3_muls( baseco, 0.5f, baseco );
- camera cam;
+ vg_camera cam;
v3f basevector;
v3_sub( display->transform.co, ref->transform.co, basevector );
float dist = v3_length( basevector );
cam.farz = 100.0f;
cam.fov = ref->fov;
- camera_update_transform( &cam );
- camera_update_view( &cam );
- camera_update_projection( &cam );
- camera_finalize( &cam );
+ vg_camera_update_transform( &cam );
+ vg_camera_update_view( &cam );
+ vg_camera_update_projection( &cam );
+ vg_camera_finalize( &cam );
m4x3f mmdl, mmdl1;
mdl_transform_m4x3( &display->transform, mmdl );
}
}
-static void workshop_form_gui(void)
+void workshop_form_gui(void)
{
enum workshop_form_page stable_page = workshop_form.page;
if( stable_page == k_workshop_form_hidden ) return;
* -----------------------------------------------------------------------------
*/
-static void async_workshop_get_filepath( void *data, u32 len )
+void async_workshop_get_filepath( void *data, u32 len )
{
struct async_workshop_filepath_info *info = data;
}
}
-static void async_workshop_get_installed_files( void *data, u32 len )
+void async_workshop_get_installed_files( void *data, u32 len )
{
struct async_workshop_installed_files_info *info = data;
published_files_list[WORKSHOP_VIEW_PER_PAGE];
int published_files_list_length;
}
-static workshop_form;
-
-
-
-static int workshop_submit_command( int argc, const char *argv[] );
-static void async_workshop_get_filepath( void *data, u32 len );
-static void async_workshop_get_installed_files( void *data, u32 len );
-static void workshop_load_metadata( const char *path,
- struct workshop_file_info *info );
+extern workshop_form;
+
+void workshop_init(void);
+int workshop_submit_command( int argc, const char *argv[] );
+void async_workshop_get_filepath( void *data, u32 len );
+void async_workshop_get_installed_files( void *data, u32 len );
+void workshop_load_metadata( const char *path,struct workshop_file_info *info );
+void workshop_form_gui(void);
* Copyright (C) 2021-2023 Mt.ZERO Software, Harry Godden - All Rights Reserved
*/
-#ifndef WORLD_C
-#define WORLD_C
-
+#include "skaterift.h"
#include "world.h"
#include "network.h"
#include "vg/vg_loader.h"
#include "vg/vg_mem.h"
+#include "save.h"
+#include "player.h"
+#include "ent_traffic.h"
+
+struct world_static world_static;
-static world_instance *world_current_instance(void){
+world_instance *world_current_instance(void)
+{
return &world_static.instances[ world_static.active_instance ];
}
-static void world_init(void)
+static int skaterift_switch_instance_cmd( int argc, const char *argv[] );
+
+void world_init(void)
{
vg_loader_step( world_render_init, NULL );
vg_loader_step( world_sfd_init, NULL );
u32 max_size = 76*1024*1024;
world_static.heap = vg_create_linear_allocator( vg_mem.rtmemory, max_size,
VG_MEMORY_SYSTEM );
+
+ vg_console_reg_cmd( "switch_active_instance",
+ skaterift_switch_instance_cmd, NULL );
}
-static void world_switch_instance( u32 index ){
+void world_switch_instance( u32 index )
+{
localplayer.subsystem = k_player_subsystem_walk;
if( index >= vg_list_size(world_static.instances) ){
player__reset();
}
-static int skaterift_switch_instance_cmd( int argc, const char *argv[] ){
+static int skaterift_switch_instance_cmd( int argc, const char *argv[] )
+{
if( argc )
world_switch_instance( atoi(argv[0]) );
else
return 0;
}
-static void skaterift_world_get_save_path( enum world_purpose which,
- char buf[128] ){
+void skaterift_world_get_save_path( enum world_purpose which, char buf[128] )
+{
addon_reg *reg = world_static.instance_addons[ which ];
if( !reg )
snprintf( buf, 128, "savedata/%s.bkv", id );
}
-#include "world_entity.c"
-#include "world_gate.c"
-#include "world_gen.c"
-#include "world_load.c"
-#include "world_physics.c"
-#include "world_render.c"
-#include "world_sfd.c"
-#include "world_volumes.c"
-#include "world_water.c"
-#include "world_audio.c"
-#include "world_routes.c"
-
-static void world_update( world_instance *world, v3f pos ){
+void world_update( world_instance *world, v3f pos )
+{
world_render.sky_time += world_render.sky_rate * vg.time_delta;
world_render.sky_rate = vg_lerp( world_render.sky_rate,
world_render.sky_target_rate,
world_sfd_update( world, pos );
world_volumes_update( world, pos );
}
-
-#endif /* WORLD_C */
/*
- * Copyright (C) 2021-2023 Mt.ZERO Software, Harry Godden - All Rights Reserved
+ * Copyright (C) 2021-2024 Mt.ZERO Software, Harry Godden - All Rights Reserved
*/
-#ifndef WORLD_H
-#define WORLD_H
-
+#pragma once
#include "render.h"
#include "network_msg.h"
+#include "addon.h"
/* types
*/
typedef struct world_instance world_instance;
-static void skaterift_world_get_save_path( enum world_purpose which,
- char buf[128] );
+void skaterift_world_get_save_path( enum world_purpose which, char buf[128] );
/* submodule headers */
#include "world_entity.h"
#include "world_gate.h"
#include "world_gen.h"
#include "world_info.h"
-#include "world_load.h"
#include "world_physics.h"
#include "world_render.h"
#include "world_sfd.h"
enum world_purpose active_instance;
u32 focused_entity; /* like skateshop, challenge.. */
f32 focus_strength;
- camera focus_cam;
+ vg_camera focus_cam;
/* challenges */
ent_objective *challenge_target;
}
load_state;
}
-static world_static;
+extern world_static;
-static void world_init(void);
-static world_instance *world_current_instance(void);
-static void world_switch_instance( u32 index );
+struct world_load_args
+{
+ enum world_purpose purpose;
+ addon_reg *reg;
+};
-#endif /* WORLD_H */
+void world_init(void);
+world_instance *world_current_instance(void);
+void world_switch_instance( u32 index );
+void skaterift_world_load_thread( void *_args );
+void world_update( world_instance *world, v3f pos );
-#ifndef WORLD_AUDIO_C
-#define WORLD_AUDIO_C
-
#include "audio.h"
#include "world_audio.h"
/* finds any active playing in world and fades them out, we can only do this
* while unloading */
-static void world_fadeout_audio( world_instance *world )
+void world_fadeout_audio( world_instance *world )
{
if( world->status != k_world_status_unloading ){
vg_fatal_error( "World status must be set to 'unloading', to fadeout"
/*
* Trace out a random point, near the player to try and determine water areas
*/
-static
-enum audio_sprite_type world_audio_sample_sprite_random(v3f origin, v3f output){
+enum audio_sprite_type world_audio_sample_sprite_random(v3f origin, v3f output)
+{
v3f chance = { (vg_randf64(&vg.rand)-0.5f) * 30.0f,
8,
(vg_randf64(&vg.rand)-0.5f) * 30.0f };
return k_audio_sprite_type_none;
}
-static void world_audio_sample_distances( v3f co, int *index, float *value )
+void world_audio_sample_distances( v3f co, int *index, float *value )
{
float inr3 = 0.57735027,
inr2 = 0.70710678118;
if( si >= 14 )
si = 0;
}
-
-#endif /* WORLD_AUDIO_C */
-#ifndef WORLD_AUDIO_H
-#define WORLD_AUDIO_H
-
+#pragma once
#include "world.h"
-static void world_fadeout_audio( world_instance *world );
-static void world_audio_sample_distances( v3f co, int *index, float *value );
-static enum audio_sprite_type world_audio_sample_sprite_random( v3f origin,
- v3f output );
-
-#endif /* WORLD_AUDIO_H */
+void world_fadeout_audio( world_instance *world );
+void world_audio_sample_distances( v3f co, int *index, float *value );
+enum audio_sprite_type
+world_audio_sample_sprite_random( v3f origin, v3f output );
-#ifndef WORLD_ENTITY_C
-#define WORLD_ENTITY_C
-
+#include "vg/vg_steam.h"
+#include "vg/vg_steam_user_stats.h"
#include "model.h"
#include "entity.h"
#include "world.h"
#include "ent_route.h"
#include "ent_traffic.h"
#include "ent_glider.h"
+#include "ent_region.h"
+#include "input.h"
+#include "player_walk.h"
-static void world_entity_focus( u32 entity_id ){
+bh_system bh_system_entity_list =
+{
+ .expand_bound = entity_bh_expand_bound,
+ .item_centroid = entity_bh_centroid,
+ .item_closest = entity_bh_closest,
+ .item_swap = entity_bh_swap,
+ .item_debug = entity_bh_debug,
+ .cast_ray = NULL
+};
+
+void world_entity_focus( u32 entity_id )
+{
localplayer.immobile = 1;
menu.disable_open = 1;
skaterift.activity = k_skaterift_ent_focus;
}
-static void world_entity_unfocus(void){
+void world_entity_unfocus(void)
+{
localplayer.immobile = 0;
skaterift.activity = k_skaterift_default;
menu.disable_open = 0;
srinput.state = k_input_state_resume;
}
-static void world_entity_focus_camera( world_instance *world, u32 uid ){
+void world_entity_focus_camera( world_instance *world, u32 uid )
+{
if( mdl_entity_id_type( uid ) == k_ent_camera ){
u32 index = mdl_entity_id_id( uid );
ent_camera *cam = mdl_arritm( &world->ent_camera, index );
world_static.focus_cam.fov = cam->fov;
}
else {
- camera_copy( &localplayer.cam, &world_static.focus_cam );
+ vg_camera_copy( &localplayer.cam, &world_static.focus_cam );
/* TODO ? */
world_static.focus_cam.nearz = localplayer.cam.nearz;
}
/* logic preupdate */
-static void world_entity_focus_preupdate(void){
+void world_entity_focus_preupdate(void)
+{
f32 rate = vg_minf( 1.0f, vg.time_frame_delta * 2.0f );
int active = 0;
if( skaterift.activity == k_skaterift_ent_focus )
}
/* additional renderings like text etc.. */
-static void world_entity_focus_render(void){
+void world_entity_focus_render(void)
+{
world_instance *world = world_current_instance();
if( skaterift.activity != k_skaterift_ent_focus ){
skateshop_render_nonfocused( world, &skaterift.cam );
}
}
-static void world_gen_entities_init( world_instance *world ){
+void world_gen_entities_init( world_instance *world )
+{
/* lights */
for( u32 j=0; j<mdl_arrcount(&world->ent_light); j ++ ){
ent_light *light = mdl_arritm( &world->ent_light, j );
}
}
-static
ent_spawn *world_find_closest_spawn( world_instance *world, v3f position )
{
ent_spawn *rp = NULL, *r;
return rp;
}
-static
ent_spawn *world_find_spawn_by_name( world_instance *world, const char *name )
{
ent_spawn *rp = NULL, *r;
return rp;
}
-static void world_default_spawn_pos( world_instance *world, v3f pos )
+void world_default_spawn_pos( world_instance *world, v3f pos )
{
ent_spawn *rp = world_find_spawn_by_name( world, "start" );
if( !rp ) rp = world_find_closest_spawn( world, (v3f){0,0,0} );
}
}
-static void ent_volume_call( world_instance *world, ent_call *call ){
+void ent_volume_call( world_instance *world, ent_call *call )
+{
u32 index = mdl_entity_id_id( call->id );
ent_volume *volume = mdl_arritm( &world->ent_volume, index );
if( !volume->target ) return;
}
}
-static void ent_audio_call( world_instance *world, ent_call *call ){
+void ent_audio_call( world_instance *world, ent_call *call )
+{
if( world->status == k_world_status_unloading ){
vg_warn( "cannot modify audio while unloading world\n" );
return;
}
-static void ent_ccmd_call( world_instance *world, ent_call *call ){
+void ent_ccmd_call( world_instance *world, ent_call *call )
+{
if( call->function == k_ent_function_trigger ){
u32 index = mdl_entity_id_id( call->id );
ent_ccmd *ccmd = mdl_arritm( &world->ent_ccmd, index );
* ----------------------------------------------------------------------------
*/
-static void
-entity_bh_expand_bound( void *user, boxf bound, u32 item_index ){
+void entity_bh_expand_bound( void *user, boxf bound, u32 item_index )
+{
world_instance *world = user;
u32 id = world->entity_list[ item_index ],
}
}
-static float entity_bh_centroid( void *user, u32 item_index, int axis ){
+float entity_bh_centroid( void *user, u32 item_index, int axis )
+{
world_instance *world = user;
u32 id = world->entity_list[ item_index ],
}
}
-static void entity_bh_swap( void *user, u32 ia, u32 ib ){
+void entity_bh_swap( void *user, u32 ia, u32 ib )
+{
world_instance *world = user;
u32 a = world->entity_list[ ia ],
world->entity_list[ ib ] = a;
}
-static void entity_bh_debug( void *user, u32 item_index ){
+void entity_bh_debug( void *user, u32 item_index ){
world_instance *world = user;
u32 id = world->entity_list[ item_index ],
}
}
-static void update_ach_models(void){
+void update_ach_models(void)
+{
world_instance *hub = &world_static.instances[k_world_purpose_hub];
if( hub->status != k_world_status_loaded ) return;
}
}
-static void entity_bh_closest( void *user, u32 item_index, v3f point,
- v3f closest ){
+void entity_bh_closest( void *user, u32 item_index, v3f point, v3f closest )
+{
world_instance *world = user;
u32 id = world->entity_list[ item_index ],
}
}
-static void world_entity_start( world_instance *world, vg_msg *sav ){
+void world_entity_start( world_instance *world, vg_msg *sav )
+{
vg_info( "Start instance %p\n", world );
world->probabilities[ k_probability_curve_constant ] = 1.0f;
ent_region_re_eval( world );
}
-static void world_entity_serialize( world_instance *world, vg_msg *sav ){
+void world_entity_serialize( world_instance *world, vg_msg *sav )
+{
for( u32 i=0; i<mdl_arrcount(&world->ent_challenge); i++ ){
ent_challenge *challenge = mdl_arritm(&world->ent_challenge,i);
vg_msg_end_frame( sav );
}
}
-
-#endif /* WORLD_ENTITY_C */
-#ifndef WORLD_ENTITY_H
-#define WORLD_ENTITY_H
-
+#pragma once
#include "world.h"
#include "entity.h"
-#include "bvh.h"
-#include "save.h"
+#include "vg/vg_bvh.h"
#include "vg/vg_msg.h"
-static void world_gen_entities_init( world_instance *world );
-static ent_spawn *world_find_spawn_by_name( world_instance *world,
- const char *name );
-static ent_spawn *world_find_closest_spawn( world_instance *world,
- v3f position );
-static void world_default_spawn_pos( world_instance *world, v3f pos );
-static void world_entity_start( world_instance *world, vg_msg *sav );
-static void world_entity_serialize( world_instance *world, vg_msg *sav );
-
-static void ent_volume_call( world_instance *world, ent_call *call );
-static void ent_audio_call( world_instance *world, ent_call *call );
-static void ent_ccmd_call( world_instance *world, ent_call *call );
+void world_gen_entities_init( world_instance *world );
+ent_spawn *world_find_spawn_by_name( world_instance *world,
+ const char *name );
+ent_spawn *world_find_closest_spawn( world_instance *world,
+ v3f position );
+void world_default_spawn_pos( world_instance *world, v3f pos );
+void world_entity_start( world_instance *world, vg_msg *sav );
+void world_entity_serialize( world_instance *world, vg_msg *sav );
-static void entity_bh_expand_bound( void *user, boxf bound, u32 item_index );
-static float entity_bh_centroid( void *user, u32 item_index, int axis );
-static void entity_bh_swap( void *user, u32 ia, u32 ib );
-static void entity_bh_debug( void *user, u32 item_index );
-static void entity_bh_closest( void *user, u32 item_index, v3f point,
- v3f closest );
+void ent_volume_call( world_instance *world, ent_call *call );
+void ent_audio_call( world_instance *world, ent_call *call );
+void ent_ccmd_call( world_instance *world, ent_call *call );
-static void world_entity_focus( u32 entity_id );
-static void world_entity_focus_preupdate(void);
-static void world_entity_focus_render(void);
-static void world_entity_unfocus();
-static void world_entity_focus_camera( world_instance *world, u32 uid );
+void entity_bh_expand_bound( void *user, boxf bound, u32 item_index );
+float entity_bh_centroid( void *user, u32 item_index, int axis );
+void entity_bh_swap( void *user, u32 ia, u32 ib );
+void entity_bh_debug( void *user, u32 item_index );
+void entity_bh_closest( void *user, u32 item_index, v3f point,
+ v3f closest );
-static bh_system bh_system_entity_list = {
- .expand_bound = entity_bh_expand_bound,
- .item_centroid = entity_bh_centroid,
- .item_closest = entity_bh_closest,
- .item_swap = entity_bh_swap,
- .item_debug = entity_bh_debug,
- .cast_ray = NULL
-};
+void world_entity_focus( u32 entity_id );
+void world_entity_focus_preupdate(void);
+void world_entity_focus_render(void);
+void world_entity_unfocus();
+void world_entity_focus_camera( world_instance *world, u32 uid );
+void update_ach_models(void);
-#endif /* WORLD_ENTITY_H */
+extern bh_system bh_system_entity_list;
#include "model.h"
#include "entity.h"
#include "render.h"
-#include "camera.h"
#include "world_water.h"
#include "player_remote.h"
#include "shaders/model_gate_unlinked.h"
+struct world_gates world_gates;
+
/*
* Update the transform matrices for gate
*/
-static void gate_transform_update( ent_gate *gate ){
+void gate_transform_update( ent_gate *gate )
+{
if( gate->flags & k_ent_gate_flip ){
v4f qflip;
q_axis_angle( qflip, (v3f){0.0f,1.0f,0.0f}, VG_PIf );
m4x3_mul( recv_to_world, to_local, gate->transport );
}
-static void world_gates_init(void)
+void world_gates_init(void)
{
vg_info( "world_gates_init\n" );
-
- shader_model_gate_register();
- shader_model_gate_unlinked_register();
-
vg_linear_clear( vg_mem.scratch );
mdl_context mgate;
mdl_close( &mgate );
}
-static void ent_gate_get_mdl_mtx( ent_gate *gate, m4x3f mmdl ){
+void ent_gate_get_mdl_mtx( ent_gate *gate, m4x3f mmdl )
+{
m4x3_copy( gate->to_world, mmdl );
if( !(gate->flags & k_ent_gate_custom_mesh) ){
}
}
-static void render_gate_mesh( world_instance *world, ent_gate *gate ){
+static void render_gate_mesh( world_instance *world, ent_gate *gate )
+{
if( gate->flags & k_ent_gate_custom_mesh ){
mesh_bind( &world->mesh_no_collide );
for( u32 i=0; i<gate->submesh_count; i++ ){
/*
* Render the view through a gate
*/
-static int render_gate( world_instance *world, world_instance *world_inside,
- ent_gate *gate, camera *cam ){
+int render_gate( world_instance *world, world_instance *world_inside,
+ ent_gate *gate, vg_camera *cam )
+{
v3f viewdir, gatedir;
m3x3_mulv( cam->transform, (v3f){0.0f,0.0f,-1.0f}, viewdir );
q_mulv( gate->q[0], (v3f){0.0f,0.0f,-1.0f}, gatedir );
world_gates.cam.farz = 2000.0f;
m4x3_mul( gate->transport, cam->transform, world_gates.cam.transform );
- camera_update_view( &world_gates.cam );
- camera_update_projection( &world_gates.cam );
+ vg_camera_update_view( &world_gates.cam );
+ vg_camera_update_projection( &world_gates.cam );
/* Add special clipping plane to projection */
v4f surface;
m4x4_clip_projection( world_gates.cam.mtx.p, surface );
/* Ready to draw with new camrea */
- camera_finalize( &world_gates.cam );
+ vg_camera_finalize( &world_gates.cam );
vg_line_point( world_gates.cam.transform[3], 0.3f, 0xff00ff00 );
return 1;
}
-static void render_gate_unlinked( world_instance *world,
- ent_gate *gate, camera *cam ){
+void render_gate_unlinked( world_instance *world,
+ ent_gate *gate, vg_camera *cam )
+{
m4x3f mmdl; m4x4f m4mdl;
ent_gate_get_mdl_mtx( gate, mmdl );
m4x3_expand( mmdl, m4mdl );
/*
* Intersect specific gate
*/
-static int gate_intersect( ent_gate *gate, v3f pos, v3f last ){
+int gate_intersect( ent_gate *gate, v3f pos, v3f last )
+{
v2f xy;
if( gate_intersect_plane( gate, pos, last, xy ) ){
/*
* Intersect all gates in the world
*/
-static u32 world_intersect_gates( world_instance *world, v3f pos, v3f last ){
+u32 world_intersect_gates( world_instance *world, v3f pos, v3f last )
+{
for( u32 i=0; i<mdl_arrcount(&world->ent_gate); i++ ){
ent_gate *gate = mdl_arritm( &world->ent_gate, i );
return 0;
}
-static void ent_gate_call( world_instance *world, ent_call *call ){
+void ent_gate_call( world_instance *world, ent_call *call )
+{
u32 index = mdl_entity_id_id( call->id );
ent_gate *gate = mdl_arritm( &world->ent_gate, index );
/*
* detatches any nonlocal gates
*/
-static void world_unlink_nonlocal( world_instance *world ){
+void world_unlink_nonlocal( world_instance *world )
+{
for( u32 j=0; j<mdl_arrcount(&world->ent_gate); j ++ ){
ent_gate *gate = mdl_arritm( &world->ent_gate, j );
/*
* attatches nonlocal gates, to be called from main thread ONLY!
*/
-static void world_link_nonlocal_async( void *payload, u32 size ){
+void world_link_nonlocal_async( void *payload, u32 size )
+{
world_instance *world = payload;
u32 world_id = world - world_static.instances;
/*
- * Copyright (C) 2021-2023 Mt.ZERO Software, Harry Godden - All Rights Reserved
+ * Copyright (C) 2021-2024 Mt.ZERO Software, Harry Godden - All Rights Reserved
*/
-#ifndef WORLD_GATE_H
-#define WORLD_GATE_H
+#pragma once
-#include "camera.h"
+#include "vg/vg_camera.h"
#include "world.h"
#include "shaders/model_gate.h"
-struct world_gates{
+struct world_gates
+{
glmesh mesh;
mdl_submesh sm_surface, sm_marker[4];
- camera cam;
+ vg_camera cam;
v3f userportal_co;
}
-static world_gates;
+extern world_gates;
-static void world_gates_init(void);
-static void gate_transform_update( ent_gate *gate );
-static int render_gate( world_instance *world, world_instance *world_inside,
- ent_gate *gate, camera *cam );
+void world_gates_init(void);
+void gate_transform_update( ent_gate *gate );
+int render_gate( world_instance *world, world_instance *world_inside,
+ ent_gate *gate, vg_camera *cam );
-static int gate_intersect( ent_gate *gate, v3f pos, v3f last );
-static u32 world_intersect_gates( world_instance *world, v3f pos, v3f last );
+int gate_intersect( ent_gate *gate, v3f pos, v3f last );
+u32 world_intersect_gates( world_instance *world, v3f pos, v3f last );
-static void ent_gate_call( world_instance *world, ent_call *call );
-static void ent_gate_get_mdl_mtx( ent_gate *gate, m4x3f mmdl );
+void ent_gate_call( world_instance *world, ent_call *call );
+void ent_gate_get_mdl_mtx( ent_gate *gate, m4x3f mmdl );
-static void world_link_nonlocal_async( void *payload, u32 size );
-static void world_unlink_nonlocal( world_instance *world );
-static void render_gate_unlinked( world_instance *world,
- ent_gate *gate, camera *cam );
-
-#endif /* WORLD_GATE_H */
+void world_link_nonlocal_async( void *payload, u32 size );
+void world_unlink_nonlocal( world_instance *world );
+void render_gate_unlinked( world_instance *world,
+ ent_gate *gate, vg_camera *cam );
* World generation/population. Different to regular loading, since it needs to
* create geometry, apply procedural stuff and save that image to files etc.
*/
-
-#ifndef WORLD_GEN_C
-#define WORLD_GEN_C
-
#include "world.h"
#include "world_gen.h"
#include "world_load.h"
/*
* Rendering the depth map
*/
- camera ortho;
+ vg_camera ortho;
v3f extent;
v3_sub( world->scene_geo.bbx[1], world->scene_geo.bbx[0], extent );
ortho.mtx.p[3][1] = (ft + fb) * -tb;
ortho.mtx.p[3][3] = 1.0f;
m4x3_identity( ortho.transform );
- camera_update_view( &ortho );
- camera_finalize( &ortho );
+ vg_camera_update_view( &ortho );
+ vg_camera_finalize( &ortho );
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
surf->flags = 0;
}
}
-
-#endif /* WORLD_GEN_C */
world_static.load_state = k_world_loader_none;
}
-struct world_load_args {
- enum world_purpose purpose;
- addon_reg *reg;
-};
-
/*
* Does a complete world switch using the remaining free slots
*/
-static void skaterift_world_load_thread( void *_args ){
+void skaterift_world_load_thread( void *_args )
+{
struct world_load_args args = *((struct world_load_args *)_args);
addon_reg *reg = args.reg;
/* holding pattern before we can start loading the new world, since we might be
* waiting for audio to stop */
-static void skaterift_change_client_world_preupdate(void){
+void skaterift_change_client_world_preupdate(void)
+{
for( u32 i=1; i<k_world_max; i++ ){
world_instance *inst = &world_static.instances[i];
}
/* places all loaded worlds into unloading state */
-static void skaterift_change_world_start( addon_reg *reg ){
+void skaterift_change_world_start( addon_reg *reg )
+{
if( world_static.active_instance != 0 )
vg_error( "Cannot change worlds while in non-root world\n" );
else{
}
/* console command for the above function */
-static int skaterift_load_world_command( int argc, const char *argv[] )
+int skaterift_load_world_command( int argc, const char *argv[] )
{
if( !vg_loader_availible() )
{
* 1. to see if all audios owned by the world have been stopped
* 2. that this is the least significant world
*/
-static int world_freeable( world_instance *world ){
+int world_freeable( world_instance *world )
+{
if( world->status != k_world_status_unloading ) return 0;
u8 world_id = (world - world_static.instances) + 1;
/*
* Free all resources for world instance
*/
-static void world_free( world_instance *world ){
+void world_free( world_instance *world )
+{
vg_info( "Free world @%p\n", world );
/* free meshes */
-#ifndef WORLD_LOAD_H
-#define WORLD_LOAD_H
-
+#pragma once
#include <time.h>
#include "world.h"
-#include "world_gen.h"
-#include "world_routes.h"
-#include "world_entity.h"
-#include "world_volumes.h"
#include "addon.h"
-static void world_free( world_instance *world );
-static int world_freeable( world_instance *world );
-static int skaterift_load_world_command( int argc, const char *argv[] );
-
-#endif /* WORLD_LOAD_H */
+void world_free( world_instance *world );
+int world_freeable( world_instance *world );
+int skaterift_load_world_command( int argc, const char *argv[] );
+void skaterift_change_world_start( addon_reg *reg );
+void skaterift_change_client_world_preupdate(void);
-#ifndef RESPAWN_C
-#define RESPAWN_C
-
-#include "world_map.h"
#include "skaterift.h"
+#include "world_map.h"
#include "world.h"
#include "input.h"
#include "gui.h"
#include "menu.h"
#include "scene.h"
+struct world_map world_map;
+
static void world_map_get_dir( v3f dir ){
/* idk */
dir[0] = -sqrtf(0.5f);
plane_pos[1] = co[2];
}
-static void respawn_map_draw_icon( camera *cam,
- enum gui_icon icon, v3f pos ){
+static void respawn_map_draw_icon( vg_camera *cam,
+ enum gui_icon icon, v3f pos ){
v4f v;
v3_copy( pos, v );
v[3] = 1.0f;
gui_draw_icon( icon, (v2f){ v[0]*0.5f+0.5f,v[1]*0.5f+0.5f }, 1.0f );
}
-static void world_map_pre_update(void){
+void world_map_pre_update(void)
+{
if( skaterift.activity != k_skaterift_world_map ) return;
if( button_down( k_srbind_mback ) ){
v2_maxv( (v2f){ bbx[0][0], bbx[0][2] }, pos, pos );
/* update camera */
- camera *cam = &world_map.cam;
+ vg_camera *cam = &world_map.cam;
v3f dir;
world_map_get_dir(dir);
cam->nearz = 10.0f;
cam->fov = 40.0f;
- camera_update_transform( cam );
- camera_update_view( cam );
- camera_update_projection( cam );
- camera_finalize( cam );
+ vg_camera_update_transform( cam );
+ vg_camera_update_view( cam );
+ vg_camera_update_projection( cam );
+ vg_camera_finalize( cam );
/* pick spawn */
world_map.spawn = NULL;
}
}
-static void world_map_enter(void){
+void world_map_enter(void)
+{
skaterift.activity = k_skaterift_world_map;
world_map.world_id = world_static.active_instance;
if( gui_new_helper( input_button_list[k_srbind_mback], &text ) )
vg_strcat( &text, "exit" );
}
-
-#endif /* RESPAWN_C */
-#ifndef RESPAWN_H
-#define RESPAWN_H
+#pragma once
+#include "vg/vg_platform.h"
+#include "vg/vg_camera.h"
+#include "world_entity.h"
-#include "skaterift.h"
-
-struct {
+struct world_map
+{
v2f plane_pos;
f32 boom_dist;
u32 world_id;
u32 home_select;
ent_spawn *spawn;
- camera cam;
+ vg_camera cam;
}
-static world_map;
-static void world_map_enter(void);
-
-#endif /* RESPAWN_H */
+extern world_map;
+void world_map_enter(void);
+void world_map_pre_update(void);
#include "world.h"
#include "world_physics.h"
-static void ray_world_get_tri( world_instance *world,
- ray_hit *hit, v3f tri[3] )
+void ray_world_get_tri( world_instance *world, ray_hit *hit, v3f tri[3] )
{
for( int i=0; i<3; i++ )
v3_copy( world->scene_geo.arrvertices[ hit->tri[i] ].co, tri[i] );
}
-static int ray_world( world_instance *world,
- v3f pos, v3f dir, ray_hit *hit, u16 ignore )
+int ray_world( world_instance *world,
+ v3f pos, v3f dir, ray_hit *hit, u16 ignore )
{
return scene_raycast( &world->scene_geo, world->geo_bh, pos, dir, hit,
ignore );
/*
* Cast a sphere from a to b and see what time it hits
*/
-static int spherecast_world( world_instance *world,
- v3f pa, v3f pb, float r, float *t, v3f n,
- u16 ignore )
+int spherecast_world( world_instance *world,
+ v3f pa, v3f pb, float r, float *t, v3f n, u16 ignore )
{
boxf region;
box_init_inf( region );
return hit;
}
-static
struct world_surface *world_tri_index_surface( world_instance *world,
- u32 index )
+ u32 index )
{
for( int i=1; i<world->surface_count; i++ ){
struct world_surface *surf = &world->surfaces[i];
return &world->surfaces[0];
}
-static struct world_surface *world_contact_surface( world_instance *world,
- rb_ct *ct )
+struct world_surface *world_contact_surface( world_instance *world, rb_ct *ct )
{
return world_tri_index_surface( world, ct->element_id );
}
-static struct world_surface *ray_hit_surface( world_instance *world,
- ray_hit *hit )
+struct world_surface *ray_hit_surface( world_instance *world, ray_hit *hit )
{
return world_tri_index_surface( world, hit->tri[0] );
}
-#ifndef WORLD_PHYSICS_H
-#define WORLD_PHYSICS_H
-
+#pragma once
#include "world.h"
#include "vg/vg_rigidbody.h"
#include "vg/vg_rigidbody_collision.h"
-static void ray_world_get_tri( world_instance *world,
- ray_hit *hit, v3f tri[3] );
+void ray_world_get_tri( world_instance *world,
+ ray_hit *hit, v3f tri[3] );
-static int ray_world( world_instance *world,
- v3f pos, v3f dir, ray_hit *hit, u16 ignore );
+int ray_world( world_instance *world,
+ v3f pos, v3f dir, ray_hit *hit, u16 ignore );
-static int spherecast_world( world_instance *world,
- v3f pa, v3f pb, float r, float *t, v3f n,
- u16 ignore );
+int spherecast_world( world_instance *world,
+ v3f pa, v3f pb, float r, float *t, v3f n,
+ u16 ignore );
-static struct world_surface *world_tri_index_surface( world_instance *world,
- u32 index );
+struct world_surface *world_tri_index_surface( world_instance *world,
+ u32 index );
-static struct world_surface *world_contact_surface( world_instance *world,
- rb_ct *ct );
+struct world_surface *world_contact_surface( world_instance *world,
+ rb_ct *ct );
-static struct world_surface *ray_hit_surface( world_instance *world,
+struct world_surface *ray_hit_surface( world_instance *world,
ray_hit *hit );
-
-#endif /* WORLD_PHYSICS_H */
* Copyright (C) 2021-2023 Mt.ZERO Software, Harry Godden - All Rights Reserved
*/
-#ifndef WORLD_RENDER_C
-#define WORLD_RENDER_C
-
#include "world.h"
#include "world_render.h"
#include "font.h"
#include "ent_skateshop.h"
#include "shaders/model_entity.h"
+struct world_render world_render;
+
static int ccmd_set_time( int argc, const char *argv[] ){
world_instance *world = world_current_instance();
if( argc == 1 )
}
}
-static void world_render_init(void){
+void world_render_init(void)
+{
VG_VAR_F32( k_day_length );
VG_VAR_I32( k_debug_light_indices );
VG_VAR_I32( k_debug_light_complexity );
world_render.sky_rate = 1.0;
world_render.sky_target_rate = 1.0;
- shader_scene_standard_register();
- shader_scene_standard_alphatest_register();
- shader_scene_foliage_register();
- shader_scene_override_register();
- shader_scene_cubemapped_register();
- shader_scene_fxglow_register();
- shader_scene_vertex_blend_register();
- shader_scene_terrain_register();
- shader_scene_depth_register();
- shader_scene_position_register();
- shader_model_sky_register();
- shader_model_sky_space_register();
-
vg_info( "Loading world resources\n" );
vg_linear_clear( vg_mem.scratch );
* standard uniform bindings
* ----------------------------------------------------------------------------
*/
-static void world_link_lighting_ub( world_instance *world, GLuint shader ){
+void world_link_lighting_ub( world_instance *world, GLuint shader )
+{
GLuint idx = glGetUniformBlockIndex( shader, "ub_world_lighting" );
glUniformBlockBinding( shader, idx, world->ubo_bind_point );
}
-static void world_bind_position_texture( world_instance *world,
- GLuint shader, GLuint location,
- int slot ){
+void world_bind_position_texture( world_instance *world,
+ GLuint shader, GLuint location,
+ int slot )
+{
render_fb_bind_texture( &world->heightmap, 0, slot );
glUniform1i( location, slot );
}
-static void world_bind_light_array( world_instance *world,
- GLuint shader, GLuint location,
- int slot ){
+void world_bind_light_array( world_instance *world,
+ GLuint shader, GLuint location,
+ int slot )
+{
glActiveTexture( GL_TEXTURE0 + slot );
glBindTexture( GL_TEXTURE_BUFFER, world->tex_light_entities );
glUniform1i( location, slot );
}
-static void world_bind_light_index( world_instance *world,
- GLuint shader, GLuint location,
- int slot ){
+void world_bind_light_index( world_instance *world,
+ GLuint shader, GLuint location,
+ int slot )
+{
glActiveTexture( GL_TEXTURE0 + slot );
glBindTexture( GL_TEXTURE_3D, world->tex_light_cubes );
glUniform1i( location, slot );
}
-static void bind_terrain_noise(void){
+void bind_terrain_noise(void)
+{
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, world_render.tex_terrain_noise );
}
*/
struct world_pass{
- camera *cam;
+ vg_camera *cam;
enum mdl_shader shader;
enum world_geo_type geo_type;
void (*fn_set_uNormalMtx)( m3x3f mnorm );
};
-static void render_world_depth( world_instance *world, camera *cam );
+void render_world_depth( world_instance *world, vg_camera *cam );
/*
* Render a run of submeshes, only of those which match material_id
glEnable( GL_CULL_FACE );
}
-static void render_world_vb( world_instance *world, camera *cam ){
+static void render_world_vb( world_instance *world, vg_camera *cam ){
shader_scene_vertex_blend_use();
shader_scene_vertex_blend_uTexGarbage(0);
shader_scene_vertex_blend_uTexGradients(1);
world_render_both_stages( world, &pass );
}
-static void world_shader_standard_bind( world_instance *world, camera *cam ){
+static void world_shader_standard_bind( world_instance *world, vg_camera *cam ){
shader_scene_standard_use();
shader_scene_standard_uTexGarbage(0);
shader_scene_standard_uTexMain(1);
shader_scene_standard_uCamera( cam->transform[3] );
}
-static void render_world_standard( world_instance *world, camera *cam ){
+static void render_world_standard( world_instance *world, vg_camera *cam ){
world_shader_standard_bind( world, cam );
struct world_pass pass = {
.shader = k_shader_standard,
shader_scene_cubemapped_uColour( mat->info.colour );
}
-static void render_world_cubemapped( world_instance *world, camera *cam,
+static void render_world_cubemapped( world_instance *world, vg_camera *cam,
int enabled ){
if( !mdl_arrcount( &world->ent_cubemap ) )
return;
}
}
-static void render_world_alphatest( world_instance *world, camera *cam ){
+static void render_world_alphatest( world_instance *world, vg_camera *cam ){
shader_scene_standard_alphatest_use();
shader_scene_standard_alphatest_uTexGarbage(0);
shader_scene_standard_alphatest_uTexMain(1);
glEnable(GL_CULL_FACE);
}
-static void render_world_foliage( world_instance *world, camera *cam ){
+static void render_world_foliage( world_instance *world, vg_camera *cam ){
shader_scene_foliage_use();
shader_scene_foliage_uTexGarbage(0);
shader_scene_foliage_uTexMain(1);
}
static void render_world_fxglow( world_instance *host_world,
- world_instance *world, camera *cam,
+ world_instance *world, vg_camera *cam,
m4x3f world_mmdl,
int generic, int challenges, int regions ){
shader_scene_fxglow_use();
}
}
-static void render_terrain( world_instance *world, camera *cam ){
+static void render_terrain( world_instance *world, vg_camera *cam ){
shader_scene_terrain_use();
shader_scene_terrain_uTexGarbage(0);
shader_scene_terrain_uTexGradients(1);
world_render_both_stages( world, &pass );
}
-static void render_sky( world_instance *world, camera *cam ){
+static void render_sky( world_instance *world, vg_camera *cam ){
/*
* Modify matrix to remove clipping and view translation
*/
glDepthMask( GL_TRUE );
}
-static void render_world_gates( world_instance *world, camera *cam ){
+void render_world_gates( world_instance *world, vg_camera *cam )
+{
float closest = INFINITY;
struct ent_gate *gate = NULL;
}
}
-static void world_prerender( world_instance *world ){
+void world_prerender( world_instance *world )
+{
if( mdl_arrcount( &world->ent_light ) ){
f32 rate = vg_maxf(0.1f, fabsf(k_day_length)) * vg_signf(k_day_length);
world->time += vg.time_frame_delta * (1.0/(rate*60.0));
sizeof(struct ub_world_lighting), &world->ub_lighting );
}
-static void render_other_entities( world_instance *world, camera *cam ){
+static void render_other_entities( world_instance *world, vg_camera *cam ){
f32 radius = 40.0f;
bh_iter it;
bh_iter_init_range( 0, &it, cam->pos, radius+10.0f );
}
}
-static void render_world( world_instance *world, camera *cam,
- int stenciled, int viewing_from_gate,
- int with_water, int with_cubemaps ){
+void render_world( world_instance *world, vg_camera *cam,
+ int stenciled, int viewing_from_gate,
+ int with_water, int with_cubemaps )
+{
if( stenciled ){
glClear( GL_DEPTH_BUFFER_BIT );
glStencilFunc( GL_EQUAL, 1, 0xFF );
}
}
-static void render_world_override( world_instance *world,
- world_instance *lighting_source,
- m4x3f mmdl,
- camera *cam,
- ent_spawn *dest_spawn, v4f map_info ){
+void render_world_override( world_instance *world,
+ world_instance *lighting_source,
+ m4x3f mmdl,
+ vg_camera *cam,
+ ent_spawn *dest_spawn, v4f map_info )
+{
struct world_pass pass = {
.cam = cam,
.fn_bind_textures = bindpoint_override,
static void render_cubemap_side( world_instance *world, ent_cubemap *cm,
u32 side ){
- camera cam;
+ vg_camera cam;
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_CUBE_MAP_POSITIVE_X + side, cm->texture_id, 0 );
glClear( GL_DEPTH_BUFFER_BIT );
v3_copy( cm->co, cam.transform[3] );
m4x3_invert_affine( cam.transform, cam.transform_inverse );
- camera_update_view( &cam );
+ vg_camera_update_view( &cam );
cam.nearz = 0.1f;
cam.farz = 1000.0f;
cam.fov = 90.0f;
m4x4_copy( cam.mtx.p, cam.mtx_prev.p );
m4x4_projection( cam.mtx.p, cam.fov, 1.0f, cam.nearz, cam.farz );
- camera_finalize( &cam );
- camera_finalize( &cam );
+ vg_camera_finalize( &cam );
+ vg_camera_finalize( &cam );
render_world( world, &cam, 0, 1, 1, 0 );
}
-static void render_world_cubemaps( world_instance *world ){
+void render_world_cubemaps( world_instance *world )
+{
if( world->cubemap_cooldown )
world->cubemap_cooldown --;
else{
* ---------------------------------------------
*/
-static void render_world_depth( world_instance *world, camera *cam ){
+void render_world_depth( world_instance *world, vg_camera *cam )
+{
m4x3f identity_matrix;
m4x3_identity( identity_matrix );
mesh_draw( &world->mesh_geo );
}
-static void render_world_position( world_instance *world, camera *cam ){
+void render_world_position( world_instance *world, vg_camera *cam )
+{
m4x3f identity_matrix;
m4x3_identity( identity_matrix );
}
}
-static void imgui_world_light_edit( world_instance *world ){
+void imgui_world_light_edit( world_instance *world )
+{
ui_rect panel = { vg.window_x-400, 0, 400, vg.window_y };
ui_fill( panel, ui_colour( k_ui_bg+1 ) );
ui_outline( panel, 1, ui_colour( k_ui_bg+7 ), 0 );
fclose( fp );
}
}
-
-#endif
/*
- * Copyright (C) 2021-2023 Mt.ZERO Software, Harry Godden - All Rights Reserved
+ * Copyright (C) 2021-2024 Mt.ZERO Software, Harry Godden - All Rights Reserved
*/
-#ifndef WORLD_RENDER_H
-#define WORLD_RENDER_H
+#pragma once
#define WORLD_CUBEMAP_RES 32
-#include "camera.h"
+#include "vg/vg_camera.h"
#include "world.h"
-
#include "shaders/scene_standard.h"
#include "shaders/scene_standard_alphatest.h"
#include "shaders/scene_foliage.h"
static const float k_world_light_cube_size = 8.0f;
-struct world_render{
+struct world_render
+{
GLuint tex_terrain_noise;
/* rendering */
text_particles[6*4];
u32 text_particle_count;
}
-static world_render;
-static void world_render_init(void);
+extern world_render;
+
+void world_render_init(void);
-static void world_link_lighting_ub( world_instance *world, GLuint shader );
-static void world_bind_position_texture( world_instance *world,
- GLuint shader, GLuint location,
- int slot );
-static void world_bind_light_array( world_instance *world,
- GLuint shader, GLuint location,
- int slot );
-static void world_bind_light_index( world_instance *world,
- GLuint shader, GLuint location,
- int slot );
-static void render_world_position( world_instance *world, camera *cam );
-static void render_world_depth( world_instance *world, camera *cam );
-static void render_world( world_instance *world, camera *cam,
- int stenciled, int viewing_from_gate,
- int with_water, int with_cubemaps );
-static void render_world_cubemaps( world_instance *world );
-static void bind_terrain_noise(void);
-static void render_world_override( world_instance *world,
- world_instance *lighting_source,
- m4x3f mmdl,
- camera *cam,
- ent_spawn *dest_spawn, v4f map_info );
+void world_prerender( world_instance *world );
+void world_link_lighting_ub( world_instance *world, GLuint shader );
+void world_bind_position_texture( world_instance *world,
+ GLuint shader, GLuint location,
+ int slot );
+void world_bind_light_array( world_instance *world,
+ GLuint shader, GLuint location,
+ int slot );
+void world_bind_light_index( world_instance *world,
+ GLuint shader, GLuint location,
+ int slot );
+void render_world_position( world_instance *world, vg_camera *cam );
+void render_world_depth( world_instance *world, vg_camera *cam );
+void render_world( world_instance *world, vg_camera *cam,
+ int stenciled, int viewing_from_gate,
+ int with_water, int with_cubemaps );
+void render_world_cubemaps( world_instance *world );
+void bind_terrain_noise(void);
+void render_world_override( world_instance *world,
+ world_instance *lighting_source,
+ m4x3f mmdl,
+ vg_camera *cam,
+ ent_spawn *dest_spawn, v4f map_info );
+void render_world_gates( world_instance *world, vg_camera *cam );
+void imgui_world_light_edit( world_instance *world );
#define WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( WORLD, SHADER ) \
world_link_lighting_ub( WORLD, _shader_##SHADER.id ); \
world_bind_light_index( WORLD, _shader_##SHADER.id, \
_uniform_##SHADER##_uLightsIndex, 4 );
-#endif /* WORLD_RENDER_H */
#include "ent_region.h"
#include "scene_rigidbody.h"
-static void world_routes_clear( world_instance *world )
+void world_routes_clear( world_instance *world )
{
for( u32 i=0; i<mdl_arrcount( &world->ent_route ); i++ ){
ent_route *route = mdl_arritm( &world->ent_route, i );
/*
* When going through a gate this is called for bookkeeping purposes
*/
-static void world_routes_activate_entry_gate( world_instance *world,
- ent_gate *rg )
+void world_routes_activate_entry_gate( world_instance *world, ent_gate *rg )
{
world_static.last_use = world_static.time;
ent_gate *dest = mdl_arritm( &world->ent_gate, rg->target );
scene_copy_slice( sc, &route->sm );
}
-static
struct world_surface *world_tri_index_surface( world_instance *world,
u32 index );
/*
* Create the strips of colour that run through the world along course paths
*/
-static void world_gen_routes_generate( u32 instance_id ){
+void world_gen_routes_generate( u32 instance_id )
+{
world_instance *world = &world_static.instances[ instance_id ];
vg_info( "Generating route meshes\n" );
vg_async_stall();
}
/* load all routes from model header */
-static void world_gen_routes_ent_init( world_instance *world ){
+void world_gen_routes_ent_init( world_instance *world )
+{
vg_info( "Initializing routes\n" );
for( u32 i=0; i<mdl_arrcount(&world->ent_gate); i++ ){
world_routes_clear( world );
}
-static void world_routes_recv_scoreboard( world_instance *world,
- vg_msg *body, u32 route_id,
- enum request_status status ){
+void world_routes_recv_scoreboard( world_instance *world,
+ vg_msg *body, u32 route_id,
+ enum request_status status )
+{
if( route_id >= mdl_arrcount( &world->ent_route ) ){
vg_error( "Scoreboard route_id out of range (%u)\n", route_id );
return;
* -----------------------------------------------------------------------------
*/
-static void world_routes_init(void){
+void world_routes_init(void)
+{
world_static.current_run_version = 200;
world_static.time = 300.0;
world_static.last_use = 0.0;
-
- shader_scene_route_register();
- shader_routeui_register();
}
-static void world_routes_update( world_instance *world ){
+void world_routes_update( world_instance *world )
+{
world_static.time += vg.time_delta;
for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ ){
}
}
-static void world_routes_fixedupdate( world_instance *world ){
+void world_routes_fixedupdate( world_instance *world )
+{
rb_solver_reset();
rigidbody _null = {0};
}
}
-static void bind_terrain_noise(void);
-static void world_bind_light_array( world_instance *world,
- GLuint shader, GLuint location,
- int slot );
-static void world_bind_light_index( world_instance *world,
- GLuint shader, GLuint location,
- int slot );
+void bind_terrain_noise(void);
+void world_bind_light_array( world_instance *world,
+ GLuint shader, GLuint location,
+ int slot );
+void world_bind_light_index( world_instance *world,
+ GLuint shader, GLuint location,
+ int slot );
-static void world_routes_update_timer_texts( world_instance *world ){
+void world_routes_update_timer_texts( world_instance *world )
+{
world_render.timer_text_count = 0;
for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ ){
}
}
-static void world_routes_fracture( world_instance *world, ent_gate *gate,
- v3f imp_co, v3f imp_v )
+void world_routes_fracture( world_instance *world, ent_gate *gate,
+ v3f imp_co, v3f imp_v )
{
world_render.text_particle_count = 0;
}
}
-static void render_world_routes( world_instance *world,
- world_instance *host_world,
- m4x3f mmdl, camera *cam,
- int viewing_from_gate, int viewing_from_hub ){
-
+void render_world_routes( world_instance *world,
+ world_instance *host_world,
+ m4x3f mmdl, vg_camera *cam,
+ int viewing_from_gate, int viewing_from_hub )
+{
shader_scene_route_use();
shader_scene_route_uTexGarbage(0);
world_link_lighting_ub( host_world, _shader_scene_route.id );
* Copyright (C) 2021-2023 Mt.ZERO Software, Harry Godden - All Rights Reserved
*/
-#ifndef ROUTES_H
-#define ROUTES_H
-
+#pragma once
+#include "vg/vg_camera.h"
#include "world.h"
#include "network_msg.h"
-static void world_routes_init(void);
-static void world_routes_fracture( world_instance *world, ent_gate *gate,
- v3f imp_co, v3f imp_v );
-static void world_routes_activate_entry_gate( world_instance *world,
- ent_gate *rg );
-static void render_world_routes( world_instance *world,
- world_instance *host_world,
- m4x3f mmdl, camera *cam,
- int viewing_from_gate, int viewing_from_hub );
-
-static void world_gen_routes_ent_init( world_instance *world );
-static void world_gen_routes_generate( u32 instance_id );
-static void world_routes_update_timer_texts( world_instance *world );
-static void world_routes_update( world_instance *world );
-static void world_routes_fixedupdate( world_instance *world );
-static void world_routes_clear( world_instance *world );
-static void world_routes_recv_scoreboard( world_instance *world,
- vg_msg *body, u32 route_id,
- enum request_status status );
+void world_routes_init(void);
+void world_routes_fracture( world_instance *world, ent_gate *gate,
+ v3f imp_co, v3f imp_v );
+void world_routes_activate_entry_gate( world_instance *world,
+ ent_gate *rg );
+void render_world_routes( world_instance *world,
+ world_instance *host_world,
+ m4x3f mmdl, vg_camera *cam,
+ int viewing_from_gate, int viewing_from_hub );
-#endif /* ROUTES_H */
+void world_gen_routes_ent_init( world_instance *world );
+void world_gen_routes_generate( u32 instance_id );
+void world_routes_update_timer_texts( world_instance *world );
+void world_routes_update( world_instance *world );
+void world_routes_fixedupdate( world_instance *world );
+void world_routes_clear( world_instance *world );
+void world_routes_recv_scoreboard( world_instance *world,
+ vg_msg *body, u32 route_id,
+ enum request_status status );
vg.time_frame_delta );
}
-static void world_routes_imgui( world_instance *world ){
+void world_routes_imgui( world_instance *world )
+{
ui_point cursor = { 4, 4 };
for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ ){
ent_route_imgui( world, mdl_arritm( &world->ent_route, i ), cursor );
-#ifndef WORLD_ROUTES_UI_H
-#define WORLD_ROUTES_UI_H
-
+#pragma once
#include "world_routes.h"
-struct route_ui{
-};
-
-static void ent_region_re_eval( world_instance *world );
-#endif /* WORLD_ROUTES_UI_H */
+struct route_ui{};
+void world_routes_imgui( world_instance *world );
#include "network_common.h"
#include "world_routes.h"
+struct world_sfd world_sfd;
+
static f32 sfd_encode_glyph( char c ){
int value = 0;
if( c >= 'a' && c <= 'z' )
}
}
-static void sfd_encode( v2i co, const char *str, enum world_sfd_align align ){
+void sfd_encode( v2i co, const char *str, enum world_sfd_align align )
+{
i32 row_h = world_sfd.h -1 -co[1];
i32 offset_x = 0;
}
}
-static void world_sfd_compile_scores( struct leaderboard_cache *board,
- const char *title ){
+void world_sfd_compile_scores( struct leaderboard_cache *board,
+ const char *title )
+{
for( u32 i=0; i<13; i++ )
sfd_clear(i);
}
}
-static void world_sfd_compile_active_scores(void){
+void world_sfd_compile_active_scores(void)
+{
world_instance *world = world_current_instance();
struct leaderboard_cache *board = NULL;
world_sfd_compile_scores( board, name );
}
-static void world_sfd_update( world_instance *world, v3f pos ){
+void world_sfd_update( world_instance *world, v3f pos )
+{
if( mdl_arrcount( &world->ent_route ) ){
u32 closest = 0;
float min_dist = INFINITY;
}
}
-static void bind_terrain_noise(void);
-static void sfd_render( world_instance *world, camera *cam, m4x3f transform ){
+void bind_terrain_noise(void);
+void sfd_render( world_instance *world, vg_camera *cam, m4x3f transform )
+{
mesh_bind( &world_sfd.mesh_display );
shader_scene_scoretext_use();
shader_scene_scoretext_uTexMain(1);
mdl_draw_submesh( &world_sfd.sm_base );
}
-static void world_sfd_init(void){
+void world_sfd_init(void)
+{
vg_info( "world_sfd_init\n" );
- shader_scene_scoretext_register();
vg_linear_clear( vg_mem.scratch );
mdl_context mscoreboard;
/*
- * Copyright (C) 2021-2023 Mt.ZERO Software, Harry Godden - All Rights Reserved
+ * Copyright (C) 2021-2024 Mt.ZERO Software, Harry Godden - All Rights Reserved
*/
-
-#ifndef SFD_H
-#define SFD_H
-
+#pragma once
#include "world.h"
#include "world_routes.h"
#include "scene.h"
u32 w, h;
float *buffer;
}
-static world_sfd;
-static void world_sfd_init(void);
+extern world_sfd;
+void world_sfd_init(void);
enum world_sfd_align {
k_world_sfd_left,
k_world_sfd_center
};
-static void sfd_encode( v2i co, const char *str, enum world_sfd_align align );
-static void sfd_render( world_instance *world, camera *cam,
- m4x3f transform );
-static void world_sfd_compile_scores( struct leaderboard_cache *leaderboard,
- const char *title );
-static void world_sfd_compile_active_scores(void);
-
-#endif /* SFD_H */
+void sfd_encode( v2i co, const char *str, enum world_sfd_align align );
+void world_sfd_update( world_instance *world, v3f pos );
+void sfd_render( world_instance *world, vg_camera *cam, m4x3f transform );
+void world_sfd_compile_scores( struct leaderboard_cache *leaderboard,
+ const char *title );
+void world_sfd_compile_active_scores(void);
-#ifndef WORLD_VOLUMES_C
-#define WORLD_VOLUMES_C
-
#include "world_volumes.h"
-static void world_volumes_update( world_instance *world, v3f pos ){
+void world_volumes_update( world_instance *world, v3f pos )
+{
/* filter and check the existing ones */
u32 j=0;
for( u32 i=0; i<world_static.active_trigger_volume_count; i++ ){
next_volume:;
}
}
-
-#endif /* WORLD_VOLUMES_H */
-#ifndef WORLD_VOLUMES_H
-#define WORLD_VOLUMES_H
-
+#pragma once
#include "world.h"
-#include "bvh.h"
+#include "vg/vg_bvh.h"
-#endif /* WORLD_VOLUMES_H */
+void world_volumes_update( world_instance *world, v3f pos );
#include "shaders/scene_water_fast.h"
#include "scene.h"
-static void world_water_init(void){
+struct world_water world_water;
+
+void world_water_init(void)
+{
vg_info( "world_water_init\n" );
- shader_scene_water_register();
- shader_scene_water_fast_register();
vg_tex2d_load_qoi_async_file( "textures/water_surf.qoi",
VG_TEX2D_LINEAR|VG_TEX2D_REPEAT,
vg_success( "done\n" );
}
-static void water_set_surface( world_instance *world, float height ){
+void water_set_surface( world_instance *world, float height )
+{
world->water.height = height;
v4_copy( (v4f){ 0.0f, 1.0f, 0.0f, height }, world->water.plane );
}
-static void world_link_lighting_ub( world_instance *world, GLuint shader );
-static void world_bind_position_texture( world_instance *world,
- GLuint shader, GLuint location,
- int slot );
-static void world_bind_light_array( world_instance *world,
- GLuint shader, GLuint location,
- int slot );
-static void world_bind_light_index( world_instance *world,
+void world_link_lighting_ub( world_instance *world, GLuint shader );
+void world_bind_position_texture( world_instance *world,
+ GLuint shader, GLuint location,
+ int slot );
+void world_bind_light_array( world_instance *world,
+ GLuint shader, GLuint location,
+ int slot );
+void world_bind_light_index( world_instance *world,
GLuint shader, GLuint location,
int slot );
/*
* Does not write motion vectors
*/
-static void render_water_texture( world_instance *world, camera *cam ){
+void render_water_texture( world_instance *world, vg_camera *cam )
+{
if( !world->water.enabled || (vg.quality_profile == k_quality_profile_low) )
return;
*/
float cam_height = cam->transform[3][1] - world->water.height;
- camera water_cam;
+ vg_camera water_cam;
water_cam.farz = cam->farz;
water_cam.nearz = cam->nearz;
v3_copy( cam->transform[3], water_cam.transform[3] );
flip[1][1] = -1.0f;
m3x3_mul( flip, cam->transform, water_cam.transform );
- camera_update_view( &water_cam );
+ vg_camera_update_view( &water_cam );
/*
* Create clipped projection
m4x4_copy( cam->mtx.p, water_cam.mtx.p );
m4x4_clip_projection( water_cam.mtx.p, clippa );
- camera_finalize( &water_cam );
+ vg_camera_finalize( &water_cam );
/*
* Draw world
/*
* Create beneath view matrix
*/
- camera beneath_cam;
+ vg_camera beneath_cam;
render_fb_bind( gpipeline.fb_water_beneath, 1 );
glClearColor( 1.0f, 0.0f, 0.0f, 0.0f );
glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
m4x3_copy( cam->transform, beneath_cam.transform );
- camera_update_view( &beneath_cam );
+ vg_camera_update_view( &beneath_cam );
float bias = -(cam->transform[3][1]-world->water.height)*0.1f;
m4x4_copy( cam->mtx.p, beneath_cam.mtx.p );
m4x4_clip_projection( beneath_cam.mtx.p, clippb );
- camera_finalize( &beneath_cam );
+ vg_camera_finalize( &beneath_cam );
glEnable( GL_DEPTH_TEST );
glDisable( GL_BLEND );
//glViewport( 0,0, g_render_x, g_render_y );
}
-static void render_water_surface( world_instance *world, camera *cam ){
+void render_water_surface( world_instance *world, vg_camera *cam )
+{
if( !world->water.enabled )
return;
* Copyright (C) 2021-2023 Mt.ZERO Software, Harry Godden - All Rights Reserved
*/
-#ifndef WATER_H
-#define WATER_H
-
+#pragma once
#include "world.h"
struct world_water{
GLuint tex_water_surf;
}
-static world_water;
-static void world_water_init(void);
-
-static void water_set_surface( world_instance *world, float height );
-static void render_water_texture( world_instance *world, camera *cam );
-static void render_water_surface( world_instance *world, camera *cam );
+extern world_water;
+void world_water_init(void);
-#endif /* WATER_H */
+void water_set_surface( world_instance *world, f32 height );
+void render_water_texture( world_instance *world, vg_camera *cam );
+void render_water_surface( world_instance *world, vg_camera *cam );