UI changes + vram reduction
parent
5eb53e7fa4
commit
a3b747fd46
23
bind/v4k.lua
23
bind/v4k.lua
|
@ -1148,7 +1148,7 @@ enum SHADOW_TECHNIQUE {
|
||||||
SHADOW_CSM,
|
SHADOW_CSM,
|
||||||
};
|
};
|
||||||
typedef struct light_t {
|
typedef struct light_t {
|
||||||
char type;
|
unsigned type;
|
||||||
vec3 diffuse, specular, ambient;
|
vec3 diffuse, specular, ambient;
|
||||||
vec3 pos, dir;
|
vec3 pos, dir;
|
||||||
struct {
|
struct {
|
||||||
|
@ -1158,12 +1158,16 @@ typedef struct light_t {
|
||||||
float specularPower;
|
float specularPower;
|
||||||
float innerCone, outerCone;
|
float innerCone, outerCone;
|
||||||
bool cast_shadows;
|
bool cast_shadows;
|
||||||
bool processed_shadows;
|
|
||||||
unsigned shadow_technique;
|
unsigned shadow_technique;
|
||||||
float shadow_distance;
|
float shadow_distance;
|
||||||
float shadow_bias;
|
float shadow_near_clip;
|
||||||
mat44 shadow_matrix[4];
|
mat44 shadow_matrix[4];
|
||||||
|
float min_variance;
|
||||||
|
float variance_transition;
|
||||||
|
float shadow_bias;
|
||||||
|
float normal_bias;
|
||||||
bool cached;
|
bool cached;
|
||||||
|
bool processed_shadows;
|
||||||
} light_t;
|
} light_t;
|
||||||
light_t light();
|
light_t light();
|
||||||
void light_type(light_t* l, char type);
|
void light_type(light_t* l, char type);
|
||||||
|
@ -1177,6 +1181,8 @@ typedef struct light_t {
|
||||||
void light_falloff(light_t* l, float constant, float linear, float quadratic);
|
void light_falloff(light_t* l, float constant, float linear, float quadratic);
|
||||||
void light_cone(light_t* l, float innerCone, float outerCone);
|
void light_cone(light_t* l, float innerCone, float outerCone);
|
||||||
void light_update(unsigned num_lights, light_t *lv);
|
void light_update(unsigned num_lights, light_t *lv);
|
||||||
|
void ui_light(light_t *l);
|
||||||
|
void ui_lights(unsigned num_lights, light_t *lights);
|
||||||
typedef struct shadowmap_t {
|
typedef struct shadowmap_t {
|
||||||
mat44 V;
|
mat44 V;
|
||||||
mat44 PV;
|
mat44 PV;
|
||||||
|
@ -1198,11 +1204,13 @@ typedef struct shadowmap_t {
|
||||||
uint64_t vram_usage_total;
|
uint64_t vram_usage_total;
|
||||||
uint64_t vram_usage_vsm;
|
uint64_t vram_usage_vsm;
|
||||||
uint64_t vram_usage_csm;
|
uint64_t vram_usage_csm;
|
||||||
|
handle depth_texture;
|
||||||
|
handle depth_texture_2d;
|
||||||
struct {
|
struct {
|
||||||
int gen;
|
int gen;
|
||||||
unsigned shadow_technique;
|
unsigned shadow_technique;
|
||||||
handle texture, depth_texture;
|
handle texture;
|
||||||
handle texture_2d[4], depth_texture_2d[4];
|
handle texture_2d[4];
|
||||||
handle blur_texture, blur_texture_2d;
|
handle blur_texture, blur_texture_2d;
|
||||||
float cascade_distances[4];
|
float cascade_distances[4];
|
||||||
} maps[MAX_LIGHTS];
|
} maps[MAX_LIGHTS];
|
||||||
|
@ -2054,6 +2062,10 @@ enum PANEL_FLAGS {
|
||||||
int ui_int(const char *label, int *value);
|
int ui_int(const char *label, int *value);
|
||||||
int ui_bool(const char *label, bool *value);
|
int ui_bool(const char *label, bool *value);
|
||||||
int ui_short(const char *label, short *value);
|
int ui_short(const char *label, short *value);
|
||||||
|
int ui_float_(const char *label, float *value, float step);
|
||||||
|
int ui_float2_(const char *label, float value[2], float step);
|
||||||
|
int ui_float3_(const char *label, float value[3], float step);
|
||||||
|
int ui_float4_(const char *label, float value[4], float step);
|
||||||
int ui_float(const char *label, float *value);
|
int ui_float(const char *label, float *value);
|
||||||
int ui_float2(const char *label, float value[2]);
|
int ui_float2(const char *label, float value[2]);
|
||||||
int ui_float3(const char *label, float value[3]);
|
int ui_float3(const char *label, float value[3]);
|
||||||
|
@ -2090,6 +2102,7 @@ enum PANEL_FLAGS {
|
||||||
int ui_bitmask8(const char *label, uint8_t *bits);
|
int ui_bitmask8(const char *label, uint8_t *bits);
|
||||||
int ui_bitmask16(const char *label, uint16_t *bits);
|
int ui_bitmask16(const char *label, uint16_t *bits);
|
||||||
int ui_console();
|
int ui_console();
|
||||||
|
int ui_clampf_(const char *label, float *value, float minf, float maxf, float step);
|
||||||
int ui_clampf(const char *label, float *value, float minf, float maxf);
|
int ui_clampf(const char *label, float *value, float minf, float maxf);
|
||||||
int ui_label(const char *label);
|
int ui_label(const char *label);
|
||||||
int ui_label2(const char *label, const char *caption);
|
int ui_label2(const char *label, const char *caption);
|
||||||
|
|
|
@ -206,6 +206,8 @@ int main(int argc, char** argv) {
|
||||||
must_reload = 1;
|
must_reload = 1;
|
||||||
}
|
}
|
||||||
ui_separator();
|
ui_separator();
|
||||||
|
ui_lights(array_count(lights), lights);
|
||||||
|
ui_separator();
|
||||||
ui_bool("CSM Blur", &sm.blur_csm);
|
ui_bool("CSM Blur", &sm.blur_csm);
|
||||||
ui_slider("CSM Blur Scale", &sm.csm_blur_scale);
|
ui_slider("CSM Blur Scale", &sm.csm_blur_scale);
|
||||||
ui_bool("VSM Blur", &sm.blur_vsm);
|
ui_bool("VSM Blur", &sm.blur_vsm);
|
||||||
|
|
|
@ -26,6 +26,10 @@ struct light_t {
|
||||||
|
|
||||||
// shadows
|
// shadows
|
||||||
mat4 shadow_matrix[NUM_SHADOW_CASCADES];
|
mat4 shadow_matrix[NUM_SHADOW_CASCADES];
|
||||||
|
float shadow_bias;
|
||||||
|
float normal_bias;
|
||||||
|
float min_variance;
|
||||||
|
float variance_transition;
|
||||||
};
|
};
|
||||||
|
|
||||||
const int LIGHT_DIRECTIONAL = 0;
|
const int LIGHT_DIRECTIONAL = 0;
|
||||||
|
|
|
@ -12,7 +12,7 @@ uniform sampler2D shadowMap2D[MAX_LIGHTS * NUM_SHADOW_CASCADES];
|
||||||
const float bias_modifier[NUM_SHADOW_CASCADES] = float[NUM_SHADOW_CASCADES](0.95, 0.35, 0.20, 0.15);
|
const float bias_modifier[NUM_SHADOW_CASCADES] = float[NUM_SHADOW_CASCADES](0.95, 0.35, 0.20, 0.15);
|
||||||
|
|
||||||
//// From http://fabiensanglard.net/shadowmappingVSM/index.php
|
//// From http://fabiensanglard.net/shadowmappingVSM/index.php
|
||||||
float shadow_vsm(float distance, vec3 dir, int light_index) {
|
float shadow_vsm(float distance, vec3 dir, int light_index, float min_variance, float variance_transition) {
|
||||||
distance = distance/200;
|
distance = distance/200;
|
||||||
|
|
||||||
// Define offsets for 3x3 PCF
|
// Define offsets for 3x3 PCF
|
||||||
|
@ -49,9 +49,9 @@ float shadow_vsm(float distance, vec3 dir, int light_index) {
|
||||||
|
|
||||||
// Calculate VSM for this sample
|
// Calculate VSM for this sample
|
||||||
float p = step(distance, moments.x);
|
float p = step(distance, moments.x);
|
||||||
float variance = max(moments.y - (moments.x * moments.x), 0.00002);
|
float variance = max(moments.y - (moments.x * moments.x), min_variance);
|
||||||
float d = distance - moments.x;
|
float d = distance - moments.x;
|
||||||
float p_max = linstep(0.2, 1.0, variance / (variance + d*d));
|
float p_max = linstep(variance_transition, 1.0, variance / (variance + d*d));
|
||||||
|
|
||||||
shadow += min(max(p, p_max), 1.0);
|
shadow += min(max(p, p_max), 1.0);
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ float shadow_vsm(float distance, vec3 dir, int light_index) {
|
||||||
return shadow / 9.0;
|
return shadow / 9.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
float shadow_csm(float distance, vec3 lightDir, int light_index) {
|
float shadow_csm(float distance, vec3 lightDir, int light_index, float shadow_bias, float normal_bias) {
|
||||||
// Determine which cascade to use
|
// Determine which cascade to use
|
||||||
int cascade_index = -1;
|
int cascade_index = -1;
|
||||||
int min_cascades_range = light_index * NUM_SHADOW_CASCADES;
|
int min_cascades_range = light_index * NUM_SHADOW_CASCADES;
|
||||||
|
@ -94,7 +94,7 @@ float shadow_csm(float distance, vec3 lightDir, int light_index) {
|
||||||
|
|
||||||
// Calculate bias
|
// Calculate bias
|
||||||
vec3 normal = normalize(vneye.xyz);
|
vec3 normal = normalize(vneye.xyz);
|
||||||
float bias = max(0.05 * (1.0 - dot(normal, lightDir)), 0.005);
|
float bias = max(normal_bias * (1.0 - dot(normal, lightDir)), shadow_bias);
|
||||||
bias *= 1 / (u_cascade_distances[cascade_index] * bias_modifier[matrix_index]);
|
bias *= 1 / (u_cascade_distances[cascade_index] * bias_modifier[matrix_index]);
|
||||||
|
|
||||||
// CSM
|
// CSM
|
||||||
|
@ -116,7 +116,7 @@ float shadow_csm(float distance, vec3 lightDir, int light_index) {
|
||||||
{
|
{
|
||||||
for(int y = -1; y <= 1; ++y)
|
for(int y = -1; y <= 1; ++y)
|
||||||
{
|
{
|
||||||
float csmDepth = texture(shadowMap2D[cascade_index], projCoords.xy + vec2(x, y) * texelSize).r;
|
float csmDepth = texture(shadowMap2D[cascade_index], projCoords.xy + vec2(x, y) * texelSize * (rand(vec2(projCoords.x + x, projCoords.y + y))*0.75f + 0.25f)).r;
|
||||||
shadow += currentDepth - bias > csmDepth ? 1.0 : 0.0;
|
shadow += currentDepth - bias > csmDepth ? 1.0 : 0.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,12 +132,12 @@ vec4 shadowmap(int idx, in vec4 peye, in vec4 neye) {
|
||||||
|
|
||||||
if (light.processed_shadows) {
|
if (light.processed_shadows) {
|
||||||
if (light.type == LIGHT_DIRECTIONAL) {
|
if (light.type == LIGHT_DIRECTIONAL) {
|
||||||
shadowFactor = shadow_csm(-peye.z, light.dir, idx);
|
shadowFactor = shadow_csm(-peye.z, light.dir, idx, light.shadow_bias, light.normal_bias);
|
||||||
} else if (light.type == LIGHT_POINT || light.type == LIGHT_SPOT) {
|
} else if (light.type == LIGHT_POINT || light.type == LIGHT_SPOT) {
|
||||||
vec3 light_pos = (view * vec4(light.pos, 1.0)).xyz;
|
vec3 light_pos = (view * vec4(light.pos, 1.0)).xyz;
|
||||||
vec3 dir = light_pos - fragment;
|
vec3 dir = light_pos - fragment;
|
||||||
vec4 sc = inv_view * vec4(dir, 0.0);
|
vec4 sc = inv_view * vec4(dir, 0.0);
|
||||||
shadowFactor = shadow_vsm(length(dir), -sc.xyz, idx);
|
shadowFactor = shadow_vsm(length(dir), -sc.xyz, idx, light.min_variance, light.variance_transition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17270,7 +17270,7 @@ enum SHADOW_TECHNIQUE {
|
||||||
#define NUM_SHADOW_CASCADES 4
|
#define NUM_SHADOW_CASCADES 4
|
||||||
|
|
||||||
typedef struct light_t {
|
typedef struct light_t {
|
||||||
char type;
|
unsigned type;
|
||||||
vec3 diffuse, specular, ambient;
|
vec3 diffuse, specular, ambient;
|
||||||
vec3 pos, dir;
|
vec3 pos, dir;
|
||||||
struct {
|
struct {
|
||||||
|
@ -17283,14 +17283,18 @@ typedef struct light_t {
|
||||||
|
|
||||||
// Shadowmapping
|
// Shadowmapping
|
||||||
bool cast_shadows;
|
bool cast_shadows;
|
||||||
bool processed_shadows;
|
|
||||||
unsigned shadow_technique;
|
unsigned shadow_technique;
|
||||||
float shadow_distance;
|
float shadow_distance;
|
||||||
float shadow_bias;
|
float shadow_near_clip;
|
||||||
mat44 shadow_matrix[NUM_SHADOW_CASCADES];
|
mat44 shadow_matrix[NUM_SHADOW_CASCADES];
|
||||||
|
float min_variance; //< VSM
|
||||||
|
float variance_transition; //< VSM
|
||||||
|
float shadow_bias; //< CSM
|
||||||
|
float normal_bias; //< CSM
|
||||||
|
|
||||||
// internals
|
// internals
|
||||||
bool cached; //< used by scene to invalidate cached light data
|
bool cached; //< used by scene to invalidate cached light data
|
||||||
|
bool processed_shadows;
|
||||||
} light_t;
|
} light_t;
|
||||||
|
|
||||||
API light_t light();
|
API light_t light();
|
||||||
|
@ -17307,6 +17311,10 @@ API void light_falloff(light_t* l, float constant, float linear, float quadra
|
||||||
API void light_cone(light_t* l, float innerCone, float outerCone);
|
API void light_cone(light_t* l, float innerCone, float outerCone);
|
||||||
API void light_update(unsigned num_lights, light_t *lv);
|
API void light_update(unsigned num_lights, light_t *lv);
|
||||||
|
|
||||||
|
API void ui_light(light_t *l);
|
||||||
|
API void ui_lights(unsigned num_lights, light_t *lights);
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// shadowmaps
|
// shadowmaps
|
||||||
|
|
||||||
|
@ -17336,11 +17344,15 @@ typedef struct shadowmap_t {
|
||||||
uint64_t vram_usage_vsm;
|
uint64_t vram_usage_vsm;
|
||||||
uint64_t vram_usage_csm;
|
uint64_t vram_usage_csm;
|
||||||
|
|
||||||
|
// depth texture
|
||||||
|
handle depth_texture;
|
||||||
|
handle depth_texture_2d;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
int gen;
|
int gen;
|
||||||
unsigned shadow_technique;
|
unsigned shadow_technique;
|
||||||
handle texture, depth_texture;
|
handle texture;
|
||||||
handle texture_2d[NUM_SHADOW_CASCADES], depth_texture_2d[NUM_SHADOW_CASCADES];
|
handle texture_2d[NUM_SHADOW_CASCADES];
|
||||||
handle blur_texture, blur_texture_2d;
|
handle blur_texture, blur_texture_2d;
|
||||||
// handle blur_fbo_cubemap, blur_texture_cubemap;
|
// handle blur_fbo_cubemap, blur_texture_cubemap;
|
||||||
float cascade_distances[NUM_SHADOW_CASCADES];
|
float cascade_distances[NUM_SHADOW_CASCADES];
|
||||||
|
@ -18699,6 +18711,10 @@ API int ui_section(const char *title);
|
||||||
API int ui_int(const char *label, int *value);
|
API int ui_int(const char *label, int *value);
|
||||||
API int ui_bool(const char *label, bool *value);
|
API int ui_bool(const char *label, bool *value);
|
||||||
API int ui_short(const char *label, short *value);
|
API int ui_short(const char *label, short *value);
|
||||||
|
API int ui_float_(const char *label, float *value, float step);
|
||||||
|
API int ui_float2_(const char *label, float value[2], float step);
|
||||||
|
API int ui_float3_(const char *label, float value[3], float step);
|
||||||
|
API int ui_float4_(const char *label, float value[4], float step);
|
||||||
API int ui_float(const char *label, float *value);
|
API int ui_float(const char *label, float *value);
|
||||||
API int ui_float2(const char *label, float value[2]);
|
API int ui_float2(const char *label, float value[2]);
|
||||||
API int ui_float3(const char *label, float value[3]);
|
API int ui_float3(const char *label, float value[3]);
|
||||||
|
@ -18735,6 +18751,7 @@ API int ui_separator();
|
||||||
API int ui_bitmask8(const char *label, uint8_t *bits);
|
API int ui_bitmask8(const char *label, uint8_t *bits);
|
||||||
API int ui_bitmask16(const char *label, uint16_t *bits);
|
API int ui_bitmask16(const char *label, uint16_t *bits);
|
||||||
API int ui_console();
|
API int ui_console();
|
||||||
|
API int ui_clampf_(const char *label, float *value, float minf, float maxf, float step);
|
||||||
API int ui_clampf(const char *label, float *value, float minf, float maxf);
|
API int ui_clampf(const char *label, float *value, float minf, float maxf);
|
||||||
API int ui_label(const char *label);
|
API int ui_label(const char *label);
|
||||||
API int ui_label2(const char *label, const char *caption);
|
API int ui_label2(const char *label, const char *caption);
|
||||||
|
@ -228865,6 +228882,8 @@ struct nk_context {
|
||||||
#define NK_PI 3.141592654f
|
#define NK_PI 3.141592654f
|
||||||
#define NK_UTF_INVALID 0xFFFD
|
#define NK_UTF_INVALID 0xFFFD
|
||||||
#define NK_MAX_FLOAT_PRECISION 2
|
#define NK_MAX_FLOAT_PRECISION 2
|
||||||
|
#define NK_MAX_FLOAT_PRECISION2 6
|
||||||
|
#define NK_FLOAT_DECIMAL_POS_THRESHOLD 0.0005
|
||||||
|
|
||||||
#define NK_UNUSED(x) ((void)(x))
|
#define NK_UNUSED(x) ((void)(x))
|
||||||
#define NK_SATURATE(x) (NK_MAX(0, NK_MIN(1.0f, x)))
|
#define NK_SATURATE(x) (NK_MAX(0, NK_MIN(1.0f, x)))
|
||||||
|
@ -251323,11 +251342,11 @@ nk_do_property(nk_flags *ws,
|
||||||
break;
|
break;
|
||||||
case NK_PROPERTY_FLOAT:
|
case NK_PROPERTY_FLOAT:
|
||||||
NK_DTOA(string, (double)variant->value.f);
|
NK_DTOA(string, (double)variant->value.f);
|
||||||
num_len = nk_string_float_limit(string, NK_MAX_FLOAT_PRECISION);
|
num_len = nk_string_float_limit(string, variant->step.f <= NK_FLOAT_DECIMAL_POS_THRESHOLD ? NK_MAX_FLOAT_PRECISION2 : NK_MAX_FLOAT_PRECISION);
|
||||||
break;
|
break;
|
||||||
case NK_PROPERTY_DOUBLE:
|
case NK_PROPERTY_DOUBLE:
|
||||||
NK_DTOA(string, variant->value.d);
|
NK_DTOA(string, variant->value.d);
|
||||||
num_len = nk_string_float_limit(string, NK_MAX_FLOAT_PRECISION);
|
num_len = nk_string_float_limit(string, variant->step.f <= NK_FLOAT_DECIMAL_POS_THRESHOLD ? NK_MAX_FLOAT_PRECISION2 : NK_MAX_FLOAT_PRECISION);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
size = font->width(font->userdata, font->height, string, num_len);
|
size = font->width(font->userdata, font->height, string, num_len);
|
||||||
|
@ -251423,12 +251442,12 @@ nk_do_property(nk_flags *ws,
|
||||||
variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i, variant->max_value.i);
|
variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i, variant->max_value.i);
|
||||||
break;
|
break;
|
||||||
case NK_PROPERTY_FLOAT:
|
case NK_PROPERTY_FLOAT:
|
||||||
nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION);
|
nk_string_float_limit(buffer, variant->step.f <= NK_FLOAT_DECIMAL_POS_THRESHOLD ? NK_MAX_FLOAT_PRECISION2 : NK_MAX_FLOAT_PRECISION);
|
||||||
variant->value.f = nk_strtof(buffer, 0);
|
variant->value.f = nk_strtof(buffer, 0);
|
||||||
variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f, variant->max_value.f);
|
variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f, variant->max_value.f);
|
||||||
break;
|
break;
|
||||||
case NK_PROPERTY_DOUBLE:
|
case NK_PROPERTY_DOUBLE:
|
||||||
nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION);
|
nk_string_float_limit(buffer, variant->step.f <= NK_FLOAT_DECIMAL_POS_THRESHOLD ? NK_MAX_FLOAT_PRECISION2 : NK_MAX_FLOAT_PRECISION);
|
||||||
variant->value.d = nk_strtod(buffer, 0);
|
variant->value.d = nk_strtod(buffer, 0);
|
||||||
variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d, variant->max_value.d);
|
variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d, variant->max_value.d);
|
||||||
break;
|
break;
|
||||||
|
@ -368386,13 +368405,42 @@ int ui_short(const char *label, short *v) {
|
||||||
return *v = (short)i, ret;
|
return *v = (short)i, ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ui_float(const char *label, float *v) {
|
static inline
|
||||||
|
float ui_float_adjust_step(float step) {
|
||||||
|
if ((input(KEY_LSHIFT) || input(KEY_RSHIFT))&&(input(KEY_LCTRL) || input(KEY_RCTRL))) step *= 100.0f;
|
||||||
|
else if (input(KEY_LSHIFT) || input(KEY_RSHIFT)) step *= 10.0f;
|
||||||
|
else if (input(KEY_LCTRL) || input(KEY_RCTRL)) step *= 0.1f;
|
||||||
|
else if (input(KEY_LALT) || input(KEY_RALT)) step *= 0.01f;
|
||||||
|
return step;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ui_float_(const char *label, float *v, float step) {
|
||||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||||
|
|
||||||
|
float inc_per_pixel = ui_float_adjust_step(0.005f);
|
||||||
|
step = ui_float_adjust_step(step);
|
||||||
|
|
||||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||||
ui_label_(label, NK_TEXT_LEFT);
|
ui_label_(label, NK_TEXT_LEFT);
|
||||||
|
|
||||||
float prev = v[0]; v[0] = nk_propertyf(ui_ctx, "#", -FLT_MAX, v[0], FLT_MAX, 0.01f,0.005f);
|
float prev = v[0]; v[0] = nk_propertyf(ui_ctx, "#", -FLT_MAX, v[0], FLT_MAX, step, inc_per_pixel);
|
||||||
|
return prev != v[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
int ui_float(const char *label, float *v) {
|
||||||
|
return ui_float_(label, v, 0.01f);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ui_double_(const char *label, double *v, double step) {
|
||||||
|
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||||
|
|
||||||
|
float inc_per_pixel = ui_float_adjust_step(0.005f);
|
||||||
|
step = ui_float_adjust_step(step);
|
||||||
|
|
||||||
|
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||||
|
ui_label_(label, NK_TEXT_LEFT);
|
||||||
|
|
||||||
|
double prev = v[0]; v[0] = nk_propertyd(ui_ctx, "#", -DBL_MAX, v[0], DBL_MAX, step, inc_per_pixel);
|
||||||
return prev != v[0];
|
return prev != v[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368406,21 +368454,30 @@ int ui_double(const char *label, double *v) {
|
||||||
return prev != v[0];
|
return prev != v[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
int ui_clampf(const char *label, float *v, float minf, float maxf) {
|
int ui_clampf_(const char *label, float *v, float minf, float maxf, float step) {
|
||||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||||
|
|
||||||
|
float inc_per_pixel = ui_float_adjust_step(0.005f);
|
||||||
|
step = ui_float_adjust_step(step);
|
||||||
|
|
||||||
if( minf > maxf ) return ui_clampf(label, v, maxf, minf);
|
if( minf > maxf ) return ui_clampf(label, v, maxf, minf);
|
||||||
|
|
||||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||||
ui_label_(label, NK_TEXT_LEFT);
|
ui_label_(label, NK_TEXT_LEFT);
|
||||||
|
|
||||||
float prev = v[0]; v[0] = nk_propertyf(ui_ctx, "#", minf, v[0], maxf, 0.1f,0.05f);
|
float prev = v[0]; v[0] = nk_propertyf(ui_ctx, "#", minf, v[0], maxf, step, inc_per_pixel);
|
||||||
return prev != v[0];
|
return prev != v[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
int ui_float2(const char *label, float *v) {
|
int ui_clampf(const char *label, float *v, float minf, float maxf) {
|
||||||
|
return ui_clampf_(label, v, minf, maxf, 0.1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ui_float2_(const char *label, float *v, float step) {
|
||||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||||
|
|
||||||
|
float inc_per_pixel = ui_float_adjust_step(0.5f);
|
||||||
|
step = ui_float_adjust_step(step);
|
||||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||||
ui_label_(label, NK_TEXT_LEFT);
|
ui_label_(label, NK_TEXT_LEFT);
|
||||||
|
|
||||||
|
@ -368430,17 +368487,23 @@ int ui_float2(const char *label, float *v) {
|
||||||
|
|
||||||
if (nk_combo_begin_label(ui_ctx, buffer, nk_vec2(200,200))) {
|
if (nk_combo_begin_label(ui_ctx, buffer, nk_vec2(200,200))) {
|
||||||
nk_layout_row_dynamic(ui_ctx, 0, 1);
|
nk_layout_row_dynamic(ui_ctx, 0, 1);
|
||||||
float prev0 = v[0]; nk_property_float(ui_ctx, "#X:", -FLT_MAX, &v[0], FLT_MAX, 1,0.5f);
|
float prev0 = v[0]; nk_property_float(ui_ctx, "#X:", -FLT_MAX, &v[0], FLT_MAX, step, inc_per_pixel);
|
||||||
float prev1 = v[1]; nk_property_float(ui_ctx, "#Y:", -FLT_MAX, &v[1], FLT_MAX, 1,0.5f);
|
float prev1 = v[1]; nk_property_float(ui_ctx, "#Y:", -FLT_MAX, &v[1], FLT_MAX, step, inc_per_pixel);
|
||||||
nk_combo_end(ui_ctx);
|
nk_combo_end(ui_ctx);
|
||||||
return prev0 != v[0] || prev1 != v[1];
|
return prev0 != v[0] || prev1 != v[1];
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ui_float3(const char *label, float *v) {
|
int ui_float2(const char *label, float *v) {
|
||||||
|
return ui_float2_(label, v, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ui_float3_(const char *label, float *v, float step) {
|
||||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||||
|
|
||||||
|
float inc_per_pixel = ui_float_adjust_step(0.5f);
|
||||||
|
step = ui_float_adjust_step(step);
|
||||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||||
ui_label_(label, NK_TEXT_LEFT);
|
ui_label_(label, NK_TEXT_LEFT);
|
||||||
|
|
||||||
|
@ -368450,18 +368513,25 @@ int ui_float3(const char *label, float *v) {
|
||||||
|
|
||||||
if (nk_combo_begin_label(ui_ctx, buffer, nk_vec2(200,200))) {
|
if (nk_combo_begin_label(ui_ctx, buffer, nk_vec2(200,200))) {
|
||||||
nk_layout_row_dynamic(ui_ctx, 0, 1);
|
nk_layout_row_dynamic(ui_ctx, 0, 1);
|
||||||
float prev0 = v[0]; nk_property_float(ui_ctx, "#X:", -FLT_MAX, &v[0], FLT_MAX, 1,0.5f);
|
float prev0 = v[0]; nk_property_float(ui_ctx, "#X:", -FLT_MAX, &v[0], FLT_MAX, step, inc_per_pixel);
|
||||||
float prev1 = v[1]; nk_property_float(ui_ctx, "#Y:", -FLT_MAX, &v[1], FLT_MAX, 1,0.5f);
|
float prev1 = v[1]; nk_property_float(ui_ctx, "#Y:", -FLT_MAX, &v[1], FLT_MAX, step, inc_per_pixel);
|
||||||
float prev2 = v[2]; nk_property_float(ui_ctx, "#Z:", -FLT_MAX, &v[2], FLT_MAX, 1,0.5f);
|
float prev2 = v[2]; nk_property_float(ui_ctx, "#Z:", -FLT_MAX, &v[2], FLT_MAX, step, inc_per_pixel);
|
||||||
nk_combo_end(ui_ctx);
|
nk_combo_end(ui_ctx);
|
||||||
return prev0 != v[0] || prev1 != v[1] || prev2 != v[2];
|
return prev0 != v[0] || prev1 != v[1] || prev2 != v[2];
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ui_float4(const char *label, float *v) {
|
|
||||||
|
int ui_float3(const char *label, float *v) {
|
||||||
|
return ui_float3_(label, v, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ui_float4_(const char *label, float *v, float step) {
|
||||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||||
|
|
||||||
|
float inc_per_pixel = ui_float_adjust_step(0.5f);
|
||||||
|
step = ui_float_adjust_step(step);
|
||||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||||
ui_label_(label, NK_TEXT_LEFT);
|
ui_label_(label, NK_TEXT_LEFT);
|
||||||
|
|
||||||
|
@ -368471,10 +368541,10 @@ int ui_float4(const char *label, float *v) {
|
||||||
|
|
||||||
if (nk_combo_begin_label(ui_ctx, buffer, nk_vec2(200,200))) {
|
if (nk_combo_begin_label(ui_ctx, buffer, nk_vec2(200,200))) {
|
||||||
nk_layout_row_dynamic(ui_ctx, 0, 1);
|
nk_layout_row_dynamic(ui_ctx, 0, 1);
|
||||||
float prev0 = v[0]; nk_property_float(ui_ctx, "#X:", -FLT_MAX, &v[0], FLT_MAX, 1,0.5f);
|
float prev0 = v[0]; nk_property_float(ui_ctx, "#X:", -FLT_MAX, &v[0], FLT_MAX, step, inc_per_pixel);
|
||||||
float prev1 = v[1]; nk_property_float(ui_ctx, "#Y:", -FLT_MAX, &v[1], FLT_MAX, 1,0.5f);
|
float prev1 = v[1]; nk_property_float(ui_ctx, "#Y:", -FLT_MAX, &v[1], FLT_MAX, step, inc_per_pixel);
|
||||||
float prev2 = v[2]; nk_property_float(ui_ctx, "#Z:", -FLT_MAX, &v[2], FLT_MAX, 1,0.5f);
|
float prev2 = v[2]; nk_property_float(ui_ctx, "#Z:", -FLT_MAX, &v[2], FLT_MAX, step, inc_per_pixel);
|
||||||
float prev3 = v[3]; nk_property_float(ui_ctx, "#W:", -FLT_MAX, &v[3], FLT_MAX, 1,0.5f);
|
float prev3 = v[3]; nk_property_float(ui_ctx, "#W:", -FLT_MAX, &v[3], FLT_MAX, step, inc_per_pixel);
|
||||||
nk_combo_end(ui_ctx);
|
nk_combo_end(ui_ctx);
|
||||||
return prev0 != v[0] || prev1 != v[1] || prev2 != v[2] || prev3 != v[3];
|
return prev0 != v[0] || prev1 != v[1] || prev2 != v[2] || prev3 != v[3];
|
||||||
}
|
}
|
||||||
|
@ -368482,6 +368552,10 @@ int ui_float4(const char *label, float *v) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ui_float4(const char *label, float *v) {
|
||||||
|
return ui_float4_(label, v, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
int ui_mat33(const char *label, float M[9]) {
|
int ui_mat33(const char *label, float M[9]) {
|
||||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||||
|
|
||||||
|
@ -383226,7 +383300,11 @@ light_t light() {
|
||||||
l.cast_shadows = true;
|
l.cast_shadows = true;
|
||||||
l.processed_shadows = false;
|
l.processed_shadows = false;
|
||||||
l.shadow_distance = 200.0f;
|
l.shadow_distance = 200.0f;
|
||||||
l.shadow_bias = 0.01f;
|
l.shadow_near_clip = 0.01f;
|
||||||
|
l.shadow_bias = 0.005f;
|
||||||
|
l.normal_bias = 0.05f;
|
||||||
|
l.min_variance = 0.00002f;
|
||||||
|
l.variance_transition = 0.2f;
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -383305,6 +383383,10 @@ void light_update(unsigned num_lights, light_t *lv) {
|
||||||
shader_float(va("u_lights[%d].quadratic", i), lv[i].falloff.quadratic);
|
shader_float(va("u_lights[%d].quadratic", i), lv[i].falloff.quadratic);
|
||||||
shader_float(va("u_lights[%d].innerCone", i), lv[i].innerCone);
|
shader_float(va("u_lights[%d].innerCone", i), lv[i].innerCone);
|
||||||
shader_float(va("u_lights[%d].outerCone", i), lv[i].outerCone);
|
shader_float(va("u_lights[%d].outerCone", i), lv[i].outerCone);
|
||||||
|
shader_float(va("u_lights[%d].shadow_bias", i), lv[i].shadow_bias);
|
||||||
|
shader_float(va("u_lights[%d].normal_bias", i), lv[i].normal_bias);
|
||||||
|
shader_float(va("u_lights[%d].min_variance", i), lv[i].min_variance);
|
||||||
|
shader_float(va("u_lights[%d].variance_transition", i), lv[i].variance_transition);
|
||||||
shader_bool(va("u_lights[%d].processed_shadows", i), lv[i].processed_shadows);
|
shader_bool(va("u_lights[%d].processed_shadows", i), lv[i].processed_shadows);
|
||||||
if (lv[i].processed_shadows) {
|
if (lv[i].processed_shadows) {
|
||||||
for (int j = 0; j < NUM_SHADOW_CASCADES; j++) {
|
for (int j = 0; j < NUM_SHADOW_CASCADES; j++) {
|
||||||
|
@ -383314,10 +383396,58 @@ void light_update(unsigned num_lights, light_t *lv) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ui_light(light_t *l) {
|
||||||
|
ui_int("Type", &l->type);
|
||||||
|
ui_vec3("Position", &l->pos);
|
||||||
|
ui_vec3("Direction", &l->dir);
|
||||||
|
ui_color3f("Diffuse", &l->diffuse.x);
|
||||||
|
ui_color3f("Specular", &l->specular.x);
|
||||||
|
ui_color3f("Ambient", &l->ambient.x);
|
||||||
|
ui_float("Specular Power", &l->specularPower);
|
||||||
|
ui_clampf("Radius", &l->radius, 0.0f, FLT_MAX);
|
||||||
|
ui_clampf_("Constant Falloff", &l->falloff.constant, 0.0, FLT_MAX, 0.005);
|
||||||
|
ui_clampf_("Linear Falloff", &l->falloff.linear, 0.0, FLT_MAX, 0.005);
|
||||||
|
ui_clampf_("Quadratic Falloff", &l->falloff.quadratic, 0.0, FLT_MAX, 0.005);
|
||||||
|
ui_float("Inner Cone", &l->innerCone);
|
||||||
|
ui_float("Outer Cone", &l->outerCone);
|
||||||
|
ui_float_("Shadow Bias", &l->shadow_bias, 0.00005);
|
||||||
|
ui_float_("Normal Bias", &l->normal_bias, 0.00005);
|
||||||
|
ui_float_("Min Variance", &l->min_variance, 0.00005);
|
||||||
|
ui_float_("Variance Transition", &l->variance_transition, 0.0005);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_lights(unsigned num_lights, light_t *lights) {
|
||||||
|
for (unsigned i = 0; i < num_lights; ++i) {
|
||||||
|
if (ui_collapse(va("Light %d", i), va("light_%d", i))) {
|
||||||
|
ui_light(&lights[i]);
|
||||||
|
ui_collapse_end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// shadowmaps
|
// shadowmaps
|
||||||
|
|
||||||
|
static inline
|
||||||
|
void shadowmap_init_common_resources(shadowmap_t *s, int vsm_texture_width, int csm_texture_width) {
|
||||||
|
// Create a cubemap depth texture
|
||||||
|
glGenTextures(1, &s->depth_texture);
|
||||||
|
glBindTexture(GL_TEXTURE_CUBE_MAP, s->depth_texture);
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT, vsm_texture_width, vsm_texture_width, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||||
|
|
||||||
|
// Create a 2D depth texture
|
||||||
|
glGenTextures(1, &s->depth_texture_2d);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, s->depth_texture_2d);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, csm_texture_width, csm_texture_width, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
shadowmap_init_caster_vsm(shadowmap_t *s, int light_index, int texture_width) {
|
shadowmap_init_caster_vsm(shadowmap_t *s, int light_index, int texture_width) {
|
||||||
float borderColor[] = {1.0, 1.0, 1.0, 1.0};
|
float borderColor[] = {1.0, 1.0, 1.0, 1.0};
|
||||||
|
@ -383341,19 +383471,6 @@ shadowmap_init_caster_vsm(shadowmap_t *s, int light_index, int texture_width) {
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||||
glTexParameterfv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BORDER_COLOR, borderColor);
|
glTexParameterfv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BORDER_COLOR, borderColor);
|
||||||
|
|
||||||
// Create a cubemap depth texture
|
|
||||||
glGenTextures(1, &s->maps[light_index].depth_texture);
|
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, s->maps[light_index].depth_texture);
|
|
||||||
for (int i = 0; i < 6; i++) {
|
|
||||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT, texture_width, texture_width, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
|
|
||||||
}
|
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER);
|
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
|
||||||
glTexParameterfv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BORDER_COLOR, borderColor);
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -383375,15 +383492,6 @@ shadowmap_init_caster_csm(shadowmap_t *s, int light_index, int texture_width) {
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||||
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
|
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
|
||||||
|
|
||||||
glGenTextures(1, &s->maps[light_index].depth_texture_2d[i]);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, s->maps[light_index].depth_texture_2d[i]);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, texture_width, texture_width, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
|
|
||||||
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_BORDER);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
|
||||||
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
@ -383434,6 +383542,8 @@ shadowmap_t shadowmap(int vsm_texture_width, int csm_texture_width) { // = 512,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
shadowmap_init_common_resources(&s, vsm_texture_width, csm_texture_width);
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, s.saved_fb);
|
glBindFramebuffer(GL_FRAMEBUFFER, s.saved_fb);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
@ -383447,20 +383557,12 @@ void shadowmap_destroy_light(shadowmap_t *s, int light_index) {
|
||||||
glDeleteTextures(1, &s->maps[light_index].texture);
|
glDeleteTextures(1, &s->maps[light_index].texture);
|
||||||
s->maps[light_index].texture = 0;
|
s->maps[light_index].texture = 0;
|
||||||
}
|
}
|
||||||
if (s->maps[light_index].depth_texture) {
|
|
||||||
glDeleteTextures(1, &s->maps[light_index].depth_texture);
|
|
||||||
s->maps[light_index].depth_texture = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < NUM_SHADOW_CASCADES; i++) {
|
for (int i = 0; i < NUM_SHADOW_CASCADES; i++) {
|
||||||
if (s->maps[light_index].texture_2d[i]) {
|
if (s->maps[light_index].texture_2d[i]) {
|
||||||
glDeleteTextures(1, &s->maps[light_index].texture_2d[i]);
|
glDeleteTextures(1, &s->maps[light_index].texture_2d[i]);
|
||||||
s->maps[light_index].texture_2d[i] = 0;
|
s->maps[light_index].texture_2d[i] = 0;
|
||||||
}
|
}
|
||||||
if (s->maps[light_index].depth_texture_2d[i]) {
|
|
||||||
glDeleteTextures(1, &s->maps[light_index].depth_texture_2d[i]);
|
|
||||||
s->maps[light_index].depth_texture_2d[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->maps[light_index].blur_texture_2d) {
|
if (s->maps[light_index].blur_texture_2d) {
|
||||||
|
@ -383478,6 +383580,18 @@ void shadowmap_destroy(shadowmap_t *s) {
|
||||||
for (int i = 0; i < MAX_LIGHTS; i++) {
|
for (int i = 0; i < MAX_LIGHTS; i++) {
|
||||||
shadowmap_destroy_light(s, i);
|
shadowmap_destroy_light(s, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (s->depth_texture) {
|
||||||
|
glDeleteTextures(1, &s->depth_texture);
|
||||||
|
s->depth_texture = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s->depth_texture_2d) {
|
||||||
|
glDeleteTextures(1, &s->depth_texture_2d);
|
||||||
|
s->depth_texture_2d = 0;
|
||||||
|
}
|
||||||
|
|
||||||
shadowmap_t z = {0};
|
shadowmap_t z = {0};
|
||||||
*s = z;
|
*s = z;
|
||||||
}
|
}
|
||||||
|
@ -383505,7 +383619,7 @@ void shadowmap_begin(shadowmap_t *s) {
|
||||||
static void shadowmap_light_point(shadowmap_t *s, light_t *l, int dir) {
|
static void shadowmap_light_point(shadowmap_t *s, light_t *l, int dir) {
|
||||||
if(dir<0) return;
|
if(dir<0) return;
|
||||||
mat44 P, V, PV;
|
mat44 P, V, PV;
|
||||||
perspective44(P, 90.0f, 1.0f, l->shadow_bias, l->shadow_distance);
|
perspective44(P, 90.0f, 1.0f, l->shadow_near_clip, l->shadow_distance);
|
||||||
vec3 lightPos = l->pos;
|
vec3 lightPos = l->pos;
|
||||||
|
|
||||||
/**/ if(dir == 0) lookat44(V, lightPos, add3(lightPos, vec3(+1, 0, 0)), vec3(0, -1, 0)); // +X
|
/**/ if(dir == 0) lookat44(V, lightPos, add3(lightPos, vec3(+1, 0, 0)), vec3(0, -1, 0)); // +X
|
||||||
|
@ -383558,7 +383672,7 @@ static void shadowmap_light_directional(shadowmap_t *s, light_t *l, int dir, flo
|
||||||
float near_plane = 0.0f;
|
float near_plane = 0.0f;
|
||||||
|
|
||||||
if (s->cascade_index == 0) {
|
if (s->cascade_index == 0) {
|
||||||
near_plane = l->shadow_bias;
|
near_plane = l->shadow_near_clip;
|
||||||
far_plane = l->shadow_distance * s->cascade_splits[0];
|
far_plane = l->shadow_distance * s->cascade_splits[0];
|
||||||
} else if (s->cascade_index < NUM_SHADOW_CASCADES - 1) {
|
} else if (s->cascade_index < NUM_SHADOW_CASCADES - 1) {
|
||||||
near_plane = l->shadow_distance * s->cascade_splits[s->cascade_index-1];
|
near_plane = l->shadow_distance * s->cascade_splits[s->cascade_index-1];
|
||||||
|
@ -383873,12 +383987,12 @@ void shadowmap_light(shadowmap_t *s, light_t *l, mat44 cam_proj, mat44 cam_view)
|
||||||
if (l->type == LIGHT_DIRECTIONAL) {
|
if (l->type == LIGHT_DIRECTIONAL) {
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, s->fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, s->fbo);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, s->maps[s->light_step].texture_2d[s->cascade_index], 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, s->maps[s->light_step].texture_2d[s->cascade_index], 0);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, s->maps[s->light_step].depth_texture_2d[s->cascade_index], 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, s->depth_texture_2d, 0);
|
||||||
shadowmap_clear_fbo();
|
shadowmap_clear_fbo();
|
||||||
} else {
|
} else {
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, s->fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, s->fbo);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + step, s->maps[s->light_step].texture, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + step, s->maps[s->light_step].texture, 0);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + step, s->maps[s->light_step].depth_texture, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + step, s->depth_texture, 0);
|
||||||
shadowmap_clear_fbo();
|
shadowmap_clear_fbo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -383900,19 +384014,25 @@ void shadowmap_end(shadowmap_t *s) {
|
||||||
{
|
{
|
||||||
const int faces = 6;
|
const int faces = 6;
|
||||||
const int cascades = NUM_SHADOW_CASCADES;
|
const int cascades = NUM_SHADOW_CASCADES;
|
||||||
|
|
||||||
|
// Depth textures
|
||||||
|
s->vram_usage += s->vsm_texture_width * s->vsm_texture_width * faces * 1;
|
||||||
|
s->vram_usage += s->csm_texture_width * s->csm_texture_width * 1;
|
||||||
|
s->vram_usage_total += s->vsm_texture_width * s->vsm_texture_width * faces * 1;
|
||||||
|
s->vram_usage_vsm += s->vsm_texture_width * s->vsm_texture_width * faces * 8;
|
||||||
|
s->vram_usage_total += s->vsm_texture_width * s->vsm_texture_width * faces * 8;
|
||||||
|
s->vram_usage_csm += s->csm_texture_width * s->csm_texture_width * 1;
|
||||||
|
|
||||||
for (int i = 0; i < MAX_LIGHTS; i++) {
|
for (int i = 0; i < MAX_LIGHTS; i++) {
|
||||||
// VSM textures
|
// VSM textures
|
||||||
if (s->maps[i].texture != 0) {
|
if (s->maps[i].texture != 0) {
|
||||||
// Color texture (GL_RG32F)
|
// Color texture (GL_RG32F)
|
||||||
s->vram_usage += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // 8 bytes per pixel (2 * 32-bit float)
|
s->vram_usage += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // 8 bytes per pixel (2 * 32-bit float)
|
||||||
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
|
|
||||||
s->vram_usage += s->vsm_texture_width * s->vsm_texture_width * faces * 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Color texture (GL_RG32F)
|
// Color texture (GL_RG32F)
|
||||||
s->vram_usage_total += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // 8 bytes per pixel (2 * 32-bit float)
|
s->vram_usage_total += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // 8 bytes per pixel (2 * 32-bit float)
|
||||||
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
|
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
|
||||||
s->vram_usage_total += s->vsm_texture_width * s->vsm_texture_width * faces * 1;
|
|
||||||
|
|
||||||
// Color texture (GL_RG32F)
|
// Color texture (GL_RG32F)
|
||||||
s->vram_usage_vsm += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // 8 bytes per pixel (2 * 32-bit float)
|
s->vram_usage_vsm += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // 8 bytes per pixel (2 * 32-bit float)
|
||||||
|
@ -383925,20 +384045,13 @@ void shadowmap_end(shadowmap_t *s) {
|
||||||
for (int j = 0; j < cascades; j++) {
|
for (int j = 0; j < cascades; j++) {
|
||||||
// Color texture (GL_R32F)
|
// Color texture (GL_R32F)
|
||||||
s->vram_usage += s->csm_texture_width * s->csm_texture_width * 4; // 4 bytes per pixel (1 * 32-bit float)
|
s->vram_usage += s->csm_texture_width * s->csm_texture_width * 4; // 4 bytes per pixel (1 * 32-bit float)
|
||||||
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
|
|
||||||
s->vram_usage += s->csm_texture_width * s->csm_texture_width * 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < cascades; j++) {
|
for (int j = 0; j < cascades; j++) {
|
||||||
// Color texture (GL_R32F)
|
// Color texture (GL_R32F)
|
||||||
s->vram_usage_total += s->csm_texture_width * s->csm_texture_width * 4; // 4 bytes per pixel (1 * 32-bit float)
|
s->vram_usage_total += s->csm_texture_width * s->csm_texture_width * 4; // 4 bytes per pixel (1 * 32-bit float)
|
||||||
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
|
|
||||||
s->vram_usage_total += s->csm_texture_width * s->csm_texture_width * 1;
|
|
||||||
|
|
||||||
s->vram_usage_csm += s->csm_texture_width * s->csm_texture_width * 4; // 4 bytes per pixel (1 * 32-bit float)
|
s->vram_usage_csm += s->csm_texture_width * s->csm_texture_width * 4; // 4 bytes per pixel (1 * 32-bit float)
|
||||||
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
|
|
||||||
s->vram_usage_csm += s->csm_texture_width * s->csm_texture_width * 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// VSM blur texture (if used)
|
// VSM blur texture (if used)
|
||||||
|
@ -383946,8 +384059,6 @@ void shadowmap_end(shadowmap_t *s) {
|
||||||
s->vram_usage += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // Assuming same format as VSM color texture
|
s->vram_usage += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // Assuming same format as VSM color texture
|
||||||
}
|
}
|
||||||
|
|
||||||
s->vram_usage_total += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // Assuming same format as VSM color texture
|
|
||||||
s->vram_usage_vsm += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // Assuming same format as VSM color texture
|
|
||||||
|
|
||||||
// CSM blur texture (if used)
|
// CSM blur texture (if used)
|
||||||
if (s->maps[i].blur_texture_2d != 0) {
|
if (s->maps[i].blur_texture_2d != 0) {
|
||||||
|
|
|
@ -5690,6 +5690,8 @@ struct nk_context {
|
||||||
#define NK_PI 3.141592654f
|
#define NK_PI 3.141592654f
|
||||||
#define NK_UTF_INVALID 0xFFFD
|
#define NK_UTF_INVALID 0xFFFD
|
||||||
#define NK_MAX_FLOAT_PRECISION 2
|
#define NK_MAX_FLOAT_PRECISION 2
|
||||||
|
#define NK_MAX_FLOAT_PRECISION2 6
|
||||||
|
#define NK_FLOAT_DECIMAL_POS_THRESHOLD 0.0005
|
||||||
|
|
||||||
#define NK_UNUSED(x) ((void)(x))
|
#define NK_UNUSED(x) ((void)(x))
|
||||||
#define NK_SATURATE(x) (NK_MAX(0, NK_MIN(1.0f, x)))
|
#define NK_SATURATE(x) (NK_MAX(0, NK_MIN(1.0f, x)))
|
||||||
|
@ -28148,11 +28150,11 @@ nk_do_property(nk_flags *ws,
|
||||||
break;
|
break;
|
||||||
case NK_PROPERTY_FLOAT:
|
case NK_PROPERTY_FLOAT:
|
||||||
NK_DTOA(string, (double)variant->value.f);
|
NK_DTOA(string, (double)variant->value.f);
|
||||||
num_len = nk_string_float_limit(string, NK_MAX_FLOAT_PRECISION);
|
num_len = nk_string_float_limit(string, variant->step.f <= NK_FLOAT_DECIMAL_POS_THRESHOLD ? NK_MAX_FLOAT_PRECISION2 : NK_MAX_FLOAT_PRECISION);
|
||||||
break;
|
break;
|
||||||
case NK_PROPERTY_DOUBLE:
|
case NK_PROPERTY_DOUBLE:
|
||||||
NK_DTOA(string, variant->value.d);
|
NK_DTOA(string, variant->value.d);
|
||||||
num_len = nk_string_float_limit(string, NK_MAX_FLOAT_PRECISION);
|
num_len = nk_string_float_limit(string, variant->step.f <= NK_FLOAT_DECIMAL_POS_THRESHOLD ? NK_MAX_FLOAT_PRECISION2 : NK_MAX_FLOAT_PRECISION);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
size = font->width(font->userdata, font->height, string, num_len);
|
size = font->width(font->userdata, font->height, string, num_len);
|
||||||
|
@ -28248,12 +28250,12 @@ nk_do_property(nk_flags *ws,
|
||||||
variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i, variant->max_value.i);
|
variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i, variant->max_value.i);
|
||||||
break;
|
break;
|
||||||
case NK_PROPERTY_FLOAT:
|
case NK_PROPERTY_FLOAT:
|
||||||
nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION);
|
nk_string_float_limit(buffer, variant->step.f <= NK_FLOAT_DECIMAL_POS_THRESHOLD ? NK_MAX_FLOAT_PRECISION2 : NK_MAX_FLOAT_PRECISION);
|
||||||
variant->value.f = nk_strtof(buffer, 0);
|
variant->value.f = nk_strtof(buffer, 0);
|
||||||
variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f, variant->max_value.f);
|
variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f, variant->max_value.f);
|
||||||
break;
|
break;
|
||||||
case NK_PROPERTY_DOUBLE:
|
case NK_PROPERTY_DOUBLE:
|
||||||
nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION);
|
nk_string_float_limit(buffer, variant->step.f <= NK_FLOAT_DECIMAL_POS_THRESHOLD ? NK_MAX_FLOAT_PRECISION2 : NK_MAX_FLOAT_PRECISION);
|
||||||
variant->value.d = nk_strtod(buffer, 0);
|
variant->value.d = nk_strtod(buffer, 0);
|
||||||
variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d, variant->max_value.d);
|
variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d, variant->max_value.d);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1483,7 +1483,11 @@ light_t light() {
|
||||||
l.cast_shadows = true;
|
l.cast_shadows = true;
|
||||||
l.processed_shadows = false;
|
l.processed_shadows = false;
|
||||||
l.shadow_distance = 200.0f;
|
l.shadow_distance = 200.0f;
|
||||||
l.shadow_bias = 0.01f;
|
l.shadow_near_clip = 0.01f;
|
||||||
|
l.shadow_bias = 0.005f;
|
||||||
|
l.normal_bias = 0.05f;
|
||||||
|
l.min_variance = 0.00002f;
|
||||||
|
l.variance_transition = 0.2f;
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1562,6 +1566,10 @@ void light_update(unsigned num_lights, light_t *lv) {
|
||||||
shader_float(va("u_lights[%d].quadratic", i), lv[i].falloff.quadratic);
|
shader_float(va("u_lights[%d].quadratic", i), lv[i].falloff.quadratic);
|
||||||
shader_float(va("u_lights[%d].innerCone", i), lv[i].innerCone);
|
shader_float(va("u_lights[%d].innerCone", i), lv[i].innerCone);
|
||||||
shader_float(va("u_lights[%d].outerCone", i), lv[i].outerCone);
|
shader_float(va("u_lights[%d].outerCone", i), lv[i].outerCone);
|
||||||
|
shader_float(va("u_lights[%d].shadow_bias", i), lv[i].shadow_bias);
|
||||||
|
shader_float(va("u_lights[%d].normal_bias", i), lv[i].normal_bias);
|
||||||
|
shader_float(va("u_lights[%d].min_variance", i), lv[i].min_variance);
|
||||||
|
shader_float(va("u_lights[%d].variance_transition", i), lv[i].variance_transition);
|
||||||
shader_bool(va("u_lights[%d].processed_shadows", i), lv[i].processed_shadows);
|
shader_bool(va("u_lights[%d].processed_shadows", i), lv[i].processed_shadows);
|
||||||
if (lv[i].processed_shadows) {
|
if (lv[i].processed_shadows) {
|
||||||
for (int j = 0; j < NUM_SHADOW_CASCADES; j++) {
|
for (int j = 0; j < NUM_SHADOW_CASCADES; j++) {
|
||||||
|
@ -1571,10 +1579,58 @@ void light_update(unsigned num_lights, light_t *lv) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ui_light(light_t *l) {
|
||||||
|
ui_int("Type", &l->type);
|
||||||
|
ui_vec3("Position", &l->pos);
|
||||||
|
ui_vec3("Direction", &l->dir);
|
||||||
|
ui_color3f("Diffuse", &l->diffuse.x);
|
||||||
|
ui_color3f("Specular", &l->specular.x);
|
||||||
|
ui_color3f("Ambient", &l->ambient.x);
|
||||||
|
ui_float("Specular Power", &l->specularPower);
|
||||||
|
ui_clampf("Radius", &l->radius, 0.0f, FLT_MAX);
|
||||||
|
ui_clampf_("Constant Falloff", &l->falloff.constant, 0.0, FLT_MAX, 0.005);
|
||||||
|
ui_clampf_("Linear Falloff", &l->falloff.linear, 0.0, FLT_MAX, 0.005);
|
||||||
|
ui_clampf_("Quadratic Falloff", &l->falloff.quadratic, 0.0, FLT_MAX, 0.005);
|
||||||
|
ui_float("Inner Cone", &l->innerCone);
|
||||||
|
ui_float("Outer Cone", &l->outerCone);
|
||||||
|
ui_float_("Shadow Bias", &l->shadow_bias, 0.00005);
|
||||||
|
ui_float_("Normal Bias", &l->normal_bias, 0.00005);
|
||||||
|
ui_float_("Min Variance", &l->min_variance, 0.00005);
|
||||||
|
ui_float_("Variance Transition", &l->variance_transition, 0.0005);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_lights(unsigned num_lights, light_t *lights) {
|
||||||
|
for (unsigned i = 0; i < num_lights; ++i) {
|
||||||
|
if (ui_collapse(va("Light %d", i), va("light_%d", i))) {
|
||||||
|
ui_light(&lights[i]);
|
||||||
|
ui_collapse_end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// shadowmaps
|
// shadowmaps
|
||||||
|
|
||||||
|
static inline
|
||||||
|
void shadowmap_init_common_resources(shadowmap_t *s, int vsm_texture_width, int csm_texture_width) {
|
||||||
|
// Create a cubemap depth texture
|
||||||
|
glGenTextures(1, &s->depth_texture);
|
||||||
|
glBindTexture(GL_TEXTURE_CUBE_MAP, s->depth_texture);
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT, vsm_texture_width, vsm_texture_width, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||||
|
|
||||||
|
// Create a 2D depth texture
|
||||||
|
glGenTextures(1, &s->depth_texture_2d);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, s->depth_texture_2d);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, csm_texture_width, csm_texture_width, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
shadowmap_init_caster_vsm(shadowmap_t *s, int light_index, int texture_width) {
|
shadowmap_init_caster_vsm(shadowmap_t *s, int light_index, int texture_width) {
|
||||||
float borderColor[] = {1.0, 1.0, 1.0, 1.0};
|
float borderColor[] = {1.0, 1.0, 1.0, 1.0};
|
||||||
|
@ -1598,19 +1654,6 @@ shadowmap_init_caster_vsm(shadowmap_t *s, int light_index, int texture_width) {
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||||
glTexParameterfv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BORDER_COLOR, borderColor);
|
glTexParameterfv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BORDER_COLOR, borderColor);
|
||||||
|
|
||||||
// Create a cubemap depth texture
|
|
||||||
glGenTextures(1, &s->maps[light_index].depth_texture);
|
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, s->maps[light_index].depth_texture);
|
|
||||||
for (int i = 0; i < 6; i++) {
|
|
||||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT, texture_width, texture_width, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
|
|
||||||
}
|
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER);
|
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
|
||||||
glTexParameterfv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BORDER_COLOR, borderColor);
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1632,15 +1675,6 @@ shadowmap_init_caster_csm(shadowmap_t *s, int light_index, int texture_width) {
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||||
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
|
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
|
||||||
|
|
||||||
glGenTextures(1, &s->maps[light_index].depth_texture_2d[i]);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, s->maps[light_index].depth_texture_2d[i]);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, texture_width, texture_width, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
|
|
||||||
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_BORDER);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
|
||||||
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
@ -1691,6 +1725,8 @@ shadowmap_t shadowmap(int vsm_texture_width, int csm_texture_width) { // = 512,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
shadowmap_init_common_resources(&s, vsm_texture_width, csm_texture_width);
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, s.saved_fb);
|
glBindFramebuffer(GL_FRAMEBUFFER, s.saved_fb);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
@ -1704,20 +1740,12 @@ void shadowmap_destroy_light(shadowmap_t *s, int light_index) {
|
||||||
glDeleteTextures(1, &s->maps[light_index].texture);
|
glDeleteTextures(1, &s->maps[light_index].texture);
|
||||||
s->maps[light_index].texture = 0;
|
s->maps[light_index].texture = 0;
|
||||||
}
|
}
|
||||||
if (s->maps[light_index].depth_texture) {
|
|
||||||
glDeleteTextures(1, &s->maps[light_index].depth_texture);
|
|
||||||
s->maps[light_index].depth_texture = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < NUM_SHADOW_CASCADES; i++) {
|
for (int i = 0; i < NUM_SHADOW_CASCADES; i++) {
|
||||||
if (s->maps[light_index].texture_2d[i]) {
|
if (s->maps[light_index].texture_2d[i]) {
|
||||||
glDeleteTextures(1, &s->maps[light_index].texture_2d[i]);
|
glDeleteTextures(1, &s->maps[light_index].texture_2d[i]);
|
||||||
s->maps[light_index].texture_2d[i] = 0;
|
s->maps[light_index].texture_2d[i] = 0;
|
||||||
}
|
}
|
||||||
if (s->maps[light_index].depth_texture_2d[i]) {
|
|
||||||
glDeleteTextures(1, &s->maps[light_index].depth_texture_2d[i]);
|
|
||||||
s->maps[light_index].depth_texture_2d[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->maps[light_index].blur_texture_2d) {
|
if (s->maps[light_index].blur_texture_2d) {
|
||||||
|
@ -1735,6 +1763,18 @@ void shadowmap_destroy(shadowmap_t *s) {
|
||||||
for (int i = 0; i < MAX_LIGHTS; i++) {
|
for (int i = 0; i < MAX_LIGHTS; i++) {
|
||||||
shadowmap_destroy_light(s, i);
|
shadowmap_destroy_light(s, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (s->depth_texture) {
|
||||||
|
glDeleteTextures(1, &s->depth_texture);
|
||||||
|
s->depth_texture = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s->depth_texture_2d) {
|
||||||
|
glDeleteTextures(1, &s->depth_texture_2d);
|
||||||
|
s->depth_texture_2d = 0;
|
||||||
|
}
|
||||||
|
|
||||||
shadowmap_t z = {0};
|
shadowmap_t z = {0};
|
||||||
*s = z;
|
*s = z;
|
||||||
}
|
}
|
||||||
|
@ -1762,7 +1802,7 @@ void shadowmap_begin(shadowmap_t *s) {
|
||||||
static void shadowmap_light_point(shadowmap_t *s, light_t *l, int dir) {
|
static void shadowmap_light_point(shadowmap_t *s, light_t *l, int dir) {
|
||||||
if(dir<0) return;
|
if(dir<0) return;
|
||||||
mat44 P, V, PV;
|
mat44 P, V, PV;
|
||||||
perspective44(P, 90.0f, 1.0f, l->shadow_bias, l->shadow_distance);
|
perspective44(P, 90.0f, 1.0f, l->shadow_near_clip, l->shadow_distance);
|
||||||
vec3 lightPos = l->pos;
|
vec3 lightPos = l->pos;
|
||||||
|
|
||||||
/**/ if(dir == 0) lookat44(V, lightPos, add3(lightPos, vec3(+1, 0, 0)), vec3(0, -1, 0)); // +X
|
/**/ if(dir == 0) lookat44(V, lightPos, add3(lightPos, vec3(+1, 0, 0)), vec3(0, -1, 0)); // +X
|
||||||
|
@ -1815,7 +1855,7 @@ static void shadowmap_light_directional(shadowmap_t *s, light_t *l, int dir, flo
|
||||||
float near_plane = 0.0f;
|
float near_plane = 0.0f;
|
||||||
|
|
||||||
if (s->cascade_index == 0) {
|
if (s->cascade_index == 0) {
|
||||||
near_plane = l->shadow_bias;
|
near_plane = l->shadow_near_clip;
|
||||||
far_plane = l->shadow_distance * s->cascade_splits[0];
|
far_plane = l->shadow_distance * s->cascade_splits[0];
|
||||||
} else if (s->cascade_index < NUM_SHADOW_CASCADES - 1) {
|
} else if (s->cascade_index < NUM_SHADOW_CASCADES - 1) {
|
||||||
near_plane = l->shadow_distance * s->cascade_splits[s->cascade_index-1];
|
near_plane = l->shadow_distance * s->cascade_splits[s->cascade_index-1];
|
||||||
|
@ -2130,12 +2170,12 @@ void shadowmap_light(shadowmap_t *s, light_t *l, mat44 cam_proj, mat44 cam_view)
|
||||||
if (l->type == LIGHT_DIRECTIONAL) {
|
if (l->type == LIGHT_DIRECTIONAL) {
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, s->fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, s->fbo);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, s->maps[s->light_step].texture_2d[s->cascade_index], 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, s->maps[s->light_step].texture_2d[s->cascade_index], 0);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, s->maps[s->light_step].depth_texture_2d[s->cascade_index], 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, s->depth_texture_2d, 0);
|
||||||
shadowmap_clear_fbo();
|
shadowmap_clear_fbo();
|
||||||
} else {
|
} else {
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, s->fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, s->fbo);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + step, s->maps[s->light_step].texture, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + step, s->maps[s->light_step].texture, 0);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + step, s->maps[s->light_step].depth_texture, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + step, s->depth_texture, 0);
|
||||||
shadowmap_clear_fbo();
|
shadowmap_clear_fbo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2157,19 +2197,25 @@ void shadowmap_end(shadowmap_t *s) {
|
||||||
{
|
{
|
||||||
const int faces = 6;
|
const int faces = 6;
|
||||||
const int cascades = NUM_SHADOW_CASCADES;
|
const int cascades = NUM_SHADOW_CASCADES;
|
||||||
|
|
||||||
|
// Depth textures
|
||||||
|
s->vram_usage += s->vsm_texture_width * s->vsm_texture_width * faces * 1;
|
||||||
|
s->vram_usage += s->csm_texture_width * s->csm_texture_width * 1;
|
||||||
|
s->vram_usage_total += s->vsm_texture_width * s->vsm_texture_width * faces * 1;
|
||||||
|
s->vram_usage_vsm += s->vsm_texture_width * s->vsm_texture_width * faces * 8;
|
||||||
|
s->vram_usage_total += s->vsm_texture_width * s->vsm_texture_width * faces * 8;
|
||||||
|
s->vram_usage_csm += s->csm_texture_width * s->csm_texture_width * 1;
|
||||||
|
|
||||||
for (int i = 0; i < MAX_LIGHTS; i++) {
|
for (int i = 0; i < MAX_LIGHTS; i++) {
|
||||||
// VSM textures
|
// VSM textures
|
||||||
if (s->maps[i].texture != 0) {
|
if (s->maps[i].texture != 0) {
|
||||||
// Color texture (GL_RG32F)
|
// Color texture (GL_RG32F)
|
||||||
s->vram_usage += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // 8 bytes per pixel (2 * 32-bit float)
|
s->vram_usage += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // 8 bytes per pixel (2 * 32-bit float)
|
||||||
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
|
|
||||||
s->vram_usage += s->vsm_texture_width * s->vsm_texture_width * faces * 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Color texture (GL_RG32F)
|
// Color texture (GL_RG32F)
|
||||||
s->vram_usage_total += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // 8 bytes per pixel (2 * 32-bit float)
|
s->vram_usage_total += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // 8 bytes per pixel (2 * 32-bit float)
|
||||||
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
|
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
|
||||||
s->vram_usage_total += s->vsm_texture_width * s->vsm_texture_width * faces * 1;
|
|
||||||
|
|
||||||
// Color texture (GL_RG32F)
|
// Color texture (GL_RG32F)
|
||||||
s->vram_usage_vsm += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // 8 bytes per pixel (2 * 32-bit float)
|
s->vram_usage_vsm += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // 8 bytes per pixel (2 * 32-bit float)
|
||||||
|
@ -2182,20 +2228,13 @@ void shadowmap_end(shadowmap_t *s) {
|
||||||
for (int j = 0; j < cascades; j++) {
|
for (int j = 0; j < cascades; j++) {
|
||||||
// Color texture (GL_R32F)
|
// Color texture (GL_R32F)
|
||||||
s->vram_usage += s->csm_texture_width * s->csm_texture_width * 4; // 4 bytes per pixel (1 * 32-bit float)
|
s->vram_usage += s->csm_texture_width * s->csm_texture_width * 4; // 4 bytes per pixel (1 * 32-bit float)
|
||||||
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
|
|
||||||
s->vram_usage += s->csm_texture_width * s->csm_texture_width * 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < cascades; j++) {
|
for (int j = 0; j < cascades; j++) {
|
||||||
// Color texture (GL_R32F)
|
// Color texture (GL_R32F)
|
||||||
s->vram_usage_total += s->csm_texture_width * s->csm_texture_width * 4; // 4 bytes per pixel (1 * 32-bit float)
|
s->vram_usage_total += s->csm_texture_width * s->csm_texture_width * 4; // 4 bytes per pixel (1 * 32-bit float)
|
||||||
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
|
|
||||||
s->vram_usage_total += s->csm_texture_width * s->csm_texture_width * 1;
|
|
||||||
|
|
||||||
s->vram_usage_csm += s->csm_texture_width * s->csm_texture_width * 4; // 4 bytes per pixel (1 * 32-bit float)
|
s->vram_usage_csm += s->csm_texture_width * s->csm_texture_width * 4; // 4 bytes per pixel (1 * 32-bit float)
|
||||||
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
|
|
||||||
s->vram_usage_csm += s->csm_texture_width * s->csm_texture_width * 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// VSM blur texture (if used)
|
// VSM blur texture (if used)
|
||||||
|
@ -2203,8 +2242,6 @@ void shadowmap_end(shadowmap_t *s) {
|
||||||
s->vram_usage += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // Assuming same format as VSM color texture
|
s->vram_usage += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // Assuming same format as VSM color texture
|
||||||
}
|
}
|
||||||
|
|
||||||
s->vram_usage_total += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // Assuming same format as VSM color texture
|
|
||||||
s->vram_usage_vsm += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // Assuming same format as VSM color texture
|
|
||||||
|
|
||||||
// CSM blur texture (if used)
|
// CSM blur texture (if used)
|
||||||
if (s->maps[i].blur_texture_2d != 0) {
|
if (s->maps[i].blur_texture_2d != 0) {
|
||||||
|
|
|
@ -302,7 +302,7 @@ enum SHADOW_TECHNIQUE {
|
||||||
#define NUM_SHADOW_CASCADES 4
|
#define NUM_SHADOW_CASCADES 4
|
||||||
|
|
||||||
typedef struct light_t {
|
typedef struct light_t {
|
||||||
char type;
|
unsigned type;
|
||||||
vec3 diffuse, specular, ambient;
|
vec3 diffuse, specular, ambient;
|
||||||
vec3 pos, dir;
|
vec3 pos, dir;
|
||||||
struct {
|
struct {
|
||||||
|
@ -315,14 +315,18 @@ typedef struct light_t {
|
||||||
|
|
||||||
// Shadowmapping
|
// Shadowmapping
|
||||||
bool cast_shadows;
|
bool cast_shadows;
|
||||||
bool processed_shadows;
|
|
||||||
unsigned shadow_technique;
|
unsigned shadow_technique;
|
||||||
float shadow_distance;
|
float shadow_distance;
|
||||||
float shadow_bias;
|
float shadow_near_clip;
|
||||||
mat44 shadow_matrix[NUM_SHADOW_CASCADES];
|
mat44 shadow_matrix[NUM_SHADOW_CASCADES];
|
||||||
|
float min_variance; //< VSM
|
||||||
|
float variance_transition; //< VSM
|
||||||
|
float shadow_bias; //< CSM
|
||||||
|
float normal_bias; //< CSM
|
||||||
|
|
||||||
// internals
|
// internals
|
||||||
bool cached; //< used by scene to invalidate cached light data
|
bool cached; //< used by scene to invalidate cached light data
|
||||||
|
bool processed_shadows;
|
||||||
} light_t;
|
} light_t;
|
||||||
|
|
||||||
API light_t light();
|
API light_t light();
|
||||||
|
@ -339,6 +343,10 @@ API void light_falloff(light_t* l, float constant, float linear, float quadra
|
||||||
API void light_cone(light_t* l, float innerCone, float outerCone);
|
API void light_cone(light_t* l, float innerCone, float outerCone);
|
||||||
API void light_update(unsigned num_lights, light_t *lv);
|
API void light_update(unsigned num_lights, light_t *lv);
|
||||||
|
|
||||||
|
API void ui_light(light_t *l);
|
||||||
|
API void ui_lights(unsigned num_lights, light_t *lights);
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// shadowmaps
|
// shadowmaps
|
||||||
|
|
||||||
|
@ -368,11 +376,15 @@ typedef struct shadowmap_t {
|
||||||
uint64_t vram_usage_vsm;
|
uint64_t vram_usage_vsm;
|
||||||
uint64_t vram_usage_csm;
|
uint64_t vram_usage_csm;
|
||||||
|
|
||||||
|
// depth texture
|
||||||
|
handle depth_texture;
|
||||||
|
handle depth_texture_2d;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
int gen;
|
int gen;
|
||||||
unsigned shadow_technique;
|
unsigned shadow_technique;
|
||||||
handle texture, depth_texture;
|
handle texture;
|
||||||
handle texture_2d[NUM_SHADOW_CASCADES], depth_texture_2d[NUM_SHADOW_CASCADES];
|
handle texture_2d[NUM_SHADOW_CASCADES];
|
||||||
handle blur_texture, blur_texture_2d;
|
handle blur_texture, blur_texture_2d;
|
||||||
// handle blur_fbo_cubemap, blur_texture_cubemap;
|
// handle blur_fbo_cubemap, blur_texture_cubemap;
|
||||||
float cascade_distances[NUM_SHADOW_CASCADES];
|
float cascade_distances[NUM_SHADOW_CASCADES];
|
||||||
|
|
|
@ -2234,13 +2234,42 @@ int ui_short(const char *label, short *v) {
|
||||||
return *v = (short)i, ret;
|
return *v = (short)i, ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ui_float(const char *label, float *v) {
|
static inline
|
||||||
|
float ui_float_adjust_step(float step) {
|
||||||
|
if ((input(KEY_LSHIFT) || input(KEY_RSHIFT))&&(input(KEY_LCTRL) || input(KEY_RCTRL))) step *= 100.0f;
|
||||||
|
else if (input(KEY_LSHIFT) || input(KEY_RSHIFT)) step *= 10.0f;
|
||||||
|
else if (input(KEY_LCTRL) || input(KEY_RCTRL)) step *= 0.1f;
|
||||||
|
else if (input(KEY_LALT) || input(KEY_RALT)) step *= 0.01f;
|
||||||
|
return step;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ui_float_(const char *label, float *v, float step) {
|
||||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||||
|
|
||||||
|
float inc_per_pixel = ui_float_adjust_step(0.005f);
|
||||||
|
step = ui_float_adjust_step(step);
|
||||||
|
|
||||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||||
ui_label_(label, NK_TEXT_LEFT);
|
ui_label_(label, NK_TEXT_LEFT);
|
||||||
|
|
||||||
float prev = v[0]; v[0] = nk_propertyf(ui_ctx, "#", -FLT_MAX, v[0], FLT_MAX, 0.01f,0.005f);
|
float prev = v[0]; v[0] = nk_propertyf(ui_ctx, "#", -FLT_MAX, v[0], FLT_MAX, step, inc_per_pixel);
|
||||||
|
return prev != v[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
int ui_float(const char *label, float *v) {
|
||||||
|
return ui_float_(label, v, 0.01f);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ui_double_(const char *label, double *v, double step) {
|
||||||
|
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||||
|
|
||||||
|
float inc_per_pixel = ui_float_adjust_step(0.005f);
|
||||||
|
step = ui_float_adjust_step(step);
|
||||||
|
|
||||||
|
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||||
|
ui_label_(label, NK_TEXT_LEFT);
|
||||||
|
|
||||||
|
double prev = v[0]; v[0] = nk_propertyd(ui_ctx, "#", -DBL_MAX, v[0], DBL_MAX, step, inc_per_pixel);
|
||||||
return prev != v[0];
|
return prev != v[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2254,21 +2283,30 @@ int ui_double(const char *label, double *v) {
|
||||||
return prev != v[0];
|
return prev != v[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
int ui_clampf(const char *label, float *v, float minf, float maxf) {
|
int ui_clampf_(const char *label, float *v, float minf, float maxf, float step) {
|
||||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||||
|
|
||||||
|
float inc_per_pixel = ui_float_adjust_step(0.005f);
|
||||||
|
step = ui_float_adjust_step(step);
|
||||||
|
|
||||||
if( minf > maxf ) return ui_clampf(label, v, maxf, minf);
|
if( minf > maxf ) return ui_clampf(label, v, maxf, minf);
|
||||||
|
|
||||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||||
ui_label_(label, NK_TEXT_LEFT);
|
ui_label_(label, NK_TEXT_LEFT);
|
||||||
|
|
||||||
float prev = v[0]; v[0] = nk_propertyf(ui_ctx, "#", minf, v[0], maxf, 0.1f,0.05f);
|
float prev = v[0]; v[0] = nk_propertyf(ui_ctx, "#", minf, v[0], maxf, step, inc_per_pixel);
|
||||||
return prev != v[0];
|
return prev != v[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
int ui_float2(const char *label, float *v) {
|
int ui_clampf(const char *label, float *v, float minf, float maxf) {
|
||||||
|
return ui_clampf_(label, v, minf, maxf, 0.1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ui_float2_(const char *label, float *v, float step) {
|
||||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||||
|
|
||||||
|
float inc_per_pixel = ui_float_adjust_step(0.5f);
|
||||||
|
step = ui_float_adjust_step(step);
|
||||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||||
ui_label_(label, NK_TEXT_LEFT);
|
ui_label_(label, NK_TEXT_LEFT);
|
||||||
|
|
||||||
|
@ -2278,17 +2316,23 @@ int ui_float2(const char *label, float *v) {
|
||||||
|
|
||||||
if (nk_combo_begin_label(ui_ctx, buffer, nk_vec2(200,200))) {
|
if (nk_combo_begin_label(ui_ctx, buffer, nk_vec2(200,200))) {
|
||||||
nk_layout_row_dynamic(ui_ctx, 0, 1);
|
nk_layout_row_dynamic(ui_ctx, 0, 1);
|
||||||
float prev0 = v[0]; nk_property_float(ui_ctx, "#X:", -FLT_MAX, &v[0], FLT_MAX, 1,0.5f);
|
float prev0 = v[0]; nk_property_float(ui_ctx, "#X:", -FLT_MAX, &v[0], FLT_MAX, step, inc_per_pixel);
|
||||||
float prev1 = v[1]; nk_property_float(ui_ctx, "#Y:", -FLT_MAX, &v[1], FLT_MAX, 1,0.5f);
|
float prev1 = v[1]; nk_property_float(ui_ctx, "#Y:", -FLT_MAX, &v[1], FLT_MAX, step, inc_per_pixel);
|
||||||
nk_combo_end(ui_ctx);
|
nk_combo_end(ui_ctx);
|
||||||
return prev0 != v[0] || prev1 != v[1];
|
return prev0 != v[0] || prev1 != v[1];
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ui_float3(const char *label, float *v) {
|
int ui_float2(const char *label, float *v) {
|
||||||
|
return ui_float2_(label, v, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ui_float3_(const char *label, float *v, float step) {
|
||||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||||
|
|
||||||
|
float inc_per_pixel = ui_float_adjust_step(0.5f);
|
||||||
|
step = ui_float_adjust_step(step);
|
||||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||||
ui_label_(label, NK_TEXT_LEFT);
|
ui_label_(label, NK_TEXT_LEFT);
|
||||||
|
|
||||||
|
@ -2298,18 +2342,25 @@ int ui_float3(const char *label, float *v) {
|
||||||
|
|
||||||
if (nk_combo_begin_label(ui_ctx, buffer, nk_vec2(200,200))) {
|
if (nk_combo_begin_label(ui_ctx, buffer, nk_vec2(200,200))) {
|
||||||
nk_layout_row_dynamic(ui_ctx, 0, 1);
|
nk_layout_row_dynamic(ui_ctx, 0, 1);
|
||||||
float prev0 = v[0]; nk_property_float(ui_ctx, "#X:", -FLT_MAX, &v[0], FLT_MAX, 1,0.5f);
|
float prev0 = v[0]; nk_property_float(ui_ctx, "#X:", -FLT_MAX, &v[0], FLT_MAX, step, inc_per_pixel);
|
||||||
float prev1 = v[1]; nk_property_float(ui_ctx, "#Y:", -FLT_MAX, &v[1], FLT_MAX, 1,0.5f);
|
float prev1 = v[1]; nk_property_float(ui_ctx, "#Y:", -FLT_MAX, &v[1], FLT_MAX, step, inc_per_pixel);
|
||||||
float prev2 = v[2]; nk_property_float(ui_ctx, "#Z:", -FLT_MAX, &v[2], FLT_MAX, 1,0.5f);
|
float prev2 = v[2]; nk_property_float(ui_ctx, "#Z:", -FLT_MAX, &v[2], FLT_MAX, step, inc_per_pixel);
|
||||||
nk_combo_end(ui_ctx);
|
nk_combo_end(ui_ctx);
|
||||||
return prev0 != v[0] || prev1 != v[1] || prev2 != v[2];
|
return prev0 != v[0] || prev1 != v[1] || prev2 != v[2];
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ui_float4(const char *label, float *v) {
|
|
||||||
|
int ui_float3(const char *label, float *v) {
|
||||||
|
return ui_float3_(label, v, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ui_float4_(const char *label, float *v, float step) {
|
||||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||||
|
|
||||||
|
float inc_per_pixel = ui_float_adjust_step(0.5f);
|
||||||
|
step = ui_float_adjust_step(step);
|
||||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||||
ui_label_(label, NK_TEXT_LEFT);
|
ui_label_(label, NK_TEXT_LEFT);
|
||||||
|
|
||||||
|
@ -2319,10 +2370,10 @@ int ui_float4(const char *label, float *v) {
|
||||||
|
|
||||||
if (nk_combo_begin_label(ui_ctx, buffer, nk_vec2(200,200))) {
|
if (nk_combo_begin_label(ui_ctx, buffer, nk_vec2(200,200))) {
|
||||||
nk_layout_row_dynamic(ui_ctx, 0, 1);
|
nk_layout_row_dynamic(ui_ctx, 0, 1);
|
||||||
float prev0 = v[0]; nk_property_float(ui_ctx, "#X:", -FLT_MAX, &v[0], FLT_MAX, 1,0.5f);
|
float prev0 = v[0]; nk_property_float(ui_ctx, "#X:", -FLT_MAX, &v[0], FLT_MAX, step, inc_per_pixel);
|
||||||
float prev1 = v[1]; nk_property_float(ui_ctx, "#Y:", -FLT_MAX, &v[1], FLT_MAX, 1,0.5f);
|
float prev1 = v[1]; nk_property_float(ui_ctx, "#Y:", -FLT_MAX, &v[1], FLT_MAX, step, inc_per_pixel);
|
||||||
float prev2 = v[2]; nk_property_float(ui_ctx, "#Z:", -FLT_MAX, &v[2], FLT_MAX, 1,0.5f);
|
float prev2 = v[2]; nk_property_float(ui_ctx, "#Z:", -FLT_MAX, &v[2], FLT_MAX, step, inc_per_pixel);
|
||||||
float prev3 = v[3]; nk_property_float(ui_ctx, "#W:", -FLT_MAX, &v[3], FLT_MAX, 1,0.5f);
|
float prev3 = v[3]; nk_property_float(ui_ctx, "#W:", -FLT_MAX, &v[3], FLT_MAX, step, inc_per_pixel);
|
||||||
nk_combo_end(ui_ctx);
|
nk_combo_end(ui_ctx);
|
||||||
return prev0 != v[0] || prev1 != v[1] || prev2 != v[2] || prev3 != v[3];
|
return prev0 != v[0] || prev1 != v[1] || prev2 != v[2] || prev3 != v[3];
|
||||||
}
|
}
|
||||||
|
@ -2330,6 +2381,10 @@ int ui_float4(const char *label, float *v) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ui_float4(const char *label, float *v) {
|
||||||
|
return ui_float4_(label, v, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
int ui_mat33(const char *label, float M[9]) {
|
int ui_mat33(const char *label, float M[9]) {
|
||||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,10 @@ API int ui_section(const char *title);
|
||||||
API int ui_int(const char *label, int *value);
|
API int ui_int(const char *label, int *value);
|
||||||
API int ui_bool(const char *label, bool *value);
|
API int ui_bool(const char *label, bool *value);
|
||||||
API int ui_short(const char *label, short *value);
|
API int ui_short(const char *label, short *value);
|
||||||
|
API int ui_float_(const char *label, float *value, float step);
|
||||||
|
API int ui_float2_(const char *label, float value[2], float step);
|
||||||
|
API int ui_float3_(const char *label, float value[3], float step);
|
||||||
|
API int ui_float4_(const char *label, float value[4], float step);
|
||||||
API int ui_float(const char *label, float *value);
|
API int ui_float(const char *label, float *value);
|
||||||
API int ui_float2(const char *label, float value[2]);
|
API int ui_float2(const char *label, float value[2]);
|
||||||
API int ui_float3(const char *label, float value[3]);
|
API int ui_float3(const char *label, float value[3]);
|
||||||
|
@ -55,6 +59,7 @@ API int ui_separator();
|
||||||
API int ui_bitmask8(const char *label, uint8_t *bits);
|
API int ui_bitmask8(const char *label, uint8_t *bits);
|
||||||
API int ui_bitmask16(const char *label, uint16_t *bits);
|
API int ui_bitmask16(const char *label, uint16_t *bits);
|
||||||
API int ui_console();
|
API int ui_console();
|
||||||
|
API int ui_clampf_(const char *label, float *value, float minf, float maxf, float step);
|
||||||
API int ui_clampf(const char *label, float *value, float minf, float maxf);
|
API int ui_clampf(const char *label, float *value, float minf, float maxf);
|
||||||
API int ui_label(const char *label);
|
API int ui_label(const char *label);
|
||||||
API int ui_label2(const char *label, const char *caption);
|
API int ui_label2(const char *label, const char *caption);
|
||||||
|
|
10
engine/v4k
10
engine/v4k
|
@ -209788,6 +209788,8 @@ struct nk_context {
|
||||||
#define NK_PI 3.141592654f
|
#define NK_PI 3.141592654f
|
||||||
#define NK_UTF_INVALID 0xFFFD
|
#define NK_UTF_INVALID 0xFFFD
|
||||||
#define NK_MAX_FLOAT_PRECISION 2
|
#define NK_MAX_FLOAT_PRECISION 2
|
||||||
|
#define NK_MAX_FLOAT_PRECISION2 6
|
||||||
|
#define NK_FLOAT_DECIMAL_POS_THRESHOLD 0.0005
|
||||||
|
|
||||||
#define NK_UNUSED(x) ((void)(x))
|
#define NK_UNUSED(x) ((void)(x))
|
||||||
#define NK_SATURATE(x) (NK_MAX(0, NK_MIN(1.0f, x)))
|
#define NK_SATURATE(x) (NK_MAX(0, NK_MIN(1.0f, x)))
|
||||||
|
@ -232246,11 +232248,11 @@ nk_do_property(nk_flags *ws,
|
||||||
break;
|
break;
|
||||||
case NK_PROPERTY_FLOAT:
|
case NK_PROPERTY_FLOAT:
|
||||||
NK_DTOA(string, (double)variant->value.f);
|
NK_DTOA(string, (double)variant->value.f);
|
||||||
num_len = nk_string_float_limit(string, NK_MAX_FLOAT_PRECISION);
|
num_len = nk_string_float_limit(string, variant->step.f <= NK_FLOAT_DECIMAL_POS_THRESHOLD ? NK_MAX_FLOAT_PRECISION2 : NK_MAX_FLOAT_PRECISION);
|
||||||
break;
|
break;
|
||||||
case NK_PROPERTY_DOUBLE:
|
case NK_PROPERTY_DOUBLE:
|
||||||
NK_DTOA(string, variant->value.d);
|
NK_DTOA(string, variant->value.d);
|
||||||
num_len = nk_string_float_limit(string, NK_MAX_FLOAT_PRECISION);
|
num_len = nk_string_float_limit(string, variant->step.f <= NK_FLOAT_DECIMAL_POS_THRESHOLD ? NK_MAX_FLOAT_PRECISION2 : NK_MAX_FLOAT_PRECISION);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
size = font->width(font->userdata, font->height, string, num_len);
|
size = font->width(font->userdata, font->height, string, num_len);
|
||||||
|
@ -232346,12 +232348,12 @@ nk_do_property(nk_flags *ws,
|
||||||
variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i, variant->max_value.i);
|
variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i, variant->max_value.i);
|
||||||
break;
|
break;
|
||||||
case NK_PROPERTY_FLOAT:
|
case NK_PROPERTY_FLOAT:
|
||||||
nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION);
|
nk_string_float_limit(buffer, variant->step.f <= NK_FLOAT_DECIMAL_POS_THRESHOLD ? NK_MAX_FLOAT_PRECISION2 : NK_MAX_FLOAT_PRECISION);
|
||||||
variant->value.f = nk_strtof(buffer, 0);
|
variant->value.f = nk_strtof(buffer, 0);
|
||||||
variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f, variant->max_value.f);
|
variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f, variant->max_value.f);
|
||||||
break;
|
break;
|
||||||
case NK_PROPERTY_DOUBLE:
|
case NK_PROPERTY_DOUBLE:
|
||||||
nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION);
|
nk_string_float_limit(buffer, variant->step.f <= NK_FLOAT_DECIMAL_POS_THRESHOLD ? NK_MAX_FLOAT_PRECISION2 : NK_MAX_FLOAT_PRECISION);
|
||||||
variant->value.d = nk_strtod(buffer, 0);
|
variant->value.d = nk_strtod(buffer, 0);
|
||||||
variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d, variant->max_value.d);
|
variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d, variant->max_value.d);
|
||||||
break;
|
break;
|
||||||
|
|
218
engine/v4k.c
218
engine/v4k.c
|
@ -3442,13 +3442,42 @@ int ui_short(const char *label, short *v) {
|
||||||
return *v = (short)i, ret;
|
return *v = (short)i, ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ui_float(const char *label, float *v) {
|
static inline
|
||||||
|
float ui_float_adjust_step(float step) {
|
||||||
|
if ((input(KEY_LSHIFT) || input(KEY_RSHIFT))&&(input(KEY_LCTRL) || input(KEY_RCTRL))) step *= 100.0f;
|
||||||
|
else if (input(KEY_LSHIFT) || input(KEY_RSHIFT)) step *= 10.0f;
|
||||||
|
else if (input(KEY_LCTRL) || input(KEY_RCTRL)) step *= 0.1f;
|
||||||
|
else if (input(KEY_LALT) || input(KEY_RALT)) step *= 0.01f;
|
||||||
|
return step;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ui_float_(const char *label, float *v, float step) {
|
||||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||||
|
|
||||||
|
float inc_per_pixel = ui_float_adjust_step(0.005f);
|
||||||
|
step = ui_float_adjust_step(step);
|
||||||
|
|
||||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||||
ui_label_(label, NK_TEXT_LEFT);
|
ui_label_(label, NK_TEXT_LEFT);
|
||||||
|
|
||||||
float prev = v[0]; v[0] = nk_propertyf(ui_ctx, "#", -FLT_MAX, v[0], FLT_MAX, 0.01f,0.005f);
|
float prev = v[0]; v[0] = nk_propertyf(ui_ctx, "#", -FLT_MAX, v[0], FLT_MAX, step, inc_per_pixel);
|
||||||
|
return prev != v[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
int ui_float(const char *label, float *v) {
|
||||||
|
return ui_float_(label, v, 0.01f);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ui_double_(const char *label, double *v, double step) {
|
||||||
|
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||||
|
|
||||||
|
float inc_per_pixel = ui_float_adjust_step(0.005f);
|
||||||
|
step = ui_float_adjust_step(step);
|
||||||
|
|
||||||
|
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||||
|
ui_label_(label, NK_TEXT_LEFT);
|
||||||
|
|
||||||
|
double prev = v[0]; v[0] = nk_propertyd(ui_ctx, "#", -DBL_MAX, v[0], DBL_MAX, step, inc_per_pixel);
|
||||||
return prev != v[0];
|
return prev != v[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3462,21 +3491,30 @@ int ui_double(const char *label, double *v) {
|
||||||
return prev != v[0];
|
return prev != v[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
int ui_clampf(const char *label, float *v, float minf, float maxf) {
|
int ui_clampf_(const char *label, float *v, float minf, float maxf, float step) {
|
||||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||||
|
|
||||||
|
float inc_per_pixel = ui_float_adjust_step(0.005f);
|
||||||
|
step = ui_float_adjust_step(step);
|
||||||
|
|
||||||
if( minf > maxf ) return ui_clampf(label, v, maxf, minf);
|
if( minf > maxf ) return ui_clampf(label, v, maxf, minf);
|
||||||
|
|
||||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||||
ui_label_(label, NK_TEXT_LEFT);
|
ui_label_(label, NK_TEXT_LEFT);
|
||||||
|
|
||||||
float prev = v[0]; v[0] = nk_propertyf(ui_ctx, "#", minf, v[0], maxf, 0.1f,0.05f);
|
float prev = v[0]; v[0] = nk_propertyf(ui_ctx, "#", minf, v[0], maxf, step, inc_per_pixel);
|
||||||
return prev != v[0];
|
return prev != v[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
int ui_float2(const char *label, float *v) {
|
int ui_clampf(const char *label, float *v, float minf, float maxf) {
|
||||||
|
return ui_clampf_(label, v, minf, maxf, 0.1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ui_float2_(const char *label, float *v, float step) {
|
||||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||||
|
|
||||||
|
float inc_per_pixel = ui_float_adjust_step(0.5f);
|
||||||
|
step = ui_float_adjust_step(step);
|
||||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||||
ui_label_(label, NK_TEXT_LEFT);
|
ui_label_(label, NK_TEXT_LEFT);
|
||||||
|
|
||||||
|
@ -3486,17 +3524,23 @@ int ui_float2(const char *label, float *v) {
|
||||||
|
|
||||||
if (nk_combo_begin_label(ui_ctx, buffer, nk_vec2(200,200))) {
|
if (nk_combo_begin_label(ui_ctx, buffer, nk_vec2(200,200))) {
|
||||||
nk_layout_row_dynamic(ui_ctx, 0, 1);
|
nk_layout_row_dynamic(ui_ctx, 0, 1);
|
||||||
float prev0 = v[0]; nk_property_float(ui_ctx, "#X:", -FLT_MAX, &v[0], FLT_MAX, 1,0.5f);
|
float prev0 = v[0]; nk_property_float(ui_ctx, "#X:", -FLT_MAX, &v[0], FLT_MAX, step, inc_per_pixel);
|
||||||
float prev1 = v[1]; nk_property_float(ui_ctx, "#Y:", -FLT_MAX, &v[1], FLT_MAX, 1,0.5f);
|
float prev1 = v[1]; nk_property_float(ui_ctx, "#Y:", -FLT_MAX, &v[1], FLT_MAX, step, inc_per_pixel);
|
||||||
nk_combo_end(ui_ctx);
|
nk_combo_end(ui_ctx);
|
||||||
return prev0 != v[0] || prev1 != v[1];
|
return prev0 != v[0] || prev1 != v[1];
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ui_float3(const char *label, float *v) {
|
int ui_float2(const char *label, float *v) {
|
||||||
|
return ui_float2_(label, v, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ui_float3_(const char *label, float *v, float step) {
|
||||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||||
|
|
||||||
|
float inc_per_pixel = ui_float_adjust_step(0.5f);
|
||||||
|
step = ui_float_adjust_step(step);
|
||||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||||
ui_label_(label, NK_TEXT_LEFT);
|
ui_label_(label, NK_TEXT_LEFT);
|
||||||
|
|
||||||
|
@ -3506,18 +3550,25 @@ int ui_float3(const char *label, float *v) {
|
||||||
|
|
||||||
if (nk_combo_begin_label(ui_ctx, buffer, nk_vec2(200,200))) {
|
if (nk_combo_begin_label(ui_ctx, buffer, nk_vec2(200,200))) {
|
||||||
nk_layout_row_dynamic(ui_ctx, 0, 1);
|
nk_layout_row_dynamic(ui_ctx, 0, 1);
|
||||||
float prev0 = v[0]; nk_property_float(ui_ctx, "#X:", -FLT_MAX, &v[0], FLT_MAX, 1,0.5f);
|
float prev0 = v[0]; nk_property_float(ui_ctx, "#X:", -FLT_MAX, &v[0], FLT_MAX, step, inc_per_pixel);
|
||||||
float prev1 = v[1]; nk_property_float(ui_ctx, "#Y:", -FLT_MAX, &v[1], FLT_MAX, 1,0.5f);
|
float prev1 = v[1]; nk_property_float(ui_ctx, "#Y:", -FLT_MAX, &v[1], FLT_MAX, step, inc_per_pixel);
|
||||||
float prev2 = v[2]; nk_property_float(ui_ctx, "#Z:", -FLT_MAX, &v[2], FLT_MAX, 1,0.5f);
|
float prev2 = v[2]; nk_property_float(ui_ctx, "#Z:", -FLT_MAX, &v[2], FLT_MAX, step, inc_per_pixel);
|
||||||
nk_combo_end(ui_ctx);
|
nk_combo_end(ui_ctx);
|
||||||
return prev0 != v[0] || prev1 != v[1] || prev2 != v[2];
|
return prev0 != v[0] || prev1 != v[1] || prev2 != v[2];
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ui_float4(const char *label, float *v) {
|
|
||||||
|
int ui_float3(const char *label, float *v) {
|
||||||
|
return ui_float3_(label, v, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ui_float4_(const char *label, float *v, float step) {
|
||||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||||
|
|
||||||
|
float inc_per_pixel = ui_float_adjust_step(0.5f);
|
||||||
|
step = ui_float_adjust_step(step);
|
||||||
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
nk_layout_row_dynamic(ui_ctx, 0, 2);
|
||||||
ui_label_(label, NK_TEXT_LEFT);
|
ui_label_(label, NK_TEXT_LEFT);
|
||||||
|
|
||||||
|
@ -3527,10 +3578,10 @@ int ui_float4(const char *label, float *v) {
|
||||||
|
|
||||||
if (nk_combo_begin_label(ui_ctx, buffer, nk_vec2(200,200))) {
|
if (nk_combo_begin_label(ui_ctx, buffer, nk_vec2(200,200))) {
|
||||||
nk_layout_row_dynamic(ui_ctx, 0, 1);
|
nk_layout_row_dynamic(ui_ctx, 0, 1);
|
||||||
float prev0 = v[0]; nk_property_float(ui_ctx, "#X:", -FLT_MAX, &v[0], FLT_MAX, 1,0.5f);
|
float prev0 = v[0]; nk_property_float(ui_ctx, "#X:", -FLT_MAX, &v[0], FLT_MAX, step, inc_per_pixel);
|
||||||
float prev1 = v[1]; nk_property_float(ui_ctx, "#Y:", -FLT_MAX, &v[1], FLT_MAX, 1,0.5f);
|
float prev1 = v[1]; nk_property_float(ui_ctx, "#Y:", -FLT_MAX, &v[1], FLT_MAX, step, inc_per_pixel);
|
||||||
float prev2 = v[2]; nk_property_float(ui_ctx, "#Z:", -FLT_MAX, &v[2], FLT_MAX, 1,0.5f);
|
float prev2 = v[2]; nk_property_float(ui_ctx, "#Z:", -FLT_MAX, &v[2], FLT_MAX, step, inc_per_pixel);
|
||||||
float prev3 = v[3]; nk_property_float(ui_ctx, "#W:", -FLT_MAX, &v[3], FLT_MAX, 1,0.5f);
|
float prev3 = v[3]; nk_property_float(ui_ctx, "#W:", -FLT_MAX, &v[3], FLT_MAX, step, inc_per_pixel);
|
||||||
nk_combo_end(ui_ctx);
|
nk_combo_end(ui_ctx);
|
||||||
return prev0 != v[0] || prev1 != v[1] || prev2 != v[2] || prev3 != v[3];
|
return prev0 != v[0] || prev1 != v[1] || prev2 != v[2] || prev3 != v[3];
|
||||||
}
|
}
|
||||||
|
@ -3538,6 +3589,10 @@ int ui_float4(const char *label, float *v) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ui_float4(const char *label, float *v) {
|
||||||
|
return ui_float4_(label, v, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
int ui_mat33(const char *label, float M[9]) {
|
int ui_mat33(const char *label, float M[9]) {
|
||||||
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
if( label && ui_filter && ui_filter[0] ) if( !strstri(label, ui_filter) ) return 0;
|
||||||
|
|
||||||
|
@ -18282,7 +18337,11 @@ light_t light() {
|
||||||
l.cast_shadows = true;
|
l.cast_shadows = true;
|
||||||
l.processed_shadows = false;
|
l.processed_shadows = false;
|
||||||
l.shadow_distance = 200.0f;
|
l.shadow_distance = 200.0f;
|
||||||
l.shadow_bias = 0.01f;
|
l.shadow_near_clip = 0.01f;
|
||||||
|
l.shadow_bias = 0.005f;
|
||||||
|
l.normal_bias = 0.05f;
|
||||||
|
l.min_variance = 0.00002f;
|
||||||
|
l.variance_transition = 0.2f;
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18361,6 +18420,10 @@ void light_update(unsigned num_lights, light_t *lv) {
|
||||||
shader_float(va("u_lights[%d].quadratic", i), lv[i].falloff.quadratic);
|
shader_float(va("u_lights[%d].quadratic", i), lv[i].falloff.quadratic);
|
||||||
shader_float(va("u_lights[%d].innerCone", i), lv[i].innerCone);
|
shader_float(va("u_lights[%d].innerCone", i), lv[i].innerCone);
|
||||||
shader_float(va("u_lights[%d].outerCone", i), lv[i].outerCone);
|
shader_float(va("u_lights[%d].outerCone", i), lv[i].outerCone);
|
||||||
|
shader_float(va("u_lights[%d].shadow_bias", i), lv[i].shadow_bias);
|
||||||
|
shader_float(va("u_lights[%d].normal_bias", i), lv[i].normal_bias);
|
||||||
|
shader_float(va("u_lights[%d].min_variance", i), lv[i].min_variance);
|
||||||
|
shader_float(va("u_lights[%d].variance_transition", i), lv[i].variance_transition);
|
||||||
shader_bool(va("u_lights[%d].processed_shadows", i), lv[i].processed_shadows);
|
shader_bool(va("u_lights[%d].processed_shadows", i), lv[i].processed_shadows);
|
||||||
if (lv[i].processed_shadows) {
|
if (lv[i].processed_shadows) {
|
||||||
for (int j = 0; j < NUM_SHADOW_CASCADES; j++) {
|
for (int j = 0; j < NUM_SHADOW_CASCADES; j++) {
|
||||||
|
@ -18370,10 +18433,58 @@ void light_update(unsigned num_lights, light_t *lv) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ui_light(light_t *l) {
|
||||||
|
ui_int("Type", &l->type);
|
||||||
|
ui_vec3("Position", &l->pos);
|
||||||
|
ui_vec3("Direction", &l->dir);
|
||||||
|
ui_color3f("Diffuse", &l->diffuse.x);
|
||||||
|
ui_color3f("Specular", &l->specular.x);
|
||||||
|
ui_color3f("Ambient", &l->ambient.x);
|
||||||
|
ui_float("Specular Power", &l->specularPower);
|
||||||
|
ui_clampf("Radius", &l->radius, 0.0f, FLT_MAX);
|
||||||
|
ui_clampf_("Constant Falloff", &l->falloff.constant, 0.0, FLT_MAX, 0.005);
|
||||||
|
ui_clampf_("Linear Falloff", &l->falloff.linear, 0.0, FLT_MAX, 0.005);
|
||||||
|
ui_clampf_("Quadratic Falloff", &l->falloff.quadratic, 0.0, FLT_MAX, 0.005);
|
||||||
|
ui_float("Inner Cone", &l->innerCone);
|
||||||
|
ui_float("Outer Cone", &l->outerCone);
|
||||||
|
ui_float_("Shadow Bias", &l->shadow_bias, 0.00005);
|
||||||
|
ui_float_("Normal Bias", &l->normal_bias, 0.00005);
|
||||||
|
ui_float_("Min Variance", &l->min_variance, 0.00005);
|
||||||
|
ui_float_("Variance Transition", &l->variance_transition, 0.0005);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_lights(unsigned num_lights, light_t *lights) {
|
||||||
|
for (unsigned i = 0; i < num_lights; ++i) {
|
||||||
|
if (ui_collapse(va("Light %d", i), va("light_%d", i))) {
|
||||||
|
ui_light(&lights[i]);
|
||||||
|
ui_collapse_end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// shadowmaps
|
// shadowmaps
|
||||||
|
|
||||||
|
static inline
|
||||||
|
void shadowmap_init_common_resources(shadowmap_t *s, int vsm_texture_width, int csm_texture_width) {
|
||||||
|
// Create a cubemap depth texture
|
||||||
|
glGenTextures(1, &s->depth_texture);
|
||||||
|
glBindTexture(GL_TEXTURE_CUBE_MAP, s->depth_texture);
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT, vsm_texture_width, vsm_texture_width, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||||
|
|
||||||
|
// Create a 2D depth texture
|
||||||
|
glGenTextures(1, &s->depth_texture_2d);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, s->depth_texture_2d);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, csm_texture_width, csm_texture_width, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
shadowmap_init_caster_vsm(shadowmap_t *s, int light_index, int texture_width) {
|
shadowmap_init_caster_vsm(shadowmap_t *s, int light_index, int texture_width) {
|
||||||
float borderColor[] = {1.0, 1.0, 1.0, 1.0};
|
float borderColor[] = {1.0, 1.0, 1.0, 1.0};
|
||||||
|
@ -18397,19 +18508,6 @@ shadowmap_init_caster_vsm(shadowmap_t *s, int light_index, int texture_width) {
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||||
glTexParameterfv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BORDER_COLOR, borderColor);
|
glTexParameterfv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BORDER_COLOR, borderColor);
|
||||||
|
|
||||||
// Create a cubemap depth texture
|
|
||||||
glGenTextures(1, &s->maps[light_index].depth_texture);
|
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, s->maps[light_index].depth_texture);
|
|
||||||
for (int i = 0; i < 6; i++) {
|
|
||||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT, texture_width, texture_width, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
|
|
||||||
}
|
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER);
|
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
|
||||||
glTexParameterfv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BORDER_COLOR, borderColor);
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18431,15 +18529,6 @@ shadowmap_init_caster_csm(shadowmap_t *s, int light_index, int texture_width) {
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||||
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
|
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
|
||||||
|
|
||||||
glGenTextures(1, &s->maps[light_index].depth_texture_2d[i]);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, s->maps[light_index].depth_texture_2d[i]);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, texture_width, texture_width, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
|
|
||||||
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_BORDER);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
|
||||||
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
@ -18490,6 +18579,8 @@ shadowmap_t shadowmap(int vsm_texture_width, int csm_texture_width) { // = 512,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
shadowmap_init_common_resources(&s, vsm_texture_width, csm_texture_width);
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, s.saved_fb);
|
glBindFramebuffer(GL_FRAMEBUFFER, s.saved_fb);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
@ -18503,20 +18594,12 @@ void shadowmap_destroy_light(shadowmap_t *s, int light_index) {
|
||||||
glDeleteTextures(1, &s->maps[light_index].texture);
|
glDeleteTextures(1, &s->maps[light_index].texture);
|
||||||
s->maps[light_index].texture = 0;
|
s->maps[light_index].texture = 0;
|
||||||
}
|
}
|
||||||
if (s->maps[light_index].depth_texture) {
|
|
||||||
glDeleteTextures(1, &s->maps[light_index].depth_texture);
|
|
||||||
s->maps[light_index].depth_texture = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < NUM_SHADOW_CASCADES; i++) {
|
for (int i = 0; i < NUM_SHADOW_CASCADES; i++) {
|
||||||
if (s->maps[light_index].texture_2d[i]) {
|
if (s->maps[light_index].texture_2d[i]) {
|
||||||
glDeleteTextures(1, &s->maps[light_index].texture_2d[i]);
|
glDeleteTextures(1, &s->maps[light_index].texture_2d[i]);
|
||||||
s->maps[light_index].texture_2d[i] = 0;
|
s->maps[light_index].texture_2d[i] = 0;
|
||||||
}
|
}
|
||||||
if (s->maps[light_index].depth_texture_2d[i]) {
|
|
||||||
glDeleteTextures(1, &s->maps[light_index].depth_texture_2d[i]);
|
|
||||||
s->maps[light_index].depth_texture_2d[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->maps[light_index].blur_texture_2d) {
|
if (s->maps[light_index].blur_texture_2d) {
|
||||||
|
@ -18534,6 +18617,18 @@ void shadowmap_destroy(shadowmap_t *s) {
|
||||||
for (int i = 0; i < MAX_LIGHTS; i++) {
|
for (int i = 0; i < MAX_LIGHTS; i++) {
|
||||||
shadowmap_destroy_light(s, i);
|
shadowmap_destroy_light(s, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (s->depth_texture) {
|
||||||
|
glDeleteTextures(1, &s->depth_texture);
|
||||||
|
s->depth_texture = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s->depth_texture_2d) {
|
||||||
|
glDeleteTextures(1, &s->depth_texture_2d);
|
||||||
|
s->depth_texture_2d = 0;
|
||||||
|
}
|
||||||
|
|
||||||
shadowmap_t z = {0};
|
shadowmap_t z = {0};
|
||||||
*s = z;
|
*s = z;
|
||||||
}
|
}
|
||||||
|
@ -18561,7 +18656,7 @@ void shadowmap_begin(shadowmap_t *s) {
|
||||||
static void shadowmap_light_point(shadowmap_t *s, light_t *l, int dir) {
|
static void shadowmap_light_point(shadowmap_t *s, light_t *l, int dir) {
|
||||||
if(dir<0) return;
|
if(dir<0) return;
|
||||||
mat44 P, V, PV;
|
mat44 P, V, PV;
|
||||||
perspective44(P, 90.0f, 1.0f, l->shadow_bias, l->shadow_distance);
|
perspective44(P, 90.0f, 1.0f, l->shadow_near_clip, l->shadow_distance);
|
||||||
vec3 lightPos = l->pos;
|
vec3 lightPos = l->pos;
|
||||||
|
|
||||||
/**/ if(dir == 0) lookat44(V, lightPos, add3(lightPos, vec3(+1, 0, 0)), vec3(0, -1, 0)); // +X
|
/**/ if(dir == 0) lookat44(V, lightPos, add3(lightPos, vec3(+1, 0, 0)), vec3(0, -1, 0)); // +X
|
||||||
|
@ -18614,7 +18709,7 @@ static void shadowmap_light_directional(shadowmap_t *s, light_t *l, int dir, flo
|
||||||
float near_plane = 0.0f;
|
float near_plane = 0.0f;
|
||||||
|
|
||||||
if (s->cascade_index == 0) {
|
if (s->cascade_index == 0) {
|
||||||
near_plane = l->shadow_bias;
|
near_plane = l->shadow_near_clip;
|
||||||
far_plane = l->shadow_distance * s->cascade_splits[0];
|
far_plane = l->shadow_distance * s->cascade_splits[0];
|
||||||
} else if (s->cascade_index < NUM_SHADOW_CASCADES - 1) {
|
} else if (s->cascade_index < NUM_SHADOW_CASCADES - 1) {
|
||||||
near_plane = l->shadow_distance * s->cascade_splits[s->cascade_index-1];
|
near_plane = l->shadow_distance * s->cascade_splits[s->cascade_index-1];
|
||||||
|
@ -18929,12 +19024,12 @@ void shadowmap_light(shadowmap_t *s, light_t *l, mat44 cam_proj, mat44 cam_view)
|
||||||
if (l->type == LIGHT_DIRECTIONAL) {
|
if (l->type == LIGHT_DIRECTIONAL) {
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, s->fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, s->fbo);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, s->maps[s->light_step].texture_2d[s->cascade_index], 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, s->maps[s->light_step].texture_2d[s->cascade_index], 0);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, s->maps[s->light_step].depth_texture_2d[s->cascade_index], 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, s->depth_texture_2d, 0);
|
||||||
shadowmap_clear_fbo();
|
shadowmap_clear_fbo();
|
||||||
} else {
|
} else {
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, s->fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, s->fbo);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + step, s->maps[s->light_step].texture, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + step, s->maps[s->light_step].texture, 0);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + step, s->maps[s->light_step].depth_texture, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + step, s->depth_texture, 0);
|
||||||
shadowmap_clear_fbo();
|
shadowmap_clear_fbo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18956,19 +19051,25 @@ void shadowmap_end(shadowmap_t *s) {
|
||||||
{
|
{
|
||||||
const int faces = 6;
|
const int faces = 6;
|
||||||
const int cascades = NUM_SHADOW_CASCADES;
|
const int cascades = NUM_SHADOW_CASCADES;
|
||||||
|
|
||||||
|
// Depth textures
|
||||||
|
s->vram_usage += s->vsm_texture_width * s->vsm_texture_width * faces * 1;
|
||||||
|
s->vram_usage += s->csm_texture_width * s->csm_texture_width * 1;
|
||||||
|
s->vram_usage_total += s->vsm_texture_width * s->vsm_texture_width * faces * 1;
|
||||||
|
s->vram_usage_vsm += s->vsm_texture_width * s->vsm_texture_width * faces * 8;
|
||||||
|
s->vram_usage_total += s->vsm_texture_width * s->vsm_texture_width * faces * 8;
|
||||||
|
s->vram_usage_csm += s->csm_texture_width * s->csm_texture_width * 1;
|
||||||
|
|
||||||
for (int i = 0; i < MAX_LIGHTS; i++) {
|
for (int i = 0; i < MAX_LIGHTS; i++) {
|
||||||
// VSM textures
|
// VSM textures
|
||||||
if (s->maps[i].texture != 0) {
|
if (s->maps[i].texture != 0) {
|
||||||
// Color texture (GL_RG32F)
|
// Color texture (GL_RG32F)
|
||||||
s->vram_usage += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // 8 bytes per pixel (2 * 32-bit float)
|
s->vram_usage += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // 8 bytes per pixel (2 * 32-bit float)
|
||||||
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
|
|
||||||
s->vram_usage += s->vsm_texture_width * s->vsm_texture_width * faces * 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Color texture (GL_RG32F)
|
// Color texture (GL_RG32F)
|
||||||
s->vram_usage_total += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // 8 bytes per pixel (2 * 32-bit float)
|
s->vram_usage_total += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // 8 bytes per pixel (2 * 32-bit float)
|
||||||
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
|
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
|
||||||
s->vram_usage_total += s->vsm_texture_width * s->vsm_texture_width * faces * 1;
|
|
||||||
|
|
||||||
// Color texture (GL_RG32F)
|
// Color texture (GL_RG32F)
|
||||||
s->vram_usage_vsm += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // 8 bytes per pixel (2 * 32-bit float)
|
s->vram_usage_vsm += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // 8 bytes per pixel (2 * 32-bit float)
|
||||||
|
@ -18981,20 +19082,13 @@ void shadowmap_end(shadowmap_t *s) {
|
||||||
for (int j = 0; j < cascades; j++) {
|
for (int j = 0; j < cascades; j++) {
|
||||||
// Color texture (GL_R32F)
|
// Color texture (GL_R32F)
|
||||||
s->vram_usage += s->csm_texture_width * s->csm_texture_width * 4; // 4 bytes per pixel (1 * 32-bit float)
|
s->vram_usage += s->csm_texture_width * s->csm_texture_width * 4; // 4 bytes per pixel (1 * 32-bit float)
|
||||||
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
|
|
||||||
s->vram_usage += s->csm_texture_width * s->csm_texture_width * 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < cascades; j++) {
|
for (int j = 0; j < cascades; j++) {
|
||||||
// Color texture (GL_R32F)
|
// Color texture (GL_R32F)
|
||||||
s->vram_usage_total += s->csm_texture_width * s->csm_texture_width * 4; // 4 bytes per pixel (1 * 32-bit float)
|
s->vram_usage_total += s->csm_texture_width * s->csm_texture_width * 4; // 4 bytes per pixel (1 * 32-bit float)
|
||||||
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
|
|
||||||
s->vram_usage_total += s->csm_texture_width * s->csm_texture_width * 1;
|
|
||||||
|
|
||||||
s->vram_usage_csm += s->csm_texture_width * s->csm_texture_width * 4; // 4 bytes per pixel (1 * 32-bit float)
|
s->vram_usage_csm += s->csm_texture_width * s->csm_texture_width * 4; // 4 bytes per pixel (1 * 32-bit float)
|
||||||
// Depth texture (GL_DEPTH_COMPONENT, assuming 8-bit depth)
|
|
||||||
s->vram_usage_csm += s->csm_texture_width * s->csm_texture_width * 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// VSM blur texture (if used)
|
// VSM blur texture (if used)
|
||||||
|
@ -19002,8 +19096,6 @@ void shadowmap_end(shadowmap_t *s) {
|
||||||
s->vram_usage += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // Assuming same format as VSM color texture
|
s->vram_usage += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // Assuming same format as VSM color texture
|
||||||
}
|
}
|
||||||
|
|
||||||
s->vram_usage_total += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // Assuming same format as VSM color texture
|
|
||||||
s->vram_usage_vsm += s->vsm_texture_width * s->vsm_texture_width * faces * 8; // Assuming same format as VSM color texture
|
|
||||||
|
|
||||||
// CSM blur texture (if used)
|
// CSM blur texture (if used)
|
||||||
if (s->maps[i].blur_texture_2d != 0) {
|
if (s->maps[i].blur_texture_2d != 0) {
|
||||||
|
|
27
engine/v4k.h
27
engine/v4k.h
|
@ -3337,7 +3337,7 @@ enum SHADOW_TECHNIQUE {
|
||||||
#define NUM_SHADOW_CASCADES 4
|
#define NUM_SHADOW_CASCADES 4
|
||||||
|
|
||||||
typedef struct light_t {
|
typedef struct light_t {
|
||||||
char type;
|
unsigned type;
|
||||||
vec3 diffuse, specular, ambient;
|
vec3 diffuse, specular, ambient;
|
||||||
vec3 pos, dir;
|
vec3 pos, dir;
|
||||||
struct {
|
struct {
|
||||||
|
@ -3350,14 +3350,18 @@ typedef struct light_t {
|
||||||
|
|
||||||
// Shadowmapping
|
// Shadowmapping
|
||||||
bool cast_shadows;
|
bool cast_shadows;
|
||||||
bool processed_shadows;
|
|
||||||
unsigned shadow_technique;
|
unsigned shadow_technique;
|
||||||
float shadow_distance;
|
float shadow_distance;
|
||||||
float shadow_bias;
|
float shadow_near_clip;
|
||||||
mat44 shadow_matrix[NUM_SHADOW_CASCADES];
|
mat44 shadow_matrix[NUM_SHADOW_CASCADES];
|
||||||
|
float min_variance; //< VSM
|
||||||
|
float variance_transition; //< VSM
|
||||||
|
float shadow_bias; //< CSM
|
||||||
|
float normal_bias; //< CSM
|
||||||
|
|
||||||
// internals
|
// internals
|
||||||
bool cached; //< used by scene to invalidate cached light data
|
bool cached; //< used by scene to invalidate cached light data
|
||||||
|
bool processed_shadows;
|
||||||
} light_t;
|
} light_t;
|
||||||
|
|
||||||
API light_t light();
|
API light_t light();
|
||||||
|
@ -3374,6 +3378,10 @@ API void light_falloff(light_t* l, float constant, float linear, float quadra
|
||||||
API void light_cone(light_t* l, float innerCone, float outerCone);
|
API void light_cone(light_t* l, float innerCone, float outerCone);
|
||||||
API void light_update(unsigned num_lights, light_t *lv);
|
API void light_update(unsigned num_lights, light_t *lv);
|
||||||
|
|
||||||
|
API void ui_light(light_t *l);
|
||||||
|
API void ui_lights(unsigned num_lights, light_t *lights);
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// shadowmaps
|
// shadowmaps
|
||||||
|
|
||||||
|
@ -3403,11 +3411,15 @@ typedef struct shadowmap_t {
|
||||||
uint64_t vram_usage_vsm;
|
uint64_t vram_usage_vsm;
|
||||||
uint64_t vram_usage_csm;
|
uint64_t vram_usage_csm;
|
||||||
|
|
||||||
|
// depth texture
|
||||||
|
handle depth_texture;
|
||||||
|
handle depth_texture_2d;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
int gen;
|
int gen;
|
||||||
unsigned shadow_technique;
|
unsigned shadow_technique;
|
||||||
handle texture, depth_texture;
|
handle texture;
|
||||||
handle texture_2d[NUM_SHADOW_CASCADES], depth_texture_2d[NUM_SHADOW_CASCADES];
|
handle texture_2d[NUM_SHADOW_CASCADES];
|
||||||
handle blur_texture, blur_texture_2d;
|
handle blur_texture, blur_texture_2d;
|
||||||
// handle blur_fbo_cubemap, blur_texture_cubemap;
|
// handle blur_fbo_cubemap, blur_texture_cubemap;
|
||||||
float cascade_distances[NUM_SHADOW_CASCADES];
|
float cascade_distances[NUM_SHADOW_CASCADES];
|
||||||
|
@ -4766,6 +4778,10 @@ API int ui_section(const char *title);
|
||||||
API int ui_int(const char *label, int *value);
|
API int ui_int(const char *label, int *value);
|
||||||
API int ui_bool(const char *label, bool *value);
|
API int ui_bool(const char *label, bool *value);
|
||||||
API int ui_short(const char *label, short *value);
|
API int ui_short(const char *label, short *value);
|
||||||
|
API int ui_float_(const char *label, float *value, float step);
|
||||||
|
API int ui_float2_(const char *label, float value[2], float step);
|
||||||
|
API int ui_float3_(const char *label, float value[3], float step);
|
||||||
|
API int ui_float4_(const char *label, float value[4], float step);
|
||||||
API int ui_float(const char *label, float *value);
|
API int ui_float(const char *label, float *value);
|
||||||
API int ui_float2(const char *label, float value[2]);
|
API int ui_float2(const char *label, float value[2]);
|
||||||
API int ui_float3(const char *label, float value[3]);
|
API int ui_float3(const char *label, float value[3]);
|
||||||
|
@ -4802,6 +4818,7 @@ API int ui_separator();
|
||||||
API int ui_bitmask8(const char *label, uint8_t *bits);
|
API int ui_bitmask8(const char *label, uint8_t *bits);
|
||||||
API int ui_bitmask16(const char *label, uint16_t *bits);
|
API int ui_bitmask16(const char *label, uint16_t *bits);
|
||||||
API int ui_console();
|
API int ui_console();
|
||||||
|
API int ui_clampf_(const char *label, float *value, float minf, float maxf, float step);
|
||||||
API int ui_clampf(const char *label, float *value, float minf, float maxf);
|
API int ui_clampf(const char *label, float *value, float minf, float maxf);
|
||||||
API int ui_label(const char *label);
|
API int ui_label(const char *label);
|
||||||
API int ui_label2(const char *label, const char *caption);
|
API int ui_label2(const char *label, const char *caption);
|
||||||
|
|
Loading…
Reference in New Issue