Compare commits
23 Commits
pre-alpha-
...
main
Author | SHA1 | Date | |
---|---|---|---|
|
ccacb3088f | ||
|
93897037b8 | ||
|
90f1cc59d5 | ||
|
b4e22d076b | ||
|
41e3abe45e | ||
|
70157a4f7f | ||
|
a34f2fd9a3 | ||
|
28cc58d2c6 | ||
|
7d074585c1 | ||
|
bffb488446 | ||
|
cced9a2b95 | ||
|
ec70bb48ac | ||
|
7788b5f6be | ||
|
734030edcb | ||
|
6c3f2ddd84 | ||
|
34ba20188f | ||
|
f58173649b | ||
|
4e1c4fe98a | ||
|
117e2c321d | ||
|
e7dd7d13d3 | ||
|
d8aaa00f1a | ||
|
8b26492b78 | ||
|
5d485b21a5 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -410,3 +410,5 @@ FodyWeavers.xsd
|
||||
*.sln.iml
|
||||
|
||||
imgui.ini
|
||||
|
||||
build/
|
||||
|
26
README.md
26
README.md
@ -3,3 +3,29 @@ A Minecraft clone made in C++ and OpenGL
|
||||
|
||||
## How to Run
|
||||
To run the game, download the ScuffedMinecraft zip file from the [latest release](https://github.com/EvanatorM/ScuffedMinecraft/releases/latest), unzip the file, and run ScuffedMinecraft.exe. The assets folder must be in the same place as the exe file.
|
||||
|
||||
## Building
|
||||
|
||||
### Building with Visual Studio
|
||||
Import the project in Visual Studio 17 or higher and build it.
|
||||
|
||||
### Building with CMake
|
||||
In the project root directory:
|
||||
Create CMake files:
|
||||
```sh
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake ../ScuffedMinecraft
|
||||
```
|
||||
After that you can build the project using:
|
||||
```sh
|
||||
cmake --build ./build
|
||||
```
|
||||
Run the build command in the project root directory.
|
||||
|
||||
The final executable can be found at `(project root)/ScuffedMinecraft/bin`
|
||||
|
||||
#### Note for building with CMake
|
||||
If you're running from a command line, make sure to run
|
||||
the executable in the same directory as it is located
|
||||
to ensure all resources are loaded properly.
|
||||
|
26
ScuffedMinecraft/CMakeLists.txt
Normal file
26
ScuffedMinecraft/CMakeLists.txt
Normal file
@ -0,0 +1,26 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
project(ScuffedMinecraft)
|
||||
|
||||
# output directories
|
||||
set(CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/bin)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
|
||||
# copy assets
|
||||
add_custom_target(copy_assets ALL
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
${CMAKE_SOURCE_DIR}/assets
|
||||
${CMAKE_BINARY_DIR}/assets
|
||||
COMMENT "Copying assets")
|
||||
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
# global dependency directories
|
||||
include_directories(../Dependencies/include/)
|
||||
link_directories(../Dependencies/lib/)
|
||||
|
||||
add_subdirectory(vendor/imgui)
|
||||
add_subdirectory(src)
|
@ -130,6 +130,7 @@
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>glfw3.lib;opengl32.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalOptions>/ignore:4099 %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
@ -148,6 +149,7 @@
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>glfw3.lib;opengl32.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalOptions>/ignore:4099 %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
@ -155,11 +157,14 @@
|
||||
<ClCompile Include="src\Block.cpp" />
|
||||
<ClCompile Include="src\Camera.cpp" />
|
||||
<ClCompile Include="src\Chunk.cpp" />
|
||||
<ClCompile Include="src\ChunkData.cpp" />
|
||||
<ClCompile Include="src\ChunkPos.cpp" />
|
||||
<ClCompile Include="src\NoiseSettings.cpp" />
|
||||
<ClCompile Include="src\Physics.cpp" />
|
||||
<ClCompile Include="src\Planet.cpp" />
|
||||
<ClCompile Include="src\Shader.cpp" />
|
||||
<ClCompile Include="src\SurfaceFeature.cpp" />
|
||||
<ClCompile Include="src\TupleHash.h" />
|
||||
<ClCompile Include="src\ChunkPosHash.h" />
|
||||
<ClCompile Include="src\WorldGen.cpp" />
|
||||
<ClCompile Include="src\WorldGen.h" />
|
||||
<ClCompile Include="vendor\glad.c" />
|
||||
@ -176,10 +181,14 @@
|
||||
<ClInclude Include="src\Blocks.h" />
|
||||
<ClInclude Include="src\Camera.h" />
|
||||
<ClInclude Include="src\Chunk.h" />
|
||||
<ClInclude Include="src\ChunkData.h" />
|
||||
<ClInclude Include="src\ChunkPos.h" />
|
||||
<ClInclude Include="src\NoiseSettings.h" />
|
||||
<ClInclude Include="src\Physics.h" />
|
||||
<ClInclude Include="src\Planet.h" />
|
||||
<ClInclude Include="src\Shader.h" />
|
||||
<ClInclude Include="src\SurfaceFeature.h" />
|
||||
<ClInclude Include="src\Vertex.h" />
|
||||
<ClInclude Include="vendor\imgui\imconfig.h" />
|
||||
<ClInclude Include="vendor\imgui\imgui.h" />
|
||||
<ClInclude Include="vendor\imgui\imgui_impl_glfw.h" />
|
||||
@ -193,11 +202,22 @@
|
||||
<ClInclude Include="vendor\stb_image.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="assets\shaders\fragment_shader.glsl" />
|
||||
<None Include="assets\shaders\vertex_shader.glsl" />
|
||||
<None Include="assets\shaders\billboard_frag.glsl" />
|
||||
<None Include="assets\shaders\billboard_vert.glsl" />
|
||||
<None Include="assets\shaders\block_outline_frag.glsl" />
|
||||
<None Include="assets\shaders\block_outline_vert.glsl" />
|
||||
<None Include="assets\shaders\crosshair_frag.glsl" />
|
||||
<None Include="assets\shaders\crosshair_vert.glsl" />
|
||||
<None Include="assets\shaders\framebuffer_frag.glsl" />
|
||||
<None Include="assets\shaders\framebuffer_vert.glsl" />
|
||||
<None Include="assets\shaders\main_frag.glsl" />
|
||||
<None Include="assets\shaders\main_vert.glsl" />
|
||||
<None Include="assets\shaders\water_frag.glsl" />
|
||||
<None Include="assets\shaders\water_vert.glsl" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="assets\sprites\block_map.png" />
|
||||
<Image Include="assets\sprites\crosshair.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="vendor\imgui\LICENSE.txt" />
|
||||
|
@ -33,7 +33,7 @@
|
||||
<ClCompile Include="src\Block.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\TupleHash.h">
|
||||
<ClCompile Include="src\ChunkPosHash.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\WorldGen.h">
|
||||
@ -72,6 +72,15 @@
|
||||
<ClCompile Include="src\SurfaceFeature.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Physics.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\ChunkPos.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\ChunkData.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\Shader.h">
|
||||
@ -131,15 +140,40 @@
|
||||
<ClInclude Include="src\SurfaceFeature.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Vertex.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Physics.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\ChunkPos.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\ChunkData.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="assets\shaders\vertex_shader.glsl" />
|
||||
<None Include="assets\shaders\fragment_shader.glsl" />
|
||||
<None Include="assets\shaders\main_vert.glsl" />
|
||||
<None Include="assets\shaders\main_frag.glsl" />
|
||||
<None Include="assets\shaders\water_frag.glsl" />
|
||||
<None Include="assets\shaders\water_vert.glsl" />
|
||||
<None Include="assets\shaders\billboard_vert.glsl" />
|
||||
<None Include="assets\shaders\billboard_frag.glsl" />
|
||||
<None Include="assets\shaders\framebuffer_vert.glsl" />
|
||||
<None Include="assets\shaders\framebuffer_frag.glsl" />
|
||||
<None Include="assets\shaders\block_outline_vert.glsl" />
|
||||
<None Include="assets\shaders\block_outline_frag.glsl" />
|
||||
<None Include="assets\shaders\crosshair_frag.glsl" />
|
||||
<None Include="assets\shaders\crosshair_vert.glsl" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="assets\sprites\block_map.png">
|
||||
<Filter>Resource Files</Filter>
|
||||
</Image>
|
||||
<Image Include="assets\sprites\crosshair.png">
|
||||
<Filter>Resource Files</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="vendor\imgui\LICENSE.txt" />
|
||||
|
27
ScuffedMinecraft/assets/shaders/billboard_frag.glsl
Normal file
27
ScuffedMinecraft/assets/shaders/billboard_frag.glsl
Normal file
@ -0,0 +1,27 @@
|
||||
#version 330 core
|
||||
|
||||
in vec2 TexCoord;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
uniform sampler2D tex;
|
||||
|
||||
const vec3 ambient = vec3(.5);
|
||||
const vec3 lightDirection = vec3(0.8, 1, 0.7);
|
||||
|
||||
const vec3 normal = vec3( 0, -1, 0);
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 lightDir = normalize(-lightDirection);
|
||||
|
||||
float diff = max(dot(normal, lightDir), 0.0);
|
||||
vec3 diffuse = diff * vec3(1);
|
||||
|
||||
vec4 result = vec4(ambient + diffuse, 1.0);
|
||||
|
||||
vec4 texResult = texture(tex, TexCoord);
|
||||
if (texResult.a == 0)
|
||||
discard;
|
||||
FragColor = texResult * result;
|
||||
}
|
19
ScuffedMinecraft/assets/shaders/billboard_vert.glsl
Normal file
19
ScuffedMinecraft/assets/shaders/billboard_vert.glsl
Normal file
@ -0,0 +1,19 @@
|
||||
#version 330 core
|
||||
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec2 aTexCoord;
|
||||
|
||||
out vec2 TexCoord;
|
||||
out vec3 Normal;
|
||||
|
||||
uniform float texMultiplier;
|
||||
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = projection * view * model * vec4(aPos, 1.0);
|
||||
TexCoord = aTexCoord * texMultiplier;
|
||||
}
|
10
ScuffedMinecraft/assets/shaders/block_outline_frag.glsl
Normal file
10
ScuffedMinecraft/assets/shaders/block_outline_frag.glsl
Normal file
@ -0,0 +1,10 @@
|
||||
#version 330 core
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
uniform float time;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
}
|
12
ScuffedMinecraft/assets/shaders/block_outline_vert.glsl
Normal file
12
ScuffedMinecraft/assets/shaders/block_outline_vert.glsl
Normal file
@ -0,0 +1,12 @@
|
||||
#version 330 core
|
||||
|
||||
layout (location = 0) in vec3 aPos;
|
||||
|
||||
uniform vec3 model;
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = projection * view * vec4(aPos + model, 1.0);
|
||||
}
|
18
ScuffedMinecraft/assets/shaders/crosshair_frag.glsl
Normal file
18
ScuffedMinecraft/assets/shaders/crosshair_frag.glsl
Normal file
@ -0,0 +1,18 @@
|
||||
#version 330 core
|
||||
|
||||
in vec2 TexCoord;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
uniform sampler2D tex;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 texResult = texture(tex, TexCoord);
|
||||
|
||||
if (texResult.a == 0)
|
||||
discard;
|
||||
|
||||
texResult.a = 0.8;
|
||||
FragColor = texResult;
|
||||
}
|
14
ScuffedMinecraft/assets/shaders/crosshair_vert.glsl
Normal file
14
ScuffedMinecraft/assets/shaders/crosshair_vert.glsl
Normal file
@ -0,0 +1,14 @@
|
||||
#version 330 core
|
||||
|
||||
layout (location = 0) in vec2 inPos;
|
||||
layout (location = 1) in vec2 inTexCoords;
|
||||
|
||||
uniform mat4 projection;
|
||||
|
||||
out vec2 TexCoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = projection * vec4(inPos, 0.0, 1.0);
|
||||
TexCoord = inTexCoords;
|
||||
}
|
32
ScuffedMinecraft/assets/shaders/framebuffer_frag.glsl
Normal file
32
ScuffedMinecraft/assets/shaders/framebuffer_frag.glsl
Normal file
@ -0,0 +1,32 @@
|
||||
#version 330 core
|
||||
|
||||
out vec4 FragColor;
|
||||
in vec2 TexCoords;
|
||||
|
||||
uniform sampler2D screenTexture;
|
||||
uniform sampler2D depthTexture;
|
||||
|
||||
uniform bool underwater;
|
||||
|
||||
const vec3 fogColor = vec3(0, 0, 0.25);
|
||||
const float fogNear = 0.9;
|
||||
const float fogFar = 1.0;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 color = texture(screenTexture, TexCoords).rgb;
|
||||
float depth = texture(depthTexture, TexCoords).r;
|
||||
|
||||
vec3 finalColor = color;
|
||||
|
||||
// Calculate fog
|
||||
if (underwater)
|
||||
{
|
||||
float fogFactor = (fogFar - depth) / (fogFar - fogNear);
|
||||
fogFactor = clamp(fogFactor, 0.0, 1.0);
|
||||
|
||||
finalColor = mix(fogColor, color, fogFactor);
|
||||
}
|
||||
|
||||
FragColor = vec4(vec3(finalColor), 1.0);
|
||||
}
|
12
ScuffedMinecraft/assets/shaders/framebuffer_vert.glsl
Normal file
12
ScuffedMinecraft/assets/shaders/framebuffer_vert.glsl
Normal file
@ -0,0 +1,12 @@
|
||||
#version 330 core
|
||||
|
||||
layout (location = 0) in vec2 inPos;
|
||||
layout (location = 1) in vec2 inTexCoords;
|
||||
|
||||
out vec2 TexCoords;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(inPos.x, inPos.y, 0.0, 1.0);
|
||||
TexCoords = inTexCoords;
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
#version 330 core
|
||||
|
||||
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec2 aTexCoord;
|
||||
layout (location = 2) in int aDirection;
|
||||
@ -13,6 +12,7 @@ uniform float texMultiplier;
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
uniform float time;
|
||||
|
||||
// Array of possible normals based on direction
|
||||
const vec3 normals[] = vec3[](
|
26
ScuffedMinecraft/assets/shaders/water_frag.glsl
Normal file
26
ScuffedMinecraft/assets/shaders/water_frag.glsl
Normal file
@ -0,0 +1,26 @@
|
||||
#version 330 core
|
||||
|
||||
in vec2 TexCoord;
|
||||
in vec3 Normal;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
uniform sampler2D tex;
|
||||
|
||||
vec3 ambient = vec3(.5);
|
||||
vec3 lightDirection = vec3(0.8, 1, 0.7);
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 lightDir = normalize(-lightDirection);
|
||||
|
||||
float diff = max(dot(Normal, lightDir), 0.0);
|
||||
vec3 diffuse = diff * vec3(1);
|
||||
|
||||
vec4 result = vec4(ambient + diffuse, 1.0);
|
||||
|
||||
vec4 texResult = texture(tex, TexCoord);
|
||||
if (texResult.a == 0)
|
||||
discard;
|
||||
FragColor = texResult * result;
|
||||
}
|
47
ScuffedMinecraft/assets/shaders/water_vert.glsl
Normal file
47
ScuffedMinecraft/assets/shaders/water_vert.glsl
Normal file
@ -0,0 +1,47 @@
|
||||
#version 330 core
|
||||
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec2 aTexCoord;
|
||||
layout (location = 2) in int aDirection;
|
||||
layout (location = 3) in int aTop;
|
||||
|
||||
out vec2 TexCoord;
|
||||
out vec3 Normal;
|
||||
|
||||
uniform float texMultiplier;
|
||||
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
uniform float time;
|
||||
|
||||
// Array of possible normals based on direction
|
||||
const vec3 normals[] = vec3[](
|
||||
vec3( 0, 0, 1), // 0
|
||||
vec3( 0, 0, -1), // 1
|
||||
vec3( 1, 0, 0), // 2
|
||||
vec3(-1, 0, 0), // 3
|
||||
vec3( 0, 1, 0), // 4
|
||||
vec3( 0, -1, 0), // 5
|
||||
vec3( 0, -1, 0) // 6
|
||||
);
|
||||
|
||||
const int aFrames = 32;
|
||||
const float animationTime = 5;
|
||||
const int texNum = 16;
|
||||
void main()
|
||||
{
|
||||
vec3 pos = aPos;
|
||||
if (aTop == 1)
|
||||
{
|
||||
pos.y -= .1;
|
||||
pos.y += (sin(pos.x * 3.1415926535 / 2 + time) + sin(pos.z * 3.1415926535 / 2 + time * 1.5)) * .05;
|
||||
}
|
||||
gl_Position = projection * view * model * vec4(pos, 1.0);
|
||||
vec2 currentTex = aTexCoord;
|
||||
currentTex.x += mod(floor(mod(time / animationTime, 1) * aFrames), texNum);
|
||||
currentTex.y += floor(floor(mod(time / animationTime, 1) * aFrames) / texNum);
|
||||
TexCoord = currentTex * texMultiplier;
|
||||
|
||||
Normal = normals[aDirection];
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 9.1 KiB |
Binary file not shown.
BIN
ScuffedMinecraft/assets/sprites/crosshair.png
Normal file
BIN
ScuffedMinecraft/assets/sprites/crosshair.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 246 B |
@ -2,6 +2,13 @@
|
||||
#include "imgui_impl_glfw.h"
|
||||
#include "imgui_impl_opengl3.h"
|
||||
|
||||
#ifdef LINUX
|
||||
#include <cstdlib>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
@ -16,11 +23,14 @@
|
||||
#include "Shader.h"
|
||||
#include "Camera.h"
|
||||
#include "Planet.h"
|
||||
#include "Blocks.h"
|
||||
#include "Physics.h"
|
||||
|
||||
void framebufferSizeCallback(GLFWwindow* window, int width, int height);
|
||||
void processInput(GLFWwindow* window);
|
||||
void mouse_callback(GLFWwindow* window, double xpos, double ypos);
|
||||
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
|
||||
void mouse_button_callback(GLFWwindow* window, int button, int action, int mods);
|
||||
|
||||
float deltaTime = 0.0f;
|
||||
float lastFrame = 0.0f;
|
||||
@ -34,17 +44,94 @@ bool firstMouse = true;
|
||||
|
||||
bool menuMode = false;
|
||||
bool escapeDown = false;
|
||||
bool f1Down = false;
|
||||
|
||||
// Window settings
|
||||
float windowX = 1920;
|
||||
float windowY = 1080;
|
||||
bool vsync = true;
|
||||
|
||||
uint16_t selectedBlock = 1;
|
||||
|
||||
bool uiEnabled = true;
|
||||
|
||||
Camera camera;
|
||||
|
||||
// Window options
|
||||
#define VSYNC 1 // 0 for off, 1 for on
|
||||
GLuint framebufferTexture;
|
||||
GLuint depthTexture;
|
||||
|
||||
int main()
|
||||
float rectangleVertices[] =
|
||||
{
|
||||
// Coords // TexCoords
|
||||
1.0f, -1.0f, 1.0f, 0.0f,
|
||||
-1.0f, -1.0f, 0.0f, 0.0f,
|
||||
-1.0f, 1.0f, 0.0f, 1.0f,
|
||||
|
||||
1.0f, 1.0f, 1.0f, 1.0f,
|
||||
1.0f, -1.0f, 1.0f, 0.0f,
|
||||
-1.0f, 1.0f, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
float outlineVertices[] =
|
||||
{
|
||||
-.001f, -.001f, -.001f, 1.001f, -.001f, -.001f,
|
||||
1.001f, -.001f, -.001f, 1.001f, 1.001f, -.001f,
|
||||
1.001f, 1.001f, -.001f, -.001f, 1.001f, -.001f,
|
||||
-.001f, 1.001f, -.001f, -.001f, -.001f, -.001f,
|
||||
|
||||
-.001f, -.001f, -.001f, -.001f, -.001f, 1.001f,
|
||||
-.001f, -.001f, 1.001f, -.001f, 1.001f, 1.001f,
|
||||
-.001f, 1.001f, 1.001f, -.001f, 1.001f, -.001f,
|
||||
|
||||
1.001f, -.001f, -.001f, 1.001f, -.001f, 1.001f,
|
||||
1.001f, -.001f, 1.001f, 1.001f, 1.001f, 1.001f,
|
||||
1.001f, 1.001f, 1.001f, 1.001f, 1.001f, -.001f,
|
||||
|
||||
-.001f, -.001f, 1.001f, 1.001f, -.001f, 1.001f,
|
||||
-.001f, 1.001f, 1.001f, 1.001f, 1.001f, 1.001f,
|
||||
};
|
||||
|
||||
float crosshairVertices[] =
|
||||
{
|
||||
windowX / 2 - 13.5, windowY / 2 - 13.5, 0.0f, 0.0f,
|
||||
windowX / 2 + 13.5, windowY / 2 - 13.5, 1.0f, 0.0f,
|
||||
windowX / 2 + 13.5, windowY / 2 + 13.5, 1.0f, 1.0f,
|
||||
|
||||
windowX / 2 - 13.5, windowY / 2 - 13.5, 0.0f, 0.0f,
|
||||
windowX / 2 - 13.5, windowY / 2 + 13.5, 0.0f, 1.0f,
|
||||
windowX / 2 + 13.5, windowY / 2 + 13.5, 1.0f, 1.0f,
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#ifdef LINUX
|
||||
char* resolved_path = realpath(argv[0], NULL);
|
||||
if (resolved_path == NULL) {
|
||||
printf("%s: Please do not place binary in PATH\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
size_t resolved_length = strlen(resolved_path);
|
||||
// remove executable from path
|
||||
for (size_t i = resolved_length; i > 0; i--) {
|
||||
if (resolved_path[i] == '/' && resolved_path[i + 1] != 0) {
|
||||
resolved_path[i + 1] = 0;
|
||||
resolved_length = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
char* assets_path = (char*)malloc(resolved_length + strlen("assets") + 2);
|
||||
strcpy(assets_path, resolved_path);
|
||||
strcpy(assets_path + resolved_length + 1, "assets");
|
||||
struct stat path_stat;
|
||||
if (stat(assets_path, &path_stat) == -1 || !S_ISDIR(path_stat.st_mode)) {
|
||||
printf("%s: Asset directory not found\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
free(assets_path);
|
||||
|
||||
chdir(resolved_path);
|
||||
free(resolved_path);
|
||||
#endif
|
||||
// Initialize GLFW
|
||||
glfwInit();
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
@ -60,7 +147,7 @@ int main()
|
||||
return -1;
|
||||
}
|
||||
glfwMakeContextCurrent(window);
|
||||
glfwSwapInterval(VSYNC);
|
||||
glfwSwapInterval(vsync ? 1 : 0);
|
||||
|
||||
// Initialize GLAD
|
||||
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
|
||||
@ -74,6 +161,7 @@ int main()
|
||||
glfwSetFramebufferSizeCallback(window, framebufferSizeCallback);
|
||||
glfwSetCursorPosCallback(window, mouse_callback);
|
||||
glfwSetScrollCallback(window, scroll_callback);
|
||||
glfwSetMouseButtonCallback(window, mouse_button_callback);
|
||||
|
||||
glClearColor(0.6f, 0.8f, 1.0f, 1.0f);
|
||||
|
||||
@ -84,13 +172,93 @@ int main()
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
// Create shader
|
||||
Shader shader("assets/shaders/vertex_shader.glsl", "assets/shaders/fragment_shader.glsl");
|
||||
// Create shaders
|
||||
Shader shader("assets/shaders/main_vert.glsl", "assets/shaders/main_frag.glsl");
|
||||
shader.use();
|
||||
|
||||
shader.setFloat("texMultiplier", .25f);
|
||||
shader.setFloat("texMultiplier", 0.0625f);
|
||||
|
||||
// Create texture
|
||||
Shader waterShader("assets/shaders/water_vert.glsl", "assets/shaders/water_frag.glsl");
|
||||
waterShader.use();
|
||||
|
||||
waterShader.setFloat("texMultiplier", 0.0625f);
|
||||
|
||||
Shader billboardShader("assets/shaders/billboard_vert.glsl", "assets/shaders/billboard_frag.glsl");
|
||||
billboardShader.use();
|
||||
|
||||
billboardShader.setFloat("texMultiplier", 0.0625f);
|
||||
|
||||
Shader framebufferShader("assets/shaders/framebuffer_vert.glsl", "assets/shaders/framebuffer_frag.glsl");
|
||||
|
||||
Shader outlineShader("assets/shaders/block_outline_vert.glsl", "assets/shaders/block_outline_frag.glsl");
|
||||
|
||||
Shader crosshairShader("assets/shaders/crosshair_vert.glsl", "assets/shaders/crosshair_frag.glsl");
|
||||
|
||||
// Create post-processing framebuffer
|
||||
unsigned int FBO;
|
||||
glGenFramebuffers(1, &FBO);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
|
||||
|
||||
glGenTextures(1, &framebufferTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, framebufferTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, windowX, windowY, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, framebufferTexture, 0);
|
||||
|
||||
glGenTextures(1, &depthTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, depthTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, windowX, windowY, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
|
||||
|
||||
auto fboStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
if (fboStatus != GL_FRAMEBUFFER_COMPLETE)
|
||||
std::cout << "Framebuffer error: " << fboStatus << '\n';
|
||||
|
||||
unsigned int rectVAO, rectVBO;
|
||||
glGenVertexArrays(1, &rectVAO);
|
||||
glGenBuffers(1, &rectVBO);
|
||||
glBindVertexArray(rectVAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, rectVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(rectangleVertices), &rectangleVertices, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
|
||||
|
||||
framebufferShader.use();
|
||||
glUniform1i(glGetUniformLocation(framebufferShader.ID, "screenTexture"), 0);
|
||||
glUniform1i(glGetUniformLocation(framebufferShader.ID, "depthTexture"), 1);
|
||||
|
||||
unsigned int outlineVAO, outlineVBO;
|
||||
glGenVertexArrays(1, &outlineVAO);
|
||||
glGenBuffers(1, &outlineVBO);
|
||||
glBindVertexArray(outlineVAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, outlineVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(outlineVertices), &outlineVertices, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
|
||||
|
||||
unsigned int crosshairVAO, crosshairVBO;
|
||||
glGenVertexArrays(1, &crosshairVAO);
|
||||
glGenBuffers(1, &crosshairVBO);
|
||||
glBindVertexArray(crosshairVAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, crosshairVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(crosshairVertices), &crosshairVertices, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
// Create terrain texture
|
||||
unsigned int texture;
|
||||
glGenTextures(1, &texture);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
@ -117,12 +285,38 @@ int main()
|
||||
|
||||
stbi_image_free(data);
|
||||
|
||||
// Create crosshair texture
|
||||
unsigned int crosshairTexture;
|
||||
glGenTextures(1, &crosshairTexture);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, crosshairTexture);
|
||||
|
||||
// Set texture parameters
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
// Load Crosshair Texture
|
||||
unsigned char* data2 = stbi_load("assets/sprites/crosshair.png", &width, &height, &nrChannels, 0);
|
||||
if (data2)
|
||||
{
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data2);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Failed to load texture\n";
|
||||
}
|
||||
|
||||
stbi_image_free(data2);
|
||||
|
||||
// Create camera
|
||||
camera = Camera(glm::vec3(0.0f, 25.0f, 0.0f));
|
||||
|
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
|
||||
Planet::planet = new Planet();
|
||||
Planet::planet = new Planet(&shader, &waterShader, &billboardShader);
|
||||
|
||||
glm::mat4 ortho = glm::ortho(0.0f, (float)windowX, (float)windowY, 0.0f, 0.0f, 10.0f);
|
||||
|
||||
// Initialize ImGui
|
||||
IMGUI_CHECKVERSION();
|
||||
@ -149,7 +343,7 @@ int main()
|
||||
highestFps = fps;
|
||||
fpsCount++;
|
||||
std::chrono::steady_clock::time_point currentTimePoint = std::chrono::steady_clock::now();
|
||||
if (std::chrono::duration_cast<std::chrono::milliseconds>(currentTimePoint - fpsStartTime).count() > 1000)
|
||||
if (std::chrono::duration_cast<std::chrono::seconds>(currentTimePoint - fpsStartTime).count() >= 1)
|
||||
{
|
||||
avgFps = fpsCount;
|
||||
lowestFps = -1;
|
||||
@ -158,11 +352,21 @@ int main()
|
||||
fpsStartTime = currentTimePoint;
|
||||
}
|
||||
|
||||
waterShader.use();
|
||||
waterShader.setFloat("time", currentFrame);
|
||||
outlineShader.use();
|
||||
outlineShader.setFloat("time", currentFrame);
|
||||
|
||||
// Input
|
||||
processInput(window);
|
||||
|
||||
// Rendering
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
// New ImGui frame
|
||||
ImGui_ImplOpenGL3_NewFrame();
|
||||
@ -173,25 +377,151 @@ int main()
|
||||
glm::mat4 view = camera.GetViewMatrix();
|
||||
|
||||
glm::mat4 projection;
|
||||
projection = glm::perspective(glm::radians(camera.Zoom), windowX / windowY, 0.1f, 100.0f);
|
||||
projection = glm::perspective(glm::radians(camera.Zoom), windowX / windowY, 0.1f, 1000.0f);
|
||||
|
||||
shader.use();
|
||||
unsigned int viewLoc = glGetUniformLocation(shader.ID, "view");
|
||||
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
|
||||
unsigned int projectionLoc = glGetUniformLocation(shader.ID, "projection");
|
||||
glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection));
|
||||
|
||||
unsigned int modelLoc = glGetUniformLocation(shader.ID, "model");
|
||||
waterShader.use();
|
||||
viewLoc = glGetUniformLocation(waterShader.ID, "view");
|
||||
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
|
||||
projectionLoc = glGetUniformLocation(waterShader.ID, "projection");
|
||||
glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection));
|
||||
|
||||
Planet::planet->Update(camera.Position.x, camera.Position.y, camera.Position.z, modelLoc);
|
||||
billboardShader.use();
|
||||
viewLoc = glGetUniformLocation(billboardShader.ID, "view");
|
||||
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
|
||||
projectionLoc = glGetUniformLocation(billboardShader.ID, "projection");
|
||||
glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection));
|
||||
|
||||
// Draw ImGui UI
|
||||
ImGui::Begin("Test");
|
||||
ImGui::Text("FPS: %f (Avg: %f, Min: %f, Max: %f)", fps, avgFps, lowestFps, highestFps);
|
||||
ImGui::Text("MS: %f", deltaTime * 100.0f);
|
||||
ImGui::Text("Chunks: %d (%d rendered)", Planet::planet->numChunks, Planet::planet->numChunksRendered);
|
||||
ImGui::End();
|
||||
outlineShader.use();
|
||||
viewLoc = glGetUniformLocation(outlineShader.ID, "view");
|
||||
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
|
||||
projectionLoc = glGetUniformLocation(outlineShader.ID, "projection");
|
||||
glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection));
|
||||
|
||||
ImGui::Render();
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||
Planet::planet->Update(camera.Position);
|
||||
|
||||
// -- Render block outline -- //
|
||||
if (uiEnabled)
|
||||
{
|
||||
// Get block position
|
||||
auto result = Physics::Raycast(camera.Position, camera.Front, 5);
|
||||
if (result.hit)
|
||||
{
|
||||
outlineShader.use();
|
||||
|
||||
// Set outline view to position
|
||||
unsigned int modelLoc = glGetUniformLocation(outlineShader.ID, "model");
|
||||
glUniform3f(modelLoc, result.blockX, result.blockY, result.blockZ);
|
||||
|
||||
// Render
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
//glEnable(GL_COLOR_LOGIC_OP);
|
||||
glLogicOp(GL_INVERT);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glBindVertexArray(outlineVAO);
|
||||
glLineWidth(2.0);
|
||||
glDrawArrays(GL_LINES, 0, 24);
|
||||
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
glEnable(GL_CULL_FACE);
|
||||
//glDisable(GL_COLOR_LOGIC_OP);
|
||||
}
|
||||
}
|
||||
|
||||
framebufferShader.use();
|
||||
|
||||
// -- Post Processing Stuff -- //
|
||||
|
||||
// Check if player is underwater
|
||||
int blockX = camera.Position.x < 0 ? camera.Position.x - 1 : camera.Position.x;
|
||||
int blockY = camera.Position.y < 0 ? camera.Position.y - 1 : camera.Position.y;
|
||||
int blockZ = camera.Position.z < 0 ? camera.Position.z - 1 : camera.Position.z;
|
||||
|
||||
int chunkX = blockX < 0 ? floorf(blockX / (float)CHUNK_SIZE) : blockX / (int)CHUNK_SIZE;
|
||||
int chunkY = blockY < 0 ? floorf(blockY / (float)CHUNK_SIZE) : blockY / (int)CHUNK_SIZE;
|
||||
int chunkZ = blockZ < 0 ? floorf(blockZ / (float)CHUNK_SIZE) : blockZ / (int)CHUNK_SIZE;
|
||||
|
||||
int localBlockX = blockX - (chunkX * CHUNK_SIZE);
|
||||
int localBlockY = blockY - (chunkY * CHUNK_SIZE);
|
||||
int localBlockZ = blockZ - (chunkZ * CHUNK_SIZE);
|
||||
|
||||
Chunk* chunk = Planet::planet->GetChunk(ChunkPos(chunkX, chunkY, chunkZ));
|
||||
if (chunk != nullptr)
|
||||
{
|
||||
unsigned int blockType = chunk->GetBlockAtPos(
|
||||
localBlockX,
|
||||
localBlockY,
|
||||
localBlockZ);
|
||||
|
||||
if (Blocks::blocks[blockType].blockType == Block::LIQUID)
|
||||
{
|
||||
framebufferShader.setBool("underwater", true);
|
||||
}
|
||||
else
|
||||
{
|
||||
framebufferShader.setBool("underwater", false);
|
||||
}
|
||||
}
|
||||
|
||||
// Post Processing
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glBindVertexArray(rectVAO);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, framebufferTexture);
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, depthTexture);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
|
||||
if (uiEnabled)
|
||||
{
|
||||
// -- Render Crosshair -- //
|
||||
|
||||
// Render
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, crosshairTexture);
|
||||
|
||||
crosshairShader.use();
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glEnable(GL_BLEND);
|
||||
glEnable(GL_COLOR_LOGIC_OP);
|
||||
|
||||
unsigned int crosshairProjLoc = glGetUniformLocation(crosshairShader.ID, "projection");
|
||||
glUniformMatrix4fv(crosshairProjLoc, 1, GL_FALSE, glm::value_ptr(ortho));
|
||||
glBindVertexArray(crosshairVAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_COLOR_LOGIC_OP);
|
||||
|
||||
// Draw ImGui UI
|
||||
ImGui::Begin("Test");
|
||||
ImGui::Text("FPS: %d (Avg: %d, Min: %d, Max: %d)", (int)fps, (int)avgFps, (int)lowestFps, (int)highestFps);
|
||||
ImGui::Text("MS: %f", deltaTime * 100.0f);
|
||||
if (ImGui::Checkbox("VSYNC", &vsync))
|
||||
glfwSwapInterval(vsync ? 1 : 0);
|
||||
ImGui::Text("Chunks: %d (%d rendered)", Planet::planet->numChunks, Planet::planet->numChunksRendered);
|
||||
ImGui::Text("Position: x: %f, y: %f, z: %f", camera.Position.x, camera.Position.y, camera.Position.z);
|
||||
ImGui::Text("Direction: x: %f, y: %f, z: %f", camera.Front.x, camera.Front.y, camera.Front.z);
|
||||
ImGui::Text("Selected Block: %s", Blocks::blocks[selectedBlock].blockName.c_str());
|
||||
if (ImGui::SliderInt("Render Distance", &Planet::planet->renderDistance, 0, 30))
|
||||
Planet::planet->ClearChunkQueue();
|
||||
if (ImGui::SliderInt("Render Height", &Planet::planet->renderHeight, 0, 10))
|
||||
Planet::planet->ClearChunkQueue();
|
||||
ImGui::Checkbox("Use absolute Y axis for camera vertical movement", &camera.absoluteVerticalMovement);
|
||||
ImGui::End();
|
||||
|
||||
ImGui::Render();
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||
}
|
||||
|
||||
// Check and call events and swap buffers
|
||||
glfwSwapBuffers(window);
|
||||
@ -200,6 +530,8 @@ int main()
|
||||
//std::cout << camera.Position.x << ", " << camera.Position.y << ", " << camera.Position.z << '\n';
|
||||
}
|
||||
|
||||
delete Planet::planet;
|
||||
|
||||
ImGui_ImplOpenGL3_Shutdown();
|
||||
ImGui_ImplGlfw_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
@ -212,10 +544,18 @@ void framebufferSizeCallback(GLFWwindow* window, int width, int height)
|
||||
windowX = width;
|
||||
windowY = height;
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
// resize framebuffer texture
|
||||
glBindTexture(GL_TEXTURE_2D, framebufferTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, windowX, windowY, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
||||
// resize framebuffer depth texture
|
||||
glBindTexture(GL_TEXTURE_2D, depthTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, windowX, windowY, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
|
||||
}
|
||||
|
||||
void processInput(GLFWwindow* window)
|
||||
{
|
||||
// Pause
|
||||
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
|
||||
{
|
||||
if (escapeDown)
|
||||
@ -230,6 +570,18 @@ void processInput(GLFWwindow* window)
|
||||
else
|
||||
escapeDown = false;
|
||||
|
||||
// UI Toggle
|
||||
if (glfwGetKey(window, GLFW_KEY_F1) == GLFW_PRESS)
|
||||
{
|
||||
if (f1Down)
|
||||
return;
|
||||
|
||||
f1Down = true;
|
||||
uiEnabled = !uiEnabled;
|
||||
}
|
||||
else
|
||||
f1Down = false;
|
||||
|
||||
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
|
||||
{
|
||||
if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS)
|
||||
@ -249,6 +601,61 @@ void processInput(GLFWwindow* window)
|
||||
camera.ProcessKeyboard(DOWN, deltaTime);
|
||||
}
|
||||
|
||||
void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
|
||||
{
|
||||
if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS)
|
||||
{
|
||||
auto result = Physics::Raycast(camera.Position, camera.Front, 5);
|
||||
if (!result.hit)
|
||||
return;
|
||||
|
||||
result.chunk->UpdateBlock(result.localBlockX, result.localBlockY, result.localBlockZ, 0);
|
||||
}
|
||||
else if (button == GLFW_MOUSE_BUTTON_MIDDLE && action == GLFW_PRESS)
|
||||
{
|
||||
auto result = Physics::Raycast(camera.Position, camera.Front, 5);
|
||||
if (!result.hit)
|
||||
return;
|
||||
|
||||
selectedBlock = result.chunk->GetBlockAtPos(result.localBlockX, result.localBlockY, result.localBlockZ);
|
||||
}
|
||||
else if (button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_PRESS)
|
||||
{
|
||||
auto result = Physics::Raycast(camera.Position, camera.Front, 5);
|
||||
if (!result.hit)
|
||||
return;
|
||||
|
||||
float distX = result.hitPos.x - (result.blockX + .5f);
|
||||
float distY = result.hitPos.y - (result.blockY + .5f);
|
||||
float distZ = result.hitPos.z - (result.blockZ + .5f);
|
||||
|
||||
int blockX = result.blockX;
|
||||
int blockY = result.blockY;
|
||||
int blockZ = result.blockZ;
|
||||
|
||||
// Choose face to place on
|
||||
if (abs(distX) > abs(distY) && abs(distX) > abs(distZ))
|
||||
blockX += (distX > 0 ? 1 : -1);
|
||||
else if (abs(distY) > abs(distX) && abs(distY) > abs(distZ))
|
||||
blockY += (distY > 0 ? 1 : -1);
|
||||
else
|
||||
blockZ += (distZ > 0 ? 1 : -1);
|
||||
|
||||
int chunkX = blockX < 0 ? floorf(blockX / (float)CHUNK_SIZE) : blockX / (int)CHUNK_SIZE;
|
||||
int chunkY = blockY < 0 ? floorf(blockY / (float)CHUNK_SIZE) : blockY / (int)CHUNK_SIZE;
|
||||
int chunkZ = blockZ < 0 ? floorf(blockZ / (float)CHUNK_SIZE) : blockZ / (int)CHUNK_SIZE;
|
||||
|
||||
int localBlockX = blockX - (chunkX * CHUNK_SIZE);
|
||||
int localBlockY = blockY - (chunkY * CHUNK_SIZE);
|
||||
int localBlockZ = blockZ - (chunkZ * CHUNK_SIZE);
|
||||
|
||||
Chunk* chunk = Planet::planet->GetChunk(ChunkPos(chunkX, chunkY, chunkZ));
|
||||
uint16_t blockToReplace = chunk->GetBlockAtPos(localBlockX, localBlockY, localBlockZ);
|
||||
if (chunk != nullptr && (blockToReplace == 0 || Blocks::blocks[blockToReplace].blockType == Block::LIQUID))
|
||||
chunk->UpdateBlock(localBlockX, localBlockY, localBlockZ, selectedBlock);
|
||||
}
|
||||
}
|
||||
|
||||
void mouse_callback(GLFWwindow* window, double xpos, double ypos)
|
||||
{
|
||||
if (menuMode)
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "Block.h"
|
||||
|
||||
Block::Block(char minX, char minY, char maxX, char maxY, bool transparent, bool billboard)
|
||||
: transparent(transparent), billboard(billboard)
|
||||
Block::Block(char minX, char minY, char maxX, char maxY, BLOCK_TYPE blockType, std::string blockName)
|
||||
: blockType(blockType), blockName(blockName)
|
||||
{
|
||||
topMinX = minX;
|
||||
topMinY = minY;
|
||||
@ -21,8 +21,8 @@ Block::Block(char minX, char minY, char maxX, char maxY, bool transparent, bool
|
||||
|
||||
Block::Block(char topMinX, char topMinY, char topMaxX, char topMaxY,
|
||||
char bottomMinX, char bottomMinY, char bottomMaxX, char bottomMaxY,
|
||||
char sideMinX, char sideMinY, char sideMaxX, char sideMaxY, bool transparent, bool billboard)
|
||||
: transparent(transparent), billboard(billboard)
|
||||
char sideMinX, char sideMinY, char sideMaxX, char sideMaxY, BLOCK_TYPE blockType, std::string blockName)
|
||||
: blockType(blockType), blockName(blockName)
|
||||
{
|
||||
this->topMinX = topMinX;
|
||||
this->topMinY = topMinY;
|
||||
|
@ -1,16 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
struct Block
|
||||
{
|
||||
public:
|
||||
enum BLOCK_TYPE
|
||||
{
|
||||
SOLID,
|
||||
TRANSPARENT,
|
||||
LEAVES,
|
||||
BILLBOARD,
|
||||
LIQUID
|
||||
};
|
||||
|
||||
char topMinX, topMinY, topMaxX, topMaxY;
|
||||
char bottomMinX, bottomMinY, bottomMaxX, bottomMaxY;
|
||||
char sideMinX, sideMinY, sideMaxX, sideMaxY;
|
||||
bool transparent;
|
||||
bool billboard;
|
||||
BLOCK_TYPE blockType;
|
||||
std::string blockName;
|
||||
|
||||
Block(char minX, char minY, char maxX, char maxY, bool transparent = false, bool billboard = false);
|
||||
Block(char minX, char minY, char maxX, char maxY, BLOCK_TYPE blockType, std::string blockName);
|
||||
Block(char topMinX, char topMinY, char topMaxX, char topMaxY,
|
||||
char bottomMinX, char bottomMinY, char bottomMaxX, char bottomMaxY,
|
||||
char sideMinX, char sideMinY, char sideMaxX, char sideMaxY, bool transparent = false, bool billboard = false);
|
||||
char sideMinX, char sideMinY, char sideMaxX, char sideMaxY, BLOCK_TYPE blockType, std::string blockName);
|
||||
|
||||
};
|
@ -1,33 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <array>
|
||||
|
||||
#include "Block.h"
|
||||
|
||||
namespace Blocks
|
||||
{
|
||||
const std::vector<Block> blocks{
|
||||
Block(0, 0, 0, 0, true), // Air block
|
||||
Block(0, 0, 1, 1), // Dirt block
|
||||
Block(0, 0, 0, 0, Block::TRANSPARENT, "Air"), // Air block
|
||||
Block(0, 0, 1, 1, Block::SOLID, "Dirt"), // Dirt block
|
||||
|
||||
Block(1, 1, 2, 2, // Grass block
|
||||
Block(1, 1, 2, 2, // Grass block
|
||||
0, 0, 1, 1,
|
||||
1, 0, 2, 1),
|
||||
1, 0, 2, 1, Block::SOLID, "Grass Block"),
|
||||
|
||||
Block(0, 1, 1, 2), // Stone block
|
||||
Block(0, 1, 1, 2, Block::SOLID, "Stone"), // Stone block
|
||||
|
||||
Block(2, 1, 3, 2, // Log
|
||||
Block(2, 1, 3, 2, // Log
|
||||
2, 1, 3, 2,
|
||||
2, 0, 3, 1),
|
||||
2, 0, 3, 1, Block::SOLID, "Log"),
|
||||
|
||||
Block(0, 2, 1, 3, true), // Leaves
|
||||
Block(1, 2, 2, 3, true, true), // Grass
|
||||
Block(3, 0, 4, 1, true, true), // Tall Grass Bottom
|
||||
Block(3, 1, 4, 2, true, true), // Tall Grass Top
|
||||
Block(0, 3, 1, 4, true, true), // Poppy
|
||||
Block(2, 2, 3, 3, true, true), // White Tulip
|
||||
Block(3, 2, 4, 3, true, true), // Pink Tulip
|
||||
Block(1, 3, 2, 4, true, true), // Orange Tulip
|
||||
Block(0, 2, 1, 3, Block::LEAVES, "Leaves"), // Leaves
|
||||
Block(1, 2, 2, 3, Block::BILLBOARD, "Grass"), // Grass
|
||||
Block(3, 0, 4, 1, Block::BILLBOARD, "Tall Grass Bottom"), // Tall Grass Bottom
|
||||
Block(3, 1, 4, 2, Block::BILLBOARD, "Tall Grass Top"), // Tall Grass Top
|
||||
Block(0, 3, 1, 4, Block::BILLBOARD, "Poppy"), // Poppy
|
||||
Block(2, 2, 3, 3, Block::BILLBOARD, "White Tulip"), // White Tulip
|
||||
Block(3, 2, 4, 3, Block::BILLBOARD, "Pink Tulip"), // Pink Tulip
|
||||
Block(1, 3, 2, 4, Block::BILLBOARD, "Orange Tulip"), // Orange Tulip
|
||||
Block(0, 4, 1, 5, Block::LIQUID, "Water"), // Water
|
||||
Block(4, 0, 5, 1, Block::SOLID, "Sand"), // Sand
|
||||
};
|
||||
|
||||
enum BLOCKS
|
||||
@ -45,5 +48,7 @@ namespace Blocks
|
||||
WHITE_TULIP = 10,
|
||||
PINK_TULIP = 11,
|
||||
ORANGE_TULIP = 12,
|
||||
WATER = 13,
|
||||
SAND = 14,
|
||||
};
|
||||
}
|
15
ScuffedMinecraft/src/CMakeLists.txt
Normal file
15
ScuffedMinecraft/src/CMakeLists.txt
Normal file
@ -0,0 +1,15 @@
|
||||
add_executable(scuffed_mc
|
||||
Application.cpp Chunk.cpp Shader.cpp
|
||||
Block.cpp NoiseSettings.cpp SurfaceFeature.cpp
|
||||
ChunkData.cpp ChunkPos.cpp Physics.cpp
|
||||
Camera.cpp Planet.cpp WorldGen.cpp ../vendor/glad.c
|
||||
)
|
||||
|
||||
if(LINUX)
|
||||
add_compile_definitions(LINUX)
|
||||
endif()
|
||||
|
||||
# make sure the program runs in the right place from visual studio
|
||||
set_target_properties(scuffed_mc PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/bin")
|
||||
|
||||
target_link_libraries(scuffed_mc imgui $<IF:$<PLATFORM_ID:Windows>,glfw3,glfw>)
|
@ -38,9 +38,9 @@ void Camera::ProcessKeyboard(Camera_Movement direction, float deltaTime)
|
||||
if (direction == RIGHT)
|
||||
Position += Right * velocity;
|
||||
if (direction == UP)
|
||||
Position += Up * velocity;
|
||||
Position += (absoluteVerticalMovement ? glm::vec3(0, 1, 0) : Up) * velocity;
|
||||
if (direction == DOWN)
|
||||
Position -= Up * velocity;
|
||||
Position -= (absoluteVerticalMovement ? glm::vec3(0, 1, 0) : Up) * velocity;
|
||||
if (direction == FORWARD_NO_Y)
|
||||
{
|
||||
glm::vec3 moveDir = Front;
|
||||
|
@ -36,6 +36,7 @@ public:
|
||||
float MovementSpeed;
|
||||
float MouseSensitivity;
|
||||
float Zoom;
|
||||
bool absoluteVerticalMovement = true;
|
||||
|
||||
Camera(glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f), float yaw = YAW, float pitch = PITCH);
|
||||
|
||||
|
@ -2,23 +2,21 @@
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <iostream>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <iostream>
|
||||
|
||||
#include "Planet.h"
|
||||
#include "Blocks.h"
|
||||
#include "WorldGen.h"
|
||||
|
||||
Chunk::Chunk(unsigned int chunkSize, glm::vec3 chunkPos)
|
||||
Chunk::Chunk(ChunkPos chunkPos, Shader* shader, Shader* waterShader)
|
||||
: chunkPos(chunkPos)
|
||||
{
|
||||
this->chunkSize = chunkSize;
|
||||
this->chunkPos = chunkPos;
|
||||
worldPos = glm::vec3(chunkPos.x * chunkSize, chunkPos.y * chunkSize, chunkPos.z * chunkSize);
|
||||
worldPos = glm::vec3(chunkPos.x * (float)CHUNK_SIZE, chunkPos.y * (float)CHUNK_SIZE, chunkPos.z * (float)CHUNK_SIZE);
|
||||
|
||||
ready = false;
|
||||
generated = false;
|
||||
chunkThread = std::thread(&Chunk::GenerateChunk, this);
|
||||
}
|
||||
|
||||
Chunk::~Chunk()
|
||||
@ -26,93 +24,86 @@ Chunk::~Chunk()
|
||||
if (chunkThread.joinable())
|
||||
chunkThread.join();
|
||||
|
||||
glDeleteBuffers(1, &vbo);
|
||||
glDeleteBuffers(1, &ebo);
|
||||
glDeleteVertexArrays(1, &vertexArrayObject);
|
||||
glDeleteBuffers(1, &mainVBO);
|
||||
glDeleteBuffers(1, &mainEBO);
|
||||
glDeleteVertexArrays(1, &mainVAO);
|
||||
|
||||
glDeleteBuffers(1, &waterVBO);
|
||||
glDeleteBuffers(1, &waterEBO);
|
||||
glDeleteVertexArrays(1, &waterVAO);
|
||||
|
||||
glDeleteBuffers(1, &billboardVBO);
|
||||
glDeleteBuffers(1, &billboardEBO);
|
||||
glDeleteVertexArrays(1, &billboardVAO);
|
||||
}
|
||||
|
||||
void Chunk::GenerateChunk()
|
||||
void Chunk::GenerateChunkMesh()
|
||||
{
|
||||
//std::cout << "Started thread: " << std::this_thread::get_id() << '\n';
|
||||
|
||||
WorldGen::GenerateChunkData(chunkPos.x, chunkPos.y, chunkPos.z, chunkSize, &chunkData);
|
||||
std::vector<unsigned int> northData, southData, eastData, westData, upData, downData;
|
||||
|
||||
WorldGen::GenerateChunkData(chunkPos.x, chunkPos.y, chunkPos.z - 1, chunkSize, &northData);
|
||||
WorldGen::GenerateChunkData(chunkPos.x, chunkPos.y, chunkPos.z + 1, chunkSize, &southData);
|
||||
WorldGen::GenerateChunkData(chunkPos.x + 1, chunkPos.y, chunkPos.z, chunkSize, &eastData);
|
||||
WorldGen::GenerateChunkData(chunkPos.x - 1, chunkPos.y, chunkPos.z, chunkSize, &westData);
|
||||
WorldGen::GenerateChunkData(chunkPos.x, chunkPos.y + 1, chunkPos.z, chunkSize, &upData);
|
||||
WorldGen::GenerateChunkData(chunkPos.x, chunkPos.y - 1, chunkPos.z, chunkSize, &downData);
|
||||
|
||||
//std::cout << "Got chunk data in thread: " << std::this_thread::get_id() << '\n';
|
||||
mainVertices.clear();
|
||||
mainIndices.clear();
|
||||
waterVertices.clear();
|
||||
waterIndices.clear();
|
||||
billboardVertices.clear();
|
||||
billboardIndices.clear();
|
||||
numTrianglesMain = 0;
|
||||
numTrianglesWater = 0;
|
||||
numTrianglesBillboard = 0;
|
||||
|
||||
unsigned int currentVertex = 0;
|
||||
for (char x = 0; x < chunkSize; x++)
|
||||
unsigned int currentLiquidVertex = 0;
|
||||
unsigned int currentBillboardVertex = 0;
|
||||
for (char x = 0; x < CHUNK_SIZE; x++)
|
||||
{
|
||||
for (char z = 0; z < chunkSize; z++)
|
||||
for (char z = 0; z < CHUNK_SIZE; z++)
|
||||
{
|
||||
for (char y = 0; y < chunkSize; y++)
|
||||
for (char y = 0; y < CHUNK_SIZE; y++)
|
||||
{
|
||||
int index = x * chunkSize * chunkSize + z * chunkSize + y;
|
||||
if (chunkData[index] == 0)
|
||||
if (chunkData->GetBlock(x, y, z) == 0)
|
||||
continue;
|
||||
|
||||
const Block* block = &Blocks::blocks[chunkData[index]];
|
||||
const Block* block = &Blocks::blocks[chunkData->GetBlock(x, y, z)];
|
||||
|
||||
if (block->billboard)
|
||||
int topBlock;
|
||||
if (y < CHUNK_SIZE - 1)
|
||||
{
|
||||
vertices.push_back(Vertex(x + .85355f, y + 0, z + .85355f, block->sideMinX, block->sideMinY, 6));
|
||||
vertices.push_back(Vertex(x + .14645f, y + 0, z + .14645f, block->sideMaxX, block->sideMinY, 6));
|
||||
vertices.push_back(Vertex(x + .85355f, y + 1, z + .85355f, block->sideMinX, block->sideMaxY, 6));
|
||||
vertices.push_back(Vertex(x + .14645f, y + 1, z + .14645f, block->sideMaxX, block->sideMaxY, 6));
|
||||
topBlock = chunkData->GetBlock(x, y + 1, z);
|
||||
}
|
||||
else
|
||||
{
|
||||
int blockIndex = x * CHUNK_SIZE * CHUNK_SIZE + z * CHUNK_SIZE + 0;
|
||||
topBlock = upData->GetBlock(x, 0, z);
|
||||
}
|
||||
|
||||
indices.push_back(currentVertex + 0);
|
||||
indices.push_back(currentVertex + 3);
|
||||
indices.push_back(currentVertex + 1);
|
||||
indices.push_back(currentVertex + 0);
|
||||
indices.push_back(currentVertex + 2);
|
||||
indices.push_back(currentVertex + 3);
|
||||
currentVertex += 4;
|
||||
const Block* topBlockType = &Blocks::blocks[topBlock];
|
||||
char waterTopValue = topBlockType->blockType == Block::TRANSPARENT ? 1 : 0;
|
||||
|
||||
vertices.push_back(Vertex(x + .14645f, y + 0, z + .14645f, block->sideMinX, block->sideMinY, 6));
|
||||
vertices.push_back(Vertex(x + .85355f, y + 0, z + .85355f, block->sideMaxX, block->sideMinY, 6));
|
||||
vertices.push_back(Vertex(x + .14645f, y + 1, z + .14645f, block->sideMinX, block->sideMaxY, 6));
|
||||
vertices.push_back(Vertex(x + .85355f, y + 1, z + .85355f, block->sideMaxX, block->sideMaxY, 6));
|
||||
if (block->blockType == Block::BILLBOARD)
|
||||
{
|
||||
billboardVertices.push_back(BillboardVertex(x + .85355f, y + 0, z + .85355f, block->sideMinX, block->sideMinY));
|
||||
billboardVertices.push_back(BillboardVertex(x + .14645f, y + 0, z + .14645f, block->sideMaxX, block->sideMinY));
|
||||
billboardVertices.push_back(BillboardVertex(x + .85355f, y + 1, z + .85355f, block->sideMinX, block->sideMaxY));
|
||||
billboardVertices.push_back(BillboardVertex(x + .14645f, y + 1, z + .14645f, block->sideMaxX, block->sideMaxY));
|
||||
|
||||
indices.push_back(currentVertex + 0);
|
||||
indices.push_back(currentVertex + 3);
|
||||
indices.push_back(currentVertex + 1);
|
||||
indices.push_back(currentVertex + 0);
|
||||
indices.push_back(currentVertex + 2);
|
||||
indices.push_back(currentVertex + 3);
|
||||
currentVertex += 4;
|
||||
billboardIndices.push_back(currentBillboardVertex + 0);
|
||||
billboardIndices.push_back(currentBillboardVertex + 3);
|
||||
billboardIndices.push_back(currentBillboardVertex + 1);
|
||||
billboardIndices.push_back(currentBillboardVertex + 0);
|
||||
billboardIndices.push_back(currentBillboardVertex + 2);
|
||||
billboardIndices.push_back(currentBillboardVertex + 3);
|
||||
currentBillboardVertex += 4;
|
||||
|
||||
vertices.push_back(Vertex(x + .14645f, y + 0, z + .85355f, block->sideMinX, block->sideMinY, 6));
|
||||
vertices.push_back(Vertex(x + .85355f, y + 0, z + .14645f, block->sideMaxX, block->sideMinY, 6));
|
||||
vertices.push_back(Vertex(x + .14645f, y + 1, z + .85355f, block->sideMinX, block->sideMaxY, 6));
|
||||
vertices.push_back(Vertex(x + .85355f, y + 1, z + .14645f, block->sideMaxX, block->sideMaxY, 6));
|
||||
billboardVertices.push_back(BillboardVertex(x + .14645f, y + 0, z + .85355f, block->sideMinX, block->sideMinY));
|
||||
billboardVertices.push_back(BillboardVertex(x + .85355f, y + 0, z + .14645f, block->sideMaxX, block->sideMinY));
|
||||
billboardVertices.push_back(BillboardVertex(x + .14645f, y + 1, z + .85355f, block->sideMinX, block->sideMaxY));
|
||||
billboardVertices.push_back(BillboardVertex(x + .85355f, y + 1, z + .14645f, block->sideMaxX, block->sideMaxY));
|
||||
|
||||
indices.push_back(currentVertex + 0);
|
||||
indices.push_back(currentVertex + 3);
|
||||
indices.push_back(currentVertex + 1);
|
||||
indices.push_back(currentVertex + 0);
|
||||
indices.push_back(currentVertex + 2);
|
||||
indices.push_back(currentVertex + 3);
|
||||
currentVertex += 4;
|
||||
|
||||
vertices.push_back(Vertex(x + .85355f, y + 0, z + .14645f, block->sideMinX, block->sideMinY, 6));
|
||||
vertices.push_back(Vertex(x + .14645f, y + 0, z + .85355f, block->sideMaxX, block->sideMinY, 6));
|
||||
vertices.push_back(Vertex(x + .85355f, y + 1, z + .14645f, block->sideMinX, block->sideMaxY, 6));
|
||||
vertices.push_back(Vertex(x + .14645f, y + 1, z + .85355f, block->sideMaxX, block->sideMaxY, 6));
|
||||
|
||||
indices.push_back(currentVertex + 0);
|
||||
indices.push_back(currentVertex + 3);
|
||||
indices.push_back(currentVertex + 1);
|
||||
indices.push_back(currentVertex + 0);
|
||||
indices.push_back(currentVertex + 2);
|
||||
indices.push_back(currentVertex + 3);
|
||||
currentVertex += 4;
|
||||
billboardIndices.push_back(currentBillboardVertex + 0);
|
||||
billboardIndices.push_back(currentBillboardVertex + 3);
|
||||
billboardIndices.push_back(currentBillboardVertex + 1);
|
||||
billboardIndices.push_back(currentBillboardVertex + 0);
|
||||
billboardIndices.push_back(currentBillboardVertex + 2);
|
||||
billboardIndices.push_back(currentBillboardVertex + 3);
|
||||
currentBillboardVertex += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -121,64 +112,102 @@ void Chunk::GenerateChunk()
|
||||
int northBlock;
|
||||
if (z > 0)
|
||||
{
|
||||
int northIndex = x * chunkSize * chunkSize + (z - 1) * chunkSize + y;
|
||||
northBlock = chunkData[northIndex];
|
||||
northBlock = chunkData->GetBlock(x, y, z - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
int northIndex = x * chunkSize * chunkSize + (chunkSize - 1) * chunkSize + y;
|
||||
northBlock = northData[northIndex];
|
||||
northBlock = northData->GetBlock(x, y, CHUNK_SIZE - 1);
|
||||
}
|
||||
|
||||
const Block* northBlockType = &Blocks::blocks[northBlock];
|
||||
|
||||
if (northBlockType->transparent)
|
||||
if (northBlockType->blockType == Block::LEAVES
|
||||
|| northBlockType->blockType == Block::TRANSPARENT
|
||||
|| northBlockType->blockType == Block::BILLBOARD
|
||||
|| (northBlockType->blockType == Block::LIQUID && block->blockType != Block::LIQUID))
|
||||
{
|
||||
vertices.push_back(Vertex(x + 1, y + 0, z + 0, block->sideMinX, block->sideMinY, 0));
|
||||
vertices.push_back(Vertex(x + 0, y + 0, z + 0, block->sideMaxX, block->sideMinY, 0));
|
||||
vertices.push_back(Vertex(x + 1, y + 1, z + 0, block->sideMinX, block->sideMaxY, 0));
|
||||
vertices.push_back(Vertex(x + 0, y + 1, z + 0, block->sideMaxX, block->sideMaxY, 0));
|
||||
if (block->blockType == Block::LIQUID)
|
||||
{
|
||||
waterVertices.push_back(WaterVertex(x + 1, y + 0, z + 0, block->sideMinX, block->sideMinY, 0, 0));
|
||||
waterVertices.push_back(WaterVertex(x + 0, y + 0, z + 0, block->sideMaxX, block->sideMinY, 0, 0));
|
||||
waterVertices.push_back(WaterVertex(x + 1, y + 1, z + 0, block->sideMinX, block->sideMaxY, 0, waterTopValue));
|
||||
waterVertices.push_back(WaterVertex(x + 0, y + 1, z + 0, block->sideMaxX, block->sideMaxY, 0, waterTopValue));
|
||||
|
||||
indices.push_back(currentVertex + 0);
|
||||
indices.push_back(currentVertex + 3);
|
||||
indices.push_back(currentVertex + 1);
|
||||
indices.push_back(currentVertex + 0);
|
||||
indices.push_back(currentVertex + 2);
|
||||
indices.push_back(currentVertex + 3);
|
||||
currentVertex += 4;
|
||||
waterIndices.push_back(currentLiquidVertex + 0);
|
||||
waterIndices.push_back(currentLiquidVertex + 3);
|
||||
waterIndices.push_back(currentLiquidVertex + 1);
|
||||
waterIndices.push_back(currentLiquidVertex + 0);
|
||||
waterIndices.push_back(currentLiquidVertex + 2);
|
||||
waterIndices.push_back(currentLiquidVertex + 3);
|
||||
currentLiquidVertex += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
mainVertices.push_back(Vertex(x + 1, y + 0, z + 0, block->sideMinX, block->sideMinY, 0));
|
||||
mainVertices.push_back(Vertex(x + 0, y + 0, z + 0, block->sideMaxX, block->sideMinY, 0));
|
||||
mainVertices.push_back(Vertex(x + 1, y + 1, z + 0, block->sideMinX, block->sideMaxY, 0));
|
||||
mainVertices.push_back(Vertex(x + 0, y + 1, z + 0, block->sideMaxX, block->sideMaxY, 0));
|
||||
|
||||
mainIndices.push_back(currentVertex + 0);
|
||||
mainIndices.push_back(currentVertex + 3);
|
||||
mainIndices.push_back(currentVertex + 1);
|
||||
mainIndices.push_back(currentVertex + 0);
|
||||
mainIndices.push_back(currentVertex + 2);
|
||||
mainIndices.push_back(currentVertex + 3);
|
||||
currentVertex += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// South
|
||||
{
|
||||
int southBlock;
|
||||
if (z < chunkSize - 1)
|
||||
if (z < CHUNK_SIZE - 1)
|
||||
{
|
||||
int southIndex = x * chunkSize * chunkSize + (z + 1) * chunkSize + y;
|
||||
southBlock = chunkData[southIndex];
|
||||
southBlock = chunkData->GetBlock(x, y, z + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
int southIndex = x * chunkSize * chunkSize + 0 * chunkSize + y;
|
||||
southBlock = southData[southIndex];
|
||||
southBlock = southData->GetBlock(x, y, 0);
|
||||
}
|
||||
|
||||
const Block* southBlockType = &Blocks::blocks[southBlock];
|
||||
|
||||
if (southBlockType->transparent)
|
||||
if (southBlockType->blockType == Block::LEAVES
|
||||
|| southBlockType->blockType == Block::TRANSPARENT
|
||||
|| southBlockType->blockType == Block::BILLBOARD
|
||||
|| (southBlockType->blockType == Block::LIQUID && block->blockType != Block::LIQUID))
|
||||
{
|
||||
vertices.push_back(Vertex(x + 0, y + 0, z + 1, block->sideMinX, block->sideMinY, 1));
|
||||
vertices.push_back(Vertex(x + 1, y + 0, z + 1, block->sideMaxX, block->sideMinY, 1));
|
||||
vertices.push_back(Vertex(x + 0, y + 1, z + 1, block->sideMinX, block->sideMaxY, 1));
|
||||
vertices.push_back(Vertex(x + 1, y + 1, z + 1, block->sideMaxX, block->sideMaxY, 1));
|
||||
if (block->blockType == Block::LIQUID)
|
||||
{
|
||||
waterVertices.push_back(WaterVertex(x + 0, y + 0, z + 1, block->sideMinX, block->sideMinY, 1, 0));
|
||||
waterVertices.push_back(WaterVertex(x + 1, y + 0, z + 1, block->sideMaxX, block->sideMinY, 1, 0));
|
||||
waterVertices.push_back(WaterVertex(x + 0, y + 1, z + 1, block->sideMinX, block->sideMaxY, 1, waterTopValue));
|
||||
waterVertices.push_back(WaterVertex(x + 1, y + 1, z + 1, block->sideMaxX, block->sideMaxY, 1, waterTopValue));
|
||||
|
||||
indices.push_back(currentVertex + 0);
|
||||
indices.push_back(currentVertex + 3);
|
||||
indices.push_back(currentVertex + 1);
|
||||
indices.push_back(currentVertex + 0);
|
||||
indices.push_back(currentVertex + 2);
|
||||
indices.push_back(currentVertex + 3);
|
||||
currentVertex += 4;
|
||||
waterIndices.push_back(currentLiquidVertex + 0);
|
||||
waterIndices.push_back(currentLiquidVertex + 3);
|
||||
waterIndices.push_back(currentLiquidVertex + 1);
|
||||
waterIndices.push_back(currentLiquidVertex + 0);
|
||||
waterIndices.push_back(currentLiquidVertex + 2);
|
||||
waterIndices.push_back(currentLiquidVertex + 3);
|
||||
currentLiquidVertex += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
mainVertices.push_back(Vertex(x + 0, y + 0, z + 1, block->sideMinX, block->sideMinY, 1));
|
||||
mainVertices.push_back(Vertex(x + 1, y + 0, z + 1, block->sideMaxX, block->sideMinY, 1));
|
||||
mainVertices.push_back(Vertex(x + 0, y + 1, z + 1, block->sideMinX, block->sideMaxY, 1));
|
||||
mainVertices.push_back(Vertex(x + 1, y + 1, z + 1, block->sideMaxX, block->sideMaxY, 1));
|
||||
|
||||
mainIndices.push_back(currentVertex + 0);
|
||||
mainIndices.push_back(currentVertex + 3);
|
||||
mainIndices.push_back(currentVertex + 1);
|
||||
mainIndices.push_back(currentVertex + 0);
|
||||
mainIndices.push_back(currentVertex + 2);
|
||||
mainIndices.push_back(currentVertex + 3);
|
||||
currentVertex += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,64 +216,102 @@ void Chunk::GenerateChunk()
|
||||
int westBlock;
|
||||
if (x > 0)
|
||||
{
|
||||
int blockIndex = (x - 1) * chunkSize * chunkSize + z * chunkSize + y;
|
||||
westBlock = chunkData[blockIndex];
|
||||
westBlock = chunkData->GetBlock(x - 1, y, z);
|
||||
}
|
||||
else
|
||||
{
|
||||
int blockIndex = (chunkSize - 1) * chunkSize * chunkSize + z * chunkSize + y;
|
||||
westBlock = westData[blockIndex];
|
||||
westBlock = westData->GetBlock(CHUNK_SIZE - 1, y, z);
|
||||
}
|
||||
|
||||
const Block* westBlockType = &Blocks::blocks[westBlock];
|
||||
|
||||
if (westBlockType->transparent)
|
||||
if (westBlockType->blockType == Block::LEAVES
|
||||
|| westBlockType->blockType == Block::TRANSPARENT
|
||||
|| westBlockType->blockType == Block::BILLBOARD
|
||||
|| (westBlockType->blockType == Block::LIQUID && block->blockType != Block::LIQUID))
|
||||
{
|
||||
vertices.push_back(Vertex(x + 0, y + 0, z + 0, block->sideMinX, block->sideMinY, 2));
|
||||
vertices.push_back(Vertex(x + 0, y + 0, z + 1, block->sideMaxX, block->sideMinY, 2));
|
||||
vertices.push_back(Vertex(x + 0, y + 1, z + 0, block->sideMinX, block->sideMaxY, 2));
|
||||
vertices.push_back(Vertex(x + 0, y + 1, z + 1, block->sideMaxX, block->sideMaxY, 2));
|
||||
if (block->blockType == Block::LIQUID)
|
||||
{
|
||||
waterVertices.push_back(WaterVertex(x + 0, y + 0, z + 0, block->sideMinX, block->sideMinY, 2, 0));
|
||||
waterVertices.push_back(WaterVertex(x + 0, y + 0, z + 1, block->sideMaxX, block->sideMinY, 2, 0));
|
||||
waterVertices.push_back(WaterVertex(x + 0, y + 1, z + 0, block->sideMinX, block->sideMaxY, 2, waterTopValue));
|
||||
waterVertices.push_back(WaterVertex(x + 0, y + 1, z + 1, block->sideMaxX, block->sideMaxY, 2, waterTopValue));
|
||||
|
||||
indices.push_back(currentVertex + 0);
|
||||
indices.push_back(currentVertex + 3);
|
||||
indices.push_back(currentVertex + 1);
|
||||
indices.push_back(currentVertex + 0);
|
||||
indices.push_back(currentVertex + 2);
|
||||
indices.push_back(currentVertex + 3);
|
||||
currentVertex += 4;
|
||||
waterIndices.push_back(currentLiquidVertex + 0);
|
||||
waterIndices.push_back(currentLiquidVertex + 3);
|
||||
waterIndices.push_back(currentLiquidVertex + 1);
|
||||
waterIndices.push_back(currentLiquidVertex + 0);
|
||||
waterIndices.push_back(currentLiquidVertex + 2);
|
||||
waterIndices.push_back(currentLiquidVertex + 3);
|
||||
currentLiquidVertex += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
mainVertices.push_back(Vertex(x + 0, y + 0, z + 0, block->sideMinX, block->sideMinY, 2));
|
||||
mainVertices.push_back(Vertex(x + 0, y + 0, z + 1, block->sideMaxX, block->sideMinY, 2));
|
||||
mainVertices.push_back(Vertex(x + 0, y + 1, z + 0, block->sideMinX, block->sideMaxY, 2));
|
||||
mainVertices.push_back(Vertex(x + 0, y + 1, z + 1, block->sideMaxX, block->sideMaxY, 2));
|
||||
|
||||
mainIndices.push_back(currentVertex + 0);
|
||||
mainIndices.push_back(currentVertex + 3);
|
||||
mainIndices.push_back(currentVertex + 1);
|
||||
mainIndices.push_back(currentVertex + 0);
|
||||
mainIndices.push_back(currentVertex + 2);
|
||||
mainIndices.push_back(currentVertex + 3);
|
||||
currentVertex += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// East
|
||||
{
|
||||
int eastBlock;
|
||||
if (x < chunkSize - 1)
|
||||
if (x < CHUNK_SIZE - 1)
|
||||
{
|
||||
int blockIndex = (x + 1) * chunkSize * chunkSize + z * chunkSize + y;
|
||||
eastBlock = chunkData[blockIndex];
|
||||
eastBlock = chunkData->GetBlock(x + 1, y, z);
|
||||
}
|
||||
else
|
||||
{
|
||||
int blockIndex = 0 * chunkSize * chunkSize + z * chunkSize + y;
|
||||
eastBlock = eastData[blockIndex];
|
||||
eastBlock = eastData->GetBlock(0, y, z);
|
||||
}
|
||||
|
||||
const Block* eastBlockType = &Blocks::blocks[eastBlock];
|
||||
|
||||
if (eastBlockType->transparent)
|
||||
if (eastBlockType->blockType == Block::LEAVES
|
||||
|| eastBlockType->blockType == Block::TRANSPARENT
|
||||
|| eastBlockType->blockType == Block::BILLBOARD
|
||||
|| (eastBlockType->blockType == Block::LIQUID && block->blockType != Block::LIQUID))
|
||||
{
|
||||
vertices.push_back(Vertex(x + 1, y + 0, z + 1, block->sideMinX, block->sideMinY, 3));
|
||||
vertices.push_back(Vertex(x + 1, y + 0, z + 0, block->sideMaxX, block->sideMinY, 3));
|
||||
vertices.push_back(Vertex(x + 1, y + 1, z + 1, block->sideMinX, block->sideMaxY, 3));
|
||||
vertices.push_back(Vertex(x + 1, y + 1, z + 0, block->sideMaxX, block->sideMaxY, 3));
|
||||
if (block->blockType == Block::LIQUID)
|
||||
{
|
||||
waterVertices.push_back(WaterVertex(x + 1, y + 0, z + 1, block->sideMinX, block->sideMinY, 3, 0));
|
||||
waterVertices.push_back(WaterVertex(x + 1, y + 0, z + 0, block->sideMaxX, block->sideMinY, 3, 0));
|
||||
waterVertices.push_back(WaterVertex(x + 1, y + 1, z + 1, block->sideMinX, block->sideMaxY, 3, waterTopValue));
|
||||
waterVertices.push_back(WaterVertex(x + 1, y + 1, z + 0, block->sideMaxX, block->sideMaxY, 3, waterTopValue));
|
||||
|
||||
indices.push_back(currentVertex + 0);
|
||||
indices.push_back(currentVertex + 3);
|
||||
indices.push_back(currentVertex + 1);
|
||||
indices.push_back(currentVertex + 0);
|
||||
indices.push_back(currentVertex + 2);
|
||||
indices.push_back(currentVertex + 3);
|
||||
currentVertex += 4;
|
||||
waterIndices.push_back(currentLiquidVertex + 0);
|
||||
waterIndices.push_back(currentLiquidVertex + 3);
|
||||
waterIndices.push_back(currentLiquidVertex + 1);
|
||||
waterIndices.push_back(currentLiquidVertex + 0);
|
||||
waterIndices.push_back(currentLiquidVertex + 2);
|
||||
waterIndices.push_back(currentLiquidVertex + 3);
|
||||
currentLiquidVertex += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
mainVertices.push_back(Vertex(x + 1, y + 0, z + 1, block->sideMinX, block->sideMinY, 3));
|
||||
mainVertices.push_back(Vertex(x + 1, y + 0, z + 0, block->sideMaxX, block->sideMinY, 3));
|
||||
mainVertices.push_back(Vertex(x + 1, y + 1, z + 1, block->sideMinX, block->sideMaxY, 3));
|
||||
mainVertices.push_back(Vertex(x + 1, y + 1, z + 0, block->sideMaxX, block->sideMaxY, 3));
|
||||
|
||||
mainIndices.push_back(currentVertex + 0);
|
||||
mainIndices.push_back(currentVertex + 3);
|
||||
mainIndices.push_back(currentVertex + 1);
|
||||
mainIndices.push_back(currentVertex + 0);
|
||||
mainIndices.push_back(currentVertex + 2);
|
||||
mainIndices.push_back(currentVertex + 3);
|
||||
currentVertex += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -253,63 +320,103 @@ void Chunk::GenerateChunk()
|
||||
int bottomBlock;
|
||||
if (y > 0)
|
||||
{
|
||||
int blockIndex = x * chunkSize * chunkSize + z * chunkSize + (y - 1);
|
||||
bottomBlock = chunkData[blockIndex];
|
||||
bottomBlock = chunkData->GetBlock(x, y - 1, z);
|
||||
}
|
||||
else
|
||||
{
|
||||
int blockIndex = x * chunkSize * chunkSize + z * chunkSize + (chunkSize - 1);
|
||||
bottomBlock = downData[blockIndex];
|
||||
//int blockIndex = x * chunkSize * chunkSize + z * chunkSize + (chunkSize - 1);
|
||||
bottomBlock = downData->GetBlock(x, CHUNK_SIZE - 1, z);
|
||||
}
|
||||
|
||||
const Block* bottomBlockType = &Blocks::blocks[bottomBlock];
|
||||
|
||||
if (bottomBlockType->transparent)
|
||||
if (bottomBlockType->blockType == Block::LEAVES
|
||||
|| bottomBlockType->blockType == Block::TRANSPARENT
|
||||
|| bottomBlockType->blockType == Block::BILLBOARD
|
||||
|| (bottomBlockType->blockType == Block::LIQUID && block->blockType != Block::LIQUID))
|
||||
{
|
||||
vertices.push_back(Vertex(x + 1, y + 0, z + 1, block->bottomMinX, block->bottomMinY, 4));
|
||||
vertices.push_back(Vertex(x + 0, y + 0, z + 1, block->bottomMaxX, block->bottomMinY, 4));
|
||||
vertices.push_back(Vertex(x + 1, y + 0, z + 0, block->bottomMinX, block->bottomMaxY, 4));
|
||||
vertices.push_back(Vertex(x + 0, y + 0, z + 0, block->bottomMaxX, block->bottomMaxY, 4));
|
||||
if (block->blockType == Block::LIQUID)
|
||||
{
|
||||
waterVertices.push_back(WaterVertex(x + 1, y + 0, z + 1, block->bottomMinX, block->bottomMinY, 4, 0));
|
||||
waterVertices.push_back(WaterVertex(x + 0, y + 0, z + 1, block->bottomMaxX, block->bottomMinY, 4, 0));
|
||||
waterVertices.push_back(WaterVertex(x + 1, y + 0, z + 0, block->bottomMinX, block->bottomMaxY, 4, 0));
|
||||
waterVertices.push_back(WaterVertex(x + 0, y + 0, z + 0, block->bottomMaxX, block->bottomMaxY, 4, 0));
|
||||
|
||||
indices.push_back(currentVertex + 0);
|
||||
indices.push_back(currentVertex + 3);
|
||||
indices.push_back(currentVertex + 1);
|
||||
indices.push_back(currentVertex + 0);
|
||||
indices.push_back(currentVertex + 2);
|
||||
indices.push_back(currentVertex + 3);
|
||||
currentVertex += 4;
|
||||
waterIndices.push_back(currentLiquidVertex + 0);
|
||||
waterIndices.push_back(currentLiquidVertex + 3);
|
||||
waterIndices.push_back(currentLiquidVertex + 1);
|
||||
waterIndices.push_back(currentLiquidVertex + 0);
|
||||
waterIndices.push_back(currentLiquidVertex + 2);
|
||||
waterIndices.push_back(currentLiquidVertex + 3);
|
||||
currentLiquidVertex += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
mainVertices.push_back(Vertex(x + 1, y + 0, z + 1, block->bottomMinX, block->bottomMinY, 4));
|
||||
mainVertices.push_back(Vertex(x + 0, y + 0, z + 1, block->bottomMaxX, block->bottomMinY, 4));
|
||||
mainVertices.push_back(Vertex(x + 1, y + 0, z + 0, block->bottomMinX, block->bottomMaxY, 4));
|
||||
mainVertices.push_back(Vertex(x + 0, y + 0, z + 0, block->bottomMaxX, block->bottomMaxY, 4));
|
||||
|
||||
mainIndices.push_back(currentVertex + 0);
|
||||
mainIndices.push_back(currentVertex + 3);
|
||||
mainIndices.push_back(currentVertex + 1);
|
||||
mainIndices.push_back(currentVertex + 0);
|
||||
mainIndices.push_back(currentVertex + 2);
|
||||
mainIndices.push_back(currentVertex + 3);
|
||||
currentVertex += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Top
|
||||
{
|
||||
int topBlock;
|
||||
if (y < chunkSize - 1)
|
||||
if (block->blockType == Block::LIQUID)
|
||||
{
|
||||
int blockIndex = x * chunkSize * chunkSize + z * chunkSize + (y + 1);
|
||||
topBlock = chunkData[blockIndex];
|
||||
if (topBlockType->blockType != Block::LIQUID)
|
||||
{
|
||||
waterVertices.push_back(WaterVertex(x + 0, y + 1, z + 1, block->topMinX, block->topMinY, 5, 1));
|
||||
waterVertices.push_back(WaterVertex(x + 1, y + 1, z + 1, block->topMaxX, block->topMinY, 5, 1));
|
||||
waterVertices.push_back(WaterVertex(x + 0, y + 1, z + 0, block->topMinX, block->topMaxY, 5, 1));
|
||||
waterVertices.push_back(WaterVertex(x + 1, y + 1, z + 0, block->topMaxX, block->topMaxY, 5, 1));
|
||||
|
||||
waterIndices.push_back(currentLiquidVertex + 0);
|
||||
waterIndices.push_back(currentLiquidVertex + 3);
|
||||
waterIndices.push_back(currentLiquidVertex + 1);
|
||||
waterIndices.push_back(currentLiquidVertex + 0);
|
||||
waterIndices.push_back(currentLiquidVertex + 2);
|
||||
waterIndices.push_back(currentLiquidVertex + 3);
|
||||
currentLiquidVertex += 4;
|
||||
|
||||
waterVertices.push_back(WaterVertex(x + 1, y + 1, z + 1, block->topMinX, block->topMinY, 5, 1));
|
||||
waterVertices.push_back(WaterVertex(x + 0, y + 1, z + 1, block->topMaxX, block->topMinY, 5, 1));
|
||||
waterVertices.push_back(WaterVertex(x + 1, y + 1, z + 0, block->topMinX, block->topMaxY, 5, 1));
|
||||
waterVertices.push_back(WaterVertex(x + 0, y + 1, z + 0, block->topMaxX, block->topMaxY, 5, 1));
|
||||
|
||||
waterIndices.push_back(currentLiquidVertex + 0);
|
||||
waterIndices.push_back(currentLiquidVertex + 3);
|
||||
waterIndices.push_back(currentLiquidVertex + 1);
|
||||
waterIndices.push_back(currentLiquidVertex + 0);
|
||||
waterIndices.push_back(currentLiquidVertex + 2);
|
||||
waterIndices.push_back(currentLiquidVertex + 3);
|
||||
currentLiquidVertex += 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (topBlockType->blockType == Block::LEAVES
|
||||
|| topBlockType->blockType == Block::TRANSPARENT
|
||||
|| topBlockType->blockType == Block::BILLBOARD
|
||||
|| topBlockType->blockType == Block::LIQUID)
|
||||
{
|
||||
int blockIndex = x * chunkSize * chunkSize + z * chunkSize + 0;
|
||||
topBlock = upData[blockIndex];
|
||||
}
|
||||
mainVertices.push_back(Vertex(x + 0, y + 1, z + 1, block->topMinX, block->topMinY, 5));
|
||||
mainVertices.push_back(Vertex(x + 1, y + 1, z + 1, block->topMaxX, block->topMinY, 5));
|
||||
mainVertices.push_back(Vertex(x + 0, y + 1, z + 0, block->topMinX, block->topMaxY, 5));
|
||||
mainVertices.push_back(Vertex(x + 1, y + 1, z + 0, block->topMaxX, block->topMaxY, 5));
|
||||
|
||||
const Block* topBlockType = &Blocks::blocks[topBlock];
|
||||
|
||||
if (topBlockType->transparent)
|
||||
{
|
||||
vertices.push_back(Vertex(x + 0, y + 1, z + 1, block->topMinX, block->topMinY, 5));
|
||||
vertices.push_back(Vertex(x + 1, y + 1, z + 1, block->topMaxX, block->topMinY, 5));
|
||||
vertices.push_back(Vertex(x + 0, y + 1, z + 0, block->topMinX, block->topMaxY, 5));
|
||||
vertices.push_back(Vertex(x + 1, y + 1, z + 0, block->topMaxX, block->topMaxY, 5));
|
||||
|
||||
indices.push_back(currentVertex + 0);
|
||||
indices.push_back(currentVertex + 3);
|
||||
indices.push_back(currentVertex + 1);
|
||||
indices.push_back(currentVertex + 0);
|
||||
indices.push_back(currentVertex + 2);
|
||||
indices.push_back(currentVertex + 3);
|
||||
mainIndices.push_back(currentVertex + 0);
|
||||
mainIndices.push_back(currentVertex + 3);
|
||||
mainIndices.push_back(currentVertex + 1);
|
||||
mainIndices.push_back(currentVertex + 0);
|
||||
mainIndices.push_back(currentVertex + 2);
|
||||
mainIndices.push_back(currentVertex + 3);
|
||||
currentVertex += 4;
|
||||
}
|
||||
}
|
||||
@ -325,31 +432,78 @@ void Chunk::GenerateChunk()
|
||||
//std::cout << "Generated: " << generated << '\n';
|
||||
}
|
||||
|
||||
void Chunk::Render(unsigned int modelLoc)
|
||||
void Chunk::Render(Shader* mainShader, Shader* billboardShader)
|
||||
{
|
||||
if (!ready)
|
||||
{
|
||||
if (generated)
|
||||
{
|
||||
numTriangles = indices.size();
|
||||
// Solid
|
||||
numTrianglesMain = mainIndices.size();
|
||||
|
||||
glGenVertexArrays(1, &vertexArrayObject);
|
||||
glBindVertexArray(vertexArrayObject);
|
||||
glGenVertexArrays(1, &mainVAO);
|
||||
glGenBuffers(1, &mainVBO);
|
||||
glGenBuffers(1, &mainEBO);
|
||||
|
||||
glGenBuffers(1, &vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), vertices.data(), GL_STATIC_DRAW);
|
||||
glBindVertexArray(mainVAO);
|
||||
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, posX));
|
||||
glBindBuffer(GL_ARRAY_BUFFER, mainVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, mainVertices.size() * sizeof(Vertex), mainVertices.data(), GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mainEBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, mainIndices.size() * sizeof(unsigned int), mainIndices.data(), GL_STATIC_DRAW);
|
||||
|
||||
glVertexAttribPointer(0, 3, GL_BYTE, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, posX));
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(1, 2, GL_BYTE, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, texGridX));
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribIPointer(2, 1, GL_BYTE, sizeof(Vertex), (void*)offsetof(Vertex, direction));
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
glGenBuffers(1, &ebo);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW);
|
||||
// Water
|
||||
numTrianglesWater = waterIndices.size();
|
||||
|
||||
glGenVertexArrays(1, &waterVAO);
|
||||
glGenBuffers(1, &waterVBO);
|
||||
glGenBuffers(1, &waterEBO);
|
||||
|
||||
glBindVertexArray(waterVAO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, waterVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, waterVertices.size() * sizeof(WaterVertex), waterVertices.data(), GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, waterEBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, waterIndices.size() * sizeof(unsigned int), waterIndices.data(), GL_STATIC_DRAW);
|
||||
|
||||
glVertexAttribPointer(0, 3, GL_BYTE, GL_FALSE, sizeof(WaterVertex), (void*)offsetof(WaterVertex, posX));
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(1, 2, GL_BYTE, GL_FALSE, sizeof(WaterVertex), (void*)offsetof(WaterVertex, texGridX));
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribIPointer(2, 1, GL_BYTE, sizeof(WaterVertex), (void*)offsetof(WaterVertex, direction));
|
||||
glEnableVertexAttribArray(2);
|
||||
glVertexAttribIPointer(3, 1, GL_BYTE, sizeof(WaterVertex), (void*)offsetof(WaterVertex, top));
|
||||
glEnableVertexAttribArray(3);
|
||||
ready = true;
|
||||
|
||||
// Billboard
|
||||
numTrianglesBillboard = billboardIndices.size();
|
||||
|
||||
glGenVertexArrays(1, &billboardVAO);
|
||||
glGenBuffers(1, &billboardVBO);
|
||||
glGenBuffers(1, &billboardEBO);
|
||||
|
||||
glBindVertexArray(billboardVAO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, billboardVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, billboardVertices.size() * sizeof(BillboardVertex), billboardVertices.data(), GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, billboardEBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, billboardIndices.size() * sizeof(unsigned int), billboardIndices.data(), GL_STATIC_DRAW);
|
||||
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(BillboardVertex), (void*)offsetof(BillboardVertex, posX));
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(1, 2, GL_BYTE, GL_FALSE, sizeof(BillboardVertex), (void*)offsetof(BillboardVertex, texGridX));
|
||||
glEnableVertexAttribArray(1);
|
||||
ready = true;
|
||||
}
|
||||
|
||||
@ -359,11 +513,171 @@ void Chunk::Render(unsigned int modelLoc)
|
||||
//std::cout << "Rendering chunk " << chunkPos.x << ", " << chunkPos.y << ", " << chunkPos.z << '\n'
|
||||
// << "Chunk VAO: " << vertexArrayObject << '\n' << "Triangles: " << numTriangles << '\n';
|
||||
|
||||
glBindVertexArray(vertexArrayObject);
|
||||
// Calculate model matrix
|
||||
glm::mat4 model = glm::mat4(1.0f);
|
||||
model = glm::translate(model, worldPos);
|
||||
|
||||
// Render main mesh
|
||||
mainShader->use();
|
||||
|
||||
modelLoc = glGetUniformLocation(mainShader->ID, "model");
|
||||
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
|
||||
|
||||
glBindVertexArray(mainVAO);
|
||||
glDrawElements(GL_TRIANGLES, numTrianglesMain, GL_UNSIGNED_INT, 0);
|
||||
|
||||
// Render billboard mesh
|
||||
billboardShader->use();
|
||||
|
||||
modelLoc = glGetUniformLocation(billboardShader->ID, "model");
|
||||
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
|
||||
|
||||
glDisable(GL_CULL_FACE);
|
||||
glBindVertexArray(billboardVAO);
|
||||
glDrawElements(GL_TRIANGLES, numTrianglesBillboard, GL_UNSIGNED_INT, 0);
|
||||
glEnable(GL_CULL_FACE);
|
||||
}
|
||||
|
||||
void Chunk::RenderWater(Shader* shader)
|
||||
{
|
||||
if (!ready)
|
||||
return;
|
||||
|
||||
//std::cout << "Rendering chunk " << chunkPos.x << ", " << chunkPos.y << ", " << chunkPos.z << '\n'
|
||||
// << "Chunk VAO: " << vertexArrayObject << '\n' << "Triangles: " << numTriangles << '\n';
|
||||
|
||||
modelLoc = glGetUniformLocation(shader->ID, "model");
|
||||
glBindVertexArray(waterVAO);
|
||||
|
||||
glm::mat4 model = glm::mat4(1.0f);
|
||||
model = glm::translate(model, worldPos);
|
||||
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
|
||||
|
||||
glDrawElements(GL_TRIANGLES, numTriangles, GL_UNSIGNED_INT, 0);
|
||||
glDrawElements(GL_TRIANGLES, numTrianglesWater, GL_UNSIGNED_INT, 0);
|
||||
}
|
||||
|
||||
uint16_t Chunk::GetBlockAtPos(int x, int y, int z)
|
||||
{
|
||||
if (!ready)
|
||||
return 0;
|
||||
|
||||
return chunkData->GetBlock(x, y, z);
|
||||
}
|
||||
|
||||
void Chunk::UpdateBlock(int x, int y, int z, uint16_t newBlock)
|
||||
{
|
||||
chunkData->SetBlock(x, y, z, newBlock);
|
||||
|
||||
GenerateChunkMesh();
|
||||
|
||||
// Main
|
||||
numTrianglesMain = mainIndices.size();
|
||||
|
||||
glBindVertexArray(mainVAO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, mainVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, mainVertices.size() * sizeof(Vertex), mainVertices.data(), GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mainEBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, mainIndices.size() * sizeof(unsigned int), mainIndices.data(), GL_STATIC_DRAW);
|
||||
|
||||
// Water
|
||||
numTrianglesWater = waterIndices.size();
|
||||
|
||||
glBindVertexArray(waterVAO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, waterVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, waterVertices.size() * sizeof(WaterVertex), waterVertices.data(), GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, waterEBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, waterIndices.size() * sizeof(unsigned int), waterIndices.data(), GL_STATIC_DRAW);
|
||||
|
||||
// Billboard
|
||||
numTrianglesBillboard = billboardIndices.size();;
|
||||
|
||||
glBindVertexArray(billboardVAO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, billboardVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, billboardVertices.size() * sizeof(BillboardVertex), billboardVertices.data(), GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, billboardEBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, billboardIndices.size() * sizeof(unsigned int), billboardIndices.data(), GL_STATIC_DRAW);
|
||||
|
||||
|
||||
if (x == 0)
|
||||
{
|
||||
Chunk* westChunk = Planet::planet->GetChunk({ chunkPos.x - 1, chunkPos.y, chunkPos.z });
|
||||
if (westChunk != nullptr)
|
||||
westChunk->UpdateChunk();
|
||||
}
|
||||
else if (x == CHUNK_SIZE - 1)
|
||||
{
|
||||
Chunk* eastChunk = Planet::planet->GetChunk({ chunkPos.x + 1, chunkPos.y, chunkPos.z });
|
||||
if (eastChunk != nullptr)
|
||||
eastChunk->UpdateChunk();
|
||||
}
|
||||
|
||||
if (y == 0)
|
||||
{
|
||||
Chunk* downChunk = Planet::planet->GetChunk({ chunkPos.x, chunkPos.y - 1, chunkPos.z });
|
||||
if (downChunk != nullptr)
|
||||
downChunk->UpdateChunk();
|
||||
}
|
||||
else if (y == CHUNK_SIZE - 1)
|
||||
{
|
||||
Chunk* upChunk = Planet::planet->GetChunk({ chunkPos.x, chunkPos.y + 1, chunkPos.z });
|
||||
if (upChunk != nullptr)
|
||||
upChunk->UpdateChunk();
|
||||
}
|
||||
|
||||
if (z == 0)
|
||||
{
|
||||
Chunk* northChunk = Planet::planet->GetChunk({ chunkPos.x, chunkPos.y, chunkPos.z - 1 });
|
||||
if (northChunk != nullptr)
|
||||
northChunk->UpdateChunk();
|
||||
}
|
||||
else if (z == CHUNK_SIZE - 1)
|
||||
{
|
||||
Chunk* southChunk = Planet::planet->GetChunk({ chunkPos.x, chunkPos.y, chunkPos.z + 1 });
|
||||
if (southChunk != nullptr)
|
||||
southChunk->UpdateChunk();
|
||||
}
|
||||
}
|
||||
|
||||
void Chunk::UpdateChunk()
|
||||
{
|
||||
GenerateChunkMesh();
|
||||
|
||||
// Main
|
||||
numTrianglesMain = mainIndices.size();
|
||||
|
||||
glBindVertexArray(mainVAO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, mainVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, mainVertices.size() * sizeof(Vertex), mainVertices.data(), GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mainEBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, mainIndices.size() * sizeof(unsigned int), mainIndices.data(), GL_STATIC_DRAW);
|
||||
|
||||
// Water
|
||||
numTrianglesWater = waterIndices.size();
|
||||
|
||||
glBindVertexArray(waterVAO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, waterVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, waterVertices.size() * sizeof(WaterVertex), waterVertices.data(), GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, waterEBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, waterIndices.size() * sizeof(unsigned int), waterIndices.data(), GL_STATIC_DRAW);
|
||||
|
||||
// Billboard
|
||||
numTrianglesBillboard = billboardIndices.size();
|
||||
|
||||
glBindVertexArray(billboardVAO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, billboardVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, billboardVertices.size() * sizeof(BillboardVertex), billboardVertices.data(), GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, billboardEBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, billboardIndices.size() * sizeof(unsigned int), billboardIndices.data(), GL_STATIC_DRAW);
|
||||
}
|
@ -4,48 +4,49 @@
|
||||
#include <thread>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
struct Vertex
|
||||
{
|
||||
float posX, posY, posZ;
|
||||
char texGridX, texGridY;
|
||||
char direction;
|
||||
|
||||
Vertex(float _posX, float _posY, float _posZ, char _texGridX, char _texGridY, char _direction)
|
||||
{
|
||||
posX = _posX;
|
||||
posY = _posY;
|
||||
posZ = _posZ;
|
||||
|
||||
texGridX = _texGridX;
|
||||
texGridY = _texGridY;
|
||||
|
||||
direction = _direction;
|
||||
}
|
||||
};
|
||||
#include "Shader.h"
|
||||
#include "Vertex.h"
|
||||
#include "ChunkPos.h"
|
||||
#include "ChunkData.h"
|
||||
|
||||
class Chunk
|
||||
{
|
||||
public:
|
||||
Chunk(unsigned int chunkSize, glm::vec3 chunkPos);
|
||||
Chunk(ChunkPos chunkPos, Shader* shader, Shader* waterShader);
|
||||
~Chunk();
|
||||
|
||||
void GenerateChunk();
|
||||
void Render(unsigned int modelLoc);
|
||||
void GenerateChunkMesh();
|
||||
void Render(Shader* mainShader, Shader* billboardShader);
|
||||
void RenderWater(Shader* shader);
|
||||
uint16_t GetBlockAtPos(int x, int y, int z);
|
||||
void UpdateBlock(int x, int y, int z, uint16_t newBlock);
|
||||
void UpdateChunk();
|
||||
|
||||
public:
|
||||
std::vector<unsigned int> chunkData;
|
||||
glm::vec3 chunkPos;
|
||||
ChunkData* chunkData;
|
||||
ChunkData* northData;
|
||||
ChunkData* southData;
|
||||
ChunkData* upData;
|
||||
ChunkData* downData;
|
||||
ChunkData* eastData;
|
||||
ChunkData* westData;
|
||||
ChunkPos chunkPos;
|
||||
bool ready;
|
||||
bool generated;
|
||||
|
||||
private:
|
||||
unsigned int vertexArrayObject;
|
||||
unsigned int vbo, ebo;
|
||||
unsigned int chunkSize;
|
||||
unsigned int numTriangles;
|
||||
glm::vec3 worldPos;
|
||||
std::thread chunkThread;
|
||||
|
||||
std::vector<Vertex> vertices;
|
||||
std::vector<unsigned int> indices;
|
||||
std::vector<Vertex> mainVertices;
|
||||
std::vector<unsigned int> mainIndices;
|
||||
std::vector<WaterVertex> waterVertices;
|
||||
std::vector<unsigned int> waterIndices;
|
||||
std::vector<BillboardVertex> billboardVertices;
|
||||
std::vector<unsigned int> billboardIndices;
|
||||
|
||||
unsigned int mainVAO, waterVAO, billboardVAO;
|
||||
unsigned int mainVBO, mainEBO, waterVBO, waterEBO, billboardVBO, billboardEBO;
|
||||
unsigned int numTrianglesMain, numTrianglesWater, numTrianglesBillboard;
|
||||
unsigned int modelLoc;
|
||||
};
|
39
ScuffedMinecraft/src/ChunkData.cpp
Normal file
39
ScuffedMinecraft/src/ChunkData.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
#include "ChunkData.h"
|
||||
|
||||
#include "Planet.h"
|
||||
|
||||
ChunkData::ChunkData(uint16_t* data)
|
||||
: data(data)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ChunkData::~ChunkData()
|
||||
{
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
inline int ChunkData::GetIndex(int x, int y, int z) const
|
||||
{
|
||||
return x * CHUNK_SIZE * CHUNK_SIZE + z * CHUNK_SIZE + y;
|
||||
}
|
||||
|
||||
inline int ChunkData::GetIndex(ChunkPos localBlockPos) const
|
||||
{
|
||||
return localBlockPos.x * CHUNK_SIZE * CHUNK_SIZE + localBlockPos.z * CHUNK_SIZE + localBlockPos.y;
|
||||
}
|
||||
|
||||
uint16_t ChunkData::GetBlock(ChunkPos blockPos)
|
||||
{
|
||||
return data[GetIndex(blockPos)];
|
||||
}
|
||||
|
||||
uint16_t ChunkData::GetBlock(int x, int y, int z)
|
||||
{
|
||||
return data[GetIndex(x, y, z)];
|
||||
}
|
||||
|
||||
void ChunkData::SetBlock(int x, int y, int z, uint16_t block)
|
||||
{
|
||||
data[GetIndex(x, y, z)] = block;
|
||||
}
|
20
ScuffedMinecraft/src/ChunkData.h
Normal file
20
ScuffedMinecraft/src/ChunkData.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "ChunkPos.h"
|
||||
|
||||
struct ChunkData
|
||||
{
|
||||
uint16_t* data;
|
||||
|
||||
ChunkData(uint16_t* data);
|
||||
~ChunkData();
|
||||
|
||||
inline int GetIndex(int x, int y, int z) const;
|
||||
inline int GetIndex(ChunkPos localBlockPos) const;
|
||||
|
||||
uint16_t GetBlock(ChunkPos blockPos);
|
||||
uint16_t GetBlock(int x, int y, int z);
|
||||
void SetBlock(int x, int y, int z, uint16_t block);
|
||||
};
|
18
ScuffedMinecraft/src/ChunkPos.cpp
Normal file
18
ScuffedMinecraft/src/ChunkPos.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
#include "ChunkPos.h"
|
||||
|
||||
ChunkPos::ChunkPos()
|
||||
: x(0), y(0), z(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ChunkPos::ChunkPos(int x, int y, int z)
|
||||
: x(x), y(y), z(z)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool ChunkPos::operator==(const ChunkPos& other) const
|
||||
{
|
||||
return other.x == x && other.y == y && other.z == z;
|
||||
}
|
13
ScuffedMinecraft/src/ChunkPos.h
Normal file
13
ScuffedMinecraft/src/ChunkPos.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
struct ChunkPos
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
|
||||
ChunkPos();
|
||||
ChunkPos(int x, int y, int z);
|
||||
|
||||
bool operator==(const ChunkPos& other) const;
|
||||
};
|
15
ScuffedMinecraft/src/ChunkPosHash.h
Normal file
15
ScuffedMinecraft/src/ChunkPosHash.h
Normal file
@ -0,0 +1,15 @@
|
||||
#include "ChunkPos.h"
|
||||
#include <unordered_map>
|
||||
|
||||
struct ChunkPosHash
|
||||
{
|
||||
std::size_t operator()(const ChunkPos& key) const
|
||||
{
|
||||
std::size_t hx = std::hash<int>()(key.x);
|
||||
std::size_t hy = std::hash<int>()(key.y);
|
||||
std::size_t hz = std::hash<int>()(key.z);
|
||||
|
||||
// Combine the hashes using bitwise XOR and shifting
|
||||
return hx ^ (hy << 1) ^ (hz << 2);
|
||||
}
|
||||
};
|
47
ScuffedMinecraft/src/Physics.cpp
Normal file
47
ScuffedMinecraft/src/Physics.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
#include "Physics.h"
|
||||
#include <iostream>
|
||||
#include "Blocks.h"
|
||||
|
||||
Physics::RaycastResult Physics::Raycast(const glm::vec3 startPos, const glm::vec3 direction, const float maxDistance)
|
||||
{
|
||||
float currentDistance = 0;
|
||||
|
||||
while (currentDistance < maxDistance)
|
||||
{
|
||||
currentDistance += Physics::RAY_STEP;
|
||||
if (currentDistance > maxDistance)
|
||||
currentDistance = maxDistance;
|
||||
|
||||
// Get chunk
|
||||
glm::vec3 resultPos = startPos + direction * currentDistance;
|
||||
int chunkX = resultPos.x >= 0 ? resultPos.x / CHUNK_SIZE : resultPos.x / CHUNK_SIZE - 1;
|
||||
int chunkY = resultPos.y >= 0 ? resultPos.y / CHUNK_SIZE : resultPos.y / CHUNK_SIZE - 1;
|
||||
int chunkZ = resultPos.z >= 0 ? resultPos.z / CHUNK_SIZE : resultPos.z / CHUNK_SIZE - 1;
|
||||
Chunk* chunk = Planet::planet->GetChunk(ChunkPos(chunkX, chunkY, chunkZ));
|
||||
if (chunk == nullptr)
|
||||
continue;
|
||||
|
||||
// Get block pos
|
||||
int localBlockX = (int)floor(resultPos.x) % CHUNK_SIZE;
|
||||
int localBlockZ = (int)floor(resultPos.z) % CHUNK_SIZE;
|
||||
int localBlockY = (int)floor(resultPos.y) % CHUNK_SIZE;
|
||||
|
||||
// Get block from chunk
|
||||
unsigned int block = chunk->GetBlockAtPos(localBlockX, localBlockY, localBlockZ);
|
||||
|
||||
// Get result pos
|
||||
int blockX = resultPos.x >= 0 ? (int)resultPos.x : (int)resultPos.x - 1;
|
||||
int blockY = resultPos.y >= 0 ? (int)resultPos.y : (int)resultPos.y - 1;
|
||||
int blockZ = resultPos.z >= 0 ? (int)resultPos.z : (int)resultPos.z - 1;
|
||||
|
||||
// Return true if it hit a block
|
||||
if (block != 0 && Blocks::blocks[block].blockType != Block::LIQUID)
|
||||
return { true, resultPos, chunk,
|
||||
blockX, blockY, blockZ,
|
||||
localBlockX, localBlockY, localBlockZ};
|
||||
}
|
||||
|
||||
return { false, glm::vec3(0), nullptr,
|
||||
0, 0, 0,
|
||||
0, 0, 0};
|
||||
}
|
30
ScuffedMinecraft/src/Physics.h
Normal file
30
ScuffedMinecraft/src/Physics.h
Normal file
@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include "glm/glm.hpp"
|
||||
#include "Planet.h"
|
||||
|
||||
namespace Physics
|
||||
{
|
||||
struct RaycastResult
|
||||
{
|
||||
bool hit;
|
||||
glm::vec3 hitPos;
|
||||
Chunk* chunk;
|
||||
int blockX;
|
||||
int blockY;
|
||||
int blockZ;
|
||||
int localBlockX;
|
||||
int localBlockY;
|
||||
int localBlockZ;
|
||||
|
||||
RaycastResult(bool hit, glm::vec3 hitPos, Chunk* chunk, int blockX, int blockY, int blockZ, int localBlockX, int localBlockY, int localBlockZ)
|
||||
: hit(hit), hitPos(hitPos), chunk(chunk), blockX(blockX), blockY(blockY), blockZ(blockZ), localBlockX(localBlockX), localBlockY(localBlockY), localBlockZ(localBlockZ)
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
RaycastResult Raycast(glm::vec3 startPos, glm::vec3 direction, float maxDistance);
|
||||
|
||||
static constexpr float RAY_STEP = 0.01f;
|
||||
}
|
@ -1,167 +1,461 @@
|
||||
#include "Planet.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <glad/glad.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include "WorldGen.h"
|
||||
|
||||
Planet* Planet::planet = nullptr;
|
||||
|
||||
// Public
|
||||
Planet::Planet()
|
||||
{
|
||||
//static const unsigned int CHUNK_SIZE = 32;
|
||||
|
||||
// Public
|
||||
Planet::Planet(Shader* solidShader, Shader* waterShader, Shader* billboardShader)
|
||||
: solidShader(solidShader), waterShader(waterShader), billboardShader(billboardShader)
|
||||
{
|
||||
chunkThread = std::thread(&Planet::ChunkThreadUpdate, this);
|
||||
}
|
||||
|
||||
Planet::~Planet()
|
||||
{
|
||||
|
||||
shouldEnd = true;
|
||||
chunkThread.join();
|
||||
}
|
||||
|
||||
std::vector<unsigned int> Planet::GetChunkData(int chunkX, int chunkY, int chunkZ)
|
||||
void Planet::Update(glm::vec3 cameraPos)
|
||||
{
|
||||
std::tuple<int, int, int> chunkTuple{ chunkX, chunkY, chunkZ };
|
||||
camChunkX = cameraPos.x < 0 ? floor(cameraPos.x / CHUNK_SIZE) : cameraPos.x / CHUNK_SIZE;
|
||||
camChunkY = cameraPos.y < 0 ? floor(cameraPos.y / CHUNK_SIZE) : cameraPos.y / CHUNK_SIZE;
|
||||
camChunkZ = cameraPos.z < 0 ? floor(cameraPos.z / CHUNK_SIZE) : cameraPos.z / CHUNK_SIZE;
|
||||
|
||||
if (chunks.find(chunkTuple) == chunks.end())
|
||||
{
|
||||
return std::vector<unsigned int>{};
|
||||
//return GenerateChunkData(chunkX, chunkY, chunkZ);
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::vector<unsigned int>{};
|
||||
//return chunks.at(chunkTuple).chunkData;
|
||||
}
|
||||
}
|
||||
|
||||
void Planet::Update(float camX, float camY, float camZ, unsigned int modelLoc)
|
||||
{
|
||||
int camChunkX = camX < 0 ? floor(camX / chunkSize) : camX / chunkSize;
|
||||
int camChunkY = camY < 0 ? floor(camY / chunkSize) : camY / chunkSize;
|
||||
int camChunkZ = camZ < 0 ? floor(camZ / chunkSize) : camZ / chunkSize;
|
||||
|
||||
// Check if camera moved to new chunk
|
||||
if (camChunkX != lastCamX || camChunkY != lastCamY || camChunkZ != lastCamZ)
|
||||
{
|
||||
// Player moved chunks, start new chunk queue
|
||||
lastCamX = camChunkX;
|
||||
lastCamY = camChunkY;
|
||||
lastCamZ = camChunkZ;
|
||||
|
||||
// Current chunk
|
||||
chunkQueue = {};
|
||||
if (chunks.find({ camChunkX, camChunkY, camChunkZ }) == chunks.end())
|
||||
chunkQueue.push({ camChunkX, camChunkY, camChunkZ });
|
||||
|
||||
for (int r = 0; r < renderDistance; r++)
|
||||
{
|
||||
// Add middle chunks
|
||||
for (int y = 0; y <= renderHeight; y++)
|
||||
{
|
||||
chunkQueue.push({ camChunkX, camChunkY + y, camChunkZ + r });
|
||||
chunkQueue.push({ camChunkX + r, camChunkY + y, camChunkZ });
|
||||
chunkQueue.push({ camChunkX, camChunkY + y, camChunkZ - r });
|
||||
chunkQueue.push({ camChunkX - r, camChunkY + y, camChunkZ });
|
||||
|
||||
if (y > 0)
|
||||
{
|
||||
chunkQueue.push({ camChunkX, camChunkY - y, camChunkZ + r });
|
||||
chunkQueue.push({ camChunkX + r, camChunkY - y, camChunkZ });
|
||||
chunkQueue.push({ camChunkX, camChunkY - y, camChunkZ - r });
|
||||
chunkQueue.push({ camChunkX - r, camChunkY - y, camChunkZ });
|
||||
}
|
||||
}
|
||||
|
||||
// Add edges
|
||||
for (int e = 1; e < r; e++)
|
||||
{
|
||||
for (int y = 0; y <= renderHeight; y++)
|
||||
{
|
||||
chunkQueue.push({ camChunkX + e, camChunkY + y, camChunkZ + r });
|
||||
chunkQueue.push({ camChunkX - e, camChunkY + y, camChunkZ + r });
|
||||
|
||||
chunkQueue.push({ camChunkX + r, camChunkY + y, camChunkZ + e });
|
||||
chunkQueue.push({ camChunkX + r, camChunkY + y, camChunkZ - e });
|
||||
|
||||
chunkQueue.push({ camChunkX + e, camChunkY + y, camChunkZ - r });
|
||||
chunkQueue.push({ camChunkX - e, camChunkY + y, camChunkZ - r });
|
||||
|
||||
chunkQueue.push({ camChunkX - r, camChunkY + y, camChunkZ + e });
|
||||
chunkQueue.push({ camChunkX - r, camChunkY + y, camChunkZ - e });
|
||||
|
||||
if (y > 0)
|
||||
{
|
||||
chunkQueue.push({ camChunkX + e, camChunkY - y, camChunkZ + r });
|
||||
chunkQueue.push({ camChunkX - e, camChunkY - y, camChunkZ + r });
|
||||
|
||||
chunkQueue.push({ camChunkX + r, camChunkY - y, camChunkZ + e });
|
||||
chunkQueue.push({ camChunkX + r, camChunkY - y, camChunkZ - e });
|
||||
|
||||
chunkQueue.push({ camChunkX + e, camChunkY - y, camChunkZ - r });
|
||||
chunkQueue.push({ camChunkX - e, camChunkY - y, camChunkZ - r });
|
||||
|
||||
chunkQueue.push({ camChunkX - r, camChunkY - y, camChunkZ + e });
|
||||
chunkQueue.push({ camChunkX - r, camChunkY - y, camChunkZ - e });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add corners
|
||||
for (int y = 0; y <= renderHeight; y++)
|
||||
{
|
||||
chunkQueue.push({ camChunkX + r, camChunkY + y, camChunkZ + r });
|
||||
chunkQueue.push({ camChunkX + r, camChunkY + y, camChunkZ - r });
|
||||
chunkQueue.push({ camChunkX - r, camChunkY + y, camChunkZ + r });
|
||||
chunkQueue.push({ camChunkX - r, camChunkY + y, camChunkZ - r });
|
||||
|
||||
if (y > 0)
|
||||
{
|
||||
chunkQueue.push({ camChunkX + r, camChunkY - y, camChunkZ + r });
|
||||
chunkQueue.push({ camChunkX + r, camChunkY - y, camChunkZ - r });
|
||||
chunkQueue.push({ camChunkX - r, camChunkY - y, camChunkZ + r });
|
||||
chunkQueue.push({ camChunkX - r, camChunkY - y, camChunkZ - r });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (chunksLoading == 0 && !chunkQueue.empty())
|
||||
{
|
||||
// Queue is not empty. Process front item in queue
|
||||
glm::vec3 next = chunkQueue.front();
|
||||
chunkQueue.pop();
|
||||
|
||||
std::tuple<int, int, int> chunkTuple{ next.x, next.y, next.z };
|
||||
|
||||
if (chunks.find(chunkTuple) == chunks.end())
|
||||
{
|
||||
chunks.try_emplace(chunkTuple,
|
||||
chunkSize, next
|
||||
);
|
||||
}
|
||||
}
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
chunksLoading = 0;
|
||||
numChunks = 0;
|
||||
numChunksRendered = 0;
|
||||
chunkMutex.lock();
|
||||
for (auto it = chunks.begin(); it != chunks.end(); )
|
||||
{
|
||||
numChunks++;
|
||||
|
||||
if (!it->second.ready)
|
||||
if (!(*it->second).ready)
|
||||
chunksLoading++;
|
||||
|
||||
int chunkX = it->second.chunkPos.x;
|
||||
int chunkY = it->second.chunkPos.y;
|
||||
int chunkZ = it->second.chunkPos.z;
|
||||
if (it->second.ready && (abs(chunkX - camChunkX) > renderDistance ||
|
||||
int chunkX = (*it->second).chunkPos.x;
|
||||
int chunkY = (*it->second).chunkPos.y;
|
||||
int chunkZ = (*it->second).chunkPos.z;
|
||||
if ((*it->second).ready && (abs(chunkX - camChunkX) > renderDistance ||
|
||||
abs(chunkY - camChunkY) > renderDistance ||
|
||||
abs(chunkZ - camChunkZ) > renderDistance))
|
||||
{
|
||||
it->second.~Chunk();
|
||||
// Out of range
|
||||
// Add chunk data to delete queue
|
||||
chunkDataDeleteQueue.push({ chunkX, chunkY, chunkZ });
|
||||
chunkDataDeleteQueue.push({ chunkX + 1, chunkY, chunkZ });
|
||||
chunkDataDeleteQueue.push({ chunkX - 1, chunkY, chunkZ });
|
||||
chunkDataDeleteQueue.push({ chunkX, chunkY + 1, chunkZ });
|
||||
chunkDataDeleteQueue.push({ chunkX, chunkY - 1, chunkZ });
|
||||
chunkDataDeleteQueue.push({ chunkX, chunkY, chunkZ + 1 });
|
||||
chunkDataDeleteQueue.push({ chunkX, chunkY, chunkZ - 1 });
|
||||
|
||||
// Delete chunk
|
||||
delete it->second;
|
||||
it = chunks.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
numChunksRendered++;
|
||||
it->second.Render(modelLoc);
|
||||
(*it->second).Render(solidShader, billboardShader);
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
waterShader->use();
|
||||
for (auto it = chunks.begin(); it != chunks.end(); )
|
||||
{
|
||||
int chunkX = (*it->second).chunkPos.x;
|
||||
int chunkY = (*it->second).chunkPos.y;
|
||||
int chunkZ = (*it->second).chunkPos.z;
|
||||
|
||||
(*it->second).RenderWater(waterShader);
|
||||
++it;
|
||||
}
|
||||
|
||||
chunkMutex.unlock();
|
||||
}
|
||||
|
||||
void Planet::ChunkThreadUpdate()
|
||||
{
|
||||
while (!shouldEnd)
|
||||
{
|
||||
for (auto it = chunkData.begin(); it != chunkData.end(); )
|
||||
{
|
||||
ChunkPos pos = it->first;
|
||||
|
||||
if (chunks.find(pos) == chunks.end() &&
|
||||
chunks.find({ pos.x + 1, pos.y, pos.z }) == chunks.end() &&
|
||||
chunks.find({ pos.x - 1, pos.y, pos.z }) == chunks.end() &&
|
||||
chunks.find({ pos.x, pos.y + 1, pos.z }) == chunks.end() &&
|
||||
chunks.find({ pos.x, pos.y - 1, pos.z }) == chunks.end() &&
|
||||
chunks.find({ pos.x, pos.y, pos.z + 1 }) == chunks.end() &&
|
||||
chunks.find({ pos.x, pos.y, pos.z - 1 }) == chunks.end())
|
||||
{
|
||||
delete chunkData.at(pos);
|
||||
chunkData.erase(pos);
|
||||
}
|
||||
++it;
|
||||
}
|
||||
|
||||
// Check if camera moved to new chunk
|
||||
if (camChunkX != lastCamX || camChunkY != lastCamY || camChunkZ != lastCamZ)
|
||||
{
|
||||
// Player moved chunks, start new chunk queue
|
||||
lastCamX = camChunkX;
|
||||
lastCamY = camChunkY;
|
||||
lastCamZ = camChunkZ;
|
||||
|
||||
// Current chunk
|
||||
chunkMutex.lock();
|
||||
chunkQueue = {};
|
||||
if (chunks.find({ camChunkX, camChunkY, camChunkZ }) == chunks.end())
|
||||
chunkQueue.push({ camChunkX, camChunkY, camChunkZ });
|
||||
|
||||
for (int r = 0; r < renderDistance; r++)
|
||||
{
|
||||
// Add middle chunks
|
||||
for (int y = 0; y <= renderHeight; y++)
|
||||
{
|
||||
chunkQueue.push({ camChunkX, camChunkY + y, camChunkZ + r });
|
||||
chunkQueue.push({ camChunkX + r, camChunkY + y, camChunkZ });
|
||||
chunkQueue.push({ camChunkX, camChunkY + y, camChunkZ - r });
|
||||
chunkQueue.push({ camChunkX - r, camChunkY + y, camChunkZ });
|
||||
|
||||
if (y > 0)
|
||||
{
|
||||
chunkQueue.push({ camChunkX, camChunkY - y, camChunkZ + r });
|
||||
chunkQueue.push({ camChunkX + r, camChunkY - y, camChunkZ });
|
||||
chunkQueue.push({ camChunkX, camChunkY - y, camChunkZ - r });
|
||||
chunkQueue.push({ camChunkX - r, camChunkY - y, camChunkZ });
|
||||
}
|
||||
}
|
||||
|
||||
// Add edges
|
||||
for (int e = 1; e < r; e++)
|
||||
{
|
||||
for (int y = 0; y <= renderHeight; y++)
|
||||
{
|
||||
chunkQueue.push({ camChunkX + e, camChunkY + y, camChunkZ + r });
|
||||
chunkQueue.push({ camChunkX - e, camChunkY + y, camChunkZ + r });
|
||||
|
||||
chunkQueue.push({ camChunkX + r, camChunkY + y, camChunkZ + e });
|
||||
chunkQueue.push({ camChunkX + r, camChunkY + y, camChunkZ - e });
|
||||
|
||||
chunkQueue.push({ camChunkX + e, camChunkY + y, camChunkZ - r });
|
||||
chunkQueue.push({ camChunkX - e, camChunkY + y, camChunkZ - r });
|
||||
|
||||
chunkQueue.push({ camChunkX - r, camChunkY + y, camChunkZ + e });
|
||||
chunkQueue.push({ camChunkX - r, camChunkY + y, camChunkZ - e });
|
||||
|
||||
if (y > 0)
|
||||
{
|
||||
chunkQueue.push({ camChunkX + e, camChunkY - y, camChunkZ + r });
|
||||
chunkQueue.push({ camChunkX - e, camChunkY - y, camChunkZ + r });
|
||||
|
||||
chunkQueue.push({ camChunkX + r, camChunkY - y, camChunkZ + e });
|
||||
chunkQueue.push({ camChunkX + r, camChunkY - y, camChunkZ - e });
|
||||
|
||||
chunkQueue.push({ camChunkX + e, camChunkY - y, camChunkZ - r });
|
||||
chunkQueue.push({ camChunkX - e, camChunkY - y, camChunkZ - r });
|
||||
|
||||
chunkQueue.push({ camChunkX - r, camChunkY - y, camChunkZ + e });
|
||||
chunkQueue.push({ camChunkX - r, camChunkY - y, camChunkZ - e });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add corners
|
||||
for (int y = 0; y <= renderHeight; y++)
|
||||
{
|
||||
chunkQueue.push({ camChunkX + r, camChunkY + y, camChunkZ + r });
|
||||
chunkQueue.push({ camChunkX + r, camChunkY + y, camChunkZ - r });
|
||||
chunkQueue.push({ camChunkX - r, camChunkY + y, camChunkZ + r });
|
||||
chunkQueue.push({ camChunkX - r, camChunkY + y, camChunkZ - r });
|
||||
|
||||
if (y > 0)
|
||||
{
|
||||
chunkQueue.push({ camChunkX + r, camChunkY - y, camChunkZ + r });
|
||||
chunkQueue.push({ camChunkX + r, camChunkY - y, camChunkZ - r });
|
||||
chunkQueue.push({ camChunkX - r, camChunkY - y, camChunkZ + r });
|
||||
chunkQueue.push({ camChunkX - r, camChunkY - y, camChunkZ - r });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
chunkMutex.unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
chunkMutex.lock();
|
||||
if (!chunkDataQueue.empty())
|
||||
{
|
||||
ChunkPos chunkPos = chunkDataQueue.front();
|
||||
|
||||
if (chunkData.find(chunkPos) != chunkData.end())
|
||||
{
|
||||
chunkDataQueue.pop();
|
||||
chunkMutex.unlock();
|
||||
continue;
|
||||
}
|
||||
|
||||
chunkMutex.unlock();
|
||||
|
||||
uint16_t* d = new uint16_t[CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE];
|
||||
ChunkData* data = new ChunkData(d);
|
||||
|
||||
WorldGen::GenerateChunkData(chunkPos, d);
|
||||
|
||||
chunkMutex.lock();
|
||||
chunkData[chunkPos] = data;
|
||||
chunkDataQueue.pop();
|
||||
chunkMutex.unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!chunkQueue.empty())
|
||||
{
|
||||
// Check if chunk exists
|
||||
ChunkPos chunkPos = chunkQueue.front();
|
||||
if (chunks.find(chunkPos) != chunks.end())
|
||||
{
|
||||
chunkQueue.pop();
|
||||
chunkMutex.unlock();
|
||||
continue;
|
||||
}
|
||||
|
||||
chunkMutex.unlock();
|
||||
|
||||
// Create chunk object
|
||||
Chunk* chunk = new Chunk(chunkPos, solidShader, waterShader);
|
||||
|
||||
// Set chunk data
|
||||
{
|
||||
chunkMutex.lock();
|
||||
if (chunkData.find(chunkPos) == chunkData.end())
|
||||
{
|
||||
chunkMutex.unlock();
|
||||
uint16_t* d = new uint16_t[CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE];
|
||||
|
||||
WorldGen::GenerateChunkData(chunkPos, d);
|
||||
|
||||
ChunkData* data = new ChunkData(d);
|
||||
|
||||
chunk->chunkData = data;
|
||||
|
||||
chunkMutex.lock();
|
||||
chunkData[chunkPos] = data;
|
||||
chunkMutex.unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
chunk->chunkData = chunkData.at(chunkPos);
|
||||
chunkMutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
// Set top data
|
||||
{
|
||||
ChunkPos topPos(chunkPos.x, chunkPos.y + 1, chunkPos.z);
|
||||
chunkMutex.lock();
|
||||
if (chunkData.find(topPos) == chunkData.end())
|
||||
{
|
||||
chunkMutex.unlock();
|
||||
uint16_t* d = new uint16_t[CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE];
|
||||
|
||||
WorldGen::GenerateChunkData(topPos, d);
|
||||
|
||||
ChunkData* data = new ChunkData(d);
|
||||
|
||||
chunk->upData = data;
|
||||
|
||||
chunkMutex.lock();
|
||||
chunkData[topPos] = data;
|
||||
chunkMutex.unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
chunk->upData = chunkData.at(topPos);
|
||||
chunkMutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
// Set bottom data
|
||||
{
|
||||
ChunkPos bottomPos(chunkPos.x, chunkPos.y - 1, chunkPos.z);
|
||||
chunkMutex.lock();
|
||||
if (chunkData.find(bottomPos) == chunkData.end())
|
||||
{
|
||||
chunkMutex.unlock();
|
||||
uint16_t* d = new uint16_t[CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE];
|
||||
|
||||
WorldGen::GenerateChunkData(bottomPos, d);
|
||||
|
||||
ChunkData* data = new ChunkData(d);
|
||||
|
||||
chunk->downData = data;
|
||||
|
||||
chunkMutex.lock();
|
||||
chunkData[bottomPos] = data;
|
||||
chunkMutex.unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
chunk->downData = chunkData.at(bottomPos);
|
||||
chunkMutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
// Set north data
|
||||
{
|
||||
ChunkPos northPos(chunkPos.x, chunkPos.y, chunkPos.z - 1);
|
||||
chunkMutex.lock();
|
||||
if (chunkData.find(northPos) == chunkData.end())
|
||||
{
|
||||
chunkMutex.unlock();
|
||||
uint16_t* d = new uint16_t[CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE];
|
||||
|
||||
WorldGen::GenerateChunkData(northPos, d);
|
||||
|
||||
ChunkData* data = new ChunkData(d);
|
||||
|
||||
chunk->northData = data;
|
||||
|
||||
chunkMutex.lock();
|
||||
chunkData[northPos] = data;
|
||||
chunkMutex.unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
chunk->northData = chunkData.at(northPos);
|
||||
chunkMutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
// Set south data
|
||||
{
|
||||
ChunkPos southPos(chunkPos.x, chunkPos.y, chunkPos.z + 1);
|
||||
chunkMutex.lock();
|
||||
if (chunkData.find(southPos) == chunkData.end())
|
||||
{
|
||||
chunkMutex.unlock();
|
||||
uint16_t* d = new uint16_t[CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE];
|
||||
|
||||
WorldGen::GenerateChunkData(southPos, d);
|
||||
|
||||
ChunkData* data = new ChunkData(d);
|
||||
|
||||
chunk->southData = data;
|
||||
|
||||
chunkMutex.lock();
|
||||
chunkData[southPos] = data;
|
||||
chunkMutex.unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
chunk->southData = chunkData.at(southPos);
|
||||
chunkMutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
// Set east data
|
||||
{
|
||||
ChunkPos eastPos(chunkPos.x + 1, chunkPos.y, chunkPos.z);
|
||||
chunkMutex.lock();
|
||||
if (chunkData.find(eastPos) == chunkData.end())
|
||||
{
|
||||
chunkMutex.unlock();
|
||||
uint16_t* d = new uint16_t[CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE];
|
||||
|
||||
WorldGen::GenerateChunkData(eastPos, d);
|
||||
|
||||
ChunkData* data = new ChunkData(d);
|
||||
|
||||
chunk->eastData = data;
|
||||
|
||||
chunkMutex.lock();
|
||||
chunkData[eastPos] = data;
|
||||
chunkMutex.unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
chunk->eastData = chunkData.at(eastPos);
|
||||
chunkMutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
// Set west data
|
||||
{
|
||||
ChunkPos westPos(chunkPos.x - 1, chunkPos.y, chunkPos.z);
|
||||
chunkMutex.lock();
|
||||
if (chunkData.find(westPos) == chunkData.end())
|
||||
{
|
||||
chunkMutex.unlock();
|
||||
uint16_t* d = new uint16_t[CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE];
|
||||
|
||||
WorldGen::GenerateChunkData(westPos, d);
|
||||
|
||||
ChunkData* data = new ChunkData(d);
|
||||
|
||||
chunk->westData = data;
|
||||
|
||||
chunkMutex.lock();
|
||||
chunkData[westPos] = data;
|
||||
chunkMutex.unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
chunk->westData = chunkData.at(westPos);
|
||||
chunkMutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
// Generate chunk mesh
|
||||
chunk->GenerateChunkMesh();
|
||||
|
||||
// Finish
|
||||
chunkMutex.lock();
|
||||
chunks[chunkPos] = chunk;
|
||||
chunkQueue.pop();
|
||||
chunkMutex.unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
chunkMutex.unlock();
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Chunk* Planet::GetChunk(ChunkPos chunkPos)
|
||||
{
|
||||
chunkMutex.lock();
|
||||
if (chunks.find(chunkPos) == chunks.end())
|
||||
{
|
||||
chunkMutex.unlock();
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
chunkMutex.unlock();
|
||||
return chunks.at(chunkPos);
|
||||
}
|
||||
}
|
||||
|
||||
void Planet::ClearChunkQueue()
|
||||
{
|
||||
lastCamX++;
|
||||
}
|
@ -5,31 +5,55 @@
|
||||
#include <string>
|
||||
#include <queue>
|
||||
#include <glm/glm.hpp>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
|
||||
#include "ChunkPos.h"
|
||||
#include "ChunkData.h"
|
||||
#include "Chunk.h"
|
||||
#include "TupleHash.h"
|
||||
#include "ChunkPosHash.h"
|
||||
|
||||
constexpr unsigned int CHUNK_SIZE = 32;
|
||||
|
||||
class Planet
|
||||
{
|
||||
// Methods
|
||||
public:
|
||||
Planet();
|
||||
Planet(Shader* solidShader, Shader* waterShader, Shader* billboardShader);
|
||||
~Planet();
|
||||
|
||||
std::vector<unsigned int> GetChunkData(int chunkX, int chunkY, int chunkZ);
|
||||
void Update(float camX, float camY, float camZ, unsigned int modelLoc);
|
||||
ChunkData* GetChunkData(ChunkPos chunkPos);
|
||||
void Update(glm::vec3 cameraPos);
|
||||
|
||||
Chunk* GetChunk(ChunkPos chunkPos);
|
||||
void ClearChunkQueue();
|
||||
|
||||
private:
|
||||
void ChunkThreadUpdate();
|
||||
|
||||
// Variables
|
||||
public:
|
||||
static Planet* planet;
|
||||
unsigned int numChunks = 0, numChunksRendered = 0;
|
||||
int renderDistance = 10;
|
||||
int renderHeight = 3;
|
||||
|
||||
private:
|
||||
std::unordered_map<std::tuple<int, int, int>, Chunk> chunks;
|
||||
std::queue<glm::vec3> chunkQueue;
|
||||
int renderDistance = 3;
|
||||
int renderHeight = 1;
|
||||
unsigned int chunkSize = 32;
|
||||
std::unordered_map<ChunkPos, Chunk*, ChunkPosHash> chunks;
|
||||
std::unordered_map<ChunkPos, ChunkData*, ChunkPosHash> chunkData;
|
||||
std::queue<ChunkPos> chunkQueue;
|
||||
std::queue<ChunkPos> chunkDataQueue;
|
||||
std::queue<ChunkPos> chunkDataDeleteQueue;
|
||||
unsigned int chunksLoading = 0;
|
||||
int lastCamX = -100, lastCamY = -100, lastCamZ = -100;
|
||||
int camChunkX = -100, camChunkY = -100, camChunkZ = -100;
|
||||
|
||||
Shader* solidShader;
|
||||
Shader* waterShader;
|
||||
Shader* billboardShader;
|
||||
|
||||
std::thread chunkThread;
|
||||
std::mutex chunkMutex;
|
||||
|
||||
bool shouldEnd = false;
|
||||
};
|
@ -1,53 +0,0 @@
|
||||
#include <tuple>
|
||||
// function has to live in the std namespace
|
||||
// so that it is picked up by argument-dependent name lookup (ADL).
|
||||
namespace std {
|
||||
namespace
|
||||
{
|
||||
|
||||
// Code from boost
|
||||
// Reciprocal of the golden ratio helps spread entropy
|
||||
// and handles duplicates.
|
||||
// See Mike Seymour in magic-numbers-in-boosthash-combine:
|
||||
// https://stackoverflow.com/questions/4948780
|
||||
|
||||
template <class T>
|
||||
inline void hash_combine(std::size_t& seed, T const& v)
|
||||
{
|
||||
seed ^= hash<T>()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||
}
|
||||
|
||||
// Recursive template code derived from Matthieu M.
|
||||
template <class Tuple, size_t Index = std::tuple_size<Tuple>::value - 1>
|
||||
struct HashValueImpl
|
||||
{
|
||||
static void apply(size_t& seed, Tuple const& tuple)
|
||||
{
|
||||
HashValueImpl<Tuple, Index - 1>::apply(seed, tuple);
|
||||
hash_combine(seed, get<Index>(tuple));
|
||||
}
|
||||
};
|
||||
|
||||
template <class Tuple>
|
||||
struct HashValueImpl<Tuple, 0>
|
||||
{
|
||||
static void apply(size_t& seed, Tuple const& tuple)
|
||||
{
|
||||
hash_combine(seed, get<0>(tuple));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <typename ... TT>
|
||||
struct hash<std::tuple<TT...>>
|
||||
{
|
||||
size_t
|
||||
operator()(std::tuple<TT...> const& tt) const
|
||||
{
|
||||
size_t seed = 0;
|
||||
HashValueImpl<std::tuple<TT...> >::apply(seed, tt);
|
||||
return seed;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
58
ScuffedMinecraft/src/Vertex.h
Normal file
58
ScuffedMinecraft/src/Vertex.h
Normal file
@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
|
||||
struct Vertex
|
||||
{
|
||||
char posX, posY, posZ;
|
||||
char texGridX, texGridY;
|
||||
char direction;
|
||||
|
||||
Vertex(char _posX, char _posY, char _posZ, char _texGridX, char _texGridY, char _direction)
|
||||
{
|
||||
posX = _posX;
|
||||
posY = _posY;
|
||||
posZ = _posZ;
|
||||
|
||||
texGridX = _texGridX;
|
||||
texGridY = _texGridY;
|
||||
|
||||
direction = _direction;
|
||||
}
|
||||
};
|
||||
|
||||
struct WaterVertex
|
||||
{
|
||||
char posX, posY, posZ;
|
||||
char texGridX, texGridY;
|
||||
char direction;
|
||||
char top;
|
||||
|
||||
WaterVertex(char _posX, char _posY, char _posZ, char _texGridX, char _texGridY, char _direction, char _top)
|
||||
{
|
||||
posX = _posX;
|
||||
posY = _posY;
|
||||
posZ = _posZ;
|
||||
|
||||
texGridX = _texGridX;
|
||||
texGridY = _texGridY;
|
||||
|
||||
direction = _direction;
|
||||
|
||||
top = _top;
|
||||
}
|
||||
};
|
||||
|
||||
struct BillboardVertex
|
||||
{
|
||||
float posX, posY, posZ;
|
||||
char texGridX, texGridY;
|
||||
|
||||
BillboardVertex(float _posX, float _posY, float _posZ, char _texGridX, char _texGridY)
|
||||
{
|
||||
posX = _posX;
|
||||
posY = _posY;
|
||||
posZ = _posZ;
|
||||
|
||||
texGridX = _texGridX;
|
||||
texGridY = _texGridY;
|
||||
}
|
||||
};
|
@ -5,9 +5,12 @@
|
||||
#include <OpenSimplexNoise.hh>
|
||||
|
||||
#include "Blocks.h"
|
||||
#include "Planet.h"
|
||||
|
||||
void WorldGen::GenerateChunkData(int chunkX, int chunkY, int chunkZ, int chunkSize, std::vector<unsigned int>* chunkData)
|
||||
void WorldGen::GenerateChunkData(ChunkPos chunkPos, uint16_t* chunkData)
|
||||
{
|
||||
static int chunkSize = CHUNK_SIZE;
|
||||
|
||||
// Init noise
|
||||
static OSN::Noise<2> noise2D;
|
||||
static OSN::Noise<3> noise3D;
|
||||
@ -15,7 +18,7 @@ void WorldGen::GenerateChunkData(int chunkX, int chunkY, int chunkZ, int chunkSi
|
||||
// Init noise settings
|
||||
static NoiseSettings surfaceSettings[]{
|
||||
{ 0.01f, 20.0f, 0 },
|
||||
{ 0.1f, 3.0f, 0 }
|
||||
{ 0.05f, 3.0f, 0 }
|
||||
};
|
||||
static int surfaceSettingsLength = sizeof(surfaceSettings) / sizeof(*surfaceSettings);
|
||||
|
||||
@ -30,70 +33,151 @@ void WorldGen::GenerateChunkData(int chunkX, int chunkY, int chunkZ, int chunkSi
|
||||
static int oreSettingsLength = sizeof(oreSettings) / sizeof(*oreSettings);
|
||||
|
||||
static SurfaceFeature surfaceFeatures[]{
|
||||
// Pond
|
||||
{
|
||||
{ 0.43f, 1.0f, 2.35f, .85f, 1, 0 }, // Noise
|
||||
{ // Blocks
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 13, 13, 0, 0,
|
||||
0, 0, 13, 13, 13, 0, 0,
|
||||
0, 0, 0, 13, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
0, 2, 13, 13, 2, 0, 0,
|
||||
0, 2, 13, 13, 13, 2, 0,
|
||||
2, 13, 13, 13, 13, 13, 2,
|
||||
2, 13, 13, 13, 13, 13, 2,
|
||||
2, 13, 13, 13, 13, 13, 2,
|
||||
0, 2, 13, 13, 13, 2, 0,
|
||||
0, 0, 2, 13, 2, 0, 0,
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
},
|
||||
{ // Replace?
|
||||
false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false,
|
||||
false, false, false, true, true, false, false,
|
||||
false, false, true, true, true, false, false,
|
||||
false, false, false, true, false, false, false,
|
||||
false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false,
|
||||
|
||||
false, false, true, true, false, false, false,
|
||||
false, false, true, true, true, false, false,
|
||||
false, true, true, true, true, true, false,
|
||||
false, true, true, true, true, true, false,
|
||||
false, true, true, true, true, true, false,
|
||||
false, false, true, true, true, false, false,
|
||||
false, false, false, true, false, false, false,
|
||||
|
||||
false, false, true, true, false, false, false,
|
||||
false, false, true, true, true, true, false,
|
||||
false, true, true, true, true, true, false,
|
||||
false, true, true, true, true, true, false,
|
||||
false, true, true, true, true, true, false,
|
||||
false, false, true, true, true, false, false,
|
||||
false, false, false, true, false, false, false,
|
||||
},
|
||||
7, 3, 7, // Size
|
||||
-3, -2, -3 // Offset
|
||||
},
|
||||
// Tree
|
||||
{
|
||||
{ 4.23f, 1.0f, 8.54f, .8f, 1, 0 },
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 5, 5, 0, 0,
|
||||
0, 0, 0, 5, 5, 0, 0,
|
||||
0, 0, 0, 5, 5, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
0, 0, 1, 0, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 5, 5, 0, 0,
|
||||
0, 0, 0, 5, 5, 5, 0,
|
||||
0, 0, 0, 5, 5, 5, 5,
|
||||
0, 0, 0, 5, 5, 5, 0,
|
||||
0, 0, 0, 5, 5, 0, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
0, 0, 4, 0, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 5, 5, 0, 0,
|
||||
0, 0, 0, 5, 5, 5, 5,
|
||||
1, 4, 4, 4, 4, 5, 5,
|
||||
0, 0, 0, 5, 5, 5, 5,
|
||||
0, 0, 0, 5, 5, 0, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
0, 0, 4, 0, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 5, 5, 0, 0,
|
||||
0, 0, 0, 5, 5, 5, 0,
|
||||
0, 0, 0, 5, 5, 5, 5,
|
||||
0, 0, 0, 5, 5, 5, 0,
|
||||
0, 0, 0, 5, 5, 0, 0,
|
||||
0, 5, 5, 5, 0,
|
||||
5, 5, 5, 5, 5,
|
||||
5, 5, 4, 5, 5,
|
||||
5, 5, 5, 5, 5,
|
||||
0, 5, 5, 5, 0,
|
||||
|
||||
0, 5, 5, 5, 0,
|
||||
5, 5, 5, 5, 5,
|
||||
5, 5, 4, 5, 5,
|
||||
5, 5, 5, 5, 5,
|
||||
0, 5, 5, 5, 0,
|
||||
|
||||
0, 0, 0, 0, 0,
|
||||
0, 0, 5, 0, 0,
|
||||
0, 5, 5, 5, 0,
|
||||
0, 0, 5, 0, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 0, 0,
|
||||
0, 0, 5, 0, 0,
|
||||
0, 5, 5, 5, 0,
|
||||
0, 0, 5, 0, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 5, 5, 0, 0,
|
||||
0, 0, 0, 5, 5, 0, 0,
|
||||
0, 0, 0, 5, 5, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
},
|
||||
{
|
||||
false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false,
|
||||
false, false, false, false, false,
|
||||
false, false, false, false, false,
|
||||
false, false, true, false, false,
|
||||
false, false, false, false, false,
|
||||
false, false, false, false, false,
|
||||
|
||||
false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false,
|
||||
false, false, false, false, false,
|
||||
false, false, false, false, false,
|
||||
false, false, true, false, false,
|
||||
false, false, false, false, false,
|
||||
false, false, false, false, false,
|
||||
|
||||
false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false,
|
||||
true, true, true, true, true, false, false,
|
||||
false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false,
|
||||
false, false, false, false, false,
|
||||
false, false, false, false, false,
|
||||
false, false, true, false, false,
|
||||
false, false, false, false, false,
|
||||
false, false, false, false, false,
|
||||
|
||||
false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false,
|
||||
false, false, false, false, false,
|
||||
false, false, false, false, false,
|
||||
false, false, true, false, false,
|
||||
false, false, false, false, false,
|
||||
false, false, false, false, false,
|
||||
|
||||
false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false,
|
||||
false, false, false, false, false,
|
||||
false, false, false, false, false,
|
||||
false, false, true, false, false,
|
||||
false, false, false, false, false,
|
||||
false, false, false, false, false,
|
||||
|
||||
false, false, false, false, false,
|
||||
false, false, false, false, false,
|
||||
false, false, false, false, false,
|
||||
false, false, false, false, false,
|
||||
false, false, false, false, false,
|
||||
|
||||
false, false, false, false, false,
|
||||
false, false, false, false, false,
|
||||
false, false, false, false, false,
|
||||
false, false, false, false, false,
|
||||
false, false, false, false, false,
|
||||
},
|
||||
5,
|
||||
7,
|
||||
@ -102,22 +186,6 @@ void WorldGen::GenerateChunkData(int chunkX, int chunkY, int chunkZ, int chunkSi
|
||||
0,
|
||||
-2
|
||||
},
|
||||
// Grass
|
||||
{
|
||||
{ 2.65f, 1.0f, 8.54f, .5f, 1, 0 },
|
||||
{
|
||||
2, 6
|
||||
},
|
||||
{
|
||||
false, false
|
||||
},
|
||||
1,
|
||||
2,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
},
|
||||
// Tall Grass
|
||||
{
|
||||
{ 1.23f, 1.0f, 4.34f, .6f, 1, 0 },
|
||||
@ -134,6 +202,22 @@ void WorldGen::GenerateChunkData(int chunkX, int chunkY, int chunkZ, int chunkSi
|
||||
0,
|
||||
0
|
||||
},
|
||||
// Grass
|
||||
{
|
||||
{ 2.65f, 1.0f, 8.54f, .5f, 1, 0 },
|
||||
{
|
||||
2, 6
|
||||
},
|
||||
{
|
||||
false, false
|
||||
},
|
||||
1,
|
||||
2,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
},
|
||||
// Poppy
|
||||
{
|
||||
{ 5.32f, 1.0f, 3.67f, .8f, 1, 0 },
|
||||
@ -201,14 +285,14 @@ void WorldGen::GenerateChunkData(int chunkX, int chunkY, int chunkZ, int chunkSi
|
||||
};
|
||||
static int surfaceFeaturesLength = sizeof(surfaceFeatures) / sizeof(*surfaceFeatures);
|
||||
|
||||
// Set vector size
|
||||
chunkData->reserve(chunkSize * chunkSize * chunkSize);
|
||||
static int waterLevel = 20;
|
||||
|
||||
// Account for chunk position
|
||||
int startX = chunkX * chunkSize;
|
||||
int startY = chunkY * chunkSize;
|
||||
int startZ = chunkZ * chunkSize;
|
||||
int startX = chunkPos.x * chunkSize;
|
||||
int startY = chunkPos.y * chunkSize;
|
||||
int startZ = chunkPos.z * chunkSize;
|
||||
|
||||
int currentIndex = 0;
|
||||
for (int x = 0; x < chunkSize; x++)
|
||||
{
|
||||
for (int z = 0; z < chunkSize; z++)
|
||||
@ -249,9 +333,14 @@ void WorldGen::GenerateChunkData(int chunkX, int chunkY, int chunkZ, int chunkSi
|
||||
|
||||
// Sky and Caves
|
||||
if (y + startY > noiseY)
|
||||
chunkData->push_back(0);
|
||||
{
|
||||
if (y + startY <= waterLevel)
|
||||
chunkData[currentIndex] = Blocks::WATER;
|
||||
else
|
||||
chunkData[currentIndex] = Blocks::AIR;
|
||||
}
|
||||
else if (cave)
|
||||
chunkData->push_back(0);
|
||||
chunkData[currentIndex] = Blocks::AIR;
|
||||
// Ground
|
||||
else
|
||||
{
|
||||
@ -269,7 +358,7 @@ void WorldGen::GenerateChunkData(int chunkX, int chunkY, int chunkZ, int chunkSi
|
||||
|
||||
if (noiseOre > oreSettings[i].chance)
|
||||
{
|
||||
chunkData->push_back(oreSettings[i].block);
|
||||
chunkData[currentIndex] = oreSettings[i].block;
|
||||
blockSet = true;
|
||||
break;
|
||||
}
|
||||
@ -278,13 +367,21 @@ void WorldGen::GenerateChunkData(int chunkX, int chunkY, int chunkZ, int chunkSi
|
||||
if (!blockSet)
|
||||
{
|
||||
if (y + startY == noiseY)
|
||||
chunkData->push_back(Blocks::GRASS_BLOCK);
|
||||
if (noiseY > waterLevel + 1)
|
||||
chunkData[currentIndex] = Blocks::GRASS_BLOCK;
|
||||
else
|
||||
chunkData[currentIndex] = Blocks::SAND;
|
||||
else if (y + startY > 10)
|
||||
chunkData->push_back(Blocks::DIRT_BLOCK);
|
||||
if (noiseY > waterLevel + 1)
|
||||
chunkData[currentIndex] = Blocks::DIRT_BLOCK;
|
||||
else
|
||||
chunkData[currentIndex] = Blocks::SAND;
|
||||
else
|
||||
chunkData->push_back(Blocks::STONE_BLOCK);
|
||||
chunkData[currentIndex] = Blocks::STONE_BLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
currentIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -305,7 +402,11 @@ void WorldGen::GenerateChunkData(int chunkX, int chunkY, int chunkZ, int chunkSi
|
||||
* surfaceSettings[s].amplitude;
|
||||
}
|
||||
|
||||
if (noiseY + surfaceFeatures[i].offsetY > startY + 32 || noiseY + surfaceFeatures[i].sizeY + surfaceFeatures[i].offsetY < startY)
|
||||
if (noiseY + surfaceFeatures[i].offsetY > startY + chunkSize || noiseY + surfaceFeatures[i].sizeY + surfaceFeatures[i].offsetY < startY)
|
||||
continue;
|
||||
|
||||
// Check if it's in water or on sand
|
||||
if (noiseY < waterLevel + 2)
|
||||
continue;
|
||||
|
||||
// Check if it's in a cave
|
||||
@ -354,30 +455,25 @@ void WorldGen::GenerateChunkData(int chunkX, int chunkY, int chunkZ, int chunkSi
|
||||
int localZ = featureZ + fZ + surfaceFeatures[i].offsetZ - startZ;
|
||||
//std::cout << "FeatureZ: " << featureZ << ", fZ: " << fZ << ", startZ: " << startZ << ", localZ: " << localZ << '\n';
|
||||
|
||||
if (localX >= 32 || localX < 0)
|
||||
if (localX >= chunkSize || localX < 0)
|
||||
continue;
|
||||
if (localY >= 32 || localY < 0)
|
||||
if (localY >= chunkSize || localY < 0)
|
||||
continue;
|
||||
if (localZ >= 32 || localZ < 0)
|
||||
if (localZ >= chunkSize || localZ < 0)
|
||||
continue;
|
||||
|
||||
int featureIndex = fX * surfaceFeatures[i].sizeZ * surfaceFeatures[i].sizeY +
|
||||
fZ * surfaceFeatures[i].sizeY +
|
||||
fY;
|
||||
int featureIndex = fY * surfaceFeatures[i].sizeX * surfaceFeatures[i].sizeZ +
|
||||
fX * surfaceFeatures[i].sizeZ +
|
||||
fZ;
|
||||
//std::cout << "Feature Index: " << featureIndex << '\n';
|
||||
int localIndex = localX * chunkSize * chunkSize + localZ * chunkSize + localY;
|
||||
//std::cout << "Local Index: " << localIndex << ", Max Index: " << chunkData->size() << '\n';
|
||||
|
||||
if (surfaceFeatures[i].replaceBlock[featureIndex] || chunkData->at(localIndex) == 0)
|
||||
chunkData->at(localIndex) = surfaceFeatures[i].blocks[featureIndex];
|
||||
if (surfaceFeatures[i].replaceBlock[featureIndex] || chunkData[localIndex] == 0)
|
||||
chunkData[localIndex] = surfaceFeatures[i].blocks[featureIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//int index = x * chunkSize * chunkSize + z * chunkSize + noiseY;
|
||||
//chunkData->at(index) = surfaceFeatures[i].block;
|
||||
//index = x * chunkSize * chunkSize + z * chunkSize + noiseY + 1;
|
||||
//chunkData->at(index) = surfaceFeatures[i].block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,9 +3,10 @@
|
||||
#include <vector>
|
||||
#include "NoiseSettings.h"
|
||||
#include "SurfaceFeature.h"
|
||||
#include "ChunkData.h"
|
||||
#include "glm/glm.hpp"
|
||||
|
||||
namespace WorldGen
|
||||
{
|
||||
void GenerateChunkData(int chunkX, int chunkY, int chunkZ, int chunkSize, std::vector<unsigned int>* chunkData);
|
||||
|
||||
void GenerateChunkData(ChunkPos chunkPos, uint16_t* chunkData);
|
||||
}
|
11
ScuffedMinecraft/vendor/imgui/CMakeLists.txt
vendored
Normal file
11
ScuffedMinecraft/vendor/imgui/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
add_library(imgui
|
||||
imgui.cpp
|
||||
imgui_demo.cpp
|
||||
imgui_draw.cpp
|
||||
imgui_impl_glfw.cpp
|
||||
imgui_impl_opengl3.cpp
|
||||
imgui_tables.cpp
|
||||
imgui_widgets.cpp
|
||||
)
|
||||
|
||||
target_include_directories(imgui PUBLIC ./)
|
Loading…
Reference in New Issue
Block a user