实现虚拟纹理的异步加载
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>
|
||||
<PreprocessorDefinitions>FRAMELESSHELPER_WIDGETS_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<WarningLevel>Level1</WarningLevel>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
|
@ -81,7 +82,7 @@
|
|||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
|
|
|
@ -182,8 +182,8 @@ std::tuple<GLuint, GLuint, GLuint, GLuint> Renderer::IblUtils::precomputeCubemap
|
|||
// ----------------------
|
||||
unsigned int captureFBO;
|
||||
unsigned int captureRBO;
|
||||
glFunc->glGenFramebuffers(1, &captureFBO);
|
||||
glFunc->glGenRenderbuffers(1, &captureRBO);
|
||||
glFunc->glCreateFramebuffers(1, &captureFBO);
|
||||
glFunc->glCreateRenderbuffers(1, &captureRBO);
|
||||
|
||||
glFunc->glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
|
||||
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->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->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)
|
||||
{
|
||||
constexpr int irradianceMapSize = 32;
|
||||
|
||||
// pbr: create an irradiance cubemap, and re-scale capture FBO to irradiance scale.
|
||||
// --------------------------------------------------------------------------------
|
||||
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)
|
||||
{
|
||||
constexpr int prefilterMapSize = 128;
|
||||
|
||||
// pbr: create a pre-filter cubemap, and re-scale capture FBO to pre-filter scale.
|
||||
// --------------------------------------------------------------------------------
|
||||
unsigned int prefilterMap;
|
||||
|
|
|
@ -7,6 +7,8 @@ namespace Renderer
|
|||
{
|
||||
public:
|
||||
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 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]}),
|
||||
};
|
||||
Painting painting;
|
||||
//for (int i = 0; i < 3; i++)
|
||||
//{
|
||||
// float x = (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 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)));
|
||||
// painting.addElement(element[i%3], QVector4D(x, y, z, w), (float)rand() / RAND_MAX * 360, 1);
|
||||
//}
|
||||
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 });
|
||||
for (int i = 0; i < 1000; i++)
|
||||
{
|
||||
float x = (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 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)));
|
||||
//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], QVector4D(-0.8, -0.8, -0.2, -0.1), 0, 0);
|
||||
|
|
|
@ -26,8 +26,9 @@ RendererGLWidget::RendererGLWidget(QWidget* parent)
|
|||
//startTimer();
|
||||
lastFrame = std::clock();
|
||||
setFocusPolicy(Qt::StrongFocus);
|
||||
QSurfaceFormat format;
|
||||
format.setSwapInterval(0);
|
||||
//QSurfaceFormat format;
|
||||
//format.setProfile(QSurfaceFormat::CoreProfile);
|
||||
////format.setSwapInterval(0);
|
||||
//setFormat(format);
|
||||
}
|
||||
|
||||
|
@ -60,7 +61,10 @@ void RendererGLWidget::startTimer()
|
|||
{
|
||||
//startTimer(1000 / QGuiApplication::primaryScreen()->refreshRate());
|
||||
if (timerId == -1)
|
||||
{
|
||||
timerId = QObject::startTimer(1);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void RendererGLWidget::stopTimer()
|
||||
|
@ -102,7 +106,7 @@ void Renderer::RendererGLWidget::setExposure(float exposure)
|
|||
|
||||
QOpenGLTexture randomMap(QOpenGLTexture::Target2D);
|
||||
|
||||
void GLAPIENTRY MessageCallback(GLenum source,
|
||||
void GLAPIENTRY messageCallback(GLenum source,
|
||||
GLenum type,
|
||||
GLuint id,
|
||||
GLenum severity,
|
||||
|
@ -128,7 +132,8 @@ void RendererGLWidget::initializeGL()
|
|||
qDebug() << "GL_VERSION" << (char*)gl->GetString(GL_VERSION);
|
||||
|
||||
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->DepthFunc(GL_LEQUAL);
|
||||
|
@ -252,6 +257,7 @@ void RendererGLWidget::initializeGL()
|
|||
finalProgramPtr->release();
|
||||
|
||||
vtManager = std::make_unique<VirtualTextureManager>(gl.get());
|
||||
|
||||
paintingHelper = new PaintingHelper(glFunc);
|
||||
model = new Model(context(), modelProgramPtr, paintingProgramPtr, shadowProgramPtr, paintingHelper, vtManager.get());
|
||||
|
||||
|
@ -283,17 +289,28 @@ void RendererGLWidget::initializeGL()
|
|||
reinterpret_cast<void*>(3 * sizeof(GLfloat)));
|
||||
quadVBO.release();
|
||||
|
||||
|
||||
|
||||
gl->GenQueries(1, &timeQuery);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
@ -311,6 +328,7 @@ void RendererGLWidget::paintGL()
|
|||
}
|
||||
gl->BindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
|
||||
vtManager->commitMutex.lock();
|
||||
{
|
||||
gl->BindFramebuffer(GL_FRAMEBUFFER, shadowFboHandle);
|
||||
gl->Viewport(0, 0, shadowMapResolution, shadowMapResolution);
|
||||
|
@ -365,20 +383,10 @@ 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();
|
||||
}
|
||||
gl->Finish();
|
||||
vtManager->commitMutex.unlock();
|
||||
|
||||
//depthInitProgramPtr->bind();
|
||||
//gl->ActiveTexture(GL_TEXTURE0);
|
||||
|
@ -479,7 +487,8 @@ void RendererGLWidget::paintGL()
|
|||
if (accTime > 1.)
|
||||
{
|
||||
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;
|
||||
frameCnt = 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->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_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
|
||||
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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);
|
||||
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->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;
|
||||
PaintingHelper* paintingHelper;
|
||||
std::unique_ptr<VirtualTextureManager> vtManager;
|
||||
|
||||
GLuint timeQuery;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,49 +1,97 @@
|
|||
#include <glad/gl.h>
|
||||
#include "VirtualTextureManager.h"
|
||||
#include <QOffscreenSurface>
|
||||
#include <array>
|
||||
#include <QDebug>
|
||||
#include <stb_image.h>
|
||||
#include <glm/gtc/integer.hpp>
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
#include <glm/gtx/component_wise.hpp>
|
||||
|
||||
std::mutex pageIdBufferMutex;
|
||||
|
||||
Renderer::VirtualTextureManager::VirtualTextureManager(GladGLContext* gl)
|
||||
:gl(gl)
|
||||
Renderer::VirtualTextureManager::VirtualTextureManager(GladGLContext* glMain)
|
||||
:glMain(glMain)
|
||||
{
|
||||
GLint numPageSizes;
|
||||
auto mainContext = QOpenGLContext::currentContext();
|
||||
auto mainSurface = mainContext->surface();
|
||||
surface.setFormat(mainContext->format());
|
||||
surface.create();
|
||||
mainContext->doneCurrent();
|
||||
|
||||
// Figure out how many page sizes are available for a 2D texture
|
||||
gl->GetInternalformativ(GL_TEXTURE_2D, GL_RGBA8, GL_NUM_VIRTUAL_PAGE_SIZES_ARB, sizeof(GLint), &numPageSizes);
|
||||
std::vector<GLint> pageSizesX(numPageSizes);
|
||||
std::vector<GLint> pageSizesY(numPageSizes);
|
||||
std::vector<GLint> pageSizesZ(numPageSizes);
|
||||
gl->GetInternalformativ(GL_TEXTURE_2D, GL_RGBA8, GL_VIRTUAL_PAGE_SIZE_X_ARB, numPageSizes * sizeof(GLint), pageSizesX.data());
|
||||
gl->GetInternalformativ(GL_TEXTURE_2D, GL_RGBA8, GL_VIRTUAL_PAGE_SIZE_Y_ARB, numPageSizes * sizeof(GLint), pageSizesY.data());
|
||||
gl->GetInternalformativ(GL_TEXTURE_2D, GL_RGBA8, GL_VIRTUAL_PAGE_SIZE_Z_ARB, numPageSizes * sizeof(GLint), pageSizesZ.data());
|
||||
qDebug() << "RGBA8" << numPageSizes;
|
||||
for (int i = 0; i < numPageSizes; i++)
|
||||
qDebug() << pageSizesX[i] << pageSizesY[i] << pageSizesZ[i];
|
||||
thread = std::jthread([&] {
|
||||
QOpenGLContext context;
|
||||
context.setFormat(mainContext->format());
|
||||
context.setShareContext(mainContext);
|
||||
context.create();
|
||||
context.makeCurrent(&surface);
|
||||
|
||||
gl->GetInternalformativ(GL_TEXTURE_2D, GL_RG8, GL_NUM_VIRTUAL_PAGE_SIZES_ARB, sizeof(GLint), &numPageSizes);
|
||||
std::vector<GLint> pageSizesRG8X(numPageSizes);
|
||||
std::vector<GLint> pageSizesRG8Y(numPageSizes);
|
||||
std::vector<GLint> pageSizesRG8Z(numPageSizes);
|
||||
gl->GetInternalformativ(GL_TEXTURE_2D, GL_RG8, GL_VIRTUAL_PAGE_SIZE_X_ARB, numPageSizes * sizeof(GLint), pageSizesRG8X.data());
|
||||
gl->GetInternalformativ(GL_TEXTURE_2D, GL_RG8, GL_VIRTUAL_PAGE_SIZE_Y_ARB, numPageSizes * sizeof(GLint), pageSizesRG8Y.data());
|
||||
gl->GetInternalformativ(GL_TEXTURE_2D, GL_RG8, GL_VIRTUAL_PAGE_SIZE_Z_ARB, numPageSizes * sizeof(GLint), pageSizesRG8Z.data());
|
||||
qDebug() << "RG8" << numPageSizes;
|
||||
for (int i = 0; i < numPageSizes; i++)
|
||||
qDebug() << pageSizesRG8X[i] << pageSizesRG8Y[i] << pageSizesRG8Z[i];
|
||||
gl = std::make_unique<GladGLContext>();
|
||||
if (!gladLoadGLContext(gl.get(), [](const char* name) { return (GLADapiproc)QOpenGLContext::currentContext()->getProcAddress(name); }))
|
||||
qCritical() << "Failed to initialize GLAD";
|
||||
|
||||
pageSize = std::max(pageSizesRG8X[0], pageSizesRG8Y[0]);
|
||||
qDebug() << "pageSize:" << pageSize;
|
||||
GLint numPageSizes;
|
||||
|
||||
// Figure out how many page sizes are available for a 2D texture
|
||||
gl->GetInternalformativ(GL_TEXTURE_2D, GL_RGBA8, GL_NUM_VIRTUAL_PAGE_SIZES_ARB, sizeof(GLint), &numPageSizes);
|
||||
std::vector<GLint> pageSizesX(numPageSizes);
|
||||
std::vector<GLint> pageSizesY(numPageSizes);
|
||||
std::vector<GLint> pageSizesZ(numPageSizes);
|
||||
gl->GetInternalformativ(GL_TEXTURE_2D, GL_RGBA8, GL_VIRTUAL_PAGE_SIZE_X_ARB, numPageSizes * sizeof(GLint), pageSizesX.data());
|
||||
gl->GetInternalformativ(GL_TEXTURE_2D, GL_RGBA8, GL_VIRTUAL_PAGE_SIZE_Y_ARB, numPageSizes * sizeof(GLint), pageSizesY.data());
|
||||
gl->GetInternalformativ(GL_TEXTURE_2D, GL_RGBA8, GL_VIRTUAL_PAGE_SIZE_Z_ARB, numPageSizes * sizeof(GLint), pageSizesZ.data());
|
||||
qDebug() << "RGBA8" << numPageSizes;
|
||||
for (int i = 0; i < numPageSizes; i++)
|
||||
qDebug() << pageSizesX[i] << pageSizesY[i] << pageSizesZ[i];
|
||||
|
||||
if (!program.addShaderFromSourceFile(QOpenGLShader::Compute, ":/Shaders/painting.comp"))
|
||||
qDebug() << "ERROR:" << program.log();
|
||||
if (!program.link())
|
||||
qDebug() << "ERROR:" << program.log();
|
||||
gl->GetInternalformativ(GL_TEXTURE_2D, GL_RG8, GL_NUM_VIRTUAL_PAGE_SIZES_ARB, sizeof(GLint), &numPageSizes);
|
||||
std::vector<GLint> pageSizesRG8X(numPageSizes);
|
||||
std::vector<GLint> pageSizesRG8Y(numPageSizes);
|
||||
std::vector<GLint> pageSizesRG8Z(numPageSizes);
|
||||
gl->GetInternalformativ(GL_TEXTURE_2D, GL_RG8, GL_VIRTUAL_PAGE_SIZE_X_ARB, numPageSizes * sizeof(GLint), pageSizesRG8X.data());
|
||||
gl->GetInternalformativ(GL_TEXTURE_2D, GL_RG8, GL_VIRTUAL_PAGE_SIZE_Y_ARB, numPageSizes * sizeof(GLint), pageSizesRG8Y.data());
|
||||
gl->GetInternalformativ(GL_TEXTURE_2D, GL_RG8, GL_VIRTUAL_PAGE_SIZE_Z_ARB, numPageSizes * sizeof(GLint), pageSizesRG8Z.data());
|
||||
qDebug() << "RG8" << numPageSizes;
|
||||
for (int i = 0; i < numPageSizes; i++)
|
||||
qDebug() << pageSizesRG8X[i] << pageSizesRG8Y[i] << pageSizesRG8Z[i];
|
||||
|
||||
pageSize = std::max(pageSizesRG8X[0], pageSizesRG8Y[0]);
|
||||
qDebug() << "pageSize:" << pageSize;
|
||||
|
||||
if (!program.addShaderFromSourceFile(QOpenGLShader::Compute, ":/Shaders/painting.comp"))
|
||||
qDebug() << "ERROR:" << program.log();
|
||||
if (!program.link())
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
|
@ -53,30 +101,30 @@ std::uint16_t Renderer::VirtualTextureManager::createVirtualTexture(Painting pai
|
|||
qDebug() << "levels:" << levels;
|
||||
|
||||
GLuint textures[2];
|
||||
gl->CreateTextures(GL_TEXTURE_2D, 2, textures);
|
||||
glMain->CreateTextures(GL_TEXTURE_2D, 2, textures);
|
||||
GLuint& baseColor = textures[0];
|
||||
GLuint& metallicRoughness = textures[1];
|
||||
|
||||
gl->TextureParameteri(baseColor, GL_TEXTURE_SPARSE_ARB, GL_TRUE);
|
||||
gl->TextureParameteri(baseColor, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
gl->TextureParameteri(baseColor, GL_TEXTURE_MAX_LEVEL, levels - 1);
|
||||
gl->TextureParameteri(baseColor, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
gl->TextureParameteri(baseColor, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
gl->TextureParameteri(baseColor, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
||||
gl->TextureParameteri(baseColor, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
gl->TextureStorage2D(baseColor, levels, GL_RGBA8, GLsizei(textureSize), GLsizei(textureSize));
|
||||
glMain->TextureParameteri(baseColor, GL_TEXTURE_SPARSE_ARB, GL_TRUE);
|
||||
glMain->TextureParameteri(baseColor, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glMain->TextureParameteri(baseColor, GL_TEXTURE_MAX_LEVEL, levels - 1);
|
||||
glMain->TextureParameteri(baseColor, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glMain->TextureParameteri(baseColor, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glMain->TextureParameteri(baseColor, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
||||
glMain->TextureParameteri(baseColor, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glMain->TextureStorage2D(baseColor, levels, GL_RGBA8, GLsizei(textureSize), GLsizei(textureSize));
|
||||
|
||||
gl->TextureParameteri(metallicRoughness, GL_TEXTURE_SPARSE_ARB, GL_TRUE);
|
||||
gl->TextureParameteri(metallicRoughness, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
gl->TextureParameteri(metallicRoughness, GL_TEXTURE_MAX_LEVEL, levels - 1);
|
||||
gl->TextureParameteri(metallicRoughness, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
gl->TextureParameteri(metallicRoughness, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
gl->TextureParameteri(metallicRoughness, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
||||
gl->TextureParameteri(metallicRoughness, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
gl->TextureStorage2D(metallicRoughness, levels, GL_RG8, GLsizei(textureSize), GLsizei(textureSize));
|
||||
glMain->TextureParameteri(metallicRoughness, GL_TEXTURE_SPARSE_ARB, GL_TRUE);
|
||||
glMain->TextureParameteri(metallicRoughness, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glMain->TextureParameteri(metallicRoughness, GL_TEXTURE_MAX_LEVEL, levels - 1);
|
||||
glMain->TextureParameteri(metallicRoughness, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glMain->TextureParameteri(metallicRoughness, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glMain->TextureParameteri(metallicRoughness, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
||||
glMain->TextureParameteri(metallicRoughness, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glMain->TextureStorage2D(metallicRoughness, levels, GL_RG8, GLsizei(textureSize), GLsizei(textureSize));
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -84,20 +132,20 @@ std::uint16_t Renderer::VirtualTextureManager::createVirtualTexture(Painting pai
|
|||
for (GLsizei j = 0; j < levelSize / pageSize; ++j)
|
||||
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), static_cast<GLsizei>(pageSize), 1,
|
||||
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), static_cast<GLsizei>(pageSize), 1,
|
||||
GL_TRUE);
|
||||
|
||||
program.bind();
|
||||
gl->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);
|
||||
gl->BindImageTexture(1, metallicRoughness, level, GL_FALSE, 0, GL_READ_WRITE, GL_RG8);
|
||||
gl->DispatchCompute(pageSize / 8, pageSize / 8, 1);
|
||||
glMain->Uniform2i(gl->GetUniformLocation(program.programId(), "pixelOffset"), static_cast<GLsizei>(pageSize) * i, static_cast<GLsizei>(pageSize) * j);
|
||||
glMain->BindImageTexture(0, baseColor, level, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8);
|
||||
glMain->BindImageTexture(1, metallicRoughness, level, GL_FALSE, 0, GL_READ_WRITE, GL_RG8);
|
||||
glMain->DispatchCompute(pageSize / 8, pageSize / 8, 1);
|
||||
program.release();
|
||||
|
||||
}
|
||||
|
@ -111,12 +159,22 @@ Renderer::PaintingHandle& Renderer::VirtualTextureManager::getPaintingHandle(std
|
|||
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)
|
||||
{
|
||||
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;
|
||||
//qDebug() << commit << level << page.x << page.y;
|
||||
commitMutex.lock();
|
||||
|
||||
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,
|
||||
|
@ -129,12 +187,16 @@ void Renderer::VirtualTextureManager::pageCommitmentById(const glm::u16vec2& pag
|
|||
if (commit)
|
||||
{
|
||||
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->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();
|
||||
}
|
||||
gl->Finish();
|
||||
commitMutex.unlock();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
pageCommitmentById(pageId, GL_TRUE);
|
||||
|
||||
}
|
||||
else
|
||||
iter->second = lifeTime;
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
#include "Painting/Painting.h"
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <unordered_map>
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <QOffscreenSurface>
|
||||
|
||||
struct GladGLContext;
|
||||
|
||||
|
@ -17,7 +21,7 @@ namespace Renderer
|
|||
class VirtualTextureManager
|
||||
{
|
||||
public:
|
||||
VirtualTextureManager(GladGLContext* gl);
|
||||
VirtualTextureManager(GladGLContext* glMain);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
|
@ -26,9 +30,17 @@ namespace Renderer
|
|||
*/
|
||||
std::uint16_t createVirtualTexture(Painting painting);
|
||||
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:
|
||||
GladGLContext* gl;
|
||||
std::jthread thread;
|
||||
QOffscreenSurface surface;
|
||||
std::unique_ptr<GladGLContext> gl;
|
||||
GladGLContext* glMain;
|
||||
static constexpr GLsizei textureSize = 16384;
|
||||
static constexpr int lifeTime = 64;
|
||||
GLint pageSize;
|
||||
|
@ -42,9 +54,11 @@ namespace Renderer
|
|||
return ((std::size_t)v.y << 16) + v.x;
|
||||
}
|
||||
};
|
||||
|
||||
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);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#include <QtWidgets/QApplication>
|
||||
#include "ElementRendererTest.h"
|
||||
#include "Renderer/Painting/ElementStyle.h"
|
||||
#include <qtemporaryfile.h>
|
||||
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
using namespace Renderer;
|
||||
|
@ -12,6 +14,12 @@ namespace UnitTest
|
|||
TEST_CLASS(ElementRendererStokeTypeTest)
|
||||
{
|
||||
public:
|
||||
TEST_METHOD(TestFile)
|
||||
{
|
||||
QFile file("D:\\BigC2022\\temp\\ArchitectureColoredPainting\\README.md");
|
||||
Logger::WriteMessage(file.open(QIODevice::ReadOnly)? "True":"False");
|
||||
}
|
||||
|
||||
TEST_METHOD(TestBothSidesRound)
|
||||
{
|
||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
|
|
Loading…
Reference in New Issue