实现虚拟纹理的异步加载
parent
b23d55e876
commit
8920dc39ad
|
@ -71,6 +71,7 @@
|
||||||
<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>
|
<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>
|
<PreprocessorDefinitions>FRAMELESSHELPER_WIDGETS_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<WarningLevel>Level1</WarningLevel>
|
<WarningLevel>Level1</WarningLevel>
|
||||||
|
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<AdditionalDependencies>opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
@ -81,7 +82,7 @@
|
||||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
|
|
|
@ -182,8 +182,8 @@ std::tuple<GLuint, GLuint, GLuint, GLuint> Renderer::IblUtils::precomputeCubemap
|
||||||
// ----------------------
|
// ----------------------
|
||||||
unsigned int captureFBO;
|
unsigned int captureFBO;
|
||||||
unsigned int captureRBO;
|
unsigned int captureRBO;
|
||||||
glFunc->glGenFramebuffers(1, &captureFBO);
|
glFunc->glCreateFramebuffers(1, &captureFBO);
|
||||||
glFunc->glGenRenderbuffers(1, &captureRBO);
|
glFunc->glCreateRenderbuffers(1, &captureRBO);
|
||||||
|
|
||||||
glFunc->glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
|
glFunc->glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
|
||||||
glFunc->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, captureRBO);
|
glFunc->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, captureRBO);
|
||||||
|
@ -262,6 +262,8 @@ GLuint Renderer::IblUtils::generateCubemap(QOpenGLFunctions_4_5_Core* glFunc, GL
|
||||||
glFunc->glActiveTexture(GL_TEXTURE0);
|
glFunc->glActiveTexture(GL_TEXTURE0);
|
||||||
glFunc->glBindTexture(GL_TEXTURE_2D, hdrTexture);
|
glFunc->glBindTexture(GL_TEXTURE_2D, hdrTexture);
|
||||||
|
|
||||||
|
glFunc->glBindRenderbuffer(GL_RENDERBUFFER, captureRBO);
|
||||||
|
glFunc->glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, cubemapSize, cubemapSize);
|
||||||
glFunc->glViewport(0, 0, cubemapSize, cubemapSize);
|
glFunc->glViewport(0, 0, cubemapSize, cubemapSize);
|
||||||
glFunc->glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
|
glFunc->glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
|
||||||
|
|
||||||
|
@ -285,8 +287,6 @@ GLuint Renderer::IblUtils::generateCubemap(QOpenGLFunctions_4_5_Core* glFunc, GL
|
||||||
|
|
||||||
GLuint Renderer::IblUtils::generateIrradianceMap(QOpenGLFunctions_4_5_Core* glFunc, GLuint captureFBO, GLuint captureRBO, const QMatrix4x4& captureProjection, const std::array<QMatrix4x4, 6>& captureViews, GLuint envCubemap)
|
GLuint Renderer::IblUtils::generateIrradianceMap(QOpenGLFunctions_4_5_Core* glFunc, GLuint captureFBO, GLuint captureRBO, const QMatrix4x4& captureProjection, const std::array<QMatrix4x4, 6>& captureViews, GLuint envCubemap)
|
||||||
{
|
{
|
||||||
constexpr int irradianceMapSize = 32;
|
|
||||||
|
|
||||||
// pbr: create an irradiance cubemap, and re-scale capture FBO to irradiance scale.
|
// pbr: create an irradiance cubemap, and re-scale capture FBO to irradiance scale.
|
||||||
// --------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------
|
||||||
unsigned int irradianceMap;
|
unsigned int irradianceMap;
|
||||||
|
@ -337,8 +337,6 @@ GLuint Renderer::IblUtils::generateIrradianceMap(QOpenGLFunctions_4_5_Core* glFu
|
||||||
|
|
||||||
GLuint Renderer::IblUtils::generatePrefilterMap(QOpenGLFunctions_4_5_Core* glFunc, GLuint captureFBO, GLuint captureRBO, const QMatrix4x4& captureProjection, const std::array<QMatrix4x4, 6>& captureViews, GLuint envCubemap)
|
GLuint Renderer::IblUtils::generatePrefilterMap(QOpenGLFunctions_4_5_Core* glFunc, GLuint captureFBO, GLuint captureRBO, const QMatrix4x4& captureProjection, const std::array<QMatrix4x4, 6>& captureViews, GLuint envCubemap)
|
||||||
{
|
{
|
||||||
constexpr int prefilterMapSize = 128;
|
|
||||||
|
|
||||||
// pbr: create a pre-filter cubemap, and re-scale capture FBO to pre-filter scale.
|
// pbr: create a pre-filter cubemap, and re-scale capture FBO to pre-filter scale.
|
||||||
// --------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------
|
||||||
unsigned int prefilterMap;
|
unsigned int prefilterMap;
|
||||||
|
|
|
@ -7,6 +7,8 @@ namespace Renderer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static constexpr int cubemapSize = 1024;
|
static constexpr int cubemapSize = 1024;
|
||||||
|
static constexpr int irradianceMapSize = 32;
|
||||||
|
static constexpr int prefilterMapSize = 128;
|
||||||
static void renderCube(QOpenGLFunctions_4_5_Core* glFunc);
|
static void renderCube(QOpenGLFunctions_4_5_Core* glFunc);
|
||||||
static void renderSphere(QOpenGLFunctions_4_5_Core* glFunc);
|
static void renderSphere(QOpenGLFunctions_4_5_Core* glFunc);
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -311,18 +311,20 @@ GLuint Renderer::Model::loadPainting(std::string path)
|
||||||
std::make_shared<Element>(Element{ contour[2], style[0]}),
|
std::make_shared<Element>(Element{ contour[2], style[0]}),
|
||||||
};
|
};
|
||||||
Painting painting;
|
Painting painting;
|
||||||
//for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 1000; i++)
|
||||||
//{
|
{
|
||||||
// float x = (float)rand() / RAND_MAX * 2 - 1;
|
float x = (float)rand() / RAND_MAX * 2 - 1;
|
||||||
// float y = (float)rand() / RAND_MAX * 2 - 1;
|
float y = (float)rand() / RAND_MAX * 2 - 1;
|
||||||
// float z = 0.05 + x;//(float)rand() / RAND_MAX * (0.1) + x;
|
float z = 0.05 + x;//(float)rand() / RAND_MAX * (0.1) + x;
|
||||||
// float w = 0.05 + y;//(float)rand() / RAND_MAX * (0.1) + y;
|
float w = 0.05 + y;//(float)rand() / RAND_MAX * (0.1) + y;
|
||||||
// //rootBvhTreeData.push_back(BvhTreeData(QVector4D(x, y, z, w), 0, encodeZIndexAngle(1, (float)rand() / RAND_MAX * 360)));
|
//rootBvhTreeData.push_back(BvhTreeData(QVector4D(x, y, z, w), 0, encodeZIndexAngle(1, (float)rand() / RAND_MAX * 360)));
|
||||||
//painting.addElement(element[i%3], QVector4D(x, y, z, w), (float)rand() / RAND_MAX * 360, 1);
|
//painting.addElement(element[i%3], QVector4D(x, y, z, w), (float)rand() / RAND_MAX * 360, 1);
|
||||||
//}
|
painting.addElement(*element[i%3], ElementTransform{ glm::vec2(x,y), glm::vec2(0.05), (float)rand() / RAND_MAX * 360, glm::bvec2(false), 0 });
|
||||||
painting.addElement(*element[0], ElementTransform{ glm::vec2(-0.5,-0.45), glm::vec2(0.6,0.7), 45, glm::bvec2(true, false), 0 });
|
|
||||||
painting.addElement(*element[1], ElementTransform{ glm::vec2(-0.45,0.45), glm::vec2(0.5,0.5), 0, glm::bvec2(false), 0 });
|
}
|
||||||
painting.addElement(*element[2], ElementTransform{ glm::vec2(0.5,-0.45), glm::vec2(0.6,0.7), 0, glm::bvec2(false), 0 });
|
//painting.addElement(*element[0], ElementTransform{ glm::vec2(-0.5,-0.45), glm::vec2(0.6,0.7), 45, glm::bvec2(true, false), 0 });
|
||||||
|
//painting.addElement(*element[1], ElementTransform{ glm::vec2(-0.45,0.45), glm::vec2(0.5,0.5), 0, glm::bvec2(false), 0 });
|
||||||
|
//painting.addElement(*element[2], ElementTransform{ glm::vec2(0.5,-0.45), glm::vec2(0.6,0.7), 0, glm::bvec2(false), 0 });
|
||||||
|
|
||||||
|
|
||||||
//painting.addElement(element[0], QVector4D(-0.8, -0.8, -0.2, -0.1), 0, 0);
|
//painting.addElement(element[0], QVector4D(-0.8, -0.8, -0.2, -0.1), 0, 0);
|
||||||
|
|
|
@ -26,8 +26,9 @@ RendererGLWidget::RendererGLWidget(QWidget* parent)
|
||||||
//startTimer();
|
//startTimer();
|
||||||
lastFrame = std::clock();
|
lastFrame = std::clock();
|
||||||
setFocusPolicy(Qt::StrongFocus);
|
setFocusPolicy(Qt::StrongFocus);
|
||||||
QSurfaceFormat format;
|
//QSurfaceFormat format;
|
||||||
format.setSwapInterval(0);
|
//format.setProfile(QSurfaceFormat::CoreProfile);
|
||||||
|
////format.setSwapInterval(0);
|
||||||
//setFormat(format);
|
//setFormat(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +61,10 @@ void RendererGLWidget::startTimer()
|
||||||
{
|
{
|
||||||
//startTimer(1000 / QGuiApplication::primaryScreen()->refreshRate());
|
//startTimer(1000 / QGuiApplication::primaryScreen()->refreshRate());
|
||||||
if (timerId == -1)
|
if (timerId == -1)
|
||||||
|
{
|
||||||
timerId = QObject::startTimer(1);
|
timerId = QObject::startTimer(1);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererGLWidget::stopTimer()
|
void RendererGLWidget::stopTimer()
|
||||||
|
@ -102,7 +106,7 @@ void Renderer::RendererGLWidget::setExposure(float exposure)
|
||||||
|
|
||||||
QOpenGLTexture randomMap(QOpenGLTexture::Target2D);
|
QOpenGLTexture randomMap(QOpenGLTexture::Target2D);
|
||||||
|
|
||||||
void GLAPIENTRY MessageCallback(GLenum source,
|
void GLAPIENTRY messageCallback(GLenum source,
|
||||||
GLenum type,
|
GLenum type,
|
||||||
GLuint id,
|
GLuint id,
|
||||||
GLenum severity,
|
GLenum severity,
|
||||||
|
@ -128,7 +132,8 @@ void RendererGLWidget::initializeGL()
|
||||||
qDebug() << "GL_VERSION" << (char*)gl->GetString(GL_VERSION);
|
qDebug() << "GL_VERSION" << (char*)gl->GetString(GL_VERSION);
|
||||||
|
|
||||||
gl->Enable(GL_DEBUG_OUTPUT);
|
gl->Enable(GL_DEBUG_OUTPUT);
|
||||||
gl->DebugMessageCallback(MessageCallback, 0);
|
//gl->Enable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
|
||||||
|
gl->DebugMessageCallback(messageCallback, 0);
|
||||||
|
|
||||||
gl->Enable(GL_DEPTH_TEST);
|
gl->Enable(GL_DEPTH_TEST);
|
||||||
gl->DepthFunc(GL_LEQUAL);
|
gl->DepthFunc(GL_LEQUAL);
|
||||||
|
@ -252,6 +257,7 @@ void RendererGLWidget::initializeGL()
|
||||||
finalProgramPtr->release();
|
finalProgramPtr->release();
|
||||||
|
|
||||||
vtManager = std::make_unique<VirtualTextureManager>(gl.get());
|
vtManager = std::make_unique<VirtualTextureManager>(gl.get());
|
||||||
|
|
||||||
paintingHelper = new PaintingHelper(glFunc);
|
paintingHelper = new PaintingHelper(glFunc);
|
||||||
model = new Model(context(), modelProgramPtr, paintingProgramPtr, shadowProgramPtr, paintingHelper, vtManager.get());
|
model = new Model(context(), modelProgramPtr, paintingProgramPtr, shadowProgramPtr, paintingHelper, vtManager.get());
|
||||||
|
|
||||||
|
@ -283,17 +289,28 @@ void RendererGLWidget::initializeGL()
|
||||||
reinterpret_cast<void*>(3 * sizeof(GLfloat)));
|
reinterpret_cast<void*>(3 * sizeof(GLfloat)));
|
||||||
quadVBO.release();
|
quadVBO.release();
|
||||||
|
|
||||||
|
gl->GenQueries(1, &timeQuery);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererGLWidget::paintGL()
|
void RendererGLWidget::paintGL()
|
||||||
{
|
{
|
||||||
QOpenGLFunctions_4_5_Core* glFunc = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_4_5_Core>();
|
QOpenGLFunctions_4_5_Core* glFunc = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_4_5_Core>();
|
||||||
GLuint timeQuery;
|
|
||||||
gl->GenQueries(1, &timeQuery);
|
|
||||||
gl->BeginQuery(GL_TIME_ELAPSED, timeQuery);
|
|
||||||
|
|
||||||
|
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.));
|
||||||
|
fboPtr->bind();
|
||||||
|
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());
|
||||||
|
//gl->GetTextureSubImage(gbuffers[4], 0, 0, 0, 0, ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1, GL_RG_INTEGER, GL_UNSIGNED_SHORT, pixels.size() * sizeof(glm::u16vec2), pixels.data());
|
||||||
|
fboPtr->release();
|
||||||
|
vtManager->tryUpdatePages(pixels);
|
||||||
|
|
||||||
|
|
||||||
|
gl->BeginQuery(GL_TIME_ELAPSED, timeQuery);
|
||||||
|
|
||||||
|
|
||||||
gl->Enable(GL_CULL_FACE);
|
gl->Enable(GL_CULL_FACE);
|
||||||
|
@ -311,6 +328,7 @@ void RendererGLWidget::paintGL()
|
||||||
}
|
}
|
||||||
gl->BindBuffer(GL_UNIFORM_BUFFER, 0);
|
gl->BindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
|
|
||||||
|
vtManager->commitMutex.lock();
|
||||||
{
|
{
|
||||||
gl->BindFramebuffer(GL_FRAMEBUFFER, shadowFboHandle);
|
gl->BindFramebuffer(GL_FRAMEBUFFER, shadowFboHandle);
|
||||||
gl->Viewport(0, 0, shadowMapResolution, shadowMapResolution);
|
gl->Viewport(0, 0, shadowMapResolution, shadowMapResolution);
|
||||||
|
@ -365,20 +383,10 @@ void RendererGLWidget::paintGL()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
plainProgramPtr->release();
|
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();
|
fboPtr->release();
|
||||||
}
|
}
|
||||||
|
gl->Finish();
|
||||||
|
vtManager->commitMutex.unlock();
|
||||||
|
|
||||||
//depthInitProgramPtr->bind();
|
//depthInitProgramPtr->bind();
|
||||||
//gl->ActiveTexture(GL_TEXTURE0);
|
//gl->ActiveTexture(GL_TEXTURE0);
|
||||||
|
@ -479,7 +487,8 @@ void RendererGLWidget::paintGL()
|
||||||
if (accTime > 1.)
|
if (accTime > 1.)
|
||||||
{
|
{
|
||||||
std::cout << std::format("{:20}\r", "");
|
std::cout << std::format("{:20}\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());
|
std::cout << std::format("FPS: {:.2f}({:.2f}ms) Page: {:}ms Pos: {:.2f},{:.2f},{:.2f}\r", frameCnt / accTime, averageDuration / 1e6 / frameCnt, vtManager->pageLoadDuration / 1e6, camera.Position.x(), camera.Position.y(), camera.Position.z());
|
||||||
|
vtManager->pageLoadDuration = 0;
|
||||||
accTime = 0;
|
accTime = 0;
|
||||||
frameCnt = 0;
|
frameCnt = 0;
|
||||||
averageDuration = 0;
|
averageDuration = 0;
|
||||||
|
@ -583,8 +592,8 @@ void RendererGLWidget::resizeGL(int width, int height)
|
||||||
gl->TexImage2D(GL_TEXTURE_2D, i, GL_R32F, depthWidth / pow(2, i), depthHeight / pow(2, i), 0, GL_RED, GL_FLOAT, NULL);
|
gl->TexImage2D(GL_TEXTURE_2D, i, GL_R32F, depthWidth / pow(2, i), depthHeight / pow(2, i), 0, GL_RED, GL_FLOAT, NULL);
|
||||||
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||||
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 6);
|
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 6);
|
||||||
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
|
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST);
|
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||||
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||||
gl->TexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, std::begin({ 1.0f, 1.0f, 1.0f, 1.0f }));
|
gl->TexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, std::begin({ 1.0f, 1.0f, 1.0f, 1.0f }));
|
||||||
|
|
|
@ -80,5 +80,7 @@ namespace Renderer
|
||||||
Model* model = nullptr;
|
Model* model = nullptr;
|
||||||
PaintingHelper* paintingHelper;
|
PaintingHelper* paintingHelper;
|
||||||
std::unique_ptr<VirtualTextureManager> vtManager;
|
std::unique_ptr<VirtualTextureManager> vtManager;
|
||||||
|
|
||||||
|
GLuint timeQuery;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,34 @@
|
||||||
#include <glad/gl.h>
|
#include <glad/gl.h>
|
||||||
#include "VirtualTextureManager.h"
|
#include "VirtualTextureManager.h"
|
||||||
|
#include <QOffscreenSurface>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <stb_image.h>
|
|
||||||
#include <glm/gtc/integer.hpp>
|
#include <glm/gtc/integer.hpp>
|
||||||
#define GLM_ENABLE_EXPERIMENTAL
|
#define GLM_ENABLE_EXPERIMENTAL
|
||||||
#include <glm/gtx/component_wise.hpp>
|
#include <glm/gtx/component_wise.hpp>
|
||||||
|
|
||||||
|
std::mutex pageIdBufferMutex;
|
||||||
|
|
||||||
Renderer::VirtualTextureManager::VirtualTextureManager(GladGLContext* gl)
|
Renderer::VirtualTextureManager::VirtualTextureManager(GladGLContext* glMain)
|
||||||
:gl(gl)
|
:glMain(glMain)
|
||||||
{
|
{
|
||||||
|
auto mainContext = QOpenGLContext::currentContext();
|
||||||
|
auto mainSurface = mainContext->surface();
|
||||||
|
surface.setFormat(mainContext->format());
|
||||||
|
surface.create();
|
||||||
|
mainContext->doneCurrent();
|
||||||
|
|
||||||
|
thread = std::jthread([&] {
|
||||||
|
QOpenGLContext context;
|
||||||
|
context.setFormat(mainContext->format());
|
||||||
|
context.setShareContext(mainContext);
|
||||||
|
context.create();
|
||||||
|
context.makeCurrent(&surface);
|
||||||
|
|
||||||
|
gl = std::make_unique<GladGLContext>();
|
||||||
|
if (!gladLoadGLContext(gl.get(), [](const char* name) { return (GLADapiproc)QOpenGLContext::currentContext()->getProcAddress(name); }))
|
||||||
|
qCritical() << "Failed to initialize GLAD";
|
||||||
|
|
||||||
GLint numPageSizes;
|
GLint numPageSizes;
|
||||||
|
|
||||||
// Figure out how many page sizes are available for a 2D texture
|
// Figure out how many page sizes are available for a 2D texture
|
||||||
|
@ -39,12 +57,42 @@ Renderer::VirtualTextureManager::VirtualTextureManager(GladGLContext* gl)
|
||||||
pageSize = std::max(pageSizesRG8X[0], pageSizesRG8Y[0]);
|
pageSize = std::max(pageSizesRG8X[0], pageSizesRG8Y[0]);
|
||||||
qDebug() << "pageSize:" << pageSize;
|
qDebug() << "pageSize:" << pageSize;
|
||||||
|
|
||||||
|
|
||||||
if (!program.addShaderFromSourceFile(QOpenGLShader::Compute, ":/Shaders/painting.comp"))
|
if (!program.addShaderFromSourceFile(QOpenGLShader::Compute, ":/Shaders/painting.comp"))
|
||||||
qDebug() << "ERROR:" << program.log();
|
qDebug() << "ERROR:" << program.log();
|
||||||
if (!program.link())
|
if (!program.link())
|
||||||
qDebug() << "ERROR:" << program.log();
|
qDebug() << "ERROR:" << program.log();
|
||||||
|
|
||||||
|
initialized = true;
|
||||||
|
|
||||||
|
GLuint pageLoadTimeQuery;
|
||||||
|
gl->GenQueries(1, &pageLoadTimeQuery);
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (needUpdate)
|
||||||
|
{
|
||||||
|
needUpdate = false;
|
||||||
|
auto& pageIds = pageIdsBuffer[currentBuffer];
|
||||||
|
pageIdBufferMutex.lock();
|
||||||
|
currentBuffer = 1 - currentBuffer;
|
||||||
|
pageIdBufferMutex.unlock();
|
||||||
|
|
||||||
|
gl->BeginQuery(GL_TIME_ELAPSED, pageLoadTimeQuery);
|
||||||
|
updatePages(pageIds);
|
||||||
|
gl->EndQuery(GL_TIME_ELAPSED);
|
||||||
|
GLuint duration;
|
||||||
|
gl->GetQueryObjectuiv(pageLoadTimeQuery, GL_QUERY_RESULT, &duration);
|
||||||
|
//qDebug() << duration;
|
||||||
|
pageLoadDuration += duration;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
while (!initialized)
|
||||||
|
std::this_thread::yield();
|
||||||
|
|
||||||
|
mainContext->makeCurrent(mainSurface);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint16_t Renderer::VirtualTextureManager::createVirtualTexture(Painting painting)
|
std::uint16_t Renderer::VirtualTextureManager::createVirtualTexture(Painting painting)
|
||||||
|
@ -53,30 +101,30 @@ std::uint16_t Renderer::VirtualTextureManager::createVirtualTexture(Painting pai
|
||||||
qDebug() << "levels:" << levels;
|
qDebug() << "levels:" << levels;
|
||||||
|
|
||||||
GLuint textures[2];
|
GLuint textures[2];
|
||||||
gl->CreateTextures(GL_TEXTURE_2D, 2, textures);
|
glMain->CreateTextures(GL_TEXTURE_2D, 2, textures);
|
||||||
GLuint& baseColor = textures[0];
|
GLuint& baseColor = textures[0];
|
||||||
GLuint& metallicRoughness = textures[1];
|
GLuint& metallicRoughness = textures[1];
|
||||||
|
|
||||||
gl->TextureParameteri(baseColor, GL_TEXTURE_SPARSE_ARB, GL_TRUE);
|
glMain->TextureParameteri(baseColor, GL_TEXTURE_SPARSE_ARB, GL_TRUE);
|
||||||
gl->TextureParameteri(baseColor, GL_TEXTURE_BASE_LEVEL, 0);
|
glMain->TextureParameteri(baseColor, GL_TEXTURE_BASE_LEVEL, 0);
|
||||||
gl->TextureParameteri(baseColor, GL_TEXTURE_MAX_LEVEL, levels - 1);
|
glMain->TextureParameteri(baseColor, GL_TEXTURE_MAX_LEVEL, levels - 1);
|
||||||
gl->TextureParameteri(baseColor, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
glMain->TextureParameteri(baseColor, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
gl->TextureParameteri(baseColor, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
glMain->TextureParameteri(baseColor, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
gl->TextureParameteri(baseColor, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
glMain->TextureParameteri(baseColor, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
||||||
gl->TextureParameteri(baseColor, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glMain->TextureParameteri(baseColor, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
gl->TextureStorage2D(baseColor, levels, GL_RGBA8, GLsizei(textureSize), GLsizei(textureSize));
|
glMain->TextureStorage2D(baseColor, levels, GL_RGBA8, GLsizei(textureSize), GLsizei(textureSize));
|
||||||
|
|
||||||
gl->TextureParameteri(metallicRoughness, GL_TEXTURE_SPARSE_ARB, GL_TRUE);
|
glMain->TextureParameteri(metallicRoughness, GL_TEXTURE_SPARSE_ARB, GL_TRUE);
|
||||||
gl->TextureParameteri(metallicRoughness, GL_TEXTURE_BASE_LEVEL, 0);
|
glMain->TextureParameteri(metallicRoughness, GL_TEXTURE_BASE_LEVEL, 0);
|
||||||
gl->TextureParameteri(metallicRoughness, GL_TEXTURE_MAX_LEVEL, levels - 1);
|
glMain->TextureParameteri(metallicRoughness, GL_TEXTURE_MAX_LEVEL, levels - 1);
|
||||||
gl->TextureParameteri(metallicRoughness, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
glMain->TextureParameteri(metallicRoughness, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
gl->TextureParameteri(metallicRoughness, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
glMain->TextureParameteri(metallicRoughness, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
gl->TextureParameteri(metallicRoughness, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
glMain->TextureParameteri(metallicRoughness, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
||||||
gl->TextureParameteri(metallicRoughness, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glMain->TextureParameteri(metallicRoughness, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
gl->TextureStorage2D(metallicRoughness, levels, GL_RG8, GLsizei(textureSize), GLsizei(textureSize));
|
glMain->TextureStorage2D(metallicRoughness, levels, GL_RG8, GLsizei(textureSize), GLsizei(textureSize));
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++)
|
for (int i = 0; i < 5; i++)
|
||||||
gl->BindBufferBase(GL_SHADER_STORAGE_BUFFER, i, painting.buffers[i]);
|
glMain->BindBufferBase(GL_SHADER_STORAGE_BUFFER, i, painting.buffers[i]);
|
||||||
|
|
||||||
for (auto level = levels - 1; level < levels; ++level)
|
for (auto level = levels - 1; level < levels; ++level)
|
||||||
{
|
{
|
||||||
|
@ -84,20 +132,20 @@ std::uint16_t Renderer::VirtualTextureManager::createVirtualTexture(Painting pai
|
||||||
for (GLsizei j = 0; j < levelSize / pageSize; ++j)
|
for (GLsizei j = 0; j < levelSize / pageSize; ++j)
|
||||||
for (GLsizei i = 0; i < levelSize / pageSize; ++i)
|
for (GLsizei i = 0; i < levelSize / pageSize; ++i)
|
||||||
{
|
{
|
||||||
gl->TexturePageCommitmentEXT(baseColor, static_cast<GLint>(level),
|
glMain->TexturePageCommitmentEXT(baseColor, static_cast<GLint>(level),
|
||||||
static_cast<GLsizei>(pageSize) * i, static_cast<GLsizei>(pageSize) * j, 0,
|
static_cast<GLsizei>(pageSize) * i, static_cast<GLsizei>(pageSize) * j, 0,
|
||||||
static_cast<GLsizei>(pageSize), static_cast<GLsizei>(pageSize), 1,
|
static_cast<GLsizei>(pageSize), static_cast<GLsizei>(pageSize), 1,
|
||||||
GL_TRUE);
|
GL_TRUE);
|
||||||
gl->TexturePageCommitmentEXT(metallicRoughness, static_cast<GLint>(level),
|
glMain->TexturePageCommitmentEXT(metallicRoughness, static_cast<GLint>(level),
|
||||||
static_cast<GLsizei>(pageSize) * i, static_cast<GLsizei>(pageSize) * j, 0,
|
static_cast<GLsizei>(pageSize) * i, static_cast<GLsizei>(pageSize) * j, 0,
|
||||||
static_cast<GLsizei>(pageSize), static_cast<GLsizei>(pageSize), 1,
|
static_cast<GLsizei>(pageSize), static_cast<GLsizei>(pageSize), 1,
|
||||||
GL_TRUE);
|
GL_TRUE);
|
||||||
|
|
||||||
program.bind();
|
program.bind();
|
||||||
gl->Uniform2i(gl->GetUniformLocation(program.programId(), "pixelOffset"), static_cast<GLsizei>(pageSize) * i, static_cast<GLsizei>(pageSize) * j);
|
glMain->Uniform2i(gl->GetUniformLocation(program.programId(), "pixelOffset"), static_cast<GLsizei>(pageSize) * i, static_cast<GLsizei>(pageSize) * j);
|
||||||
gl->BindImageTexture(0, baseColor, level, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8);
|
glMain->BindImageTexture(0, baseColor, level, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8);
|
||||||
gl->BindImageTexture(1, metallicRoughness, level, GL_FALSE, 0, GL_READ_WRITE, GL_RG8);
|
glMain->BindImageTexture(1, metallicRoughness, level, GL_FALSE, 0, GL_READ_WRITE, GL_RG8);
|
||||||
gl->DispatchCompute(pageSize / 8, pageSize / 8, 1);
|
glMain->DispatchCompute(pageSize / 8, pageSize / 8, 1);
|
||||||
program.release();
|
program.release();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -111,12 +159,22 @@ Renderer::PaintingHandle& Renderer::VirtualTextureManager::getPaintingHandle(std
|
||||||
return paintings[id - 1];
|
return paintings[id - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Renderer::VirtualTextureManager::tryUpdatePages(const std::vector<glm::u16vec2>& pageIds)
|
||||||
|
{
|
||||||
|
pageIdBufferMutex.lock();
|
||||||
|
pageIdsBuffer[currentBuffer] = pageIds;
|
||||||
|
pageIdBufferMutex.unlock();
|
||||||
|
needUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
void Renderer::VirtualTextureManager::pageCommitmentById(const glm::u16vec2& pageId, GLboolean commit)
|
void Renderer::VirtualTextureManager::pageCommitmentById(const glm::u16vec2& pageId, GLboolean commit)
|
||||||
{
|
{
|
||||||
auto& painting = getPaintingHandle(pageId.x >> 4);
|
auto& painting = getPaintingHandle(pageId.x >> 4);
|
||||||
GLint level = pageId.x & 0b1111;
|
GLint level = pageId.x & 0b1111;
|
||||||
glm::ivec2 page(pageId.y & 0b11111111, pageId.y >> 8);
|
glm::ivec2 page(pageId.y & 0b11111111, pageId.y >> 8);
|
||||||
qDebug() << commit << level << page.x << page.y;
|
//qDebug() << commit << level << page.x << page.y;
|
||||||
|
commitMutex.lock();
|
||||||
|
|
||||||
gl->TexturePageCommitmentEXT(painting.baseColor, level,
|
gl->TexturePageCommitmentEXT(painting.baseColor, level,
|
||||||
static_cast<GLsizei>(pageSize) * page.x, static_cast<GLsizei>(pageSize) * page.y, 0,
|
static_cast<GLsizei>(pageSize) * page.x, static_cast<GLsizei>(pageSize) * page.y, 0,
|
||||||
static_cast<GLsizei>(pageSize), static_cast<GLsizei>(pageSize), 1,
|
static_cast<GLsizei>(pageSize), static_cast<GLsizei>(pageSize), 1,
|
||||||
|
@ -129,12 +187,16 @@ void Renderer::VirtualTextureManager::pageCommitmentById(const glm::u16vec2& pag
|
||||||
if (commit)
|
if (commit)
|
||||||
{
|
{
|
||||||
program.bind();
|
program.bind();
|
||||||
|
for (int i = 0; i < 5; i++)
|
||||||
|
gl->BindBufferBase(GL_SHADER_STORAGE_BUFFER, i, painting.buffers[i]);
|
||||||
gl->Uniform2i(gl->GetUniformLocation(program.programId(), "pixelOffset"), static_cast<GLsizei>(pageSize) * page.x, static_cast<GLsizei>(pageSize) * page.y);
|
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(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->BindImageTexture(1, painting.metallicRoughness, level, GL_FALSE, 0, GL_READ_WRITE, GL_RG8);
|
||||||
gl->DispatchCompute(pageSize / 8, pageSize / 8, 1);
|
gl->DispatchCompute(pageSize / 8, pageSize / 8, 1);
|
||||||
program.release();
|
program.release();
|
||||||
}
|
}
|
||||||
|
gl->Finish();
|
||||||
|
commitMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::VirtualTextureManager::updatePages(const std::vector<glm::u16vec2>& pageIds)
|
void Renderer::VirtualTextureManager::updatePages(const std::vector<glm::u16vec2>& pageIds)
|
||||||
|
@ -158,7 +220,6 @@ void Renderer::VirtualTextureManager::updatePages(const std::vector<glm::u16vec2
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
pageCommitmentById(pageId, GL_TRUE);
|
pageCommitmentById(pageId, GL_TRUE);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
iter->second = lifeTime;
|
iter->second = lifeTime;
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
#include "Painting/Painting.h"
|
#include "Painting/Painting.h"
|
||||||
#include <QOpenGLShaderProgram>
|
#include <QOpenGLShaderProgram>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <thread>
|
||||||
|
#include <atomic>
|
||||||
|
#include <mutex>
|
||||||
|
#include <QOffscreenSurface>
|
||||||
|
|
||||||
struct GladGLContext;
|
struct GladGLContext;
|
||||||
|
|
||||||
|
@ -17,7 +21,7 @@ namespace Renderer
|
||||||
class VirtualTextureManager
|
class VirtualTextureManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VirtualTextureManager(GladGLContext* gl);
|
VirtualTextureManager(GladGLContext* glMain);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
|
@ -26,9 +30,17 @@ namespace Renderer
|
||||||
*/
|
*/
|
||||||
std::uint16_t createVirtualTexture(Painting painting);
|
std::uint16_t createVirtualTexture(Painting painting);
|
||||||
PaintingHandle& getPaintingHandle(std::uint16_t id);
|
PaintingHandle& getPaintingHandle(std::uint16_t id);
|
||||||
void updatePages(const std::vector<glm::u16vec2>& pageIds);
|
void tryUpdatePages(const std::vector<glm::u16vec2>& pageIds);
|
||||||
|
|
||||||
|
std::atomic<bool> initialized = false;
|
||||||
|
std::atomic<bool> needUpdate = false;
|
||||||
|
std::atomic<GLuint> pageLoadDuration = 0;
|
||||||
|
std::mutex commitMutex;
|
||||||
private:
|
private:
|
||||||
GladGLContext* gl;
|
std::jthread thread;
|
||||||
|
QOffscreenSurface surface;
|
||||||
|
std::unique_ptr<GladGLContext> gl;
|
||||||
|
GladGLContext* glMain;
|
||||||
static constexpr GLsizei textureSize = 16384;
|
static constexpr GLsizei textureSize = 16384;
|
||||||
static constexpr int lifeTime = 64;
|
static constexpr int lifeTime = 64;
|
||||||
GLint pageSize;
|
GLint pageSize;
|
||||||
|
@ -42,9 +54,11 @@ namespace Renderer
|
||||||
return ((std::size_t)v.y << 16) + v.x;
|
return ((std::size_t)v.y << 16) + v.x;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unordered_map<glm::u16vec2, int, u16vec2Hash> loadedPages;
|
std::unordered_map<glm::u16vec2, int, u16vec2Hash> loadedPages;
|
||||||
|
std::vector<glm::u16vec2> pageIdsBuffer[2];
|
||||||
|
int currentBuffer = 0;
|
||||||
|
|
||||||
|
void updatePages(const std::vector<glm::u16vec2>& pageIds);
|
||||||
void pageCommitmentById(const glm::u16vec2& pageId, GLboolean commit);
|
void pageCommitmentById(const glm::u16vec2& pageId, GLboolean commit);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#include <QtWidgets/QApplication>
|
#include <QtWidgets/QApplication>
|
||||||
#include "ElementRendererTest.h"
|
#include "ElementRendererTest.h"
|
||||||
#include "Renderer/Painting/ElementStyle.h"
|
#include "Renderer/Painting/ElementStyle.h"
|
||||||
|
#include <qtemporaryfile.h>
|
||||||
|
|
||||||
|
|
||||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||||
using namespace Renderer;
|
using namespace Renderer;
|
||||||
|
@ -12,6 +14,12 @@ namespace UnitTest
|
||||||
TEST_CLASS(ElementRendererStokeTypeTest)
|
TEST_CLASS(ElementRendererStokeTypeTest)
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
TEST_METHOD(TestFile)
|
||||||
|
{
|
||||||
|
QFile file("D:\\BigC2022\\temp\\ArchitectureColoredPainting\\README.md");
|
||||||
|
Logger::WriteMessage(file.open(QIODevice::ReadOnly)? "True":"False");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_METHOD(TestBothSidesRound)
|
TEST_METHOD(TestBothSidesRound)
|
||||||
{
|
{
|
||||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||||
|
|
Loading…
Reference in New Issue