初步完成page的按需加载卸载

dev-VirtualTexture
wuyize 2023-02-23 22:18:52 +08:00
parent 063be364c2
commit b23d55e876
16 changed files with 256 additions and 137 deletions

View File

@ -70,6 +70,7 @@
<LanguageStandard>stdcpp20</LanguageStandard>
<AdditionalIncludeDirectories>$(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)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>FRAMELESSHELPER_WIDGETS_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>Level1</WarningLevel>
</ClCompile>
<Link>
<AdditionalDependencies>opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -171,6 +172,7 @@
<None Include="res\Shaders\model_shadow.frag" />
<None Include="res\Shaders\model_shadow.geom" />
<None Include="res\Shaders\model_shadow.vert" />
<None Include="res\Shaders\pageId_downsample.comp" />
<None Include="res\Shaders\painting.comp" />
<None Include="res\Shaders\painting.frag" />
<None Include="res\Shaders\painting.vert" />

View File

@ -326,6 +326,9 @@
<None Include="res\Shaders\brdf_lut.comp">
<Filter>Resource Files\Shaders</Filter>
</None>
<None Include="res\Shaders\pageId_downsample.comp">
<Filter>Resource Files\Shaders</Filter>
</None>
</ItemGroup>
<ItemGroup>
<QtUic Include="EditorWidget.ui">

View File

@ -31,6 +31,7 @@
<file>Shaders/irradiance_convolution.frag</file>
<file>Shaders/cubemap_prefilter.frag</file>
<file>Shaders/brdf_lut.comp</file>
<file>Shaders/pageId_downsample.comp</file>
</qresource>
<qresource prefix="/qt/etc">
<file>qt.conf</file>

View File

@ -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);
}

View File

@ -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))&&lod<textureQueryLevels(texture_basecolor))
lod++;
if(baseColor.a<0.4)
discard;
}

View File

@ -0,0 +1,14 @@
#version 450 core
layout (local_size_x = 8, local_size_y = 8) in;
layout(rg16ui, binding = 3) uniform uimage2D gPageId;
uniform uvec2 dither = uvec2(0);
void main()
{
uvec2 targetLocation = gl_GlobalInvocationID.xy;
uvec2 sourceLocation = targetLocation * 8 + dither;
imageStore(gPageId, ivec2(targetLocation), uvec4(imageLoad(gPageId, ivec2(sourceLocation))));
}

View File

@ -4,11 +4,13 @@
uniform sampler2D texture_basecolor;
uniform sampler2D texture_metallic_roughness;
uniform uint paintingId;
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;
layout(location = 5) out vec2 gPaintingTexCoord;
in vec2 TexCoords;
@ -17,24 +19,36 @@ in vec3 Normal;
void main()
{
float lod = textureQueryLod(texture_basecolor, TexCoords).x;
while(!sparseTexelsResidentARB(sparseTextureLodARB(texture_basecolor, TexCoords, lod, gBaseColor))&&lod<textureQueryLevels(texture_basecolor))
int lodExpect = int(textureQueryLod(texture_basecolor, TexCoords).x);
int levels = textureQueryLevels(texture_basecolor);
float lod = lodExpect;
while(!sparseTexelsResidentARB(sparseTextureLodARB(texture_basecolor, TexCoords, lod, gBaseColor))&&lod<levels)
lod++;
if(gBaseColor.a<0.4)
discard;
//gBaseColor = vec4( vec3(1),1 );
// mainImage(gBaseColor, vec2(1.,1.)-TexCoords);
gPosition = WorldPos;
gNormal = normalize(Normal);
//gMetallicRoughness = vec2(0,1);
lod = textureQueryLod(texture_metallic_roughness, TexCoords).x;
lod = lodExpect;
vec4 mt;
while(!sparseTexelsResidentARB(sparseTextureLodARB(texture_metallic_roughness, TexCoords, lod, mt))&&lod<textureQueryLevels(texture_metallic_roughness))
while(!sparseTexelsResidentARB(sparseTextureLodARB(texture_metallic_roughness, TexCoords, lod, mt))&&lod<levels)
lod++;
gMetallicRoughness = mt.rg;
//gPaintingIndex = 1;
gPaintingIndex = 0;
// int pageSize = textureSize(texture_basecolor, levels-1).x;
// uint pageId = 0;
// for(uint i = 0; i < lodExpect; i++)
// pageId += 1<<(2*(levels-1-i));
uint w = 1<<(levels-1-lodExpect);
ivec2 page = ivec2(TexCoords * vec2(w));
page = clamp(page, ivec2(0), ivec2(w-1));
// pageId += page.y*w+page.x;
if(lodExpect==levels-1)
gPaintingIndex = uvec2(0);
else
gPaintingIndex = uvec2((paintingId<<4)+lodExpect, (page.y<<8)+page.x);
gPaintingTexCoord = vec2(1., 1.) - TexCoords * 2;
return;

View File

@ -22,12 +22,9 @@ void Mesh::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->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);

View File

@ -148,8 +148,8 @@ std::unique_ptr<Drawable> 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();

View File

@ -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();

View File

@ -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;

View File

@ -10,6 +10,7 @@
#include <glm/gtc/matrix_transform.hpp>
#include "IblUtils.h"
#include "VirtualTextureManager.h"
#include <QDebug>
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<GladGLContext>();
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<QOpenGLFunctions_4_5_Core>();
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<QOpenGLFunctions_4_5_Core>();
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<glm::u16vec2> 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);

View File

@ -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;

View File

@ -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<GLsizei>(pageSize) * page.x, static_cast<GLsizei>(pageSize) * page.y, 0,
static_cast<GLsizei>(pageSize), static_cast<GLsizei>(pageSize), 1,
commit);
gl->TexturePageCommitmentEXT(painting.metallicRoughness, level,
static_cast<GLsizei>(pageSize) * page.x, static_cast<GLsizei>(pageSize) * page.y, 0,
static_cast<GLsizei>(pageSize), static_cast<GLsizei>(pageSize), 1,
commit);
if (commit)
{
program.bind();
gl->Uniform2i(gl->GetUniformLocation(program.programId(), "pixelOffset"), static_cast<GLsizei>(pageSize) * page.x, static_cast<GLsizei>(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<glm::u16vec2>& 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;
}
}
}

View File

@ -1,6 +1,7 @@
#pragma once
#include "Painting/Painting.h"
#include <QOpenGLShaderProgram>
#include <unordered_map>
struct GladGLContext;
@ -16,22 +17,35 @@ namespace Renderer
class VirtualTextureManager
{
public:
static constexpr GLsizei textureSize = 16384;
std::vector<PaintingHandle> 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<glm::u16vec2>& pageIds);
private:
GladGLContext* gl;
static constexpr GLsizei textureSize = 16384;
static constexpr int lifeTime = 64;
GLint pageSize;
QOpenGLShaderProgram program;
std::vector<PaintingHandle> paintings;
struct u16vec2Hash
{
std::size_t operator()(glm::u16vec2 const& v) const
{
return ((std::size_t)v.y << 16) + v.x;
}
};
std::unordered_map<glm::u16vec2, int, u16vec2Hash> loadedPages;
void pageCommitmentById(const glm::u16vec2& pageId, GLboolean commit);
};
}

View File

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