diff --git a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj index 6fa540b..fd1624c 100644 --- a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj +++ b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj @@ -70,6 +70,7 @@ stdcpp20 $(ProjectDir)include;$(SolutionDir)ArchitectureColoredPainting\src\Editor\RightBar;$(SolutionDir)ArchitectureColoredPainting\src\Editor\;$(SolutionDir)FramelessHelper\include;$(SolutionDir)FramelessHelper\qmake\inc\core;$(SolutionDir)FramelessHelper\include\FramelessHelper\Core;%(AdditionalIncludeDirectories) FRAMELESSHELPER_WIDGETS_STATIC;%(PreprocessorDefinitions) + Level1 opengl32.lib;%(AdditionalDependencies) @@ -171,6 +172,7 @@ + diff --git a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters index aa91db3..6a72e52 100644 --- a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters +++ b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters @@ -326,6 +326,9 @@ Resource Files\Shaders + + Resource Files\Shaders + diff --git a/ArchitectureColoredPainting/res/MainWindow.qrc b/ArchitectureColoredPainting/res/MainWindow.qrc index 5fb0bed..05dcdbb 100644 --- a/ArchitectureColoredPainting/res/MainWindow.qrc +++ b/ArchitectureColoredPainting/res/MainWindow.qrc @@ -31,6 +31,7 @@ Shaders/irradiance_convolution.frag Shaders/cubemap_prefilter.frag Shaders/brdf_lut.comp + Shaders/pageId_downsample.comp qt.conf diff --git a/ArchitectureColoredPainting/res/Shaders/model.frag b/ArchitectureColoredPainting/res/Shaders/model.frag index 62b7b3b..97e724a 100644 --- a/ArchitectureColoredPainting/res/Shaders/model.frag +++ b/ArchitectureColoredPainting/res/Shaders/model.frag @@ -9,7 +9,7 @@ layout (location = 0) out vec4 gBaseColor; layout (location = 1) out vec3 gNormal; layout (location = 2) out vec3 gPosition; layout (location = 3) out vec2 gMetallicRoughness; -layout (location = 4) out uint gPaintingIndex; +layout (location = 4) out uvec2 gPaintingIndex; in vec2 TexCoords; in vec3 WorldPos; @@ -52,6 +52,6 @@ void main() else gMetallicRoughness = vec2(0,1); - gPaintingIndex = 0; + gPaintingIndex = uvec2(0); } \ No newline at end of file diff --git a/ArchitectureColoredPainting/res/Shaders/model_shadow.frag b/ArchitectureColoredPainting/res/Shaders/model_shadow.frag index 391e444..308e92b 100644 --- a/ArchitectureColoredPainting/res/Shaders/model_shadow.frag +++ b/ArchitectureColoredPainting/res/Shaders/model_shadow.frag @@ -1,4 +1,5 @@ #version 450 core +#extension GL_ARB_sparse_texture2 : enable uniform sampler2D texture_basecolor; @@ -6,8 +7,11 @@ in vec2 TexCoords; void main() { - //gBaseColor = vec4(1,0,0,1); - vec4 baseColor = texture(texture_basecolor, TexCoords); + vec4 baseColor;// = texture(texture_basecolor, TexCoords); + float lod = textureQueryLod(texture_basecolor, TexCoords).x; + while(!sparseTexelsResidentARB(sparseTextureLodARB(texture_basecolor, TexCoords, lod, baseColor))&&lodbind()) { - glFunc->glActiveTexture(GL_TEXTURE0); - glFunc->glBindTexture(GL_TEXTURE_2D, textureBasecolor); - glFunc->glActiveTexture(GL_TEXTURE1); - glFunc->glBindTexture(GL_TEXTURE_2D, textureMetallicRoughness); - glFunc->glActiveTexture(GL_TEXTURE2); - glFunc->glBindTexture(GL_TEXTURE_2D, textureNormal); + glFunc->glBindTextureUnit(0, textureBasecolor); + glFunc->glBindTextureUnit(1, textureMetallicRoughness); + glFunc->glBindTextureUnit(2, textureNormal); shaderProgram->setUniformValue("texture_basecolor", 0); shaderProgram->setUniformValue("texture_metallic_roughness", 1); shaderProgram->setUniformValue("texture_normal", 2); @@ -44,8 +41,7 @@ void Mesh::drawShadow() { if (shadowProgram->bind()) { - glFunc->glActiveTexture(GL_TEXTURE0); - glFunc->glBindTexture(GL_TEXTURE_2D, textureBasecolor); + glFunc->glBindTextureUnit(0, textureBasecolor); shadowProgram->setUniformValue("texture_basecolor", 0); QOpenGLVertexArrayObject::Binder bind(&VAO); diff --git a/ArchitectureColoredPainting/src/Renderer/Model.cpp b/ArchitectureColoredPainting/src/Renderer/Model.cpp index 9f1edad..773d4cf 100644 --- a/ArchitectureColoredPainting/src/Renderer/Model.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Model.cpp @@ -148,8 +148,8 @@ std::unique_ptr Model::processMesh(aiMesh* mesh, const aiScene* scene, } } - m_mesh->paintingIndex = loadPainting(std::string(str.C_Str())); - auto& handle = vtManager->paintings[m_mesh->paintingIndex]; + m_mesh->paintingId = loadPainting(std::string(str.C_Str())); + auto& handle = vtManager->getPaintingHandle(m_mesh->paintingId); m_mesh->textureBasecolor = handle.baseColor; m_mesh->textureMetallicRoughness = handle.metallicRoughness; m_mesh->setupMesh(); diff --git a/ArchitectureColoredPainting/src/Renderer/PaintingMesh.cpp b/ArchitectureColoredPainting/src/Renderer/PaintingMesh.cpp index 64cbd09..4449a96 100644 --- a/ArchitectureColoredPainting/src/Renderer/PaintingMesh.cpp +++ b/ArchitectureColoredPainting/src/Renderer/PaintingMesh.cpp @@ -13,15 +13,14 @@ void PaintingMesh::draw() { if (shaderProgram->bind()) { - glFunc->glActiveTexture(GL_TEXTURE0); - glFunc->glBindTexture(GL_TEXTURE_2D, textureBasecolor); - glFunc->glActiveTexture(GL_TEXTURE1); - glFunc->glBindTexture(GL_TEXTURE_2D, textureMetallicRoughness); + glFunc->glBindTextureUnit(0, textureBasecolor); + glFunc->glBindTextureUnit(1, textureMetallicRoughness); shaderProgram->setUniformValue("texture_basecolor", 0); shaderProgram->setUniformValue("texture_metallic_roughness", 1); QOpenGLVertexArrayObject::Binder bind(&VAO); shaderProgram->setUniformValue("model", model); + glFunc->glUniform1ui(glFunc->glGetUniformLocation(shaderProgram->programId(), "paintingId"), paintingId); EBO.bind(); glFunc->glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0); shaderProgram->release(); @@ -31,6 +30,8 @@ void PaintingMesh::drawShadow() { if (shadowProgram->bind()) { + glFunc->glBindTextureUnit(0, textureBasecolor); + shadowProgram->setUniformValue("texture_basecolor", 0); QOpenGLVertexArrayObject::Binder bind(&VAO); shadowProgram->setUniformValue("model", model); EBO.bind(); diff --git a/ArchitectureColoredPainting/src/Renderer/PaintingMesh.h b/ArchitectureColoredPainting/src/Renderer/PaintingMesh.h index 3d55d0a..8c22c21 100644 --- a/ArchitectureColoredPainting/src/Renderer/PaintingMesh.h +++ b/ArchitectureColoredPainting/src/Renderer/PaintingMesh.h @@ -25,7 +25,7 @@ namespace Renderer QMatrix4x4 model; QOpenGLFunctions_4_5_Compatibility* glFunc; QOpenGLShaderProgram* shaderProgram, * shadowProgram; - GLuint paintingIndex; + GLuint paintingId; PaintingMesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* shadowProgram, const QMatrix4x4& model); void draw() override; diff --git a/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp b/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp index 5bebcab..2944193 100644 --- a/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp +++ b/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp @@ -10,6 +10,7 @@ #include #include "IblUtils.h" #include "VirtualTextureManager.h" +#include using namespace Renderer; @@ -101,16 +102,34 @@ void Renderer::RendererGLWidget::setExposure(float exposure) QOpenGLTexture randomMap(QOpenGLTexture::Target2D); +void GLAPIENTRY MessageCallback(GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar* message, + const void* userParam) +{ + //fprintf(stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n", + // (type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : ""), + // type, severity, message); + if (type == GL_DEBUG_TYPE_ERROR) + qCritical() << QString::fromStdString(std::format("GL_ERROR: type = {:#x}, severity = {:#x}, message = {}", + type, severity, message)); +} void RendererGLWidget::initializeGL() { gl = std::make_unique(); if (!gladLoadGLContext(gl.get(), [](const char* name) { return (GLADapiproc)QOpenGLContext::currentContext()->getProcAddress(name); })) - qDebug() << "Failed to initialize GLAD"; - + qCritical() << "Failed to initialize GLAD"; + QOpenGLFunctions_4_5_Core* glFunc = QOpenGLContext::currentContext()->versionFunctions(); qDebug() << "GL_VERSION" << (char*)gl->GetString(GL_VERSION); + gl->Enable(GL_DEBUG_OUTPUT); + gl->DebugMessageCallback(MessageCallback, 0); + gl->Enable(GL_DEPTH_TEST); gl->DepthFunc(GL_LEQUAL); gl->Enable(GL_TEXTURE_CUBE_MAP_SEAMLESS); @@ -118,83 +137,83 @@ void RendererGLWidget::initializeGL() shadowProgramPtr = new QOpenGLShaderProgram; if (!shadowProgramPtr->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shaders/model_shadow.vert")) - qDebug() << "ERROR:" << shadowProgramPtr->log(); + qCritical() << "ERROR:" << shadowProgramPtr->log(); if (!shadowProgramPtr->addShaderFromSourceFile(QOpenGLShader::Geometry, ":/Shaders/model_shadow.geom")) - qDebug() << "ERROR:" << shadowProgramPtr->log(); + qCritical() << "ERROR:" << shadowProgramPtr->log(); if (!shadowProgramPtr->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/Shaders/model_shadow.frag")) - qDebug() << "ERROR:" << shadowProgramPtr->log(); + qCritical() << "ERROR:" << shadowProgramPtr->log(); if (!shadowProgramPtr->link()) - qDebug() << "ERROR:" << shadowProgramPtr->log(); + qCritical() << "ERROR:" << shadowProgramPtr->log(); plainProgramPtr = new QOpenGLShaderProgram; if (!plainProgramPtr->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shaders/shader.vert")) - qDebug() << "ERROR:" << plainProgramPtr->log(); + qCritical() << "ERROR:" << plainProgramPtr->log(); if (!plainProgramPtr->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/Shaders/shader.frag")) - qDebug() << "ERROR:" << plainProgramPtr->log(); + qCritical() << "ERROR:" << plainProgramPtr->log(); if (!plainProgramPtr->link()) - qDebug() << "ERROR:" << plainProgramPtr->log(); + qCritical() << "ERROR:" << plainProgramPtr->log(); modelProgramPtr = new QOpenGLShaderProgram; if (!modelProgramPtr->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shaders/model.vert")) - qDebug() << "ERROR:" << modelProgramPtr->log(); + qCritical() << "ERROR:" << modelProgramPtr->log(); if (!modelProgramPtr->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/Shaders/model.frag")) - qDebug() << "ERROR:" << modelProgramPtr->log(); + qCritical() << "ERROR:" << modelProgramPtr->log(); if (!modelProgramPtr->link()) - qDebug() << "ERROR:" << modelProgramPtr->log(); + qCritical() << "ERROR:" << modelProgramPtr->log(); paintingProgramPtr = new QOpenGLShaderProgram; if (!paintingProgramPtr->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shaders/painting.vert")) - qDebug() << "ERROR:" << paintingProgramPtr->log(); + qCritical() << "ERROR:" << paintingProgramPtr->log(); if (!paintingProgramPtr->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/Shaders/painting.frag")) - qDebug() << "ERROR:" << paintingProgramPtr->log(); + qCritical() << "ERROR:" << paintingProgramPtr->log(); if (!paintingProgramPtr->link()) - qDebug() << "ERROR:" << paintingProgramPtr->log(); + qCritical() << "ERROR:" << paintingProgramPtr->log(); - paintingCompProgramPtr = new QOpenGLShaderProgram; - if (!paintingCompProgramPtr->addShaderFromSourceFile(QOpenGLShader::Compute, ":/Shaders/painting.comp")) - qDebug() << "ERROR:" << paintingCompProgramPtr->log(); - if (!paintingCompProgramPtr->link()) - qDebug() << "ERROR:" << paintingCompProgramPtr->log(); + pageIdDownsampleProgramPtr = new QOpenGLShaderProgram; + if (!pageIdDownsampleProgramPtr->addShaderFromSourceFile(QOpenGLShader::Compute, ":/Shaders/pageId_downsample.comp")) + qCritical() << "ERROR:" << pageIdDownsampleProgramPtr->log(); + if (!pageIdDownsampleProgramPtr->link()) + qCritical() << "ERROR:" << pageIdDownsampleProgramPtr->log(); depthInitProgramPtr = new QOpenGLShaderProgram; if (!depthInitProgramPtr->addShaderFromSourceFile(QOpenGLShader::Compute, ":/Shaders/depth_init.comp")) - qDebug() << "ERROR:" << depthInitProgramPtr->log(); + qCritical() << "ERROR:" << depthInitProgramPtr->log(); if (!depthInitProgramPtr->link()) - qDebug() << "ERROR:" << depthInitProgramPtr->log(); + qCritical() << "ERROR:" << depthInitProgramPtr->log(); depthMipmapProgramPtr = new QOpenGLShaderProgram; if (!depthMipmapProgramPtr->addShaderFromSourceFile(QOpenGLShader::Compute, ":/Shaders/depth_mipmap.comp")) - qDebug() << "ERROR:" << depthMipmapProgramPtr->log(); + qCritical() << "ERROR:" << depthMipmapProgramPtr->log(); if (!depthMipmapProgramPtr->link()) - qDebug() << "ERROR:" << depthMipmapProgramPtr->log(); + qCritical() << "ERROR:" << depthMipmapProgramPtr->log(); shadowMappingProgramPtr = new QOpenGLShaderProgram; if (!shadowMappingProgramPtr->addShaderFromSourceFile(QOpenGLShader::Compute, ":/Shaders/shadow_mapping.comp")) - qDebug() << "ERROR:" << shadowMappingProgramPtr->log(); + qCritical() << "ERROR:" << shadowMappingProgramPtr->log(); if (!shadowMappingProgramPtr->link()) - qDebug() << "ERROR:" << shadowMappingProgramPtr->log(); + qCritical() << "ERROR:" << shadowMappingProgramPtr->log(); ssgiProgramPtr = new QOpenGLShaderProgram; if (!ssgiProgramPtr->addShaderFromSourceFile(QOpenGLShader::Compute, ":/Shaders/ssgi.comp")) - qDebug() << "ERROR:" << ssgiProgramPtr->log(); + qCritical() << "ERROR:" << ssgiProgramPtr->log(); if (!ssgiProgramPtr->link()) - qDebug() << "ERROR:" << ssgiProgramPtr->log(); + qCritical() << "ERROR:" << ssgiProgramPtr->log(); finalProgramPtr = new QOpenGLShaderProgram; if (!finalProgramPtr->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shaders/final.vert")) - qDebug() << "ERROR:" << finalProgramPtr->log(); + qCritical() << "ERROR:" << finalProgramPtr->log(); if (!finalProgramPtr->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/Shaders/final.frag")) - qDebug() << "ERROR:" << finalProgramPtr->log(); + qCritical() << "ERROR:" << finalProgramPtr->log(); if (!finalProgramPtr->link()) - qDebug() << "ERROR:" << finalProgramPtr->log(); + qCritical() << "ERROR:" << finalProgramPtr->log(); skyBoxProgramPtr = new QOpenGLShaderProgram; if (!skyBoxProgramPtr->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shaders/skybox.vert")) - qDebug() << "ERROR:" << skyBoxProgramPtr->log(); + qCritical() << "ERROR:" << skyBoxProgramPtr->log(); if (!skyBoxProgramPtr->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/Shaders/skybox.frag")) - qDebug() << "ERROR:" << skyBoxProgramPtr->log(); + qCritical() << "ERROR:" << skyBoxProgramPtr->log(); if (!skyBoxProgramPtr->link()) - qDebug() << "ERROR:" << skyBoxProgramPtr->log(); + qCritical() << "ERROR:" << skyBoxProgramPtr->log(); shadowProgramPtr->bind(); gl->GenBuffers(1, &lightSpaceMatricesUBO); @@ -271,6 +290,11 @@ void RendererGLWidget::initializeGL() void RendererGLWidget::paintGL() { QOpenGLFunctions_4_5_Core* glFunc = QOpenGLContext::currentContext()->versionFunctions(); + GLuint timeQuery; + gl->GenQueries(1, &timeQuery); + gl->BeginQuery(GL_TIME_ELAPSED, timeQuery); + + gl->Enable(GL_CULL_FACE); @@ -316,7 +340,7 @@ void RendererGLWidget::paintGL() paintingProgramPtr->release(); if (model != nullptr) model->draw(); - + plainProgramPtr->bind(); plainProgramPtr->setUniformValue("projection", projection); plainProgramPtr->setUniformValue("view", view); @@ -330,11 +354,11 @@ void RendererGLWidget::paintGL() for (int col = 0; col < nrColumns; ++col) { plainProgramPtr->setUniformValue("roughness", glm::clamp((float)col / (float)nrColumns, 0.05f, 1.0f)); - + model.setToIdentity(); model.scale(10); model.translate(QVector3D((float)(col - (nrColumns / 2)) * spacing, - (float)(row - (nrRows / 2)) * spacing+20, + (float)(row - (nrRows / 2)) * spacing + 20, -2.0f)); plainProgramPtr->setUniformValue("model", model); IblUtils::renderSphere(glFunc); @@ -342,40 +366,35 @@ void RendererGLWidget::paintGL() } plainProgramPtr->release(); + pageIdDownsampleProgramPtr->bind(); + gl->BindImageTexture(3, gbuffers[4], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG16UI); + gl->DispatchCompute(ceil(frameWidth / 8. / 8.), ceil(frameWidth / 8. / 8.), 1); + pageIdDownsampleProgramPtr->release(); + + std::vector pixels; + pixels.resize(ceil(frameWidth / 8.) * ceil(frameHeight / 8.)); + gl->ReadBuffer(GL_COLOR_ATTACHMENT4); + gl->ReadnPixels(0, 0, ceil(frameWidth / 8.), ceil(frameHeight / 8.), GL_RG_INTEGER, GL_UNSIGNED_SHORT, pixels.size() * sizeof(glm::u16vec2), pixels.data()); + vtManager->updatePages(pixels); + fboPtr->release(); } - GLuint paintingCompQuery; - gl->GenQueries(1, &paintingCompQuery); - gl->BeginQuery(GL_TIME_ELAPSED, paintingCompQuery); + //depthInitProgramPtr->bind(); + //gl->ActiveTexture(GL_TEXTURE0); + //gl->BindTexture(GL_TEXTURE_2D, gbuffers[6]); + //gl->BindImageTexture(0, gbuffers[7], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F); + //gl->DispatchCompute(ceil(depthWidth / 8.), ceil(depthHeight / 8.), 1); + //depthInitProgramPtr->release(); - paintingCompProgramPtr->bind(); - gl->BindImageTexture(0, gbuffers[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8); - gl->BindImageTexture(1, gbuffers[3], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG8); - gl->BindImageTexture(2, gbuffers[4], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R16UI); - gl->BindImageTexture(3, gbuffers[5], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG32F); - - //gl->DispatchCompute(ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1); - paintingCompProgramPtr->release(); - - gl->EndQuery(GL_TIME_ELAPSED); - - - depthInitProgramPtr->bind(); - gl->ActiveTexture(GL_TEXTURE0); - gl->BindTexture(GL_TEXTURE_2D, gbuffers[6]); - gl->BindImageTexture(0, gbuffers[7], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F); - gl->DispatchCompute(ceil(depthWidth / 8.), ceil(depthHeight / 8.), 1); - depthInitProgramPtr->release(); - - depthMipmapProgramPtr->bind(); - for (int i = 0; i <= 3; i++) - gl->BindImageTexture(i, gbuffers[7], i, GL_FALSE, 0, GL_READ_WRITE, GL_R32F); - gl->DispatchCompute(ceil(depthWidth / 2. / 8.), ceil(depthHeight / 2. / 8.), 1); - for (int i = 0; i <= 3; i++) - gl->BindImageTexture(i, gbuffers[7], i + 3, GL_FALSE, 0, GL_READ_WRITE, GL_R32F); - gl->DispatchCompute(ceil(depthWidth / 2. / 8. / 8.), ceil(depthHeight / 2. / 8. / 8.), 1); - depthMipmapProgramPtr->release(); + //depthMipmapProgramPtr->bind(); + //for (int i = 0; i <= 3; i++) + // gl->BindImageTexture(i, gbuffers[7], i, GL_FALSE, 0, GL_READ_WRITE, GL_R32F); + //gl->DispatchCompute(ceil(depthWidth / 2. / 8.), ceil(depthHeight / 2. / 8.), 1); + //for (int i = 0; i <= 3; i++) + // gl->BindImageTexture(i, gbuffers[7], i + 3, GL_FALSE, 0, GL_READ_WRITE, GL_R32F); + //gl->DispatchCompute(ceil(depthWidth / 2. / 8. / 8.), ceil(depthHeight / 2. / 8. / 8.), 1); + //depthMipmapProgramPtr->release(); shadowMappingProgramPtr->bind(); shadowMappingProgramPtr->setUniformValue("view", view); @@ -388,22 +407,15 @@ void RendererGLWidget::paintGL() shadowMappingProgramPtr->setUniformValue("camPos", camera.Position); shadowMappingProgramPtr->setUniformValue("mainLightDirection", light.lightDirection); shadowMappingProgramPtr->setUniformValue("mainLightRadiance", mainLightRadiance); - /*gl->ActiveTexture(GL_TEXTURE0); - gl->BindTexture(GL_TEXTURE_2D, gbuffers[0]);*/ - gl->ActiveTexture(GL_TEXTURE1); - gl->BindTexture(GL_TEXTURE_2D, gbuffers[1]); - gl->ActiveTexture(GL_TEXTURE2); - gl->BindTexture(GL_TEXTURE_2D, gbuffers[2]); - gl->ActiveTexture(GL_TEXTURE3); - gl->BindTexture(GL_TEXTURE_2D, gbuffers[3]); - gl->ActiveTexture(GL_TEXTURE4); - gl->BindTexture(GL_TEXTURE_2D_ARRAY, shadowGbuffer); - gl->ActiveTexture(GL_TEXTURE5); - gl->BindTexture(GL_TEXTURE_CUBE_MAP, irradianceMap); - gl->ActiveTexture(GL_TEXTURE6); - gl->BindTexture(GL_TEXTURE_CUBE_MAP, prefilterMap); - gl->ActiveTexture(GL_TEXTURE7); - gl->BindTexture(GL_TEXTURE_2D, brdfLUTTexture); + + gl->BindTextureUnit(1, gbuffers[1]); + gl->BindTextureUnit(2, gbuffers[2]); + gl->BindTextureUnit(3, gbuffers[3]); + gl->BindTextureUnit(4, shadowGbuffer); + gl->BindTextureUnit(5, irradianceMap); + gl->BindTextureUnit(6, prefilterMap); + gl->BindTextureUnit(7, brdfLUTTexture); + gl->BindImageTexture(0, gbuffers[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8); gl->BindImageTexture(1, gbuffers[8], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA16F); gl->DispatchCompute(ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1); @@ -435,11 +447,9 @@ void RendererGLWidget::paintGL() gl->Viewport(0, 0, frameWidth, frameHeight); gl->Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - //QOpenGLVertexArrayObject::Binder vaoBinder(&quadVAO); finalProgramPtr->bind(); finalProgramPtr->setUniformValue("exposure", exposure); - gl->ActiveTexture(GL_TEXTURE0); - gl->BindTexture(GL_TEXTURE_2D, gbuffers[0]); + gl->BindTextureUnit(0, gbuffers[0]); quadVAO.bind(); gl->DrawArrays(GL_TRIANGLE_STRIP, 0, 4); quadVAO.release(); @@ -448,30 +458,31 @@ void RendererGLWidget::paintGL() skyBoxProgramPtr->bind(); gl->Disable(GL_CULL_FACE); skyBoxProgramPtr->setUniformValue("view", view); - skyBoxProgramPtr->setUniformValue("projection", projection); + skyBoxProgramPtr->setUniformValue("projection", projection); skyBoxProgramPtr->setUniformValue("exposure", exposure); - gl->ActiveTexture(GL_TEXTURE0); - gl->BindTexture(GL_TEXTURE_CUBE_MAP, skyCubemap); + gl->BindTextureUnit(0, skyCubemap); IblUtils::renderCube(glFunc); skyBoxProgramPtr->release(); - GLuint paintingCompDuration; - gl->GetQueryObjectuiv(paintingCompQuery, GL_QUERY_RESULT, &paintingCompDuration); + gl->EndQuery(GL_TIME_ELAPSED); + GLuint frameDuration; + gl->GetQueryObjectuiv(timeQuery, GL_QUERY_RESULT, &frameDuration); clock_t currentFrame = std::clock(); deltaTime = (float)(currentFrame - lastFrame) / CLOCKS_PER_SEC; lastFrame = currentFrame; - static float accTime = 0, frameCnt = 0; + static float accTime = 0, frameCnt = 0, averageDuration = 0; accTime += deltaTime; frameCnt++; + averageDuration += frameDuration; if (accTime > 1.) { std::cout << std::format("{:20}\r", ""); - std::cout << std::format("FPS: {:.2f} Painting: {}ms Pos: {},{},{}\r", frameCnt / accTime, paintingCompDuration / 1e6, camera.Position.x(), camera.Position.y(), camera.Position.z()); - //std::cout << "FPS: " << frameCnt / accTime << " " << camera.Position.x() << " " << camera.Position.y() << " " << camera.Position.z() << "\r"; + std::cout << std::format("FPS: {:.2f}({:.2f}ms) Pos: {:.2f},{:.2f},{:.2f}\r", frameCnt / accTime, averageDuration / 1e6 / frameCnt, camera.Position.x(), camera.Position.y(), camera.Position.z()); accTime = 0; frameCnt = 0; + averageDuration = 0; } if (pressedKeys.contains(Qt::Key_W)) { @@ -536,7 +547,7 @@ void RendererGLWidget::resizeGL(int width, int height) gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, gbuffers[3], 0); //gPaintingIndex gl->BindTexture(GL_TEXTURE_2D, gbuffers[4]); - gl->TexImage2D(GL_TEXTURE_2D, 0, GL_R16UI, frameWidth, frameHeight, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL); + gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RG16UI, frameWidth, frameHeight, 0, GL_RG_INTEGER, GL_UNSIGNED_INT, NULL); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT4, GL_TEXTURE_2D, gbuffers[4], 0); diff --git a/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.h b/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.h index a068dff..dc62637 100644 --- a/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.h +++ b/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.h @@ -59,7 +59,7 @@ namespace Renderer QOpenGLShaderProgram* plainProgramPtr = nullptr; QOpenGLShaderProgram* modelProgramPtr = nullptr; QOpenGLShaderProgram* paintingProgramPtr = nullptr; - QOpenGLShaderProgram* paintingCompProgramPtr = nullptr; + QOpenGLShaderProgram* pageIdDownsampleProgramPtr = nullptr; QOpenGLShaderProgram* depthInitProgramPtr = nullptr; QOpenGLShaderProgram* depthMipmapProgramPtr = nullptr; QOpenGLShaderProgram* shadowMappingProgramPtr = nullptr; diff --git a/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.cpp b/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.cpp index 375db34..f1f0371 100644 --- a/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.cpp +++ b/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.cpp @@ -47,7 +47,7 @@ Renderer::VirtualTextureManager::VirtualTextureManager(GladGLContext* gl) } -GLuint Renderer::VirtualTextureManager::createVirtualTexture(Painting painting) +std::uint16_t Renderer::VirtualTextureManager::createVirtualTexture(Painting painting) { const GLsizei levels = glm::log2(textureSize / pageSize) + 1; qDebug() << "levels:" << levels; @@ -103,6 +103,66 @@ GLuint Renderer::VirtualTextureManager::createVirtualTexture(Painting painting) } } paintings.emplace_back(baseColor, metallicRoughness, painting.buffers); - - return paintings.size() - 1; + return paintings.size(); +} + +Renderer::PaintingHandle& Renderer::VirtualTextureManager::getPaintingHandle(std::uint16_t id) +{ + return paintings[id - 1]; +} + +void Renderer::VirtualTextureManager::pageCommitmentById(const glm::u16vec2& pageId, GLboolean commit) +{ + auto& painting = getPaintingHandle(pageId.x >> 4); + GLint level = pageId.x & 0b1111; + glm::ivec2 page(pageId.y & 0b11111111, pageId.y >> 8); + qDebug() << commit << level << page.x << page.y; + gl->TexturePageCommitmentEXT(painting.baseColor, level, + static_cast(pageSize) * page.x, static_cast(pageSize) * page.y, 0, + static_cast(pageSize), static_cast(pageSize), 1, + commit); + gl->TexturePageCommitmentEXT(painting.metallicRoughness, level, + static_cast(pageSize) * page.x, static_cast(pageSize) * page.y, 0, + static_cast(pageSize), static_cast(pageSize), 1, + commit); + + if (commit) + { + program.bind(); + gl->Uniform2i(gl->GetUniformLocation(program.programId(), "pixelOffset"), static_cast(pageSize) * page.x, static_cast(pageSize) * page.y); + gl->BindImageTexture(0, painting.baseColor, level, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8); + gl->BindImageTexture(1, painting.metallicRoughness, level, GL_FALSE, 0, GL_READ_WRITE, GL_RG8); + gl->DispatchCompute(pageSize / 8, pageSize / 8, 1); + program.release(); + } +} + +void Renderer::VirtualTextureManager::updatePages(const std::vector& pageIds) +{ + for (auto iter = loadedPages.begin(); iter != loadedPages.end();) + { + iter->second--; + if (iter->second == 0) + { + pageCommitmentById(iter->first, GL_FALSE); + iter = loadedPages.erase(iter); + } + else + iter++; + } + for (auto& pageId : pageIds) + { + if (pageId.x) + { + auto [iter, success] = loadedPages.emplace(pageId, lifeTime); + if (success) + { + pageCommitmentById(pageId, GL_TRUE); + + } + else + iter->second = lifeTime; + } + } + } diff --git a/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h b/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h index de06da3..61e9ca9 100644 --- a/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h +++ b/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h @@ -1,6 +1,7 @@ #pragma once #include "Painting/Painting.h" #include +#include struct GladGLContext; @@ -16,22 +17,35 @@ namespace Renderer class VirtualTextureManager { public: - static constexpr GLsizei textureSize = 16384; - std::vector paintings; - VirtualTextureManager(GladGLContext* gl); /** * @brief * @param painting - * @return ÔÚpaintingsÖÐË÷Òý + * @return ÐéÄâÎÆÀíid */ - GLuint createVirtualTexture(Painting painting); + std::uint16_t createVirtualTexture(Painting painting); + PaintingHandle& getPaintingHandle(std::uint16_t id); + void updatePages(const std::vector& pageIds); private: GladGLContext* gl; + static constexpr GLsizei textureSize = 16384; + static constexpr int lifeTime = 64; GLint pageSize; QOpenGLShaderProgram program; - + std::vector paintings; + + struct u16vec2Hash + { + std::size_t operator()(glm::u16vec2 const& v) const + { + return ((std::size_t)v.y << 16) + v.x; + } + }; + + std::unordered_map loadedPages; + + void pageCommitmentById(const glm::u16vec2& pageId, GLboolean commit); }; } diff --git a/ArchitectureColoredPainting/src/main.cpp b/ArchitectureColoredPainting/src/main.cpp index 0d8791b..6cd3b6b 100644 --- a/ArchitectureColoredPainting/src/main.cpp +++ b/ArchitectureColoredPainting/src/main.cpp @@ -27,12 +27,11 @@ void messageHandler(QtMsgType type, const QMessageLogContext& context, const QSt SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN); break; case QtCriticalMsg: - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE); - break; - case QtFatalMsg: SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED); break; - + case QtFatalMsg: + SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | BACKGROUND_RED); + break; } std::cout << std::format("{}({},{}) {}\n", QString(context.file).splitRef("\\").back().toLocal8Bit().data(),