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(),