mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
Merge pull request #13582 from Zvork/scale
Render Scale Resolution applied only to 3D rendering not HUD
This commit is contained in:
commit
b59e9f9899
12 changed files with 188 additions and 43 deletions
|
@ -3267,13 +3267,22 @@ void Application::resizeGL() {
|
|||
// Set the desired FBO texture size. If it hasn't changed, this does nothing.
|
||||
// Otherwise, it must rebuild the FBOs
|
||||
uvec2 framebufferSize = displayPlugin->getRecommendedRenderSize();
|
||||
float renderResolutionScale = getRenderResolutionScale();
|
||||
uvec2 renderSize = uvec2(vec2(framebufferSize) * renderResolutionScale);
|
||||
uvec2 renderSize = uvec2(framebufferSize);
|
||||
if (_renderResolution != renderSize) {
|
||||
_renderResolution = renderSize;
|
||||
DependencyManager::get<FramebufferCache>()->setFrameBufferSize(fromGlm(renderSize));
|
||||
}
|
||||
|
||||
auto renderResolutionScale = getRenderResolutionScale();
|
||||
if (displayPlugin->getRenderResolutionScale() != renderResolutionScale) {
|
||||
auto renderConfig = _renderEngine->getConfiguration();
|
||||
assert(renderConfig);
|
||||
auto mainView = renderConfig->getConfig("RenderMainView.RenderDeferredTask");
|
||||
assert(mainView);
|
||||
mainView->setProperty("resolutionScale", renderResolutionScale);
|
||||
displayPlugin->setRenderResolutionScale(renderResolutionScale);
|
||||
}
|
||||
|
||||
// FIXME the aspect ratio for stereo displays is incorrect based on this.
|
||||
float aspectRatio = displayPlugin->getRecommendedAspectRatio();
|
||||
_myCamera.setProjection(glm::perspective(glm::radians(_fieldOfView.get()), aspectRatio,
|
||||
|
@ -3285,7 +3294,6 @@ void Application::resizeGL() {
|
|||
}
|
||||
|
||||
DependencyManager::get<OffscreenUi>()->resize(fromGlm(displayPlugin->getRecommendedUiSize()));
|
||||
displayPlugin->setRenderResolutionScale(renderResolutionScale);
|
||||
}
|
||||
|
||||
void Application::handleSandboxStatus(QNetworkReply* reply) {
|
||||
|
|
|
@ -102,7 +102,7 @@ void Application::paintGL() {
|
|||
PerformanceTimer perfTimer("renderOverlay");
|
||||
// NOTE: There is no batch associated with this renderArgs
|
||||
// the ApplicationOverlay class assumes it's viewport is setup to be the device size
|
||||
renderArgs._viewport = glm::ivec4(0, 0, getDeviceSize() * getRenderResolutionScale());
|
||||
renderArgs._viewport = glm::ivec4(0, 0, getDeviceSize());
|
||||
_applicationOverlay.renderOverlay(&renderArgs);
|
||||
}
|
||||
|
||||
|
@ -118,7 +118,7 @@ void Application::paintGL() {
|
|||
// Primary rendering pass
|
||||
auto framebufferCache = DependencyManager::get<FramebufferCache>();
|
||||
finalFramebufferSize = framebufferCache->getFrameBufferSize();
|
||||
// Final framebuffer that will be handled to the display-plugin
|
||||
// Final framebuffer that will be handed to the display-plugin
|
||||
finalFramebuffer = framebufferCache->getFramebuffer();
|
||||
}
|
||||
|
||||
|
|
|
@ -179,7 +179,7 @@ static const auto DEPTH_FORMAT = gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::DEPT
|
|||
void ApplicationOverlay::buildFramebufferObject() {
|
||||
PROFILE_RANGE(app, __FUNCTION__);
|
||||
|
||||
auto uiSize = glm::uvec2(glm::vec2(qApp->getUiSize()) * qApp->getRenderResolutionScale());
|
||||
auto uiSize = glm::uvec2(qApp->getUiSize());
|
||||
if (!_overlayFramebuffer || uiSize != _overlayFramebuffer->getSize()) {
|
||||
_overlayFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("ApplicationOverlay"));
|
||||
}
|
||||
|
|
|
@ -116,7 +116,7 @@ void Overlays::renderHUD(RenderArgs* renderArgs) {
|
|||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
auto textureCache = DependencyManager::get<TextureCache>();
|
||||
|
||||
auto size = glm::uvec2(glm::vec2(qApp->getUiSize()) * qApp->getRenderResolutionScale());
|
||||
auto size = glm::uvec2(qApp->getUiSize());
|
||||
int width = size.x;
|
||||
int height = size.y;
|
||||
mat4 legacyProjection = glm::ortho<float>(0, width, height, 0, -1000, 1000);
|
||||
|
|
|
@ -275,7 +275,7 @@ bool CompositorHelper::getReticleOverDesktop() const {
|
|||
// as being over the desktop.
|
||||
if (isHMD()) {
|
||||
QMutexLocker locker(&_reticleLock);
|
||||
glm::vec2 maxOverlayPosition = glm::vec2(_currentDisplayPlugin->getRecommendedUiSize()) * _currentDisplayPlugin->getRenderResolutionScale();
|
||||
glm::vec2 maxOverlayPosition = glm::vec2(_currentDisplayPlugin->getRecommendedUiSize());
|
||||
static const glm::vec2 minOverlayPosition;
|
||||
if (glm::any(glm::lessThan(_reticlePositionInHMD, minOverlayPosition)) ||
|
||||
glm::any(glm::greaterThan(_reticlePositionInHMD, maxOverlayPosition))) {
|
||||
|
@ -317,7 +317,7 @@ void CompositorHelper::sendFakeMouseEvent() {
|
|||
|
||||
void CompositorHelper::setReticlePosition(const glm::vec2& position, bool sendFakeEvent) {
|
||||
if (isHMD()) {
|
||||
glm::vec2 maxOverlayPosition = glm::vec2(_currentDisplayPlugin->getRecommendedUiSize()) * _currentDisplayPlugin->getRenderResolutionScale();
|
||||
glm::vec2 maxOverlayPosition = glm::vec2(_currentDisplayPlugin->getRecommendedUiSize());
|
||||
// FIXME don't allow negative mouseExtra
|
||||
glm::vec2 mouseExtra = (MOUSE_EXTENTS_PIXELS - maxOverlayPosition) / 2.0f;
|
||||
glm::vec2 minMouse = vec2(0) - mouseExtra;
|
||||
|
|
|
@ -888,7 +888,7 @@ OpenGLDisplayPlugin::~OpenGLDisplayPlugin() {
|
|||
}
|
||||
|
||||
void OpenGLDisplayPlugin::updateCompositeFramebuffer() {
|
||||
auto renderSize = glm::uvec2(glm::vec2(getRecommendedRenderSize()) * getRenderResolutionScale());
|
||||
auto renderSize = glm::uvec2(getRecommendedRenderSize());
|
||||
if (!_compositeFramebuffer || _compositeFramebuffer->getSize() != renderSize) {
|
||||
_compositeFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("OpenGLDisplayPlugin::composite", gpu::Element::COLOR_RGBA_32, renderSize.x, renderSize.y));
|
||||
}
|
||||
|
|
|
@ -393,34 +393,42 @@ graphics::MeshPointer DeferredLightingEffect::getSpotLightMesh() {
|
|||
return _spotLightMesh;
|
||||
}
|
||||
|
||||
void PreparePrimaryFramebuffer::run(const RenderContextPointer& renderContext, gpu::FramebufferPointer& primaryFramebuffer) {
|
||||
gpu::FramebufferPointer PreparePrimaryFramebuffer::createFramebuffer(const char* name, const glm::uvec2& frameSize) {
|
||||
gpu::FramebufferPointer framebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create(name));
|
||||
auto colorFormat = gpu::Element::COLOR_SRGBA_32;
|
||||
|
||||
auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR);
|
||||
auto primaryColorTexture = gpu::Texture::createRenderBuffer(colorFormat, frameSize.x, frameSize.y, gpu::Texture::SINGLE_MIP, defaultSampler);
|
||||
|
||||
framebuffer->setRenderBuffer(0, primaryColorTexture);
|
||||
|
||||
auto depthFormat = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::DEPTH_STENCIL); // Depth24_Stencil8 texel format
|
||||
auto primaryDepthTexture = gpu::Texture::createRenderBuffer(depthFormat, frameSize.x, frameSize.y, gpu::Texture::SINGLE_MIP, defaultSampler);
|
||||
|
||||
framebuffer->setDepthStencilBuffer(primaryDepthTexture, depthFormat);
|
||||
|
||||
return framebuffer;
|
||||
}
|
||||
|
||||
void PreparePrimaryFramebuffer::configure(const Config& config) {
|
||||
_resolutionScale = config.resolutionScale;
|
||||
}
|
||||
|
||||
void PreparePrimaryFramebuffer::run(const RenderContextPointer& renderContext, Output& primaryFramebuffer) {
|
||||
glm::uvec2 frameSize(renderContext->args->_viewport.z, renderContext->args->_viewport.w);
|
||||
glm::uvec2 scaledFrameSize(glm::vec2(frameSize) * _resolutionScale);
|
||||
|
||||
// Resizing framebuffers instead of re-building them seems to cause issues with threaded
|
||||
// rendering
|
||||
if (_primaryFramebuffer && _primaryFramebuffer->getSize() != frameSize) {
|
||||
_primaryFramebuffer.reset();
|
||||
if (!_primaryFramebuffer || _primaryFramebuffer->getSize() != scaledFrameSize) {
|
||||
_primaryFramebuffer = createFramebuffer("deferredPrimary", scaledFrameSize);
|
||||
}
|
||||
|
||||
if (!_primaryFramebuffer) {
|
||||
_primaryFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("deferredPrimary"));
|
||||
auto colorFormat = gpu::Element::COLOR_SRGBA_32;
|
||||
|
||||
auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT);
|
||||
auto primaryColorTexture = gpu::Texture::createRenderBuffer(colorFormat, frameSize.x, frameSize.y, gpu::Texture::SINGLE_MIP, defaultSampler);
|
||||
|
||||
|
||||
_primaryFramebuffer->setRenderBuffer(0, primaryColorTexture);
|
||||
|
||||
|
||||
auto depthFormat = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::DEPTH_STENCIL); // Depth24_Stencil8 texel format
|
||||
auto primaryDepthTexture = gpu::Texture::createRenderBuffer(depthFormat, frameSize.x, frameSize.y, gpu::Texture::SINGLE_MIP, defaultSampler);
|
||||
|
||||
_primaryFramebuffer->setDepthStencilBuffer(primaryDepthTexture, depthFormat);
|
||||
}
|
||||
|
||||
|
||||
primaryFramebuffer = _primaryFramebuffer;
|
||||
|
||||
// Set viewport for the rest of the scaled passes
|
||||
renderContext->args->_viewport.z = scaledFrameSize.x;
|
||||
renderContext->args->_viewport.w = scaledFrameSize.y;
|
||||
}
|
||||
|
||||
void PrepareDeferred::run(const RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs) {
|
||||
|
|
|
@ -93,13 +93,34 @@ private:
|
|||
friend class RenderDeferredCleanup;
|
||||
};
|
||||
|
||||
class PreparePrimaryFramebufferConfig : public render::Job::Config {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(float resolutionScale MEMBER resolutionScale NOTIFY dirty)
|
||||
public:
|
||||
|
||||
float resolutionScale{ 1.0f };
|
||||
|
||||
signals:
|
||||
void dirty();
|
||||
};
|
||||
|
||||
class PreparePrimaryFramebuffer {
|
||||
public:
|
||||
using JobModel = render::Job::ModelO<PreparePrimaryFramebuffer, gpu::FramebufferPointer>;
|
||||
|
||||
void run(const render::RenderContextPointer& renderContext, gpu::FramebufferPointer& primaryFramebuffer);
|
||||
using Output = gpu::FramebufferPointer;
|
||||
using Config = PreparePrimaryFramebufferConfig;
|
||||
using JobModel = render::Job::ModelO<PreparePrimaryFramebuffer, Output, Config>;
|
||||
|
||||
PreparePrimaryFramebuffer(float resolutionScale = 1.0f) : _resolutionScale{resolutionScale} {}
|
||||
void configure(const Config& config);
|
||||
void run(const render::RenderContextPointer& renderContext, Output& primaryFramebuffer);
|
||||
|
||||
gpu::FramebufferPointer _primaryFramebuffer;
|
||||
float _resolutionScale{ 1.0f };
|
||||
|
||||
private:
|
||||
|
||||
static gpu::FramebufferPointer createFramebuffer(const char* name, const glm::uvec2& size);
|
||||
};
|
||||
|
||||
class PrepareDeferred {
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <render/DrawStatus.h>
|
||||
#include <render/DrawSceneOctree.h>
|
||||
#include <render/BlurTask.h>
|
||||
#include <render/ResampleTask.h>
|
||||
|
||||
#include "RenderHifi.h"
|
||||
#include "RenderCommonTask.h"
|
||||
|
@ -59,8 +60,14 @@ RenderDeferredTask::RenderDeferredTask()
|
|||
{
|
||||
}
|
||||
|
||||
void RenderDeferredTask::configure(const Config& config)
|
||||
{
|
||||
void RenderDeferredTask::configure(const Config& config) {
|
||||
// Propagate resolution scale to sub jobs who need it
|
||||
auto preparePrimaryBufferConfig = config.getConfig<PreparePrimaryFramebuffer>("PreparePrimaryBuffer");
|
||||
auto upsamplePrimaryBufferConfig = config.getConfig<Upsample>("PrimaryBufferUpscale");
|
||||
assert(preparePrimaryBufferConfig);
|
||||
assert(upsamplePrimaryBufferConfig);
|
||||
preparePrimaryBufferConfig->setProperty("resolutionScale", config.resolutionScale);
|
||||
upsamplePrimaryBufferConfig->setProperty("factor", 1.0f / config.resolutionScale);
|
||||
}
|
||||
|
||||
const render::Varying RenderDeferredTask::addSelectItemJobs(JobModel& task, const char* selectionName,
|
||||
|
@ -97,23 +104,22 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
|
||||
const auto jitter = task.addJob<JitterSample>("JitterCam");
|
||||
|
||||
// Prepare deferred, generate the shared Deferred Frame Transform
|
||||
// GPU jobs: Start preparing the primary, deferred and lighting buffer
|
||||
const auto scaledPrimaryFramebuffer = task.addJob<PreparePrimaryFramebuffer>("PreparePrimaryBuffer");
|
||||
|
||||
// Prepare deferred, generate the shared Deferred Frame Transform. Only valid with the scaled frame buffer
|
||||
const auto deferredFrameTransform = task.addJob<GenerateDeferredFrameTransform>("DeferredFrameTransform", jitter);
|
||||
const auto lightingModel = task.addJob<MakeLightingModel>("LightingModel");
|
||||
|
||||
|
||||
// GPU jobs: Start preparing the primary, deferred and lighting buffer
|
||||
const auto primaryFramebuffer = task.addJob<PreparePrimaryFramebuffer>("PreparePrimaryBuffer");
|
||||
|
||||
const auto opaqueRangeTimer = task.addJob<BeginGPURangeTimer>("BeginOpaqueRangeTimer", "DrawOpaques");
|
||||
|
||||
const auto prepareDeferredInputs = PrepareDeferred::Inputs(primaryFramebuffer, lightingModel).asVarying();
|
||||
const auto prepareDeferredInputs = PrepareDeferred::Inputs(scaledPrimaryFramebuffer, lightingModel).asVarying();
|
||||
const auto prepareDeferredOutputs = task.addJob<PrepareDeferred>("PrepareDeferred", prepareDeferredInputs);
|
||||
const auto deferredFramebuffer = prepareDeferredOutputs.getN<PrepareDeferred::Outputs>(0);
|
||||
const auto lightingFramebuffer = prepareDeferredOutputs.getN<PrepareDeferred::Outputs>(1);
|
||||
|
||||
// draw a stencil mask in hidden regions of the framebuffer.
|
||||
task.addJob<PrepareStencil>("PrepareStencil", primaryFramebuffer);
|
||||
task.addJob<PrepareStencil>("PrepareStencil", scaledPrimaryFramebuffer);
|
||||
|
||||
// Render opaque objects in DeferredBuffer
|
||||
const auto opaqueInputs = DrawStateSortDeferred::Inputs(opaques, lightingModel, jitter).asVarying();
|
||||
|
@ -223,7 +229,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
task.addJob<Bloom>("Bloom", bloomInputs);
|
||||
|
||||
// Lighting Buffer ready for tone mapping
|
||||
const auto toneMappingInputs = ToneMappingDeferred::Inputs(lightingFramebuffer, primaryFramebuffer).asVarying();
|
||||
const auto toneMappingInputs = ToneMappingDeferred::Inputs(lightingFramebuffer, scaledPrimaryFramebuffer).asVarying();
|
||||
task.addJob<ToneMappingDeferred>("ToneMapping", toneMappingInputs);
|
||||
|
||||
{ // Debug the bounds of the rendered items, still look at the zbuffer
|
||||
|
@ -284,6 +290,9 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
task.addJob<DebugZoneLighting>("DrawZoneStack", deferredFrameTransform);
|
||||
}
|
||||
|
||||
// Upscale to finale resolution
|
||||
const auto primaryFramebuffer = task.addJob<render::Upsample>("PrimaryBufferUpscale", scaledPrimaryFramebuffer);
|
||||
|
||||
// Composite the HUD and HUD overlays
|
||||
task.addJob<CompositeHUD>("HUD");
|
||||
|
||||
|
|
|
@ -105,11 +105,13 @@ class RenderDeferredTaskConfig : public render::Task::Config {
|
|||
Q_OBJECT
|
||||
Q_PROPERTY(float fadeScale MEMBER fadeScale NOTIFY dirty)
|
||||
Q_PROPERTY(float fadeDuration MEMBER fadeDuration NOTIFY dirty)
|
||||
Q_PROPERTY(float resolutionScale MEMBER resolutionScale NOTIFY dirty)
|
||||
Q_PROPERTY(bool debugFade MEMBER debugFade NOTIFY dirty)
|
||||
Q_PROPERTY(float debugFadePercent MEMBER debugFadePercent NOTIFY dirty)
|
||||
public:
|
||||
float fadeScale{ 0.5f };
|
||||
float fadeDuration{ 3.0f };
|
||||
float resolutionScale{ 1.f };
|
||||
float debugFadePercent{ 0.f };
|
||||
bool debugFade{ false };
|
||||
|
||||
|
|
|
@ -81,3 +81,69 @@ void HalfDownsample::run(const RenderContextPointer& renderContext, const gpu::F
|
|||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
});
|
||||
}
|
||||
|
||||
gpu::PipelinePointer Upsample::_pipeline;
|
||||
|
||||
void Upsample::configure(const Config& config) {
|
||||
_factor = config.factor;
|
||||
}
|
||||
|
||||
gpu::FramebufferPointer Upsample::getResampledFrameBuffer(const gpu::FramebufferPointer& sourceFramebuffer) {
|
||||
if (_factor == 1.0f) {
|
||||
return sourceFramebuffer;
|
||||
}
|
||||
|
||||
auto resampledFramebufferSize = glm::uvec2(glm::vec2(sourceFramebuffer->getSize()) * _factor);
|
||||
|
||||
if (!_destinationFrameBuffer || resampledFramebufferSize != _destinationFrameBuffer->getSize()) {
|
||||
_destinationFrameBuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("UpsampledOutput"));
|
||||
|
||||
auto sampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR);
|
||||
auto target = gpu::Texture::createRenderBuffer(sourceFramebuffer->getRenderBuffer(0)->getTexelFormat(), resampledFramebufferSize.x, resampledFramebufferSize.y, gpu::Texture::SINGLE_MIP, sampler);
|
||||
_destinationFrameBuffer->setRenderBuffer(0, target);
|
||||
}
|
||||
return _destinationFrameBuffer;
|
||||
}
|
||||
|
||||
void Upsample::run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& sourceFramebuffer, gpu::FramebufferPointer& resampledFrameBuffer) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->hasViewFrustum());
|
||||
RenderArgs* args = renderContext->args;
|
||||
|
||||
resampledFrameBuffer = getResampledFrameBuffer(sourceFramebuffer);
|
||||
if (resampledFrameBuffer != sourceFramebuffer) {
|
||||
if (!_pipeline) {
|
||||
auto vs = gpu::StandardShaderLib::getDrawTransformUnitQuadVS();
|
||||
auto ps = gpu::StandardShaderLib::getDrawTextureOpaquePS();
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
state->setDepthTest(gpu::State::DepthTest(false, false));
|
||||
_pipeline = gpu::Pipeline::create(program, state);
|
||||
}
|
||||
|
||||
const auto bufferSize = resampledFrameBuffer->getSize();
|
||||
glm::ivec4 viewport{ 0, 0, bufferSize.x, bufferSize.y };
|
||||
|
||||
gpu::doInBatch("Upsample::run", args->_context, [&](gpu::Batch& batch) {
|
||||
batch.enableStereo(false);
|
||||
|
||||
batch.setFramebuffer(resampledFrameBuffer);
|
||||
|
||||
batch.setViewportTransform(viewport);
|
||||
batch.setProjectionTransform(glm::mat4());
|
||||
batch.resetViewTransform();
|
||||
batch.setPipeline(_pipeline);
|
||||
|
||||
batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(bufferSize, viewport));
|
||||
batch.setResourceTexture(0, sourceFramebuffer->getRenderBuffer(0));
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
});
|
||||
|
||||
// Set full final viewport
|
||||
args->_viewport = viewport;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,37 @@ namespace render {
|
|||
|
||||
gpu::FramebufferPointer getResampledFrameBuffer(const gpu::FramebufferPointer& sourceFramebuffer);
|
||||
};
|
||||
|
||||
class UpsampleConfig : public render::Job::Config {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(float factor MEMBER factor NOTIFY dirty)
|
||||
public:
|
||||
|
||||
float factor{ 1.0f };
|
||||
|
||||
signals:
|
||||
void dirty();
|
||||
};
|
||||
|
||||
class Upsample {
|
||||
public:
|
||||
using Config = UpsampleConfig;
|
||||
using JobModel = Job::ModelIO<Upsample, gpu::FramebufferPointer, gpu::FramebufferPointer, Config>;
|
||||
|
||||
Upsample(float factor = 2.0f) : _factor{ factor } {}
|
||||
|
||||
void configure(const Config& config);
|
||||
void run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& sourceFramebuffer, gpu::FramebufferPointer& resampledFrameBuffer);
|
||||
|
||||
protected:
|
||||
|
||||
static gpu::PipelinePointer _pipeline;
|
||||
|
||||
gpu::FramebufferPointer _destinationFrameBuffer;
|
||||
float _factor{ 2.0f };
|
||||
|
||||
gpu::FramebufferPointer getResampledFrameBuffer(const gpu::FramebufferPointer& sourceFramebuffer);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // hifi_render_ResampleTask_h
|
||||
|
|
Loading…
Reference in a new issue