#include "Pipeline.hpp" #include "../../../core/world/materials.hpp" #include "../../control/Camera.hpp" #include using namespace render::gl; Pipeline::Pipeline(const Pipeline::options& options): IndicatorCubeBuffer(GL_LINES, 24, { glm::vec3(0, 0, 0), glm::vec3(0, 0, 1), glm::vec3(0, 0, 1), glm::vec3(0, 1, 1), glm::vec3(0, 1, 1), glm::vec3(0, 1, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 0), glm::vec3(1, 0, 0), glm::vec3(1, 0, 1), glm::vec3(1, 0, 1), glm::vec3(1, 1, 1), glm::vec3(1, 1, 1), glm::vec3(1, 1, 0), glm::vec3(1, 1, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 0), glm::vec3(1, 0, 0), glm::vec3(0, 0, 1), glm::vec3(1, 0, 1), glm::vec3(0, 1, 1), glm::vec3(1, 1, 1), glm::vec3(0, 1, 0), glm::vec3(1, 1, 0), }, { glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1), glm::vec4(1, 1, 1, 1), }) { glGenVertexArrays(1, &VertexArrayID); glBindVertexArray(VertexArrayID); reloadShaders(options.voxel); SkyPass = std::make_unique(); SkyEnable = options.skybox; IndicatorPass = std::make_unique(); FogColor = glm::vec3(options.clear_color.x, options.clear_color.y, options.clear_color.z); loadTextures(options.textures, options.mipMapLOD, options.anisotropy); } Pipeline::~Pipeline() { unloadTextures(); glDeleteVertexArrays(1, &VertexArrayID); } void Pipeline::beginFrame() { TracyGpuZone("Render"); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } std::function Pipeline::beginWorldPass() { WorldPass->useIt(); WorldPass->start(this); return [&](glm::mat4 model) { return WorldPass->setup(this, model); }; } std::function &)> Pipeline::beginEntityPass() { EntityPass->useIt(); EntityPass->start(this); return [&](const std::vector& models) { return EntityPass->setup(this, models); }; } size_t Pipeline::drawIndicatorCube(glm::mat4 model) { IndicatorPass->useIt(); return IndicatorCubeBuffer.draw(IndicatorPass->setup(this, model)); } void Pipeline::endPass() { if(SkyEnable) { SkyPass->draw(this); } } void Pipeline::swapBuffer(GLFWwindow* ptr) { TracyGpuZone("Swap"); glfwSwapBuffers(ptr); TracyGpuCollect; } void Pipeline::reloadShaders(const pass::VoxelProgram::options& options) { WorldPass = std::make_unique(options); EntityPass = std::make_unique(options); } void Pipeline::reloadTextures(const std::string& texturePath, float mipMapLOD, float anisotropy) { unloadTextures(); loadTextures(texturePath, mipMapLOD, anisotropy); } void Pipeline::unloadTextures() { glDeleteTextures(1, &HOSAtlas); glDeleteTextures(1, &NormalAtlas); glDeleteTextures(1, &TextureAtlas); } void Pipeline::loadTextures(const std::string& texturePath, float mipMapLOD, float anisotropy) { std::vector terrainTextures; for(const auto& texture: world::materials::textures) { terrainTextures.emplace_back(texturePath + "/terrain/" + texture); } const auto ani = anisotropy >= 1 ? (1 << (static_cast(anisotropy)-1)) : 0; TextureAtlas = pass::Program::loadTextureArray(terrainTextures, "", mipMapLOD, ani); NormalAtlas = pass::Program::loadTextureArray(terrainTextures, ".nrm", mipMapLOD, ani); HOSAtlas = pass::Program::loadTextureArray(terrainTextures, ".hos", mipMapLOD, ani); Skybox = pass::Program::loadTextureCube(texturePath + "/sky/Space_tray"); } void Pipeline::lookFrom(const Camera& camera) { ProjectionMatrix = camera.getProjectionMatrix(); ViewMatrix = camera.getViewMatrix(); FogDepth = camera.getDepth(); } void Pipeline::setClearColor(glm::vec4 c) { FogColor = c; glClearColor(c.r, c.g, c.b, c.a); }