day-night loop, dynamic skybox, clock on debug panel
This commit is contained in:
parent
4a9a4ddd14
commit
c08c31b0ad
11
res/shaders/background.glslf
Normal file
11
res/shaders/background.glslf
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#version 330 core
|
||||||
|
|
||||||
|
in vec3 v_coord;
|
||||||
|
out vec4 f_color;
|
||||||
|
|
||||||
|
uniform samplerCube u_cubemap;
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
vec3 dir = normalize(v_coord);
|
||||||
|
f_color = texture(u_cubemap, dir);
|
||||||
|
}
|
||||||
14
res/shaders/background.glslv
Normal file
14
res/shaders/background.glslv
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#version 330 core
|
||||||
|
|
||||||
|
layout (location = 0) in vec2 v_position;
|
||||||
|
|
||||||
|
out vec3 v_coord;
|
||||||
|
|
||||||
|
uniform mat4 u_view;
|
||||||
|
uniform float u_ar;
|
||||||
|
uniform float u_zoom;
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
v_coord = (vec4(v_position*vec2(u_ar, 1.0f)*u_zoom, -1.0, 1.0) * u_view).xyz;
|
||||||
|
gl_Position = vec4(v_position, 0.0, 1.0);
|
||||||
|
}
|
||||||
@ -3,20 +3,23 @@
|
|||||||
in vec4 a_color;
|
in vec4 a_color;
|
||||||
in vec2 a_texCoord;
|
in vec2 a_texCoord;
|
||||||
in float a_distance;
|
in float a_distance;
|
||||||
|
in vec3 a_dir;
|
||||||
out vec4 f_color;
|
out vec4 f_color;
|
||||||
|
|
||||||
uniform sampler2D u_texture0;
|
uniform sampler2D u_texture0;
|
||||||
|
uniform samplerCube u_cubemap;
|
||||||
uniform vec3 u_fogColor;
|
uniform vec3 u_fogColor;
|
||||||
uniform float u_fogFactor;
|
uniform float u_fogFactor;
|
||||||
uniform float u_fogCurve;
|
uniform float u_fogCurve;
|
||||||
|
|
||||||
void main(){
|
void main(){
|
||||||
|
vec3 fogColor = texture(u_cubemap, a_dir).rgb;
|
||||||
vec4 tex_color = texture(u_texture0, a_texCoord);
|
vec4 tex_color = texture(u_texture0, a_texCoord);
|
||||||
float depth = (a_distance/256.0);
|
float depth = (a_distance/256.0);
|
||||||
float alpha = a_color.a * tex_color.a;
|
float alpha = a_color.a * tex_color.a;
|
||||||
// anyway it's any alpha-test alternative required
|
// anyway it's any alpha-test alternative required
|
||||||
if (alpha < 0.1f)
|
if (alpha < 0.1f)
|
||||||
discard;
|
discard;
|
||||||
f_color = mix(a_color * tex_color, vec4(u_fogColor,1.0), min(1.0, pow(depth*u_fogFactor, u_fogCurve)));
|
f_color = mix(a_color * tex_color, vec4(fogColor,1.0), min(1.0, pow(depth*u_fogFactor, u_fogCurve)));
|
||||||
f_color.a = alpha;
|
f_color.a = alpha;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,7 @@ layout (location = 2) in float v_light;
|
|||||||
out vec4 a_color;
|
out vec4 a_color;
|
||||||
out vec2 a_texCoord;
|
out vec2 a_texCoord;
|
||||||
out float a_distance;
|
out float a_distance;
|
||||||
|
out vec3 a_dir;
|
||||||
|
|
||||||
uniform mat4 u_model;
|
uniform mat4 u_model;
|
||||||
uniform mat4 u_proj;
|
uniform mat4 u_proj;
|
||||||
@ -14,10 +15,13 @@ uniform mat4 u_view;
|
|||||||
uniform vec3 u_skyLightColor;
|
uniform vec3 u_skyLightColor;
|
||||||
uniform vec3 u_cameraPos;
|
uniform vec3 u_cameraPos;
|
||||||
uniform float u_gamma;
|
uniform float u_gamma;
|
||||||
|
uniform samplerCube u_cubemap;
|
||||||
|
|
||||||
uniform vec3 u_torchlightColor;
|
uniform vec3 u_torchlightColor;
|
||||||
uniform float u_torchlightDistance;
|
uniform float u_torchlightDistance;
|
||||||
|
|
||||||
|
#define SKY_LIGHT_MUL 2.5
|
||||||
|
|
||||||
vec4 decompress_light(float compressed_light) {
|
vec4 decompress_light(float compressed_light) {
|
||||||
vec4 result;
|
vec4 result;
|
||||||
int compressed = floatBitsToInt(compressed_light);
|
int compressed = floatBitsToInt(compressed_light);
|
||||||
@ -30,15 +34,22 @@ vec4 decompress_light(float compressed_light) {
|
|||||||
|
|
||||||
void main(){
|
void main(){
|
||||||
vec2 pos2d = (u_model * vec4(v_position, 1.0)).xz-u_cameraPos.xz;
|
vec2 pos2d = (u_model * vec4(v_position, 1.0)).xz-u_cameraPos.xz;
|
||||||
vec4 modelpos = u_model * vec4(v_position+vec3(0,pow(length(pos2d)*0.0, 3.0),0), 1.0);
|
vec4 modelpos = u_model * vec4(v_position, 1.0);
|
||||||
vec4 viewmodelpos = u_view * modelpos;
|
vec4 viewmodelpos = u_view * modelpos;
|
||||||
vec4 decomp_light = decompress_light(v_light);
|
vec4 decomp_light = decompress_light(v_light);
|
||||||
vec3 light = decomp_light.rgb;
|
vec3 light = decomp_light.rgb;
|
||||||
float torchlight = max(0.0, 1.0-distance(u_cameraPos, modelpos.xyz)/u_torchlightDistance);
|
float torchlight = max(0.0, 1.0-distance(u_cameraPos, modelpos.xyz)/u_torchlightDistance);
|
||||||
|
a_dir = modelpos.xyz - u_cameraPos;
|
||||||
light += torchlight * u_torchlightColor;
|
light += torchlight * u_torchlightColor;
|
||||||
a_color = vec4(pow(light, vec3(u_gamma)),1.0f);
|
a_color = vec4(pow(light, vec3(u_gamma)),1.0f);
|
||||||
a_texCoord = v_texCoord;
|
a_texCoord = v_texCoord;
|
||||||
a_color.rgb = max(a_color.rgb, u_skyLightColor.rgb*decomp_light.a);
|
|
||||||
|
vec3 skyLightColor = texture(u_cubemap, vec3(-0.4f, -0.4f, -0.4f)).rgb;
|
||||||
|
skyLightColor.g *= 0.9;
|
||||||
|
skyLightColor.b *= 0.8;
|
||||||
|
skyLightColor = min(vec3(1.0), skyLightColor*SKY_LIGHT_MUL);
|
||||||
|
|
||||||
|
a_color.rgb = max(a_color.rgb, skyLightColor.rgb*decomp_light.a);
|
||||||
a_distance = length(viewmodelpos);
|
a_distance = length(viewmodelpos);
|
||||||
gl_Position = u_proj * viewmodelpos;
|
gl_Position = u_proj * viewmodelpos;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +0,0 @@
|
|||||||
#version 330 core
|
|
||||||
|
|
||||||
in vec2 v_coord;
|
|
||||||
out vec4 f_color;
|
|
||||||
|
|
||||||
uniform sampler2D u_texture;
|
|
||||||
|
|
||||||
void main(){
|
|
||||||
f_color = texture(u_texture, v_coord);
|
|
||||||
}
|
|
||||||
291
res/shaders/skybox_gen.glslf
Normal file
291
res/shaders/skybox_gen.glslf
Normal file
@ -0,0 +1,291 @@
|
|||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2019 Dimas Leenman
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
// first, lets define some constants to use (planet radius, position, and scattering coefficients)
|
||||||
|
#define PLANET_POS vec3(0.0) /* the position of the planet */
|
||||||
|
#define PLANET_RADIUS 6371e3 /* radius of the planet */
|
||||||
|
#define ATMOS_RADIUS 6471e3 /* radius of the atmosphere */
|
||||||
|
// scattering coeffs
|
||||||
|
#define RAY_BETA vec3(5.5e-6, 13.0e-6, 22.4e-6) /* rayleigh, affects the color of the sky */
|
||||||
|
#define MIE_BETA vec3(21e-6) /* mie, affects the color of the blob around the sun */
|
||||||
|
#define AMBIENT_BETA vec3(0.0) /* ambient, affects the scattering color when there is no lighting from the sun */
|
||||||
|
#define ABSORPTION_BETA vec3(2.04e-5, 4.97e-5, 1.95e-6) /* what color gets absorbed by the atmosphere (Due to things like ozone) */
|
||||||
|
#define G 0.9 /* mie scattering direction, or how big the blob around the sun is */
|
||||||
|
// and the heights (how far to go up before the scattering has no effect)
|
||||||
|
#define HEIGHT_RAY 8e3 /* rayleigh height */
|
||||||
|
#define HEIGHT_MIE 1.2e3 /* and mie */
|
||||||
|
#define HEIGHT_ABSORPTION 30e3 /* at what height the absorption is at it's maximum */
|
||||||
|
#define ABSORPTION_FALLOFF 4e3 /* how much the absorption decreases the further away it gets from the maximum height */
|
||||||
|
// and the steps (more looks better, but is slower)
|
||||||
|
// the primary step has the most effect on looks
|
||||||
|
#define PRIMARY_STEPS 12
|
||||||
|
#define LIGHT_STEPS 4
|
||||||
|
|
||||||
|
vec3 calculate_scattering(
|
||||||
|
vec3 start, // the start of the ray (the camera position)
|
||||||
|
vec3 dir, // the direction of the ray (the camera vector)
|
||||||
|
float max_dist, // the maximum distance the ray can travel (because something is in the way, like an object)
|
||||||
|
vec3 scene_color, // the color of the scene
|
||||||
|
vec3 light_dir, // the direction of the light
|
||||||
|
vec3 light_intensity, // how bright the light is, affects the brightness of the atmosphere
|
||||||
|
vec3 planet_position, // the position of the planet
|
||||||
|
float planet_radius, // the radius of the planet
|
||||||
|
float atmo_radius, // the radius of the atmosphere
|
||||||
|
vec3 beta_ray, // the amount rayleigh scattering scatters the colors (for earth: causes the blue atmosphere)
|
||||||
|
vec3 beta_mie, // the amount mie scattering scatters colors
|
||||||
|
vec3 beta_absorption, // how much air is absorbed
|
||||||
|
vec3 beta_ambient, // the amount of scattering that always occurs, cna help make the back side of the atmosphere a bit brighter
|
||||||
|
float g, // the direction mie scatters the light in (like a cone). closer to -1 means more towards a single direction
|
||||||
|
float height_ray, // how high do you have to go before there is no rayleigh scattering?
|
||||||
|
float height_mie, // the same, but for mie
|
||||||
|
float height_absorption, // the height at which the most absorption happens
|
||||||
|
float absorption_falloff, // how fast the absorption falls off from the absorption height
|
||||||
|
int steps_i, // the amount of steps along the 'primary' ray, more looks better but slower
|
||||||
|
int steps_l // the amount of steps along the light ray, more looks better but slower
|
||||||
|
) {
|
||||||
|
// add an offset to the camera position, so that the atmosphere is in the correct position
|
||||||
|
start -= planet_position;
|
||||||
|
// calculate the start and end position of the ray, as a distance along the ray
|
||||||
|
// we do this with a ray sphere intersect
|
||||||
|
float a = dot(dir, dir);
|
||||||
|
float b = 2.0 * dot(dir, start);
|
||||||
|
float c = dot(start, start) - (atmo_radius * atmo_radius);
|
||||||
|
float d = (b * b) - 4.0 * a * c;
|
||||||
|
|
||||||
|
// stop early if there is no intersect
|
||||||
|
if (d < 0.0) return scene_color;
|
||||||
|
|
||||||
|
// calculate the ray length
|
||||||
|
vec2 ray_length = vec2(
|
||||||
|
max((-b - sqrt(d)) / (2.0 * a), 0.0),
|
||||||
|
min((-b + sqrt(d)) / (2.0 * a), max_dist)
|
||||||
|
);
|
||||||
|
|
||||||
|
// if the ray did not hit the atmosphere, return a black color
|
||||||
|
if (ray_length.x > ray_length.y) return scene_color;
|
||||||
|
// prevent the mie glow from appearing if there's an object in front of the camera
|
||||||
|
bool allow_mie = max_dist > ray_length.y;
|
||||||
|
// make sure the ray is no longer than allowed
|
||||||
|
ray_length.y = min(ray_length.y, max_dist);
|
||||||
|
ray_length.x = max(ray_length.x, 0.0);
|
||||||
|
// get the step size of the ray
|
||||||
|
float step_size_i = (ray_length.y - ray_length.x) / float(steps_i);
|
||||||
|
|
||||||
|
// next, set how far we are along the ray, so we can calculate the position of the sample
|
||||||
|
// if the camera is outside the atmosphere, the ray should start at the edge of the atmosphere
|
||||||
|
// if it's inside, it should start at the position of the camera
|
||||||
|
// the min statement makes sure of that
|
||||||
|
float ray_pos_i = ray_length.x + step_size_i * 0.5;
|
||||||
|
|
||||||
|
// these are the values we use to gather all the scattered light
|
||||||
|
vec3 total_ray = vec3(0.0); // for rayleigh
|
||||||
|
vec3 total_mie = vec3(0.0); // for mie
|
||||||
|
|
||||||
|
// initialize the optical depth. This is used to calculate how much air was in the ray
|
||||||
|
vec3 opt_i = vec3(0.0);
|
||||||
|
|
||||||
|
// also init the scale height, avoids some vec2's later on
|
||||||
|
vec2 scale_height = vec2(height_ray, height_mie);
|
||||||
|
|
||||||
|
// Calculate the Rayleigh and Mie phases.
|
||||||
|
// This is the color that will be scattered for this ray
|
||||||
|
// mu, mumu and gg are used quite a lot in the calculation, so to speed it up, precalculate them
|
||||||
|
float mu = dot(dir, light_dir);
|
||||||
|
float mumu = mu * mu;
|
||||||
|
float gg = g * g;
|
||||||
|
float phase_ray = 3.0 / (50.2654824574 /* (16 * pi) */) * (1.0 + mumu);
|
||||||
|
float phase_mie = allow_mie ? 3.0 / (25.1327412287 /* (8 * pi) */) * ((1.0 - gg) * (mumu + 1.0)) / (pow(1.0 + gg - 2.0 * mu * g, 1.5) * (2.0 + gg)) : 0.0;
|
||||||
|
|
||||||
|
// now we need to sample the 'primary' ray. this ray gathers the light that gets scattered onto it
|
||||||
|
for (int i = 0; i < steps_i; ++i) {
|
||||||
|
|
||||||
|
// calculate where we are along this ray
|
||||||
|
vec3 pos_i = start + dir * ray_pos_i;
|
||||||
|
|
||||||
|
// and how high we are above the surface
|
||||||
|
float height_i = length(pos_i) - planet_radius;
|
||||||
|
|
||||||
|
// now calculate the density of the particles (both for rayleigh and mie)
|
||||||
|
vec3 density = vec3(exp(-height_i / scale_height), 0.0);
|
||||||
|
|
||||||
|
// and the absorption density. this is for ozone, which scales together with the rayleigh,
|
||||||
|
// but absorbs the most at a specific height, so use the sech function for a nice curve falloff for this height
|
||||||
|
// clamp it to avoid it going out of bounds. This prevents weird black spheres on the night side
|
||||||
|
float denom = (height_absorption - height_i) / absorption_falloff;
|
||||||
|
density.z = (1.0 / (denom * denom + 1.0)) * density.x;
|
||||||
|
|
||||||
|
// multiply it by the step size here
|
||||||
|
// we are going to use the density later on as well
|
||||||
|
density *= step_size_i;
|
||||||
|
|
||||||
|
// Add these densities to the optical depth, so that we know how many particles are on this ray.
|
||||||
|
opt_i += density;
|
||||||
|
|
||||||
|
// Calculate the step size of the light ray.
|
||||||
|
// again with a ray sphere intersect
|
||||||
|
// a, b, c and d are already defined
|
||||||
|
a = dot(light_dir, light_dir);
|
||||||
|
b = 2.0 * dot(light_dir, pos_i);
|
||||||
|
c = dot(pos_i, pos_i) - (atmo_radius * atmo_radius);
|
||||||
|
d = (b * b) - 4.0 * a * c;
|
||||||
|
|
||||||
|
// no early stopping, this one should always be inside the atmosphere
|
||||||
|
// calculate the ray length
|
||||||
|
float step_size_l = (-b + sqrt(d)) / (2.0 * a * float(steps_l));
|
||||||
|
|
||||||
|
// and the position along this ray
|
||||||
|
// this time we are sure the ray is in the atmosphere, so set it to 0
|
||||||
|
float ray_pos_l = step_size_l * 0.5;
|
||||||
|
|
||||||
|
// and the optical depth of this ray
|
||||||
|
vec3 opt_l = vec3(0.0);
|
||||||
|
|
||||||
|
// now sample the light ray
|
||||||
|
// this is similar to what we did before
|
||||||
|
for (int l = 0; l < steps_l; ++l) {
|
||||||
|
|
||||||
|
// calculate where we are along this ray
|
||||||
|
vec3 pos_l = pos_i + light_dir * ray_pos_l;
|
||||||
|
|
||||||
|
// the heigth of the position
|
||||||
|
float height_l = length(pos_l) - planet_radius;
|
||||||
|
|
||||||
|
// calculate the particle density, and add it
|
||||||
|
// this is a bit verbose
|
||||||
|
// first, set the density for ray and mie
|
||||||
|
vec3 density_l = vec3(exp(-height_l / scale_height), 0.0);
|
||||||
|
|
||||||
|
// then, the absorption
|
||||||
|
float denom = (height_absorption - height_l) / absorption_falloff;
|
||||||
|
density_l.z = (1.0 / (denom * denom + 1.0)) * density_l.x;
|
||||||
|
|
||||||
|
// multiply the density by the step size
|
||||||
|
density_l *= step_size_l;
|
||||||
|
|
||||||
|
// and add it to the total optical depth
|
||||||
|
opt_l += density_l;
|
||||||
|
|
||||||
|
// and increment where we are along the light ray.
|
||||||
|
ray_pos_l += step_size_l;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now we need to calculate the attenuation
|
||||||
|
// this is essentially how much light reaches the current sample point due to scattering
|
||||||
|
vec3 attn = exp(-beta_ray * (opt_i.x + opt_l.x) - beta_mie * (opt_i.y + opt_l.y) - beta_absorption * (opt_i.z + opt_l.z));
|
||||||
|
|
||||||
|
// accumulate the scattered light (how much will be scattered towards the camera)
|
||||||
|
total_ray += density.x * attn;
|
||||||
|
total_mie += density.y * attn;
|
||||||
|
|
||||||
|
// and increment the position on this ray
|
||||||
|
ray_pos_i += step_size_i;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate how much light can pass through the atmosphere
|
||||||
|
vec3 opacity = exp(-(beta_mie * opt_i.y + beta_ray * opt_i.x + beta_absorption * opt_i.z));
|
||||||
|
|
||||||
|
// calculate and return the final color
|
||||||
|
return (
|
||||||
|
phase_ray * beta_ray * total_ray // rayleigh color
|
||||||
|
+ phase_mie * beta_mie * total_mie // mie
|
||||||
|
+ opt_i.x * beta_ambient // and ambient
|
||||||
|
) * light_intensity + scene_color * opacity; // now make sure the background is rendered correctly
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 ray_sphere_intersect(
|
||||||
|
vec3 start, // starting position of the ray
|
||||||
|
vec3 dir, // the direction of the ray
|
||||||
|
float radius // and the sphere radius
|
||||||
|
) {
|
||||||
|
// ray-sphere intersection that assumes
|
||||||
|
// the sphere is centered at the origin.
|
||||||
|
// No intersection when result.x > result.y
|
||||||
|
float a = dot(dir, dir);
|
||||||
|
float b = 2.0 * dot(dir, start);
|
||||||
|
float c = dot(start, start) - (radius * radius);
|
||||||
|
float d = (b*b) - 4.0*a*c;
|
||||||
|
if (d < 0.0) return vec2(1e5,-1e5);
|
||||||
|
return vec2(
|
||||||
|
(-b - sqrt(d))/(2.0*a),
|
||||||
|
(-b + sqrt(d))/(2.0*a)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
in vec2 v_coord;
|
||||||
|
out vec4 f_color;
|
||||||
|
|
||||||
|
uniform vec3 u_xaxis;
|
||||||
|
uniform vec3 u_yaxis;
|
||||||
|
uniform vec3 u_zaxis;
|
||||||
|
uniform vec3 u_lightDir;
|
||||||
|
uniform int u_quality;
|
||||||
|
uniform float u_mie;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec3 camera_position = vec3(0.0f, PLANET_RADIUS+1.0f, 0.0f);
|
||||||
|
vec3 camera_vector = normalize(u_xaxis * v_coord.x +
|
||||||
|
u_yaxis * -v_coord.y -
|
||||||
|
u_zaxis);
|
||||||
|
// hide darkness at horizon
|
||||||
|
camera_vector.y = max(0.01, camera_vector.y)*(1.0-u_mie*0.08) + 0.08*u_mie;
|
||||||
|
camera_vector = normalize(camera_vector);
|
||||||
|
|
||||||
|
// the color of this pixel
|
||||||
|
vec3 col = vec3(0.0);//scene.xyz;
|
||||||
|
|
||||||
|
// get the atmosphere color
|
||||||
|
col += calculate_scattering(
|
||||||
|
camera_position, // the position of the camera
|
||||||
|
camera_vector, // the camera vector (ray direction of this pixel)
|
||||||
|
1e12f, // max dist, essentially the scene depth
|
||||||
|
vec3(0.0f), // scene color, the color of the current pixel being rendered
|
||||||
|
u_lightDir, // light direction
|
||||||
|
vec3(40.0), // light intensity, 40 looks nice
|
||||||
|
PLANET_POS, // position of the planet
|
||||||
|
PLANET_RADIUS, // radius of the planet in meters
|
||||||
|
ATMOS_RADIUS, // radius of the atmosphere in meters
|
||||||
|
RAY_BETA, // Rayleigh scattering coefficient
|
||||||
|
MIE_BETA, // Mie scattering coefficient
|
||||||
|
ABSORPTION_BETA, // Absorbtion coefficient
|
||||||
|
AMBIENT_BETA, // ambient scattering, turned off for now. This causes the air to glow a bit when no light reaches it
|
||||||
|
G, // Mie preferred scattering direction
|
||||||
|
HEIGHT_RAY, // Rayleigh scale height
|
||||||
|
HEIGHT_MIE*u_mie*u_mie, // Mie scale height
|
||||||
|
HEIGHT_ABSORPTION, // the height at which the most absorption happens
|
||||||
|
ABSORPTION_FALLOFF, // how fast the absorption falls off from the absorption height
|
||||||
|
PRIMARY_STEPS*u_quality, // steps in the ray direction
|
||||||
|
LIGHT_STEPS*u_quality // steps in the light direction
|
||||||
|
);
|
||||||
|
|
||||||
|
// apply exposure, removing this makes the brighter colors look ugly
|
||||||
|
// you can play around with removing this
|
||||||
|
col = 1.0 - exp(-col);
|
||||||
|
|
||||||
|
// Output to screen
|
||||||
|
f_color = vec4(col, 1.0);
|
||||||
|
}
|
||||||
@ -5,6 +5,6 @@ layout (location = 0) in vec2 v_position;
|
|||||||
out vec2 v_coord;
|
out vec2 v_coord;
|
||||||
|
|
||||||
void main(){
|
void main(){
|
||||||
v_coord = v_position*0.5+0.5;
|
v_coord = v_position;
|
||||||
gl_Position = vec4(v_position, 0.0, 1.0);
|
gl_Position = vec4(v_position, 0.0, 1.0);
|
||||||
}
|
}
|
||||||
@ -110,6 +110,8 @@ void AssetsLoader::addDefaults(AssetsLoader& loader) {
|
|||||||
loader.add(ASSET_SHADER, resdir/path(SHADERS_FOLDER"/main"), "main");
|
loader.add(ASSET_SHADER, resdir/path(SHADERS_FOLDER"/main"), "main");
|
||||||
loader.add(ASSET_SHADER, resdir/path(SHADERS_FOLDER"/lines"), "lines");
|
loader.add(ASSET_SHADER, resdir/path(SHADERS_FOLDER"/lines"), "lines");
|
||||||
loader.add(ASSET_SHADER, resdir/path(SHADERS_FOLDER"/ui"), "ui");
|
loader.add(ASSET_SHADER, resdir/path(SHADERS_FOLDER"/ui"), "ui");
|
||||||
|
loader.add(ASSET_SHADER, resdir/path(SHADERS_FOLDER"/background"), "background");
|
||||||
|
loader.add(ASSET_SHADER, resdir/path(SHADERS_FOLDER"/skybox_gen"), "skybox_gen");
|
||||||
|
|
||||||
loader.add(ASSET_ATLAS, resdir/path(TEXTURES_FOLDER"/blocks"), "blocks");
|
loader.add(ASSET_ATLAS, resdir/path(TEXTURES_FOLDER"/blocks"), "blocks");
|
||||||
loader.add(ASSET_TEXTURE, resdir/path(TEXTURES_FOLDER"/menubg.png"), "menubg");
|
loader.add(ASSET_TEXTURE, resdir/path(TEXTURES_FOLDER"/menubg.png"), "menubg");
|
||||||
|
|||||||
@ -27,6 +27,7 @@
|
|||||||
#define PLAYER_FLAG_NOCLIP 0x2
|
#define PLAYER_FLAG_NOCLIP 0x2
|
||||||
|
|
||||||
#define WORLD_SECTION_MAIN 1
|
#define WORLD_SECTION_MAIN 1
|
||||||
|
#define WORLD_SECTION_DAYNIGHT 2
|
||||||
|
|
||||||
using glm::ivec2;
|
using glm::ivec2;
|
||||||
using glm::vec3;
|
using glm::vec3;
|
||||||
@ -235,11 +236,15 @@ void WorldFiles::writeWorldInfo(const WorldInfo& info) {
|
|||||||
BinaryWriter out;
|
BinaryWriter out;
|
||||||
out.putCStr(WORLD_FORMAT_MAGIC);
|
out.putCStr(WORLD_FORMAT_MAGIC);
|
||||||
out.put(WORLD_FORMAT_VERSION);
|
out.put(WORLD_FORMAT_VERSION);
|
||||||
out.put(WORLD_SECTION_MAIN);
|
|
||||||
|
|
||||||
|
out.put(WORLD_SECTION_MAIN);
|
||||||
out.putInt64(info.seed);
|
out.putInt64(info.seed);
|
||||||
out.put(info.name);
|
out.put(info.name);
|
||||||
|
|
||||||
|
out.put(WORLD_SECTION_DAYNIGHT);
|
||||||
|
out.putFloat32(info.daytime);
|
||||||
|
out.putFloat32(info.daytimeSpeed);
|
||||||
|
|
||||||
files::write_bytes(getWorldFile(), (const char*)out.data(), out.size());
|
files::write_bytes(getWorldFile(), (const char*)out.data(), out.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,6 +265,10 @@ bool WorldFiles::readWorldInfo(WorldInfo& info) {
|
|||||||
info.seed = inp.getInt64();
|
info.seed = inp.getInt64();
|
||||||
info.name = inp.getString();
|
info.name = inp.getString();
|
||||||
break;
|
break;
|
||||||
|
case WORLD_SECTION_DAYNIGHT:
|
||||||
|
info.daytime = inp.getFloat32();
|
||||||
|
info.daytimeSpeed = inp.getFloat32();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -36,6 +36,8 @@ struct WorldInfo {
|
|||||||
std::string name;
|
std::string name;
|
||||||
std::filesystem::path directory;
|
std::filesystem::path directory;
|
||||||
uint64_t seed;
|
uint64_t seed;
|
||||||
|
float daytime;
|
||||||
|
float daytimeSpeed;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WorldFiles {
|
class WorldFiles {
|
||||||
|
|||||||
111
src/frontend/graphics/Skybox.cpp
Normal file
111
src/frontend/graphics/Skybox.cpp
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
#include "Skybox.h"
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
#include "../../graphics/Shader.h"
|
||||||
|
#include "../../graphics/Mesh.h"
|
||||||
|
#include "../../window/Window.h"
|
||||||
|
|
||||||
|
using glm::vec3;
|
||||||
|
|
||||||
|
Skybox::Skybox(uint size, Shader* shader) : size(size), shader(shader) {
|
||||||
|
glGenTextures(1, &cubemap);
|
||||||
|
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap);
|
||||||
|
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||||
|
for (uint face = 0; face < 6; face++) {
|
||||||
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGB, size, size, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
||||||
|
}
|
||||||
|
glGenFramebuffers(1, &fbo);
|
||||||
|
|
||||||
|
float vertices[] {
|
||||||
|
-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f,
|
||||||
|
-1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f
|
||||||
|
};
|
||||||
|
vattr attrs[] {2, 0};
|
||||||
|
mesh = new Mesh(vertices, 6, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
Skybox::~Skybox() {
|
||||||
|
glDeleteTextures(1, &cubemap);
|
||||||
|
glDeleteFramebuffers(1, &fbo);
|
||||||
|
delete mesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Skybox::draw(Shader* shader) {
|
||||||
|
shader->uniform1i("u_cubemap", 1);
|
||||||
|
bind();
|
||||||
|
mesh->draw();
|
||||||
|
unbind();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Skybox::refresh(float t, float mie, uint quality) {
|
||||||
|
ready = true;
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap);
|
||||||
|
shader->use();
|
||||||
|
Window::viewport(0,0, size,size);
|
||||||
|
const vec3 xaxs[] = {
|
||||||
|
{0.0f, 0.0f, -1.0f},
|
||||||
|
{0.0f, 0.0f, 1.0f},
|
||||||
|
{-1.0f, 0.0f, 0.0f},
|
||||||
|
|
||||||
|
{-1.0f, 0.0f, 0.0f},
|
||||||
|
{-1.0f, 0.0f, 0.0f},
|
||||||
|
{1.0f, 0.0f, 0.0f},
|
||||||
|
};
|
||||||
|
const vec3 yaxs[] = {
|
||||||
|
{0.0f, 1.0f, 0.0f},
|
||||||
|
{0.0f, 1.0f, 0.0f},
|
||||||
|
{0.0f, 0.0f, -1.0f},
|
||||||
|
|
||||||
|
{0.0f, 0.0f, 1.0f},
|
||||||
|
{0.0f, 1.0f, 0.0f},
|
||||||
|
{0.0f, 1.0f, 0.0f},
|
||||||
|
};
|
||||||
|
|
||||||
|
const vec3 zaxs[] = {
|
||||||
|
{1.0f, 0.0f, 0.0f},
|
||||||
|
{-1.0f, 0.0f, 0.0f},
|
||||||
|
{0.0f, -1.0f, 0.0f},
|
||||||
|
|
||||||
|
{0.0f, 1.0f, 0.0f},
|
||||||
|
{0.0f, 0.0f, -1.0f},
|
||||||
|
{0.0f, 0.0f, 1.0f},
|
||||||
|
};
|
||||||
|
t *= M_PI*2.0f;
|
||||||
|
|
||||||
|
shader->uniform1i("u_quality", quality);
|
||||||
|
shader->uniform1f("u_mie", mie);
|
||||||
|
shader->uniform3f("u_lightDir", glm::normalize(vec3(sin(t), -cos(t), 0.7f)));
|
||||||
|
for (uint face = 0; face < 6; face++) {
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, cubemap, 0);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
shader->uniform3f("u_xaxis", xaxs[face]);
|
||||||
|
shader->uniform3f("u_yaxis", yaxs[face]);
|
||||||
|
shader->uniform3f("u_zaxis", zaxs[face]);
|
||||||
|
mesh->draw(GL_TRIANGLES);
|
||||||
|
}
|
||||||
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
Window::viewport(0, 0, Window::width, Window::height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Skybox::bind() const {
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Skybox::unbind() const {
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
}
|
||||||
30
src/frontend/graphics/Skybox.h
Normal file
30
src/frontend/graphics/Skybox.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#ifndef FRONTEND_GRAPHICS_SKYBOX_H_
|
||||||
|
#define FRONTEND_GRAPHICS_SKYBOX_H_
|
||||||
|
|
||||||
|
#include "../../typedefs.h"
|
||||||
|
|
||||||
|
class Mesh;
|
||||||
|
class Shader;
|
||||||
|
|
||||||
|
class Skybox {
|
||||||
|
uint fbo;
|
||||||
|
uint cubemap;
|
||||||
|
uint size;
|
||||||
|
Mesh* mesh;
|
||||||
|
Shader* shader;
|
||||||
|
bool ready = false;
|
||||||
|
public:
|
||||||
|
Skybox(uint size, Shader* shader);
|
||||||
|
~Skybox();
|
||||||
|
|
||||||
|
void draw(Shader* shader);
|
||||||
|
|
||||||
|
void refresh(float t, float mie, uint quality);
|
||||||
|
void bind() const;
|
||||||
|
void unbind() const;
|
||||||
|
bool isReady() const {
|
||||||
|
return ready;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FRONTEND_GRAPHICS_SKYBOX_H_
|
||||||
@ -11,6 +11,7 @@
|
|||||||
#include "../typedefs.h"
|
#include "../typedefs.h"
|
||||||
#include "../content/Content.h"
|
#include "../content/Content.h"
|
||||||
#include "../util/stringutil.h"
|
#include "../util/stringutil.h"
|
||||||
|
#include "../util/timeutil.h"
|
||||||
#include "../assets/Assets.h"
|
#include "../assets/Assets.h"
|
||||||
#include "../graphics/Shader.h"
|
#include "../graphics/Shader.h"
|
||||||
#include "../graphics/Batch2D.h"
|
#include "../graphics/Batch2D.h"
|
||||||
@ -128,13 +129,22 @@ HudRenderer::HudRenderer(Engine* engine,
|
|||||||
sub->add(box);
|
sub->add(box);
|
||||||
panel->add(sub);
|
panel->add(sub);
|
||||||
}
|
}
|
||||||
|
panel->add(shared_ptr<Label>(create_label([this](){
|
||||||
|
int hour, minute, second;
|
||||||
|
timeutil::from_value(this->level->world->daytime, hour, minute, second);
|
||||||
|
|
||||||
|
std::wstring timeString =
|
||||||
|
util::lfill(std::to_wstring(hour), 2, L'0') + L":" +
|
||||||
|
util::lfill(std::to_wstring(minute), 2, L'0');
|
||||||
|
return L"time: "+timeString;
|
||||||
|
})));
|
||||||
{
|
{
|
||||||
TrackBar* bar = new TrackBar(0.0f, 1.0f, 1.0f, 0.02f, 2);
|
TrackBar* bar = new TrackBar(0.0f, 1.0f, 1.0f, 0.005f, 8);
|
||||||
bar->supplier([=]() {
|
bar->supplier([=]() {
|
||||||
return renderer->skyLightMutliplier;
|
return level->world->daytime;
|
||||||
});
|
});
|
||||||
bar->consumer([=](double val) {
|
bar->consumer([=](double val) {
|
||||||
renderer->skyLightMutliplier = val;
|
level->world->daytime = val;
|
||||||
});
|
});
|
||||||
panel->add(bar);
|
panel->add(bar);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -136,6 +136,9 @@ void LevelScreen::update(float delta) {
|
|||||||
level->chunks->saveAndClear();
|
level->chunks->saveAndClear();
|
||||||
backlight = settings.graphics.backlight;
|
backlight = settings.graphics.backlight;
|
||||||
}
|
}
|
||||||
|
if (!hud->isPause()) {
|
||||||
|
level->world->updateTimers(delta);
|
||||||
|
}
|
||||||
level->updatePlayer(delta, !inputLocked, hud->isPause(), !inputLocked);
|
level->updatePlayer(delta, !inputLocked, hud->isPause(), !inputLocked);
|
||||||
level->update();
|
level->update();
|
||||||
|
|
||||||
|
|||||||
@ -28,6 +28,7 @@
|
|||||||
#include "../settings.h"
|
#include "../settings.h"
|
||||||
#include "../engine.h"
|
#include "../engine.h"
|
||||||
#include "ContentGfxCache.h"
|
#include "ContentGfxCache.h"
|
||||||
|
#include "graphics/Skybox.h"
|
||||||
|
|
||||||
using glm::vec3;
|
using glm::vec3;
|
||||||
using std::string;
|
using std::string;
|
||||||
@ -35,15 +36,19 @@ using std::shared_ptr;
|
|||||||
|
|
||||||
WorldRenderer::WorldRenderer(Engine* engine, Level* level, const ContentGfxCache* cache)
|
WorldRenderer::WorldRenderer(Engine* engine, Level* level, const ContentGfxCache* cache)
|
||||||
: engine(engine), level(level) {
|
: engine(engine), level(level) {
|
||||||
|
EngineSettings& settings = engine->getSettings();
|
||||||
|
|
||||||
lineBatch = new LineBatch(4096);
|
lineBatch = new LineBatch(4096);
|
||||||
renderer = new ChunksRenderer(level, cache, engine->getSettings());
|
renderer = new ChunksRenderer(level, cache, settings);
|
||||||
frustumCulling = new Frustum();
|
frustumCulling = new Frustum();
|
||||||
level->events->listen(EVT_CHUNK_HIDDEN, [this](lvl_event_type type, Chunk* chunk) {
|
level->events->listen(EVT_CHUNK_HIDDEN, [this](lvl_event_type type, Chunk* chunk) {
|
||||||
renderer->unload(chunk);
|
renderer->unload(chunk);
|
||||||
});
|
});
|
||||||
|
skybox = new Skybox(64, engine->getAssets()->getShader("skybox_gen"));
|
||||||
}
|
}
|
||||||
|
|
||||||
WorldRenderer::~WorldRenderer() {
|
WorldRenderer::~WorldRenderer() {
|
||||||
|
delete skybox;
|
||||||
delete lineBatch;
|
delete lineBatch;
|
||||||
delete renderer;
|
delete renderer;
|
||||||
delete frustumCulling;
|
delete frustumCulling;
|
||||||
@ -100,6 +105,10 @@ void WorldRenderer::drawChunks(Chunks* chunks,
|
|||||||
|
|
||||||
|
|
||||||
void WorldRenderer::draw(const GfxContext& pctx, Camera* camera, bool occlusion){
|
void WorldRenderer::draw(const GfxContext& pctx, Camera* camera, bool occlusion){
|
||||||
|
EngineSettings& settings = engine->getSettings();
|
||||||
|
skybox->refresh(level->world->daytime,
|
||||||
|
fmax(1.0f, 18.0f/settings.chunks.loadDistance), 4);
|
||||||
|
|
||||||
const Content* content = level->content;
|
const Content* content = level->content;
|
||||||
const ContentIndices* contentIds = content->indices;
|
const ContentIndices* contentIds = content->indices;
|
||||||
Assets* assets = engine->getAssets();
|
Assets* assets = engine->getAssets();
|
||||||
@ -110,32 +119,32 @@ void WorldRenderer::draw(const GfxContext& pctx, Camera* camera, bool occlusion)
|
|||||||
const Viewport& viewport = pctx.getViewport();
|
const Viewport& viewport = pctx.getViewport();
|
||||||
int displayWidth = viewport.getWidth();
|
int displayWidth = viewport.getWidth();
|
||||||
int displayHeight = viewport.getHeight();
|
int displayHeight = viewport.getHeight();
|
||||||
|
Window::clearDepth();
|
||||||
|
Window::viewport(0, 0, displayWidth, displayHeight);
|
||||||
|
|
||||||
|
Shader* backShader = assets->getShader("background");
|
||||||
|
backShader->use();
|
||||||
|
backShader->uniformMatrix("u_view", camera->getView(false));
|
||||||
|
backShader->uniform1f("u_zoom", camera->zoom);
|
||||||
|
backShader->uniform1f("u_ar", (float)Window::width/(float)Window::height);
|
||||||
|
skybox->draw(backShader);
|
||||||
|
|
||||||
{
|
{
|
||||||
GfxContext ctx = pctx.sub();
|
GfxContext ctx = pctx.sub();
|
||||||
ctx.depthTest(true);
|
ctx.depthTest(true);
|
||||||
ctx.cullFace(true);
|
ctx.cullFace(true);
|
||||||
|
|
||||||
EngineSettings& settings = engine->getSettings();
|
|
||||||
|
|
||||||
vec3 skyColor(0.7f, 0.81f, 1.0f);
|
|
||||||
skyColor *= skyLightMutliplier;
|
|
||||||
|
|
||||||
Window::setBgColor(skyColor);
|
|
||||||
Window::clear();
|
|
||||||
Window::viewport(0, 0, displayWidth, displayHeight);
|
|
||||||
|
|
||||||
float fogFactor = 18.0f / (float)settings.chunks.loadDistance;
|
float fogFactor = 18.0f / (float)settings.chunks.loadDistance;
|
||||||
|
|
||||||
shader->use();
|
shader->use();
|
||||||
|
skybox->bind();
|
||||||
shader->uniformMatrix("u_proj", camera->getProjection());
|
shader->uniformMatrix("u_proj", camera->getProjection());
|
||||||
shader->uniformMatrix("u_view", camera->getView());
|
shader->uniformMatrix("u_view", camera->getView());
|
||||||
shader->uniform1f("u_gamma", 1.0f);
|
shader->uniform1f("u_gamma", 1.0f);
|
||||||
shader->uniform3f("u_skyLightColor", vec3(1.1f) * skyLightMutliplier);
|
|
||||||
shader->uniform3f("u_fogColor", skyColor);
|
|
||||||
shader->uniform1f("u_fogFactor", fogFactor);
|
shader->uniform1f("u_fogFactor", fogFactor);
|
||||||
shader->uniform1f("u_fogCurve", settings.graphics.fogCurve);
|
shader->uniform1f("u_fogCurve", settings.graphics.fogCurve);
|
||||||
shader->uniform3f("u_cameraPos", camera->position);
|
shader->uniform3f("u_cameraPos", camera->position);
|
||||||
|
shader->uniform1i("u_cubemap", 1);
|
||||||
|
|
||||||
Block* cblock = contentIds->getBlockDef(level->player->choosenBlock);
|
Block* cblock = contentIds->getBlockDef(level->player->choosenBlock);
|
||||||
assert(cblock != nullptr);
|
assert(cblock != nullptr);
|
||||||
@ -168,6 +177,7 @@ void WorldRenderer::draw(const GfxContext& pctx, Camera* camera, bool occlusion)
|
|||||||
}
|
}
|
||||||
lineBatch->render();
|
lineBatch->render();
|
||||||
}
|
}
|
||||||
|
skybox->unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (level->player->debug) {
|
if (level->player->debug) {
|
||||||
@ -175,7 +185,7 @@ void WorldRenderer::draw(const GfxContext& pctx, Camera* camera, bool occlusion)
|
|||||||
ctx.depthTest(true);
|
ctx.depthTest(true);
|
||||||
|
|
||||||
linesShader->use();
|
linesShader->use();
|
||||||
if (engine->getSettings().debug.showChunkBorders){
|
if (settings.debug.showChunkBorders){
|
||||||
linesShader->uniformMatrix("u_projview", camera->getProjView());
|
linesShader->uniformMatrix("u_projview", camera->getProjView());
|
||||||
vec3 coord = level->player->camera->position;
|
vec3 coord = level->player->camera->position;
|
||||||
if (coord.x < 0) coord.x--;
|
if (coord.x < 0) coord.x--;
|
||||||
|
|||||||
@ -22,6 +22,7 @@ class Frustum;
|
|||||||
class Engine;
|
class Engine;
|
||||||
class Chunks;
|
class Chunks;
|
||||||
class ContentGfxCache;
|
class ContentGfxCache;
|
||||||
|
class Skybox;
|
||||||
|
|
||||||
class WorldRenderer {
|
class WorldRenderer {
|
||||||
Engine* engine;
|
Engine* engine;
|
||||||
@ -29,11 +30,10 @@ class WorldRenderer {
|
|||||||
Frustum* frustumCulling;
|
Frustum* frustumCulling;
|
||||||
LineBatch* lineBatch;
|
LineBatch* lineBatch;
|
||||||
ChunksRenderer* renderer;
|
ChunksRenderer* renderer;
|
||||||
|
Skybox* skybox;
|
||||||
bool drawChunk(size_t index, Camera* camera, Shader* shader, bool occlusion);
|
bool drawChunk(size_t index, Camera* camera, Shader* shader, bool occlusion);
|
||||||
void drawChunks(Chunks* chunks, Camera* camera, Shader* shader, bool occlusion);
|
void drawChunks(Chunks* chunks, Camera* camera, Shader* shader, bool occlusion);
|
||||||
public:
|
public:
|
||||||
float skyLightMutliplier = 1.0f; // will be replaced with day-night cycle
|
|
||||||
|
|
||||||
WorldRenderer(Engine* engine, Level* level, const ContentGfxCache* cache);
|
WorldRenderer(Engine* engine, Level* level, const ContentGfxCache* cache);
|
||||||
~WorldRenderer();
|
~WorldRenderer();
|
||||||
|
|
||||||
|
|||||||
14
src/util/timeutil.cpp
Normal file
14
src/util/timeutil.cpp
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#include "timeutil.h"
|
||||||
|
|
||||||
|
float timeutil::time_value(float hour, float minute, float second) {
|
||||||
|
return (hour + (minute + second / 60.0f) / 60.0f) / 24.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void timeutil::from_value(float value, int& hour, int& minute, int& second) {
|
||||||
|
value *= 24;
|
||||||
|
hour = value;
|
||||||
|
value *= 60;
|
||||||
|
minute = int(value) % 60;
|
||||||
|
value *= 60;
|
||||||
|
second = int(value) % 60;
|
||||||
|
}
|
||||||
9
src/util/timeutil.h
Normal file
9
src/util/timeutil.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#ifndef UTIL_TIMEUTIL_H_
|
||||||
|
#define UTIL_TIMEUTIL_H_
|
||||||
|
|
||||||
|
namespace timeutil {
|
||||||
|
float time_value(float hour, float minute, float second);
|
||||||
|
void from_value(float value, int& hour, int& minute, int& second);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // UTIL_TIMEUTIL_H_
|
||||||
@ -42,11 +42,16 @@ mat4 Camera::getProjection(){
|
|||||||
return glm::ortho(0.0f, fov*aspect, 0.0f, fov);
|
return glm::ortho(0.0f, fov*aspect, 0.0f, fov);
|
||||||
}
|
}
|
||||||
|
|
||||||
mat4 Camera::getView(){
|
mat4 Camera::getView(bool pos){
|
||||||
if (perspective)
|
vec3 position = this->position;
|
||||||
|
if (!pos) {
|
||||||
|
position = vec3(0.0f);
|
||||||
|
}
|
||||||
|
if (perspective) {
|
||||||
return glm::lookAt(position, position+front, up);
|
return glm::lookAt(position, position+front, up);
|
||||||
else
|
} else {
|
||||||
return glm::translate(glm::mat4(1.0f), position);
|
return glm::translate(glm::mat4(1.0f), position);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mat4 Camera::getProjView(){
|
mat4 Camera::getProjView(){
|
||||||
|
|||||||
@ -24,7 +24,7 @@ public:
|
|||||||
void rotate(float x, float y, float z);
|
void rotate(float x, float y, float z);
|
||||||
|
|
||||||
mat4 getProjection();
|
mat4 getProjection();
|
||||||
mat4 getView();
|
mat4 getView(bool position=true);
|
||||||
mat4 getProjView();
|
mat4 getProjView();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -127,6 +127,10 @@ int Window::initialize(DisplaySettings& settings){
|
|||||||
glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, GLFW_DONT_CARE);
|
glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, GLFW_DONT_CARE);
|
||||||
}
|
}
|
||||||
glfwSwapInterval(settings.swapInterval);
|
glfwSwapInterval(settings.swapInterval);
|
||||||
|
const GLubyte* vendor = glGetString(GL_VENDOR);
|
||||||
|
const GLubyte* renderer = glGetString(GL_RENDERER);
|
||||||
|
std::cout << "GL Vendor: " << (char*)vendor << std::endl;
|
||||||
|
std::cout << "GL Renderer: " << (char*)renderer << std::endl;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,6 +138,10 @@ void Window::clear() {
|
|||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Window::clearDepth() {
|
||||||
|
glClear(GL_DEPTH_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
void Window::setBgColor(glm::vec3 color) {
|
void Window::setBgColor(glm::vec3 color) {
|
||||||
glClearColor(color.r, color.g, color.b, 1.0f);
|
glClearColor(color.r, color.g, color.b, 1.0f);
|
||||||
}
|
}
|
||||||
@ -252,6 +260,7 @@ DisplaySettings* Window::getSettings() {
|
|||||||
|
|
||||||
ImageData* Window::takeScreenshot() {
|
ImageData* Window::takeScreenshot() {
|
||||||
ubyte* data = new ubyte[width * height * 3];
|
ubyte* data = new ubyte[width * height * 3];
|
||||||
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||||
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, data);
|
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||||
return new ImageData(ImageFormat::rgb888, width, height, data);
|
return new ImageData(ImageFormat::rgb888, width, height, data);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,6 +44,7 @@ public:
|
|||||||
static void resetScissor();
|
static void resetScissor();
|
||||||
|
|
||||||
static void clear();
|
static void clear();
|
||||||
|
static void clearDepth();
|
||||||
static void setBgColor(glm::vec3 color);
|
static void setBgColor(glm::vec3 color);
|
||||||
static double time();
|
static double time();
|
||||||
static DisplaySettings* getSettings();
|
static DisplaySettings* getSettings();
|
||||||
|
|||||||
@ -29,6 +29,11 @@ World::~World(){
|
|||||||
delete wfile;
|
delete wfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void World::updateTimers(float delta) {
|
||||||
|
daytime += delta * daytimeSpeed;
|
||||||
|
daytime = fmod(daytime, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
void World::write(Level* level) {
|
void World::write(Level* level) {
|
||||||
const Content* content = level->content;
|
const Content* content = level->content;
|
||||||
|
|
||||||
@ -41,15 +46,17 @@ void World::write(Level* level) {
|
|||||||
wfile->put(chunk.get());
|
wfile->put(chunk.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
wfile->write(WorldInfo {name, wfile->directory, seed}, content);
|
wfile->write(WorldInfo {name, wfile->directory, seed, daytime, daytimeSpeed}, content);
|
||||||
wfile->writePlayer(level->player);
|
wfile->writePlayer(level->player);
|
||||||
}
|
}
|
||||||
|
|
||||||
Level* World::load(EngineSettings& settings, const Content* content) {
|
Level* World::load(EngineSettings& settings, const Content* content) {
|
||||||
WorldInfo info {name, wfile->directory, seed};
|
WorldInfo info {name, wfile->directory, seed, daytime, daytimeSpeed};
|
||||||
wfile->readWorldInfo(info);
|
wfile->readWorldInfo(info);
|
||||||
seed = info.seed;
|
seed = info.seed;
|
||||||
name = info.name;
|
name = info.name;
|
||||||
|
daytime = info.daytime;
|
||||||
|
daytimeSpeed = info.daytimeSpeed;
|
||||||
|
|
||||||
vec3 playerPosition = vec3(0, 100, 0);
|
vec3 playerPosition = vec3(0, 100, 0);
|
||||||
Camera* camera = new Camera(playerPosition, glm::radians(90.0f));
|
Camera* camera = new Camera(playerPosition, glm::radians(90.0f));
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include "../typedefs.h"
|
#include "../typedefs.h"
|
||||||
#include "../settings.h"
|
#include "../settings.h"
|
||||||
|
#include "../util/timeutil.h"
|
||||||
|
|
||||||
class Content;
|
class Content;
|
||||||
class WorldFiles;
|
class WorldFiles;
|
||||||
@ -18,12 +19,20 @@ public:
|
|||||||
WorldFiles* wfile;
|
WorldFiles* wfile;
|
||||||
uint64_t seed;
|
uint64_t seed;
|
||||||
|
|
||||||
|
/* Day/night loop timer in range 0..1
|
||||||
|
0.0 - is midnight
|
||||||
|
0.5 - is noon
|
||||||
|
*/
|
||||||
|
float daytime = timeutil::time_value(10, 00, 00);
|
||||||
|
float daytimeSpeed = 1.0f/60.0f/24.0f;
|
||||||
|
|
||||||
World(std::string name,
|
World(std::string name,
|
||||||
std::filesystem::path directory,
|
std::filesystem::path directory,
|
||||||
uint64_t seed,
|
uint64_t seed,
|
||||||
EngineSettings& settings);
|
EngineSettings& settings);
|
||||||
~World();
|
~World();
|
||||||
|
|
||||||
|
void updateTimers(float delta);
|
||||||
void write(Level* level);
|
void write(Level* level);
|
||||||
Level* load(EngineSettings& settings, const Content* content);
|
Level* load(EngineSettings& settings, const Content* content);
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user