remove inner blocks when rendering

This commit is contained in:
pointer-to-bios 2024-04-29 21:06:15 +08:00
parent 5c655135b0
commit 6a69fee686
11 changed files with 131 additions and 74 deletions

View File

@ -2,9 +2,10 @@
#define UI_H
#include "world.h"
#include "ui/camera.h"
int player_ui(
std::vector<WorldRequire> &require_pipe, std::mutex &require_pipe_lock,
std::vector<std::vector<std::tuple<glm::ivec3, Block &>>> &blocks_pipe, std::mutex &blocks_pipe_lock);
std::vector<std::vector<std::tuple<glm::ivec3, Block &>>> &blocks_pipe, std::mutex &blocks_pipe_lock, Camera &camera);
#endif

View File

@ -52,30 +52,5 @@ float vertices[] = {
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f};
// world space positions of our cubes
glm::ivec3 cubePositions[] = {
glm::ivec3(0, 0, 0),
glm::ivec3(0, 0, 1),
glm::ivec3(0, 0, 2),
glm::ivec3(0, 0, 3),
glm::ivec3(0, 0, 4),
glm::ivec3(0, 0, 5),
glm::ivec3(0, 0, 6),
glm::ivec3(0, 0, 7),
glm::ivec3(0, 0, 8),
glm::ivec3(0, 0, 9)};
glm::ivec2 cubeTextures[] = {
glm::ivec2(1, 12),
glm::ivec2(1, 11),
glm::ivec2(1, 10),
glm::ivec2(1, 9),
glm::ivec2(1, 8),
glm::ivec2(1, 7),
glm::ivec2(1, 6),
glm::ivec2(1, 5),
glm::ivec2(1, 4),
glm::ivec2(1, 0)};
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f
};

View File

@ -1,6 +1,7 @@
#ifndef WORLD_H
#define WORLD_H
#include "ui/camera.h"
#include "world/trunk.h"
#include "world/block.h"
#include <vector>
@ -15,6 +16,6 @@ enum WorldRequire
void world_simulator(std::vector<WorldRequire> &require_pipe, std::mutex &require_pipe_lock,
std::vector<std::vector<std::tuple<glm::ivec3, Block &>>> &blocks_pipe, std::mutex &blocks_pipe_lock);
std::vector<std::vector<std::tuple<glm::ivec3, Block &>>> &blocks_pipe, std::mutex &blocks_pipe_lock, Camera &camera);
#endif

View File

