*
This commit is contained in:
@@ -17,8 +17,8 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections") # -rdy
|
|||||||
# set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg")
|
# set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg")
|
||||||
|
|
||||||
# sanitizer
|
# sanitizer
|
||||||
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
|
||||||
# set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
|
||||||
|
|
||||||
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fno-sanitize=null -fno-sanitize=alignment")
|
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fno-sanitize=null -fno-sanitize=alignment")
|
||||||
|
|
||||||
|
|||||||
@@ -199,10 +199,10 @@ void VulkanRenderSession::init(Vulkan *instance) {
|
|||||||
int width, height;
|
int width, height;
|
||||||
bool hasAlpha;
|
bool hasAlpha;
|
||||||
for(const char *path : {
|
for(const char *path : {
|
||||||
//"tropical_rainforest_wood.png",
|
|
||||||
"grass.png",
|
"grass.png",
|
||||||
|
"tropical_rainforest_wood.png",
|
||||||
"willow_wood.png",
|
"willow_wood.png",
|
||||||
//"xnether_blue_wood.png",
|
"xnether_blue_wood.png",
|
||||||
"xnether_purple_wood.png"
|
"xnether_purple_wood.png"
|
||||||
}) {
|
}) {
|
||||||
ByteBuffer image = VK::loadPNG(getResource(std::string("textures/") + path)->makeStream().Stream, width, height, hasAlpha);
|
ByteBuffer image = VK::loadPNG(getResource(std::string("textures/") + path)->makeStream().Stream, width, height, hasAlpha);
|
||||||
@@ -619,28 +619,41 @@ void VulkanRenderSession::onChunksChange(WorldId_t worldId, const std::unordered
|
|||||||
Pos::GlobalRegion rPos = pos >> 4;
|
Pos::GlobalRegion rPos = pos >> 4;
|
||||||
Pos::bvec16u cPos = pos & 0xf;
|
Pos::bvec16u cPos = pos & 0xf;
|
||||||
|
|
||||||
const auto &voxels = ServerSession->Data.Worlds[worldId].Regions[rPos].Chunks[cPos.x][cPos.y][cPos.z].Voxels;
|
auto &buffers = table[pos];
|
||||||
|
|
||||||
if(voxels.empty()) {
|
const auto &chunk = ServerSession->Data.Worlds[worldId].Regions[rPos].Chunks[cPos.x][cPos.y][cPos.z];
|
||||||
auto iter = table.find(pos);
|
|
||||||
if(iter != table.end())
|
if(chunk.Voxels.empty()) {
|
||||||
table.erase(iter);
|
std::get<0>(buffers) = nullptr;
|
||||||
} else {
|
} else {
|
||||||
Logger("Test").debug() << voxels.size();
|
std::vector<VoxelVertexPoint> vertexs = generateMeshForVoxelChunks(chunk.Voxels);
|
||||||
std::vector<VoxelVertexPoint> vertexs = generateMeshForVoxelChunks(voxels);
|
|
||||||
Logger("Test").debug() << vertexs.size();
|
|
||||||
|
|
||||||
if(!vertexs.empty()) {
|
if(!vertexs.empty()) {
|
||||||
auto &buffer = table[pos] = std::make_unique<Buffer>(VkInst, vertexs.size()*sizeof(VoxelVertexPoint));
|
auto &voxels = std::get<0>(buffers);
|
||||||
std::copy(vertexs.data(), vertexs.data()+vertexs.size(), (VoxelVertexPoint*) buffer->mapMemory());
|
voxels = std::make_unique<Buffer>(VkInst, vertexs.size()*sizeof(VoxelVertexPoint));
|
||||||
buffer->unMapMemory();
|
std::copy(vertexs.data(), vertexs.data()+vertexs.size(), (VoxelVertexPoint*) voxels->mapMemory());
|
||||||
|
voxels->unMapMemory();
|
||||||
} else {
|
} else {
|
||||||
|
std::get<0>(buffers) = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<NodeVertexStatic> vertexs2 = generateMeshForNodeChunks(chunk.Nodes);
|
||||||
|
if(vertexs2.empty()) {
|
||||||
|
std::get<1>(buffers) = nullptr;
|
||||||
|
} else {
|
||||||
|
auto &nodes = std::get<1>(buffers);
|
||||||
|
nodes = std::make_unique<Buffer>(VkInst, vertexs2.size()*sizeof(NodeVertexStatic));
|
||||||
|
std::copy(vertexs2.data(), vertexs2.data()+vertexs2.size(), (NodeVertexStatic*) nodes->mapMemory());
|
||||||
|
nodes->unMapMemory();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!std::get<0>(buffers) && !std::get<1>(buffers)) {
|
||||||
auto iter = table.find(pos);
|
auto iter = table.find(pos);
|
||||||
if(iter != table.end())
|
if(iter != table.end())
|
||||||
table.erase(iter);
|
table.erase(iter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for(Pos::GlobalRegion pos : remove) {
|
for(Pos::GlobalRegion pos : remove) {
|
||||||
for(int z = 0; z < 4; z++)
|
for(int z = 0; z < 4; z++)
|
||||||
@@ -725,14 +738,45 @@ void VulkanRenderSession::drawWorld(GlobalTime gTime, float dTime, VkCommandBuff
|
|||||||
glm::mat4 orig = PCO.Model;
|
glm::mat4 orig = PCO.Model;
|
||||||
|
|
||||||
for(auto &pair : iterWorld->second) {
|
for(auto &pair : iterWorld->second) {
|
||||||
|
if(auto& voxels = std::get<0>(pair.second)) {
|
||||||
glm::vec3 cpos(pair.first.x, pair.first.y, pair.first.z);
|
glm::vec3 cpos(pair.first.x, pair.first.y, pair.first.z);
|
||||||
PCO.Model = glm::translate(orig, cpos*16.f);
|
PCO.Model = glm::translate(orig, cpos*16.f);
|
||||||
vkBuffer = *pair.second;
|
vkBuffer = *voxels;
|
||||||
|
|
||||||
vkCmdPushConstants(drawCmd, MainAtlas_LightMap_PipelineLayout,
|
vkCmdPushConstants(drawCmd, MainAtlas_LightMap_PipelineLayout,
|
||||||
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_GEOMETRY_BIT, offsetof(WorldPCO, Model), sizeof(WorldPCO::Model), &PCO.Model);
|
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_GEOMETRY_BIT, offsetof(WorldPCO, Model), sizeof(WorldPCO::Model), &PCO.Model);
|
||||||
vkCmdBindVertexBuffers(drawCmd, 0, 1, &vkBuffer, &vkOffsets);
|
vkCmdBindVertexBuffers(drawCmd, 0, 1, &vkBuffer, &vkOffsets);
|
||||||
vkCmdDraw(drawCmd, pair.second->getSize() / sizeof(VoxelVertexPoint), 1, 0, 0);
|
vkCmdDraw(drawCmd, voxels->getSize() / sizeof(VoxelVertexPoint), 1, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PCO.Model = orig;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vkCmdBindPipeline(drawCmd, VK_PIPELINE_BIND_POINT_GRAPHICS, NodeStaticOpaquePipeline);
|
||||||
|
vkCmdPushConstants(drawCmd, MainAtlas_LightMap_PipelineLayout,
|
||||||
|
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_GEOMETRY_BIT, 0, sizeof(WorldPCO), &PCO);
|
||||||
|
vkCmdBindDescriptorSets(drawCmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||||
|
MainAtlas_LightMap_PipelineLayout, 0, 2,
|
||||||
|
(const VkDescriptorSet[]) {MainAtlasDescriptor, VoxelLightMapDescriptor}, 0, nullptr);
|
||||||
|
|
||||||
|
{
|
||||||
|
auto iterWorld = External.ChunkVoxelMesh.find(WorldId);
|
||||||
|
if(iterWorld != External.ChunkVoxelMesh.end()) {
|
||||||
|
glm::mat4 orig = PCO.Model;
|
||||||
|
|
||||||
|
for(auto &pair : iterWorld->second) {
|
||||||
|
if(auto& nodes = std::get<1>(pair.second)) {
|
||||||
|
glm::vec3 cpos(pair.first.x, pair.first.y, pair.first.z);
|
||||||
|
PCO.Model = glm::translate(orig, cpos*16.f);
|
||||||
|
vkBuffer = *nodes;
|
||||||
|
|
||||||
|
vkCmdPushConstants(drawCmd, MainAtlas_LightMap_PipelineLayout,
|
||||||
|
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_GEOMETRY_BIT, offsetof(WorldPCO, Model), sizeof(WorldPCO::Model), &PCO.Model);
|
||||||
|
vkCmdBindVertexBuffers(drawCmd, 0, 1, &vkBuffer, &vkOffsets);
|
||||||
|
vkCmdDraw(drawCmd, nodes->getSize() / sizeof(NodeVertexStatic), 1, 0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PCO.Model = orig;
|
PCO.Model = orig;
|
||||||
@@ -827,6 +871,57 @@ std::vector<VoxelVertexPoint> VulkanRenderSession::generateMeshForVoxelChunks(co
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<NodeVertexStatic> VulkanRenderSession::generateMeshForNodeChunks(const Node nodes[16][16][16]) {
|
||||||
|
std::vector<NodeVertexStatic> out;
|
||||||
|
NodeVertexStatic v;
|
||||||
|
|
||||||
|
for(int z = 0; z < 16; z++)
|
||||||
|
for(int y = 0; y < 16; y++)
|
||||||
|
for(int x = 0; x < 16; x++)
|
||||||
|
{
|
||||||
|
if(nodes[x][y][z].Data == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
v.Tex = nodes[x][y][z].NodeId;
|
||||||
|
|
||||||
|
if((y+1) < 16 || nodes[x][y+1][z].NodeId != 0) {
|
||||||
|
v.FX = 135+x*16;
|
||||||
|
v.FY = 135+y*16+16;
|
||||||
|
v.FZ = 135+z*16;
|
||||||
|
v.TU = 0;
|
||||||
|
v.TV = 0;
|
||||||
|
out.push_back(v);
|
||||||
|
|
||||||
|
v.FX += 15;
|
||||||
|
v.TU = 65535;
|
||||||
|
out.push_back(v);
|
||||||
|
|
||||||
|
v.FZ += 15;
|
||||||
|
v.TV = 65535;
|
||||||
|
out.push_back(v);
|
||||||
|
|
||||||
|
v.FX = 135+x*16;
|
||||||
|
v.FY = 135+y*16+16;
|
||||||
|
v.FZ = 135+z*16;
|
||||||
|
v.TU = 0;
|
||||||
|
v.TV = 0;
|
||||||
|
out.push_back(v);
|
||||||
|
|
||||||
|
v.FX += 15;
|
||||||
|
v.FZ += 15;
|
||||||
|
v.TV = 65535;
|
||||||
|
v.TU = 65535;
|
||||||
|
out.push_back(v);
|
||||||
|
|
||||||
|
v.FX -= 15;
|
||||||
|
v.TV = 0;
|
||||||
|
out.push_back(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
void VulkanRenderSession::updateDescriptor_MainAtlas() {
|
void VulkanRenderSession::updateDescriptor_MainAtlas() {
|
||||||
VkDescriptorBufferInfo bufferInfo = VKCTX->MainTest;
|
VkDescriptorBufferInfo bufferInfo = VKCTX->MainTest;
|
||||||
VkDescriptorImageInfo imageInfo = VKCTX->MainTest;
|
VkDescriptorImageInfo imageInfo = VKCTX->MainTest;
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ struct VoxelVertexPoint {
|
|||||||
|
|
||||||
struct NodeVertexStatic {
|
struct NodeVertexStatic {
|
||||||
uint32_t
|
uint32_t
|
||||||
FX : 9, FY : 9, FZ : 9, // Позиция -112 ~ 369 / 16
|
FX : 9, FY : 9, FZ : 9, // Позиция 15 -120 ~ 240 360 15 / 16
|
||||||
N1 : 4, // Не занято
|
N1 : 4, // Не занято
|
||||||
LS : 1, // Масштаб карты освещения (1м/16 или 1м)
|
LS : 1, // Масштаб карты освещения (1м/16 или 1м)
|
||||||
Tex : 18, // Текстура
|
Tex : 18, // Текстура
|
||||||
@@ -133,7 +133,11 @@ class VulkanRenderSession : public IRenderSession, public IVulkanDependent {
|
|||||||
std::map<BinTextureId_t, uint16_t> ServerToAtlas;
|
std::map<BinTextureId_t, uint16_t> ServerToAtlas;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
std::unordered_map<WorldId_t, std::unordered_map<Pos::GlobalChunk, std::unique_ptr<Buffer>>> ChunkVoxelMesh;
|
std::unordered_map<WorldId_t,
|
||||||
|
std::unordered_map<Pos::GlobalChunk,
|
||||||
|
std::pair<std::unique_ptr<Buffer>, std::unique_ptr<Buffer>> // Voxels, Nodes
|
||||||
|
>
|
||||||
|
> ChunkVoxelMesh;
|
||||||
} External;
|
} External;
|
||||||
|
|
||||||
virtual void free(Vulkan *instance) override;
|
virtual void free(Vulkan *instance) override;
|
||||||
@@ -166,6 +170,7 @@ public:
|
|||||||
void drawWorld(GlobalTime gTime, float dTime, VkCommandBuffer drawCmd);
|
void drawWorld(GlobalTime gTime, float dTime, VkCommandBuffer drawCmd);
|
||||||
|
|
||||||
static std::vector<VoxelVertexPoint> generateMeshForVoxelChunks(const std::vector<VoxelCube> cubes);
|
static std::vector<VoxelVertexPoint> generateMeshForVoxelChunks(const std::vector<VoxelCube> cubes);
|
||||||
|
static std::vector<NodeVertexStatic> generateMeshForNodeChunks(const Node nodes[16][16][16]);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateDescriptor_MainAtlas();
|
void updateDescriptor_MainAtlas();
|
||||||
|
|||||||
@@ -741,7 +741,6 @@ IWorldSaveBackend::TickSyncInfo_Out GameServer::stepDatabaseSync() {
|
|||||||
IWorldSaveBackend::TickSyncInfo_In toDB;
|
IWorldSaveBackend::TickSyncInfo_In toDB;
|
||||||
|
|
||||||
for(std::shared_ptr<ContentEventController>& cec : Game.CECs) {
|
for(std::shared_ptr<ContentEventController>& cec : Game.CECs) {
|
||||||
break;
|
|
||||||
assert(cec);
|
assert(cec);
|
||||||
// Пересчитать зоны наблюдения
|
// Пересчитать зоны наблюдения
|
||||||
if(cec->CrossedBorder) {
|
if(cec->CrossedBorder) {
|
||||||
@@ -838,11 +837,8 @@ void GameServer::stepGeneratorAndLuaAsync(IWorldSaveBackend::TickSyncInfo_Out db
|
|||||||
|
|
||||||
// Синхронизация с контроллером асинхронных обработчиков луа
|
// Синхронизация с контроллером асинхронных обработчиков луа
|
||||||
// 2.2 и 3.1
|
// 2.2 и 3.1
|
||||||
// Обработка шума
|
// Обработка шума на стороне луа
|
||||||
for(auto& [key, region] : calculatedNoise) {
|
for(auto& [key, region] : calculatedNoise) {
|
||||||
LOG.debug() << "Сгенерирован " << key.WId << ' ' << key.RegionPos.x << ' '
|
|
||||||
<< key.RegionPos.y << ' ' << key.RegionPos.z;
|
|
||||||
|
|
||||||
auto &obj = toLoadRegions[key.WId].emplace_back(key.RegionPos, World::RegionIn()).second;
|
auto &obj = toLoadRegions[key.WId].emplace_back(key.RegionPos, World::RegionIn()).second;
|
||||||
float *ptr = ®ion[0];
|
float *ptr = ®ion[0];
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#version 450
|
#version 450
|
||||||
|
|
||||||
layout(location = 0) in uvec4 Vertex;
|
layout(location = 0) in uvec3 Vertex;
|
||||||
|
|
||||||
layout(location = 0) out GeometryObj {
|
layout(location = 0) out GeometryObj {
|
||||||
vec3 GeoPos; // Реальная позиция в мире
|
vec3 GeoPos; // Реальная позиция в мире
|
||||||
@@ -16,7 +16,7 @@ layout(push_constant) uniform UniformBufferObject {
|
|||||||
|
|
||||||
// struct NodeVertexStatic {
|
// struct NodeVertexStatic {
|
||||||
// uint32_t
|
// uint32_t
|
||||||
// FX : 9, FY : 9, FZ : 9, // Позиция -112 ~ 369 / 16
|
// FX : 9, FY : 9, FZ : 9, // Позиция 15 -120 ~ 240 360 15 / 16
|
||||||
// N1 : 4, // Не занято
|
// N1 : 4, // Не занято
|
||||||
// LS : 1, // Масштаб карты освещения (1м/16 или 1м)
|
// LS : 1, // Масштаб карты освещения (1м/16 или 1м)
|
||||||
// Tex : 18, // Текстура
|
// Tex : 18, // Текстура
|
||||||
@@ -27,9 +27,9 @@ layout(push_constant) uniform UniformBufferObject {
|
|||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec4 baseVec = ubo.model*vec4(
|
vec4 baseVec = ubo.model*vec4(
|
||||||
float(Vertex.x & 0x1ff) / 16.f - 7,
|
float(Vertex.x & 0x1ff) / 16.f - 135/16.f,
|
||||||
float((Vertex.x >> 9) & 0x1ff) / 16.f - 7,
|
float((Vertex.x >> 9) & 0x1ff) / 16.f - 135/16.f,
|
||||||
float((Vertex.x >> 18) & 0x1ff) / 16.f - 7,
|
float((Vertex.x >> 18) & 0x1ff) / 16.f - 135/16.f,
|
||||||
1
|
1
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user