This commit is contained in:
@@ -13,5 +13,3 @@ cd ..
|
|||||||
mkdir OUTPUT-Linux
|
mkdir OUTPUT-Linux
|
||||||
cp build/src/RCRAFT OUTPUT-Linux/CubeGame
|
cp build/src/RCRAFT OUTPUT-Linux/CubeGame
|
||||||
cp -r data/resources OUTPUT-Linux
|
cp -r data/resources OUTPUT-Linux
|
||||||
mkdir OUTPUT-Linux/user
|
|
||||||
mkdir OUTPUT-Linux/user/worlds
|
|
||||||
@@ -13,5 +13,3 @@ cd ..
|
|||||||
mkdir OUTPUT-w32
|
mkdir OUTPUT-w32
|
||||||
cp build/src/RCRAFT.exe OUTPUT-w32/CubeGame.exe
|
cp build/src/RCRAFT.exe OUTPUT-w32/CubeGame.exe
|
||||||
cp -r data/resources OUTPUT-w32
|
cp -r data/resources OUTPUT-w32
|
||||||
mkdir OUTPUT-w32/user
|
|
||||||
mkdir OUTPUT-w32/user/worlds
|
|
||||||
@@ -13,5 +13,3 @@ cd ..
|
|||||||
mkdir OUTPUT-w64
|
mkdir OUTPUT-w64
|
||||||
cp build/src/RCRAFT.exe OUTPUT-w64/CubeGame.exe
|
cp build/src/RCRAFT.exe OUTPUT-w64/CubeGame.exe
|
||||||
cp -r data/resources OUTPUT-w64
|
cp -r data/resources OUTPUT-w64
|
||||||
mkdir OUTPUT-w64/user
|
|
||||||
mkdir OUTPUT-w64/user/worlds
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
211d25
|
|
||||||
413d42
|
|
||||||
5c5b63
|
|
||||||
7c808b
|
|
||||||
a5b0b6
|
|
||||||
d6dede
|
|
||||||
ffffff
|
|
||||||
dcded1
|
|
||||||
aab1a1
|
|
||||||
7b8375
|
|
||||||
585f57
|
|
||||||
3c3c3c
|
|
||||||
635d5a
|
|
||||||
8d837d
|
|
||||||
b4aea4
|
|
||||||
dedcd1
|
|
||||||
eadedf
|
|
||||||
bcacb1
|
|
||||||
8f8189
|
|
||||||
685d66
|
|
||||||
643747
|
|
||||||
b2434d
|
|
||||||
e55858
|
|
||||||
fa8971
|
|
||||||
ffb999
|
|
||||||
ffe0b7
|
|
||||||
ffbdc1
|
|
||||||
ef93b5
|
|
||||||
c971a2
|
|
||||||
944e89
|
|
||||||
4c3d57
|
|
||||||
5d558f
|
|
||||||
777dc4
|
|
||||||
96b1e7
|
|
||||||
bedef6
|
|
||||||
aae3db
|
|
||||||
5ac5ce
|
|
||||||
4694a8
|
|
||||||
346376
|
|
||||||
2a3b4a
|
|
||||||
29684a
|
|
||||||
379648
|
|
||||||
79b547
|
|
||||||
b8cf61
|
|
||||||
f3db6f
|
|
||||||
f4ba7a
|
|
||||||
e79055
|
|
||||||
ce6442
|
|
||||||
944940
|
|
||||||
91555d
|
|
||||||
b76f6b
|
|
||||||
cd9383
|
|
||||||
e1ba9e
|
|
||||||
facafb
|
|
||||||
d49ce5
|
|
||||||
9f76b8
|
|
||||||
725689
|
|
||||||
edb762
|
|
||||||
fcfbc9
|
|
||||||
de9463
|
|
||||||
b66a4d
|
|
||||||
333f29
|
|
||||||
4e5c2c
|
|
||||||
708939
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 308 B |
@@ -14,12 +14,14 @@ speed_up: Fly faster
|
|||||||
fly: Toggle flying
|
fly: Toggle flying
|
||||||
chat: Open chat
|
chat: Open chat
|
||||||
swap_mouse: Swap LMB/RMB
|
swap_mouse: Swap LMB/RMB
|
||||||
|
inventory: Open inventory
|
||||||
# Menu
|
# Menu
|
||||||
select_level: Singleplayer
|
select_level: Singleplayer
|
||||||
multiplayer: Multiplayer
|
multiplayer: Multiplayer
|
||||||
join: Join
|
join: Join
|
||||||
exit: Exit
|
exit: Exit
|
||||||
options: Options
|
options: Options
|
||||||
|
create_world: Create world
|
||||||
# Multiplayer errors
|
# Multiplayer errors
|
||||||
error_notfound: Host not found!
|
error_notfound: Host not found!
|
||||||
error_internal: Internal enet error!
|
error_internal: Internal enet error!
|
||||||
@@ -41,21 +43,17 @@ item.dirt: "Dirt"
|
|||||||
item.sand: "Sand"
|
item.sand: "Sand"
|
||||||
item.water: "Water"
|
item.water: "Water"
|
||||||
item.planks: "Wooden Planks"
|
item.planks: "Wooden Planks"
|
||||||
item.gray_bricks: "Gray Bricks"
|
item.stone_bricks: "Stone Bricks"
|
||||||
item.red_bricks: "Red Bricks"
|
item.copper_block: "Copper Block"
|
||||||
item.blue_bricks: "Blue Bricks"
|
item.silver_block: "Silver Block"
|
||||||
item.green_bricks: "Green Bricks"
|
item.gold_block: "Gold Block"
|
||||||
item.glass: "Glass"
|
item.glass: "Glass"
|
||||||
item.log: "Log"
|
item.log: "Log"
|
||||||
item.spruce_planks: "Spruce Planks"
|
item.spruce_planks: "Spruce Planks"
|
||||||
item.red_block: "Red Block"
|
item.red_block: "Red Block"
|
||||||
item.green_block: "Green Block"
|
item.green_block: "Green Block"
|
||||||
item.blue_block: "Blue Block"
|
item.blue_block: "Blue Block"
|
||||||
item.yellow_block: "Yellow Block"
|
|
||||||
item.cyan_block: "Cyan Block"
|
|
||||||
item.magenta_block: "Magenta Block"
|
|
||||||
item.white_block: "White Block"
|
item.white_block: "White Block"
|
||||||
item.black_block: "Black Block"
|
|
||||||
item.leaves: "Leaves"
|
item.leaves: "Leaves"
|
||||||
item.copper_ore: "Copper Ore"
|
item.copper_ore: "Copper Ore"
|
||||||
item.silver_ore: "Silver Ore"
|
item.silver_ore: "Silver Ore"
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 4.5 KiB |
@@ -0,0 +1,37 @@
|
|||||||
|
#version 330
|
||||||
|
|
||||||
|
in vec2 fragTexCoord;
|
||||||
|
in vec4 fragColor;
|
||||||
|
in vec3 fragPosition;
|
||||||
|
in vec3 fragNormal;
|
||||||
|
|
||||||
|
uniform sampler2D texture0;
|
||||||
|
uniform vec4 sunlightColor;
|
||||||
|
|
||||||
|
uniform vec3 lightDir;
|
||||||
|
|
||||||
|
out vec4 finalColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 texelColor = texture(texture0, fragTexCoord);
|
||||||
|
|
||||||
|
vec3 N = normalize(fragNormal);
|
||||||
|
vec3 L = normalize(lightDir);
|
||||||
|
|
||||||
|
float ndotl = max(dot(N, L), 0.0);
|
||||||
|
float ambient = 0.1;
|
||||||
|
float sunfactor = ambient + (1.0 - ambient) * ndotl;
|
||||||
|
|
||||||
|
sunfactor *= 1+min(0, L.y);
|
||||||
|
vec3 Lmoon = normalize(-lightDir);
|
||||||
|
float ndotlMoon = max(dot(N, Lmoon), 0.0);
|
||||||
|
float moonfactor = (ambient + (1.0 - ambient) * ndotlMoon) * 8;
|
||||||
|
moonfactor *= max(0, -L.y);
|
||||||
|
|
||||||
|
// In fragColor, 'r' is blocklight R, 'g' is blocklight G, 'b' is blocklight B and 'a' is sunlight
|
||||||
|
texelColor.r *= fragColor.a * sunlightColor.r * (sunfactor+moonfactor) + fragColor.r;
|
||||||
|
texelColor.g *= fragColor.a * sunlightColor.g * (sunfactor+moonfactor) + fragColor.g;
|
||||||
|
texelColor.b *= fragColor.a * sunlightColor.b * (sunfactor+moonfactor) + fragColor.b;
|
||||||
|
finalColor = texelColor;
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#version 330
|
||||||
|
|
||||||
|
// Input vertex attributes
|
||||||
|
in vec3 vertexPosition;
|
||||||
|
in vec2 vertexTexCoord;
|
||||||
|
in vec3 vertexNormal;
|
||||||
|
in vec4 vertexColor;
|
||||||
|
|
||||||
|
// Input uniform values
|
||||||
|
uniform mat4 mvp;
|
||||||
|
uniform mat4 matModel;
|
||||||
|
uniform mat4 matNormal;
|
||||||
|
|
||||||
|
// Output vertex attributes (to fragment shader)
|
||||||
|
out vec3 fragPosition;
|
||||||
|
out vec2 fragTexCoord;
|
||||||
|
out vec4 fragColor;
|
||||||
|
out vec3 fragNormal;
|
||||||
|
|
||||||
|
// NOTE: Add your custom variables here
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Send vertex attributes to fragment shader
|
||||||
|
fragPosition = vec3(matModel*vec4(vertexPosition, 1.0));
|
||||||
|
fragTexCoord = vertexTexCoord;
|
||||||
|
fragColor = vertexColor;
|
||||||
|
fragNormal = normalize(vec3(matNormal*vec4(vertexNormal, 1.0)));
|
||||||
|
|
||||||
|
// Calculate final vertex position
|
||||||
|
gl_Position = mvp*vec4(vertexPosition, 1.0);
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
#version 330
|
||||||
|
|
||||||
|
in vec2 fragTexCoord;
|
||||||
|
in vec4 fragColor;
|
||||||
|
in vec3 fragPosition;
|
||||||
|
in vec3 fragNormal;
|
||||||
|
|
||||||
|
uniform sampler2D texture0;
|
||||||
|
uniform vec4 sunlightColor;
|
||||||
|
uniform vec4 skyColor;
|
||||||
|
|
||||||
|
uniform vec3 lightDir;
|
||||||
|
|
||||||
|
out vec4 finalColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 texelColor = texture(texture0, fragTexCoord);
|
||||||
|
|
||||||
|
vec3 N = normalize(fragNormal);
|
||||||
|
vec3 L = normalize(lightDir);
|
||||||
|
|
||||||
|
float ndotl = max(dot(N, L), 0.0);
|
||||||
|
float ambient = 0.1;
|
||||||
|
float sunfactor = ambient + (1.0 - ambient) * ndotl;
|
||||||
|
|
||||||
|
sunfactor *= 1+min(0, L.y);
|
||||||
|
vec3 Lmoon = normalize(-lightDir);
|
||||||
|
float ndotlMoon = max(dot(N, Lmoon), 0.0);
|
||||||
|
float moonfactor = (ambient + (1.0 - ambient) * ndotlMoon) * 8;
|
||||||
|
moonfactor *= max(0, -L.y);
|
||||||
|
|
||||||
|
// In fragColor, 'r' is blocklight R, 'g' is blocklight G, 'b' is blocklight B and 'a' is sunlight
|
||||||
|
float sunlight = fragColor.a;
|
||||||
|
texelColor.r *= sunlight * sunlightColor.r * (sunfactor+moonfactor) + fragColor.r;
|
||||||
|
texelColor.g *= sunlight * sunlightColor.g * (sunfactor+moonfactor) + fragColor.g;
|
||||||
|
texelColor.b *= sunlight * sunlightColor.b * (sunfactor+moonfactor) + fragColor.b;
|
||||||
|
float highlight = texelColor.a;
|
||||||
|
if(highlight < 0.25) highlight = 0;
|
||||||
|
float highlight_final = abs(N.y)*highlight * 4;
|
||||||
|
vec3 highlightColor = sunlightColor.rgb*highlight_final*sunlight;
|
||||||
|
highlightColor.r += fragColor.r*highlight_final;
|
||||||
|
highlightColor.g += fragColor.g*highlight_final;
|
||||||
|
highlightColor.b += fragColor.b*highlight_final;
|
||||||
|
finalColor = texelColor + vec4(highlightColor, min(1.0, highlight_final));
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
#version 330
|
||||||
|
|
||||||
|
// Input vertex attributes
|
||||||
|
in vec3 vertexPosition;
|
||||||
|
in vec2 vertexTexCoord;
|
||||||
|
in vec3 vertexNormal;
|
||||||
|
in vec4 vertexColor;
|
||||||
|
|
||||||
|
// Input uniform values
|
||||||
|
uniform mat4 mvp;
|
||||||
|
uniform mat4 matModel;
|
||||||
|
uniform mat4 matNormal;
|
||||||
|
uniform float time;
|
||||||
|
|
||||||
|
// Output vertex attributes (to fragment shader)
|
||||||
|
out vec3 fragPosition;
|
||||||
|
out vec2 fragTexCoord;
|
||||||
|
out vec4 fragColor;
|
||||||
|
out vec3 fragNormal;
|
||||||
|
|
||||||
|
// NOTE: Add your custom variables here
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Send vertex attributes to fragment shader
|
||||||
|
fragPosition = vec3(matModel*vec4(vertexPosition, 1.0));
|
||||||
|
fragTexCoord = vertexTexCoord;
|
||||||
|
fragColor = vertexColor;
|
||||||
|
fragNormal = normalize(vec3(matNormal*vec4(vertexNormal, 1.0)));
|
||||||
|
|
||||||
|
// Calculate final vertex position
|
||||||
|
vec3 pos = vertexPosition + vec3(0, sin(time * 2.0 + vertexPosition.x * 1.5) / 20.0 + cos(time * 2.0 + vertexPosition.z * 1.5) / 20.0-0.1, 0);
|
||||||
|
gl_Position = mvp*vec4(pos, 1.0);
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 901 B |
Binary file not shown.
|
After Width: | Height: | Size: 2.0 KiB |
+1
-1
@@ -5,7 +5,7 @@ add_subdirectory(helpers)
|
|||||||
|
|
||||||
set(YAML_BUILD_SHARED_LIBS OFF)
|
set(YAML_BUILD_SHARED_LIBS OFF)
|
||||||
set(YAML_MSVC_SHARED_RT OFF)
|
set(YAML_MSVC_SHARED_RT OFF)
|
||||||
set(OPENGL_VERSION 2.1)
|
set(OPENGL_VERSION 3.3)
|
||||||
|
|
||||||
add_subdirectory(libraries/raylib)
|
add_subdirectory(libraries/raylib)
|
||||||
add_subdirectory(libraries/enet)
|
add_subdirectory(libraries/enet)
|
||||||
|
|||||||
+2441
File diff suppressed because it is too large
Load Diff
@@ -1,659 +0,0 @@
|
|||||||
//----------------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// siv::PerlinNoise
|
|
||||||
// Perlin noise library for modern C++
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013-2021 Ryo Suzuki <reputeless@gmail.com>
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
//
|
|
||||||
//----------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# pragma once
|
|
||||||
# include <cstdint>
|
|
||||||
# include <algorithm>
|
|
||||||
# include <array>
|
|
||||||
# include <iterator>
|
|
||||||
# include <numeric>
|
|
||||||
# include <random>
|
|
||||||
# include <type_traits>
|
|
||||||
|
|
||||||
# if __has_include(<concepts>) && defined(__cpp_concepts)
|
|
||||||
# include <concepts>
|
|
||||||
# endif
|
|
||||||
|
|
||||||
|
|
||||||
// Library major version
|
|
||||||
# define SIVPERLIN_VERSION_MAJOR 3
|
|
||||||
|
|
||||||
// Library minor version
|
|
||||||
# define SIVPERLIN_VERSION_MINOR 0
|
|
||||||
|
|
||||||
// Library revision version
|
|
||||||
# define SIVPERLIN_VERSION_REVISION 0
|
|
||||||
|
|
||||||
// Library version
|
|
||||||
# define SIVPERLIN_VERSION ((SIVPERLIN_VERSION_MAJOR * 100 * 100) + (SIVPERLIN_VERSION_MINOR * 100) + (SIVPERLIN_VERSION_REVISION))
|
|
||||||
|
|
||||||
|
|
||||||
// [[nodiscard]] for constructors
|
|
||||||
# if (201907L <= __has_cpp_attribute(nodiscard))
|
|
||||||
# define SIVPERLIN_NODISCARD_CXX20 [[nodiscard]]
|
|
||||||
# else
|
|
||||||
# define SIVPERLIN_NODISCARD_CXX20
|
|
||||||
# endif
|
|
||||||
|
|
||||||
|
|
||||||
// std::uniform_random_bit_generator concept
|
|
||||||
# if __cpp_lib_concepts
|
|
||||||
# define SIVPERLIN_CONCEPT_URBG template <std::uniform_random_bit_generator URBG>
|
|
||||||
# define SIVPERLIN_CONCEPT_URBG_ template <std::uniform_random_bit_generator URBG>
|
|
||||||
# else
|
|
||||||
# define SIVPERLIN_CONCEPT_URBG template <class URBG, std::enable_if_t<std::conjunction_v<std::is_invocable<URBG&>, std::is_unsigned<std::invoke_result_t<URBG&>>>>* = nullptr>
|
|
||||||
# define SIVPERLIN_CONCEPT_URBG_ template <class URBG, std::enable_if_t<std::conjunction_v<std::is_invocable<URBG&>, std::is_unsigned<std::invoke_result_t<URBG&>>>>*>
|
|
||||||
# endif
|
|
||||||
|
|
||||||
|
|
||||||
// arbitrary value for increasing entropy
|
|
||||||
# ifndef SIVPERLIN_DEFAULT_Y
|
|
||||||
# define SIVPERLIN_DEFAULT_Y (0.12345)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
// arbitrary value for increasing entropy
|
|
||||||
# ifndef SIVPERLIN_DEFAULT_Z
|
|
||||||
# define SIVPERLIN_DEFAULT_Z (0.34567)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
|
|
||||||
namespace siv
|
|
||||||
{
|
|
||||||
template <class Float>
|
|
||||||
class BasicPerlinNoise
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
static_assert(std::is_floating_point_v<Float>);
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Typedefs
|
|
||||||
//
|
|
||||||
|
|
||||||
using state_type = std::array<std::uint8_t, 256>;
|
|
||||||
|
|
||||||
using value_type = Float;
|
|
||||||
|
|
||||||
using default_random_engine = std::mt19937;
|
|
||||||
|
|
||||||
using seed_type = typename default_random_engine::result_type;
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Constructors
|
|
||||||
//
|
|
||||||
|
|
||||||
SIVPERLIN_NODISCARD_CXX20
|
|
||||||
constexpr BasicPerlinNoise() noexcept;
|
|
||||||
|
|
||||||
SIVPERLIN_NODISCARD_CXX20
|
|
||||||
explicit BasicPerlinNoise(seed_type seed);
|
|
||||||
|
|
||||||
SIVPERLIN_CONCEPT_URBG
|
|
||||||
SIVPERLIN_NODISCARD_CXX20
|
|
||||||
explicit BasicPerlinNoise(URBG&& urbg);
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Reseed
|
|
||||||
//
|
|
||||||
|
|
||||||
void reseed(seed_type seed);
|
|
||||||
|
|
||||||
SIVPERLIN_CONCEPT_URBG
|
|
||||||
void reseed(URBG&& urbg);
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Serialization
|
|
||||||
//
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
constexpr const state_type& serialize() const noexcept;
|
|
||||||
|
|
||||||
constexpr void deserialize(const state_type& state) noexcept;
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Noise (The result is in the range [-1, 1])
|
|
||||||
//
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
value_type noise1D(value_type x) const noexcept;
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
value_type noise2D(value_type x, value_type y) const noexcept;
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
value_type noise3D(value_type x, value_type y, value_type z) const noexcept;
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Noise (The result is remapped to the range [0, 1])
|
|
||||||
//
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
value_type noise1D_01(value_type x) const noexcept;
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
value_type noise2D_01(value_type x, value_type y) const noexcept;
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
value_type noise3D_01(value_type x, value_type y, value_type z) const noexcept;
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Octave noise (The result can be out of the range [-1, 1])
|
|
||||||
//
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
value_type octave1D(value_type x, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
value_type octave2D(value_type x, value_type y, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
value_type octave3D(value_type x, value_type y, value_type z, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Octave noise (The result is clamped to the range [-1, 1])
|
|
||||||
//
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
value_type octave1D_11(value_type x, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
value_type octave2D_11(value_type x, value_type y, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
value_type octave3D_11(value_type x, value_type y, value_type z, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Octave noise (The result is clamped and remapped to the range [0, 1])
|
|
||||||
//
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
value_type octave1D_01(value_type x, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
value_type octave2D_01(value_type x, value_type y, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
value_type octave3D_01(value_type x, value_type y, value_type z, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Octave noise (The result is normalized to the range [-1, 1])
|
|
||||||
//
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
value_type normalizedOctave1D(value_type x, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
value_type normalizedOctave2D(value_type x, value_type y, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
value_type normalizedOctave3D(value_type x, value_type y, value_type z, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Octave noise (The result is normalized and remapped to the range [0, 1])
|
|
||||||
//
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
value_type normalizedOctave1D_01(value_type x, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
value_type normalizedOctave2D_01(value_type x, value_type y, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
value_type normalizedOctave3D_01(value_type x, value_type y, value_type z, std::int32_t octaves, value_type persistence = value_type(0.5)) const noexcept;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
state_type m_permutation;
|
|
||||||
};
|
|
||||||
|
|
||||||
using PerlinNoise = BasicPerlinNoise<double>;
|
|
||||||
|
|
||||||
namespace perlin_detail
|
|
||||||
{
|
|
||||||
////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// These functions are provided for consistency.
|
|
||||||
// You may get different results from std::shuffle() with different standard library implementations.
|
|
||||||
//
|
|
||||||
SIVPERLIN_CONCEPT_URBG
|
|
||||||
[[nodiscard]]
|
|
||||||
inline std::uint64_t Random(const std::uint64_t max, URBG&& urbg)
|
|
||||||
{
|
|
||||||
return (urbg() % (max + 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class RandomIt, class URBG>
|
|
||||||
inline void Shuffle(RandomIt first, RandomIt last, URBG&& urbg)
|
|
||||||
{
|
|
||||||
if (first == last)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
using difference_type = typename std::iterator_traits<RandomIt>::difference_type;
|
|
||||||
|
|
||||||
for (RandomIt it = first + 1; it < last; ++it)
|
|
||||||
{
|
|
||||||
const std::uint64_t n = static_cast<std::uint64_t>(it - first);
|
|
||||||
std::iter_swap(it, first + static_cast<difference_type>(Random(n, std::forward<URBG>(urbg))));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
[[nodiscard]]
|
|
||||||
inline constexpr Float Fade(const Float t) noexcept
|
|
||||||
{
|
|
||||||
return t * t * t * (t * (t * 6 - 15) + 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
[[nodiscard]]
|
|
||||||
inline constexpr Float Lerp(const Float a, const Float b, const Float t) noexcept
|
|
||||||
{
|
|
||||||
return (a + (b - a) * t);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
[[nodiscard]]
|
|
||||||
inline constexpr Float Grad(const std::uint8_t hash, const Float x, const Float y, const Float z) noexcept
|
|
||||||
{
|
|
||||||
const std::uint8_t h = hash & 15;
|
|
||||||
const Float u = h < 8 ? x : y;
|
|
||||||
const Float v = h < 4 ? y : h == 12 || h == 14 ? x : z;
|
|
||||||
return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
[[nodiscard]]
|
|
||||||
inline constexpr Float Remap_01(const Float x) noexcept
|
|
||||||
{
|
|
||||||
return (x * Float(0.5) + Float(0.5));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
[[nodiscard]]
|
|
||||||
inline constexpr Float Clamp_11(const Float x) noexcept
|
|
||||||
{
|
|
||||||
return std::clamp(x, Float(-1.0), Float(1.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
[[nodiscard]]
|
|
||||||
inline constexpr Float RemapClamp_01(const Float x) noexcept
|
|
||||||
{
|
|
||||||
if (x <= Float(-1.0))
|
|
||||||
{
|
|
||||||
return Float(0.0);
|
|
||||||
}
|
|
||||||
else if (Float(1.0) <= x)
|
|
||||||
{
|
|
||||||
return Float(1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (x * Float(0.5) + Float(0.5));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Noise, class Float>
|
|
||||||
[[nodiscard]]
|
|
||||||
inline auto Octave1D(const Noise& noise, Float x, const std::int32_t octaves, const Float persistence) noexcept
|
|
||||||
{
|
|
||||||
using value_type = Float;
|
|
||||||
value_type result = 0;
|
|
||||||
value_type amplitude = 1;
|
|
||||||
|
|
||||||
for (std::int32_t i = 0; i < octaves; ++i)
|
|
||||||
{
|
|
||||||
result += (noise.noise1D(x) * amplitude);
|
|
||||||
x *= 2;
|
|
||||||
amplitude *= persistence;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Noise, class Float>
|
|
||||||
[[nodiscard]]
|
|
||||||
inline auto Octave2D(const Noise& noise, Float x, Float y, const std::int32_t octaves, const Float persistence) noexcept
|
|
||||||
{
|
|
||||||
using value_type = Float;
|
|
||||||
value_type result = 0;
|
|
||||||
value_type amplitude = 1;
|
|
||||||
|
|
||||||
for (std::int32_t i = 0; i < octaves; ++i)
|
|
||||||
{
|
|
||||||
result += (noise.noise2D(x, y) * amplitude);
|
|
||||||
x *= 2;
|
|
||||||
y *= 2;
|
|
||||||
amplitude *= persistence;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Noise, class Float>
|
|
||||||
[[nodiscard]]
|
|
||||||
inline auto Octave3D(const Noise& noise, Float x, Float y, Float z, const std::int32_t octaves, const Float persistence) noexcept
|
|
||||||
{
|
|
||||||
using value_type = Float;
|
|
||||||
value_type result = 0;
|
|
||||||
value_type amplitude = 1;
|
|
||||||
|
|
||||||
for (std::int32_t i = 0; i < octaves; ++i)
|
|
||||||
{
|
|
||||||
result += (noise.noise3D(x, y, z) * amplitude);
|
|
||||||
x *= 2;
|
|
||||||
y *= 2;
|
|
||||||
z *= 2;
|
|
||||||
amplitude *= persistence;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
[[nodiscard]]
|
|
||||||
inline constexpr Float MaxAmplitude(const std::int32_t octaves, const Float persistence) noexcept
|
|
||||||
{
|
|
||||||
using value_type = Float;
|
|
||||||
value_type result = 0;
|
|
||||||
value_type amplitude = 1;
|
|
||||||
|
|
||||||
for (std::int32_t i = 0; i < octaves; ++i)
|
|
||||||
{
|
|
||||||
result += amplitude;
|
|
||||||
amplitude *= persistence;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
inline constexpr BasicPerlinNoise<Float>::BasicPerlinNoise() noexcept
|
|
||||||
: m_permutation{ 151,160,137,91,90,15,
|
|
||||||
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
|
|
||||||
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
|
|
||||||
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
|
|
||||||
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
|
|
||||||
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
|
|
||||||
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
|
|
||||||
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
|
|
||||||
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
|
|
||||||
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
|
|
||||||
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
|
|
||||||
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
|
|
||||||
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180 } {}
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
inline BasicPerlinNoise<Float>::BasicPerlinNoise(const seed_type seed)
|
|
||||||
{
|
|
||||||
reseed(seed);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
SIVPERLIN_CONCEPT_URBG_
|
|
||||||
inline BasicPerlinNoise<Float>::BasicPerlinNoise(URBG&& urbg)
|
|
||||||
{
|
|
||||||
reseed(std::forward<URBG>(urbg));
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
inline void BasicPerlinNoise<Float>::reseed(const seed_type seed)
|
|
||||||
{
|
|
||||||
reseed(default_random_engine{ seed });
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
SIVPERLIN_CONCEPT_URBG_
|
|
||||||
inline void BasicPerlinNoise<Float>::reseed(URBG&& urbg)
|
|
||||||
{
|
|
||||||
std::iota(m_permutation.begin(), m_permutation.end(), uint8_t{ 0 });
|
|
||||||
|
|
||||||
perlin_detail::Shuffle(m_permutation.begin(), m_permutation.end(), std::forward<URBG>(urbg));
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
inline constexpr const typename BasicPerlinNoise<Float>::state_type& BasicPerlinNoise<Float>::serialize() const noexcept
|
|
||||||
{
|
|
||||||
return m_permutation;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
inline constexpr void BasicPerlinNoise<Float>::deserialize(const state_type& state) noexcept
|
|
||||||
{
|
|
||||||
m_permutation = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::noise1D(const value_type x) const noexcept
|
|
||||||
{
|
|
||||||
return noise3D(x,
|
|
||||||
static_cast<value_type>(SIVPERLIN_DEFAULT_Y),
|
|
||||||
static_cast<value_type>(SIVPERLIN_DEFAULT_Z));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::noise2D(const value_type x, const value_type y) const noexcept
|
|
||||||
{
|
|
||||||
return noise3D(x,
|
|
||||||
y,
|
|
||||||
static_cast<value_type>(SIVPERLIN_DEFAULT_Z));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::noise3D(const value_type x, const value_type y, const value_type z) const noexcept
|
|
||||||
{
|
|
||||||
const value_type _x = std::floor(x);
|
|
||||||
const value_type _y = std::floor(y);
|
|
||||||
const value_type _z = std::floor(z);
|
|
||||||
|
|
||||||
const std::int32_t ix = static_cast<std::int32_t>(_x) & 255;
|
|
||||||
const std::int32_t iy = static_cast<std::int32_t>(_y) & 255;
|
|
||||||
const std::int32_t iz = static_cast<std::int32_t>(_z) & 255;
|
|
||||||
|
|
||||||
const value_type fx = (x - _x);
|
|
||||||
const value_type fy = (y - _y);
|
|
||||||
const value_type fz = (z - _z);
|
|
||||||
|
|
||||||
const value_type u = perlin_detail::Fade(fx);
|
|
||||||
const value_type v = perlin_detail::Fade(fy);
|
|
||||||
const value_type w = perlin_detail::Fade(fz);
|
|
||||||
|
|
||||||
const std::uint8_t A = (m_permutation[ix & 255] + iy) & 255;
|
|
||||||
const std::uint8_t B = (m_permutation[(ix + 1) & 255] + iy) & 255;
|
|
||||||
|
|
||||||
const std::uint8_t AA = (m_permutation[A] + iz) & 255;
|
|
||||||
const std::uint8_t AB = (m_permutation[(A + 1) & 255] + iz) & 255;
|
|
||||||
|
|
||||||
const std::uint8_t BA = (m_permutation[B] + iz) & 255;
|
|
||||||
const std::uint8_t BB = (m_permutation[(B + 1) & 255] + iz) & 255;
|
|
||||||
|
|
||||||
const value_type p0 = perlin_detail::Grad(m_permutation[AA], fx, fy, fz);
|
|
||||||
const value_type p1 = perlin_detail::Grad(m_permutation[BA], fx - 1, fy, fz);
|
|
||||||
const value_type p2 = perlin_detail::Grad(m_permutation[AB], fx, fy - 1, fz);
|
|
||||||
const value_type p3 = perlin_detail::Grad(m_permutation[BB], fx - 1, fy - 1, fz);
|
|
||||||
const value_type p4 = perlin_detail::Grad(m_permutation[(AA + 1) & 255], fx, fy, fz - 1);
|
|
||||||
const value_type p5 = perlin_detail::Grad(m_permutation[(BA + 1) & 255], fx - 1, fy, fz - 1);
|
|
||||||
const value_type p6 = perlin_detail::Grad(m_permutation[(AB + 1) & 255], fx, fy - 1, fz - 1);
|
|
||||||
const value_type p7 = perlin_detail::Grad(m_permutation[(BB + 1) & 255], fx - 1, fy - 1, fz - 1);
|
|
||||||
|
|
||||||
const value_type q0 = perlin_detail::Lerp(p0, p1, u);
|
|
||||||
const value_type q1 = perlin_detail::Lerp(p2, p3, u);
|
|
||||||
const value_type q2 = perlin_detail::Lerp(p4, p5, u);
|
|
||||||
const value_type q3 = perlin_detail::Lerp(p6, p7, u);
|
|
||||||
|
|
||||||
const value_type r0 = perlin_detail::Lerp(q0, q1, v);
|
|
||||||
const value_type r1 = perlin_detail::Lerp(q2, q3, v);
|
|
||||||
|
|
||||||
return perlin_detail::Lerp(r0, r1, w);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::noise1D_01(const value_type x) const noexcept
|
|
||||||
{
|
|
||||||
return perlin_detail::Remap_01(noise1D(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::noise2D_01(const value_type x, const value_type y) const noexcept
|
|
||||||
{
|
|
||||||
return perlin_detail::Remap_01(noise2D(x, y));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::noise3D_01(const value_type x, const value_type y, const value_type z) const noexcept
|
|
||||||
{
|
|
||||||
return perlin_detail::Remap_01(noise3D(x, y, z));
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::octave1D(const value_type x, const std::int32_t octaves, const value_type persistence) const noexcept
|
|
||||||
{
|
|
||||||
return perlin_detail::Octave1D(*this, x, octaves, persistence);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::octave2D(const value_type x, const value_type y, const std::int32_t octaves, const value_type persistence) const noexcept
|
|
||||||
{
|
|
||||||
return perlin_detail::Octave2D(*this, x, y, octaves, persistence);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::octave3D(const value_type x, const value_type y, const value_type z, const std::int32_t octaves, const value_type persistence) const noexcept
|
|
||||||
{
|
|
||||||
return perlin_detail::Octave3D(*this, x, y, z, octaves, persistence);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::octave1D_11(const value_type x, const std::int32_t octaves, const value_type persistence) const noexcept
|
|
||||||
{
|
|
||||||
return perlin_detail::Clamp_11(octave1D(x, octaves, persistence));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::octave2D_11(const value_type x, const value_type y, const std::int32_t octaves, const value_type persistence) const noexcept
|
|
||||||
{
|
|
||||||
return perlin_detail::Clamp_11(octave2D(x, y, octaves, persistence));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::octave3D_11(const value_type x, const value_type y, const value_type z, const std::int32_t octaves, const value_type persistence) const noexcept
|
|
||||||
{
|
|
||||||
return perlin_detail::Clamp_11(octave3D(x, y, z, octaves, persistence));
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::octave1D_01(const value_type x, const std::int32_t octaves, const value_type persistence) const noexcept
|
|
||||||
{
|
|
||||||
return perlin_detail::RemapClamp_01(octave1D(x, octaves, persistence));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::octave2D_01(const value_type x, const value_type y, const std::int32_t octaves, const value_type persistence) const noexcept
|
|
||||||
{
|
|
||||||
return perlin_detail::RemapClamp_01(octave2D(x, y, octaves, persistence));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::octave3D_01(const value_type x, const value_type y, const value_type z, const std::int32_t octaves, const value_type persistence) const noexcept
|
|
||||||
{
|
|
||||||
return perlin_detail::RemapClamp_01(octave3D(x, y, z, octaves, persistence));
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::normalizedOctave1D(const value_type x, const std::int32_t octaves, const value_type persistence) const noexcept
|
|
||||||
{
|
|
||||||
return (octave1D(x, octaves, persistence) / perlin_detail::MaxAmplitude(octaves, persistence));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::normalizedOctave2D(const value_type x, const value_type y, const std::int32_t octaves, const value_type persistence) const noexcept
|
|
||||||
{
|
|
||||||
return (octave2D(x, y, octaves, persistence) / perlin_detail::MaxAmplitude(octaves, persistence));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::normalizedOctave3D(const value_type x, const value_type y, const value_type z, const std::int32_t octaves, const value_type persistence) const noexcept
|
|
||||||
{
|
|
||||||
return (octave3D(x, y, z, octaves, persistence) / perlin_detail::MaxAmplitude(octaves, persistence));
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::normalizedOctave1D_01(const value_type x, const std::int32_t octaves, const value_type persistence) const noexcept
|
|
||||||
{
|
|
||||||
return perlin_detail::Remap_01(normalizedOctave1D(x, octaves, persistence));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::normalizedOctave2D_01(const value_type x, const value_type y, const std::int32_t octaves, const value_type persistence) const noexcept
|
|
||||||
{
|
|
||||||
return perlin_detail::Remap_01(normalizedOctave2D(x, y, octaves, persistence));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Float>
|
|
||||||
inline typename BasicPerlinNoise<Float>::value_type BasicPerlinNoise<Float>::normalizedOctave3D_01(const value_type x, const value_type y, const value_type z, const std::int32_t octaves, const value_type persistence) const noexcept
|
|
||||||
{
|
|
||||||
return perlin_detail::Remap_01(normalizedOctave3D(x, y, z, octaves, persistence));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# undef SIVPERLIN_NODISCARD_CXX20
|
|
||||||
# undef SIVPERLIN_CONCEPT_URBG
|
|
||||||
# undef SIVPERLIN_CONCEPT_URBG_
|
|
||||||
+150
-81
@@ -9,9 +9,12 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
|
#define FNL_IMPL
|
||||||
|
#include "../FastNoiseLite.h"
|
||||||
|
|
||||||
#define HUMIDITY_OFFSET 12.3f
|
#define HUMIDITY_OFFSET 12.3f
|
||||||
#define CAVE_OFFSET 45.6f
|
#define CAVE_OFFSET 45.6f
|
||||||
#define SCALE 0.01f
|
#define SCALE 0.1f
|
||||||
#define CAVE_COEFF 0.06
|
#define CAVE_COEFF 0.06
|
||||||
#define EDGES_FADE 64
|
#define EDGES_FADE 64
|
||||||
#define CLOUD_SCALE 0.25f
|
#define CLOUD_SCALE 0.25f
|
||||||
@@ -19,7 +22,9 @@
|
|||||||
#define BIOME_FOREST 0
|
#define BIOME_FOREST 0
|
||||||
#define BIOME_TAIGA 1
|
#define BIOME_TAIGA 1
|
||||||
|
|
||||||
static const siv::PerlinNoise perlin;
|
static fnl_state perlin;
|
||||||
|
static fnl_state perlin2;
|
||||||
|
static fnl_state perlinLofi;
|
||||||
|
|
||||||
static int world_type = 0;
|
static int world_type = 0;
|
||||||
|
|
||||||
@@ -31,10 +36,10 @@ std::vector<BlockDef> BLOCKS = {
|
|||||||
BlockDef{ "sand", R_Normal, B_Dirt, 2, 0, 4},
|
BlockDef{ "sand", R_Normal, B_Dirt, 2, 0, 4},
|
||||||
BlockDef{ "water", R_Translucent, B_Stone, 0, 0, 14},
|
BlockDef{ "water", R_Translucent, B_Stone, 0, 0, 14},
|
||||||
BlockDef{ "planks", R_Normal, B_Wood, 3, 0, 11},
|
BlockDef{ "planks", R_Normal, B_Wood, 3, 0, 11},
|
||||||
BlockDef{ "gray_bricks", R_Normal, B_Stone, 5, 1, 16},
|
BlockDef{ "stone_bricks", R_Normal, B_Stone, 5, 1, 16},
|
||||||
BlockDef{ "red_bricks", R_Normal, B_Stone, 5, 1, 17},
|
BlockDef{ "copper_block", R_Normal, B_Stone, 5, 1, 17},
|
||||||
BlockDef{ "blue_bricks", R_Normal, B_Stone, 5, 1, 18},
|
BlockDef{ "silver_block", R_Normal, B_Stone, 5, 1, 18},
|
||||||
BlockDef{ "green_bricks", R_Normal, B_Stone, 5, 1, 19},
|
BlockDef{ "gold_block", R_Normal, B_Stone, 5, 1, 19},
|
||||||
BlockDef{ "glass", R_Translucent, B_Stone, 3, 1, 12},
|
BlockDef{ "glass", R_Translucent, B_Stone, 3, 1, 12},
|
||||||
BlockDef{ "log", R_TriSide, B_Wood, 5, 0, 10, 9, 10},
|
BlockDef{ "log", R_TriSide, B_Wood, 5, 0, 10, 9, 10},
|
||||||
BlockDef{ "spruce_planks", R_Normal, B_Wood, 3, 0, 13},
|
BlockDef{ "spruce_planks", R_Normal, B_Wood, 3, 0, 13},
|
||||||
@@ -67,24 +72,38 @@ int GetNumericIDFromString(std::string s) {
|
|||||||
}
|
}
|
||||||
static std::bitset<256> marked;
|
static std::bitset<256> marked;
|
||||||
|
|
||||||
static int GetBlockRegularWorld(int x, int y, int z) {
|
static int GetBlockRegularWorld(int _x, int y, int _z) {
|
||||||
float fade_x = (fmax(EDGES_FADE - x, 0) + fmax(EDGES_FADE - WORLD_SIZE_BLOCKS + x, 0)) / (float)EDGES_FADE;
|
int x = _x + 0;
|
||||||
float fade_z = (fmax(EDGES_FADE - z, 0) + fmax(EDGES_FADE - WORLD_SIZE_BLOCKS + z, 0)) / (float)EDGES_FADE;
|
int z = _z + 0;
|
||||||
float fade = 1 - (fade_x + fade_z);
|
const int SEA_HEIGHT = 64;
|
||||||
|
const int BEACH_DEPTH = 3;
|
||||||
|
const float heightBias = 24;
|
||||||
|
float p0 = fnlGetNoise3D(&perlin, (float)x, y / 2.0f, z);
|
||||||
|
float p1 = fnlGetNoise3D(&perlin2, x, y / 2.0f, z);
|
||||||
|
float pr = fnlGetNoise3D(&perlinLofi, x, y / 2.0f, z)*12.75f;
|
||||||
|
float P = 0;
|
||||||
|
if(pr >= 1) P = p1;
|
||||||
|
if(pr <= 0) P = p0;
|
||||||
|
if(pr>0&&pr<1) P = Lerp(p0, p1, pr);
|
||||||
|
float density = P + (WORLD_HEIGHT-(y+60)) / heightBias;
|
||||||
|
if(density > 0.5f) {
|
||||||
|
return BLOCK_STONE;
|
||||||
|
}
|
||||||
|
if(density > 0) {
|
||||||
|
return BLOCK_DIRT;
|
||||||
|
}
|
||||||
|
if(y < SEA_HEIGHT) {
|
||||||
|
return BLOCK_WATERS;
|
||||||
|
}
|
||||||
|
//float height0 = (fnlGetNoise3D(&perlin, x, y, z) + 1.0f ) / 2.0f * 8.0f;
|
||||||
|
//float height1 = (fnlGetNoise3D(&perlin2, x, y, z) + 1.0f ) / 2.0f * 16.0f;
|
||||||
|
|
||||||
const int SEA_HEIGHT = 32; // sea surface y
|
//int height = Lerp(height0, height1, fnlGetNoise2D(&perlinLofi, x, z)) + 26 + 48;
|
||||||
const int BEACH_DEPTH = 3; // how many blocks below surface become sand
|
//float dist = Vector2Distance({(float)x, (float)z}, {MAX_WORLD_SIZE*CHUNK_SIZE/2, MAX_WORLD_SIZE*CHUNK_SIZE/2});
|
||||||
|
|
||||||
float height0 = (perlin.noise2D((double)x * 1.5f * SCALE, (double)z * 1.5f * SCALE) + 1.0f ) / 2.0f * 16.0f;
|
//height = Lerp(32, height, fmin(1.0f, -fmin(0.0f, dist - (MAX_WORLD_SIZE*CHUNK_SIZE/2)-48)/96.0f));
|
||||||
float mountains = pow((perlin.noise2D((double)x * 0.5f, (double)z * 0.5f * SCALE) + 1.0f ) / 2.0f, 16);
|
/*if (y <= height) {
|
||||||
float height1 = (perlin.noise2D((double)x * 4.5f * SCALE, (double)z * 4.5f * SCALE) + 1.0f ) / 2.0f * 24.0f * mountains;
|
//if(caveNoise < 0.02f) return BLOCK_AIR;
|
||||||
|
|
||||||
int height = floor((height0 + height1) * fade) + 26;
|
|
||||||
|
|
||||||
float caveNoise = fabs(perlin.noise3D((double)x * 1.0f * SCALE + CAVE_OFFSET, (double)y * 4.0f * SCALE + CAVE_OFFSET, (double)z * 1.0f * SCALE + CAVE_OFFSET));
|
|
||||||
|
|
||||||
if (y <= height) {
|
|
||||||
if(caveNoise < 0.02f) return BLOCK_AIR;
|
|
||||||
if (y == height) {
|
if (y == height) {
|
||||||
if (height <= SEA_HEIGHT) {
|
if (height <= SEA_HEIGHT) {
|
||||||
return BLOCK_SAND;
|
return BLOCK_SAND;
|
||||||
@@ -96,13 +115,13 @@ static int GetBlockRegularWorld(int x, int y, int z) {
|
|||||||
if (y > height - BEACH_DEPTH && height <= SEA_HEIGHT + 2) {
|
if (y > height - BEACH_DEPTH && height <= SEA_HEIGHT + 2) {
|
||||||
return BLOCK_SAND;
|
return BLOCK_SAND;
|
||||||
}
|
}
|
||||||
if(caveNoise < 0.2f || y < 4) return BLOCK_STONE;
|
//if(caveNoise < 0.2f || y < 4) return BLOCK_STONE;
|
||||||
return BLOCK_DIRT;
|
return BLOCK_DIRT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y <= SEA_HEIGHT && height < SEA_HEIGHT) {
|
if (y <= SEA_HEIGHT && height < SEA_HEIGHT) {
|
||||||
return BLOCK_WATERS;
|
return BLOCK_WATERS;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
return BLOCK_AIR;
|
return BLOCK_AIR;
|
||||||
}
|
}
|
||||||
@@ -162,6 +181,7 @@ int GetBLight(World &world, int x, int y, int z) {
|
|||||||
int skyLight = light & 0xF;
|
int skyLight = light & 0xF;
|
||||||
return skyLight;
|
return skyLight;
|
||||||
}
|
}
|
||||||
|
Color GetSunlightColor();
|
||||||
Color GetLight(World &world, int x, int y, int z) {
|
Color GetLight(World &world, int x, int y, int z) {
|
||||||
if(CheckOOBWorld(x, y, z)) return {0, 0, 0, 0};
|
if(CheckOOBWorld(x, y, z)) return {0, 0, 0, 0};
|
||||||
int locX = x % CHUNK_SIZE;
|
int locX = x % CHUNK_SIZE;
|
||||||
@@ -173,24 +193,41 @@ Color GetLight(World &world, int x, int y, int z) {
|
|||||||
Color r = {((light >> 8) & 0xF) * 16, 0, 0, 255};
|
Color r = {((light >> 8) & 0xF) * 16, 0, 0, 255};
|
||||||
Color g = {0, ((light >> 4) & 0xF) * 16, 0, 255};
|
Color g = {0, ((light >> 4) & 0xF) * 16, 0, 255};
|
||||||
Color b = {0, 0, ((light >> 0) & 0xF) * 16, 255};
|
Color b = {0, 0, ((light >> 0) & 0xF) * 16, 255};
|
||||||
|
Color sun = GetSunlightColor();
|
||||||
return {
|
return {
|
||||||
fmin((int)skyLight + (int)r.r, 255),
|
fmax((int)skyLight * (sun.r/255.0f), (int)r.r),
|
||||||
fmin((int)skyLight + (int)g.g, 255),
|
fmax((int)skyLight * (sun.g/255.0f), (int)g.g),
|
||||||
fmin((int)skyLight + (int)b.b, 255),
|
fmax((int)skyLight * (sun.b/255.0f), (int)b.b),
|
||||||
255
|
255
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Color GetLightMesher(World &world, int x, int y, int z) {
|
||||||
|
if(CheckOOBWorld(x, y, z)) return {0, 0, 0, 0};
|
||||||
|
int locX = x % CHUNK_SIZE;
|
||||||
|
int locZ = z % CHUNK_SIZE;
|
||||||
|
int cx = x / CHUNK_SIZE;
|
||||||
|
int cz = z / CHUNK_SIZE;
|
||||||
|
uint16_t light = world.chunks[GetIndexWorld(cx, cz)].light[GetIndexChunk(locX, y, locZ)];
|
||||||
|
int skyLight = powf(((light >> 12) & 0xF) / 15.0f, 1) * 255;
|
||||||
|
return {
|
||||||
|
((light >> 8) & 0xF) * 16,
|
||||||
|
((light >> 4) & 0xF) * 16,
|
||||||
|
((light >> 0) & 0xF) * 16,
|
||||||
|
skyLight
|
||||||
|
};
|
||||||
|
}
|
||||||
bool CanTick(int blockType) { // TODO: make smarter in case other blocks can tick too!
|
bool CanTick(int blockType) { // TODO: make smarter in case other blocks can tick too!
|
||||||
return blockType == BLOCK_SAND;
|
return blockType == BLOCK_SAND;
|
||||||
}
|
}
|
||||||
bool GetCloud(int x, int z) {
|
bool GetCloud(int x, int z) {
|
||||||
return (perlin.noise2D((x / 8) * 1.5f * CLOUD_SCALE, (z / 8) * 1.5f * CLOUD_SCALE) + 1.0f) / 2.0f > 0.5f;
|
//return (perlin.noise2D((x / 8) * 1.5f * CLOUD_SCALE, (z / 8) * 1.5f * CLOUD_SCALE) + 1.0f) / 2.0f > 0.5f;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
static int GetBlockCaveWorld(int x, int y, int z) {
|
static int GetBlockCaveWorld(int x, int y, int z) {
|
||||||
float caveNoise = (perlin.noise3D((float)x * 3.0f * SCALE + CAVE_OFFSET, (float)y * 3.0f * SCALE + CAVE_OFFSET, (float)z * 3.0f * SCALE + CAVE_OFFSET) + 1.0f) / 2.0f;
|
/*float caveNoise = (perlin.noise3D((float)x * 3.0f * SCALE + CAVE_OFFSET, (float)y * 3.0f * SCALE + CAVE_OFFSET, (float)z * 3.0f * SCALE + CAVE_OFFSET) + 1.0f) / 2.0f;
|
||||||
if(caveNoise > 0.5f) {
|
if(caveNoise > 0.5f) {
|
||||||
return BLOCK_STONE;
|
return BLOCK_STONE;
|
||||||
}
|
}*/
|
||||||
return BLOCK_AIR;
|
return BLOCK_AIR;
|
||||||
}
|
}
|
||||||
static int has_block(int x, int y, int z)
|
static int has_block(int x, int y, int z)
|
||||||
@@ -311,8 +348,24 @@ void SetLight(World &world, int x, int y, int z, uint8_t sky, uint8_t r, uint8_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
void InitWorldgen(int worldType) {
|
void InitWorldgen(int worldType) {
|
||||||
const siv::PerlinNoise::seed_type seed = 0u;
|
perlin = fnlCreateState();
|
||||||
const siv::PerlinNoise perlin{ seed };
|
perlin.noise_type = FNL_NOISE_OPENSIMPLEX2;
|
||||||
|
perlin.fractal_type = FNL_FRACTAL_FBM;
|
||||||
|
perlin.frequency = 0.00522f;
|
||||||
|
perlin.octaves = 8;
|
||||||
|
|
||||||
|
perlinLofi = fnlCreateState();
|
||||||
|
perlinLofi.noise_type = FNL_NOISE_OPENSIMPLEX2;
|
||||||
|
perlinLofi.fractal_type = FNL_FRACTAL_FBM;
|
||||||
|
perlinLofi.frequency = 0.01671f;
|
||||||
|
perlinLofi.octaves = 4;
|
||||||
|
|
||||||
|
perlin2 = fnlCreateState();
|
||||||
|
perlin2.noise_type = FNL_NOISE_OPENSIMPLEX2;
|
||||||
|
perlin2.fractal_type = FNL_FRACTAL_FBM;
|
||||||
|
perlin2.frequency = 0.00522f;
|
||||||
|
perlin2.octaves = 8;
|
||||||
|
|
||||||
constexpr size_t MAX = 128; // allowed range: 0..MAX-1
|
constexpr size_t MAX = 128; // allowed range: 0..MAX-1
|
||||||
for (int i = 0; i < BLOCKS.size(); i++)
|
for (int i = 0; i < BLOCKS.size(); i++)
|
||||||
{
|
{
|
||||||
@@ -332,16 +385,11 @@ Chunk GenerateChunk(int _x, int _y) {
|
|||||||
new_chunk.x = _x;
|
new_chunk.x = _x;
|
||||||
new_chunk.z = _y;
|
new_chunk.z = _y;
|
||||||
memset(&new_chunk.light, 0, sizeof(new_chunk.light));
|
memset(&new_chunk.light, 0, sizeof(new_chunk.light));
|
||||||
|
for (int y = 0; y < WORLD_HEIGHT; y++)
|
||||||
for (int x = 0; x < CHUNK_SIZE; x++)
|
for (int x = 0; x < CHUNK_SIZE; x++)
|
||||||
{
|
for (int z = 0; z < CHUNK_SIZE; z++) {
|
||||||
for (int y = 0; y < WORLD_HEIGHT; y++)
|
int id = has_block(_x * CHUNK_SIZE + x,y,_y * CHUNK_SIZE + z);
|
||||||
{
|
SetBlockChunk(&new_chunk, x, y, z, id);
|
||||||
for (int z = 0; z < CHUNK_SIZE; z++)
|
|
||||||
{
|
|
||||||
int id = has_block(_x * CHUNK_SIZE + x,y,_y * CHUNK_SIZE + z);
|
|
||||||
SetBlockChunk(&new_chunk, x, y, z, id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return new_chunk;
|
return new_chunk;
|
||||||
}
|
}
|
||||||
@@ -357,33 +405,8 @@ void GenerateWorldAdditional(World &world) {
|
|||||||
Chunk c = world.chunks[GetIndexWorld(x / CHUNK_SIZE, z / CHUNK_SIZE)];
|
Chunk c = world.chunks[GetIndexWorld(x / CHUNK_SIZE, z / CHUNK_SIZE)];
|
||||||
int highestY = c.highestBlock[GetIndexChunk2D(x % CHUNK_SIZE, z % CHUNK_SIZE)];
|
int highestY = c.highestBlock[GetIndexChunk2D(x % CHUNK_SIZE, z % CHUNK_SIZE)];
|
||||||
int b = fetch_block(c, x % CHUNK_SIZE, highestY, z % CHUNK_SIZE);
|
int b = fetch_block(c, x % CHUNK_SIZE, highestY, z % CHUNK_SIZE);
|
||||||
for (int _ = 0; _ < GetRandomValue(0, 6); _++)
|
if(b == BLOCK_DIRT) {
|
||||||
{
|
SetBlock(world, x, highestY, z, BLOCK_GRASS);
|
||||||
if(GetRandomValue(0, 800) == 0) {
|
|
||||||
int max = GetRandomValue(10, 120);
|
|
||||||
Vector3 pos = {x, GetRandomValue(12, WORLD_HEIGHT-32), z};
|
|
||||||
Vector3 direction = {GetRandomValue(-100, 100) / 100.0f, GetRandomValue(-100, -5) / 100.0f, GetRandomValue(-100, 100) / 100.0f};
|
|
||||||
int radius = 2;
|
|
||||||
for (int _ = 0; _ < max; _++)
|
|
||||||
{
|
|
||||||
for (int x = -radius; x < radius; x++)
|
|
||||||
{
|
|
||||||
for (int y = -radius; y < radius; y++)
|
|
||||||
{
|
|
||||||
for (int z = -radius; z < radius; z++)
|
|
||||||
{
|
|
||||||
if(Vector3Distance({pos.x + x, pos.y + y, pos.z + z}, pos) <= radius) {
|
|
||||||
if(!CheckOOBWorld(pos.x + x, pos.y + y, pos.z + z)) {
|
|
||||||
SetBlock(world, pos.x + x, pos.y + y, pos.z + z, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
direction += {GetRandomValue(-100, 100) / 100.0f, GetRandomValue(-100, -5) / 100.0f, GetRandomValue(-100, 100) / 100.0f};
|
|
||||||
pos += direction;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (int _ = 0; _ < GetRandomValue(8, 24); _++)
|
for (int _ = 0; _ < GetRandomValue(8, 24); _++)
|
||||||
{
|
{
|
||||||
@@ -424,7 +447,7 @@ void GenerateWorldAdditional(World &world) {
|
|||||||
Chunk c = world.chunks[GetIndexWorld(x / CHUNK_SIZE, z / CHUNK_SIZE)];
|
Chunk c = world.chunks[GetIndexWorld(x / CHUNK_SIZE, z / CHUNK_SIZE)];
|
||||||
int highestY = c.highestBlock[GetIndexChunk2D(x % CHUNK_SIZE, z % CHUNK_SIZE)];
|
int highestY = c.highestBlock[GetIndexChunk2D(x % CHUNK_SIZE, z % CHUNK_SIZE)];
|
||||||
int b = fetch_block(c, x % CHUNK_SIZE, highestY, z % CHUNK_SIZE);
|
int b = fetch_block(c, x % CHUNK_SIZE, highestY, z % CHUNK_SIZE);
|
||||||
if(b == BLOCK_GRASS && GetRandomValue(0, 100) < 4 && biome == BIOME_FOREST) { // Regular trees
|
if(b == BLOCK_GRASS && GetRandomValue(0, 100) == 0 && biome == BIOME_FOREST) { // Regular trees
|
||||||
SetBlock(world, x, highestY, z, BLOCK_DIRT);
|
SetBlock(world, x, highestY, z, BLOCK_DIRT);
|
||||||
int maxY = GetRandomValue(5, 7);
|
int maxY = GetRandomValue(5, 7);
|
||||||
for (int y = 1; y < maxY; y++)
|
for (int y = 1; y < maxY; y++)
|
||||||
@@ -441,7 +464,7 @@ void GenerateWorldAdditional(World &world) {
|
|||||||
SetBlock(world, x, wy, z, 12); // log
|
SetBlock(world, x, wy, z, 12); // log
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(b == BLOCK_GRASS && GetRandomValue(0, 100) < 2 && biome == BIOME_TAIGA) { // Spruce
|
if(b == BLOCK_GRASS && GetRandomValue(0, 100) == 0 && biome == BIOME_TAIGA) { // Spruce
|
||||||
SetBlock(world, x, highestY, z, BLOCK_DIRT);
|
SetBlock(world, x, highestY, z, BLOCK_DIRT);
|
||||||
int maxY = 8;
|
int maxY = 8;
|
||||||
for (int y = 1; y < maxY; y++)
|
for (int y = 1; y < maxY; y++)
|
||||||
@@ -658,7 +681,6 @@ void RebuildLighting(World &world, int startX, int startZ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::cout << nodes.size() << std::endl;
|
|
||||||
while (!nodes.empty()) {
|
while (!nodes.empty()) {
|
||||||
LightNode node = nodes.front();
|
LightNode node = nodes.front();
|
||||||
nodes.pop();
|
nodes.pop();
|
||||||
@@ -696,7 +718,6 @@ void RebuildLighting(World &world, int startX, int startZ) {
|
|||||||
if (CheckOOBWorld(x, y, z)) continue;
|
if (CheckOOBWorld(x, y, z)) continue;
|
||||||
if(chunk.blocks[i] != 18 && chunk.blocks[i] != 21) continue;
|
if(chunk.blocks[i] != 18 && chunk.blocks[i] != 21) continue;
|
||||||
Vector3I pos = { x + chunk.x * CHUNK_SIZE, y, z + chunk.z * CHUNK_SIZE };
|
Vector3I pos = { x + chunk.x * CHUNK_SIZE, y, z + chunk.z * CHUNK_SIZE };
|
||||||
std::cout << pos.y << std::endl;
|
|
||||||
LightNode node{pos, 15};
|
LightNode node{pos, 15};
|
||||||
nodesR.push(node);
|
nodesR.push(node);
|
||||||
}
|
}
|
||||||
@@ -704,7 +725,6 @@ void RebuildLighting(World &world, int startX, int startZ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (!nodesR.empty()) {
|
while (!nodesR.empty()) {
|
||||||
std::cout << nodesR.size() << std::endl;
|
|
||||||
LightNode node = nodesR.front();
|
LightNode node = nodesR.front();
|
||||||
nodesR.pop();
|
nodesR.pop();
|
||||||
|
|
||||||
@@ -741,7 +761,6 @@ void RebuildLighting(World &world, int startX, int startZ) {
|
|||||||
if (CheckOOBWorld(x, y, z)) continue;
|
if (CheckOOBWorld(x, y, z)) continue;
|
||||||
if(chunk.blocks[i] != 19 && chunk.blocks[i] != 21) continue;
|
if(chunk.blocks[i] != 19 && chunk.blocks[i] != 21) continue;
|
||||||
Vector3I pos = { x + chunk.x * CHUNK_SIZE, y, z + chunk.z * CHUNK_SIZE };
|
Vector3I pos = { x + chunk.x * CHUNK_SIZE, y, z + chunk.z * CHUNK_SIZE };
|
||||||
std::cout << pos.y << std::endl;
|
|
||||||
LightNode node{pos, 15};
|
LightNode node{pos, 15};
|
||||||
nodesG.push(node);
|
nodesG.push(node);
|
||||||
}
|
}
|
||||||
@@ -749,7 +768,6 @@ void RebuildLighting(World &world, int startX, int startZ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (!nodesG.empty()) {
|
while (!nodesG.empty()) {
|
||||||
std::cout << nodesG.size() << std::endl;
|
|
||||||
LightNode node = nodesG.front();
|
LightNode node = nodesG.front();
|
||||||
nodesG.pop();
|
nodesG.pop();
|
||||||
|
|
||||||
@@ -786,7 +804,6 @@ void RebuildLighting(World &world, int startX, int startZ) {
|
|||||||
if (CheckOOBWorld(x, y, z)) continue;
|
if (CheckOOBWorld(x, y, z)) continue;
|
||||||
if(chunk.blocks[i] != 20 && chunk.blocks[i] != 21) continue;
|
if(chunk.blocks[i] != 20 && chunk.blocks[i] != 21) continue;
|
||||||
Vector3I pos = { x + chunk.x * CHUNK_SIZE, y, z + chunk.z * CHUNK_SIZE };
|
Vector3I pos = { x + chunk.x * CHUNK_SIZE, y, z + chunk.z * CHUNK_SIZE };
|
||||||
std::cout << pos.y << std::endl;
|
|
||||||
LightNode node{pos, 15};
|
LightNode node{pos, 15};
|
||||||
nodesB.push(node);
|
nodesB.push(node);
|
||||||
}
|
}
|
||||||
@@ -794,7 +811,6 @@ void RebuildLighting(World &world, int startX, int startZ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (!nodesB.empty()) {
|
while (!nodesB.empty()) {
|
||||||
std::cout << nodesB.size() << std::endl;
|
|
||||||
LightNode node = nodesB.front();
|
LightNode node = nodesB.front();
|
||||||
nodesB.pop();
|
nodesB.pop();
|
||||||
|
|
||||||
@@ -887,6 +903,55 @@ ChunkRenderData GenerateCRDTranslucent(Chunk chunk, World &world) {
|
|||||||
new_chunk.sides[i2] = 0xFF;
|
new_chunk.sides[i2] = 0xFF;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if(BLOCKS[fetch_block(chunk, _x, y, _z)].name == "water") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int x = _x + chunk.x * CHUNK_SIZE;
|
||||||
|
int z = _z + chunk.z * CHUNK_SIZE;
|
||||||
|
bool l = (_x > 0) ? !TestMask(mask, i2-1) : !TestAirMaskWorld(world, x - 1, y, z);
|
||||||
|
bool r = (_x < CHUNK_SIZE-1) ? !TestMask(mask, i2+1) : !TestAirMaskWorld(world, x + 1, y, z);
|
||||||
|
bool u = (y==WORLD_HEIGHT-1) ? false : !TestMask(mask, i2+CHUNK_SIZE_SQR);
|
||||||
|
bool d = (y==0) ? true : !TestMask(mask, i2-CHUNK_SIZE_SQR);
|
||||||
|
bool b = (_z==0) ? !TestAirMaskWorld(world, x, y, z - 1) : !TestMask(mask, i2-CHUNK_SIZE);
|
||||||
|
bool f = (_z==CHUNK_SIZE-1) ? !TestAirMaskWorld(world, x, y, z + 1) : !TestMask(mask, i2+CHUNK_SIZE);
|
||||||
|
new_chunk.sides[i2] = pack6(
|
||||||
|
!l,
|
||||||
|
!r,
|
||||||
|
!u,
|
||||||
|
!d,
|
||||||
|
!b,
|
||||||
|
!f
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new_chunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Generates a CRD for water (ChunkRenderData). Outputs the CRD.
|
||||||
|
ChunkRenderData GenerateCRDWater(Chunk chunk, World &world) {
|
||||||
|
struct ChunkRenderData new_chunk = { 0 };
|
||||||
|
uint16_t *mask0= chunk.opaqueMask;
|
||||||
|
uint16_t *mask = chunk.airMask;
|
||||||
|
for (int step = 0; step < CHUNK_DATA_SIZE/16; ++step)
|
||||||
|
{
|
||||||
|
uint16_t m = ~(mask[step]);
|
||||||
|
if(m == 0) continue;
|
||||||
|
|
||||||
|
while (m) {
|
||||||
|
int bit = __builtin_ctz(m);
|
||||||
|
m &= m - 1;
|
||||||
|
int i2 = (step<<4) + bit;
|
||||||
|
int _x = bit;
|
||||||
|
int y = step >> 4;
|
||||||
|
int _z = step & 0xF;
|
||||||
|
|
||||||
|
if (TestMask(mask0, i2)) {
|
||||||
|
new_chunk.sides[i2] = 0;
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
if(BLOCKS[fetch_block(chunk, _x, y, _z)].name != "water") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
int x = _x + chunk.x * CHUNK_SIZE;
|
int x = _x + chunk.x * CHUNK_SIZE;
|
||||||
int z = _z + chunk.z * CHUNK_SIZE;
|
int z = _z + chunk.z * CHUNK_SIZE;
|
||||||
bool l = (_x > 0) ? !TestMask(mask, i2-1) : !TestAirMaskWorld(world, x - 1, y, z);
|
bool l = (_x > 0) ? !TestMask(mask, i2-1) : !TestAirMaskWorld(world, x - 1, y, z);
|
||||||
@@ -957,6 +1022,7 @@ void SaveWorld(World &world, const char* path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Debug_Write(const std::string &stuff);
|
void Debug_Write(const std::string &stuff);
|
||||||
|
|
||||||
bool LoadWorld(World &world, const char* path) {
|
bool LoadWorld(World &world, const char* path) {
|
||||||
std::ifstream data(path, std::ios::binary);
|
std::ifstream data(path, std::ios::binary);
|
||||||
if (!data) return false;
|
if (!data) return false;
|
||||||
@@ -986,19 +1052,22 @@ bool LoadWorld(World &world, const char* path) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Chunk *c = &world.chunks[i];
|
Chunk c = {0};
|
||||||
|
c.x = i % 16;
|
||||||
|
c.z = i >> 4;
|
||||||
int outIndex = 0;
|
int outIndex = 0;
|
||||||
for (size_t p = 0; p + 1 < size; p += 2) {
|
for (size_t p = 0; p + 1 < size; p += 2) {
|
||||||
uint8_t count = temp[p];
|
uint8_t count = temp[p];
|
||||||
uint8_t value = temp[p + 1];
|
uint8_t value = temp[p + 1];
|
||||||
for (uint8_t k = 0; k < count; ++k) {
|
for (uint8_t k = 0; k < count; ++k) {
|
||||||
SetBlockChunkFast(c, outIndex++, value);
|
SetBlockChunkFast(&c, outIndex++, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (outIndex < CHUNK_DATA_SIZE) {
|
while (outIndex < CHUNK_DATA_SIZE) {
|
||||||
SetBlockChunkFast(c, outIndex++, 0);
|
SetBlockChunkFast(&c, outIndex++, 0);
|
||||||
}
|
}
|
||||||
RebuildHeightmap(*c);
|
RebuildHeightmap(c);
|
||||||
|
memcpy(&world.chunks[i], &c, sizeof(c));
|
||||||
}
|
}
|
||||||
free(temp);
|
free(temp);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
+11
-5
@@ -11,7 +11,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include "glfw_keycodes_to_string.h"
|
#include "glfw_keycodes_to_string.h"
|
||||||
#include "../PerlinNoise.hpp"
|
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
#include "raymath.h"
|
#include "raymath.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@@ -76,9 +75,9 @@
|
|||||||
#define GAME_NAME "CubeGame"
|
#define GAME_NAME "CubeGame"
|
||||||
#define GAME_VERSION_INT 0
|
#define GAME_VERSION_INT 0
|
||||||
#define DEFAULT_FONT_SIZE 16
|
#define DEFAULT_FONT_SIZE 16
|
||||||
#define TPS 30.0
|
#define TPS 30
|
||||||
#define TPS_DIV 1.0 / TPS
|
#define TPS_DIV 1.0 / TPS
|
||||||
#define RENDER_DISTANCE 5
|
#define RENDER_DISTANCE 16
|
||||||
#define RENDER_DISTANCE_SQUARED RENDER_DISTANCE*RENDER_DISTANCE
|
#define RENDER_DISTANCE_SQUARED RENDER_DISTANCE*RENDER_DISTANCE
|
||||||
#define MAX_HP 100
|
#define MAX_HP 100
|
||||||
#define PATH_APPEND "resources/"
|
#define PATH_APPEND "resources/"
|
||||||
@@ -87,6 +86,8 @@
|
|||||||
#define INVENTORY_WIDTH 8
|
#define INVENTORY_WIDTH 8
|
||||||
#define INVENTORY_HEIGHT 6
|
#define INVENTORY_HEIGHT 6
|
||||||
#define INVENTORY_SIZE INVENTORY_WIDTH*INVENTORY_HEIGHT
|
#define INVENTORY_SIZE INVENTORY_WIDTH*INVENTORY_HEIGHT
|
||||||
|
#define WORLD_TIME_SECONDS (24*60)
|
||||||
|
#define WORLD_TIME_TICKS WORLD_TIME_SECONDS*TPS
|
||||||
enum BlockType {
|
enum BlockType {
|
||||||
B_Wood,
|
B_Wood,
|
||||||
B_Stone,
|
B_Stone,
|
||||||
@@ -311,7 +312,9 @@ int GetSkyLight(World&world,int x,int y,int z);
|
|||||||
int GetRLight(World&world,int x,int y,int z);
|
int GetRLight(World&world,int x,int y,int z);
|
||||||
int GetGLight(World&world,int x,int y,int z);
|
int GetGLight(World&world,int x,int y,int z);
|
||||||
int GetBLight(World&world,int x,int y,int z);
|
int GetBLight(World&world,int x,int y,int z);
|
||||||
|
Color GetSunlightColor();
|
||||||
Color GetLight(World&world,int x,int y,int z);
|
Color GetLight(World&world,int x,int y,int z);
|
||||||
|
Color GetLightMesher(World&world,int x,int y,int z);
|
||||||
bool CanTick(int blockType);
|
bool CanTick(int blockType);
|
||||||
bool GetCloud(int x,int z);
|
bool GetCloud(int x,int z);
|
||||||
bool IsTranslucent(int blockType);
|
bool IsTranslucent(int blockType);
|
||||||
@@ -333,6 +336,7 @@ void RebuildLighting(World&world,int startX,int startZ);
|
|||||||
#if !defined(SERVER)
|
#if !defined(SERVER)
|
||||||
ChunkRenderData GenerateCRDOpaque(Chunk&chunk,World&world);
|
ChunkRenderData GenerateCRDOpaque(Chunk&chunk,World&world);
|
||||||
ChunkRenderData GenerateCRDTranslucent(Chunk chunk,World&world);
|
ChunkRenderData GenerateCRDTranslucent(Chunk chunk,World&world);
|
||||||
|
ChunkRenderData GenerateCRDWater(Chunk chunk,World&world);
|
||||||
#endif
|
#endif
|
||||||
void SaveWorld(World&world,const char *path);
|
void SaveWorld(World&world,const char *path);
|
||||||
bool LoadWorld(World&world,const char *path);
|
bool LoadWorld(World&world,const char *path);
|
||||||
@@ -444,10 +448,12 @@ const char *Pathify(const char *src);
|
|||||||
const char *PathifyUser(const char *src);
|
const char *PathifyUser(const char *src);
|
||||||
#if !defined(SERVER)
|
#if !defined(SERVER)
|
||||||
void DrawCubeTexture(Texture2D texture,Vector3 position,float width,float height,float length,Color color,int offsetX,int offsetY,int sizeX,int sizeY);
|
void DrawCubeTexture(Texture2D texture,Vector3 position,float width,float height,float length,Color color,int offsetX,int offsetY,int sizeX,int sizeY);
|
||||||
void DrawCubeBlock(Texture2D texture,Vector3 position,float width,float height,float length,BlockDef def);
|
void DrawCubeBlock(Texture2D texture,Vector3 position,float width,float height,float length,BlockDef def,Color tint);
|
||||||
void DrawTextCodepoint3D(Font font,int codepoint,Vector3 position,float fontSize,bool backface,Color tint);
|
void DrawTextCodepoint3D(Font font,int codepoint,Vector3 position,float fontSize,bool backface,Color tint);
|
||||||
void DrawText3D(Font font,const char *text,Vector3 position,float fontSize,float fontSpacing,float lineSpacing,bool backface,Color tint);
|
void DrawText3D(Font font,const char *text,Vector3 position,float fontSize,float fontSpacing,float lineSpacing,bool backface,Color tint);
|
||||||
#endif
|
#endif
|
||||||
|
RenderTexture2D LoadRenderTextureDepthTex(int width,int height);
|
||||||
|
void UnloadRenderTextureDepthTex(RenderTexture2D target);
|
||||||
inline uint8_t pack6(bool b0,bool b1,bool b2,bool b3,bool b4,bool b5){
|
inline uint8_t pack6(bool b0,bool b1,bool b2,bool b3,bool b4,bool b5){
|
||||||
return (uint8_t)(
|
return (uint8_t)(
|
||||||
((uint8_t)(b0 ? 1 : 0) << 0) |
|
((uint8_t)(b0 ? 1 : 0) << 0) |
|
||||||
@@ -619,7 +625,7 @@ void HotbarAddItemLots(Item *registry,int damage,int amount);
|
|||||||
void InitHotbar();
|
void InitHotbar();
|
||||||
void DrawHotbar();
|
void DrawHotbar();
|
||||||
InventoryItem HotbarGetSelected();
|
InventoryItem HotbarGetSelected();
|
||||||
void DrawSelectedItem();
|
void DrawSelectedItem(Color tint);
|
||||||
void CloseInventory();
|
void CloseInventory();
|
||||||
void UpdateHotbar();
|
void UpdateHotbar();
|
||||||
void LocaleUpdate();
|
void LocaleUpdate();
|
||||||
|
|||||||
@@ -363,7 +363,7 @@ void DrawEntities(float dt) {
|
|||||||
DrawCube(pos_lerped, 1, 1, 1, RED);
|
DrawCube(pos_lerped, 1, 1, 1, RED);
|
||||||
}
|
}
|
||||||
if(ent.type == 4) {
|
if(ent.type == 4) {
|
||||||
DrawCubeBlock(terrain, pos_lerped, 1,1,1, GetBlockDefinition(ent.data[1]));
|
DrawCubeBlock(terrain, pos_lerped, 1,1,1, GetBlockDefinition(ent.data[1]), WHITE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ Vector2 InputGetWalkAxis() {
|
|||||||
float y = 0;
|
float y = 0;
|
||||||
if(isJoystick) {
|
if(isJoystick) {
|
||||||
x = GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X);
|
x = GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X);
|
||||||
y = GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_Y);
|
y = -GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_Y);
|
||||||
if(abs(x) < 0.5f) {
|
if(abs(x) < 0.5f) {
|
||||||
x = 0;
|
x = 0;
|
||||||
}
|
}
|
||||||
@@ -84,8 +84,8 @@ Vector2 InputGetLookAxis() {
|
|||||||
float x = 0;
|
float x = 0;
|
||||||
float y = 0;
|
float y = 0;
|
||||||
if(isJoystick) {
|
if(isJoystick) {
|
||||||
x = GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_X);
|
x = GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_X)*3.0f;
|
||||||
y = GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_Y);
|
y = GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_Y)*3.0f;
|
||||||
if(abs(x) < 0.1f) {
|
if(abs(x) < 0.1f) {
|
||||||
x = 0;
|
x = 0;
|
||||||
}
|
}
|
||||||
@@ -108,6 +108,7 @@ Vector2 InputGetDPAD() {
|
|||||||
if (IsGamepadButtonPressed(0, GAMEPAD_BUTTON_LEFT_FACE_RIGHT)) { x = 1; }
|
if (IsGamepadButtonPressed(0, GAMEPAD_BUTTON_LEFT_FACE_RIGHT)) { x = 1; }
|
||||||
if (IsGamepadButtonPressed(0, GAMEPAD_BUTTON_LEFT_FACE_LEFT)) { x = -1; }
|
if (IsGamepadButtonPressed(0, GAMEPAD_BUTTON_LEFT_FACE_LEFT)) { x = -1; }
|
||||||
}
|
}
|
||||||
|
|
||||||
return {x, y};
|
return {x, y};
|
||||||
}
|
}
|
||||||
void InputWriteControls() {
|
void InputWriteControls() {
|
||||||
@@ -136,7 +137,6 @@ void InputInit() {
|
|||||||
controls[key] = val;
|
controls[key] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
swap_mouse = config["Swap mouse buttons"].as<bool>();
|
swap_mouse = config["Swap mouse buttons"].as<bool>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -441,7 +441,7 @@ void DrawHotbar() {
|
|||||||
InventoryItem HotbarGetSelected() {
|
InventoryItem HotbarGetSelected() {
|
||||||
return hotbar[selected];
|
return hotbar[selected];
|
||||||
}
|
}
|
||||||
void DrawSelectedItem() {
|
void DrawSelectedItem(Color tint) {
|
||||||
InventoryItem item = hotbar[selected];
|
InventoryItem item = hotbar[selected];
|
||||||
Vector3 center = {-0.75f, -0.45f, 0.5f};
|
Vector3 center = {-0.75f, -0.45f, 0.5f};
|
||||||
rlPushMatrix();
|
rlPushMatrix();
|
||||||
@@ -458,16 +458,16 @@ void DrawSelectedItem() {
|
|||||||
|
|
||||||
rlRotatef(-45, 1, 0, 0);
|
rlRotatef(-45, 1, 0, 0);
|
||||||
rlRotatef(25, 0, 0, 1);
|
rlRotatef(25, 0, 0, 1);
|
||||||
DrawCubeTexture(playerTex, {0, -12*PIXUNIT/2, 0}, 4*PIXUNIT, 12*PIXUNIT, 4*PIXUNIT, WHITE, 44,20,4,4);
|
DrawCubeTexture(playerTex, {0, -12*PIXUNIT/2, 0}, 4*PIXUNIT, 12*PIXUNIT, 4*PIXUNIT, tint, 44,20,4,4);
|
||||||
if(item.item != nullptr) {
|
if(item.item != nullptr) {
|
||||||
if(item.item->type == IType_Block) {
|
if(item.item->type == IType_Block) {
|
||||||
DrawCubeBlock(terrain, {0, -12*PIXUNIT - 0.25f, 0}, 0.5f, 0.5f, 0.5f, GetBlockDefinition(item.damage));
|
DrawCubeBlock(terrain, {0, -12*PIXUNIT - 0.25f, 0}, 0.5f, 0.5f, 0.5f, GetBlockDefinition(item.damage), tint);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
UVCorners left = GetUVTex(item.item->texture);
|
UVCorners left = GetUVTex(item.item->texture);
|
||||||
rlSetTexture(item_atlas.id);
|
rlSetTexture(item_atlas.id);
|
||||||
rlBegin(RL_QUADS);
|
rlBegin(RL_QUADS);
|
||||||
rlColor4ub(255, 255, 255, 255);
|
rlColor4ub(tint.r, tint.g, tint.b, 255);
|
||||||
rlNormal3f(1.0f, 0.0f, 0.0f);
|
rlNormal3f(1.0f, 0.0f, 0.0f);
|
||||||
const float size = 0.5f;
|
const float size = 0.5f;
|
||||||
rlTexCoord2f(left.corner0.x, left.corner0.y); rlVertex3f(0, -12*PIXUNIT - size, 0.25f - size);
|
rlTexCoord2f(left.corner0.x, left.corner0.y); rlVertex3f(0, -12*PIXUNIT - size, 0.25f - size);
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ MeshData GenerateChunkMesh(World &world, ChunkRenderData chunkRenderData, Chunk
|
|||||||
positions.push_back(verts[3]);
|
positions.push_back(verts[3]);
|
||||||
|
|
||||||
normals.push_back(normal);
|
normals.push_back(normal);
|
||||||
Color clr = GetLight(world, wx-1, wy, wz);
|
Color clr = GetLightMesher(world, wx-1, wy, wz);
|
||||||
colors.push_back(clr);
|
colors.push_back(clr);
|
||||||
|
|
||||||
uvs.push_back(corners[0]);
|
uvs.push_back(corners[0]);
|
||||||
@@ -112,7 +112,7 @@ MeshData GenerateChunkMesh(World &world, ChunkRenderData chunkRenderData, Chunk
|
|||||||
positions.push_back(verts[3]);
|
positions.push_back(verts[3]);
|
||||||
|
|
||||||
normals.push_back(normal);
|
normals.push_back(normal);
|
||||||
Color clr = GetLight(world, wx+1, wy, wz);
|
Color clr = GetLightMesher(world, wx+1, wy, wz);
|
||||||
colors.push_back(clr);
|
colors.push_back(clr);
|
||||||
|
|
||||||
uvs.push_back(corners[0]);
|
uvs.push_back(corners[0]);
|
||||||
@@ -152,7 +152,7 @@ MeshData GenerateChunkMesh(World &world, ChunkRenderData chunkRenderData, Chunk
|
|||||||
positions.push_back(verts[3]);
|
positions.push_back(verts[3]);
|
||||||
|
|
||||||
normals.push_back(normal);
|
normals.push_back(normal);
|
||||||
Color clr = GetLight(world, wx, wy-1, wz);
|
Color clr = GetLightMesher(world, wx, wy-1, wz);
|
||||||
colors.push_back(clr);
|
colors.push_back(clr);
|
||||||
|
|
||||||
uvs.push_back(corners[0]);
|
uvs.push_back(corners[0]);
|
||||||
@@ -192,7 +192,7 @@ MeshData GenerateChunkMesh(World &world, ChunkRenderData chunkRenderData, Chunk
|
|||||||
positions.push_back(verts[3]);
|
positions.push_back(verts[3]);
|
||||||
|
|
||||||
normals.push_back(normal);
|
normals.push_back(normal);
|
||||||
Color clr = GetLight(world, wx, wy+1, wz);
|
Color clr = GetLightMesher(world, wx, wy+1, wz);
|
||||||
colors.push_back(clr);
|
colors.push_back(clr);
|
||||||
|
|
||||||
uvs.push_back(corners[0]);
|
uvs.push_back(corners[0]);
|
||||||
@@ -232,7 +232,7 @@ MeshData GenerateChunkMesh(World &world, ChunkRenderData chunkRenderData, Chunk
|
|||||||
positions.push_back(verts[3]);
|
positions.push_back(verts[3]);
|
||||||
|
|
||||||
normals.push_back(normal);
|
normals.push_back(normal);
|
||||||
Color clr = GetLight(world, wx, wy, wz+1);
|
Color clr = GetLightMesher(world, wx, wy, wz+1);
|
||||||
colors.push_back(clr);
|
colors.push_back(clr);
|
||||||
|
|
||||||
uvs.push_back(corners[0]);
|
uvs.push_back(corners[0]);
|
||||||
@@ -272,7 +272,7 @@ MeshData GenerateChunkMesh(World &world, ChunkRenderData chunkRenderData, Chunk
|
|||||||
positions.push_back(verts[3]);
|
positions.push_back(verts[3]);
|
||||||
|
|
||||||
normals.push_back(normal);
|
normals.push_back(normal);
|
||||||
Color clr = GetLight(world, wx, wy, wz-1);
|
Color clr = GetLightMesher(world, wx, wy, wz-1);
|
||||||
colors.push_back(clr);
|
colors.push_back(clr);
|
||||||
|
|
||||||
uvs.push_back(corners[0]);
|
uvs.push_back(corners[0]);
|
||||||
|
|||||||
+55
-2
@@ -87,7 +87,7 @@ void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float hei
|
|||||||
|
|
||||||
rlSetTexture(0);
|
rlSetTexture(0);
|
||||||
}
|
}
|
||||||
void DrawCubeBlock(Texture2D texture, Vector3 position, float width, float height, float length, BlockDef def)
|
void DrawCubeBlock(Texture2D texture, Vector3 position, float width, float height, float length, BlockDef def, Color tint)
|
||||||
{
|
{
|
||||||
float x = position.x;
|
float x = position.x;
|
||||||
float y = position.y;
|
float y = position.y;
|
||||||
@@ -104,7 +104,7 @@ void DrawCubeBlock(Texture2D texture, Vector3 position, float width, float heigh
|
|||||||
UVCorners right = GetUVTex(def.textureSide);
|
UVCorners right = GetUVTex(def.textureSide);
|
||||||
rlSetTexture(texture.id);
|
rlSetTexture(texture.id);
|
||||||
rlBegin(RL_QUADS);
|
rlBegin(RL_QUADS);
|
||||||
rlColor4ub(255, 255, 255, 255);
|
rlColor4ub(tint.r, tint.g, tint.b, 255);
|
||||||
// Front Face
|
// Front Face
|
||||||
rlNormal3f(0.0f, 0.0f, 1.0f); // Normal Pointing Towards Viewer
|
rlNormal3f(0.0f, 0.0f, 1.0f); // Normal Pointing Towards Viewer
|
||||||
rlTexCoord2f(front.corner0.x, front.corner0.y); rlVertex3f(x - width/2, y - height/2, z + length/2); // Bottom Left Of The Texture and Quad
|
rlTexCoord2f(front.corner0.x, front.corner0.y); rlVertex3f(x - width/2, y - height/2, z + length/2); // Bottom Left Of The Texture and Quad
|
||||||
@@ -254,3 +254,56 @@ void DrawText3D(Font font, const char *text, Vector3 position, float fontSize, f
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
RenderTexture2D LoadRenderTextureDepthTex(int width, int height)
|
||||||
|
{
|
||||||
|
RenderTexture2D target = { 0 };
|
||||||
|
|
||||||
|
target.id = rlLoadFramebuffer(); // Load an empty framebuffer
|
||||||
|
|
||||||
|
if (target.id > 0)
|
||||||
|
{
|
||||||
|
rlEnableFramebuffer(target.id);
|
||||||
|
|
||||||
|
// Create color texture (default to RGBA)
|
||||||
|
target.texture.id = rlLoadTexture(0, width, height, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, 1);
|
||||||
|
target.texture.width = width;
|
||||||
|
target.texture.height = height;
|
||||||
|
target.texture.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
|
||||||
|
target.texture.mipmaps = 1;
|
||||||
|
|
||||||
|
// Create depth texture buffer (instead of raylib default renderbuffer)
|
||||||
|
target.depth.id = rlLoadTextureDepth(width, height, false);
|
||||||
|
target.depth.width = width;
|
||||||
|
target.depth.height = height;
|
||||||
|
target.depth.format = 19; // DEPTH_COMPONENT_24BIT: Not defined in raylib
|
||||||
|
target.depth.mipmaps = 1;
|
||||||
|
|
||||||
|
// Attach color texture and depth texture to FBO
|
||||||
|
rlFramebufferAttach(target.id, target.texture.id, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_TEXTURE2D, 0);
|
||||||
|
rlFramebufferAttach(target.id, target.depth.id, RL_ATTACHMENT_DEPTH, RL_ATTACHMENT_TEXTURE2D, 0);
|
||||||
|
|
||||||
|
// Check if fbo is complete with attachments (valid)
|
||||||
|
if (rlFramebufferComplete(target.id)) TRACELOG(LOG_INFO, "FBO: [ID %i] Framebuffer object created successfully", target.id);
|
||||||
|
|
||||||
|
rlDisableFramebuffer();
|
||||||
|
}
|
||||||
|
else TRACELOG(LOG_WARNING, "FBO: Framebuffer object can not be created");
|
||||||
|
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unload render texture from GPU memory (VRAM)
|
||||||
|
void UnloadRenderTextureDepthTex(RenderTexture2D target)
|
||||||
|
{
|
||||||
|
if (target.id > 0)
|
||||||
|
{
|
||||||
|
// Color texture attached to FBO is deleted
|
||||||
|
rlUnloadTexture(target.texture.id);
|
||||||
|
rlUnloadTexture(target.depth.id);
|
||||||
|
|
||||||
|
// NOTE: Depth texture is automatically
|
||||||
|
// queried and deleted before deleting framebuffer
|
||||||
|
rlUnloadFramebuffer(target.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,6 @@
|
|||||||
#undef Escape
|
#undef Escape
|
||||||
#endif
|
#endif
|
||||||
#include "glfw_keycodes_to_string.h"
|
#include "glfw_keycodes_to_string.h"
|
||||||
#include "../PerlinNoise.hpp"
|
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include "external/fix_win32_compatibility.h"
|
#include "external/fix_win32_compatibility.h"
|
||||||
@@ -99,10 +98,10 @@
|
|||||||
#define GAME_VERSION_INT 0
|
#define GAME_VERSION_INT 0
|
||||||
|
|
||||||
#define DEFAULT_FONT_SIZE 16
|
#define DEFAULT_FONT_SIZE 16
|
||||||
#define TPS 30.0
|
#define TPS 30
|
||||||
#define TPS_DIV 1.0 / TPS
|
#define TPS_DIV 1.0 / TPS
|
||||||
//Rendering
|
//Rendering
|
||||||
#define RENDER_DISTANCE 5
|
#define RENDER_DISTANCE 16
|
||||||
#define RENDER_DISTANCE_SQUARED RENDER_DISTANCE*RENDER_DISTANCE
|
#define RENDER_DISTANCE_SQUARED RENDER_DISTANCE*RENDER_DISTANCE
|
||||||
|
|
||||||
//Game stuff
|
//Game stuff
|
||||||
@@ -115,6 +114,8 @@
|
|||||||
#define INVENTORY_HEIGHT 6
|
#define INVENTORY_HEIGHT 6
|
||||||
#define INVENTORY_SIZE INVENTORY_WIDTH*INVENTORY_HEIGHT
|
#define INVENTORY_SIZE INVENTORY_WIDTH*INVENTORY_HEIGHT
|
||||||
|
|
||||||
|
#define WORLD_TIME_SECONDS (24*60)
|
||||||
|
#define WORLD_TIME_TICKS WORLD_TIME_SECONDS*TPS
|
||||||
enum BlockType {
|
enum BlockType {
|
||||||
B_Wood,
|
B_Wood,
|
||||||
B_Stone,
|
B_Stone,
|
||||||
|
|||||||
+181
-39
@@ -15,6 +15,7 @@
|
|||||||
#include <list>
|
#include <list>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
#include <map>
|
||||||
#define MAX_RAY_DISTANCE 8.0f
|
#define MAX_RAY_DISTANCE 8.0f
|
||||||
struct MessageData {
|
struct MessageData {
|
||||||
std::string message;
|
std::string message;
|
||||||
@@ -57,15 +58,21 @@ static Sound wood_place;
|
|||||||
static Sound stone_place;
|
static Sound stone_place;
|
||||||
static Sound dirt_place;
|
static Sound dirt_place;
|
||||||
static Sound grass_place;
|
static Sound grass_place;
|
||||||
bool tick_entities;
|
static Texture2D sun;
|
||||||
|
static Texture2D moon;
|
||||||
|
static Texture2D stars;
|
||||||
|
bool tick_entities = true;
|
||||||
const std::string LocaleGet(std::string loc);
|
const std::string LocaleGet(std::string loc);
|
||||||
bool InputGetKeyDown(const std::string name);
|
bool InputGetKeyDown(const std::string name);
|
||||||
bool InputGetKeyPressed(const std::string name);
|
bool InputGetKeyPressed(const std::string name);
|
||||||
|
|
||||||
extern std::list<Entity> entities;
|
extern std::list<Entity> entities;
|
||||||
std::bitset<WORLD_SIZE_BLOCKS*WORLD_SIZE_BLOCKS/8/8> clouds;
|
std::bitset<WORLD_SIZE_BLOCKS*WORLD_SIZE_BLOCKS/8/8> clouds;
|
||||||
std::queue<Vector3I> tickedBlocks;
|
std::queue<Vector3I> tickedBlocks;
|
||||||
struct MeshUnit {
|
struct MeshUnit {
|
||||||
Model model;
|
Model model;
|
||||||
|
Model modelTransparent;
|
||||||
|
Model modelWater;
|
||||||
int vertices;
|
int vertices;
|
||||||
};
|
};
|
||||||
struct ProfilerPart {
|
struct ProfilerPart {
|
||||||
@@ -91,8 +98,17 @@ static Vector3 CameraForwardFromYawPitch(float yaw, float pitch)
|
|||||||
}
|
}
|
||||||
World world;
|
World world;
|
||||||
static MeshUnit rendering[MAX_WORLD_AREA];
|
static MeshUnit rendering[MAX_WORLD_AREA];
|
||||||
static MeshUnit renderingT[MAX_WORLD_AREA];
|
|
||||||
|
|
||||||
|
std::map<std::string, Shader> loadedShaders;
|
||||||
|
static void LoadNewShader(std::string name) {
|
||||||
|
Shader temp = LoadShader(
|
||||||
|
TextFormat("%s/shaders/%s.vs", PATH_APPEND, name.c_str()),
|
||||||
|
TextFormat("%s/shaders/%s.fs", PATH_APPEND, name.c_str())
|
||||||
|
);
|
||||||
|
temp.locs[SHADER_LOC_MATRIX_MODEL] = GetShaderLocation(temp, "matModel");
|
||||||
|
temp.locs[SHADER_LOC_VECTOR_VIEW] = GetShaderLocation(temp, "viewPos");
|
||||||
|
loadedShaders[name] = temp;
|
||||||
|
}
|
||||||
GameState state = GAME_STATE_MAINMENU;
|
GameState state = GAME_STATE_MAINMENU;
|
||||||
bool loaderParam_remeshOnly = false;
|
bool loaderParam_remeshOnly = false;
|
||||||
int worldCreationProgress = 0;
|
int worldCreationProgress = 0;
|
||||||
@@ -274,37 +290,37 @@ void Debug_EndMeasureLoops(const std::string &stuff, int loops);
|
|||||||
static void RemeshChunk(int x, int y) {
|
static void RemeshChunk(int x, int y) {
|
||||||
int idx = GetIndexWorld(x, y);
|
int idx = GetIndexWorld(x, y);
|
||||||
if(loadedChunks[idx]) {
|
if(loadedChunks[idx]) {
|
||||||
UnloadModel(renderingT[idx].model);
|
|
||||||
UnloadModel(rendering[idx].model);
|
UnloadModel(rendering[idx].model);
|
||||||
|
UnloadModel(rendering[idx].modelTransparent);
|
||||||
|
UnloadModel(rendering[idx].modelWater);
|
||||||
}
|
}
|
||||||
Chunk &chunk = world.chunks[idx];
|
Chunk &chunk = world.chunks[idx];
|
||||||
RebuildOpaqueMask(chunk);
|
RebuildOpaqueMask(chunk);
|
||||||
/*for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
Vector3I dir = dirs2d[i];
|
|
||||||
if(!CheckOOBWorldChunk(x+dir.x, y+dir.z)) {
|
|
||||||
RebuildLighting(world, world.chunks[GetIndexWorld(x+dir.x, y+dir.z)]);
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
RebuildLighting(world, chunk.x, chunk.z);
|
RebuildLighting(world, chunk.x, chunk.z);
|
||||||
|
|
||||||
|
|
||||||
MeshData renderDataOpq = GenerateChunkMesh(world, GenerateCRDOpaque(chunk, world), chunk, x, y, 0xFF);
|
MeshData renderDataOpq = GenerateChunkMesh(world, GenerateCRDOpaque(chunk, world), chunk, x, y, 0xFF);
|
||||||
MeshData renderDataTsl = GenerateChunkMesh(world, GenerateCRDTranslucent(chunk, world), chunk, x, y, 0xFF);
|
Model model0 = LoadModelFromMesh(GenChunkMesh(renderDataOpq));
|
||||||
|
model0.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = terrain;
|
||||||
Model model = LoadModelFromMesh(GenChunkMesh(renderDataOpq));
|
model0.materials[0].shader = loadedShaders["terrain"];
|
||||||
model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = terrain;
|
|
||||||
MeshUnit munit0;
|
MeshUnit munit0;
|
||||||
munit0.model = model;
|
munit0.model = model0;
|
||||||
munit0.vertices += renderDataOpq.vertexCount;
|
munit0.vertices += renderDataOpq.vertexCount;
|
||||||
rendering[idx] = munit0;
|
|
||||||
model = LoadModelFromMesh(GenChunkMesh(renderDataTsl));
|
|
||||||
model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = terrain;
|
|
||||||
MeshUnit munit1;
|
|
||||||
munit1.model = model;
|
|
||||||
munit1.vertices += renderDataTsl.vertexCount;
|
|
||||||
renderingT[idx] = munit1;
|
|
||||||
loadedChunks[idx] = true;
|
|
||||||
|
|
||||||
|
MeshData renderDataTsl = GenerateChunkMesh(world, GenerateCRDTranslucent(chunk, world), chunk, x, y, 0xFF);
|
||||||
|
Model model1 = LoadModelFromMesh(GenChunkMesh(renderDataTsl));
|
||||||
|
model1.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = terrain;
|
||||||
|
model1.materials[0].shader = loadedShaders["terrain"];
|
||||||
|
munit0.modelTransparent = model1;
|
||||||
|
|
||||||
|
MeshData renderDataWtr = GenerateChunkMesh(world, GenerateCRDWater(chunk, world), chunk, x, y, 0xFF);
|
||||||
|
Model model2 = LoadModelFromMesh(GenChunkMesh(renderDataWtr));
|
||||||
|
model2.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = terrain;
|
||||||
|
model2.materials[0].shader = loadedShaders["water"];
|
||||||
|
munit0.modelWater = model2;
|
||||||
|
|
||||||
|
loadedChunks[idx] = true;
|
||||||
|
rendering[idx] = munit0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool RaycastBlock(Vector3 origin, Vector3 dir, float maxDist, Vector3 *outBlock, Vector3 *outPrev)
|
static bool RaycastBlock(Vector3 origin, Vector3 dir, float maxDist, Vector3 *outBlock, Vector3 *outPrev)
|
||||||
@@ -549,6 +565,54 @@ void TakeDamage(float amount) {
|
|||||||
int currentlyTickedChunk = 0;
|
int currentlyTickedChunk = 0;
|
||||||
Vector3 highlightBlock = {-1, -1, -1};
|
Vector3 highlightBlock = {-1, -1, -1};
|
||||||
|
|
||||||
|
float GetDayProgression() {
|
||||||
|
return (float)(worldTime % (unsigned long long)(WORLD_TIME_TICKS)) / (float)(WORLD_TIME_TICKS);
|
||||||
|
}
|
||||||
|
Color GetSkyColor() {
|
||||||
|
float progression = GetDayProgression();
|
||||||
|
Color night = ColorBrightness(BLUE, -0.9f);
|
||||||
|
Color sunrise = ColorBrightness(ORANGE, -0.25f);
|
||||||
|
Color noon = BLUE;
|
||||||
|
if(progression > 0.5f) {
|
||||||
|
progression = 1 - progression;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(progression < 0.20f) {
|
||||||
|
return night;
|
||||||
|
}
|
||||||
|
if(progression>=0.20f&&progression<0.30f) {
|
||||||
|
return ColorLerp(night, sunrise, (progression - 0.2f) / 0.1f);
|
||||||
|
}
|
||||||
|
if(progression>=0.30f&&progression<0.35f) {
|
||||||
|
return ColorLerp(sunrise, noon, (progression - 0.3f) / 0.05f);
|
||||||
|
}
|
||||||
|
return noon;
|
||||||
|
}
|
||||||
|
Color GetSunlightColor() {
|
||||||
|
float progression = GetDayProgression();
|
||||||
|
Color night = ColorBrightness(BLUE, -0.9f);
|
||||||
|
Color sunrise = ColorBrightness(ORANGE, -0.25f);
|
||||||
|
Color noon = WHITE;
|
||||||
|
if(progression > 0.5f) {
|
||||||
|
progression = 1 - progression;
|
||||||
|
}
|
||||||
|
if(progression < 0.20f) {
|
||||||
|
return night;
|
||||||
|
}
|
||||||
|
if(progression>=0.20f&&progression<0.30f) {
|
||||||
|
return ColorLerp(night, sunrise, (progression - 0.2f) / 0.1f);
|
||||||
|
}
|
||||||
|
if(progression>=0.30f&&progression<0.35f) {
|
||||||
|
return ColorLerp(sunrise, noon, (progression - 0.3f) / 0.05f);
|
||||||
|
}
|
||||||
|
return noon;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Vector3 GetSunDirection() {
|
||||||
|
float time = GetDayProgression() - 0.25f;
|
||||||
|
return Vector3Normalize({-sinf(time*PI*2), -sinf(time*PI*2)/2.0f, -cosf(time*PI*2)});
|
||||||
|
}
|
||||||
|
|
||||||
static void GameUpdate(Camera camera, float &time) {
|
static void GameUpdate(Camera camera, float &time) {
|
||||||
if (player_position.y < 0 ||
|
if (player_position.y < 0 ||
|
||||||
player_position.x < 0 ||
|
player_position.x < 0 ||
|
||||||
@@ -691,6 +755,9 @@ static void GameUpdate(Camera camera, float &time) {
|
|||||||
if(IsKeyPressed(KEY_F10)) {
|
if(IsKeyPressed(KEY_F10)) {
|
||||||
tick_entities = !tick_entities;
|
tick_entities = !tick_entities;
|
||||||
}
|
}
|
||||||
|
if(IsKeyDown(KEY_F11)) {
|
||||||
|
worldTime+=8;
|
||||||
|
}
|
||||||
if(IsKeyPressed(KEY_B) && !online) {
|
if(IsKeyPressed(KEY_B) && !online) {
|
||||||
Entity temp = NewEntity();
|
Entity temp = NewEntity();
|
||||||
temp.type = 3;
|
temp.type = 3;
|
||||||
@@ -888,12 +955,13 @@ static void GameUpdate(Camera camera, float &time) {
|
|||||||
|
|
||||||
PROFCOUNT = GetTime();
|
PROFCOUNT = GetTime();
|
||||||
if(tick_entities) {
|
if(tick_entities) {
|
||||||
entUpdateCounter += dt;
|
entUpdateCounter += dt / 2.0f;
|
||||||
if(entUpdateCounter > TPS_DIV) {
|
if(entUpdateCounter > TPS_DIV) {
|
||||||
while (entUpdateCounter > 0)
|
while (entUpdateCounter > 0)
|
||||||
{
|
{
|
||||||
UpdateEntities(world, TPS_DIV / 2.0f);
|
UpdateEntities(world, TPS_DIV / 2.0f);
|
||||||
entUpdateCounter-= TPS_DIV;
|
entUpdateCounter-= TPS_DIV;
|
||||||
|
worldTime++;
|
||||||
}
|
}
|
||||||
TickAvailableBlocks();
|
TickAvailableBlocks();
|
||||||
entUpdateCounter = 0.0f;
|
entUpdateCounter = 0.0f;
|
||||||
@@ -917,12 +985,56 @@ static void GameUpdate(Camera camera, float &time) {
|
|||||||
UpdateCamera(&camera, CAMERA_CUSTOM);
|
UpdateCamera(&camera, CAMERA_CUSTOM);
|
||||||
|
|
||||||
unsigned int debug_verts_opaque = 0;
|
unsigned int debug_verts_opaque = 0;
|
||||||
unsigned int debug_verts_transparent = 0;
|
|
||||||
UpdateHotbar();
|
UpdateHotbar();
|
||||||
Frustum frustum = ExtractFrustumPlanes(camera, (float)GetScreenWidth() / (float)GetScreenHeight());
|
Frustum frustum = ExtractFrustumPlanes(camera, (float)GetScreenWidth() / (float)GetScreenHeight());
|
||||||
BeginDrawing();
|
BeginDrawing();
|
||||||
ClearBackground(RAYWHITE);
|
UpdateCamera(&camera, CAMERA_CUSTOM);
|
||||||
DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), BLUE);
|
|
||||||
|
ClearBackground(GetSkyColor());
|
||||||
|
|
||||||
|
BeginMode3D(camera);
|
||||||
|
float time = GetDayProgression() - 0.25f;
|
||||||
|
Vector3 sunOffset = Vector3Negate(GetSunDirection());
|
||||||
|
Vector3 _forward = Vector3Subtract(camera.target, camera.position);
|
||||||
|
Vector3 up = { 0.0f, 1.0f, 0.0f };
|
||||||
|
Vector3 _right = Vector3CrossProduct(up, _forward);
|
||||||
|
up = Vector3CrossProduct(_forward, _right);
|
||||||
|
up = Vector3Normalize(up);
|
||||||
|
SetRandomSeed(1337);
|
||||||
|
time += 0.25f;
|
||||||
|
if(time > 0.5f) {
|
||||||
|
time = 1-time;
|
||||||
|
}
|
||||||
|
float starAlpha = 0.0f;
|
||||||
|
if(time > 0.2f && time <= 0.3f) {
|
||||||
|
starAlpha = 1-(time - 0.2f) / 0.1f;
|
||||||
|
}
|
||||||
|
if(time <= 0.2f) {
|
||||||
|
starAlpha = 1;
|
||||||
|
}
|
||||||
|
rlSetBlendMode(BLEND_ADDITIVE);
|
||||||
|
DrawBillboardPro(camera, sun, {0, 0, 64, 64}, player_position+sunOffset*1000, up, {150, 150}, {0.5f, 0.5f}, 0, WHITE);
|
||||||
|
DrawBillboardPro(camera, moon, {0, 0, 64, 64}, player_position-sunOffset*1000, up, {150, 150}, {0.5f, 0.5f}, 0, WHITE);
|
||||||
|
for (int i = 0; i < 120; i++)
|
||||||
|
{
|
||||||
|
float u = GetRandomValue(0, 100) / 100.0f;
|
||||||
|
float v = GetRandomValue(0, 100) / 100.0f;
|
||||||
|
double theta = 2.0 * M_PI * u;
|
||||||
|
double z = v;
|
||||||
|
double r = std::sqrt(1.0 - z*z);
|
||||||
|
|
||||||
|
Vector3 starOffset = {
|
||||||
|
r * std::cos(theta),
|
||||||
|
z,
|
||||||
|
r * std::sin(theta)
|
||||||
|
};
|
||||||
|
Vector3 tgt = starOffset*1000;
|
||||||
|
float alphaModMoon = fmax(0, fmin(1, Vector3Distance(starOffset, (Vector3Negate(sunOffset)))/0.25f-1));
|
||||||
|
float alphaModSun = fmax(0, fmin(1, Vector3Distance(starOffset, sunOffset)/0.25f-0.25f));
|
||||||
|
DrawBillboardPro(camera, stars, {(float)GetRandomValue(0, stars.width/8)*8, 0, 8, 8}, player_position+tgt, up, {10, 10}, {0.5f, 0.5f}, GetRandomValue(0, 360), ColorAlpha(WHITE, starAlpha*alphaModMoon*alphaModSun));
|
||||||
|
}
|
||||||
|
rlSetBlendMode(BLEND_ALPHA);
|
||||||
|
EndMode3D();
|
||||||
|
|
||||||
BeginMode3D(camera);
|
BeginMode3D(camera);
|
||||||
|
|
||||||
@@ -1017,8 +1129,8 @@ static void GameUpdate(Camera camera, float &time) {
|
|||||||
|
|
||||||
for (auto &p : distances) {
|
for (auto &p : distances) {
|
||||||
int idx = p.second;
|
int idx = p.second;
|
||||||
DrawModel(renderingT[idx].model, {0, 0, 0}, 1.0f, WHITE);
|
DrawModel(rendering[idx].modelTransparent, {0, 0, 0}, 1.0f, WHITE);
|
||||||
debug_verts_transparent += renderingT[idx].vertices;
|
DrawModel(rendering[idx].modelWater, {0, 0, 0}, 1.0f, WHITE);
|
||||||
}
|
}
|
||||||
AddProfilerPart("chunk render tsl", GetTime()-PROFCOUNT, RED);
|
AddProfilerPart("chunk render tsl", GetTime()-PROFCOUNT, RED);
|
||||||
if (highlightValid)
|
if (highlightValid)
|
||||||
@@ -1037,7 +1149,7 @@ static void GameUpdate(Camera camera, float &time) {
|
|||||||
BeginMode3D(camera);
|
BeginMode3D(camera);
|
||||||
rlDisableDepthMask();
|
rlDisableDepthMask();
|
||||||
rlDisableDepthTest();
|
rlDisableDepthTest();
|
||||||
DrawSelectedItem();
|
DrawSelectedItem(GetLight(world, (int)player_position.x, (int)player_position.y, (int)player_position.z));
|
||||||
rlEnableDepthTest();
|
rlEnableDepthTest();
|
||||||
rlEnableDepthMask();
|
rlEnableDepthMask();
|
||||||
EndMode3D();
|
EndMode3D();
|
||||||
@@ -1076,6 +1188,13 @@ static void GameUpdate(Camera camera, float &time) {
|
|||||||
GetBLight(world, ppos.x, ppos.y, ppos.z)
|
GetBLight(world, ppos.x, ppos.y, ppos.z)
|
||||||
);
|
);
|
||||||
DrawTextB(text, 20, 100, DEFAULT_FONT_SIZE, WHITE);
|
DrawTextB(text, 20, 100, DEFAULT_FONT_SIZE, WHITE);
|
||||||
|
sprintf(text, "world time %dt (%.1fs)", worldTime, worldTime * TPS_DIV);
|
||||||
|
DrawTextB(text, 20, 120, DEFAULT_FONT_SIZE, WHITE);
|
||||||
|
float progress = GetDayProgression();
|
||||||
|
int hours = progress*24;
|
||||||
|
int minutes = (int)(progress*24*60)%60;
|
||||||
|
sprintf(text, "%02d:%02d", hours, minutes);
|
||||||
|
DrawTextB(text, 20, 140, DEFAULT_FONT_SIZE, WHITE);
|
||||||
DrawRectangle(GetScreenWidth()/2-3, GetScreenHeight()/2-3, 6, 6, BLACK);
|
DrawRectangle(GetScreenWidth()/2-3, GetScreenHeight()/2-3, 6, 6, BLACK);
|
||||||
DrawRectangle(GetScreenWidth()/2-2, GetScreenHeight()/2-2, 4, 4, WHITE);
|
DrawRectangle(GetScreenWidth()/2-2, GetScreenHeight()/2-2, 4, 4, WHITE);
|
||||||
|
|
||||||
@@ -1176,6 +1295,7 @@ static void GameUpdate(Camera camera, float &time) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void GameStart() {
|
static void GameStart() {
|
||||||
|
|
||||||
const int cloudMapSize = MAX_WORLD_SIZE*CHUNK_SIZE/8;
|
const int cloudMapSize = MAX_WORLD_SIZE*CHUNK_SIZE/8;
|
||||||
for (int x = 0; x < cloudMapSize; x++)
|
for (int x = 0; x < cloudMapSize; x++)
|
||||||
{
|
{
|
||||||
@@ -1191,6 +1311,8 @@ static void GameStart() {
|
|||||||
SendPacketR(peer, data, 1); // Tell the server to fetch all players
|
SendPacketR(peer, data, 1); // Tell the server to fetch all players
|
||||||
}
|
}
|
||||||
|
|
||||||
|
worldTime = (int)(WORLD_TIME_TICKS * 0.3f);
|
||||||
|
|
||||||
camera = { 0 };
|
camera = { 0 };
|
||||||
camera.position = (Vector3){ MAX_WORLD_SIZE / 2 * CHUNK_SIZE, 12.0f, MAX_WORLD_SIZE / 2 * CHUNK_SIZE};
|
camera.position = (Vector3){ MAX_WORLD_SIZE / 2 * CHUNK_SIZE, 12.0f, MAX_WORLD_SIZE / 2 * CHUNK_SIZE};
|
||||||
camera.target = (Vector3){camera.position.x, camera.position.y, camera.position.z + 1};
|
camera.target = (Vector3){camera.position.x, camera.position.y, camera.position.z + 1};
|
||||||
@@ -1408,14 +1530,6 @@ void GameModeCleanupFull() {
|
|||||||
enet_host_destroy(client);
|
enet_host_destroy(client);
|
||||||
online = false;
|
online = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int idx = 0; idx < MAX_WORLD_AREA; idx++)
|
|
||||||
{
|
|
||||||
if(loadedChunks[idx]) {
|
|
||||||
//UnloadModel(renderingT[idx]);
|
|
||||||
//UnloadModel(rendering[idx]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
memset(loadedChunks, 0, sizeof(loadedChunks));
|
memset(loadedChunks, 0, sizeof(loadedChunks));
|
||||||
memset(dirtyChunks, 0, sizeof(dirtyChunks));
|
memset(dirtyChunks, 0, sizeof(dirtyChunks));
|
||||||
entities.clear();
|
entities.clear();
|
||||||
@@ -1439,6 +1553,13 @@ int main(void)
|
|||||||
SetTraceLogLevel(LOG_WARNING);
|
SetTraceLogLevel(LOG_WARNING);
|
||||||
SetConfigFlags(FLAG_WINDOW_RESIZABLE);
|
SetConfigFlags(FLAG_WINDOW_RESIZABLE);
|
||||||
InitWindow(WIDTH, HEIGHT, GAME_NAME);
|
InitWindow(WIDTH, HEIGHT, GAME_NAME);
|
||||||
|
|
||||||
|
if(!DirectoryExists(PathifyUser(""))) {
|
||||||
|
MakeDirectory(PathifyUser(""));
|
||||||
|
}
|
||||||
|
if(!DirectoryExists(PathifyUser("worlds"))) {
|
||||||
|
MakeDirectory(PathifyUser("worlds"));
|
||||||
|
}
|
||||||
InitWorldgen(0);
|
InitWorldgen(0);
|
||||||
InitAudioDevice();
|
InitAudioDevice();
|
||||||
InitMenu();
|
InitMenu();
|
||||||
@@ -1456,6 +1577,9 @@ int main(void)
|
|||||||
|
|
||||||
fnt = LoadFontEx(Pathify("font.ttf"), 32, NULL, 1024*8);
|
fnt = LoadFontEx(Pathify("font.ttf"), 32, NULL, 1024*8);
|
||||||
terrain = LoadTexture(Pathify("terrain.png"));
|
terrain = LoadTexture(Pathify("terrain.png"));
|
||||||
|
sun = LoadTexture(Pathify("sun.png"));
|
||||||
|
moon = LoadTexture(Pathify("moon.png"));
|
||||||
|
stars = LoadTexture(Pathify("stars.png"));
|
||||||
GenTextureMipmaps(&terrain);
|
GenTextureMipmaps(&terrain);
|
||||||
Image temp = GenImageColor(1, 1, WHITE);
|
Image temp = GenImageColor(1, 1, WHITE);
|
||||||
white_pixel = LoadTextureFromImage(temp);
|
white_pixel = LoadTextureFromImage(temp);
|
||||||
@@ -1471,14 +1595,32 @@ int main(void)
|
|||||||
ImageCrop(&copied, src0);
|
ImageCrop(&copied, src0);
|
||||||
|
|
||||||
water = LoadTextureFromImage(copied);
|
water = LoadTextureFromImage(copied);
|
||||||
|
SetTextureWrap(terrain, TEXTURE_WRAP_REPEAT);
|
||||||
SetTextureWrap(water, TEXTURE_WRAP_REPEAT);
|
SetTextureWrap(water, TEXTURE_WRAP_REPEAT);
|
||||||
SetTargetFPS(-1);
|
SetTargetFPS(-1);
|
||||||
float time;
|
float time;
|
||||||
|
|
||||||
|
LoadNewShader("terrain");
|
||||||
|
LoadNewShader("water");
|
||||||
|
|
||||||
SetExitKey(KEY_NULL);
|
SetExitKey(KEY_NULL);
|
||||||
|
|
||||||
while (!WindowShouldClose())
|
while (!WindowShouldClose())
|
||||||
{
|
{
|
||||||
|
for (const auto& [key, shader] : loadedShaders) {
|
||||||
|
Vector4 sunlight = ColorNormalize(GetSunlightColor());
|
||||||
|
SetShaderValue(shader, GetShaderLocation(shader, "sunlightColor"), &sunlight, SHADER_UNIFORM_VEC4);
|
||||||
|
|
||||||
|
Vector4 skyColor = ColorNormalize(GetSkyColor());
|
||||||
|
SetShaderValue(shader, GetShaderLocation(shader, "skyColor"), &skyColor, SHADER_UNIFORM_VEC4);
|
||||||
|
|
||||||
|
Vector3 sunlightDir = Vector3Negate(GetSunDirection());
|
||||||
|
SetShaderValue(shader, GetShaderLocation(shader, "lightDir"), &sunlightDir, SHADER_UNIFORM_VEC3);
|
||||||
|
|
||||||
|
float time = (float)GetTime();
|
||||||
|
SetShaderValue(shader, GetShaderLocation(shader, "time"), &time, SHADER_UNIFORM_FLOAT);
|
||||||
|
}
|
||||||
|
|
||||||
NetworkUpdate();
|
NetworkUpdate();
|
||||||
InputUpdate();
|
InputUpdate();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user