diff --git a/ScuffedMinecraft/ScuffedMinecraft.vcxproj b/ScuffedMinecraft/ScuffedMinecraft.vcxproj index da168e1..1461acf 100644 --- a/ScuffedMinecraft/ScuffedMinecraft.vcxproj +++ b/ScuffedMinecraft/ScuffedMinecraft.vcxproj @@ -180,6 +180,7 @@ + @@ -193,8 +194,14 @@ - - + + + + + + + + diff --git a/ScuffedMinecraft/ScuffedMinecraft.vcxproj.filters b/ScuffedMinecraft/ScuffedMinecraft.vcxproj.filters index 92cc2ea..44ed770 100644 --- a/ScuffedMinecraft/ScuffedMinecraft.vcxproj.filters +++ b/ScuffedMinecraft/ScuffedMinecraft.vcxproj.filters @@ -131,10 +131,19 @@ Header Files + + Header Files + - - + + + + + + + + diff --git a/ScuffedMinecraft/assets/shaders/billboard_frag.glsl b/ScuffedMinecraft/assets/shaders/billboard_frag.glsl new file mode 100644 index 0000000..fbcfd1f --- /dev/null +++ b/ScuffedMinecraft/assets/shaders/billboard_frag.glsl @@ -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; +} \ No newline at end of file diff --git a/ScuffedMinecraft/assets/shaders/billboard_vert.glsl b/ScuffedMinecraft/assets/shaders/billboard_vert.glsl new file mode 100644 index 0000000..5be1325 --- /dev/null +++ b/ScuffedMinecraft/assets/shaders/billboard_vert.glsl @@ -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; +} \ No newline at end of file diff --git a/ScuffedMinecraft/assets/shaders/framebuffer_frag.glsl b/ScuffedMinecraft/assets/shaders/framebuffer_frag.glsl new file mode 100644 index 0000000..878ea4b --- /dev/null +++ b/ScuffedMinecraft/assets/shaders/framebuffer_frag.glsl @@ -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); +} \ No newline at end of file diff --git a/ScuffedMinecraft/assets/shaders/framebuffer_vert.glsl b/ScuffedMinecraft/assets/shaders/framebuffer_vert.glsl new file mode 100644 index 0000000..3ec6042 --- /dev/null +++ b/ScuffedMinecraft/assets/shaders/framebuffer_vert.glsl @@ -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; +} \ No newline at end of file diff --git a/ScuffedMinecraft/assets/shaders/fragment_shader.glsl b/ScuffedMinecraft/assets/shaders/main_frag.glsl similarity index 100% rename from ScuffedMinecraft/assets/shaders/fragment_shader.glsl rename to ScuffedMinecraft/assets/shaders/main_frag.glsl diff --git a/ScuffedMinecraft/assets/shaders/vertex_shader.glsl b/ScuffedMinecraft/assets/shaders/main_vert.glsl similarity index 92% rename from ScuffedMinecraft/assets/shaders/vertex_shader.glsl rename to ScuffedMinecraft/assets/shaders/main_vert.glsl index 46aea5d..cd3b298 100644 --- a/ScuffedMinecraft/assets/shaders/vertex_shader.glsl +++ b/ScuffedMinecraft/assets/shaders/main_vert.glsl @@ -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[]( diff --git a/ScuffedMinecraft/assets/shaders/water_frag.glsl b/ScuffedMinecraft/assets/shaders/water_frag.glsl new file mode 100644 index 0000000..890725d --- /dev/null +++ b/ScuffedMinecraft/assets/shaders/water_frag.glsl @@ -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; +} \ No newline at end of file diff --git a/ScuffedMinecraft/assets/shaders/water_vert.glsl b/ScuffedMinecraft/assets/shaders/water_vert.glsl new file mode 100644 index 0000000..5912972 --- /dev/null +++ b/ScuffedMinecraft/assets/shaders/water_vert.glsl @@ -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]; +} \ No newline at end of file diff --git a/ScuffedMinecraft/assets/sprites/block_map.png b/ScuffedMinecraft/assets/sprites/block_map.png index 4018519..79efa49 100644 Binary files a/ScuffedMinecraft/assets/sprites/block_map.png and b/ScuffedMinecraft/assets/sprites/block_map.png differ diff --git a/ScuffedMinecraft/assets/sprites/block_map.psd b/ScuffedMinecraft/assets/sprites/block_map.psd index 95fd05f..378f4e4 100644 Binary files a/ScuffedMinecraft/assets/sprites/block_map.psd and b/ScuffedMinecraft/assets/sprites/block_map.psd differ diff --git a/ScuffedMinecraft/src/Application.cpp b/ScuffedMinecraft/src/Application.cpp index 9a6c43c..953a117 100644 --- a/ScuffedMinecraft/src/Application.cpp +++ b/ScuffedMinecraft/src/Application.cpp @@ -16,6 +16,7 @@ #include "Shader.h" #include "Camera.h" #include "Planet.h" +#include "Blocks.h" void framebufferSizeCallback(GLFWwindow* window, int width, int height); void processInput(GLFWwindow* window); @@ -43,6 +44,18 @@ Camera camera; // Window options #define VSYNC 1 // 0 for off, 1 for on +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 +}; + int main() { // Initialize GLFW @@ -84,13 +97,71 @@ 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); + + 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); - // Create texture + Shader framebufferShader("assets/shaders/framebuffer_vert.glsl", "assets/shaders/framebuffer_frag.glsl"); + + // Create post-processing framebuffer + unsigned int FBO; + glGenFramebuffers(1, &FBO); + glBindFramebuffer(GL_FRAMEBUFFER, FBO); + + unsigned int framebufferTexture; + 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); + + unsigned int depthTexture; + 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); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + // Create terrain texture unsigned int texture; glGenTextures(1, &texture); glActiveTexture(GL_TEXTURE0); @@ -122,7 +193,7 @@ int main() glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); - Planet::planet = new Planet(); + Planet::planet = new Planet(&shader, &waterShader, &billboardShader); // Initialize ImGui IMGUI_CHECKVERSION(); @@ -158,11 +229,19 @@ int main() fpsStartTime = currentTimePoint; } + waterShader.use(); + waterShader.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,15 +252,69 @@ 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)); + + 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)); + + Planet::planet->Update(camera.Position.x, camera.Position.y, camera.Position.z); + + framebufferShader.use(); + + // 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)Planet::chunkSize) : blockX / (int)Planet::chunkSize; + int chunkY = blockY < 0 ? floorf(blockY / (float)Planet::chunkSize) : blockY / (int)Planet::chunkSize; + int chunkZ = blockZ < 0 ? floorf(blockZ / (float)Planet::chunkSize) : blockZ / (int)Planet::chunkSize; + + int localBlockX = blockX - (chunkX * Planet::chunkSize); + int localBlockY = blockY - (chunkY * Planet::chunkSize); + int localBlockZ = blockZ - (chunkZ * Planet::chunkSize); + + Chunk* chunk = Planet::planet->GetChunk(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); + } + } - Planet::planet->Update(camera.Position.x, camera.Position.y, camera.Position.z, modelLoc); + 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); // Draw ImGui UI ImGui::Begin("Test"); diff --git a/ScuffedMinecraft/src/Block.cpp b/ScuffedMinecraft/src/Block.cpp index 0552839..7ab0153 100644 --- a/ScuffedMinecraft/src/Block.cpp +++ b/ScuffedMinecraft/src/Block.cpp @@ -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) + : blockType(blockType) { 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) + : blockType(blockType) { this->topMinX = topMinX; this->topMinY = topMinY; diff --git a/ScuffedMinecraft/src/Block.h b/ScuffedMinecraft/src/Block.h index 051f22d..e828c4a 100644 --- a/ScuffedMinecraft/src/Block.h +++ b/ScuffedMinecraft/src/Block.h @@ -3,14 +3,23 @@ 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; - 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); 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); + }; \ No newline at end of file diff --git a/ScuffedMinecraft/src/Blocks.h b/ScuffedMinecraft/src/Blocks.h index f2a58bd..ae0a4eb 100644 --- a/ScuffedMinecraft/src/Blocks.h +++ b/ScuffedMinecraft/src/Blocks.h @@ -7,27 +7,28 @@ namespace Blocks { const std::vector blocks{ - Block(0, 0, 0, 0, true), // Air block - Block(0, 0, 1, 1), // Dirt block + Block(0, 0, 0, 0, Block::TRANSPARENT), // Air block + Block(0, 0, 1, 1, Block::SOLID), // 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), - Block(0, 1, 1, 2), // Stone block + Block(0, 1, 1, 2, Block::SOLID), // Stone block - Block(2, 1, 3, 2, // Log + Block(2, 1, 3, 2, // Log 2, 1, 3, 2, - 2, 0, 3, 1), - - 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 + 2, 0, 3, 1, Block::SOLID), + + Block(0, 2, 1, 3, Block::LEAVES), // Leaves + Block(1, 2, 2, 3, Block::BILLBOARD), // Grass + Block(3, 0, 4, 1, Block::BILLBOARD), // Tall Grass Bottom + Block(3, 1, 4, 2, Block::BILLBOARD), // Tall Grass Top + Block(0, 3, 1, 4, Block::BILLBOARD), // Poppy + Block(2, 2, 3, 3, Block::BILLBOARD), // White Tulip + Block(3, 2, 4, 3, Block::BILLBOARD), // Pink Tulip + Block(1, 3, 2, 4, Block::BILLBOARD), // Orange Tulip + Block(0, 4, 1, 5, Block::LIQUID) // Water }; enum BLOCKS @@ -45,5 +46,6 @@ namespace Blocks WHITE_TULIP = 10, PINK_TULIP = 11, ORANGE_TULIP = 12, + WATER = 13 }; } \ No newline at end of file diff --git a/ScuffedMinecraft/src/Chunk.cpp b/ScuffedMinecraft/src/Chunk.cpp index 9759b22..4b7e95a 100644 --- a/ScuffedMinecraft/src/Chunk.cpp +++ b/ScuffedMinecraft/src/Chunk.cpp @@ -2,18 +2,17 @@ #include #include +#include #include #include -#include #include "Planet.h" #include "Blocks.h" #include "WorldGen.h" -Chunk::Chunk(unsigned int chunkSize, glm::vec3 chunkPos) +Chunk::Chunk(unsigned int chunkSize, glm::vec3 chunkPos, Shader* shader, Shader* waterShader) + : chunkSize(chunkSize), chunkPos(chunkPos) { - this->chunkSize = chunkSize; - this->chunkPos = chunkPos; worldPos = glm::vec3(chunkPos.x * chunkSize, chunkPos.y * chunkSize, chunkPos.z * chunkSize); ready = false; @@ -26,9 +25,17 @@ 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() @@ -48,6 +55,8 @@ void Chunk::GenerateChunk() //std::cout << "Got chunk data in thread: " << std::this_thread::get_id() << '\n'; unsigned int currentVertex = 0; + unsigned int currentLiquidVertex = 0; + unsigned int currentBillboardVertex = 0; for (char x = 0; x < chunkSize; x++) { for (char z = 0; z < chunkSize; z++) @@ -60,59 +69,48 @@ void Chunk::GenerateChunk() const Block* block = &Blocks::blocks[chunkData[index]]; - if (block->billboard) + int topBlock; + if (y < chunkSize - 1) + { + int blockIndex = x * chunkSize * chunkSize + z * chunkSize + (y + 1); + topBlock = chunkData[blockIndex]; + } + else + { + int blockIndex = x * chunkSize * chunkSize + z * chunkSize + 0; + topBlock = upData[blockIndex]; + } + + const Block* topBlockType = &Blocks::blocks[topBlock]; + char waterTopValue = topBlockType->blockType == Block::TRANSPARENT ? 1 : 0; + + if (block->blockType == Block::BILLBOARD) { - 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)); - - 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 + .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)); - - 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 + .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)); - - 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; + 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)); + + 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; + + 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)); + + 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 { @@ -132,20 +130,41 @@ void Chunk::GenerateChunk() 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)); - - 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; + 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)); + + 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)); + + mianIndices.push_back(currentVertex + 0); + mianIndices.push_back(currentVertex + 3); + mianIndices.push_back(currentVertex + 1); + mianIndices.push_back(currentVertex + 0); + mianIndices.push_back(currentVertex + 2); + mianIndices.push_back(currentVertex + 3); + currentVertex += 4; + } } } @@ -165,20 +184,41 @@ void Chunk::GenerateChunk() 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)); - - 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; + 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)); + + 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)); + + mianIndices.push_back(currentVertex + 0); + mianIndices.push_back(currentVertex + 3); + mianIndices.push_back(currentVertex + 1); + mianIndices.push_back(currentVertex + 0); + mianIndices.push_back(currentVertex + 2); + mianIndices.push_back(currentVertex + 3); + currentVertex += 4; + } } } @@ -198,20 +238,41 @@ void Chunk::GenerateChunk() 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)); - - 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; + 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)); + + 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)); + + mianIndices.push_back(currentVertex + 0); + mianIndices.push_back(currentVertex + 3); + mianIndices.push_back(currentVertex + 1); + mianIndices.push_back(currentVertex + 0); + mianIndices.push_back(currentVertex + 2); + mianIndices.push_back(currentVertex + 3); + currentVertex += 4; + } } } @@ -231,20 +292,41 @@ void Chunk::GenerateChunk() 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)); - - 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; + 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)); + + 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)); + + mianIndices.push_back(currentVertex + 0); + mianIndices.push_back(currentVertex + 3); + mianIndices.push_back(currentVertex + 1); + mianIndices.push_back(currentVertex + 0); + mianIndices.push_back(currentVertex + 2); + mianIndices.push_back(currentVertex + 3); + currentVertex += 4; + } } } @@ -264,52 +346,93 @@ void Chunk::GenerateChunk() 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)); - - 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; + 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)); + + 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)); + + mianIndices.push_back(currentVertex + 0); + mianIndices.push_back(currentVertex + 3); + mianIndices.push_back(currentVertex + 1); + mianIndices.push_back(currentVertex + 0); + mianIndices.push_back(currentVertex + 2); + mianIndices.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 - { - int blockIndex = x * chunkSize * chunkSize + z * chunkSize + 0; - topBlock = upData[blockIndex]; - } - - const Block* topBlockType = &Blocks::blocks[topBlock]; - - if (topBlockType->transparent) + else if (topBlockType->blockType == Block::LEAVES + || topBlockType->blockType == Block::TRANSPARENT + || topBlockType->blockType == Block::BILLBOARD + || topBlockType->blockType == Block::LIQUID) { - 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); + 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)); + + mianIndices.push_back(currentVertex + 0); + mianIndices.push_back(currentVertex + 3); + mianIndices.push_back(currentVertex + 1); + mianIndices.push_back(currentVertex + 0); + mianIndices.push_back(currentVertex + 2); + mianIndices.push_back(currentVertex + 3); currentVertex += 4; } } @@ -325,45 +448,135 @@ 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 = mianIndices.size(); + + glGenVertexArrays(1, &mainVAO); + glGenBuffers(1, &mainVBO); + glGenBuffers(1, &mainEBO); - glGenVertexArrays(1, &vertexArrayObject); - glBindVertexArray(vertexArrayObject); + glBindVertexArray(mainVAO); - glGenBuffers(1, &vbo); - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), vertices.data(), GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, mainVBO); + glBufferData(GL_ARRAY_BUFFER, mainVertices.size() * sizeof(Vertex), mainVertices.data(), GL_STATIC_DRAW); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, posX)); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mainEBO); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, mianIndices.size() * sizeof(unsigned int), mianIndices.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); + + // 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; - glGenBuffers(1, &ebo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW); + // 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; } - + return; } //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); } + +unsigned int Chunk::GetBlockAtPos(int x, int y, int z) +{ + if (!ready) + return 0; + + int index = x * chunkSize * chunkSize + z * chunkSize + y; + return chunkData[index]; +} \ No newline at end of file diff --git a/ScuffedMinecraft/src/Chunk.h b/ScuffedMinecraft/src/Chunk.h index bbf8152..1c380f2 100644 --- a/ScuffedMinecraft/src/Chunk.h +++ b/ScuffedMinecraft/src/Chunk.h @@ -4,33 +4,19 @@ #include #include -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" class Chunk { public: - Chunk(unsigned int chunkSize, glm::vec3 chunkPos); + Chunk(unsigned int chunkSize, glm::vec3 chunkPos, Shader* shader, Shader* waterShader); ~Chunk(); void GenerateChunk(); - void Render(unsigned int modelLoc); + void Render(Shader* mainShader, Shader* billboardShader); + void RenderWater(Shader* shader); + unsigned int GetBlockAtPos(int x, int y, int z); public: std::vector chunkData; @@ -39,13 +25,19 @@ class Chunk bool generated; private: - unsigned int vertexArrayObject; - unsigned int vbo, ebo; unsigned int chunkSize; - unsigned int numTriangles; glm::vec3 worldPos; std::thread chunkThread; - std::vector vertices; - std::vector indices; + std::vector mainVertices; + std::vector mianIndices; + std::vector waterVertices; + std::vector waterIndices; + std::vector billboardVertices; + std::vector billboardIndices; + + unsigned int mainVAO, waterVAO, billboardVAO; + unsigned int mainVBO, mainEBO, waterVBO, waterEBO, billboardVBO, billboardEBO; + unsigned int numTrianglesMain, numTrianglesWater, numTrianglesBillboard; + unsigned int modelLoc; }; \ No newline at end of file diff --git a/ScuffedMinecraft/src/Planet.cpp b/ScuffedMinecraft/src/Planet.cpp index 9d2d72f..8d1eb87 100644 --- a/ScuffedMinecraft/src/Planet.cpp +++ b/ScuffedMinecraft/src/Planet.cpp @@ -1,11 +1,14 @@ #include "Planet.h" #include +#include +#include Planet* Planet::planet = nullptr; // Public -Planet::Planet() +Planet::Planet(Shader* solidShader, Shader* waterShader, Shader* billboardShader) + : solidShader(solidShader), waterShader(waterShader), billboardShader(billboardShader) { } @@ -31,7 +34,7 @@ std::vector Planet::GetChunkData(int chunkX, int chunkY, int chunk } } -void Planet::Update(float camX, float camY, float camZ, unsigned int modelLoc) +void Planet::Update(float camX, float camY, float camZ) { int camChunkX = camX < 0 ? floor(camX / chunkSize) : camX / chunkSize; int camChunkY = camY < 0 ? floor(camY / chunkSize) : camY / chunkSize; @@ -132,11 +135,13 @@ void Planet::Update(float camX, float camY, float camZ, unsigned int modelLoc) if (chunks.find(chunkTuple) == chunks.end()) { chunks.try_emplace(chunkTuple, - chunkSize, next + chunkSize, next, solidShader, waterShader ); } } + glDisable(GL_BLEND); + chunksLoading = 0; numChunks = 0; numChunksRendered = 0; @@ -154,14 +159,39 @@ void Planet::Update(float camX, float camY, float camZ, unsigned int modelLoc) abs(chunkY - camChunkY) > renderDistance || abs(chunkZ - camChunkZ) > renderDistance)) { - it->second.~Chunk(); 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; + } +} + +Chunk* Planet::GetChunk(int chunkX, int chunkY, int chunkZ) +{ + std::tuple chunkTuple{ chunkX, chunkY, chunkZ }; + + if (chunks.find(chunkTuple) == chunks.end()) + { + return nullptr; + } + else + { + return &chunks.at(chunkTuple); + } } \ No newline at end of file diff --git a/ScuffedMinecraft/src/Planet.h b/ScuffedMinecraft/src/Planet.h index 97bc214..ad39d0a 100644 --- a/ScuffedMinecraft/src/Planet.h +++ b/ScuffedMinecraft/src/Planet.h @@ -13,23 +13,29 @@ class Planet { // Methods public: - Planet(); + Planet(Shader* solidShader, Shader* waterShader, Shader* billboardShader); ~Planet(); std::vector GetChunkData(int chunkX, int chunkY, int chunkZ); - void Update(float camX, float camY, float camZ, unsigned int modelLoc); + void Update(float camX, float camY, float camZ); + + Chunk* GetChunk(int chunkX, int chunkY, int chunkZ); // Variables public: static Planet* planet; unsigned int numChunks = 0, numChunksRendered = 0; + static const unsigned int chunkSize = 32; private: std::unordered_map, Chunk> chunks; std::queue chunkQueue; int renderDistance = 3; int renderHeight = 1; - unsigned int chunkSize = 32; unsigned int chunksLoading = 0; int lastCamX = -100, lastCamY = -100, lastCamZ = -100; + + Shader* solidShader; + Shader* waterShader; + Shader* billboardShader; }; \ No newline at end of file diff --git a/ScuffedMinecraft/src/Vertex.h b/ScuffedMinecraft/src/Vertex.h new file mode 100644 index 0000000..4dc83bc --- /dev/null +++ b/ScuffedMinecraft/src/Vertex.h @@ -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; + } +}; \ No newline at end of file diff --git a/ScuffedMinecraft/src/WorldGen.cpp b/ScuffedMinecraft/src/WorldGen.cpp index 87d9036..6d434a4 100644 --- a/ScuffedMinecraft/src/WorldGen.cpp +++ b/ScuffedMinecraft/src/WorldGen.cpp @@ -15,7 +15,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 +30,151 @@ void WorldGen::GenerateChunkData(int chunkX, int chunkY, int chunkZ, int chunkSi static int oreSettingsLength = sizeof(oreSettings) / sizeof(*oreSettings); static SurfaceFeature surfaceFeatures[]{ - // Tree + // Pond { - { 4.23f, 1.0f, 8.54f, .8f, 1, 0 }, - { + { 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, 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, 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, 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, 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, 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, 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, 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, + 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, + 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 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, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 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, - 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, 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, 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, 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, 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,33 +183,33 @@ void WorldGen::GenerateChunkData(int chunkX, int chunkY, int chunkZ, int chunkSi 0, -2 }, - // Grass + // Tall Grass { - { 2.65f, 1.0f, 8.54f, .5f, 1, 0 }, + { 1.23f, 1.0f, 4.34f, .6f, 1, 0 }, { - 2, 6 + 2, 7, 8 }, { - false, false + false, false, false }, 1, - 2, + 3, 1, 0, 0, 0 }, - // Tall Grass + // Grass { - { 1.23f, 1.0f, 4.34f, .6f, 1, 0 }, + { 2.65f, 1.0f, 8.54f, .5f, 1, 0 }, { - 2, 7, 8 + 2, 6 }, { - false, false, false + false, false }, 1, - 3, + 2, 1, 0, 0, @@ -201,6 +282,8 @@ void WorldGen::GenerateChunkData(int chunkX, int chunkY, int chunkZ, int chunkSi }; static int surfaceFeaturesLength = sizeof(surfaceFeatures) / sizeof(*surfaceFeatures); + static int waterLevel = 20; + // Set vector size chunkData->reserve(chunkSize * chunkSize * chunkSize); @@ -249,9 +332,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->push_back(Blocks::WATER); + else + chunkData->push_back(Blocks::AIR); + } else if (cave) - chunkData->push_back(0); + chunkData->push_back(Blocks::AIR); // Ground else { @@ -307,6 +395,10 @@ void WorldGen::GenerateChunkData(int chunkX, int chunkY, int chunkZ, int chunkSi if (noiseY + surfaceFeatures[i].offsetY > startY + 32 || noiseY + surfaceFeatures[i].sizeY + surfaceFeatures[i].offsetY < startY) continue; + + // Check if it's in water + if (noiseY < waterLevel) + continue; // Check if it's in a cave bool cave = false; @@ -361,9 +453,9 @@ void WorldGen::GenerateChunkData(int chunkX, int chunkY, int chunkZ, int chunkSi if (localZ >= 32 || 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'; @@ -373,11 +465,6 @@ void WorldGen::GenerateChunkData(int chunkX, int chunkY, int chunkZ, int chunkSi } } } - - //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; } } }