@ -6,9 +6,9 @@
enum BlockType
{
Air,
Soil,
Grass,
AirBlock,
SoilBlock,
GrassBlock,
};
enum BlockFacing
@ -25,7 +25,7 @@ enum BlockFacing
class Block
{
public:
Block(BlockType type = BlockType::Air, BlockFacing facing = BlockFacing::FacingNone) : type(type), facing(facing) {}
Block(BlockType type = BlockType::AirBlock, BlockFacing facing = BlockFacing::FacingNone) : type(type), facing(facing) {}
void set_type(BlockType type)
{
@ -43,7 +43,7 @@ private:
};
#ifndef WORLD
extern std::map<BlockType, glm::ivec2> block_type_texture_table;
extern std::map<BlockType, std::vector<glm::ivec2>> block_type_texture_table;
#endif
#endif

View File

@ -2,6 +2,8 @@
#define TRUNK_H
#include <glm/glm.hpp>
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/intersect.hpp>
#include <vector>
#include <tuple>
@ -14,31 +16,106 @@ const int TrunkSizeZ = 32;
class Trunk
{
public:
Trunk()
Trunk(long long x, long long z) : trunk_locx(x), trunk_locz(z)
{
for (int i = 0; i < TrunkSizeX; i++)
for (int j = 0; j < 61; j++)
for (int k = 0; k < TrunkSizeZ; k++)
if (j < 60)
blocks[i][j][k].set_type(BlockType::Soil);
blocks[i][j][k].set_type(BlockType::SoilBlock);
else
blocks[i][j][k].set_type(BlockType::Grass);
blocks[i][j][k].set_type(BlockType::GrassBlock);
}
std::vector<std::tuple<glm::ivec3, Block &>> &getBlockList()
std::vector<std::tuple<glm::ivec3, Block &>> &getBlockList(glm::vec3 &camera_pos, glm::vec3 &camera_facing)
{
static std::vector<std::tuple<glm::ivec3, Block &>> res;
res.clear();
for (int i = 0; i < TrunkSizeX; i++)
for (int j = 0; j < TrunkSizeY; j++)
for (int k = 0; k < TrunkSizeZ; k++)
if (blocks[i][j][k].get_type() != BlockType::Air)
if (blocks[i][j][k].get_type() != BlockType::AirBlock)
{
glm::ivec3 worldp(i + trunk_locx, j, k + trunk_locz);
if (!blockInFront(worldp, camera_pos, camera_facing))
continue;
std::vector<glm::ivec3> surrs{
glm::ivec3(worldp.x + 1, worldp.y, worldp.z),
glm::ivec3(worldp.x - 1, worldp.y, worldp.z),
glm::ivec3(worldp.x, worldp.y + 1, worldp.z),
glm::ivec3(worldp.x, worldp.y - 1, worldp.z),
glm::ivec3(worldp.x, worldp.y, worldp.z + 1),
glm::ivec3(worldp.x, worldp.y, worldp.z - 1)};
if (!blockOnTheSurface(worldp, surrs))
continue;
res.push_back(std::tuple<glm::ivec3, Block &>({i, j, k}, blocks[i][j][k]));
}
return res;
}
private:
Block blocks[TrunkSizeX][TrunkSizeY][TrunkSizeZ];
const int trunk_locx;
const int trunk_locz;
bool in_trunk(glm::ivec3 block)
{
return block.x >= 0 && block.x < TrunkSizeX && block.y >= 0 && block.y < TrunkSizeY && block.z >= 0 && block.z < TrunkSizeZ;
}
bool blockOnTheSurface(glm::ivec3 tblock, std::vector<glm::ivec3> surr_blocks)
{
bool res = false;
for (auto block : surr_blocks)
{
if (!in_trunk(block))
{
if (block.y >= 0)
{
res = true;
break;
}
else
{
continue;
}
}
if (blocks[block.x][block.y][block.z].get_type() == BlockType::AirBlock)
{
res = true;
break;
}
}
return res;
}
bool blockInFront(glm::ivec3 block, glm::vec3 &camera_pos, glm::vec3 &camera_facing)
{
glm::vec3 p1(block.x, block.y, block.z);
glm::vec3 p2(block.x + 1, block.y, block.z);
glm::vec3 p3(block.x, block.y, block.z + 1);
glm::vec3 p4(block.x + 1, block.y, block.z + 1);
glm::vec3 p5(block.x, block.y + 1, block.z);
glm::vec3 p6(block.x + 1, block.y + 1, block.z);
glm::vec3 p7(block.x, block.y + 1, block.z + 1);
glm::vec3 p8(block.x + 1, block.y + 1, block.z + 1);
return (isVisible(p1, camera_pos, camera_facing) ||
isVisible(p2, camera_pos, camera_facing) ||
isVisible(p3, camera_pos, camera_facing) ||
isVisible(p4, camera_pos, camera_facing) ||
isVisible(p5, camera_pos, camera_facing) ||
isVisible(p6, camera_pos, camera_facing) ||
isVisible(p7, camera_pos, camera_facing) ||
isVisible(p8, camera_pos, camera_facing));
}
bool isVisible(glm::vec3 &point, glm::vec3 &camera_pos, glm::vec3 &camera_facing)
{
glm::vec3 cam2p = point - camera_pos;
float prod = glm::dot(camera_facing, cam2p);
// If the vertex out of camera
return prod > 0;
}
};
#endif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 84 KiB

View File

@ -3,6 +3,7 @@
#include <iostream>
#include <vector>
#include "ui.h"
#include "ui/camera.h"
#include "world.h"
int main()
@ -12,20 +13,22 @@ int main()
std::vector<std::vector<std::tuple<glm::ivec3, Block &>>> blocks_pipe;
std::mutex blocks_pipe_lock;
Camera camera(glm::vec3(0.0f, 63.0f, 0.0f));
// 启动ui渲染线程
std::promise<int> ui_prom;
std::future<int> ui_future = ui_prom.get_future();
std::thread ui(
[&ui_prom, &require_pipe, &require_pipe_lock, &blocks_pipe, &blocks_pipe_lock]()
[&ui_prom, &require_pipe, &require_pipe_lock, &blocks_pipe, &blocks_pipe_lock, &camera]()
{
int res = player_ui(require_pipe, require_pipe_lock, blocks_pipe, blocks_pipe_lock);
int res = player_ui(require_pipe, require_pipe_lock, blocks_pipe, blocks_pipe_lock, camera);
ui_prom.set_value(res); });
// 启动世界模拟器线程
std::thread world_sim(
[&require_pipe, &require_pipe_lock, &blocks_pipe, &blocks_pipe_lock]()
[&require_pipe, &require_pipe_lock, &blocks_pipe, &blocks_pipe_lock, &camera]()
{
world_simulator(require_pipe, require_pipe_lock, blocks_pipe, blocks_pipe_lock);
world_simulator(require_pipe, require_pipe_lock, blocks_pipe, blocks_pipe_lock, camera);
});
ui.join();

View File

@ -22,7 +22,7 @@ void framebuffer_size_callback(GLFWwindow *window, int width, int height);
void mouse_callback(GLFWwindow *window, double xpos, double ypos);
void scroll_callback(GLFWwindow *window, double xoffset, double yoffset);
void focus_callback(GLFWwindow *window, int focused);
void processInput(GLFWwindow *window);
void processInput(GLFWwindow *window, Camera &camera);
void glfwDump(GLFWwindow *window);
@ -35,7 +35,7 @@ const unsigned int SCR_WIDTH = 1920;
const unsigned int SCR_HEIGHT = 1080;
// camera
Camera camera(glm::vec3(0.0f, 63.0f, 0.0f));
Camera *camera_glb;
float lastX = SCR_WIDTH / 2.0f;
float lastY = SCR_HEIGHT / 2.0f;
bool firstMouse = true;
@ -59,8 +59,9 @@ GLFWimage icon;
int player_ui(
std::vector<WorldRequire> &require_pipe, std::mutex &require_pipe_lock,
std::vector<std::vector<std::tuple<glm::ivec3, Block &>>> &blocks_pipe, std::mutex &blocks_pipe_lock)
std::vector<std::vector<std::tuple<glm::ivec3, Block &>>> &blocks_pipe, std::mutex &blocks_pipe_lock, Camera &camera)
{
camera_glb = &camera;
#ifdef __linux__
nativeSetIcon();
#endif
@ -190,7 +191,7 @@ int player_ui(
// input
// -----
processInput(window);
processInput(window, camera);
// render
// ------
@ -211,24 +212,14 @@ int player_ui(
// render opaque objects first
glBindVertexArray(VAO);
/*for (unsigned int i = 0; i < 10; i++)
{
ourShader.setIVec2("index", cubeTextures[i]);
// calculate the model matrix for each object and pass it to shader before drawing
glm::mat4 model = glm::mat4(1.0f); // make sure to initialize matrix to identity matrix first
model = glm::translate(model, glm::vec3(cubePositions[i]));
ourShader.setMat4("model", model);
glDrawArrays(GL_TRIANGLES, 0, 36);
}*/
require_pipe_lock.lock();
require_pipe.push_back(WorldRequire::BlockReq);
require_pipe_lock.unlock();
std::vector<std::tuple<glm::ivec3, Block &>> blks;
static std::vector<std::tuple<glm::ivec3, Block &>> blks;
blocks_pipe_lock.lock();
if (!blocks_pipe.empty())
{
blks.clear();
blks = blocks_pipe.back();
blocks_pipe.pop_back();
}
@ -236,11 +227,16 @@ int player_ui(
for (auto block : blks)
{
auto loc = std::get<0>(block);
ourShader.setIVec2("index", block_type_texture_table[std::get<1>(block).get_type()]);
glm::mat4 model(1.0f);
model = glm::translate(model, glm::vec3(loc));
ourShader.setMat4("model", model);
glDrawArrays(GL_TRIANGLES, 0, 36);
int ind = 0;
for (auto pic : block_type_texture_table[std::get<1>(block).get_type()])
{
ourShader.setIVec2("index", pic);
glDrawArrays(GL_TRIANGLES, ind * 6, 6);
ind++;
}
}
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
@ -272,7 +268,7 @@ int player_ui(
// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
bool ESC_KEY_PRESSED = false;
void processInput(GLFWwindow *window)
void processInput(GLFWwindow *window, Camera &camera)
{
int esc_key_evetype = glfwGetKey(window, GLFW_KEY_ESCAPE);
if (!ESC_KEY_PRESSED && esc_key_evetype == GLFW_PRESS)
@ -361,14 +357,14 @@ void mouse_callback(GLFWwindow *window, double xposIn, double yposIn)
lastX = xpos;
lastY = ypos;
camera.ProcessMouseMovement(xoffset, yoffset);
camera_glb->ProcessMouseMovement(xoffset, yoffset);
}
// glfw: whenever the mouse scroll wheel scrolls, this callback is called
// ----------------------------------------------------------------------
void scroll_callback(GLFWwindow *window, double xoffset, double yoffset)
{
camera.ProcessMouseScroll(static_cast<float>(yoffset));
camera_glb->ProcessMouseScroll(static_cast<float>(yoffset));
}
void focus_callback(GLFWwindow *window, int focused)

View File

@ -1,17 +1,15 @@
#define WORLD
#include "world.h"
#include <iostream>
std::map<BlockType, glm::ivec2> block_type_texture_table{
std::make_pair(BlockType::Soil, glm::ivec2(2, 15)),
std::make_pair(BlockType::Grass, glm::ivec2(3, 15)),
};
#include <vector>
#include <chrono>
#include <thread>
void world_simulator(
std::vector<WorldRequire> &require_pipe, std::mutex &require_pipe_lock,
std::vector<std::vector<std::tuple<glm::ivec3, Block &>>> &blocks_pipe, std::mutex &blocks_pipe_lock)
std::vector<std::vector<std::tuple<glm::ivec3, Block &>>> &blocks_pipe, std::mutex &blocks_pipe_lock, Camera &camera)
{
Trunk trunk000;
Trunk trunk000(0, 0);
bool ends = false;
while (true)
{
@ -29,7 +27,7 @@ void world_simulator(
switch (wreq)
{
case BlockReq:
list = &trunk000.getBlockList();
list = &trunk000.getBlockList(camera.Position, camera.Front);
blocks_pipe_lock.lock();
blocks_pipe.push_back(*list);
blocks_pipe_lock.unlock();
@ -40,5 +38,11 @@ void world_simulator(
}
if (ends)
break;
std::this_thread::sleep_for(std::chrono::milliseconds(4));
}
}
std::map<BlockType, std::vector<glm::ivec2>> block_type_texture_table{
std::make_pair(BlockType::SoilBlock, std::vector{glm::ivec2(2, 15), glm::ivec2(2, 15), glm::ivec2(2, 15), glm::ivec2(2, 15), glm::ivec2(2, 15), glm::ivec2(2, 15)}),
std::make_pair(BlockType::GrassBlock, std::vector{glm::ivec2(3, 15), glm::ivec2(3, 15), glm::ivec2(3, 15), glm::ivec2(3, 15), glm::ivec2(2, 15), glm::ivec2(9, 6)}),
};