mirror of
https://github.com/overte-org/overte.git
synced 2025-07-22 22:34:12 +02:00
Fixing UI
This commit is contained in:
parent
fd01f1ca9c
commit
105dffebaf
11 changed files with 469 additions and 399 deletions
|
@ -23,12 +23,7 @@ android {
|
||||||
'-DBUILD_BRANCH=' + BUILD_BRANCH
|
'-DBUILD_BRANCH=' + BUILD_BRANCH
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
compileOptions {
|
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
applicationVariants.all { variant ->
|
applicationVariants.all { variant ->
|
||||||
variant.outputs.all {
|
variant.outputs.all {
|
||||||
|
@ -43,17 +38,23 @@ android {
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
cmake {
|
cmake {
|
||||||
path '../../CMakeLists.txt'
|
path '../../CMakeLists.txt'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
buildToolsVersion '27.0.3'
|
||||||
|
dexOptions {
|
||||||
|
}
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'com.google.vr:sdk-audio:1.80.0'
|
implementation 'com.google.vr:sdk-audio:1.80.0'
|
||||||
implementation 'com.google.vr:sdk-base:1.80.0'
|
implementation 'com.google.vr:sdk-base:1.80.0'
|
||||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
28
android/app/src/main/cpp/native.cpp
Normal file
28
android/app/src/main/cpp/native.cpp
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
#include <QtCore/QThread>
|
||||||
|
#include <QtAndroidExtras/QAndroidJniObject>
|
||||||
|
|
||||||
|
#include <android/log.h>
|
||||||
|
#include <android/asset_manager.h>
|
||||||
|
#include <android/asset_manager_jni.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeOnCreate(JNIEnv* env, jobject obj, jobject instance, jobject asset_mgr) {
|
||||||
|
qDebug() << "nativeOnCreate On thread " << QThread::currentThreadId();
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeOnPause(JNIEnv* env, jobject obj) {
|
||||||
|
qDebug() << "nativeOnPause";
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeOnResume(JNIEnv* env, jobject obj) {
|
||||||
|
qDebug() << "nativeOnResume";
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeOnExitVr(JNIEnv* env, jobject obj) {
|
||||||
|
qDebug() << "nativeOnCreate On thread " << QThread::currentThreadId();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -22,10 +22,6 @@ OriginalDesktop.Desktop {
|
||||||
acceptedButtons: Qt.NoButton
|
acceptedButtons: Qt.NoButton
|
||||||
}
|
}
|
||||||
|
|
||||||
// The tool window, one instance
|
|
||||||
property alias toolWindow: toolWindow
|
|
||||||
ToolWindow { id: toolWindow }
|
|
||||||
|
|
||||||
Action {
|
Action {
|
||||||
text: "Open Browser"
|
text: "Open Browser"
|
||||||
shortcut: "Ctrl+B"
|
shortcut: "Ctrl+B"
|
||||||
|
|
|
@ -210,14 +210,7 @@
|
||||||
#include "commerce/QmlCommerce.h"
|
#include "commerce/QmlCommerce.h"
|
||||||
|
|
||||||
#include "webbrowser/WebBrowserSuggestionsEngine.h"
|
#include "webbrowser/WebBrowserSuggestionsEngine.h"
|
||||||
#if defined(Q_OS_ANDROID)
|
|
||||||
#include <QtAndroidExtras/QAndroidJniObject>
|
|
||||||
#include <android/log.h>
|
|
||||||
#include <android/asset_manager.h>
|
|
||||||
#include <android/asset_manager_jni.h>
|
|
||||||
#endif
|
|
||||||
// On Windows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU
|
|
||||||
// FIXME seems to be broken.
|
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
#include <VersionHelpers.h>
|
#include <VersionHelpers.h>
|
||||||
|
|
||||||
|
@ -232,35 +225,17 @@
|
||||||
#undef QT_BOOTSTRAPPED
|
#undef QT_BOOTSTRAPPED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// On Windows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU
|
||||||
|
// FIXME seems to be broken.
|
||||||
extern "C" {
|
extern "C" {
|
||||||
_declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
|
_declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(Q_OS_ANDROID)
|
#if defined(Q_OS_ANDROID)
|
||||||
extern "C" {
|
#include <android/log.h>
|
||||||
|
|
||||||
JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeOnCreate(JNIEnv* env, jobject obj, jobject instance, jobject asset_mgr) {
|
|
||||||
qDebug() << "nativeOnCreate On thread " << QThread::currentThreadId();
|
|
||||||
}
|
|
||||||
|
|
||||||
JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeOnPause(JNIEnv* env, jobject obj) {
|
|
||||||
qDebug() << "nativeOnPause";
|
|
||||||
}
|
|
||||||
|
|
||||||
JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeOnResume(JNIEnv* env, jobject obj) {
|
|
||||||
qDebug() << "nativeOnResume";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeOnExitVr(JNIEnv* env, jobject obj) {
|
|
||||||
qDebug() << "nativeOnCreate On thread " << QThread::currentThreadId();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum ApplicationEvent {
|
enum ApplicationEvent {
|
||||||
// Execute a lambda function
|
// Execute a lambda function
|
||||||
Lambda = QEvent::User + 1,
|
Lambda = QEvent::User + 1,
|
||||||
|
@ -270,7 +245,6 @@ enum ApplicationEvent {
|
||||||
Idle,
|
Idle,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class RenderEventHandler : public QObject {
|
class RenderEventHandler : public QObject {
|
||||||
using Parent = QObject;
|
using Parent = QObject;
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -2232,7 +2206,9 @@ void Application::initializeGL() {
|
||||||
_chromiumShareContext->setObjectName("ChromiumShareContext");
|
_chromiumShareContext->setObjectName("ChromiumShareContext");
|
||||||
_chromiumShareContext->create(_glWidget->qglContext());
|
_chromiumShareContext->create(_glWidget->qglContext());
|
||||||
_chromiumShareContext->makeCurrent();
|
_chromiumShareContext->makeCurrent();
|
||||||
qt_gl_set_global_share_context(_chromiumShareContext->getContext());
|
if (nsightActive()) {
|
||||||
|
qt_gl_set_global_share_context(_chromiumShareContext->getContext());
|
||||||
|
}
|
||||||
|
|
||||||
_glWidget->makeCurrent();
|
_glWidget->makeCurrent();
|
||||||
gpu::Context::init<gpu::gl::GLBackend>();
|
gpu::Context::init<gpu::gl::GLBackend>();
|
||||||
|
|
|
@ -884,6 +884,7 @@ void OpenGLDisplayPlugin::updateCompositeFramebuffer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLDisplayPlugin::copyTextureToQuickFramebuffer(NetworkTexturePointer networkTexture, QOpenGLFramebufferObject* target, GLsync* fenceSync) {
|
void OpenGLDisplayPlugin::copyTextureToQuickFramebuffer(NetworkTexturePointer networkTexture, QOpenGLFramebufferObject* target, GLsync* fenceSync) {
|
||||||
|
#if !defined(Q_OS_ANDROID)
|
||||||
auto glBackend = const_cast<OpenGLDisplayPlugin&>(*this).getGLBackend();
|
auto glBackend = const_cast<OpenGLDisplayPlugin&>(*this).getGLBackend();
|
||||||
withMainThreadContext([&] {
|
withMainThreadContext([&] {
|
||||||
GLuint sourceTexture = glBackend->getTextureID(networkTexture->getGPUTexture());
|
GLuint sourceTexture = glBackend->getTextureID(networkTexture->getGPUTexture());
|
||||||
|
@ -891,14 +892,10 @@ void OpenGLDisplayPlugin::copyTextureToQuickFramebuffer(NetworkTexturePointer ne
|
||||||
GLuint fbo[2] {0, 0};
|
GLuint fbo[2] {0, 0};
|
||||||
|
|
||||||
// need mipmaps for blitting texture
|
// need mipmaps for blitting texture
|
||||||
#if !defined(Q_OS_ANDROID)
|
glGenerateTextureMipmap(sourceTexture);
|
||||||
glGenerateTextureMipmap(sourceTexture);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// create 2 fbos (one for initial texture, second for scaled one)
|
// create 2 fbos (one for initial texture, second for scaled one)
|
||||||
#if !defined(Q_OS_ANDROID)
|
glCreateFramebuffers(2, fbo);
|
||||||
glCreateFramebuffers(2, fbo);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// setup source fbo
|
// setup source fbo
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo[0]);
|
glBindFramebuffer(GL_FRAMEBUFFER, fbo[0]);
|
||||||
|
@ -928,13 +925,13 @@ void OpenGLDisplayPlugin::copyTextureToQuickFramebuffer(NetworkTexturePointer ne
|
||||||
} else {
|
} else {
|
||||||
newY = (target->height() - newHeight) / 2;
|
newY = (target->height() - newHeight) / 2;
|
||||||
}
|
}
|
||||||
#if !defined(Q_OS_ANDROID)
|
|
||||||
glBlitNamedFramebuffer(fbo[0], fbo[1], 0, 0, texWidth, texHeight, newX, newY, newX + newWidth, newY + newHeight, GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
glBlitNamedFramebuffer(fbo[0], fbo[1], 0, 0, texWidth, texHeight, newX, newY, newX + newWidth, newY + newHeight, GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
#endif
|
|
||||||
|
|
||||||
// don't delete the textures!
|
// don't delete the textures!
|
||||||
glDeleteFramebuffers(2, fbo);
|
glDeleteFramebuffers(2, fbo);
|
||||||
*fenceSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
*fenceSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||||
});
|
});
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
238
libraries/render-utils/src/RenderCommonTask.cpp
Normal file
238
libraries/render-utils/src/RenderCommonTask.cpp
Normal file
|
@ -0,0 +1,238 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2018/01/09
|
||||||
|
// Copyright 2013-2018 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "RenderCommonTask.h"
|
||||||
|
|
||||||
|
#include <PerfStat.h>
|
||||||
|
#include <PathUtils.h>
|
||||||
|
#include <ViewFrustum.h>
|
||||||
|
#include <gpu/Context.h>
|
||||||
|
|
||||||
|
#include <render/CullTask.h>
|
||||||
|
#include <render/FilterTask.h>
|
||||||
|
#include <render/SortTask.h>
|
||||||
|
#include <render/DrawTask.h>
|
||||||
|
#include <render/DrawStatus.h>
|
||||||
|
#include <render/DrawSceneOctree.h>
|
||||||
|
#include <render/BlurTask.h>
|
||||||
|
|
||||||
|
#include "LightingModel.h"
|
||||||
|
#include "StencilMaskPass.h"
|
||||||
|
#include "DebugDeferredBuffer.h"
|
||||||
|
#include "DeferredFramebuffer.h"
|
||||||
|
#include "DeferredLightingEffect.h"
|
||||||
|
#include "SurfaceGeometryPass.h"
|
||||||
|
#include "FramebufferCache.h"
|
||||||
|
#include "TextureCache.h"
|
||||||
|
#include "ZoneRenderer.h"
|
||||||
|
#include "FadeEffect.h"
|
||||||
|
#include "RenderUtilsLogging.h"
|
||||||
|
|
||||||
|
#include "AmbientOcclusionEffect.h"
|
||||||
|
#include "AntialiasingEffect.h"
|
||||||
|
#include "ToneMappingEffect.h"
|
||||||
|
#include "SubsurfaceScattering.h"
|
||||||
|
#include "DrawHaze.h"
|
||||||
|
#include "BloomEffect.h"
|
||||||
|
#include "HighlightEffect.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
using namespace render;
|
||||||
|
extern void initOverlay3DPipelines(render::ShapePlumber& plumber, bool depthTest = false);
|
||||||
|
|
||||||
|
void BeginGPURangeTimer::run(const render::RenderContextPointer& renderContext, gpu::RangeTimerPointer& timer) {
|
||||||
|
timer = _gpuTimer;
|
||||||
|
gpu::doInBatch(renderContext->args->_context, [&](gpu::Batch& batch) {
|
||||||
|
_gpuTimer->begin(batch);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void EndGPURangeTimer::run(const render::RenderContextPointer& renderContext, const gpu::RangeTimerPointer& timer) {
|
||||||
|
gpu::doInBatch(renderContext->args->_context, [&](gpu::Batch& batch) {
|
||||||
|
timer->end(batch);
|
||||||
|
});
|
||||||
|
|
||||||
|
auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
|
||||||
|
config->setGPUBatchRunTime(timer->getGPUAverage(), timer->getBatchAverage());
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawOverlay3D::DrawOverlay3D(bool opaque) :
|
||||||
|
_shapePlumber(std::make_shared<ShapePlumber>()),
|
||||||
|
_opaquePass(opaque) {
|
||||||
|
initOverlay3DPipelines(*_shapePlumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawOverlay3D::run(const RenderContextPointer& renderContext, const Inputs& inputs) {
|
||||||
|
assert(renderContext->args);
|
||||||
|
assert(renderContext->args->hasViewFrustum());
|
||||||
|
|
||||||
|
auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
|
||||||
|
|
||||||
|
const auto& inItems = inputs.get0();
|
||||||
|
const auto& lightingModel = inputs.get1();
|
||||||
|
|
||||||
|
config->setNumDrawn((int)inItems.size());
|
||||||
|
emit config->numDrawnChanged();
|
||||||
|
|
||||||
|
if (!inItems.empty()) {
|
||||||
|
RenderArgs* args = renderContext->args;
|
||||||
|
|
||||||
|
// Clear the framebuffer without stereo
|
||||||
|
// Needs to be distinct from the other batch because using the clear call
|
||||||
|
// while stereo is enabled triggers a warning
|
||||||
|
if (_opaquePass) {
|
||||||
|
gpu::doInBatch(args->_context, [&](gpu::Batch& batch){
|
||||||
|
batch.enableStereo(false);
|
||||||
|
batch.clearFramebuffer(gpu::Framebuffer::BUFFER_DEPTH, glm::vec4(), 1.f, 0, false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render the items
|
||||||
|
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||||
|
args->_batch = &batch;
|
||||||
|
batch.setViewportTransform(args->_viewport);
|
||||||
|
batch.setStateScissorRect(args->_viewport);
|
||||||
|
|
||||||
|
glm::mat4 projMat;
|
||||||
|
Transform viewMat;
|
||||||
|
args->getViewFrustum().evalProjectionMatrix(projMat);
|
||||||
|
args->getViewFrustum().evalViewTransform(viewMat);
|
||||||
|
|
||||||
|
batch.setProjectionTransform(projMat);
|
||||||
|
batch.setViewTransform(viewMat);
|
||||||
|
|
||||||
|
// Setup lighting model for all items;
|
||||||
|
batch.setUniformBuffer(render::ShapePipeline::Slot::LIGHTING_MODEL, lightingModel->getParametersBuffer());
|
||||||
|
|
||||||
|
renderShapes(renderContext, _shapePlumber, inItems, _maxDrawn);
|
||||||
|
args->_batch = nullptr;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompositeHUD::run(const RenderContextPointer& renderContext) {
|
||||||
|
assert(renderContext->args);
|
||||||
|
assert(renderContext->args->_context);
|
||||||
|
|
||||||
|
// We do not want to render HUD elements in secondary camera
|
||||||
|
if (renderContext->args->_renderMode == RenderArgs::RenderMode::SECONDARY_CAMERA_RENDER_MODE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grab the HUD texture
|
||||||
|
gpu::doInBatch(renderContext->args->_context, [&](gpu::Batch& batch) {
|
||||||
|
if (renderContext->args->_hudOperator) {
|
||||||
|
renderContext->args->_hudOperator(batch, renderContext->args->_hudTexture, renderContext->args->_renderMode == RenderArgs::RenderMode::MIRROR_RENDER_MODE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Blit::run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer) {
|
||||||
|
assert(renderContext->args);
|
||||||
|
assert(renderContext->args->_context);
|
||||||
|
|
||||||
|
RenderArgs* renderArgs = renderContext->args;
|
||||||
|
auto blitFbo = renderArgs->_blitFramebuffer;
|
||||||
|
|
||||||
|
if (!blitFbo) {
|
||||||
|
qCWarning(renderutils) << "Blit::run - no blit frame buffer.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine size from viewport
|
||||||
|
int width = renderArgs->_viewport.z;
|
||||||
|
int height = renderArgs->_viewport.w;
|
||||||
|
|
||||||
|
// Blit primary to blit FBO
|
||||||
|
auto primaryFbo = srcFramebuffer;
|
||||||
|
|
||||||
|
gpu::doInBatch(renderArgs->_context, [&](gpu::Batch& batch) {
|
||||||
|
batch.setFramebuffer(blitFbo);
|
||||||
|
|
||||||
|
if (renderArgs->_renderMode == RenderArgs::MIRROR_RENDER_MODE) {
|
||||||
|
if (renderArgs->isStereo()) {
|
||||||
|
gpu::Vec4i srcRectLeft;
|
||||||
|
srcRectLeft.z = width / 2;
|
||||||
|
srcRectLeft.w = height;
|
||||||
|
|
||||||
|
gpu::Vec4i srcRectRight;
|
||||||
|
srcRectRight.x = width / 2;
|
||||||
|
srcRectRight.z = width;
|
||||||
|
srcRectRight.w = height;
|
||||||
|
|
||||||
|
gpu::Vec4i destRectLeft;
|
||||||
|
destRectLeft.x = srcRectLeft.z;
|
||||||
|
destRectLeft.z = srcRectLeft.x;
|
||||||
|
destRectLeft.y = srcRectLeft.y;
|
||||||
|
destRectLeft.w = srcRectLeft.w;
|
||||||
|
|
||||||
|
gpu::Vec4i destRectRight;
|
||||||
|
destRectRight.x = srcRectRight.z;
|
||||||
|
destRectRight.z = srcRectRight.x;
|
||||||
|
destRectRight.y = srcRectRight.y;
|
||||||
|
destRectRight.w = srcRectRight.w;
|
||||||
|
|
||||||
|
// Blit left to right and right to left in stereo
|
||||||
|
batch.blit(primaryFbo, srcRectRight, blitFbo, destRectLeft);
|
||||||
|
batch.blit(primaryFbo, srcRectLeft, blitFbo, destRectRight);
|
||||||
|
} else {
|
||||||
|
gpu::Vec4i srcRect;
|
||||||
|
srcRect.z = width;
|
||||||
|
srcRect.w = height;
|
||||||
|
|
||||||
|
gpu::Vec4i destRect;
|
||||||
|
destRect.x = width;
|
||||||
|
destRect.y = 0;
|
||||||
|
destRect.z = 0;
|
||||||
|
destRect.w = height;
|
||||||
|
|
||||||
|
batch.blit(primaryFbo, srcRect, blitFbo, destRect);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
gpu::Vec4i rect;
|
||||||
|
rect.z = width;
|
||||||
|
rect.w = height;
|
||||||
|
|
||||||
|
batch.blit(primaryFbo, rect, blitFbo, rect);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExtractFrustums::run(const render::RenderContextPointer& renderContext, Output& output) {
|
||||||
|
assert(renderContext->args);
|
||||||
|
assert(renderContext->args->_context);
|
||||||
|
|
||||||
|
RenderArgs* args = renderContext->args;
|
||||||
|
|
||||||
|
// Return view frustum
|
||||||
|
auto& viewFrustum = output[VIEW_FRUSTUM].edit<ViewFrustumPointer>();
|
||||||
|
if (!viewFrustum) {
|
||||||
|
viewFrustum = std::make_shared<ViewFrustum>(args->getViewFrustum());
|
||||||
|
} else {
|
||||||
|
*viewFrustum = args->getViewFrustum();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return shadow frustum
|
||||||
|
auto lightStage = args->_scene->getStage<LightStage>(LightStage::getName());
|
||||||
|
for (auto i = 0; i < SHADOW_CASCADE_FRUSTUM_COUNT; i++) {
|
||||||
|
auto& shadowFrustum = output[SHADOW_CASCADE0_FRUSTUM+i].edit<ViewFrustumPointer>();
|
||||||
|
if (lightStage) {
|
||||||
|
auto globalShadow = lightStage->getCurrentKeyShadow();
|
||||||
|
|
||||||
|
if (globalShadow && i<(int)globalShadow->getCascadeCount()) {
|
||||||
|
auto& cascade = globalShadow->getCascade(i);
|
||||||
|
shadowFrustum = cascade.getFrustum();
|
||||||
|
} else {
|
||||||
|
shadowFrustum.reset();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
shadowFrustum.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
116
libraries/render-utils/src/RenderCommonTask.h
Normal file
116
libraries/render-utils/src/RenderCommonTask.h
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2018/01/09
|
||||||
|
// Copyright 2013-2018 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_RenderCommonTask_h
|
||||||
|
#define hifi_RenderCommonTask_h
|
||||||
|
|
||||||
|
#include <gpu/Pipeline.h>
|
||||||
|
#include <render/RenderFetchCullSortTask.h>
|
||||||
|
#include "LightingModel.h"
|
||||||
|
|
||||||
|
class BeginGPURangeTimer {
|
||||||
|
public:
|
||||||
|
using JobModel = render::Job::ModelO<BeginGPURangeTimer, gpu::RangeTimerPointer>;
|
||||||
|
|
||||||
|
BeginGPURangeTimer(const std::string& name) : _gpuTimer(std::make_shared<gpu::RangeTimer>(name)) {}
|
||||||
|
|
||||||
|
void run(const render::RenderContextPointer& renderContext, gpu::RangeTimerPointer& timer);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
gpu::RangeTimerPointer _gpuTimer;
|
||||||
|
};
|
||||||
|
|
||||||
|
using GPURangeTimerConfig = render::GPUJobConfig;
|
||||||
|
|
||||||
|
class EndGPURangeTimer {
|
||||||
|
public:
|
||||||
|
using Config = GPURangeTimerConfig;
|
||||||
|
using JobModel = render::Job::ModelI<EndGPURangeTimer, gpu::RangeTimerPointer, Config>;
|
||||||
|
|
||||||
|
EndGPURangeTimer() {}
|
||||||
|
|
||||||
|
void configure(const Config& config) {}
|
||||||
|
void run(const render::RenderContextPointer& renderContext, const gpu::RangeTimerPointer& timer);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
};
|
||||||
|
|
||||||
|
class DrawOverlay3DConfig : public render::Job::Config {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(int numDrawn READ getNumDrawn NOTIFY numDrawnChanged)
|
||||||
|
Q_PROPERTY(int maxDrawn MEMBER maxDrawn NOTIFY dirty)
|
||||||
|
public:
|
||||||
|
int getNumDrawn() { return numDrawn; }
|
||||||
|
void setNumDrawn(int num) { numDrawn = num; emit numDrawnChanged(); }
|
||||||
|
|
||||||
|
int maxDrawn{ -1 };
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void numDrawnChanged();
|
||||||
|
void dirty();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int numDrawn{ 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
class DrawOverlay3D {
|
||||||
|
public:
|
||||||
|
using Inputs = render::VaryingSet2 <render::ItemBounds, LightingModelPointer>;
|
||||||
|
|
||||||
|
using Config = DrawOverlay3DConfig;
|
||||||
|
using JobModel = render::Job::ModelI<DrawOverlay3D, Inputs, Config>;
|
||||||
|
|
||||||
|
DrawOverlay3D(bool opaque);
|
||||||
|
|
||||||
|
void configure(const Config& config) { _maxDrawn = config.maxDrawn; }
|
||||||
|
void run(const render::RenderContextPointer& renderContext, const Inputs& inputs);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
render::ShapePlumberPointer _shapePlumber;
|
||||||
|
int _maxDrawn; // initialized by Config
|
||||||
|
bool _opaquePass{ true };
|
||||||
|
};
|
||||||
|
|
||||||
|
class CompositeHUD {
|
||||||
|
public:
|
||||||
|
using JobModel = render::Job::Model<CompositeHUD>;
|
||||||
|
|
||||||
|
CompositeHUD() {}
|
||||||
|
void run(const render::RenderContextPointer& renderContext);
|
||||||
|
};
|
||||||
|
|
||||||
|
class Blit {
|
||||||
|
public:
|
||||||
|
using JobModel = render::Job::ModelI<Blit, gpu::FramebufferPointer>;
|
||||||
|
|
||||||
|
void run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer);
|
||||||
|
};
|
||||||
|
|
||||||
|
class ExtractFrustums {
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum Frustum {
|
||||||
|
SHADOW_CASCADE0_FRUSTUM = 0,
|
||||||
|
SHADOW_CASCADE1_FRUSTUM,
|
||||||
|
SHADOW_CASCADE2_FRUSTUM,
|
||||||
|
SHADOW_CASCADE3_FRUSTUM,
|
||||||
|
|
||||||
|
SHADOW_CASCADE_FRUSTUM_COUNT,
|
||||||
|
|
||||||
|
VIEW_FRUSTUM = SHADOW_CASCADE_FRUSTUM_COUNT,
|
||||||
|
|
||||||
|
FRUSTUM_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
using Output = render::VaryingArray<ViewFrustumPointer, FRUSTUM_COUNT>;
|
||||||
|
using JobModel = render::Job::ModelO<ExtractFrustums, Output>;
|
||||||
|
|
||||||
|
void run(const render::RenderContextPointer& renderContext, Output& output);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // hifi_RenderDeferredTask_h
|
|
@ -25,6 +25,7 @@
|
||||||
#include <render/DrawSceneOctree.h>
|
#include <render/DrawSceneOctree.h>
|
||||||
#include <render/BlurTask.h>
|
#include <render/BlurTask.h>
|
||||||
|
|
||||||
|
#include "RenderCommonTask.h"
|
||||||
#include "LightingModel.h"
|
#include "LightingModel.h"
|
||||||
#include "StencilMaskPass.h"
|
#include "StencilMaskPass.h"
|
||||||
#include "DebugDeferredBuffer.h"
|
#include "DebugDeferredBuffer.h"
|
||||||
|
@ -289,23 +290,6 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
||||||
task.addJob<Blit>("Blit", primaryFramebuffer);
|
task.addJob<Blit>("Blit", primaryFramebuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BeginGPURangeTimer::run(const render::RenderContextPointer& renderContext, gpu::RangeTimerPointer& timer) {
|
|
||||||
timer = _gpuTimer;
|
|
||||||
gpu::doInBatch(renderContext->args->_context, [&](gpu::Batch& batch) {
|
|
||||||
_gpuTimer->begin(batch);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void EndGPURangeTimer::run(const render::RenderContextPointer& renderContext, const gpu::RangeTimerPointer& timer) {
|
|
||||||
gpu::doInBatch(renderContext->args->_context, [&](gpu::Batch& batch) {
|
|
||||||
timer->end(batch);
|
|
||||||
});
|
|
||||||
|
|
||||||
auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
|
|
||||||
config->setGPUBatchRunTime(timer->getGPUAverage(), timer->getBatchAverage());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DrawDeferred::run(const RenderContextPointer& renderContext, const Inputs& inputs) {
|
void DrawDeferred::run(const RenderContextPointer& renderContext, const Inputs& inputs) {
|
||||||
assert(renderContext->args);
|
assert(renderContext->args);
|
||||||
assert(renderContext->args->hasViewFrustum());
|
assert(renderContext->args->hasViewFrustum());
|
||||||
|
@ -410,177 +394,3 @@ void DrawStateSortDeferred::run(const RenderContextPointer& renderContext, const
|
||||||
config->setNumDrawn((int)inItems.size());
|
config->setNumDrawn((int)inItems.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawOverlay3D::DrawOverlay3D(bool opaque) :
|
|
||||||
_shapePlumber(std::make_shared<ShapePlumber>()),
|
|
||||||
_opaquePass(opaque) {
|
|
||||||
initOverlay3DPipelines(*_shapePlumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DrawOverlay3D::run(const RenderContextPointer& renderContext, const Inputs& inputs) {
|
|
||||||
assert(renderContext->args);
|
|
||||||
assert(renderContext->args->hasViewFrustum());
|
|
||||||
|
|
||||||
auto config = std::static_pointer_cast<Config>(renderContext->jobConfig);
|
|
||||||
|
|
||||||
const auto& inItems = inputs.get0();
|
|
||||||
const auto& lightingModel = inputs.get1();
|
|
||||||
|
|
||||||
config->setNumDrawn((int)inItems.size());
|
|
||||||
emit config->numDrawnChanged();
|
|
||||||
|
|
||||||
if (!inItems.empty()) {
|
|
||||||
RenderArgs* args = renderContext->args;
|
|
||||||
|
|
||||||
// Clear the framebuffer without stereo
|
|
||||||
// Needs to be distinct from the other batch because using the clear call
|
|
||||||
// while stereo is enabled triggers a warning
|
|
||||||
if (_opaquePass) {
|
|
||||||
gpu::doInBatch(args->_context, [&](gpu::Batch& batch){
|
|
||||||
batch.enableStereo(false);
|
|
||||||
batch.clearFramebuffer(gpu::Framebuffer::BUFFER_DEPTH, glm::vec4(), 1.f, 0, false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Render the items
|
|
||||||
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
|
||||||
args->_batch = &batch;
|
|
||||||
batch.setViewportTransform(args->_viewport);
|
|
||||||
batch.setStateScissorRect(args->_viewport);
|
|
||||||
|
|
||||||
glm::mat4 projMat;
|
|
||||||
Transform viewMat;
|
|
||||||
args->getViewFrustum().evalProjectionMatrix(projMat);
|
|
||||||
args->getViewFrustum().evalViewTransform(viewMat);
|
|
||||||
|
|
||||||
batch.setProjectionTransform(projMat);
|
|
||||||
batch.setViewTransform(viewMat);
|
|
||||||
|
|
||||||
// Setup lighting model for all items;
|
|
||||||
batch.setUniformBuffer(render::ShapePipeline::Slot::LIGHTING_MODEL, lightingModel->getParametersBuffer());
|
|
||||||
|
|
||||||
renderShapes(renderContext, _shapePlumber, inItems, _maxDrawn);
|
|
||||||
args->_batch = nullptr;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CompositeHUD::run(const RenderContextPointer& renderContext) {
|
|
||||||
assert(renderContext->args);
|
|
||||||
assert(renderContext->args->_context);
|
|
||||||
|
|
||||||
// We do not want to render HUD elements in secondary camera
|
|
||||||
if (renderContext->args->_renderMode == RenderArgs::RenderMode::SECONDARY_CAMERA_RENDER_MODE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Grab the HUD texture
|
|
||||||
gpu::doInBatch(renderContext->args->_context, [&](gpu::Batch& batch) {
|
|
||||||
if (renderContext->args->_hudOperator) {
|
|
||||||
renderContext->args->_hudOperator(batch, renderContext->args->_hudTexture, renderContext->args->_renderMode == RenderArgs::RenderMode::MIRROR_RENDER_MODE);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void Blit::run(const RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer) {
|
|
||||||
assert(renderContext->args);
|
|
||||||
assert(renderContext->args->_context);
|
|
||||||
|
|
||||||
RenderArgs* renderArgs = renderContext->args;
|
|
||||||
auto blitFbo = renderArgs->_blitFramebuffer;
|
|
||||||
|
|
||||||
if (!blitFbo) {
|
|
||||||
qCWarning(renderutils) << "Blit::run - no blit frame buffer.";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine size from viewport
|
|
||||||
int width = renderArgs->_viewport.z;
|
|
||||||
int height = renderArgs->_viewport.w;
|
|
||||||
|
|
||||||
// Blit primary to blit FBO
|
|
||||||
auto primaryFbo = srcFramebuffer;
|
|
||||||
|
|
||||||
gpu::doInBatch(renderArgs->_context, [&](gpu::Batch& batch) {
|
|
||||||
batch.setFramebuffer(blitFbo);
|
|
||||||
|
|
||||||
if (renderArgs->_renderMode == RenderArgs::MIRROR_RENDER_MODE) {
|
|
||||||
if (renderArgs->isStereo()) {
|
|
||||||
gpu::Vec4i srcRectLeft;
|
|
||||||
srcRectLeft.z = width / 2;
|
|
||||||
srcRectLeft.w = height;
|
|
||||||
|
|
||||||
gpu::Vec4i srcRectRight;
|
|
||||||
srcRectRight.x = width / 2;
|
|
||||||
srcRectRight.z = width;
|
|
||||||
srcRectRight.w = height;
|
|
||||||
|
|
||||||
gpu::Vec4i destRectLeft;
|
|
||||||
destRectLeft.x = srcRectLeft.z;
|
|
||||||
destRectLeft.z = srcRectLeft.x;
|
|
||||||
destRectLeft.y = srcRectLeft.y;
|
|
||||||
destRectLeft.w = srcRectLeft.w;
|
|
||||||
|
|
||||||
gpu::Vec4i destRectRight;
|
|
||||||
destRectRight.x = srcRectRight.z;
|
|
||||||
destRectRight.z = srcRectRight.x;
|
|
||||||
destRectRight.y = srcRectRight.y;
|
|
||||||
destRectRight.w = srcRectRight.w;
|
|
||||||
|
|
||||||
// Blit left to right and right to left in stereo
|
|
||||||
batch.blit(primaryFbo, srcRectRight, blitFbo, destRectLeft);
|
|
||||||
batch.blit(primaryFbo, srcRectLeft, blitFbo, destRectRight);
|
|
||||||
} else {
|
|
||||||
gpu::Vec4i srcRect;
|
|
||||||
srcRect.z = width;
|
|
||||||
srcRect.w = height;
|
|
||||||
|
|
||||||
gpu::Vec4i destRect;
|
|
||||||
destRect.x = width;
|
|
||||||
destRect.y = 0;
|
|
||||||
destRect.z = 0;
|
|
||||||
destRect.w = height;
|
|
||||||
|
|
||||||
batch.blit(primaryFbo, srcRect, blitFbo, destRect);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
gpu::Vec4i rect;
|
|
||||||
rect.z = width;
|
|
||||||
rect.w = height;
|
|
||||||
|
|
||||||
batch.blit(primaryFbo, rect, blitFbo, rect);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExtractFrustums::run(const render::RenderContextPointer& renderContext, Output& output) {
|
|
||||||
assert(renderContext->args);
|
|
||||||
assert(renderContext->args->_context);
|
|
||||||
|
|
||||||
RenderArgs* args = renderContext->args;
|
|
||||||
|
|
||||||
// Return view frustum
|
|
||||||
auto& viewFrustum = output[VIEW_FRUSTUM].edit<ViewFrustumPointer>();
|
|
||||||
if (!viewFrustum) {
|
|
||||||
viewFrustum = std::make_shared<ViewFrustum>(args->getViewFrustum());
|
|
||||||
} else {
|
|
||||||
*viewFrustum = args->getViewFrustum();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return shadow frustum
|
|
||||||
auto lightStage = args->_scene->getStage<LightStage>(LightStage::getName());
|
|
||||||
for (auto i = 0; i < SHADOW_CASCADE_FRUSTUM_COUNT; i++) {
|
|
||||||
auto& shadowFrustum = output[SHADOW_CASCADE0_FRUSTUM+i].edit<ViewFrustumPointer>();
|
|
||||||
if (lightStage) {
|
|
||||||
auto globalShadow = lightStage->getCurrentKeyShadow();
|
|
||||||
|
|
||||||
if (globalShadow && i<(int)globalShadow->getCascadeCount()) {
|
|
||||||
auto& cascade = globalShadow->getCascade(i);
|
|
||||||
shadowFrustum = cascade.getFrustum();
|
|
||||||
} else {
|
|
||||||
shadowFrustum.reset();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
shadowFrustum.reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -16,42 +16,17 @@
|
||||||
#include <render/RenderFetchCullSortTask.h>
|
#include <render/RenderFetchCullSortTask.h>
|
||||||
#include "LightingModel.h"
|
#include "LightingModel.h"
|
||||||
|
|
||||||
class BeginGPURangeTimer {
|
class DrawDeferredConfig : public render::Job::Config {
|
||||||
public:
|
|
||||||
using JobModel = render::Job::ModelO<BeginGPURangeTimer, gpu::RangeTimerPointer>;
|
|
||||||
|
|
||||||
BeginGPURangeTimer(const std::string& name) : _gpuTimer(std::make_shared<gpu::RangeTimer>(name)) {}
|
|
||||||
|
|
||||||
void run(const render::RenderContextPointer& renderContext, gpu::RangeTimerPointer& timer);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
gpu::RangeTimerPointer _gpuTimer;
|
|
||||||
};
|
|
||||||
|
|
||||||
using GPURangeTimerConfig = render::GPUJobConfig;
|
|
||||||
|
|
||||||
class EndGPURangeTimer {
|
|
||||||
public:
|
|
||||||
using Config = GPURangeTimerConfig;
|
|
||||||
using JobModel = render::Job::ModelI<EndGPURangeTimer, gpu::RangeTimerPointer, Config>;
|
|
||||||
|
|
||||||
EndGPURangeTimer() {}
|
|
||||||
|
|
||||||
void configure(const Config& config) {}
|
|
||||||
void run(const render::RenderContextPointer& renderContext, const gpu::RangeTimerPointer& timer);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
};
|
|
||||||
|
|
||||||
class DrawConfig : public render::Job::Config {
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(int numDrawn READ getNumDrawn NOTIFY newStats)
|
Q_PROPERTY(int numDrawn READ getNumDrawn NOTIFY newStats)
|
||||||
Q_PROPERTY(int maxDrawn MEMBER maxDrawn NOTIFY dirty)
|
Q_PROPERTY(int maxDrawn MEMBER maxDrawn NOTIFY dirty)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
int getNumDrawn() { return _numDrawn; }
|
int getNumDrawn() { return _numDrawn; }
|
||||||
void setNumDrawn(int numDrawn) { _numDrawn = numDrawn; emit newStats(); }
|
void setNumDrawn(int numDrawn) {
|
||||||
|
_numDrawn = numDrawn;
|
||||||
|
emit newStats();
|
||||||
|
}
|
||||||
|
|
||||||
int maxDrawn{ -1 };
|
int maxDrawn{ -1 };
|
||||||
|
|
||||||
|
@ -65,29 +40,32 @@ protected:
|
||||||
|
|
||||||
class DrawDeferred {
|
class DrawDeferred {
|
||||||
public:
|
public:
|
||||||
using Inputs = render::VaryingSet2 <render::ItemBounds, LightingModelPointer>;
|
using Inputs = render::VaryingSet2<render::ItemBounds, LightingModelPointer>;
|
||||||
using Config = DrawConfig;
|
using Config = DrawDeferredConfig;
|
||||||
using JobModel = render::Job::ModelI<DrawDeferred, Inputs, Config>;
|
using JobModel = render::Job::ModelI<DrawDeferred, Inputs, Config>;
|
||||||
|
|
||||||
DrawDeferred(render::ShapePlumberPointer shapePlumber) : _shapePlumber{ shapePlumber } {}
|
DrawDeferred(render::ShapePlumberPointer shapePlumber)
|
||||||
|
: _shapePlumber{ shapePlumber } {}
|
||||||
|
|
||||||
void configure(const Config& config) { _maxDrawn = config.maxDrawn; }
|
void configure(const Config& config) { _maxDrawn = config.maxDrawn; }
|
||||||
void run(const render::RenderContextPointer& renderContext, const Inputs& inputs);
|
void run(const render::RenderContextPointer& renderContext, const Inputs& inputs);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
render::ShapePlumberPointer _shapePlumber;
|
render::ShapePlumberPointer _shapePlumber;
|
||||||
int _maxDrawn; // initialized by Config
|
int _maxDrawn; // initialized by Config
|
||||||
};
|
};
|
||||||
|
|
||||||
class DrawStateSortConfig : public render::Job::Config {
|
class DrawStateSortConfig : public render::Job::Config {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(int numDrawn READ getNumDrawn NOTIFY numDrawnChanged)
|
Q_PROPERTY(int numDrawn READ getNumDrawn NOTIFY numDrawnChanged)
|
||||||
Q_PROPERTY(int maxDrawn MEMBER maxDrawn NOTIFY dirty)
|
Q_PROPERTY(int maxDrawn MEMBER maxDrawn NOTIFY dirty)
|
||||||
Q_PROPERTY(bool stateSort MEMBER stateSort NOTIFY dirty)
|
Q_PROPERTY(bool stateSort MEMBER stateSort NOTIFY dirty)
|
||||||
public:
|
public:
|
||||||
|
|
||||||
int getNumDrawn() { return numDrawn; }
|
int getNumDrawn() { return numDrawn; }
|
||||||
void setNumDrawn(int num) { numDrawn = num; emit numDrawnChanged(); }
|
void setNumDrawn(int num) {
|
||||||
|
numDrawn = num;
|
||||||
|
emit numDrawnChanged();
|
||||||
|
}
|
||||||
|
|
||||||
int maxDrawn{ -1 };
|
int maxDrawn{ -1 };
|
||||||
bool stateSort{ true };
|
bool stateSort{ true };
|
||||||
|
@ -102,101 +80,32 @@ protected:
|
||||||
|
|
||||||
class DrawStateSortDeferred {
|
class DrawStateSortDeferred {
|
||||||
public:
|
public:
|
||||||
using Inputs = render::VaryingSet2 <render::ItemBounds, LightingModelPointer>;
|
using Inputs = render::VaryingSet2<render::ItemBounds, LightingModelPointer>;
|
||||||
|
|
||||||
using Config = DrawStateSortConfig;
|
using Config = DrawStateSortConfig;
|
||||||
using JobModel = render::Job::ModelI<DrawStateSortDeferred, Inputs, Config>;
|
using JobModel = render::Job::ModelI<DrawStateSortDeferred, Inputs, Config>;
|
||||||
|
|
||||||
DrawStateSortDeferred(render::ShapePlumberPointer shapePlumber) : _shapePlumber{ shapePlumber } {}
|
DrawStateSortDeferred(render::ShapePlumberPointer shapePlumber)
|
||||||
|
: _shapePlumber{ shapePlumber } {}
|
||||||
|
|
||||||
void configure(const Config& config) { _maxDrawn = config.maxDrawn; _stateSort = config.stateSort; }
|
void configure(const Config& config) {
|
||||||
|
_maxDrawn = config.maxDrawn;
|
||||||
|
_stateSort = config.stateSort;
|
||||||
|
}
|
||||||
void run(const render::RenderContextPointer& renderContext, const Inputs& inputs);
|
void run(const render::RenderContextPointer& renderContext, const Inputs& inputs);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
render::ShapePlumberPointer _shapePlumber;
|
render::ShapePlumberPointer _shapePlumber;
|
||||||
int _maxDrawn; // initialized by Config
|
int _maxDrawn; // initialized by Config
|
||||||
bool _stateSort;
|
bool _stateSort;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DrawOverlay3DConfig : public render::Job::Config {
|
|
||||||
Q_OBJECT
|
|
||||||
Q_PROPERTY(int numDrawn READ getNumDrawn NOTIFY numDrawnChanged)
|
|
||||||
Q_PROPERTY(int maxDrawn MEMBER maxDrawn NOTIFY dirty)
|
|
||||||
public:
|
|
||||||
int getNumDrawn() { return numDrawn; }
|
|
||||||
void setNumDrawn(int num) { numDrawn = num; emit numDrawnChanged(); }
|
|
||||||
|
|
||||||
int maxDrawn{ -1 };
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void numDrawnChanged();
|
|
||||||
void dirty();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
int numDrawn{ 0 };
|
|
||||||
};
|
|
||||||
|
|
||||||
class DrawOverlay3D {
|
|
||||||
public:
|
|
||||||
using Inputs = render::VaryingSet2 <render::ItemBounds, LightingModelPointer>;
|
|
||||||
|
|
||||||
using Config = DrawOverlay3DConfig;
|
|
||||||
using JobModel = render::Job::ModelI<DrawOverlay3D, Inputs, Config>;
|
|
||||||
|
|
||||||
DrawOverlay3D(bool opaque);
|
|
||||||
|
|
||||||
void configure(const Config& config) { _maxDrawn = config.maxDrawn; }
|
|
||||||
void run(const render::RenderContextPointer& renderContext, const Inputs& inputs);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
render::ShapePlumberPointer _shapePlumber;
|
|
||||||
int _maxDrawn; // initialized by Config
|
|
||||||
bool _opaquePass { true };
|
|
||||||
};
|
|
||||||
|
|
||||||
class CompositeHUD {
|
|
||||||
public:
|
|
||||||
using JobModel = render::Job::Model<CompositeHUD>;
|
|
||||||
|
|
||||||
CompositeHUD() {}
|
|
||||||
void run(const render::RenderContextPointer& renderContext);
|
|
||||||
};
|
|
||||||
|
|
||||||
class Blit {
|
|
||||||
public:
|
|
||||||
using JobModel = render::Job::ModelI<Blit, gpu::FramebufferPointer>;
|
|
||||||
|
|
||||||
void run(const render::RenderContextPointer& renderContext, const gpu::FramebufferPointer& srcFramebuffer);
|
|
||||||
};
|
|
||||||
|
|
||||||
class ExtractFrustums {
|
|
||||||
public:
|
|
||||||
|
|
||||||
enum Frustum {
|
|
||||||
SHADOW_CASCADE0_FRUSTUM = 0,
|
|
||||||
SHADOW_CASCADE1_FRUSTUM,
|
|
||||||
SHADOW_CASCADE2_FRUSTUM,
|
|
||||||
SHADOW_CASCADE3_FRUSTUM,
|
|
||||||
|
|
||||||
SHADOW_CASCADE_FRUSTUM_COUNT,
|
|
||||||
|
|
||||||
VIEW_FRUSTUM = SHADOW_CASCADE_FRUSTUM_COUNT,
|
|
||||||
|
|
||||||
FRUSTUM_COUNT
|
|
||||||
};
|
|
||||||
|
|
||||||
using Output = render::VaryingArray<ViewFrustumPointer, FRUSTUM_COUNT>;
|
|
||||||
using JobModel = render::Job::ModelO<ExtractFrustums, Output>;
|
|
||||||
|
|
||||||
void run(const render::RenderContextPointer& renderContext, Output& output);
|
|
||||||
};
|
|
||||||
|
|
||||||
class RenderDeferredTaskConfig : public render::Task::Config {
|
class RenderDeferredTaskConfig : public render::Task::Config {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(float fadeScale MEMBER fadeScale NOTIFY dirty)
|
Q_PROPERTY(float fadeScale MEMBER fadeScale NOTIFY dirty)
|
||||||
Q_PROPERTY(float fadeDuration MEMBER fadeDuration NOTIFY dirty)
|
Q_PROPERTY(float fadeDuration MEMBER fadeDuration NOTIFY dirty)
|
||||||
Q_PROPERTY(bool debugFade MEMBER debugFade NOTIFY dirty)
|
Q_PROPERTY(bool debugFade MEMBER debugFade NOTIFY dirty)
|
||||||
Q_PROPERTY(float debugFadePercent MEMBER debugFadePercent NOTIFY dirty)
|
Q_PROPERTY(float debugFadePercent MEMBER debugFadePercent NOTIFY dirty)
|
||||||
public:
|
public:
|
||||||
float fadeScale{ 0.5f };
|
float fadeScale{ 0.5f };
|
||||||
float fadeDuration{ 3.0f };
|
float fadeDuration{ 3.0f };
|
||||||
|
@ -205,7 +114,6 @@ public:
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void dirty();
|
void dirty();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class RenderDeferredTask {
|
class RenderDeferredTask {
|
||||||
|
@ -220,9 +128,11 @@ public:
|
||||||
void build(JobModel& task, const render::Varying& inputs, render::Varying& outputs);
|
void build(JobModel& task, const render::Varying& inputs, render::Varying& outputs);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static const render::Varying addSelectItemJobs(JobModel& task,
|
||||||
static const render::Varying addSelectItemJobs(JobModel& task, const char* selectionName,
|
const char* selectionName,
|
||||||
const render::Varying& metas, const render::Varying& opaques, const render::Varying& transparents);
|
const render::Varying& metas,
|
||||||
|
const render::Varying& opaques,
|
||||||
|
const render::Varying& transparents);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_RenderDeferredTask_h
|
#endif // hifi_RenderDeferredTask_h
|
||||||
|
|
|
@ -11,26 +11,28 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "RenderForwardTask.h"
|
#include "RenderForwardTask.h"
|
||||||
#include "RenderDeferredTask.h"
|
|
||||||
|
|
||||||
#include <PerfStat.h>
|
#include <PerfStat.h>
|
||||||
#include <PathUtils.h>
|
#include <PathUtils.h>
|
||||||
#include <ViewFrustum.h>
|
#include <ViewFrustum.h>
|
||||||
#include <gpu/Context.h>
|
#include <gpu/Context.h>
|
||||||
|
#include <gpu/Texture.h>
|
||||||
|
#include <gpu/StandardShaderLib.h>
|
||||||
|
|
||||||
#include "StencilMaskPass.h"
|
#include "StencilMaskPass.h"
|
||||||
#include "ZoneRenderer.h"
|
#include "ZoneRenderer.h"
|
||||||
#include "FadeEffect.h"
|
#include "FadeEffect.h"
|
||||||
#include "BackgroundStage.h"
|
#include "BackgroundStage.h"
|
||||||
|
|
||||||
#include "FramebufferCache.h"
|
#include "FramebufferCache.h"
|
||||||
#include "TextureCache.h"
|
#include "TextureCache.h"
|
||||||
#include <gpu/Texture.h>
|
#include "RenderCommonTask.h"
|
||||||
#include <gpu/StandardShaderLib.h>
|
|
||||||
|
|
||||||
#include "nop_frag.h"
|
#include "nop_frag.h"
|
||||||
|
|
||||||
using namespace render;
|
using namespace render;
|
||||||
extern void initForwardPipelines(ShapePlumber& plumber, const render::ShapePipeline::BatchSetter& batchSetter, const render::ShapePipeline::ItemSetter& itemSetter);
|
extern void initForwardPipelines(ShapePlumber& plumber,
|
||||||
|
const render::ShapePipeline::BatchSetter& batchSetter,
|
||||||
|
const render::ShapePipeline::ItemSetter& itemSetter);
|
||||||
|
|
||||||
void RenderForwardTask::build(JobModel& task, const render::Varying& input, render::Varying& output) {
|
void RenderForwardTask::build(JobModel& task, const render::Varying& input, render::Varying& output) {
|
||||||
auto items = input.get<Input>();
|
auto items = input.get<Input>();
|
||||||
|
@ -43,12 +45,14 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend
|
||||||
// Extract opaques / transparents / lights / metas / overlays / background
|
// Extract opaques / transparents / lights / metas / overlays / background
|
||||||
const auto& opaques = items.get0()[RenderFetchCullSortTask::OPAQUE_SHAPE];
|
const auto& opaques = items.get0()[RenderFetchCullSortTask::OPAQUE_SHAPE];
|
||||||
const auto& transparents = items.get0()[RenderFetchCullSortTask::TRANSPARENT_SHAPE];
|
const auto& transparents = items.get0()[RenderFetchCullSortTask::TRANSPARENT_SHAPE];
|
||||||
// const auto& lights = items.get0()[RenderFetchCullSortTask::LIGHT];
|
// const auto& lights = items.get0()[RenderFetchCullSortTask::LIGHT];
|
||||||
const auto& metas = items.get0()[RenderFetchCullSortTask::META];
|
const auto& metas = items.get0()[RenderFetchCullSortTask::META];
|
||||||
// const auto& overlayOpaques = items.get0()[RenderFetchCullSortTask::OVERLAY_OPAQUE_SHAPE];
|
// const auto& overlayOpaques = items.get0()[RenderFetchCullSortTask::OVERLAY_OPAQUE_SHAPE];
|
||||||
// const auto& overlayTransparents = items.get0()[RenderFetchCullSortTask::OVERLAY_TRANSPARENT_SHAPE];
|
// const auto& overlayTransparents = items.get0()[RenderFetchCullSortTask::OVERLAY_TRANSPARENT_SHAPE];
|
||||||
//const auto& background = items.get0()[RenderFetchCullSortTask::BACKGROUND];
|
//const auto& background = items.get0()[RenderFetchCullSortTask::BACKGROUND];
|
||||||
// const auto& spatialSelection = items[1];
|
// const auto& spatialSelection = items[1];
|
||||||
|
|
||||||
|
fadeEffect->build(task, opaques);
|
||||||
|
|
||||||
const auto framebuffer = task.addJob<PrepareFramebuffer>("PrepareFramebuffer");
|
const auto framebuffer = task.addJob<PrepareFramebuffer>("PrepareFramebuffer");
|
||||||
|
|
||||||
|
@ -60,11 +64,11 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend
|
||||||
// Filter zones from the general metas bucket
|
// Filter zones from the general metas bucket
|
||||||
const auto zones = task.addJob<ZoneRendererTask>("ZoneRenderer", metas);
|
const auto zones = task.addJob<ZoneRendererTask>("ZoneRenderer", metas);
|
||||||
|
|
||||||
// task.addJob<DrawBackground>("DrawBackground", background);
|
// task.addJob<DrawBackground>("DrawBackground", background);
|
||||||
// Similar to light stage, background stage has been filled by several potential render items and resolved for the frame in this job
|
// Similar to light stage, background stage has been filled by several potential render items and resolved for the frame in this job
|
||||||
task.addJob<DrawBackgroundStage>("DrawBackgroundDeferred", lightingModel);
|
task.addJob<DrawBackgroundStage>("DrawBackgroundDeferred", lightingModel);
|
||||||
|
|
||||||
{ // Debug the bounds of the rendered items, still look at the zbuffer
|
{ // Debug the bounds of the rendered items, still look at the zbuffer
|
||||||
|
|
||||||
task.addJob<DrawBounds>("DrawMetaBounds", metas);
|
task.addJob<DrawBounds>("DrawMetaBounds", metas);
|
||||||
task.addJob<DrawBounds>("DrawBounds", opaques);
|
task.addJob<DrawBounds>("DrawBounds", opaques);
|
||||||
|
@ -74,13 +78,14 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend
|
||||||
|
|
||||||
task.addJob<Draw>("DrawTransparents", transparents, shapePlumber);
|
task.addJob<Draw>("DrawTransparents", transparents, shapePlumber);
|
||||||
|
|
||||||
|
// Composite the HUD and HUD overlays
|
||||||
|
task.addJob<CompositeHUD>("HUD");
|
||||||
|
|
||||||
// Blit!
|
// Blit!
|
||||||
task.addJob<Blit>("Blit", framebuffer);
|
task.addJob<Blit>("Blit", framebuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrepareFramebuffer::run(const RenderContextPointer& renderContext,
|
void PrepareFramebuffer::run(const RenderContextPointer& renderContext, gpu::FramebufferPointer& framebuffer) {
|
||||||
gpu::FramebufferPointer& framebuffer) {
|
|
||||||
auto framebufferCache = DependencyManager::get<FramebufferCache>();
|
auto framebufferCache = DependencyManager::get<FramebufferCache>();
|
||||||
auto framebufferSize = framebufferCache->getFrameBufferSize();
|
auto framebufferSize = framebufferCache->getFrameBufferSize();
|
||||||
glm::uvec2 frameSize(framebufferSize.width(), framebufferSize.height());
|
glm::uvec2 frameSize(framebufferSize.width(), framebufferSize.height());
|
||||||
|
@ -95,11 +100,13 @@ void PrepareFramebuffer::run(const RenderContextPointer& renderContext,
|
||||||
|
|
||||||
auto colorFormat = gpu::Element::COLOR_SRGBA_32;
|
auto colorFormat = gpu::Element::COLOR_SRGBA_32;
|
||||||
auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT);
|
auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT);
|
||||||
auto colorTexture = gpu::Texture::createRenderBuffer(colorFormat, frameSize.x, frameSize.y, gpu::Texture::SINGLE_MIP, defaultSampler);
|
auto colorTexture =
|
||||||
|
gpu::Texture::createRenderBuffer(colorFormat, frameSize.x, frameSize.y, gpu::Texture::SINGLE_MIP, defaultSampler);
|
||||||
_framebuffer->setRenderBuffer(0, colorTexture);
|
_framebuffer->setRenderBuffer(0, colorTexture);
|
||||||
|
|
||||||
auto depthFormat = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::DEPTH_STENCIL); // Depth24_Stencil8 texel format
|
auto depthFormat = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::DEPTH_STENCIL); // Depth24_Stencil8 texel format
|
||||||
auto depthTexture = gpu::Texture::createRenderBuffer(depthFormat, frameSize.x, frameSize.y, gpu::Texture::SINGLE_MIP, defaultSampler);
|
auto depthTexture =
|
||||||
|
gpu::Texture::createRenderBuffer(depthFormat, frameSize.x, frameSize.y, gpu::Texture::SINGLE_MIP, defaultSampler);
|
||||||
_framebuffer->setDepthStencilBuffer(depthTexture, depthFormat);
|
_framebuffer->setDepthStencilBuffer(depthTexture, depthFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,18 +117,15 @@ void PrepareFramebuffer::run(const RenderContextPointer& renderContext,
|
||||||
batch.setStateScissorRect(args->_viewport);
|
batch.setStateScissorRect(args->_viewport);
|
||||||
|
|
||||||
batch.setFramebuffer(_framebuffer);
|
batch.setFramebuffer(_framebuffer);
|
||||||
batch.clearFramebuffer(
|
batch.clearFramebuffer(gpu::Framebuffer::BUFFER_COLOR0 | gpu::Framebuffer::BUFFER_DEPTH |
|
||||||
gpu::Framebuffer::BUFFER_COLOR0 |
|
gpu::Framebuffer::BUFFER_STENCIL,
|
||||||
gpu::Framebuffer::BUFFER_DEPTH |
|
vec4(vec3(0), 1), 1.0, 0, true);
|
||||||
gpu::Framebuffer::BUFFER_STENCIL,
|
|
||||||
vec4(vec3(0), 1), 1.0, 0, true);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
framebuffer = _framebuffer;
|
framebuffer = _framebuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Draw::run(const RenderContextPointer& renderContext,
|
void Draw::run(const RenderContextPointer& renderContext, const Inputs& items) {
|
||||||
const Inputs& items) {
|
|
||||||
RenderArgs* args = renderContext->args;
|
RenderArgs* args = renderContext->args;
|
||||||
|
|
||||||
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||||
|
@ -174,8 +178,7 @@ void Stencil::run(const RenderContextPointer& renderContext) {
|
||||||
args->_batch = nullptr;
|
args->_batch = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawBackground::run(const RenderContextPointer& renderContext,
|
void DrawBackground::run(const RenderContextPointer& renderContext, const Inputs& background) {
|
||||||
const Inputs& background) {
|
|
||||||
RenderArgs* args = renderContext->args;
|
RenderArgs* args = renderContext->args;
|
||||||
|
|
||||||
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||||
|
@ -197,5 +200,3 @@ void DrawBackground::run(const RenderContextPointer& renderContext,
|
||||||
});
|
});
|
||||||
args->_batch = nullptr;
|
args->_batch = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -548,15 +548,12 @@ void OffscreenQmlSurface::render() {
|
||||||
|
|
||||||
PROFILE_RANGE(render_qml_gl, __FUNCTION__)
|
PROFILE_RANGE(render_qml_gl, __FUNCTION__)
|
||||||
_canvas->makeCurrent();
|
_canvas->makeCurrent();
|
||||||
|
|
||||||
_renderControl->sync();
|
_renderControl->sync();
|
||||||
_quickWindow->setRenderTarget(_fbo, QSize(_size.x, _size.y));
|
_quickWindow->setRenderTarget(_fbo, QSize(_size.x, _size.y));
|
||||||
|
|
||||||
GLuint texture = offscreenTextures.getNextTexture(_size);
|
GLuint texture = offscreenTextures.getNextTexture(_size);
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo);
|
||||||
#if !defined(Q_OS_ANDROID)
|
glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0);
|
||||||
glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0);
|
|
||||||
#endif
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
_renderControl->render();
|
_renderControl->render();
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
|
@ -843,7 +840,7 @@ QQmlContext* OffscreenQmlSurface::contextForUrl(const QUrl& qmlSource, QQuickIte
|
||||||
|
|
||||||
QQmlContext* targetContext = parent ? QQmlEngine::contextForObject(parent) : _qmlContext;
|
QQmlContext* targetContext = parent ? QQmlEngine::contextForObject(parent) : _qmlContext;
|
||||||
if (!targetContext) {
|
if (!targetContext) {
|
||||||
targetContext = _qmlContext;
|
targetContext = _qmlContext;
|
||||||
}
|
}
|
||||||
if (_rootItem && forceNewContext) {
|
if (_rootItem && forceNewContext) {
|
||||||
targetContext = new QQmlContext(targetContext);
|
targetContext = new QQmlContext(targetContext);
|
||||||
|
|
Loading…
Reference in a new issue