remove inner blocks when rendering #5

Merged
pointer-to-bios merged 1 commits from main into render_demo 2024-04-29 22:57:32 +08:00
11 changed files with 131 additions and 74 deletions

View File

@ -2,9 +2,10 @@
#define UI_H #define UI_H
#include "world.h" #include "world.h"
#include "ui/camera.h"
int player_ui( int player_ui(
std::vector<WorldRequire> &require_pipe, std::mutex &require_pipe_lock, 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 #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, 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, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.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)};

View File

@ -1,6 +1,7 @@
#ifndef WORLD_H #ifndef WORLD_H
#define WORLD_H #define WORLD_H
#include "ui/camera.h"
#include "world/trunk.h" #include "world/trunk.h"
#include "world/block.h" #include "world/block.h"
#include <vector> #include <vector>
@ -15,6 +16,6 @@ enum WorldRequire
void world_simulator(std::vector<WorldRequire> &require_pipe, std::mutex &require_pipe_lock, 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 #endif

View File

@ -6,9 +6,9 @@
enum BlockType enum BlockType
{ {
Air, AirBlock,
Soil, SoilBlock,
Grass, GrassBlock,
}; };
enum BlockFacing enum BlockFacing
@ -25,7 +25,7 @@ enum BlockFacing
class Block class Block
{ {
public: 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) void set_type(BlockType type)
{ {
@ -43,7 +43,7 @@ private:
}; };
#ifndef WORLD #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
#endif #endif

View File

@ -2,6 +2,8 @@
#define TRUNK_H #define TRUNK_H
#include <glm/glm.hpp> #include <glm/glm.hpp>
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/intersect.hpp>
#include <vector> #include <vector>
#include <tuple> #include <tuple>
@ -14,31 +16,106 @@ const int TrunkSizeZ = 32;
class Trunk class Trunk
{ {
public: public:
Trunk() Trunk(long long x, long long z) : trunk_locx(x), trunk_locz(z)
{ {
for (int i = 0; i < TrunkSizeX; i++) for (int i = 0; i < TrunkSizeX; i++)
for (int j = 0; j < 61; j++) for (int j = 0; j < 61; j++)
for (int k = 0; k < TrunkSizeZ; k++) for (int k = 0; k < TrunkSizeZ; k++)
if (j < 60) if (j < 60)
blocks[i][j][k].set_type(BlockType::Soil); blocks[i][j][k].set_type(BlockType::SoilBlock);
else 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; static std::vector<std::tuple<glm::ivec3, Block &>> res;
res.clear(); res.clear();
for (int i = 0; i < TrunkSizeX; i++) for (int i = 0; i < TrunkSizeX; i++)
for (int j = 0; j < TrunkSizeY; j++) for (int j = 0; j < TrunkSizeY; j++)
for (int k = 0; k < TrunkSizeZ; k++) 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])); res.push_back(std::tuple<glm::ivec3, Block &>({i, j, k}, blocks[i][j][k]));
}
return res; return res;
} }
private: private:
Block blocks[TrunkSizeX][TrunkSizeY][TrunkSizeZ]; 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 #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 <iostream>
#include <vector> #include <vector>
#include "ui.h" #include "ui.h"
#include "ui/camera.h"
#include "world.h" #include "world.h"
int main() int main()
@ -12,20 +13,22 @@ int main()
std::vector<std::vector<std::tuple<glm::ivec3, Block &>>> blocks_pipe; std::vector<std::vector<std::tuple<glm::ivec3, Block &>>> blocks_pipe;
std::mutex blocks_pipe_lock; std::mutex blocks_pipe_lock;
Camera camera(glm::vec3(0.0f, 63.0f, 0.0f));
// 启动ui渲染线程 // 启动ui渲染线程
std::promise<int> ui_prom; std::promise<int> ui_prom;
std::future<int> ui_future = ui_prom.get_future(); std::future<int> ui_future = ui_prom.get_future();
std::thread ui( 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); }); ui_prom.set_value(res); });
// 启动世界模拟器线程 // 启动世界模拟器线程
std::thread world_sim( 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(); 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 mouse_callback(GLFWwindow *window, double xpos, double ypos);
void scroll_callback(GLFWwindow *window, double xoffset, double yoffset); void scroll_callback(GLFWwindow *window, double xoffset, double yoffset);
void focus_callback(GLFWwindow *window, int focused); void focus_callback(GLFWwindow *window, int focused);
void processInput(GLFWwindow *window); void processInput(GLFWwindow *window, Camera &camera);
void glfwDump(GLFWwindow *window); void glfwDump(GLFWwindow *window);
@ -35,7 +35,7 @@ const unsigned int SCR_WIDTH = 1920;
const unsigned int SCR_HEIGHT = 1080; const unsigned int SCR_HEIGHT = 1080;
// camera // camera
Camera camera(glm::vec3(0.0f, 63.0f, 0.0f)); Camera *camera_glb;
float lastX = SCR_WIDTH / 2.0f; float lastX = SCR_WIDTH / 2.0f;
float lastY = SCR_HEIGHT / 2.0f; float lastY = SCR_HEIGHT / 2.0f;
bool firstMouse = true; bool firstMouse = true;
@ -59,8 +59,9 @@ GLFWimage icon;
int player_ui( int player_ui(
std::vector<WorldRequire> &require_pipe, std::mutex &require_pipe_lock, 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__ #ifdef __linux__
nativeSetIcon(); nativeSetIcon();
#endif #endif
@ -190,7 +191,7 @@ int player_ui(
// input // input
// ----- // -----
processInput(window); processInput(window, camera);
// render // render
// ------ // ------
@ -211,24 +212,14 @@ int player_ui(
// render opaque objects first // render opaque objects first
glBindVertexArray(VAO); 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_lock.lock();
require_pipe.push_back(WorldRequire::BlockReq); require_pipe.push_back(WorldRequire::BlockReq);
require_pipe_lock.unlock(); 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(); blocks_pipe_lock.lock();
if (!blocks_pipe.empty()) if (!blocks_pipe.empty())
{ {
blks.clear();
blks = blocks_pipe.back(); blks = blocks_pipe.back();
blocks_pipe.pop_back(); blocks_pipe.pop_back();
} }
@ -236,11 +227,16 @@ int player_ui(
for (auto block : blks) for (auto block : blks)
{ {
auto loc = std::get<0>(block); auto loc = std::get<0>(block);
ourShader.setIVec2("index", block_type_texture_table[std::get<1>(block).get_type()]);
glm::mat4 model(1.0f); glm::mat4 model(1.0f);
model = glm::translate(model, glm::vec3(loc)); model = glm::translate(model, glm::vec3(loc));
ourShader.setMat4("model", model); 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.) // 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 // process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// --------------------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------------------
bool ESC_KEY_PRESSED = false; bool ESC_KEY_PRESSED = false;
void processInput(GLFWwindow *window) void processInput(GLFWwindow *window, Camera &camera)
{ {
int esc_key_evetype = glfwGetKey(window, GLFW_KEY_ESCAPE); int esc_key_evetype = glfwGetKey(window, GLFW_KEY_ESCAPE);
if (!ESC_KEY_PRESSED && esc_key_evetype == GLFW_PRESS) if (!ESC_KEY_PRESSED && esc_key_evetype == GLFW_PRESS)
@ -361,14 +357,14 @@ void mouse_callback(GLFWwindow *window, double xposIn, double yposIn)
lastX = xpos; lastX = xpos;
lastY = ypos; lastY = ypos;
camera.ProcessMouseMovement(xoffset, yoffset); camera_glb->ProcessMouseMovement(xoffset, yoffset);
} }
// glfw: whenever the mouse scroll wheel scrolls, this callback is called // glfw: whenever the mouse scroll wheel scrolls, this callback is called
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
void scroll_callback(GLFWwindow *window, double xoffset, double yoffset) 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) void focus_callback(GLFWwindow *window, int focused)

View File

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