初步完成page的按需加载卸载
parent
063be364c2
commit
b23d55e876
|
@ -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" />
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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))));
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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(),
|
||||
|
|
Loading…
Reference in New Issue