Compare commits
48 Commits
ca82d6a447
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f4114c2699 | ||
|
|
932463663f | ||
|
|
bac3df801b | ||
|
|
d0bc8d627f | ||
|
|
2906106597 | ||
|
|
a0139dd315 | ||
|
|
5901ab7cd9 | ||
|
|
bbf8b4e969 | ||
|
|
a54e87dbc6 | ||
|
|
1a26474a05 | ||
|
|
d986e03f9c | ||
|
|
9d200f31be | ||
|
|
a02bfad639 | ||
|
|
a63dfa7f47 | ||
|
|
d4d761b2aa | ||
|
|
315c60e4a6 | ||
|
|
9a8e76d25f | ||
| 14c942333c | |||
| b88bc30756 | |||
| a526d37f97 | |||
| fb86836e19 | |||
| f2f00ce658 | |||
| 611a795481 | |||
| dc3be5a4bc | |||
| 932c11a646 | |||
| 5b2f06b3ec | |||
| bd5665c935 | |||
| 59ab47d317 | |||
| e34a20599d | |||
| c5a78185ba | |||
| a3eb19e58f | |||
| 9402847e89 | |||
| a95ad796ce | |||
| 8b5717a655 | |||
| 055c4d687b | |||
| 4ca2133ff3 | |||
| ada0603a2f | |||
| dc3926e47f | |||
| 3e27ab675c | |||
| 106cc3d398 | |||
| 2409734e89 | |||
| 8f8e2c1bd5 | |||
| 2707748843 | |||
| e90b0ce2f4 | |||
| c7a0aff0c1 | |||
| c2321a0a6e | |||
| 6c74f4582c | |||
| 553955841b |
321
.clang-format
Normal file
@@ -0,0 +1,321 @@
|
||||
---
|
||||
Language: Cpp
|
||||
AlignAfterOpenBracket: true
|
||||
AccessModifierOffset: -4
|
||||
AlignArrayOfStructures: None
|
||||
AlignConsecutiveAssignments:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
AlignFunctionDeclarations: false
|
||||
AlignFunctionPointers: false
|
||||
PadOperators: true
|
||||
AlignConsecutiveBitFields:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
AlignFunctionDeclarations: false
|
||||
AlignFunctionPointers: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveDeclarations:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
AlignFunctionDeclarations: true
|
||||
AlignFunctionPointers: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveMacros:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
AlignFunctionDeclarations: false
|
||||
AlignFunctionPointers: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveShortCaseStatements:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCaseArrows: false
|
||||
AlignCaseColons: false
|
||||
AlignConsecutiveTableGenBreakingDAGArgColons:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
AlignFunctionDeclarations: false
|
||||
AlignFunctionPointers: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveTableGenCondOperatorColons:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
AlignFunctionDeclarations: false
|
||||
AlignFunctionPointers: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveTableGenDefinitionColons:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
AlignFunctionDeclarations: false
|
||||
AlignFunctionPointers: false
|
||||
PadOperators: false
|
||||
AlignEscapedNewlines: Right
|
||||
AlignOperands: Align
|
||||
AlignTrailingComments:
|
||||
AlignPPAndNotPP: true
|
||||
Kind: Always
|
||||
OverEmptyLines: 0
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowBreakBeforeNoexceptSpecifier: Never
|
||||
AllowBreakBeforeQtProperty: false
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortCaseExpressionOnASingleLine: true
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortCompoundRequirementOnASingleLine: true
|
||||
AllowShortEnumsOnASingleLine: true
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AllowShortNamespacesOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AttributeMacros:
|
||||
- __capability
|
||||
BinPackArguments: true
|
||||
BinPackLongBracedList: true
|
||||
BinPackParameters: BinPack
|
||||
BitFieldColonSpacing: Both
|
||||
BracedInitializerIndentWidth: -1
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: Never
|
||||
AfterEnum: false
|
||||
AfterExternBlock: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakAdjacentStringLiterals: true
|
||||
BreakAfterAttributes: Leave
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakAfterOpenBracketBracedList: false
|
||||
BreakAfterOpenBracketFunction: false
|
||||
BreakAfterOpenBracketIf: false
|
||||
BreakAfterOpenBracketLoop: false
|
||||
BreakAfterOpenBracketSwitch: false
|
||||
BreakAfterReturnType: None
|
||||
BreakArrays: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeCloseBracketBracedList: false
|
||||
BreakBeforeCloseBracketFunction: false
|
||||
BreakBeforeCloseBracketIf: false
|
||||
BreakBeforeCloseBracketLoop: false
|
||||
BreakBeforeCloseBracketSwitch: false
|
||||
BreakBeforeConceptDeclarations: Always
|
||||
BreakBeforeBraces: Attach
|
||||
BreakBeforeInlineASMColon: OnlyMultiline
|
||||
BreakBeforeTemplateCloser: false
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakBinaryOperations: Never
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakFunctionDefinitionParameters: false
|
||||
BreakInheritanceList: BeforeColon
|
||||
BreakStringLiterals: true
|
||||
BreakTemplateDeclarations: MultiLine
|
||||
ColumnLimit: 80
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: AlignFirstComment
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
EmptyLineAfterAccessModifier: Never
|
||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||
EnumTrailingComma: Leave
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
FixNamespaceComments: true
|
||||
ForEachMacros:
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IfMacros:
|
||||
- KJ_IF_MAYBE
|
||||
IncludeBlocks: Regroup
|
||||
IncludeCategories:
|
||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||
Priority: 2
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||
Priority: 3
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
IncludeIsMainRegex: '(Test)?$'
|
||||
IncludeIsMainSourceRegex: ''
|
||||
IndentAccessModifiers: false
|
||||
IndentCaseBlocks: false
|
||||
IndentCaseLabels: false
|
||||
IndentExportBlock: true
|
||||
IndentExternBlock: AfterExternBlock
|
||||
IndentGotoLabels: true
|
||||
IndentPPDirectives: None
|
||||
IndentRequiresClause: true
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
InsertBraces: false
|
||||
InsertNewlineAtEOF: false
|
||||
InsertTrailingCommas: None
|
||||
IntegerLiteralSeparator:
|
||||
Binary: 0
|
||||
BinaryMinDigitsInsert: 0
|
||||
BinaryMaxDigitsRemove: 0
|
||||
Decimal: 0
|
||||
DecimalMinDigitsInsert: 0
|
||||
DecimalMaxDigitsRemove: 0
|
||||
Hex: 0
|
||||
HexMinDigitsInsert: 0
|
||||
HexMaxDigitsRemove: 0
|
||||
BinaryMinDigits: 0
|
||||
DecimalMinDigits: 0
|
||||
HexMinDigits: 0
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLines:
|
||||
AtEndOfFile: false
|
||||
AtStartOfBlock: true
|
||||
AtStartOfFile: true
|
||||
KeepFormFeed: false
|
||||
LambdaBodyIndentation: Signature
|
||||
LineEnding: DeriveLF
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MainIncludeChar: Quote
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
NumericLiteralCase:
|
||||
ExponentLetter: Leave
|
||||
HexDigit: Leave
|
||||
Prefix: Leave
|
||||
Suffix: Leave
|
||||
ObjCBinPackProtocolList: Auto
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCBreakBeforeNestedBlockParam: true
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
OneLineFormatOffRegex: ''
|
||||
PackConstructorInitializers: BinPack
|
||||
PenaltyBreakAssignment: 2
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakBeforeMemberAccess: 150
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakOpenParenthesis: 0
|
||||
PenaltyBreakScopeResolution: 500
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyIndentedWhitespace: 0
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PointerAlignment: Left
|
||||
PPIndentWidth: -1
|
||||
QualifierAlignment: Leave
|
||||
ReferenceAlignment: Pointer
|
||||
ReflowComments: Always
|
||||
RemoveBracesLLVM: false
|
||||
RemoveEmptyLinesInUnwrappedLines: false
|
||||
RemoveParentheses: Leave
|
||||
RemoveSemicolon: false
|
||||
RequiresClausePosition: OwnLine
|
||||
RequiresExpressionIndentation: OuterScope
|
||||
SeparateDefinitionBlocks: Leave
|
||||
ShortNamespaceLines: 1
|
||||
SkipMacroDefinitionBody: false
|
||||
SortIncludes:
|
||||
Enabled: true
|
||||
IgnoreCase: false
|
||||
IgnoreExtension: false
|
||||
SortJavaStaticImport: Before
|
||||
SortUsingDeclarations: LexicographicNumeric
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterOperatorKeyword: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceAroundPointerQualifiers: Default
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCaseColon: false
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeJsonColon: false
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeParensOptions:
|
||||
AfterControlStatements: true
|
||||
AfterForeachMacros: true
|
||||
AfterFunctionDefinitionName: false
|
||||
AfterFunctionDeclarationName: false
|
||||
AfterIfMacros: true
|
||||
AfterNot: false
|
||||
AfterOverloadedOperator: false
|
||||
AfterPlacementOperator: true
|
||||
AfterRequiresInClause: false
|
||||
AfterRequiresInExpression: false
|
||||
BeforeNonEmptyParentheses: false
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceBeforeSquareBrackets: false
|
||||
SpaceInEmptyBraces: Never
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: Never
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInLineCommentPrefix:
|
||||
Minimum: 1
|
||||
Maximum: -1
|
||||
SpacesInParens: Never
|
||||
SpacesInParensOptions:
|
||||
ExceptDoubleParentheses: false
|
||||
InCStyleCasts: false
|
||||
InConditionalStatements: false
|
||||
InEmptyParentheses: false
|
||||
Other: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Latest
|
||||
StatementAttributeLikeMacros:
|
||||
- Q_EMIT
|
||||
StatementMacros:
|
||||
- Q_UNUSED
|
||||
- QT_REQUIRE_VERSION
|
||||
TableGenBreakInsideDAGArg: DontBreak
|
||||
TabWidth: 8
|
||||
UseTab: Never
|
||||
VerilogBreakBetweenInstancePorts: true
|
||||
WhitespaceSensitiveMacros:
|
||||
- BOOST_PP_STRINGIZE
|
||||
- CF_SWIFT_NAME
|
||||
- NS_SWIFT_NAME
|
||||
- PP_STRINGIZE
|
||||
- STRINGIZE
|
||||
WrapNamespaceBodyWithEmptyLines: Leave
|
||||
...
|
||||
|
||||
3
.clang-format-ignore
Normal file
@@ -0,0 +1,3 @@
|
||||
third_party/
|
||||
build/
|
||||
vendor/
|
||||
2
.clangd
Normal file
@@ -0,0 +1,2 @@
|
||||
CompileFlags:
|
||||
Add: [-Wall, -Wextra, -Wpedantic, -Wno-unused-parameter]
|
||||
17
.github/workflows/format-check.yml
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
# .github/workflows/format-check.yml
|
||||
name: Code Format Check
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
formatting:
|
||||
runs-on: ubuntu-latest
|
||||
container: silkeh/clang:latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Run clang-format
|
||||
run: |
|
||||
find src include -name '*.cpp' -o -name '*.h' -print0 | xargs -0 clang-format --dry-run --Werror
|
||||
2
.gitignore
vendored
@@ -40,3 +40,5 @@ CMakeError.log
|
||||
*.swo
|
||||
*~
|
||||
.DS_Store
|
||||
assets/config.toml
|
||||
.venv/
|
||||
8
.pre-commit-config.yaml
Normal file
@@ -0,0 +1,8 @@
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/mirrors-clang-format
|
||||
rev: "v22.1.4"
|
||||
hooks:
|
||||
- id: clang-format
|
||||
args: ["--style=file"]
|
||||
types_or: ["c++", "c"]
|
||||
exclude: '^third_party/.*$'
|
||||
1
.python-version
Normal file
@@ -0,0 +1 @@
|
||||
3.14
|
||||
@@ -58,6 +58,21 @@ if (WIN32)
|
||||
if(TARGET freetype)
|
||||
add_library(Freetype::Freetype ALIAS freetype)
|
||||
endif()
|
||||
set(_BUILD_SHARED_LIBS_SAVED ${BUILD_SHARED_LIBS})
|
||||
set(BUILD_SHARED_LIBS ON)
|
||||
|
||||
FetchContent_Declare(
|
||||
onetbb
|
||||
GIT_REPOSITORY https://github.com/uxlfoundation/oneTBB.git
|
||||
GIT_TAG v2023.0.0
|
||||
)
|
||||
set(BUILD_TESTING OFF CACHE BOOL "Build tests" FORCE)
|
||||
set(TBB_TEST OFF CACHE BOOL "Build TBB tests" FORCE)
|
||||
FetchContent_MakeAvailable(onetbb)
|
||||
|
||||
set(BUILD_SHARED_LIBS ${_BUILD_SHARED_LIBS_SAVED})
|
||||
unset(_BUILD_SHARED_LIBS_SAVED)
|
||||
|
||||
endif()
|
||||
|
||||
FetchContent_Declare(
|
||||
@@ -74,6 +89,14 @@ FetchContent_Declare(
|
||||
|
||||
)
|
||||
FetchContent_MakeAvailable(soil2)
|
||||
FetchContent_Declare(
|
||||
tomlplusplus
|
||||
GIT_REPOSITORY https://github.com/marzer/tomlplusplus.git
|
||||
GIT_TAG v3.4.0
|
||||
)
|
||||
FetchContent_MakeAvailable(tomlplusplus)
|
||||
|
||||
add_subdirectory(third_party/imgui)
|
||||
|
||||
set(INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include)
|
||||
|
||||
@@ -82,8 +105,11 @@ add_executable(${PROJECT_NAME}
|
||||
src/app.cpp
|
||||
src/debug_collector.cpp
|
||||
src/camera.cpp
|
||||
src/config.cpp
|
||||
src/dev_panel.cpp
|
||||
src/gameplay/biome.cpp
|
||||
src/gameplay/chunk.cpp
|
||||
src/gameplay/chunk_generator.cpp
|
||||
src/gameplay/player.cpp
|
||||
src/gameplay/tree.cpp
|
||||
src/gameplay/world.cpp
|
||||
@@ -96,24 +122,37 @@ add_executable(${PROJECT_NAME}
|
||||
src/tools/math_tools.cpp
|
||||
src/tools/shader_tools.cpp
|
||||
src/tools/font.cpp
|
||||
src/tools/log.cpp
|
||||
src/tools/perlin_noise.cpp
|
||||
src/ui/text.cpp
|
||||
src/window.cpp
|
||||
src/gameplay/builders/biome_builder.cpp
|
||||
src/gameplay/builders/plain_builder.cpp
|
||||
src/gameplay/builders/mountain_builder.cpp
|
||||
src/gameplay/builders/river_builder.cpp
|
||||
src/gameplay/builders/desert_builder.cpp
|
||||
src/gameplay/builders/forest_builder.cpp
|
||||
src/gameplay/cave_carver.cpp
|
||||
src/gameplay/cave_path.cpp
|
||||
src/gameplay/builders/snowy_plain_builder.cpp
|
||||
src/gameplay/river_worm.cpp
|
||||
src/gameplay/river_path.cpp
|
||||
src/block.cpp
|
||||
src/gameplay/vertex_data.cpp
|
||||
src/gameplay/builders/ocean_builder.cpp
|
||||
)
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
message(STATUS "Building with AddressSanitizer enabled for target: ${PROJECT_NAME}")
|
||||
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE
|
||||
-fsanitize=address
|
||||
#-fsanitize=address
|
||||
#-fsanitize=thread
|
||||
-fno-omit-frame-pointer
|
||||
-g
|
||||
)
|
||||
|
||||
target_link_options(${PROJECT_NAME} PRIVATE
|
||||
-fsanitize=address
|
||||
#-fsanitize=address
|
||||
#-fsanitize=thread
|
||||
)
|
||||
|
||||
@@ -137,10 +176,13 @@ target_link_libraries(${PROJECT_NAME}
|
||||
OpenGL::GL
|
||||
soil2
|
||||
Freetype::Freetype
|
||||
tomlplusplus::tomlplusplus
|
||||
imgui
|
||||
tbb
|
||||
)
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE tbb)
|
||||
# target_link_libraries(${PROJECT_NAME} PRIVATE tbb)
|
||||
endif()
|
||||
|
||||
if (UNIX AND NOT APPLE)
|
||||
@@ -160,3 +202,19 @@ if (UNIX AND NOT APPLE)
|
||||
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE ${EGL_CFLAGS_OTHER} ${Wayland_CFLAGS_OTHER})
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
foreach(TBB_LIB IN ITEMS tbb tbbmalloc tbbmalloc_proxy)
|
||||
if(TARGET ${TBB_LIB})
|
||||
add_custom_command(
|
||||
TARGET ${PROJECT_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
$<TARGET_FILE:${TBB_LIB}>
|
||||
$<TARGET_FILE_DIR:${PROJECT_NAME}>
|
||||
COMMENT "Copying ${TBB_LIB}.dll"
|
||||
)
|
||||
else()
|
||||
message(STATUS "Target ${TBB_LIB} not found, skipping copy")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
19
README.md
@@ -1,2 +1,21 @@
|
||||
## What's it
|
||||
A cube game like Minecraft, using C++ and OpenGL.
|
||||
|
||||
## Build Guide
|
||||
### Prerequisites
|
||||
- **CMake** (>= 3.24)
|
||||
- **C++ 23** compatible compiler
|
||||
### Step
|
||||
1. Clone the repository
|
||||
```bash
|
||||
git clone https://github.com/zhenyan121/Cubed.git && cd Cubed
|
||||
```
|
||||
2. Configure with CMake
|
||||
```bash
|
||||
mkdir build && cd build
|
||||
cmake -G "Ninja" ..
|
||||
```
|
||||
3. Build the project
|
||||
```bash
|
||||
ninja
|
||||
```
|
||||
10
assets/data/block/air.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
id = 0
|
||||
is_blend = false
|
||||
is_cross_plane = false
|
||||
is_discard = true
|
||||
is_gas = true
|
||||
is_liquid = false
|
||||
is_passable = true
|
||||
is_transitional = false
|
||||
is_transparent = true
|
||||
name = 'air'
|
||||
10
assets/data/block/dirt.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
id = 2
|
||||
is_blend = false
|
||||
is_cross_plane = false
|
||||
is_discard = false
|
||||
is_gas = false
|
||||
is_liquid = false
|
||||
is_passable = false
|
||||
is_transitional = true
|
||||
is_transparent = false
|
||||
name = 'dirt'
|
||||
10
assets/data/block/grass.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
id = 9
|
||||
is_blend = false
|
||||
is_cross_plane = true
|
||||
is_discard = true
|
||||
is_gas = false
|
||||
is_liquid = false
|
||||
is_passable = true
|
||||
is_transitional = false
|
||||
is_transparent = true
|
||||
name = 'grass'
|
||||
10
assets/data/block/grass_block.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
id = 1
|
||||
is_blend = false
|
||||
is_cross_plane = false
|
||||
is_discard = false
|
||||
is_gas = false
|
||||
is_liquid = false
|
||||
is_passable = false
|
||||
is_transitional = true
|
||||
is_transparent = false
|
||||
name = 'grass_block'
|
||||
10
assets/data/block/leaf.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
id = 6
|
||||
is_blend = false
|
||||
is_cross_plane = false
|
||||
is_discard = true
|
||||
is_gas = false
|
||||
is_liquid = false
|
||||
is_passable = false
|
||||
is_transitional = false
|
||||
is_transparent = true
|
||||
name = 'leaf'
|
||||
10
assets/data/block/log.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
id = 5
|
||||
is_blend = false
|
||||
is_cross_plane = false
|
||||
is_discard = false
|
||||
is_gas = false
|
||||
is_liquid = false
|
||||
is_passable = false
|
||||
is_transitional = false
|
||||
is_transparent = false
|
||||
name = 'log'
|
||||
10
assets/data/block/sand.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
id = 4
|
||||
is_blend = false
|
||||
is_cross_plane = false
|
||||
is_discard = false
|
||||
is_gas = false
|
||||
is_liquid = false
|
||||
is_passable = false
|
||||
is_transitional = true
|
||||
is_transparent = false
|
||||
name = 'sand'
|
||||
10
assets/data/block/snowy_grass_block.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
id = 8
|
||||
is_blend = false
|
||||
is_cross_plane = false
|
||||
is_discard = false
|
||||
is_gas = false
|
||||
is_liquid = false
|
||||
is_passable = false
|
||||
is_transitional = true
|
||||
is_transparent = false
|
||||
name = 'snowy_grass_block'
|
||||
10
assets/data/block/stone.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
id = 3
|
||||
is_blend = false
|
||||
is_cross_plane = false
|
||||
is_discard = false
|
||||
is_gas = false
|
||||
is_liquid = false
|
||||
is_passable = false
|
||||
is_transitional = true
|
||||
is_transparent = false
|
||||
name = 'stone'
|
||||
10
assets/data/block/template.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
name = "template"
|
||||
id = 0
|
||||
is_liquid = false
|
||||
is_gas = false
|
||||
is_passable = false
|
||||
is_cross_plane = false
|
||||
is_transparent = false
|
||||
is_discard = false
|
||||
is_blend = false
|
||||
is_transitional = false
|
||||
10
assets/data/block/water.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
id = 7
|
||||
is_blend = true
|
||||
is_cross_plane = false
|
||||
is_discard = false
|
||||
is_gas = false
|
||||
is_liquid = true
|
||||
is_passable = true
|
||||
is_transitional = false
|
||||
is_transparent = true
|
||||
name = 'water'
|
||||
28
assets/shaders/block_accumulation_f_shader.glsl
Normal file
@@ -0,0 +1,28 @@
|
||||
#version 460
|
||||
|
||||
layout (location = 0) out vec4 accum;
|
||||
layout (location = 1) out float reveal;
|
||||
|
||||
in vec2 tc;
|
||||
flat in int tex_layer;
|
||||
in float v_depth;
|
||||
layout (binding = 0) uniform sampler2DArray samp;
|
||||
|
||||
float weight(float z, float a) {
|
||||
float intermediate = 0.03 / (1e-5 + pow(z / 200.0, 4.0));
|
||||
|
||||
return a * clamp(intermediate, 1e-2, 3e2);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 color = texture(samp, vec3(tc, tex_layer));
|
||||
float alpha = color.a;
|
||||
if (alpha < 1e-4) discard;
|
||||
|
||||
|
||||
float w = weight(v_depth, alpha);
|
||||
|
||||
accum = vec4(color.rgb * alpha * w, alpha * w);
|
||||
|
||||
reveal = alpha;
|
||||
}
|
||||
21
assets/shaders/block_accumulation_v_shader.glsl
Normal file
@@ -0,0 +1,21 @@
|
||||
#version 460
|
||||
|
||||
layout (location = 0) in vec3 pos;
|
||||
layout (location = 1) in vec2 texCoord;
|
||||
layout (location = 2) in float layer;
|
||||
out vec2 tc;
|
||||
flat out int tex_layer;
|
||||
out float v_depth;
|
||||
|
||||
uniform mat4 mv_matrix;
|
||||
uniform mat4 proj_matrix;
|
||||
|
||||
|
||||
|
||||
void main(void) {
|
||||
vec4 view_pos = mv_matrix * vec4(pos, 1.0);
|
||||
gl_Position = proj_matrix * view_pos;
|
||||
tc = texCoord;
|
||||
tex_layer = int(layer);
|
||||
v_depth = -view_pos.z;
|
||||
}
|
||||
19
assets/shaders/block_composite_f_shader.glsl
Normal file
@@ -0,0 +1,19 @@
|
||||
#version 460
|
||||
|
||||
uniform sampler2D u_accumTex;
|
||||
uniform sampler2D u_revealTex;
|
||||
in vec2 TexCoord;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main() {
|
||||
vec4 a = texture(u_accumTex, TexCoord);
|
||||
float r = texture(u_revealTex, TexCoord).r;
|
||||
|
||||
if (a.a < 1e-4) discard;
|
||||
|
||||
vec3 color = a.rgb / max(a.a, 1e-5);
|
||||
float transmittance = r;
|
||||
float opacity = 1.0 - transmittance;
|
||||
|
||||
FragColor = vec4(color * opacity, opacity);
|
||||
}
|
||||
11
assets/shaders/block_composite_v_shader.glsl
Normal file
@@ -0,0 +1,11 @@
|
||||
#version 460
|
||||
|
||||
layout (location = 0) in vec2 pos;
|
||||
layout (location = 1) in vec2 texCoord;
|
||||
|
||||
out vec2 TexCoord;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(pos.x, pos.y, 0.0, 1.0);
|
||||
TexCoord = texCoord;
|
||||
}
|
||||
@@ -8,7 +8,7 @@ layout (binding = 0) uniform sampler2DArray samp;
|
||||
|
||||
void main(void) {
|
||||
color = texture(samp, vec3(tc, tex_layer));
|
||||
if (color.a < 0.5) {
|
||||
if (color.a < 0.8) {
|
||||
discard;
|
||||
}
|
||||
//color = varyingColor;
|
||||
|
||||
35
assets/shaders/under_water_f_shader.glsl
Normal file
@@ -0,0 +1,35 @@
|
||||
#version 460
|
||||
|
||||
in vec2 TexCoord;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
uniform sampler2D u_sceneTexture;
|
||||
uniform float u_time;
|
||||
uniform bool u_underwater;
|
||||
uniform vec3 u_waterColor;
|
||||
uniform float u_fogDensity;
|
||||
|
||||
void main() {
|
||||
vec4 original = texture(u_sceneTexture, TexCoord);
|
||||
|
||||
if (!u_underwater) {
|
||||
FragColor = original;
|
||||
return;
|
||||
}
|
||||
|
||||
vec2 distoredUV = TexCoord;
|
||||
float strength = 0.003;
|
||||
distoredUV.x += sin(TexCoord.y * 15.0 + u_time * 5.0) * strength;
|
||||
distoredUV.y += cos(TexCoord.x * 15.0 + u_time * 4.3) * strength;
|
||||
distoredUV = clamp(distoredUV, 0.001, 0.999);
|
||||
vec4 distorted = texture(u_sceneTexture, distoredUV);
|
||||
|
||||
float caustic = 0.9 + 0.1 * sin(TexCoord.x * 20.0 + u_time) * cos(TexCoord.y * 20.0 + u_time * 1.2);
|
||||
vec3 causticLight = vec3(caustic, caustic * 0.95, caustic * 0.9);
|
||||
//vec3 causticLight = vec3(1.0);
|
||||
float fogFactor = clamp(1.0 - (TexCoord.y * u_fogDensity * 10.0), 0.0, 1.0);
|
||||
vec3 mixed = mix(u_waterColor, distorted.rgb * causticLight, fogFactor);
|
||||
|
||||
FragColor = vec4(mixed, 1.0);
|
||||
}
|
||||
11
assets/shaders/under_water_v_shader.glsl
Normal file
@@ -0,0 +1,11 @@
|
||||
#version 460
|
||||
|
||||
layout (location = 0) in vec2 pos;
|
||||
layout (location = 1) in vec2 texCoord;
|
||||
|
||||
out vec2 TexCoord;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(pos.x, pos.y, 0.0, 1.0);
|
||||
TexCoord = texCoord;
|
||||
}
|
||||
BIN
assets/texture/block/grass/cross.png
Normal file
|
After Width: | Height: | Size: 277 B |
|
Before Width: | Height: | Size: 563 B After Width: | Height: | Size: 555 B |
|
Before Width: | Height: | Size: 563 B After Width: | Height: | Size: 555 B |
|
Before Width: | Height: | Size: 563 B After Width: | Height: | Size: 555 B |
|
Before Width: | Height: | Size: 563 B After Width: | Height: | Size: 555 B |
|
Before Width: | Height: | Size: 399 B After Width: | Height: | Size: 381 B |
BIN
assets/texture/block/snowy_grass_block/back.png
Normal file
|
After Width: | Height: | Size: 568 B |
BIN
assets/texture/block/snowy_grass_block/base.png
Normal file
|
After Width: | Height: | Size: 482 B |
BIN
assets/texture/block/snowy_grass_block/front.png
Normal file
|
After Width: | Height: | Size: 568 B |
BIN
assets/texture/block/snowy_grass_block/left.png
Normal file
|
After Width: | Height: | Size: 568 B |
BIN
assets/texture/block/snowy_grass_block/right.png
Normal file
|
After Width: | Height: | Size: 568 B |
BIN
assets/texture/block/snowy_grass_block/top.png
Normal file
|
After Width: | Height: | Size: 394 B |
BIN
assets/texture/block/water/back.png
Normal file
|
After Width: | Height: | Size: 261 B |
BIN
assets/texture/block/water/base.png
Normal file
|
After Width: | Height: | Size: 261 B |
BIN
assets/texture/block/water/front.png
Normal file
|
After Width: | Height: | Size: 261 B |
BIN
assets/texture/block/water/left.png
Normal file
|
After Width: | Height: | Size: 261 B |
BIN
assets/texture/block/water/right.png
Normal file
|
After Width: | Height: | Size: 261 B |
BIN
assets/texture/block/water/top.png
Normal file
|
After Width: | Height: | Size: 261 B |
BIN
assets/texture/item/block/air.png
Normal file
|
After Width: | Height: | Size: 99 B |
BIN
assets/texture/item/block/dirt.png
Normal file
|
After Width: | Height: | Size: 882 B |
BIN
assets/texture/item/block/grass.png
Normal file
|
After Width: | Height: | Size: 277 B |
BIN
assets/texture/item/block/grass_block.png
Normal file
|
After Width: | Height: | Size: 499 B |
BIN
assets/texture/item/block/leaf.png
Normal file
|
After Width: | Height: | Size: 890 B |
BIN
assets/texture/item/block/log.png
Normal file
|
After Width: | Height: | Size: 874 B |
BIN
assets/texture/item/block/sand.png
Normal file
|
After Width: | Height: | Size: 877 B |
BIN
assets/texture/item/block/snowy_grass_block.png
Normal file
|
After Width: | Height: | Size: 914 B |
BIN
assets/texture/item/block/stone.png
Normal file
|
After Width: | Height: | Size: 915 B |
BIN
assets/texture/item/block/water.png
Normal file
|
After Width: | Height: | Size: 874 B |
@@ -1,15 +1,14 @@
|
||||
#pragma once
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
namespace Cubed {
|
||||
|
||||
struct AABB {
|
||||
glm::vec3 min{0.0f, 0.0f, 0.0f};
|
||||
glm::vec3 max{0.0f, 0.0f, 0.0f};
|
||||
|
||||
AABB(glm::vec3 min_point, glm::vec3 max_point):
|
||||
min(min_point),
|
||||
max(max_point)
|
||||
{
|
||||
|
||||
}
|
||||
AABB(glm::vec3 min_point, glm::vec3 max_point)
|
||||
: min(min_point), max(max_point) {}
|
||||
|
||||
bool intersects(const AABB& other) const {
|
||||
return (min.x <= other.max.x && max.x >= other.min.x) &&
|
||||
@@ -17,3 +16,5 @@ struct AABB {
|
||||
(min.z <= other.max.z && max.z >= other.min.z);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
@@ -1,33 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
#include <Cubed/camera.hpp>
|
||||
#include <Cubed/gameplay/world.hpp>
|
||||
#include <Cubed/input.hpp>
|
||||
#include <Cubed/renderer.hpp>
|
||||
#include <Cubed/texture_manager.hpp>
|
||||
#include <Cubed/window.hpp>
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include "Cubed/camera.hpp"
|
||||
#include "Cubed/dev_panel.hpp"
|
||||
#include "Cubed/gameplay/world.hpp"
|
||||
#include "Cubed/renderer.hpp"
|
||||
#include "Cubed/texture_manager.hpp"
|
||||
#include "Cubed/window.hpp"
|
||||
namespace Cubed {
|
||||
|
||||
class App {
|
||||
public:
|
||||
App();
|
||||
~App();
|
||||
static void cursor_position_callback(GLFWwindow* window, double xpos, double ypos);
|
||||
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);
|
||||
static void mouse_button_callback(GLFWwindow* window, int button, int action, int mods);
|
||||
static void cursor_position_callback(GLFWwindow* window, double xpos,
|
||||
double ypos);
|
||||
static void key_callback(GLFWwindow* window, int key, int scancode,
|
||||
int action, int mods);
|
||||
static void mouse_button_callback(GLFWwindow* window, int button,
|
||||
int action, int mods);
|
||||
static void window_focus_callback(GLFWwindow* window, int focused);
|
||||
static void window_reshape_callback(GLFWwindow* window, int new_width, int new_height);
|
||||
static void mouse_scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
|
||||
|
||||
static void window_reshape_callback(GLFWwindow* window, int new_width,
|
||||
int new_height);
|
||||
static void mouse_scroll_callback(GLFWwindow* window, double xoffset,
|
||||
double yoffset);
|
||||
static void cursor_enter_callback(GLFWwindow* window, int entered);
|
||||
static void char_callback(GLFWwindow* window, unsigned int ch);
|
||||
static int start_cubed_application(int argc, char** argv);
|
||||
|
||||
static unsigned int seed();
|
||||
static float delte_time();
|
||||
static float get_fps();
|
||||
|
||||
Camera& camera();
|
||||
DevPanel& dev_panel();
|
||||
Renderer& renderer();
|
||||
TextureManager& texture_manager();
|
||||
Window& window();
|
||||
World& world();
|
||||
|
||||
private:
|
||||
Camera m_camera;
|
||||
TextureManager m_texture_manager;
|
||||
World m_world;
|
||||
Renderer m_renderer{m_camera, m_world, m_texture_manager};
|
||||
DevPanel m_dev_panel{*this};
|
||||
Renderer m_renderer{m_camera, m_world, m_texture_manager, m_dev_panel};
|
||||
|
||||
Window m_window{m_renderer};
|
||||
|
||||
@@ -49,4 +65,4 @@ private:
|
||||
void update();
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace Cubed
|
||||
@@ -1,35 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <glad/glad.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
namespace Cubed {
|
||||
|
||||
class Player;
|
||||
|
||||
|
||||
class Camera {
|
||||
private:
|
||||
|
||||
bool m_firse_mouse = true;
|
||||
Player* m_player;
|
||||
float m_last_mouse_x, m_last_mouse_y;
|
||||
glm::vec3 m_camera_pos;
|
||||
|
||||
bool m_under_water = false;
|
||||
|
||||
public:
|
||||
|
||||
Camera();
|
||||
|
||||
void update_move_camera();
|
||||
|
||||
void camera_init(Player* player);
|
||||
void hot_reload();
|
||||
void reset_camera();
|
||||
void update_cursor_position_camera(double xpos, double ypos);
|
||||
|
||||
const glm::mat4 get_camera_lookat() const;
|
||||
const glm::vec3& get_camera_pos() const;
|
||||
|
||||
bool is_under_water() const;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Cubed
|
||||
|
||||
@@ -1,150 +1,107 @@
|
||||
#pragma once
|
||||
constexpr int WORLD_SIZE_Y = 256;
|
||||
constexpr int MAX_BLOCK_NUM = 7;
|
||||
constexpr int MAX_UI_NUM = 1;
|
||||
#include "Cubed/tools/cubed_assert.hpp"
|
||||
|
||||
constexpr int CHUCK_SIZE = 16;
|
||||
constexpr int DISTANCE = 24;
|
||||
constexpr int MAX_BLOCK_STATUS = 1;
|
||||
constexpr int MAX_CHARACTER = 128;
|
||||
constexpr float NORMAL_FOV = 70.0f;
|
||||
#include <toml++/toml.hpp>
|
||||
|
||||
constexpr int MAX_BIOME_SUM = 4;
|
||||
namespace Cubed {
|
||||
|
||||
constexpr float VERTICES_POS[6][6][3] = {
|
||||
// ===== front (z = +1) =====
|
||||
0.0f, 0.0f, 1.0f, // bottom left
|
||||
0.0f, 1.0f, 1.0f, // top left
|
||||
1.0f, 1.0f, 1.0f, // top right
|
||||
1.0f, 1.0f, 1.0f, // top right
|
||||
1.0f, 0.0f, 1.0f, // bottom right
|
||||
0.0f, 0.0f, 1.0f, // bottom left
|
||||
// ===== right (x = +1) =====
|
||||
1.0f, 0.0f, 1.0f, // bottom front
|
||||
1.0f, 0.0f, 0.0f, // bottom back
|
||||
1.0f, 1.0f, 0.0f, // top back
|
||||
1.0f, 1.0f, 0.0f, // top back
|
||||
1.0f, 1.0f, 1.0f, // top front
|
||||
1.0f, 0.0f, 1.0f, // bottom front
|
||||
// ===== back (z = -1) =====
|
||||
0.0f, 0.0f, 0.0f, // bottom left
|
||||
1.0f, 0.0f, 0.0f, // bottom right
|
||||
1.0f, 1.0f, 0.0f, // top right
|
||||
1.0f, 1.0f, 0.0f, // top right
|
||||
0.0f, 1.0f, 0.0f, // top left
|
||||
0.0f, 0.0f, 0.0f, // bottom left
|
||||
// ===== left (x = -1) =====
|
||||
0.0f, 0.0f, 0.0f, // bottom back
|
||||
0.0f, 0.0f, 1.0f, // bottom front
|
||||
0.0f, 1.0f, 1.0f, // top front
|
||||
0.0f, 1.0f, 1.0f, // top front
|
||||
0.0f, 1.0f, 0.0f, // top back
|
||||
0.0f, 0.0f, 0.0f, // bottom back
|
||||
// ===== top (y = +1) =====
|
||||
0.0f, 1.0f, 0.0f, // back left
|
||||
1.0f, 1.0f, 0.0f, // back right
|
||||
1.0f, 1.0f, 1.0f, // front right
|
||||
1.0f, 1.0f, 1.0f, // front right
|
||||
0.0f, 1.0f, 1.0f, // front left
|
||||
0.0f, 1.0f, 0.0f, // back left
|
||||
// ===== bottom (y = -1) =====
|
||||
0.0f, 0.0f, 1.0f, // front left
|
||||
1.0f, 0.0f, 1.0f, // front right
|
||||
1.0f, 0.0f, 0.0f, // back right
|
||||
1.0f, 0.0f, 0.0f, // back right
|
||||
0.0f, 0.0f, 0.0f, // back left
|
||||
0.0f, 0.0f, 1.0f // front left
|
||||
};
|
||||
template <typename T>
|
||||
concept TomlValueType =
|
||||
std::same_as<T, int> || std::same_as<T, bool> || std::same_as<T, double> ||
|
||||
std::same_as<T, const char*> || std::same_as<T, toml::date> ||
|
||||
std::same_as<T, toml::time> || std::same_as<T, toml::date_time> ||
|
||||
std::same_as<T, std::string>;
|
||||
|
||||
constexpr float TEX_COORDS[6][6][2] = {
|
||||
// ===== front (z = +1) =====
|
||||
0.0f, 1.0f, // bottom left
|
||||
0.0f, 0.0f, // top left
|
||||
1.0f, 0.0f, // top right
|
||||
1.0f, 0.0f, // top right
|
||||
1.0f, 1.0f, // bottom right
|
||||
0.0f, 1.0f, // bottom left
|
||||
// ===== right (x = +1) =====
|
||||
0.0f, 1.0f, // bottom front
|
||||
1.0f, 1.0f, // bottom back
|
||||
1.0f, 0.0f, // top back
|
||||
1.0f, 0.0f, // top back
|
||||
0.0f, 0.0f, // top front
|
||||
0.0f, 1.0f, // bottom front
|
||||
// ===== back (z = -1) =====
|
||||
1.0f, 1.0f, // bottom left
|
||||
0.0f, 1.0f, // bottom right
|
||||
0.0f, 0.0f, // top right
|
||||
0.0f, 0.0f, // top right
|
||||
1.0f, 0.0f, // top left
|
||||
1.0f, 1.0f, // bottom left
|
||||
// ===== left (x = -1) =====
|
||||
1.0f, 1.0f, // bottom back
|
||||
0.0f, 1.0f, // bottom front
|
||||
0.0f, 0.0f, // top front
|
||||
0.0f, 0.0f, // top front
|
||||
1.0f, 0.0f, // top back
|
||||
1.0f, 1.0f, // bottom back
|
||||
// ===== top (y = +1) =====
|
||||
0.0f, 0.0f, // back left
|
||||
1.0f, 0.0f, // back right
|
||||
1.0f, 1.0f, // front right
|
||||
1.0f, 1.0f, // front right
|
||||
0.0f, 1.0f, // front left
|
||||
0.0f, 0.0f, // back left
|
||||
// ===== bottom (y = -1) =====
|
||||
0.0f, 0.0f, // front left
|
||||
1.0f, 0.0f, // front right
|
||||
1.0f, 1.0f, // back right
|
||||
1.0f, 1.0f, // back right
|
||||
0.0f, 1.0f, // back left
|
||||
0.0f, 0.0f, // front left
|
||||
class Config {
|
||||
public:
|
||||
Config();
|
||||
~Config();
|
||||
|
||||
static Config& get();
|
||||
|
||||
toml::table& table();
|
||||
|
||||
void load_or_create_config();
|
||||
void save_to_file();
|
||||
|
||||
template <TomlValueType T> T get(std::string_view key) const {
|
||||
size_t cur = 0;
|
||||
auto pos = key.find('.');
|
||||
const toml::table* table = &m_tbl;
|
||||
while (pos != std::string_view::npos) {
|
||||
std::string_view s = key.substr(cur, pos - cur);
|
||||
if (s.empty()) {
|
||||
Logger::error("Empty key/table name in path '{}'", key);
|
||||
ASSERT(false);
|
||||
std::abort();
|
||||
}
|
||||
cur = pos + 1;
|
||||
pos = key.find('.', cur);
|
||||
if (auto* next = (*table)[s].as_table()) {
|
||||
table = next;
|
||||
} else {
|
||||
Logger::error("Can't find table {}", s);
|
||||
ASSERT(false);
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
std::string_view n_key = key.substr(cur);
|
||||
if (n_key.empty()) {
|
||||
Logger::error("Trailing dot in path '{}'", key);
|
||||
ASSERT(false);
|
||||
std::abort();
|
||||
}
|
||||
auto opt = (*table)[n_key].value<T>();
|
||||
if (opt) {
|
||||
return *opt;
|
||||
} else {
|
||||
Logger::error("Can't find key {}", n_key);
|
||||
ASSERT(false);
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
template <typename T> void set(std::string_view key, T&& val) {
|
||||
if constexpr (!TomlValueType<std::decay_t<T>>) {
|
||||
static_assert(false, "Type Not Support");
|
||||
}
|
||||
size_t cur = 0;
|
||||
auto pos = key.find('.');
|
||||
toml::table* table = &m_tbl;
|
||||
while (pos != std::string_view::npos) {
|
||||
std::string_view s = key.substr(cur, pos - cur);
|
||||
if (s.empty()) {
|
||||
Logger::error("Empty key/table name in path '{}'", key);
|
||||
ASSERT(false);
|
||||
std::abort();
|
||||
}
|
||||
cur = pos + 1;
|
||||
pos = key.find('.', cur);
|
||||
if (auto* next = (*table)[s].as_table()) {
|
||||
table = next;
|
||||
} else {
|
||||
auto [it, inserted] = table->insert_or_assign(s, toml::table{});
|
||||
table = it->second.as_table();
|
||||
}
|
||||
}
|
||||
std::string_view n_key = key.substr(cur);
|
||||
if (n_key.empty()) {
|
||||
Logger::error("Trailing dot in path '{}'", key);
|
||||
ASSERT(false);
|
||||
std::abort();
|
||||
}
|
||||
table->insert_or_assign(n_key, std::forward<T>(val));
|
||||
}
|
||||
template <typename T> void set_and_save(std::string_view key, T&& val) {
|
||||
set(key, std::forward(val));
|
||||
save_to_file();
|
||||
}
|
||||
toml::node_view<toml::node> val_view(std::string_view key);
|
||||
|
||||
private:
|
||||
toml::table m_tbl;
|
||||
constexpr static inline std::string_view CONGIF_PATH =
|
||||
ASSETS_PATH "config.toml";
|
||||
void create_config();
|
||||
};
|
||||
|
||||
constexpr float CUBE_VER[24] = {
|
||||
0.0, 0.0, 0.0,
|
||||
1.0, 0.0, 0.0,
|
||||
1.0, 1.0, 0.0,
|
||||
0.0, 1.0, 0.0,
|
||||
0.0, 0.0, 1.0,
|
||||
1.0, 0.0, 1.0,
|
||||
1.0, 1.0, 1.0,
|
||||
0.0, 1.0, 1.0
|
||||
};
|
||||
|
||||
|
||||
constexpr int OUTLINE_CUBE_INDICES[24] = {
|
||||
0,1, 1,2, 2,3, 3,0,
|
||||
4,5, 5,6, 6,7, 7,4,
|
||||
0,4, 1,5, 2,6, 3,7
|
||||
};
|
||||
|
||||
constexpr float SQUARE_VERTICES[6][2] = {
|
||||
-0.5f, -0.5f, // bottom left
|
||||
-0.5f, 0.5f, // top left
|
||||
0.5f, 0.5f, // top right
|
||||
0.5f, 0.5f, // top right
|
||||
0.5f, -0.5f, // bottom right
|
||||
-0.5f, -0.5f // bottom left
|
||||
};
|
||||
|
||||
constexpr float SQUARE_TEXTURE_POS[6][2] = {
|
||||
0.0f, 0.0f,
|
||||
0.0f, 1.0f,
|
||||
1.0f, 1.0f,
|
||||
1.0f, 1.0f,
|
||||
1.0f, 0.0f,
|
||||
0.0f, 0.0f,
|
||||
};
|
||||
|
||||
struct Vertex {
|
||||
float x = 0.0f, y = 0.0f, z = 0.0f;
|
||||
float s = 0.0f, t = 0.0f;
|
||||
float layer = 0.0f;
|
||||
};
|
||||
|
||||
struct Vertex2D {
|
||||
float x = 0.0f, y = 0.0f;
|
||||
float s = 0.0f, t = 0.0f;
|
||||
float layer = 0.0f;
|
||||
};
|
||||
} // namespace Cubed
|
||||
|
||||
35
include/Cubed/constants.hpp
Normal file
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
#include "Cubed/gameplay/chunk_pos.hpp"
|
||||
|
||||
#include <array>
|
||||
namespace Cubed {
|
||||
|
||||
constexpr int WORLD_SIZE_Y = 256;
|
||||
constexpr int CHUNK_SIZE = 16;
|
||||
constexpr int SEA_LEVEL = 63;
|
||||
|
||||
constexpr int MAX_UI_NUM = 1;
|
||||
constexpr int MAX_BLOCK_STATUS = 1;
|
||||
constexpr int MAX_BIOME_SUM = 4;
|
||||
constexpr int MAX_CHARACTER = 128;
|
||||
|
||||
constexpr int PRE_LOAD_DISTANCE = 24;
|
||||
|
||||
constexpr int MAX_DISTANCE = 128;
|
||||
constexpr int CROSS_PLANE_DISTANCE = 8;
|
||||
constexpr float DEFAULT_FOV = 70.0f;
|
||||
constexpr float DEFAULT_MAX_WALK_SPEED = 4.5f;
|
||||
constexpr float DEFAULT_MAX_RUN_SPEED = 7.0f;
|
||||
constexpr float DEFAULT_ACCELERATION = 10.0f;
|
||||
constexpr float DEFAULT_DECELERATION = 15.0f;
|
||||
constexpr float DEFAULT_G = 22.5f;
|
||||
static constexpr int SIZE_X = CHUNK_SIZE;
|
||||
static constexpr int SIZE_Y = WORLD_SIZE_Y;
|
||||
static constexpr int SIZE_Z = CHUNK_SIZE;
|
||||
|
||||
constexpr ChunkPos CHUNK_DIR[]{{1, 0}, {-1, 0}, {0, 1}, {0, -1},
|
||||
{1, 1}, {-1, 1}, {1, -1}, {-1, -1}};
|
||||
|
||||
using HeightMapArray = std::array<std::array<int, CHUNK_SIZE>, CHUNK_SIZE>;
|
||||
|
||||
} // namespace Cubed
|
||||
@@ -1,9 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <Cubed/ui/text.hpp>
|
||||
#include "Cubed/ui/text.hpp"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
namespace Cubed {
|
||||
|
||||
class DebugCollector {
|
||||
public:
|
||||
static DebugCollector& get();
|
||||
@@ -18,3 +20,5 @@ public:
|
||||
private:
|
||||
std::unordered_map<std::size_t, Text> m_texts;
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
60
include/Cubed/dev_panel.hpp
Normal file
@@ -0,0 +1,60 @@
|
||||
#pragma once
|
||||
|
||||
#include <toml++/toml.hpp>
|
||||
|
||||
namespace Cubed {
|
||||
|
||||
class App;
|
||||
class Player;
|
||||
class DevPanel {
|
||||
struct ConfigView {
|
||||
float fov = 70.0f;
|
||||
bool fullscreen = false;
|
||||
bool v_sync = true;
|
||||
float mouse_sensitivity = 0.15f;
|
||||
int width = 800;
|
||||
int height = 600;
|
||||
int rendering_distance = 24;
|
||||
int aniso = 1;
|
||||
int max_aniso = 1;
|
||||
bool is_enable_aniso = false;
|
||||
bool is_support_aniso = true;
|
||||
bool is_reload = true;
|
||||
};
|
||||
struct PlayerProfile {
|
||||
int game_mode = 0;
|
||||
int gait = 0;
|
||||
float pos[3] = {0.0f, 0.0f, 0.0f};
|
||||
};
|
||||
struct TextEditing {
|
||||
bool perlin_seed = false;
|
||||
};
|
||||
|
||||
public:
|
||||
DevPanel(App& app);
|
||||
void init();
|
||||
void render();
|
||||
|
||||
private:
|
||||
App& m_app;
|
||||
ConfigView m_config;
|
||||
Player* m_player;
|
||||
PlayerProfile m_player_profile;
|
||||
TextEditing m_text_editing;
|
||||
bool m_need_save_config = false;
|
||||
bool m_gen_thread_running = true;
|
||||
int m_theme = 0;
|
||||
void show_about_table_bar();
|
||||
void show_biome_table_bar();
|
||||
void show_cave_table_bar();
|
||||
void show_river_table_bar();
|
||||
void show_settings_tab_item();
|
||||
void show_world_tab_item();
|
||||
void show_player_tab_item();
|
||||
void show_items_tab_item();
|
||||
|
||||
void update_config_view();
|
||||
void update_player_profile();
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
@@ -1,19 +1,28 @@
|
||||
#pragma once
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
constexpr float BIOME_NOISE_FREQUENCY = 0.003f;
|
||||
namespace Cubed {
|
||||
|
||||
constexpr float PLAIN_FREQ = 0.4f;
|
||||
constexpr float FOREST_FREQ = 1.2f;
|
||||
constexpr float DESERT_FREQ = 1.2f;
|
||||
constexpr float MOUNTAIN_FREQ = 2.0f;
|
||||
|
||||
enum class Biome {
|
||||
constexpr float BIOME_NOISE_FREQUENCY = 0.06f;
|
||||
constexpr float HEIGHTMAP_NOISE_FREQUENCY = 0.001f;
|
||||
constexpr float MOUNTAINOUS_NOISE_FREQUENCY = 0.003f;
|
||||
enum class BiomeType {
|
||||
PLAIN = 0,
|
||||
FOREST,
|
||||
DESERT,
|
||||
MOUNTAIN
|
||||
MOUNTAIN,
|
||||
RIVER,
|
||||
SNOWY_PLAIN,
|
||||
OCEAN,
|
||||
NONE
|
||||
};
|
||||
|
||||
struct BiomeConditions {
|
||||
float temp = 0.0f;
|
||||
float humid = 0.0f;
|
||||
float mountainous = 0.0f;
|
||||
};
|
||||
|
||||
struct BiomeHeightRange {
|
||||
@@ -21,10 +30,51 @@ struct BiomeHeightRange {
|
||||
int amplitude;
|
||||
};
|
||||
|
||||
std::string get_biome_str(Biome biome);
|
||||
Biome get_biome_from_noise(float temp, float humid);
|
||||
std::array<float, 3> get_noise_frequencies_for_biome(Biome biome);
|
||||
BiomeHeightRange get_biome_height_range(Biome biome);
|
||||
Biome safe_int_to_biome(int x);
|
||||
int get_interpolated_height(float world_x, float world_z, float temp, float humid);
|
||||
struct BiomeNonAdjacent {
|
||||
BiomeType first;
|
||||
std::vector<BiomeType> second;
|
||||
BiomeType replace;
|
||||
};
|
||||
|
||||
static inline const std::vector<BiomeNonAdjacent> NON_ADJACENT{
|
||||
{{BiomeType::PLAIN, {BiomeType::DESERT}, BiomeType::RIVER},
|
||||
{BiomeType::FOREST, {BiomeType::DESERT}, BiomeType::RIVER},
|
||||
{BiomeType::DESERT, {BiomeType::FOREST}, BiomeType::RIVER},
|
||||
{BiomeType::MOUNTAIN, {BiomeType::NONE}, BiomeType::RIVER}}};
|
||||
|
||||
struct BaseBiomeParams {
|
||||
BiomeType biome;
|
||||
std::pair<float, float> temp;
|
||||
std::pair<float, float> humid;
|
||||
std::array<float, 3> frequencies;
|
||||
BiomeHeightRange height_range;
|
||||
};
|
||||
|
||||
struct PlainParams : public BaseBiomeParams {};
|
||||
|
||||
struct ForestParams : public BaseBiomeParams {
|
||||
float tree_frequency;
|
||||
};
|
||||
|
||||
struct DesertParams : public BaseBiomeParams {};
|
||||
|
||||
struct MountainParams : public BaseBiomeParams {};
|
||||
|
||||
struct RiverParams : public BaseBiomeParams {};
|
||||
|
||||
std::string get_biome_str(BiomeType biome);
|
||||
// std::array<float, 3> get_noise_frequencies_for_biome(BiomeType biome);
|
||||
// BiomeHeightRange get_biome_height_range(BiomeType biome);
|
||||
BiomeType safe_int_to_biome(int x);
|
||||
int get_interpolated_height(float world_x, float world_z, float temp,
|
||||
float humid);
|
||||
|
||||
BiomeType determine_biome(const BiomeConditions& conditions);
|
||||
|
||||
PlainParams& plain_params();
|
||||
ForestParams& forest_params();
|
||||
DesertParams& desert_params();
|
||||
MountainParams& mountain_params();
|
||||
RiverParams& river_params();
|
||||
|
||||
} // namespace Cubed
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <Cubed/config.hpp>
|
||||
#include <Cubed/tools/cubed_assert.hpp>
|
||||
namespace Cubed {
|
||||
|
||||
using BlockType = uint8_t;
|
||||
|
||||
struct BlockTexture {
|
||||
std::string name;
|
||||
unsigned id;
|
||||
std::vector<GLuint> texture;
|
||||
};
|
||||
|
||||
struct Block : public BlockTexture{
|
||||
|
||||
};
|
||||
struct Block : public BlockTexture {};
|
||||
|
||||
struct BlockRenderData {
|
||||
std::vector<bool> draw_face;
|
||||
@@ -23,12 +23,8 @@ struct BlockRenderData {
|
||||
BlockRenderData() = default;
|
||||
BlockRenderData(const BlockRenderData&) = default;
|
||||
BlockRenderData& operator=(const BlockRenderData&) = default;
|
||||
BlockRenderData(BlockRenderData&& data) :
|
||||
draw_face(std::move(data.draw_face)),
|
||||
block_id(data.block_id)
|
||||
{
|
||||
|
||||
}
|
||||
BlockRenderData(BlockRenderData&& data)
|
||||
: draw_face(std::move(data.draw_face)), block_id(data.block_id) {}
|
||||
BlockRenderData& operator=(BlockRenderData&& data) {
|
||||
draw_face = std::move(data.draw_face);
|
||||
block_id = data.block_id;
|
||||
@@ -41,27 +37,55 @@ struct LookBlock {
|
||||
glm::ivec3 normal;
|
||||
};
|
||||
|
||||
constexpr std::array<std::string_view, MAX_BLOCK_NUM> BLOCK_REISTER{
|
||||
"air",
|
||||
"grass_block",
|
||||
"dirt",
|
||||
"stone",
|
||||
"sand",
|
||||
"log",
|
||||
"leaf"
|
||||
struct BlockData {
|
||||
std::string name;
|
||||
BlockType id = 0;
|
||||
|
||||
bool is_liquid = false;
|
||||
bool is_gas = false;
|
||||
|
||||
bool is_passable = false;
|
||||
bool is_cross_plane = false;
|
||||
bool is_transparent = false;
|
||||
|
||||
bool is_discard = false;
|
||||
bool is_blend = false;
|
||||
bool is_transitional = false;
|
||||
BlockData(BlockType b_id, std::string_view b_name, bool liquid,
|
||||
bool passable, bool cross_plane, bool transparent, bool gas,
|
||||
bool discard, bool blend, bool transitional)
|
||||
: name(b_name), id(b_id), is_liquid(liquid), is_gas(gas),
|
||||
is_passable(passable), is_cross_plane(cross_plane),
|
||||
is_transparent(transparent), is_discard(discard), is_blend(blend),
|
||||
is_transitional(transitional) {}
|
||||
};
|
||||
|
||||
const std::array<bool, MAX_BLOCK_NUM> TRANSPARENT_MAP {
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
class BlockManager {
|
||||
|
||||
public:
|
||||
static const std::vector<BlockData>& datas();
|
||||
static void init();
|
||||
static unsigned sums();
|
||||
static unsigned cross_plane_sum();
|
||||
static const std::string& name_form_id(BlockType id);
|
||||
|
||||
static bool is_gas(BlockType id);
|
||||
static bool is_liquid(BlockType id);
|
||||
|
||||
static bool is_cross_plane(BlockType id);
|
||||
static bool is_transparent(BlockType id);
|
||||
static bool is_passable(BlockType id);
|
||||
|
||||
static bool is_discard(BlockType id);
|
||||
static bool is_blend(BlockType id);
|
||||
static bool is_transitional(BlockType id);
|
||||
static BlockType cross_plane_index(BlockType id);
|
||||
|
||||
private:
|
||||
static void set_up_cross_plane_map();
|
||||
static inline std::vector<BlockData> m_datas;
|
||||
static inline bool is_init = false;
|
||||
static inline std::unordered_map<BlockType, BlockType> m_cross_plane_map;
|
||||
};
|
||||
|
||||
inline bool is_in_transparent_map(unsigned id) {
|
||||
CUBED_ASSERT_MSG(id < MAX_BLOCK_NUM, "ID is invaild");
|
||||
return TRANSPARENT_MAP[id];
|
||||
};
|
||||
} // namespace Cubed
|
||||
18
include/Cubed/gameplay/builders/biome_builder.hpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
namespace Cubed {
|
||||
class ChunkGenerator;
|
||||
class BiomeBuilder {
|
||||
public:
|
||||
BiomeBuilder() = default;
|
||||
virtual ~BiomeBuilder() = default;
|
||||
virtual ChunkGenerator& get_chunk_generator() = 0;
|
||||
virtual void build_biome() = 0;
|
||||
virtual void build_vegetation() = 0;
|
||||
void ocean_water_build();
|
||||
|
||||
protected:
|
||||
void build_bottom();
|
||||
void place_grass();
|
||||
};
|
||||
} // namespace Cubed
|
||||
21
include/Cubed/gameplay/builders/desert_builder.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cubed/gameplay/builders/biome_builder.hpp"
|
||||
namespace Cubed {
|
||||
|
||||
class ChunkGenerator;
|
||||
|
||||
class DesertBuilder : public BiomeBuilder {
|
||||
public:
|
||||
DesertBuilder(ChunkGenerator& chunk_generator);
|
||||
void build_biome() override;
|
||||
ChunkGenerator& get_chunk_generator() override;
|
||||
void build_vegetation() override;
|
||||
|
||||
private:
|
||||
ChunkGenerator& m_chunk_generator;
|
||||
|
||||
void build_blocks();
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
21
include/Cubed/gameplay/builders/forest_builder.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cubed/gameplay/builders/biome_builder.hpp"
|
||||
namespace Cubed {
|
||||
|
||||
class ChunkGenerator;
|
||||
|
||||
class ForestBuilder : public BiomeBuilder {
|
||||
public:
|
||||
ForestBuilder(ChunkGenerator& chunk_generator);
|
||||
void build_biome() override;
|
||||
ChunkGenerator& get_chunk_generator() override;
|
||||
void build_vegetation() override;
|
||||
|
||||
private:
|
||||
ChunkGenerator& m_chunk_generator;
|
||||
|
||||
void build_blocks();
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
21
include/Cubed/gameplay/builders/mountain_builder.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cubed/gameplay/builders/biome_builder.hpp"
|
||||
namespace Cubed {
|
||||
|
||||
class ChunkGenerator;
|
||||
|
||||
class MountainBuilder : public BiomeBuilder {
|
||||
public:
|
||||
MountainBuilder(ChunkGenerator& chunk_generator);
|
||||
void build_biome() override;
|
||||
ChunkGenerator& get_chunk_generator() override;
|
||||
void build_vegetation() override;
|
||||
|
||||
private:
|
||||
ChunkGenerator& m_chunk_generator;
|
||||
|
||||
void build_blocks();
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
23
include/Cubed/gameplay/builders/ocean_builder.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Cubed/gameplay/builders/biome_builder.hpp"
|
||||
namespace Cubed {
|
||||
|
||||
class ChunkGenerator;
|
||||
|
||||
class OceanBuilder : public BiomeBuilder {
|
||||
public:
|
||||
OceanBuilder(ChunkGenerator& chunk_generator);
|
||||
void build_biome() override;
|
||||
ChunkGenerator& get_chunk_generator() override;
|
||||
void build_vegetation() override;
|
||||
|
||||
private:
|
||||
ChunkGenerator& m_chunk_generator;
|
||||
|
||||
void build_blocks();
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
21
include/Cubed/gameplay/builders/plain_builder.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cubed/gameplay/builders/biome_builder.hpp"
|
||||
namespace Cubed {
|
||||
|
||||
class ChunkGenerator;
|
||||
|
||||
class PlainBuilder : public BiomeBuilder {
|
||||
public:
|
||||
PlainBuilder(ChunkGenerator& chunk_generator);
|
||||
void build_biome() override;
|
||||
ChunkGenerator& get_chunk_generator() override;
|
||||
void build_vegetation() override;
|
||||
|
||||
private:
|
||||
ChunkGenerator& m_chunk_generator;
|
||||
|
||||
void build_blocks();
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
21
include/Cubed/gameplay/builders/river_builder.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cubed/gameplay/builders/biome_builder.hpp"
|
||||
namespace Cubed {
|
||||
|
||||
class ChunkGenerator;
|
||||
|
||||
class RiverBuilder : public BiomeBuilder {
|
||||
public:
|
||||
RiverBuilder(ChunkGenerator& chunk_generator);
|
||||
void build_biome() override;
|
||||
ChunkGenerator& get_chunk_generator() override;
|
||||
void build_vegetation() override;
|
||||
|
||||
private:
|
||||
ChunkGenerator& m_chunk_generator;
|
||||
|
||||
void build_blocks();
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
21
include/Cubed/gameplay/builders/snowy_plain_builder.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cubed/gameplay/builders/biome_builder.hpp"
|
||||
namespace Cubed {
|
||||
|
||||
class ChunkGenerator;
|
||||
|
||||
class SnowyPlainBuilder : public BiomeBuilder {
|
||||
public:
|
||||
SnowyPlainBuilder(ChunkGenerator& chunk_generator);
|
||||
void build_biome() override;
|
||||
ChunkGenerator& get_chunk_generator() override;
|
||||
void build_vegetation() override;
|
||||
|
||||
private:
|
||||
ChunkGenerator& m_chunk_generator;
|
||||
|
||||
void build_blocks();
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
27
include/Cubed/gameplay/cave_carver.hpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
#include "Cubed/gameplay/cave_path.hpp"
|
||||
|
||||
#include <tbb/concurrent_hash_map.h>
|
||||
namespace Cubed {
|
||||
class CaveCarver {
|
||||
using CaveHashMap = tbb::concurrent_hash_map<unsigned, CavePath>;
|
||||
|
||||
public:
|
||||
CaveCarver();
|
||||
CaveHashMap& paths();
|
||||
void init(unsigned world_seed);
|
||||
void reload(unsigned world_seed);
|
||||
void add_path(const glm::vec3& pos, unsigned chunk_seed);
|
||||
void try_to_add_path(const ChunkPos& pos, unsigned chunk_seed);
|
||||
void cleanup_finished_caves();
|
||||
|
||||
int cave_sum() const;
|
||||
float& cave_probability();
|
||||
|
||||
private:
|
||||
CaveHashMap m_paths;
|
||||
unsigned m_seed = 0;
|
||||
Random m_random;
|
||||
float m_cave_probability = 0.035f;
|
||||
};
|
||||
} // namespace Cubed
|
||||
54
include/Cubed/gameplay/cave_path.hpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cubed/gameplay/chunk_pos.hpp"
|
||||
#include "Cubed/gameplay/path_point.hpp"
|
||||
#include "Cubed/tools/cubed_random.hpp"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <tbb/concurrent_hash_map.h>
|
||||
namespace Cubed {
|
||||
|
||||
class CavePath {
|
||||
using ChunkPosSet =
|
||||
tbb::concurrent_hash_map<ChunkPos, bool, ChunkPos::TBBHash>;
|
||||
|
||||
public:
|
||||
CavePath(unsigned int chunk_seed, unsigned world_seed,
|
||||
const glm::vec3& start_pos);
|
||||
const std::vector<PathPoint>& points() const;
|
||||
void clear_chunk(const ChunkPos& pos);
|
||||
bool is_finished() const;
|
||||
|
||||
static float& radius_xz_min();
|
||||
static float& radius_xz_max();
|
||||
static float& radius_y_min();
|
||||
static float& radius_y_max();
|
||||
static float& delta_angle_min();
|
||||
static float& delta_angle_max();
|
||||
static int& step_min();
|
||||
static int& step_max();
|
||||
|
||||
private:
|
||||
static inline float m_radius_xz_min = 5.0f;
|
||||
static inline float m_radius_xz_max = 15.0f;
|
||||
static inline float m_radius_y_min = 4.0f;
|
||||
static inline float m_radius_y_max = 10.0f;
|
||||
static inline float m_delta_angle_min = -5.0f;
|
||||
static inline float m_delta_angle_max = 5.0f;
|
||||
static inline int m_step_min = 10;
|
||||
static inline int m_step_max = 400;
|
||||
|
||||
unsigned int m_seed = 0;
|
||||
float m_yaw = 0.0f;
|
||||
float m_pitch = 0.0f;
|
||||
int m_step = 0;
|
||||
float m_step_len = 1.0f;
|
||||
PathPoint m_start_path_point{{0.0f, 0.0f, 0.0f}, 0.0f, 0.0f};
|
||||
Random m_random;
|
||||
|
||||
std::vector<PathPoint> m_points;
|
||||
ChunkPosSet m_pending_chunks;
|
||||
void collect_path_points();
|
||||
void precompute_chunk_coverage();
|
||||
};
|
||||
} // namespace Cubed
|
||||
@@ -1,68 +1,134 @@
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include "Cubed/gameplay/biome.hpp"
|
||||
#include "Cubed/gameplay/block.hpp"
|
||||
#include "Cubed/gameplay/chunk_generator.hpp"
|
||||
#include "Cubed/gameplay/chunk_pos.hpp"
|
||||
#include "Cubed/gameplay/vertex_data.hpp"
|
||||
|
||||
#include <Cubed/config.hpp>
|
||||
#include <Cubed/gameplay/biome.hpp>
|
||||
#include <Cubed/gameplay/chunk_pos.hpp>
|
||||
#include <Cubed/gameplay/block.hpp>
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
namespace Cubed {
|
||||
|
||||
class World;
|
||||
// if want to use, do init_chunk(), gen_vertex_data() and
|
||||
class Chunk {
|
||||
private:
|
||||
std::atomic<bool> m_dirty {false};
|
||||
|
||||
static constexpr int SIZE_X = CHUCK_SIZE;
|
||||
using OptionalBlockVectorArray =
|
||||
std::array<std::optional<std::vector<BlockType>>, 4>;
|
||||
static constexpr int SIZE_X = CHUNK_SIZE;
|
||||
static constexpr int SIZE_Y = WORLD_SIZE_Y;
|
||||
static constexpr int SIZE_Z = CHUCK_SIZE;
|
||||
static constexpr int SIZE_Z = CHUNK_SIZE;
|
||||
static constexpr int VERTEX_DATA_SUM = 4;
|
||||
std::atomic<bool> m_dirty{false};
|
||||
std::atomic<bool> m_need_upload{true};
|
||||
std::atomic<bool> m_is_on_gen_vertex_data{false};
|
||||
std::atomic<BiomeType> m_biome = BiomeType::PLAIN;
|
||||
std::mutex m_vertexs_data_mutex;
|
||||
|
||||
std::unique_ptr<ChunkGenerator> m_generator;
|
||||
|
||||
Biome m_biome = Biome::PLAIN;
|
||||
ChunkPos m_chunk_pos;
|
||||
World& m_world;
|
||||
HeightMapArray m_heightmap;
|
||||
// the index is a array of block id
|
||||
std::vector<uint8_t> m_blocks;
|
||||
GLuint m_vbo = 0;
|
||||
std::vector<Vertex> m_vertexs_data;
|
||||
std::vector<BlockType> m_blocks;
|
||||
|
||||
/*
|
||||
0 - normal
|
||||
1 - cross_plane
|
||||
2 - normal_discard
|
||||
3 - transparent and blend
|
||||
*/
|
||||
std::vector<VertexData> m_vertex_data;
|
||||
float frequency = 0.01f;
|
||||
float height = 80;
|
||||
unsigned m_seed = 0;
|
||||
|
||||
BiomeConditions m_conditions;
|
||||
|
||||
void clear_dirty();
|
||||
|
||||
void resolve_biome();
|
||||
void resolve_blocks();
|
||||
void gen_vertices(const OptionalBlockVectorArray& neighbor_block);
|
||||
void gen_cross_plane_vertices(int world_x, int world_y, int world_z,
|
||||
BlockType id);
|
||||
|
||||
public:
|
||||
Chunk(World& world, ChunkPos chunk_pos);
|
||||
~Chunk();
|
||||
Chunk(const Chunk&) = delete;
|
||||
Chunk& operator=(const Chunk&) = delete;
|
||||
Chunk(Chunk&&);
|
||||
Chunk& operator=(Chunk&&);
|
||||
Chunk(Chunk&&) noexcept;
|
||||
Chunk& operator=(Chunk&&) noexcept;
|
||||
|
||||
Biome get_biome() const;
|
||||
|
||||
const std::vector<uint8_t>& get_chunk_blocks() const;
|
||||
|
||||
static int get_index(int x, int y, int z);
|
||||
static int get_index(const glm::vec3& pos);
|
||||
void init_chunk();
|
||||
//void gen_vertex_data();
|
||||
// 0 : (1, 0)
|
||||
// 1 : (-1, 0)
|
||||
// 2 : (0, 1)
|
||||
// 3 : (0, -1)
|
||||
void gen_vertex_data(const std::array<const std::vector<uint8_t>*, 4>& neighbor_block);
|
||||
static std::tuple<int, int, int> world_to_block(int world_x, int world_y,
|
||||
int world_z, int chunk_x,
|
||||
int chunk_z);
|
||||
static std::tuple<int, int, int> world_to_block(const glm::ivec3& block_pos,
|
||||
ChunkPos chunk_pos);
|
||||
static std::tuple<int, int, int> block_to_world(int x, int y, int z,
|
||||
int chunk_x, int chunk_z);
|
||||
static std::tuple<int, int, int> block_to_world(const glm::ivec3& block_pos,
|
||||
ChunkPos chunk_pos);
|
||||
BiomeType get_biome() const;
|
||||
ChunkPos get_chunk_pos() const;
|
||||
const std::vector<BlockType>& get_chunk_blocks() const;
|
||||
HeightMapArray get_heightmap() const;
|
||||
static int index(int x, int y, int z);
|
||||
static int index(const glm::vec3& pos);
|
||||
// Init Chunk
|
||||
// Determine biome from temperature and humidity noise
|
||||
void gen_phase_one();
|
||||
// Resolve biome adjacency conflicts with neighbor chunks
|
||||
void gen_phase_two(const std::array<const Chunk*, 8>& adj_chunks);
|
||||
// Generate heightmap using biome-specific noise
|
||||
void gen_phase_three();
|
||||
// Blend heightmap with neighbors for smooth transitions
|
||||
void gen_phase_four(
|
||||
const std::array<std::optional<HeightMapArray>, 8>& neighbor_heightmap,
|
||||
const std::array<BiomeType, 8>& neighbor_biome);
|
||||
// Generate terrain blocks from heightmap and biome
|
||||
void gen_phase_five();
|
||||
// Blend surface blocks at chunk borders with neighbors
|
||||
void gen_phase_six(const std::array<std::optional<std::vector<BlockType>>,
|
||||
4>& neighbor_block);
|
||||
// Generate biome-specific vegetation/structures
|
||||
void gen_phase_seven();
|
||||
// void gen_vertex_data();
|
||||
// 0 : (1, 0)
|
||||
// 1 : (-1, 0)
|
||||
// 2 : (0, 1)
|
||||
// 3 : (0, -1)
|
||||
void gen_vertex_data(const OptionalBlockVectorArray& neighbor_block);
|
||||
void upload_to_gpu();
|
||||
|
||||
GLuint get_vbo() const;
|
||||
const std::vector<Vertex>& get_vertex_data() const;
|
||||
GLuint get_normal_vao() const;
|
||||
size_t get_normal_vertices_sum() const;
|
||||
|
||||
GLuint get_cross_vao() const;
|
||||
size_t get_cross_vertices_sum() const;
|
||||
|
||||
GLuint get_normal_discard_vao() const;
|
||||
size_t get_normal_discard_vertices_sum() const;
|
||||
|
||||
GLuint get_normal_blend_vao() const;
|
||||
size_t get_normal_blend_vertices_sum() const;
|
||||
|
||||
bool is_dirty() const;
|
||||
void mark_dirty();
|
||||
|
||||
bool is_need_upload() const;
|
||||
void need_upload();
|
||||
|
||||
void set_chunk_block(int index, unsigned id);
|
||||
|
||||
ChunkPos chunk_pos() const;
|
||||
BiomeType biome() const;
|
||||
void biome(BiomeType b);
|
||||
HeightMapArray& heightmap();
|
||||
std::vector<BlockType>& blocks();
|
||||
World& world();
|
||||
unsigned seed() const;
|
||||
BiomeConditions& conditions();
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
70
include/Cubed/gameplay/chunk_generator.hpp
Normal file
@@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cubed/constants.hpp"
|
||||
#include "Cubed/gameplay/biome.hpp"
|
||||
#include "Cubed/gameplay/block.hpp"
|
||||
#include "Cubed/gameplay/builders/biome_builder.hpp"
|
||||
#include "Cubed/gameplay/path_point.hpp"
|
||||
#include "Cubed/tools/cubed_random.hpp"
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
namespace Cubed {
|
||||
|
||||
class Chunk;
|
||||
|
||||
class ChunkGenerator {
|
||||
public:
|
||||
ChunkGenerator(Chunk& chunk);
|
||||
|
||||
static void init();
|
||||
static void reload();
|
||||
static const unsigned& seed();
|
||||
static void seed(unsigned s);
|
||||
unsigned chunk_seed() const;
|
||||
// Generate Biome
|
||||
void assign_chunk_biome();
|
||||
// Adjust Biome
|
||||
void resolve_biome_adjacency_conflict(
|
||||
const std::array<const Chunk*, 8>& adj_chunks);
|
||||
// Generate Heightmap
|
||||
void generate_heightmap();
|
||||
// Adjust Height
|
||||
void blend_heightmap_boundaries(
|
||||
const std::array<std::optional<HeightMapArray>, 8>& neighbor_heightmap,
|
||||
const std::array<BiomeType, 8>& neighbor_biome);
|
||||
// Generate Block
|
||||
void generate_terrain_blocks();
|
||||
// Adjust Block;
|
||||
void blend_surface_blocks_borders(
|
||||
const std::array<std::optional<std::vector<BlockType>>, 4>&
|
||||
neighbor_block);
|
||||
// Generate Structure
|
||||
void generate_vegetation();
|
||||
BiomeType get_biome_at(float world_x, float world_z);
|
||||
Chunk& chunk();
|
||||
Random& random();
|
||||
const std::array<BiomeType, 8>& neighbor_biome() const;
|
||||
void ocean_build();
|
||||
void generate_cave();
|
||||
void generate_river();
|
||||
|
||||
private:
|
||||
static inline std::atomic<bool> is_init{false};
|
||||
static inline unsigned m_generator_seed{0};
|
||||
static inline std::atomic<bool> is_seed_change{false};
|
||||
Chunk& m_chunk;
|
||||
Random m_random;
|
||||
std::unique_ptr<BiomeBuilder> m_biome_builder{nullptr};
|
||||
bool is_cur_chunk_ins = false;
|
||||
std::array<BiomeType, 8> m_neighbor_biome;
|
||||
unsigned m_chunk_seed = 0;
|
||||
|
||||
void make_biome_builder();
|
||||
void
|
||||
carve_worm(const std::vector<PathPoint>& points, const ChunkPos& chunk_pos,
|
||||
std::function<void(int /*x*/, int /*y*/, int /*z*/)> on_hit);
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
@@ -1,23 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace Cubed {
|
||||
|
||||
#include <Cubed/tools/log.hpp>
|
||||
#include <Cubed/tools/cubed_assert.hpp>
|
||||
struct ChunkPos {
|
||||
int x;
|
||||
int z;
|
||||
|
||||
bool operator==(const ChunkPos&) const = default;
|
||||
struct Hash {
|
||||
std::size_t operator()(const ChunkPos& pos) const{
|
||||
std::size_t operator()(const ChunkPos& pos) const {
|
||||
std::size_t h1 = std::hash<int>{}(pos.x);
|
||||
std::size_t h2 = std::hash<int>{}(pos.z);
|
||||
return h1 ^ (h2 + 0x9e3779b9 + (h1 << 6) + (h1 >> 2));
|
||||
}
|
||||
};
|
||||
|
||||
ChunkPos operator+(const ChunkPos& pos) const{
|
||||
struct TBBHash {
|
||||
std::size_t hash(const ChunkPos& p) const {
|
||||
return ChunkPos::Hash{}(p);
|
||||
}
|
||||
bool equal(const ChunkPos& a, const ChunkPos& b) const {
|
||||
return a == b;
|
||||
}
|
||||
};
|
||||
ChunkPos operator+(const ChunkPos& pos) const {
|
||||
return ChunkPos{x + pos.x, z + pos.z};
|
||||
}
|
||||
|
||||
@@ -28,3 +35,4 @@ struct ChunkPos {
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
@@ -2,18 +2,20 @@
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
enum class GameMode {
|
||||
CREATIVE,
|
||||
SPECTATOR
|
||||
};
|
||||
|
||||
namespace Cubed {
|
||||
|
||||
enum class GameMode { CREATIVE = 0, SPECTATOR };
|
||||
|
||||
inline std::string to_str(GameMode mode) {
|
||||
using enum GameMode;
|
||||
switch (mode) {
|
||||
case CREATIVE:
|
||||
return {"Creative"};
|
||||
case SPECTATOR:
|
||||
return {"Spective"};
|
||||
case CREATIVE:
|
||||
return {"Creative"};
|
||||
case SPECTATOR:
|
||||
return {"Spective"};
|
||||
}
|
||||
throw std::invalid_argument{"GameMode is invaild"};
|
||||
}
|
||||
|
||||
} // namespace Cubed
|
||||
36
include/Cubed/gameplay/path_point.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
#include <glm/glm.hpp>
|
||||
struct PathPoint {
|
||||
glm::vec3 pos;
|
||||
glm::vec3 tangent{0.0f, 0.0f, 1.0f};
|
||||
float rad_xz;
|
||||
float rad_y;
|
||||
PathPoint(const glm::vec3& p, float rx, float ry)
|
||||
: pos(p), rad_xz(rx), rad_y(ry) {}
|
||||
bool contains(const glm::vec3& other_pos) const {
|
||||
glm::vec3 to_point = other_pos - pos;
|
||||
|
||||
glm::vec3 world_up(0.0f, 1.0f, 0.0f);
|
||||
|
||||
glm::vec3 right = glm::normalize(glm::cross(tangent, world_up));
|
||||
|
||||
if (glm::length(right) < 0.001f) {
|
||||
glm::vec3 alt_up(1.0f, 0.0f, 0.0f);
|
||||
right = glm::normalize(glm::cross(tangent, alt_up));
|
||||
}
|
||||
|
||||
glm::vec3 up = glm::normalize(glm::cross(right, tangent));
|
||||
|
||||
float horizontal_dist = glm::dot(to_point, right);
|
||||
float vertical_dist = glm::dot(to_point, up);
|
||||
|
||||
float a = rad_xz;
|
||||
float b = rad_y;
|
||||
if (a <= 0.0f || b <= 0.0f)
|
||||
return false;
|
||||
|
||||
float check = (horizontal_dist * horizontal_dist) / (a * a) +
|
||||
(vertical_dist * vertical_dist) / (b * b);
|
||||
return check <= 1.0f;
|
||||
}
|
||||
};
|
||||
@@ -1,67 +1,70 @@
|
||||
#pragma once
|
||||
#include "Cubed/AABB.hpp"
|
||||
#include "Cubed/constants.hpp"
|
||||
#include "Cubed/gameplay/block.hpp"
|
||||
#include "Cubed/gameplay/chunk_pos.hpp"
|
||||
#include "Cubed/gameplay/game_mode.hpp"
|
||||
#include "Cubed/input.hpp"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <Cubed/AABB.hpp>
|
||||
#include <Cubed/config.hpp>
|
||||
#include <Cubed/gameplay/block.hpp>
|
||||
#include <Cubed/gameplay/chunk_pos.hpp>
|
||||
#include <Cubed/gameplay/game_mode.hpp>
|
||||
#include <Cubed/input.hpp>
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
enum class Gait{
|
||||
WALK,
|
||||
RUN
|
||||
};
|
||||
namespace Cubed {
|
||||
|
||||
enum class Gait { WALK = 0, RUN };
|
||||
|
||||
class World;
|
||||
|
||||
class Player {
|
||||
private:
|
||||
using enum GameMode;
|
||||
constexpr static float WALK_SPEED = 4.5f;
|
||||
constexpr static float RUN_SPEED = 7.0f;
|
||||
constexpr static float ACCELERATION = 10.0f;
|
||||
constexpr static float DECELERATION = 15.0f;
|
||||
constexpr static float G = 22.5f;
|
||||
float m_max_walk_speed = DEFAULT_MAX_WALK_SPEED;
|
||||
float m_max_run_speed = DEFAULT_MAX_RUN_SPEED;
|
||||
float m_acceleration = DEFAULT_ACCELERATION;
|
||||
float m_deceleration = DEFAULT_DECELERATION;
|
||||
float m_g = DEFAULT_G;
|
||||
|
||||
constexpr static float MAX_SPACE_ON_TIME = 0.3f;
|
||||
|
||||
float m_yaw = 0.0f;
|
||||
float m_pitch = 0.0f;
|
||||
|
||||
float m_sensitivity = 0.15f;
|
||||
|
||||
float max_speed = WALK_SPEED;
|
||||
float y_speed = 0.0f;
|
||||
float m_max_speed = m_max_walk_speed;
|
||||
float m_y_speed = 0.0f;
|
||||
bool can_up = true;
|
||||
|
||||
float space_on_time = 0.0f;
|
||||
bool space_on = false;
|
||||
bool is_fly = false;
|
||||
|
||||
float speed = 0;
|
||||
float m_xz_speed = 0.0f;
|
||||
|
||||
unsigned m_place_block = 1;
|
||||
|
||||
glm::vec3 direction = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||
glm::vec3 move_distance {0.0f, 0.0f, 0.0f};
|
||||
glm::vec3 move_distance{0.0f, 0.0f, 0.0f};
|
||||
// player is tow block tall, the pos is the lower pos
|
||||
|
||||
glm::vec3 m_player_pos {0.0f, 120.0f, 0.0f};
|
||||
ChunkPos m_player_chunk_pos {0, 0};
|
||||
glm::vec3 m_player_pos{0.0f, 255.0f, 0.0f};
|
||||
ChunkPos m_player_chunk_pos{0, 0};
|
||||
|
||||
glm::vec3 m_front {0, 0, -1};
|
||||
glm::vec3 m_right {0, 0, 0};
|
||||
glm::vec3 m_size {0.6f, 1.8f, 0.6f};
|
||||
glm::vec3 m_front{0, 0, -1};
|
||||
glm::vec3 m_right{0, 0, 0};
|
||||
glm::vec3 m_size{0.6f, 1.8f, 0.6f};
|
||||
|
||||
Gait m_gait = Gait::WALK;
|
||||
MoveState m_move_state {};
|
||||
MoveState m_move_state{};
|
||||
GameMode m_game_mode = CREATIVE;
|
||||
std::optional<LookBlock> m_look_block = std::nullopt;
|
||||
std::string m_name {};
|
||||
std::string m_name{};
|
||||
World& m_world;
|
||||
|
||||
bool ray_cast(const glm::vec3& start, const glm::vec3& dir, glm::ivec3& block_pos, glm::vec3& normal, float distance = 4.0f);
|
||||
bool ray_cast(const glm::vec3& start, const glm::vec3& dir,
|
||||
glm::ivec3& block_pos, glm::vec3& normal,
|
||||
float distance = 4.0f);
|
||||
|
||||
void check_player_chunk_transition();
|
||||
void update_direction();
|
||||
@@ -82,10 +85,26 @@ public:
|
||||
const MoveState& get_move_state() const;
|
||||
|
||||
void change_mode(GameMode mode);
|
||||
void hot_reload();
|
||||
void set_player_pos(const glm::vec3& pos);
|
||||
void set_place_block(unsigned id);
|
||||
void update(float delta_time);
|
||||
void update_front_vec(float offset_x, float offset_y);
|
||||
void update_player_move_state(int key, int action);
|
||||
void update_scroll(double yoffset);
|
||||
|
||||
float& max_walk_speed();
|
||||
float& max_run_speed();
|
||||
float& max_speed();
|
||||
float& acceleration();
|
||||
float& deceleration();
|
||||
float& g();
|
||||
|
||||
unsigned place_block() const;
|
||||
|
||||
Gait& gait();
|
||||
GameMode& game_mode();
|
||||
const World& get_world() const;
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
|
||||
55
include/Cubed/gameplay/river.path.hpp
Normal file
@@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cubed/gameplay/chunk_pos.hpp"
|
||||
#include "Cubed/gameplay/path_point.hpp"
|
||||
#include "Cubed/tools/cubed_random.hpp"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <tbb/concurrent_hash_map.h>
|
||||
|
||||
namespace Cubed {
|
||||
class RiverPath {
|
||||
using ChunkPosSet =
|
||||
tbb::concurrent_hash_map<ChunkPos, bool, ChunkPos::TBBHash>;
|
||||
|
||||
public:
|
||||
RiverPath(unsigned int chunk_seed, unsigned world_seed,
|
||||
const glm::vec3& start_pos);
|
||||
const std::vector<PathPoint>& points() const;
|
||||
void clear_chunk(const ChunkPos& pos);
|
||||
bool is_finished() const;
|
||||
|
||||
static float& radius_xz_min();
|
||||
static float& radius_xz_max();
|
||||
static float& radius_y_min();
|
||||
static float& radius_y_max();
|
||||
static float& delta_angle_min();
|
||||
static float& delta_angle_max();
|
||||
static int& step_min();
|
||||
static int& step_max();
|
||||
|
||||
private:
|
||||
static inline float m_radius_xz_min = 5.0f;
|
||||
static inline float m_radius_xz_max = 10.0f;
|
||||
static inline float m_radius_y_min = 4.0f;
|
||||
static inline float m_radius_y_max = 8.0f;
|
||||
static inline float m_delta_angle_min = -3.0f;
|
||||
static inline float m_delta_angle_max = 3.0f;
|
||||
static inline int m_step_min = 200;
|
||||
static inline int m_step_max = 400;
|
||||
|
||||
unsigned int m_seed = 0;
|
||||
float m_yaw = 0.0f;
|
||||
float m_initial_yaw = 0.0f;
|
||||
float m_pitch = 0.0f;
|
||||
int m_step = 0;
|
||||
float m_step_len = 1.0f;
|
||||
PathPoint m_start_path_point{{0.0f, 0.0f, 0.0f}, 0.0f, 0.0f};
|
||||
Random m_random;
|
||||
|
||||
std::vector<PathPoint> m_points;
|
||||
ChunkPosSet m_pending_chunks;
|
||||
void collect_path_points();
|
||||
void precompute_chunk_coverage();
|
||||
};
|
||||
} // namespace Cubed
|
||||
32
include/Cubed/gameplay/river_worm.hpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
#include "Cubed/gameplay/chunk_pos.hpp"
|
||||
#include "Cubed/gameplay/river.path.hpp"
|
||||
#include "Cubed/tools/cubed_random.hpp"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <tbb/concurrent_hash_map.h>
|
||||
namespace Cubed {
|
||||
|
||||
class RiverWorm {
|
||||
using RiverHashMap = tbb::concurrent_hash_map<unsigned, RiverPath>;
|
||||
|
||||
public:
|
||||
RiverWorm();
|
||||
RiverHashMap& paths();
|
||||
void init(unsigned world_seed);
|
||||
void reload(unsigned world_seed);
|
||||
void add_path(const glm::vec3& pos, unsigned chunk_seed);
|
||||
void try_to_add_path(const ChunkPos& pos, unsigned chunk_seed);
|
||||
void cleanup_finished_rivers();
|
||||
|
||||
int river_sum() const;
|
||||
float& river_probability();
|
||||
|
||||
private:
|
||||
RiverHashMap m_paths;
|
||||
unsigned m_seed = 0;
|
||||
Random m_random;
|
||||
float m_probability = 0.01f;
|
||||
};
|
||||
|
||||
}; // namespace Cubed
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
namespace Cubed {
|
||||
|
||||
class Chunk;
|
||||
|
||||
struct TreeStructNode {
|
||||
@@ -10,3 +12,5 @@ struct TreeStructNode {
|
||||
};
|
||||
|
||||
bool build_tree(Chunk& chunk, const glm::ivec3& pos);
|
||||
|
||||
} // namespace Cubed
|
||||
|
||||
25
include/Cubed/gameplay/vertex_data.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
#include "Cubed/primitive_data.hpp"
|
||||
|
||||
#include <atomic>
|
||||
#include <glad/glad.h>
|
||||
#include <vector>
|
||||
namespace Cubed {
|
||||
class World;
|
||||
struct VertexData {
|
||||
std::vector<Vertex> m_vertices;
|
||||
GLuint m_vbo = 0;
|
||||
GLuint m_vao = 0;
|
||||
std::atomic<std::size_t> m_sum{0};
|
||||
World& m_world;
|
||||
VertexData(World& world);
|
||||
~VertexData();
|
||||
VertexData(const VertexData&) = delete;
|
||||
VertexData(VertexData&&) noexcept;
|
||||
VertexData& operator=(const VertexData&) = delete;
|
||||
VertexData& operator=(VertexData&&) noexcept;
|
||||
|
||||
void upload();
|
||||
void update_sum();
|
||||
};
|
||||
} // namespace Cubed
|
||||
@@ -1,28 +1,46 @@
|
||||
#pragma once
|
||||
#include "Cubed/AABB.hpp"
|
||||
#include "Cubed/gameplay/cave_carver.hpp"
|
||||
#include "Cubed/gameplay/chunk.hpp"
|
||||
#include "Cubed/gameplay/river_worm.hpp"
|
||||
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <optional>
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
#include <Cubed/AABB.hpp>
|
||||
#include <Cubed/gameplay/chunk.hpp>
|
||||
namespace Cubed {
|
||||
|
||||
struct ChunkRenderSnapshot {
|
||||
GLuint vbo;
|
||||
size_t vertex_count;
|
||||
GLuint normal_vao;
|
||||
size_t normal_vertices_count;
|
||||
GLuint cross_vao;
|
||||
size_t cross_vertices_count;
|
||||
GLuint normal_discard_vao;
|
||||
size_t normal_discard_vertices_count;
|
||||
GLuint normal_blend_vao;
|
||||
size_t normal_blend_vertices_count;
|
||||
glm::vec3 center;
|
||||
glm::vec3 half_extents;
|
||||
};
|
||||
|
||||
|
||||
class Player;
|
||||
|
||||
class TextureManager;
|
||||
class World {
|
||||
private:
|
||||
using OptionalBlockVectorArray =
|
||||
std::array<std::optional<std::vector<BlockType>>, 4>;
|
||||
using ChunkPtrUpdateList = std::vector<std::pair<ChunkPos, Chunk*>>;
|
||||
using ChunkPairVector = std::vector<std::pair<ChunkPos, Chunk>>;
|
||||
using ConstChunkMap =
|
||||
std::unordered_map<ChunkPos, const Chunk*, ChunkPos::Hash>;
|
||||
using ChunkPosSet = std::unordered_set<ChunkPos, ChunkPos::Hash>;
|
||||
using ChunkHashMap = std::unordered_map<ChunkPos, Chunk, ChunkPos::Hash>;
|
||||
glm::vec3 m_gen_player_pos{0.0f, 0.0f, 0.0f};
|
||||
std::unordered_map<ChunkPos , Chunk, ChunkPos::Hash> m_chunks;
|
||||
ChunkHashMap m_chunks;
|
||||
std::unordered_map<std::size_t, Player> m_players;
|
||||
std::vector<glm::vec4> m_planes;
|
||||
|
||||
@@ -31,48 +49,82 @@ private:
|
||||
std::mutex m_gen_signal_mutex;
|
||||
std::mutex m_new_chunk_queue_mutex;
|
||||
std::mutex m_delete_vbo_mutex;
|
||||
std::mutex m_delete_vao_mutex;
|
||||
std::mutex m_gen_player_pos_mutex;
|
||||
std::vector<GLuint> m_pending_delete_vbo;
|
||||
std::vector<GLuint> m_pending_delete_vao;
|
||||
std::condition_variable m_gen_cv;
|
||||
std::atomic<bool> m_gen_running{false};
|
||||
std::atomic<bool> m_need_gen_chunk{false};
|
||||
|
||||
std::atomic<bool> m_is_rebuilding{false};
|
||||
std::atomic<bool> m_chunk_gen_finished{false};
|
||||
std::atomic<bool> m_could_gen{true};
|
||||
std::atomic<int> m_rendering_distance{24};
|
||||
std::atomic<float> m_chunk_gen_fraction{0.0f};
|
||||
std::vector<ChunkPos> m_dirty_queue;
|
||||
std::vector<ChunkRenderSnapshot> m_render_snapshots;
|
||||
std::vector<std::pair<ChunkPos, Chunk>> m_new_chunk;
|
||||
std::vector<std::pair<ChunkPos, Chunk>> m_new_chunk_queue;
|
||||
|
||||
void gen_chunks_internal();
|
||||
CaveCarver m_cave_carcer;
|
||||
RiverWorm m_river_worm;
|
||||
void init_chunks();
|
||||
|
||||
void start_gen_thread();
|
||||
void stop_gen_thread();
|
||||
void gen_chunks_internal();
|
||||
void sync_player_pos(glm::vec3& player_pos);
|
||||
void
|
||||
compute_required_chunks(ChunkPosSet& required_chunks,
|
||||
ChunkPairVector& temp_neighbor,
|
||||
std::vector<ChunkPos>& need_gen_temp_chunks_pos);
|
||||
void sync_and_collect_missing_chunks(std::vector<ChunkPos>&,
|
||||
const ChunkPosSet&);
|
||||
void
|
||||
build_neighbor_context_for_new_chunks(ConstChunkMap& new_chunks_neighbor,
|
||||
ChunkPtrUpdateList& affected_neighbor,
|
||||
const ChunkPairVector& new_chunks);
|
||||
void build_neighbor_context_for_affected_neighbors(ChunkPtrUpdateList&,
|
||||
ConstChunkMap&);
|
||||
|
||||
public:
|
||||
|
||||
World();
|
||||
~World();
|
||||
|
||||
bool can_move(const AABB& player_box) const;
|
||||
//const BlockRenderData& get_block_render_data(int x, int y ,int z);
|
||||
// const BlockRenderData& get_block_render_data(int x, int y ,int z);
|
||||
|
||||
const std::optional<LookBlock>& get_look_block_pos(const std::string& name) const;
|
||||
const std::optional<LookBlock>&
|
||||
get_look_block_pos(const std::string& name) const;
|
||||
const Chunk* get_chunk(const ChunkPos& pos) const;
|
||||
|
||||
Player& get_player(const std::string& name);
|
||||
void init_world();
|
||||
bool is_aabb_in_frustum(const glm::vec3& center, const glm::vec3& half_extents);
|
||||
|
||||
int get_block(const glm::ivec3& block_pos) const;
|
||||
bool is_block(const glm::ivec3& block_pos) const;
|
||||
|
||||
bool is_solid(const glm::ivec3& block_pos) const;
|
||||
bool can_pass_block(const glm::ivec3& block_pos) const;
|
||||
BlockType get_block_tpye(const glm::ivec3& block_pos) const;
|
||||
static ChunkPos chunk_pos(int world_x, int world_z);
|
||||
|
||||
void need_gen();
|
||||
void render(const glm::mat4& mvp_matrix);
|
||||
|
||||
void set_block(const glm::ivec3& pos, unsigned id);
|
||||
void update(float delta_time);
|
||||
|
||||
void push_delete_vbo(GLuint vbo);
|
||||
void push_delete_vao(GLuint vao);
|
||||
void hot_reload();
|
||||
|
||||
void rebuild_world();
|
||||
|
||||
float chunk_gen_fraction() const;
|
||||
int rendering_distance() const;
|
||||
void rendering_distance(int rendering_distance);
|
||||
void start_gen_thread();
|
||||
void stop_gen_thread();
|
||||
|
||||
CaveCarver& cave_carcer();
|
||||
RiverWorm& river_worm();
|
||||
std::vector<glm::vec4>& planes();
|
||||
std::vector<ChunkRenderSnapshot>& render_snapshots();
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
namespace Cubed {
|
||||
|
||||
struct MoveState {
|
||||
bool forward = false;
|
||||
bool back = false;
|
||||
@@ -27,7 +29,8 @@ struct InputState {
|
||||
};
|
||||
|
||||
namespace Input {
|
||||
InputState& get_input_state();
|
||||
|
||||
InputState& get_input_state();
|
||||
|
||||
}
|
||||
|
||||
} // namespace Cubed
|
||||
@@ -1,14 +1,26 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
// #include <string>
|
||||
// #include <unordered_map>
|
||||
// #include <vector>
|
||||
namespace Cubed {
|
||||
|
||||
class MapTable {
|
||||
private:
|
||||
static std::unordered_map<unsigned, std::string> id_to_name_map;
|
||||
static std::unordered_map<size_t, unsigned> name_to_id_map;
|
||||
/*
|
||||
static inline std::unordered_map<unsigned, std::string> id_to_name_map;
|
||||
static inline std::unordered_map<size_t, unsigned> name_to_id_map;
|
||||
static inline std::vector<std::string> item_id_to_name;
|
||||
*/
|
||||
public:
|
||||
// please using reference
|
||||
static const std::string& get_name_from_id(unsigned id);
|
||||
static const unsigned get_id_from_name(const std::string& name);
|
||||
static void init_map();
|
||||
/*
|
||||
static std::string_view get_name_from_id(unsigned id);
|
||||
static unsigned get_id_from_name(const std::string& name);
|
||||
|
||||
static std::string_view item_name(unsigned id);
|
||||
static const std::vector<std::string>& item_map();
|
||||
*/
|
||||
static void init_map();
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
171
include/Cubed/primitive_data.hpp
Normal file
@@ -0,0 +1,171 @@
|
||||
#pragma once
|
||||
|
||||
namespace Cubed {
|
||||
#pragma region NORMAL_BLOCK
|
||||
constexpr float VERTICES_POS[6][6][3] = {
|
||||
// ===== front (z = +1) =====
|
||||
{{0.0f, 0.0f, 1.0f}, // bottom left
|
||||
{0.0f, 1.0f, 1.0f}, // top left
|
||||
{1.0f, 1.0f, 1.0f}, // top right
|
||||
{1.0f, 1.0f, 1.0f}, // top right
|
||||
{1.0f, 0.0f, 1.0f}, // bottom right
|
||||
{0.0f, 0.0f, 1.0f}}, // bottom left
|
||||
// ===== right (x = +1) =====
|
||||
{{1.0f, 0.0f, 1.0f}, // bottom front
|
||||
{1.0f, 0.0f, 0.0f}, // bottom back
|
||||
{1.0f, 1.0f, 0.0f}, // top back
|
||||
{1.0f, 1.0f, 0.0f}, // top back
|
||||
{1.0f, 1.0f, 1.0f}, // top front
|
||||
{1.0f, 0.0f, 1.0f}}, // bottom front
|
||||
// ===== back (z = -1) =====
|
||||
{{0.0f, 0.0f, 0.0f}, // bottom left
|
||||
{1.0f, 0.0f, 0.0f}, // bottom right
|
||||
{1.0f, 1.0f, 0.0f}, // top right
|
||||
{1.0f, 1.0f, 0.0f}, // top right
|
||||
{0.0f, 1.0f, 0.0f}, // top left
|
||||
{0.0f, 0.0f, 0.0f}}, // bottom left
|
||||
// ===== left (x = -1) =====
|
||||
{{0.0f, 0.0f, 0.0f}, // bottom back
|
||||
{0.0f, 0.0f, 1.0f}, // bottom front
|
||||
{0.0f, 1.0f, 1.0f}, // top front
|
||||
{0.0f, 1.0f, 1.0f}, // top front
|
||||
{0.0f, 1.0f, 0.0f}, // top back
|
||||
{0.0f, 0.0f, 0.0f}}, // bottom back
|
||||
// ===== top (y = +1) =====
|
||||
{{0.0f, 1.0f, 0.0f}, // back left
|
||||
{1.0f, 1.0f, 0.0f}, // back right
|
||||
{1.0f, 1.0f, 1.0f}, // front right
|
||||
{1.0f, 1.0f, 1.0f}, // front right
|
||||
{0.0f, 1.0f, 1.0f}, // front left
|
||||
{0.0f, 1.0f, 0.0f}}, // back left
|
||||
// ===== bottom (y = -1) =====
|
||||
{{0.0f, 0.0f, 1.0f}, // front left
|
||||
{1.0f, 0.0f, 1.0f}, // front right
|
||||
{1.0f, 0.0f, 0.0f}, // back right
|
||||
{1.0f, 0.0f, 0.0f}, // back right
|
||||
{0.0f, 0.0f, 0.0f}, // back left
|
||||
{0.0f, 0.0f, 1.0f}} // front left
|
||||
};
|
||||
|
||||
constexpr float TEX_COORDS[6][6][2] = {
|
||||
// ===== front (z = +1) =====
|
||||
{{0.0f, 1.0f}, // bottom left
|
||||
{0.0f, 0.0f}, // top left
|
||||
{1.0f, 0.0f}, // top right
|
||||
{1.0f, 0.0f}, // top right
|
||||
{1.0f, 1.0f}, // bottom right
|
||||
{0.0f, 1.0f}}, // bottom left
|
||||
// ===== right (x = +1) =====
|
||||
{{0.0f, 1.0f}, // bottom front
|
||||
{1.0f, 1.0f}, // bottom back
|
||||
{1.0f, 0.0f}, // top back
|
||||
{1.0f, 0.0f}, // top back
|
||||
{0.0f, 0.0f}, // top front
|
||||
{0.0f, 1.0f}}, // bottom front
|
||||
// ===== back (z = -1) =====
|
||||
{{1.0f, 1.0f}, // bottom left
|
||||
{0.0f, 1.0f}, // bottom right
|
||||
{0.0f, 0.0f}, // top right
|
||||
{0.0f, 0.0f}, // top right
|
||||
{1.0f, 0.0f}, // top left
|
||||
{1.0f, 1.0f}}, // bottom left
|
||||
// ===== left (x = -1) =====
|
||||
{{1.0f, 1.0f}, // bottom back
|
||||
{0.0f, 1.0f}, // bottom front
|
||||
{0.0f, 0.0f}, // top front
|
||||
{0.0f, 0.0f}, // top front
|
||||
{1.0f, 0.0f}, // top back
|
||||
{1.0f, 1.0f}}, // bottom back
|
||||
// ===== top (y = +1) =====
|
||||
{{0.0f, 0.0f}, // back left
|
||||
{1.0f, 0.0f}, // back right
|
||||
{1.0f, 1.0f}, // front right
|
||||
{1.0f, 1.0f}, // front right
|
||||
{0.0f, 1.0f}, // front left
|
||||
{0.0f, 0.0f}}, // back left
|
||||
// ===== bottom (y = -1) =====
|
||||
{{0.0f, 0.0f}, // front left
|
||||
{1.0f, 0.0f}, // front right
|
||||
{1.0f, 1.0f}, // back right
|
||||
{1.0f, 1.0f}, // back right
|
||||
{0.0f, 1.0f}, // back left
|
||||
{0.0f, 0.0f}} // front left
|
||||
};
|
||||
#pragma endregion
|
||||
constexpr float CUBE_VER[24] = {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0,
|
||||
0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0,
|
||||
0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0};
|
||||
|
||||
constexpr int OUTLINE_CUBE_INDICES[24] = {0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6,
|
||||
6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7};
|
||||
|
||||
constexpr float SQUARE_VERTICES[6][2] = {
|
||||
{-0.5f, -0.5f}, // bottom left
|
||||
{-0.5f, 0.5f}, // top left
|
||||
{0.5f, 0.5f}, // top right
|
||||
{0.5f, 0.5f}, // top right
|
||||
{0.5f, -0.5f}, // bottom right
|
||||
{-0.5f, -0.5f} // bottom left
|
||||
};
|
||||
|
||||
constexpr float SQUARE_TEXTURE_POS[6][2] = {
|
||||
{0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f},
|
||||
{1.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 0.0f},
|
||||
};
|
||||
#pragma region CROSS_PLANE
|
||||
constexpr float CROSS_VERTICES_POS[2][6][3] = {
|
||||
// ===== Plane 1: bottom-front-left to top-back-right =====
|
||||
{{0.0f, 0.0f, 0.0f}, // bottom front left
|
||||
{0.0f, 1.0f, 0.0f}, // top front left
|
||||
{1.0f, 1.0f, 1.0f}, // top back right
|
||||
{1.0f, 1.0f, 1.0f}, // top back right
|
||||
{1.0f, 0.0f, 1.0f}, // bottom back right
|
||||
{0.0f, 0.0f, 0.0f}}, // bottom front left
|
||||
|
||||
// ===== Plane 2: bottom-front-right to top-back-left =====
|
||||
{{1.0f, 0.0f, 0.0f}, // bottom front right
|
||||
{1.0f, 1.0f, 0.0f}, // top front right
|
||||
{0.0f, 1.0f, 1.0f}, // top back left
|
||||
{0.0f, 1.0f, 1.0f}, // top back left
|
||||
{0.0f, 0.0f, 1.0f}, // bottom back left
|
||||
{1.0f, 0.0f, 0.0f}}, // bottom front right
|
||||
};
|
||||
|
||||
constexpr float CROSS_TEX_COORDS[2][6][2] = {
|
||||
// ===== Plane 1: bottom-front-left to top-back-right =====
|
||||
{{0.0f, 1.0f}, // bottom left
|
||||
{0.0f, 0.0f}, // top left
|
||||
{1.0f, 0.0f}, // top right
|
||||
{1.0f, 0.0f}, // top right
|
||||
{1.0f, 1.0f}, // bottom right
|
||||
{0.0f, 1.0f}}, // bottom left
|
||||
|
||||
// ===== Plane 2: bottom-front-right to top-back-left =====
|
||||
{{0.0f, 1.0f}, // bottom left
|
||||
{0.0f, 0.0f}, // top left
|
||||
{1.0f, 0.0f}, // top right
|
||||
{1.0f, 0.0f}, // top right
|
||||
{1.0f, 1.0f}, // bottom right
|
||||
{0.0f, 1.0f}}, // bottom left
|
||||
};
|
||||
#pragma endregion
|
||||
|
||||
constexpr float QUAD_VERTICES[] = {
|
||||
// postion // texcoorlds
|
||||
-1.0f, 1.0f, 0.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f,
|
||||
|
||||
-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f};
|
||||
|
||||
struct Vertex {
|
||||
float x = 0.0f, y = 0.0f, z = 0.0f;
|
||||
float s = 0.0f, t = 0.0f;
|
||||
float layer = 0.0f;
|
||||
};
|
||||
|
||||
struct Vertex2D {
|
||||
float x = 0.0f, y = 0.0f;
|
||||
float s = 0.0f, t = 0.0f;
|
||||
float layer = 0.0f;
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
@@ -1,52 +1,84 @@
|
||||
#pragma once
|
||||
|
||||
#include <Cubed/config.hpp>
|
||||
#include <Cubed/shader.hpp>
|
||||
#include <Cubed/ui/text.hpp>
|
||||
#include "Cubed/constants.hpp"
|
||||
#include "Cubed/primitive_data.hpp"
|
||||
#include "Cubed/shader.hpp"
|
||||
#include "Cubed/ui/text.hpp"
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <vector>
|
||||
namespace Cubed {
|
||||
|
||||
class Camera;
|
||||
class TextureManager;
|
||||
class World;
|
||||
class DevPanel;
|
||||
class Renderer {
|
||||
public:
|
||||
constexpr static int NUM_VAO = 5;
|
||||
constexpr static int NUM_VAO = 7;
|
||||
|
||||
Renderer(const Camera& camera, World& world, const TextureManager& texture_manager);
|
||||
Renderer(const Camera& camera, World& world,
|
||||
const TextureManager& texture_manager, DevPanel& dev_panel);
|
||||
~Renderer();
|
||||
void hot_reload();
|
||||
void init();
|
||||
const Shader& get_shader(const std::string& name) const;
|
||||
void render();
|
||||
void update(float delta_time);
|
||||
void update_fov(float fov);
|
||||
void update_proj_matrix(float aspect, float width, float height);
|
||||
private:
|
||||
void updata_framebuffer(int width, int height);
|
||||
|
||||
private:
|
||||
const Camera& m_camera;
|
||||
DevPanel& m_dev_panel;
|
||||
const TextureManager& m_texture_manager;
|
||||
World& m_world;
|
||||
|
||||
float m_aspect = 0.0f;
|
||||
float m_fov = NORMAL_FOV;
|
||||
float m_fov = DEFAULT_FOV;
|
||||
|
||||
float m_delta_time = 0.0f;
|
||||
|
||||
float m_width = 0.0f;
|
||||
float m_height = 0.0f;
|
||||
|
||||
glm::mat4 m_p_mat, m_v_mat, m_m_mat, m_mv_mat, m_mvp_mat;
|
||||
|
||||
GLuint m_mv_loc;
|
||||
GLuint m_proj_loc;
|
||||
GLuint m_mv_loc = 0;
|
||||
GLuint m_proj_loc = 0;
|
||||
|
||||
GLuint m_sky_vbo;
|
||||
GLuint m_text_vbo;
|
||||
GLuint m_outline_indices_vbo;
|
||||
GLuint m_outline_vbo;
|
||||
GLuint m_ui_vbo;
|
||||
GLuint m_sky_vbo = 0;
|
||||
GLuint m_text_vbo = 0;
|
||||
GLuint m_outline_indices_vbo = 0;
|
||||
GLuint m_outline_vbo = 0;
|
||||
GLuint m_ui_vbo = 0;
|
||||
|
||||
GLuint m_fbo = 0;
|
||||
GLuint m_screen_texture = 0;
|
||||
GLuint m_depth_render_buffer = 0;
|
||||
|
||||
GLuint m_oit_fbo = 0;
|
||||
GLuint m_accum_texture = 0;
|
||||
GLuint m_reveal_texture = 0;
|
||||
GLuint m_oit_depth_render_buffer = 0;
|
||||
GLuint m_quad_vbo = 0;
|
||||
|
||||
glm::mat4 m_ui_proj;
|
||||
glm::mat4 m_ui_m_matrix;
|
||||
std::unordered_map<std::size_t, Shader> m_shaders;
|
||||
|
||||
/*
|
||||
0 - quad vao
|
||||
1 - sky vao
|
||||
2 - outline vao
|
||||
3 - ui vao
|
||||
4 - text vao
|
||||
*/
|
||||
std::vector<GLuint> m_vao;
|
||||
std::vector<Vertex2D> m_ui;
|
||||
|
||||
void init_quad();
|
||||
void init_text();
|
||||
|
||||
void render_outline();
|
||||
@@ -54,4 +86,8 @@ private:
|
||||
void render_text();
|
||||
void render_ui();
|
||||
void render_world();
|
||||
void render_underwater();
|
||||
void render_dev_panel();
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
@@ -1,18 +1,22 @@
|
||||
#pragma once
|
||||
#include <glad/glad.h>
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
namespace Cubed {
|
||||
|
||||
class Shader {
|
||||
public:
|
||||
Shader();
|
||||
Shader(const std::string& name, const std::string& v_shader_path, const std::string& f_shader_path);
|
||||
Shader(const std::string& name, const std::string& v_shader_path,
|
||||
const std::string& f_shader_path);
|
||||
~Shader();
|
||||
Shader(const Shader&) = delete;
|
||||
Shader& operator=(const Shader&) = delete;
|
||||
Shader(Shader&& shader) noexcept;
|
||||
Shader& operator=(Shader&& shader) noexcept;
|
||||
|
||||
void create(const std::string& name, const std::string& v_shader_path, const std::string& f_shader_path);
|
||||
void create(const std::string& name, const std::string& v_shader_path,
|
||||
const std::string& f_shader_path);
|
||||
std::size_t hash() const;
|
||||
GLuint loc(const std::string& loc) const;
|
||||
const std::string& name() const;
|
||||
@@ -22,5 +26,7 @@ private:
|
||||
GLuint m_program = 0;
|
||||
std::size_t m_hash = 0;
|
||||
std::string m_name = "-1";
|
||||
|
||||
mutable std::unordered_map<std::string, GLint> m_uniform_cache;
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
@@ -1,18 +1,31 @@
|
||||
#pragma once
|
||||
#include <glad/glad.h>
|
||||
#include <Cubed/gameplay/block.hpp>
|
||||
#include <Cubed/tools/shader_tools.hpp>
|
||||
#include "Cubed/gameplay/block.hpp"
|
||||
|
||||
#include <glad/glad.h>
|
||||
|
||||
namespace Cubed {
|
||||
|
||||
class TextureManager {
|
||||
private:
|
||||
bool m_need_reload = false;
|
||||
GLuint m_block_status_array;
|
||||
GLuint m_texture_array;
|
||||
GLuint m_ui_array;
|
||||
GLuint m_block_status_array = 0;
|
||||
GLuint m_texture_array = 0;
|
||||
GLuint m_cross_plane_array = 0;
|
||||
GLuint m_ui_array = 0;
|
||||
GLfloat m_max_aniso = 0.0f;
|
||||
int m_aniso = 1;
|
||||
|
||||
std::vector<GLuint> m_item_textures;
|
||||
|
||||
void load_block_status(unsigned status_id);
|
||||
void load_block_texture(unsigned block_id);
|
||||
void load_block_item_texture(unsigned id);
|
||||
void load_cross_plane_texture(unsigned id);
|
||||
void load_ui_texture(unsigned id);
|
||||
void init_item();
|
||||
void init_block();
|
||||
void init_ui();
|
||||
void init_block_status();
|
||||
|
||||
public:
|
||||
TextureManager();
|
||||
@@ -21,11 +34,15 @@ public:
|
||||
void delet_texture();
|
||||
GLuint get_block_status_array() const;
|
||||
GLuint get_texture_array() const;
|
||||
GLuint get_cross_plane_array() const;
|
||||
GLuint get_ui_array() const;
|
||||
const std::vector<GLuint>& item_textures() const;
|
||||
// Must call after MapTable::init_map() and glfwMakeContextCurrent(window);
|
||||
void init_texture();
|
||||
void hot_reload();
|
||||
void need_reload();
|
||||
void update();
|
||||
|
||||
int max_aniso() const;
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
@@ -1,36 +1,39 @@
|
||||
#pragma once
|
||||
#include <Cubed/tools/log.hpp>
|
||||
#include "Cubed/tools/log.hpp"
|
||||
|
||||
namespace Cubed {
|
||||
|
||||
namespace Assert {
|
||||
inline void msg(const char* condition, const char* file,
|
||||
int line, const char* func,
|
||||
std::string_view message = ""
|
||||
) {
|
||||
|
||||
Logger::error("Assertion failed: {} at {}: {} in function {}",
|
||||
condition, file, line, func);
|
||||
if (message.size()) {
|
||||
Logger::error("Message: {}", message);
|
||||
}
|
||||
std::abort();
|
||||
inline void msg(const char* condition, const char* file, int line,
|
||||
const char* func, std::string_view message = "") {
|
||||
|
||||
Logger::error("Assertion failed: {} at {}: {} in function {}", condition,
|
||||
file, line, func);
|
||||
if (message.size()) {
|
||||
Logger::error("Message: {}", message);
|
||||
}
|
||||
std::abort();
|
||||
}
|
||||
} // namespace Assert
|
||||
|
||||
#ifdef DEBUG_MODE
|
||||
#define CUBED_ASSERT(cond) \
|
||||
do { \
|
||||
if (!(cond)) { \
|
||||
::Assert::msg(#cond, __FILE__, __LINE__, __func__); \
|
||||
} \
|
||||
#define ASSERT(cond) \
|
||||
do { \
|
||||
if (!(cond)) { \
|
||||
::Cubed::Assert::msg(#cond, __FILE__, __LINE__, __func__); \
|
||||
} \
|
||||
} while (0)
|
||||
#define CUBED_ASSERT_MSG(cond, message) \
|
||||
do { \
|
||||
if (!(cond)) { \
|
||||
::Assert::msg(#cond, __FILE__, __LINE__, __func__, message); \
|
||||
} \
|
||||
#define ASSERT_MSG(cond, message) \
|
||||
do { \
|
||||
if (!(cond)) { \
|
||||
::Cubed::Assert::msg(#cond, __FILE__, __LINE__, __func__, \
|
||||
message); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
#define CUBED_ASSERT(cond) ((void)0)
|
||||
#define CUBED_ASSERT_MSG(cond, message) ((void)0)
|
||||
#define ASSERT(cond) ((void)0)
|
||||
#define ASSERT_MSG(cond, message) ((void)0)
|
||||
#endif
|
||||
|
||||
} // namespace Cubed
|
||||
@@ -1,8 +1,44 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <string_view>
|
||||
namespace HASH {
|
||||
inline std::size_t str(std::string_view value) {
|
||||
return std::hash<std::string_view>{}(value);
|
||||
}
|
||||
namespace Cubed {
|
||||
|
||||
namespace HASH {
|
||||
inline std::size_t str(std::string_view value) {
|
||||
return std::hash<std::string_view>{}(value);
|
||||
}
|
||||
inline uint32_t combine_32(uint32_t seed, uint32_t v) {
|
||||
seed ^= v + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||
return seed;
|
||||
}
|
||||
inline uint32_t chunk_seed_hash(int32_t a, int32_t b, uint32_t fixed_seed) {
|
||||
uint32_t seed =
|
||||
combine_32(combine_32(fixed_seed, (uint32_t)a), (uint32_t)b);
|
||||
return seed;
|
||||
}
|
||||
/*
|
||||
inline uint32_t chunk_seed_hash(int32_t a, int32_t b, uint32_t fixed_seed) {
|
||||
uint32_t h = fixed_seed;
|
||||
|
||||
h ^= (uint32_t)a * 0xcc9e2d51u;
|
||||
h = (h << 15) | (h >> 17); // rotl 15
|
||||
h *= 0x1b873593u;
|
||||
|
||||
h ^= (uint32_t)b * 0xcc9e2d51u;
|
||||
h = (h << 15) | (h >> 17); // rotl 15
|
||||
h *= 0x1b873593u;
|
||||
|
||||
// Finalization(avalanche)
|
||||
h ^= h >> 16;
|
||||
h *= 0x85ebca6bu;
|
||||
h ^= h >> 13;
|
||||
h *= 0xc2b2ae35u;
|
||||
h ^= h >> 16;
|
||||
|
||||
return h;
|
||||
}
|
||||
*/
|
||||
|
||||
} // namespace HASH
|
||||
|
||||
} // namespace Cubed
|
||||
@@ -4,19 +4,19 @@ namespace Cubed {
|
||||
|
||||
class Random {
|
||||
public:
|
||||
static unsigned get_base_seed();
|
||||
static unsigned get_thread_seed();
|
||||
static Random& get();
|
||||
|
||||
Random();
|
||||
Random(unsigned seed);
|
||||
bool random_bool(double probability);
|
||||
std::mt19937& engine();
|
||||
unsigned seed();
|
||||
|
||||
void init(unsigned seed);
|
||||
int random_int(int min, int max);
|
||||
float random_float(float min, float max);
|
||||
|
||||
private:
|
||||
Random();
|
||||
unsigned int m_seed = 0;
|
||||
std::mt19937 m_engine;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
} // namespace Cubed
|
||||
|
||||
@@ -2,13 +2,14 @@
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
#include "Cubed/primitive_data.hpp"
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <Cubed/config.hpp>
|
||||
namespace Cubed {
|
||||
|
||||
struct Character {
|
||||
glm::vec2 uv_min;
|
||||
@@ -25,8 +26,12 @@ public:
|
||||
Font();
|
||||
~Font();
|
||||
|
||||
static std::vector<Vertex2D> vertices(const std::string& text, float x = 0.0f, float y = 0.0f, float scale = 1.0f);
|
||||
static std::vector<Vertex2D> vertices(const std::string& text,
|
||||
float x = 0.0f, float y = 0.0f,
|
||||
float scale = 1.0f);
|
||||
static GLuint text_texture();
|
||||
static const std::string& font_path();
|
||||
|
||||
private:
|
||||
FT_Library m_ft;
|
||||
FT_Face m_face;
|
||||
@@ -35,10 +40,12 @@ private:
|
||||
float m_texture_height = 64;
|
||||
|
||||
static inline GLuint m_text_texture;
|
||||
static inline std::string m_font_path{ASSETS_PATH
|
||||
"fonts/IBMPlexSans-Regular.ttf"};
|
||||
std::unordered_map<char8_t, Character> m_characters;
|
||||
|
||||
void load_character(char8_t c);
|
||||
void setup_font_character();
|
||||
|
||||
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
@@ -1,96 +1,85 @@
|
||||
#pragma once
|
||||
#include <syncstream>
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
#include <source_location>
|
||||
#include <string>
|
||||
#include <syncstream>
|
||||
|
||||
namespace Cubed {
|
||||
|
||||
namespace Logger {
|
||||
enum class Level {
|
||||
TRACE,
|
||||
DEBUG,
|
||||
INFO,
|
||||
ERROR,
|
||||
WARN
|
||||
};
|
||||
enum class Level { TRACE, DEBUG, INFO, ERROR, WARN };
|
||||
|
||||
template<typename... Args>
|
||||
inline void info(std::format_string<Args...> fmt, Args&&... args) {
|
||||
auto now_time = std::chrono::
|
||||
time_point_cast<std::chrono::seconds>
|
||||
(std::chrono::system_clock::now());
|
||||
|
||||
std::string msg = std::vformat(fmt.get(), std::make_format_args(args...));
|
||||
std::osyncstream(std::cout) << "\033[1;32m"
|
||||
<< std::format("[INFO][{:%Y-%m-%d %H:%M:%S}]", now_time)
|
||||
<< msg
|
||||
<< "\033[0m"
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
inline void error(std::format_string<Args...> fmt, Args&&... args) {
|
||||
auto now_time = std::chrono::
|
||||
time_point_cast<std::chrono::seconds>
|
||||
(std::chrono::system_clock::now());
|
||||
std::string msg = std::vformat(fmt.get(), std::make_format_args(args...));
|
||||
std::osyncstream(std::cerr) << "\033[1;31m"
|
||||
<< std::format("[ERROR][{:%Y-%m-%d %H:%M:%S}]", now_time)
|
||||
<< msg
|
||||
<< "\033[0m"
|
||||
<< "\n";
|
||||
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
inline void warn(std::format_string<Args...> fmt, Args&&... args) {
|
||||
auto now_time = std::chrono::
|
||||
time_point_cast<std::chrono::seconds>
|
||||
(std::chrono::system_clock::now());
|
||||
std::string msg = std::vformat(fmt.get(), std::make_format_args(args...));
|
||||
std::osyncstream(std::cout) << "\033[1;33m"
|
||||
<< std::format("[WARN][{:%Y-%m-%d %H:%M:%S}]", now_time)
|
||||
<< msg
|
||||
<< "\033[0m"
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
inline void log(Level level, std::source_location loc, std::format_string<Args...> fmt, Args&&... args) {
|
||||
auto now_time = std::chrono::
|
||||
time_point_cast<std::chrono::seconds>
|
||||
(std::chrono::system_clock::now());
|
||||
std::string msg = std::vformat(fmt.get(), std::make_format_args(args...));
|
||||
switch (level) {
|
||||
case Logger::Level::TRACE:
|
||||
std::osyncstream(std::cout) << "\033[1;34m"
|
||||
<< std::format("[TRACE][{:%Y-%m-%d %H:%M:%S}]", now_time)
|
||||
<< "[" << loc.file_name() << ":" << loc.line() << "]"
|
||||
<< "[" << loc.function_name() << "]"
|
||||
<< msg
|
||||
<< "\033[0m"
|
||||
<< "\n";
|
||||
break;
|
||||
case Logger::Level::DEBUG:
|
||||
std::osyncstream(std::cout) << "\033[1;34m"
|
||||
<< std::format("[DEBUG][{:%Y-%m-%d %H:%M:%S}]", now_time)
|
||||
<< msg
|
||||
<< "\033[0m"
|
||||
<< "\n";
|
||||
break;
|
||||
case Logger::Level::INFO:
|
||||
info(fmt, std::forward<Args>(args)...);
|
||||
break;
|
||||
case Logger::Level::WARN:
|
||||
warn(fmt, std::forward<Args>(args)...);
|
||||
break;
|
||||
case Logger::Level::ERROR:
|
||||
error(fmt, std::forward<Args>(args)...);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
template <typename... Args>
|
||||
inline void info(std::format_string<Args...> fmt, Args&&... args) {
|
||||
auto now_time = std::chrono::time_point_cast<std::chrono::seconds>(
|
||||
std::chrono::system_clock::now());
|
||||
|
||||
std::string msg = std::vformat(fmt.get(), std::make_format_args(args...));
|
||||
std::osyncstream(std::cout)
|
||||
<< "\033[1;32m" << std::format("[INFO][{:%Y-%m-%d %H:%M:%S}]", now_time)
|
||||
<< msg << "\033[0m"
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void error(std::format_string<Args...> fmt, Args&&... args) {
|
||||
auto now_time = std::chrono::time_point_cast<std::chrono::seconds>(
|
||||
std::chrono::system_clock::now());
|
||||
std::string msg = std::vformat(fmt.get(), std::make_format_args(args...));
|
||||
std::osyncstream(std::cerr)
|
||||
<< "\033[1;31m"
|
||||
<< std::format("[ERROR][{:%Y-%m-%d %H:%M:%S}]", now_time) << msg
|
||||
<< "\033[0m"
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void warn(std::format_string<Args...> fmt, Args&&... args) {
|
||||
auto now_time = std::chrono::time_point_cast<std::chrono::seconds>(
|
||||
std::chrono::system_clock::now());
|
||||
std::string msg = std::vformat(fmt.get(), std::make_format_args(args...));
|
||||
std::osyncstream(std::cout)
|
||||
<< "\033[1;33m" << std::format("[WARN][{:%Y-%m-%d %H:%M:%S}]", now_time)
|
||||
<< msg << "\033[0m"
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void log(Level level, std::source_location loc,
|
||||
std::format_string<Args...> fmt, Args&&... args) {
|
||||
auto now_time = std::chrono::time_point_cast<std::chrono::seconds>(
|
||||
std::chrono::system_clock::now());
|
||||
std::string msg = std::vformat(fmt.get(), std::make_format_args(args...));
|
||||
switch (level) {
|
||||
case Logger::Level::TRACE:
|
||||
std::osyncstream(std::cout)
|
||||
<< "\033[1;34m"
|
||||
<< std::format("[TRACE][{:%Y-%m-%d %H:%M:%S}]", now_time) << "["
|
||||
<< loc.file_name() << ":" << loc.line() << "]"
|
||||
<< "[" << loc.function_name() << "]" << msg << "\033[0m"
|
||||
<< "\n";
|
||||
break;
|
||||
case Logger::Level::DEBUG:
|
||||
std::osyncstream(std::cout)
|
||||
<< "\033[1;34m"
|
||||
<< std::format("[DEBUG][{:%Y-%m-%d %H:%M:%S}]", now_time) << msg
|
||||
<< "\033[0m"
|
||||
<< "\n";
|
||||
break;
|
||||
case Logger::Level::INFO:
|
||||
info(fmt, std::forward<Args>(args)...);
|
||||
break;
|
||||
case Logger::Level::WARN:
|
||||
warn(fmt, std::forward<Args>(args)...);
|
||||
break;
|
||||
case Logger::Level::ERROR:
|
||||
error(fmt, std::forward<Args>(args)...);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Logger
|
||||
|
||||
} // namespace Cubed
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
#pragma once
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
namespace Cubed {
|
||||
|
||||
namespace Math {
|
||||
void extract_frustum_planes(const glm::mat4& mvp_matrix, std::vector<glm::vec4>& planes);
|
||||
}
|
||||
|
||||
void extract_frustum_planes(const glm::mat4& mvp_matrix,
|
||||
std::vector<glm::vec4>& planes);
|
||||
|
||||
float smootherstep(float edge0, float edge1, float x);
|
||||
bool is_aabb_in_frustum(const glm::vec3& center, const glm::vec3& half_extents,
|
||||
const std::vector<glm::vec4>& planes);
|
||||
float deterministic_random(int x, int z, uint64_t seed);
|
||||
} // namespace Math
|
||||
|
||||
} // namespace Cubed
|
||||
@@ -2,15 +2,35 @@
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
|
||||
class PerlinNoise {
|
||||
namespace Cubed {
|
||||
|
||||
class PerlinNoise3D {
|
||||
public:
|
||||
static void init();
|
||||
static void init(unsigned seed);
|
||||
static float noise(float x, float y, float z);
|
||||
static void reload(unsigned seed);
|
||||
|
||||
private:
|
||||
static inline std::atomic<bool> is_init = false;
|
||||
static inline std::vector<int> p;
|
||||
static float fade(float t);
|
||||
static float lerp(float t, float a, float b);
|
||||
static float grad(int hash, float x, float y, float z);
|
||||
};
|
||||
|
||||
class PerlinNoise2D {
|
||||
public:
|
||||
static void init(unsigned seed);
|
||||
static float noise(float x, float y);
|
||||
static void reload(unsigned seed);
|
||||
|
||||
private:
|
||||
static inline std::atomic<bool> is_init = false;
|
||||
static inline std::vector<int> p;
|
||||
|
||||
static float fade(float t);
|
||||
static float lerp(float t, float a, float b);
|
||||
static float grad(int hash, float x, float y, float z);
|
||||
static float grad(int hash, float x, float y);
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
@@ -1,16 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include <SOIL2.h>
|
||||
#include <glad/glad.h>
|
||||
#include <string>
|
||||
|
||||
namespace Tools {
|
||||
GLuint create_shader_program(const std::string& v_shader_path, const std::string& f_shader_path);
|
||||
void print_shader_log(GLuint shader);
|
||||
void print_program_info(int prog);
|
||||
bool check_opengl_error();
|
||||
std::string read_shader_source(const std::string& file_path);
|
||||
void delete_image_data(unsigned char* data);
|
||||
unsigned char* load_image_data(const std::string& tex_image_path);
|
||||
namespace Cubed {
|
||||
|
||||
}
|
||||
namespace Tools {
|
||||
GLuint create_shader_program(const std::string& v_shader_path,
|
||||
const std::string& f_shader_path);
|
||||
void print_shader_log(GLuint shader);
|
||||
void print_program_info(int prog);
|
||||
bool check_opengl_error();
|
||||
std::string read_shader_source(const std::string& file_path);
|
||||
void delete_image_data(unsigned char* data);
|
||||
unsigned char* load_image_data(const std::string& tex_image_path);
|
||||
|
||||
} // namespace Tools
|
||||
|
||||
} // namespace Cubed
|
||||
|
||||
@@ -1,33 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cubed/tools/log.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <Cubed/tools/log.hpp>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
// clang-format off
|
||||
#include <windows.h>
|
||||
#include <psapi.h>
|
||||
typedef LONG (WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);
|
||||
// clang-format on
|
||||
typedef LONG(WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);
|
||||
#elif defined(__linux__)
|
||||
#include <fstream>
|
||||
#include <sys/resource.h>
|
||||
#include <unistd.h>
|
||||
#include <fstream>
|
||||
#endif
|
||||
|
||||
namespace Cubed {
|
||||
|
||||
namespace Tools {
|
||||
|
||||
inline bool get_os_version(std::string& str) {
|
||||
#ifdef _WIN32
|
||||
HMODULE hntdll = GetModuleHandleW(L"ntdll.dll");
|
||||
if (!hntdll) return false;
|
||||
if (!hntdll)
|
||||
return false;
|
||||
|
||||
auto prtl_get_version = reinterpret_cast<RtlGetVersionPtr>(
|
||||
GetProcAddress(hntdll, "RtlGetVersion"));
|
||||
if (!prtl_get_version) return false;
|
||||
if (!prtl_get_version)
|
||||
return false;
|
||||
|
||||
RTL_OSVERSIONINFOW osvi = { 0 };
|
||||
RTL_OSVERSIONINFOW osvi = {0};
|
||||
osvi.dwOSVersionInfoSize = sizeof(osvi);
|
||||
if (prtl_get_version(&osvi) != 0) return false;
|
||||
if (prtl_get_version(&osvi) != 0)
|
||||
return false;
|
||||
if (osvi.dwMajorVersion == 10) {
|
||||
if (osvi.dwBuildNumber >= 22000) {
|
||||
str = "Windows 11 Build " + std::to_string(osvi.dwBuildNumber);
|
||||
@@ -71,7 +79,8 @@ inline bool get_os_version(std::string& str) {
|
||||
inline size_t get_current_rss() {
|
||||
#ifdef _WIN32
|
||||
PROCESS_MEMORY_COUNTERS_EX pmc;
|
||||
if (GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc))) {
|
||||
if (GetProcessMemoryInfo(GetCurrentProcess(),
|
||||
(PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc))) {
|
||||
return pmc.WorkingSetSize;
|
||||
}
|
||||
return 0;
|
||||
@@ -93,17 +102,23 @@ inline std::string get_cpu_info() {
|
||||
std::string cpu_name;
|
||||
|
||||
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
||||
L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",
|
||||
0, KEY_READ, &h_key) == ERROR_SUCCESS) {
|
||||
L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0,
|
||||
KEY_READ, &h_key) == ERROR_SUCCESS) {
|
||||
|
||||
DWORD dw_size = 0;
|
||||
if (RegQueryValueExW(h_key, L"ProcessorNameString", NULL, NULL, NULL, &dw_size) == ERROR_SUCCESS && dw_size > 0) {
|
||||
if (RegQueryValueExW(h_key, L"ProcessorNameString", NULL, NULL, NULL,
|
||||
&dw_size) == ERROR_SUCCESS &&
|
||||
dw_size > 0) {
|
||||
std::vector<wchar_t> buffer(dw_size / sizeof(wchar_t));
|
||||
if (RegQueryValueExW(h_key, L"ProcessorNameString", NULL, NULL, (LPBYTE)buffer.data(), &dw_size) == ERROR_SUCCESS) {
|
||||
int len = WideCharToMultiByte(CP_UTF8, 0, buffer.data(), -1, NULL, 0, NULL, NULL);
|
||||
if (RegQueryValueExW(h_key, L"ProcessorNameString", NULL, NULL,
|
||||
(LPBYTE)buffer.data(),
|
||||
&dw_size) == ERROR_SUCCESS) {
|
||||
int len = WideCharToMultiByte(CP_UTF8, 0, buffer.data(), -1,
|
||||
NULL, 0, NULL, NULL);
|
||||
if (len > 0) {
|
||||
std::vector<char> narrow(len);
|
||||
WideCharToMultiByte(CP_UTF8, 0, buffer.data(), -1, narrow.data(), len, NULL, NULL);
|
||||
WideCharToMultiByte(CP_UTF8, 0, buffer.data(), -1,
|
||||
narrow.data(), len, NULL, NULL);
|
||||
cpu_name = narrow.data();
|
||||
}
|
||||
}
|
||||
@@ -114,7 +129,7 @@ inline std::string get_cpu_info() {
|
||||
cpu_name = "Unknown";
|
||||
}
|
||||
return cpu_name;
|
||||
#elif defined (__linux__)
|
||||
#elif defined(__linux__)
|
||||
std::ifstream file("/proc/cpuinfo");
|
||||
if (!file.is_open()) {
|
||||
return std::string{"Unkown"};
|
||||
@@ -138,7 +153,6 @@ inline std::string get_cpu_info() {
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace Tools
|
||||
|
||||
}
|
||||
|
||||
|
||||
} // namespace Cubed
|
||||
|
||||