diff --git a/ArchitectureColoredPainting/res/Shaders/painting.comp b/ArchitectureColoredPainting/res/Shaders/painting.comp index 91d39d0..b00edc5 100644 --- a/ArchitectureColoredPainting/res/Shaders/painting.comp +++ b/ArchitectureColoredPainting/res/Shaders/painting.comp @@ -7,24 +7,15 @@ uniform ivec2 pixelOffset; layout(rgba8, binding = 0) uniform image2D gBaseColor; layout(rg8, binding = 1) uniform image2D gMetallicRoughness; -layout(std430, binding = 1) buffer paintingOffsetBuffer -{ - /********************** - ** @x paintingBvhRoot - ** @y paintingBvhLength - **********************/ - uvec2 paintingOffsets[]; -}; - -layout(std430, binding = 2) buffer bvhBuffer +layout(std430, binding = 0) buffer bvhBuffer { uvec2 bvhChildren[]; }; -layout(std430, binding = 3) buffer bvhBoundBuffer +layout(std430, binding = 1) buffer bvhBoundBuffer { vec4 bvhBound[]; }; -layout(std430, binding = 4) buffer elementOffsetBuffer +layout(std430, binding = 2) buffer elementOffsetBuffer { /********************** ** @[0] elementBvhRoot @@ -34,11 +25,11 @@ layout(std430, binding = 4) buffer elementOffsetBuffer **********************/ uvec4 elementOffset[]; }; -layout(std430, binding = 5) buffer elementIndexBuffer +layout(std430, binding = 3) buffer elementIndexBuffer { uint elementIndexs[]; //线和面 }; -layout(std430, binding = 6) buffer elementDataBuffer +layout(std430, binding = 4) buffer elementDataBuffer { float elementData[]; //点和Style }; @@ -1182,14 +1173,12 @@ bool drawElement(uint elementIndex, vec2 localUV, out vec3 color, out vec2 metal void main() { - //ivec2 pixelLocation = ivec2(((gl_LocalInvocationID.xy)*imageSize(gPaintingIndex)/gl_WorkGroupSize.xy + gl_WorkGroupID.xy).xy); - ivec2 pixelLocation = ivec2(gl_GlobalInvocationID.xy); - - vec2 uv = (pixelOffset + pixelLocation + vec2(0.5)) / imageSize(gBaseColor); - imageStore(gBaseColor, ivec2( pixelOffset + pixelLocation), vec4(uv,1,1)); - imageStore(gMetallicRoughness, ivec2( pixelOffset + pixelLocation), vec4(uv,1,1)); - return; - uv= uv*2-vec2(1); + ivec2 pixelLocation = ivec2(pixelOffset + gl_GlobalInvocationID.xy); + vec2 uv = (pixelLocation + vec2(0.5)) / imageSize(gBaseColor); + //imageStore(gBaseColor, pixelLocation, vec4(uv,1,1)); + //imageStore(gMetallicRoughness, pixelLocation, vec4(uv,1,1)); + //return; + uv = vec2(1)-uv*2; //vec2 uv = imageLoad(gPaintingTexCoord, pixelLocation).rg; vec3 debugBVH = vec3(0); diff --git a/ArchitectureColoredPainting/res/Shaders/painting.frag b/ArchitectureColoredPainting/res/Shaders/painting.frag index 677deb2..f027120 100644 --- a/ArchitectureColoredPainting/res/Shaders/painting.frag +++ b/ArchitectureColoredPainting/res/Shaders/painting.frag @@ -1,4 +1,5 @@ #version 450 core +#extension GL_ARB_sparse_texture2 : enable uniform sampler2D texture_basecolor; uniform sampler2D texture_metallic_roughness; @@ -16,7 +17,10 @@ in vec3 Normal; void main() { - gBaseColor = texture(texture_basecolor, TexCoords); + float lod = textureQueryLod(texture_basecolor, TexCoords).x; + while(!sparseTexelsResidentARB(sparseTextureLodARB(texture_basecolor, TexCoords, lod, gBaseColor))&&lod Model::processMesh(aiMesh* mesh, const aiScene* scene, } } - //m_mesh->paintingIndex = loadPainting(std::string(str.C_Str())); - std::tie(m_mesh->textureBasecolor, m_mesh->textureMetallicRoughness) = loadPainting(std::string(str.C_Str())); + m_mesh->paintingIndex = loadPainting(std::string(str.C_Str())); + auto& handle = vtManager->paintings[m_mesh->paintingIndex]; + m_mesh->textureBasecolor = handle.baseColor; + m_mesh->textureMetallicRoughness = handle.metallicRoughness; m_mesh->setupMesh(); return m_mesh; } @@ -225,7 +227,7 @@ GLuint Model::loadMaterialTextures(aiMaterial* mat, aiTextureType type) return texture.textureId(); } -std::tuple Renderer::Model::loadPainting(std::string path) +GLuint Renderer::Model::loadPainting(std::string path) { auto iter = paintingLoaded.find(path); if (iter != paintingLoaded.end()) @@ -327,7 +329,7 @@ std::tuple Renderer::Model::loadPainting(std::string path) //painting.addElement(element[1], QVector4D(-0.7, 0.2, -0.2, 0.7), 0, 0); //painting.addElement(element[2], QVector4D(0.2, -0.8, 0.8, -0.1), 0, 0); - painting.generateBuffers(); + painting.generateBuffers(glFunc); ///////////////////////////////////////////////////////////////////////////////////////////////// std::vector bvhChildren0 = { //root @@ -466,7 +468,7 @@ std::tuple Renderer::Model::loadPainting(std::string path) //GLuint index = paintingHelper->addPainting(painting); //paintingLoaded.insert({ path, index }); - auto ids = vtManager->createVirtualTexture(painting); - paintingLoaded.emplace(path, ids); - return ids; + auto index = vtManager->createVirtualTexture(painting); + paintingLoaded.emplace(path, index); + return index; } diff --git a/ArchitectureColoredPainting/src/Renderer/Model.h b/ArchitectureColoredPainting/src/Renderer/Model.h index 2993026..3883a08 100644 --- a/ArchitectureColoredPainting/src/Renderer/Model.h +++ b/ArchitectureColoredPainting/src/Renderer/Model.h @@ -29,7 +29,7 @@ namespace Renderer VirtualTextureManager* vtManager = nullptr; /* 模型数据 */ - std::unordered_map> paintingLoaded; + std::unordered_map paintingLoaded; std::unordered_map texturesLoaded; std::vector> meshes; @@ -47,6 +47,6 @@ namespace Renderer //加载材质纹理 GLuint loadMaterialTextures(aiMaterial* mat, aiTextureType type); - std::tuple loadPainting(std::string path); + GLuint loadPainting(std::string path); }; } \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/Painting.cpp b/ArchitectureColoredPainting/src/Renderer/Painting/Painting.cpp index e78a81a..18fc638 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/Painting.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Painting/Painting.cpp @@ -105,13 +105,12 @@ BvhTreeData Painting::encodeElementLeaf(ElementWithTransform e) return BvhTreeData(bound, elementPool[e.element], rightSon); } -void Painting::generateBuffers() +void Painting::generateBuffers(QOpenGLFunctions_4_5_Compatibility* glFunc) { qDebug() << "Element Count: " << elementPool.size(); qDebug() << "Coutour Count: " << contourPool.size(); qDebug() << " Style Count: " << stylePool.size(); - bvhChildren.clear(); bvhBounds.clear(); elementOffset.clear(); @@ -161,6 +160,19 @@ void Painting::generateBuffers() elementOffset.push_back({ contourBuffer->bvhOffset, stylePool[i.first.style], contourBuffer->pointsOffset, contourBuffer->linesOffset }); //std::cout << std::format("{} {} {} {}\n", contourBuffer->bvhOffset, stylePool[i.first->style], contourBuffer->pointsOffset, contourBuffer->linesOffset); } + + glFunc->glCreateBuffers(5, buffers.data()); + GLuint& bvhSSBO = buffers[0]; + GLuint& bvhBoundSSBO = buffers[1]; + GLuint& elementOffsetSSBO = buffers[2]; + GLuint& elementIndexSSBO = buffers[3]; + GLuint& elementDataSSBO = buffers[4]; + + glFunc->glNamedBufferData(bvhSSBO, bvhChildren.size() * sizeof(GLuint), bvhChildren.data(), GL_STATIC_READ); + glFunc->glNamedBufferData(bvhBoundSSBO, bvhBounds.size() * sizeof(QVector4D), bvhBounds.data(), GL_STATIC_READ); + glFunc->glNamedBufferData(elementOffsetSSBO, elementOffset.size() * sizeof(glm::uvec4), elementOffset.data(), GL_STATIC_READ); + glFunc->glNamedBufferData(elementIndexSSBO, elementIndex.size() * sizeof(GLuint), elementIndex.data(), GL_STATIC_READ); + glFunc->glNamedBufferData(elementDataSSBO, elementData.size() * sizeof(GLfloat), elementData.data(), GL_STATIC_READ); } GLuint Renderer::Painting::getElementCount() diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/Painting.h b/ArchitectureColoredPainting/src/Renderer/Painting/Painting.h index a4ccedd..fe29c1d 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/Painting.h +++ b/ArchitectureColoredPainting/src/Renderer/Painting/Painting.h @@ -1,11 +1,13 @@ #pragma once #include +#include #include #include #include "Line.h" #include "BvhTree.h" #include "ElementStyle.h" #include "Element.h" +#include namespace Renderer { @@ -64,12 +66,13 @@ namespace Renderer std::vector elementIndex; std::vector elementData; int paintingId = 0; + std::array buffers; Painting(); void addElement(ElementWithTransform element); void addElement(const Element& element, const ElementTransform& transform); void addElement(std::shared_ptr element, QVector4D bound, float rotation, int zIndex); - void generateBuffers(); + void generateBuffers(QOpenGLFunctions_4_5_Compatibility* glFunc); GLuint getElementCount(); private: std::unordered_map, std::pair/*面*/, std::shared_ptr/*线*/>> contourPool; diff --git a/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp b/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp index 8f68578..5bebcab 100644 --- a/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp +++ b/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp @@ -75,10 +75,10 @@ void RendererGLWidget::setModel() //model = new Model("E:\\3D Objects\\gallery_gltf\\gallery_gltf.gltf", context(), modelProgramPtr, paintingProgramPtr, shadowProgramPtr, paintingHelper); light.model = model; qDebug() << model->AABB; - paintingHelper->allocateBuffers(); - paintingCompProgramPtr->bind(); - paintingHelper->bindPaintingBuffers(); - paintingCompProgramPtr->release(); + //paintingHelper->allocateBuffers(); + //paintingCompProgramPtr->bind(); + //paintingHelper->bindPaintingBuffers(); + //paintingCompProgramPtr->release(); doneCurrent(); } diff --git a/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.cpp b/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.cpp index 4d6d2ef..375db34 100644 --- a/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.cpp +++ b/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.cpp @@ -44,12 +44,13 @@ Renderer::VirtualTextureManager::VirtualTextureManager(GladGLContext* gl) qDebug() << "ERROR:" << program.log(); if (!program.link()) qDebug() << "ERROR:" << program.log(); - + } -std::tuple Renderer::VirtualTextureManager::createVirtualTexture(Painting painting) +GLuint Renderer::VirtualTextureManager::createVirtualTexture(Painting painting) { - const GLsizei levels = static_cast(glm::log2(textureSize) + static_cast(1)); + const GLsizei levels = glm::log2(textureSize / pageSize) + 1; + qDebug() << "levels:" << levels; GLuint textures[2]; gl->CreateTextures(GL_TEXTURE_2D, 2, textures); @@ -57,20 +58,27 @@ std::tuple Renderer::VirtualTextureManager::createVirtualTexture GLuint& metallicRoughness = textures[1]; gl->TextureParameteri(baseColor, GL_TEXTURE_SPARSE_ARB, GL_TRUE); + gl->TextureParameteri(baseColor, GL_TEXTURE_BASE_LEVEL, 0); + gl->TextureParameteri(baseColor, GL_TEXTURE_MAX_LEVEL, levels - 1); gl->TextureParameteri(baseColor, GL_TEXTURE_WRAP_S, GL_REPEAT); gl->TextureParameteri(baseColor, GL_TEXTURE_WRAP_T, GL_REPEAT); - gl->TextureParameteri(baseColor, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + gl->TextureParameteri(baseColor, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); gl->TextureParameteri(baseColor, GL_TEXTURE_MAG_FILTER, GL_LINEAR); gl->TextureStorage2D(baseColor, levels, GL_RGBA8, GLsizei(textureSize), GLsizei(textureSize)); gl->TextureParameteri(metallicRoughness, GL_TEXTURE_SPARSE_ARB, GL_TRUE); + gl->TextureParameteri(metallicRoughness, GL_TEXTURE_BASE_LEVEL, 0); + gl->TextureParameteri(metallicRoughness, GL_TEXTURE_MAX_LEVEL, levels - 1); gl->TextureParameteri(metallicRoughness, GL_TEXTURE_WRAP_S, GL_REPEAT); gl->TextureParameteri(metallicRoughness, GL_TEXTURE_WRAP_T, GL_REPEAT); - gl->TextureParameteri(metallicRoughness, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + gl->TextureParameteri(metallicRoughness, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); gl->TextureParameteri(metallicRoughness, GL_TEXTURE_MAG_FILTER, GL_LINEAR); gl->TextureStorage2D(metallicRoughness, levels, GL_RG8, GLsizei(textureSize), GLsizei(textureSize)); - for (std::size_t level = 0; level < 1; ++level) + for (int i = 0; i < 5; i++) + gl->BindBufferBase(GL_SHADER_STORAGE_BUFFER, i, painting.buffers[i]); + + for (auto level = levels - 1; level < levels; ++level) { GLsizei levelSize = (textureSize >> level); for (GLsizei j = 0; j < levelSize / pageSize; ++j) @@ -87,14 +95,14 @@ std::tuple Renderer::VirtualTextureManager::createVirtualTexture program.bind(); gl->Uniform2i(gl->GetUniformLocation(program.programId(), "pixelOffset"), static_cast(pageSize) * i, static_cast(pageSize) * j); - gl->BindImageTexture(0, baseColor, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8); - gl->BindImageTexture(1, metallicRoughness, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG8); - + gl->BindImageTexture(0, baseColor, level, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8); + gl->BindImageTexture(1, metallicRoughness, level, GL_FALSE, 0, GL_READ_WRITE, GL_RG8); gl->DispatchCompute(pageSize / 8, pageSize / 8, 1); program.release(); } } + paintings.emplace_back(baseColor, metallicRoughness, painting.buffers); - return { baseColor, metallicRoughness }; + return paintings.size() - 1; } diff --git a/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h b/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h index 947e4ac..de06da3 100644 --- a/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h +++ b/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h @@ -6,25 +6,32 @@ struct GladGLContext; namespace Renderer { - + struct PaintingHandle + { + GLuint baseColor; + GLuint metallicRoughness; + std::array buffers; + }; class VirtualTextureManager { public: static constexpr GLsizei textureSize = 16384; + std::vector paintings; + VirtualTextureManager(GladGLContext* gl); /** - * @brief - * @param painting - * @return 0 baseColor - * @return 1 metallicRoughness + * @brief + * @param painting + * @return 在paintings中索引 */ - std::tuple createVirtualTexture(Painting painting); + GLuint createVirtualTexture(Painting painting); private: GladGLContext* gl; GLint pageSize; QOpenGLShaderProgram program; + }; }