mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 23:03:12 +02:00
Merge pull request #5885 from ZappoMan/batchOptimizations
Batch optimizations
This commit is contained in:
commit
46e9c463fc
14 changed files with 733 additions and 697 deletions
|
@ -1035,13 +1035,6 @@ void Application::initializeUi() {
|
||||||
updateInputModes();
|
updateInputModes();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename F>
|
|
||||||
void doInBatch(RenderArgs* args, F f) {
|
|
||||||
gpu::Batch batch;
|
|
||||||
f(batch);
|
|
||||||
args->_context->render(batch);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::paintGL() {
|
void Application::paintGL() {
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(__FUNCTION__);
|
||||||
if (nullptr == _displayPlugin) {
|
if (nullptr == _displayPlugin) {
|
||||||
|
@ -1095,12 +1088,12 @@ void Application::paintGL() {
|
||||||
auto mirrorRectDest = glm::ivec4(mirrorRect.z, mirrorRect.y, mirrorRect.x, mirrorRect.w);
|
auto mirrorRectDest = glm::ivec4(mirrorRect.z, mirrorRect.y, mirrorRect.x, mirrorRect.w);
|
||||||
|
|
||||||
auto selfieFbo = DependencyManager::get<FramebufferCache>()->getSelfieFramebuffer();
|
auto selfieFbo = DependencyManager::get<FramebufferCache>()->getSelfieFramebuffer();
|
||||||
gpu::Batch batch;
|
doInBatch(renderArgs._context, [=](gpu::Batch& batch) {
|
||||||
batch.setFramebuffer(selfieFbo);
|
batch.setFramebuffer(selfieFbo);
|
||||||
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0f, 0.0f, 0.0f, 0.0f));
|
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0f, 0.0f, 0.0f, 0.0f));
|
||||||
batch.blit(primaryFbo, mirrorRect, selfieFbo, mirrorRectDest);
|
batch.blit(primaryFbo, mirrorRect, selfieFbo, mirrorRectDest);
|
||||||
batch.setFramebuffer(nullptr);
|
batch.setFramebuffer(nullptr);
|
||||||
renderArgs._context->render(batch);
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1224,7 +1217,7 @@ void Application::paintGL() {
|
||||||
}
|
}
|
||||||
displaySide(&renderArgs, _myCamera);
|
displaySide(&renderArgs, _myCamera);
|
||||||
renderArgs._context->enableStereo(false);
|
renderArgs._context->enableStereo(false);
|
||||||
doInBatch(&renderArgs, [](gpu::Batch& batch) {
|
doInBatch(renderArgs._context, [](gpu::Batch& batch) {
|
||||||
batch.setFramebuffer(nullptr);
|
batch.setFramebuffer(nullptr);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1288,9 +1281,9 @@ void Application::paintGL() {
|
||||||
|
|
||||||
// Reset the gpu::Context Stages
|
// Reset the gpu::Context Stages
|
||||||
// Back to the default framebuffer;
|
// Back to the default framebuffer;
|
||||||
gpu::Batch batch;
|
doInBatch(renderArgs._context, [=](gpu::Batch& batch) {
|
||||||
batch.resetStages();
|
batch.resetStages();
|
||||||
renderArgs._context->render(batch);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::runTests() {
|
void Application::runTests() {
|
||||||
|
|
|
@ -207,36 +207,36 @@ void ApplicationCompositor::displayOverlayTexture(RenderArgs* renderArgs) {
|
||||||
updateTooltips();
|
updateTooltips();
|
||||||
|
|
||||||
//Handle fading and deactivation/activation of UI
|
//Handle fading and deactivation/activation of UI
|
||||||
gpu::Batch batch;
|
doInBatch(renderArgs->_context, [=](gpu::Batch& batch) {
|
||||||
|
|
||||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||||
|
|
||||||
geometryCache->useSimpleDrawPipeline(batch);
|
geometryCache->useSimpleDrawPipeline(batch);
|
||||||
batch.setViewportTransform(renderArgs->_viewport);
|
batch.setViewportTransform(renderArgs->_viewport);
|
||||||
batch.setModelTransform(Transform());
|
batch.setModelTransform(Transform());
|
||||||
batch.setViewTransform(Transform());
|
batch.setViewTransform(Transform());
|
||||||
batch.setProjectionTransform(mat4());
|
batch.setProjectionTransform(mat4());
|
||||||
batch.setResourceTexture(0, overlayFramebuffer->getRenderBuffer(0));
|
batch.setResourceTexture(0, overlayFramebuffer->getRenderBuffer(0));
|
||||||
geometryCache->renderUnitQuad(batch, vec4(vec3(1), _alpha));
|
geometryCache->renderUnitQuad(batch, vec4(vec3(1), _alpha));
|
||||||
|
|
||||||
// Doesn't actually render
|
// Doesn't actually render
|
||||||
renderPointers(batch);
|
renderPointers(batch);
|
||||||
|
|
||||||
//draw the mouse pointer
|
//draw the mouse pointer
|
||||||
// Get the mouse coordinates and convert to NDC [-1, 1]
|
// Get the mouse coordinates and convert to NDC [-1, 1]
|
||||||
vec2 canvasSize = qApp->getCanvasSize();
|
vec2 canvasSize = qApp->getCanvasSize();
|
||||||
vec2 mousePosition = toNormalizedDeviceScale(vec2(qApp->getMouse()), canvasSize);
|
vec2 mousePosition = toNormalizedDeviceScale(vec2(qApp->getMouse()), canvasSize);
|
||||||
// Invert the Y axis
|
// Invert the Y axis
|
||||||
mousePosition.y *= -1.0f;
|
mousePosition.y *= -1.0f;
|
||||||
|
|
||||||
Transform model;
|
Transform model;
|
||||||
model.setTranslation(vec3(mousePosition, 0));
|
model.setTranslation(vec3(mousePosition, 0));
|
||||||
vec2 mouseSize = CURSOR_PIXEL_SIZE / canvasSize;
|
vec2 mouseSize = CURSOR_PIXEL_SIZE / canvasSize;
|
||||||
model.setScale(vec3(mouseSize, 1.0f));
|
model.setScale(vec3(mouseSize, 1.0f));
|
||||||
batch.setModelTransform(model);
|
batch.setModelTransform(model);
|
||||||
bindCursorTexture(batch);
|
bindCursorTexture(batch);
|
||||||
geometryCache->renderUnitQuad(batch, vec4(1));
|
geometryCache->renderUnitQuad(batch, vec4(1));
|
||||||
renderArgs->_context->render(batch);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -278,75 +278,67 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int
|
||||||
|
|
||||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||||
|
|
||||||
gpu::Batch batch;
|
doInBatch(renderArgs->_context, [=](gpu::Batch& batch) {
|
||||||
geometryCache->useSimpleDrawPipeline(batch);
|
geometryCache->useSimpleDrawPipeline(batch);
|
||||||
//batch._glDisable(GL_DEPTH_TEST);
|
|
||||||
//batch._glDisable(GL_CULL_FACE);
|
|
||||||
//batch._glBindTexture(GL_TEXTURE_2D, texture);
|
|
||||||
//batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
//batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
|
|
||||||
batch.setResourceTexture(0, overlayFramebuffer->getRenderBuffer(0));
|
batch.setResourceTexture(0, overlayFramebuffer->getRenderBuffer(0));
|
||||||
|
|
||||||
mat4 camMat;
|
mat4 camMat;
|
||||||
_cameraBaseTransform.getMatrix(camMat);
|
_cameraBaseTransform.getMatrix(camMat);
|
||||||
camMat = camMat * qApp->getEyePose(eye);
|
camMat = camMat * qApp->getEyePose(eye);
|
||||||
batch.setViewportTransform(renderArgs->_viewport);
|
batch.setViewportTransform(renderArgs->_viewport);
|
||||||
batch.setViewTransform(camMat);
|
batch.setViewTransform(camMat);
|
||||||
|
|
||||||
batch.setProjectionTransform(qApp->getEyeProjection(eye));
|
batch.setProjectionTransform(qApp->getEyeProjection(eye));
|
||||||
|
|
||||||
#ifdef DEBUG_OVERLAY
|
#ifdef DEBUG_OVERLAY
|
||||||
{
|
{
|
||||||
batch.setModelTransform(glm::translate(mat4(), vec3(0, 0, -2)));
|
batch.setModelTransform(glm::translate(mat4(), vec3(0, 0, -2)));
|
||||||
geometryCache->renderUnitQuad(batch, glm::vec4(1));
|
geometryCache->renderUnitQuad(batch, glm::vec4(1));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
//batch.setModelTransform(overlayXfm);
|
batch.setModelTransform(_modelTransform);
|
||||||
|
drawSphereSection(batch);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
batch.setModelTransform(_modelTransform);
|
// Doesn't actually render
|
||||||
drawSphereSection(batch);
|
renderPointers(batch);
|
||||||
}
|
vec3 reticleScale = vec3(Cursor::Manager::instance().getScale() * reticleSize);
|
||||||
#endif
|
|
||||||
|
|
||||||
// Doesn't actually render
|
bindCursorTexture(batch);
|
||||||
renderPointers(batch);
|
|
||||||
vec3 reticleScale = vec3(Cursor::Manager::instance().getScale() * reticleSize);
|
|
||||||
|
|
||||||
bindCursorTexture(batch);
|
//Controller Pointers
|
||||||
|
glm::mat4 overlayXfm;
|
||||||
|
_modelTransform.getMatrix(overlayXfm);
|
||||||
|
|
||||||
//Controller Pointers
|
MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||||
glm::mat4 overlayXfm;
|
for (int i = 0; i < (int)myAvatar->getHand()->getNumPalms(); i++) {
|
||||||
_modelTransform.getMatrix(overlayXfm);
|
PalmData& palm = myAvatar->getHand()->getPalms()[i];
|
||||||
|
if (palm.isActive()) {
|
||||||
|
glm::vec2 polar = getPolarCoordinates(palm);
|
||||||
|
// Convert to quaternion
|
||||||
|
mat4 pointerXfm = glm::mat4_cast(quat(vec3(polar.y, -polar.x, 0.0f))) * glm::translate(mat4(), vec3(0, 0, -1));
|
||||||
|
mat4 reticleXfm = overlayXfm * pointerXfm;
|
||||||
|
reticleXfm = glm::scale(reticleXfm, reticleScale);
|
||||||
|
batch.setModelTransform(reticleXfm);
|
||||||
|
// Render reticle at location
|
||||||
|
geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
//Mouse Pointer
|
||||||
for (int i = 0; i < (int)myAvatar->getHand()->getNumPalms(); i++) {
|
if (_reticleActive[MOUSE]) {
|
||||||
PalmData& palm = myAvatar->getHand()->getPalms()[i];
|
glm::vec2 projection = screenToSpherical(glm::vec2(_reticlePosition[MOUSE].x(),
|
||||||
if (palm.isActive()) {
|
_reticlePosition[MOUSE].y()));
|
||||||
glm::vec2 polar = getPolarCoordinates(palm);
|
mat4 pointerXfm = glm::mat4_cast(quat(vec3(-projection.y, projection.x, 0.0f))) * glm::translate(mat4(), vec3(0, 0, -1));
|
||||||
// Convert to quaternion
|
|
||||||
mat4 pointerXfm = glm::mat4_cast(quat(vec3(polar.y, -polar.x, 0.0f))) * glm::translate(mat4(), vec3(0, 0, -1));
|
|
||||||
mat4 reticleXfm = overlayXfm * pointerXfm;
|
mat4 reticleXfm = overlayXfm * pointerXfm;
|
||||||
reticleXfm = glm::scale(reticleXfm, reticleScale);
|
reticleXfm = glm::scale(reticleXfm, reticleScale);
|
||||||
batch.setModelTransform(reticleXfm);
|
batch.setModelTransform(reticleXfm);
|
||||||
// Render reticle at location
|
|
||||||
geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad);
|
geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
//Mouse Pointer
|
|
||||||
if (_reticleActive[MOUSE]) {
|
|
||||||
glm::vec2 projection = screenToSpherical(glm::vec2(_reticlePosition[MOUSE].x(),
|
|
||||||
_reticlePosition[MOUSE].y()));
|
|
||||||
mat4 pointerXfm = glm::mat4_cast(quat(vec3(-projection.y, projection.x, 0.0f))) * glm::translate(mat4(), vec3(0, 0, -1));
|
|
||||||
mat4 reticleXfm = overlayXfm * pointerXfm;
|
|
||||||
reticleXfm = glm::scale(reticleXfm, reticleScale);
|
|
||||||
batch.setModelTransform(reticleXfm);
|
|
||||||
geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderArgs->_context->render(batch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,8 @@ void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) {
|
||||||
|
|
||||||
renderArgs->_context->render(batch);
|
renderArgs->_context->render(batch);
|
||||||
|
|
||||||
|
qDebug() << "ApplicationOverlay::renderOverlay() batch:" << batch.getCacheState();
|
||||||
|
|
||||||
renderArgs->_batch = nullptr; // so future users of renderArgs don't try to use our batch
|
renderArgs->_batch = nullptr; // so future users of renderArgs don't try to use our batch
|
||||||
|
|
||||||
CHECK_GL_ERROR();
|
CHECK_GL_ERROR();
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
//
|
//
|
||||||
#include "Batch.h"
|
#include "Batch.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#if defined(NSIGHT_FOUND)
|
#if defined(NSIGHT_FOUND)
|
||||||
|
@ -41,7 +42,21 @@ Batch::Batch() :
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Batch::Batch(const CacheState& cacheState) : Batch() {
|
||||||
|
_commands.reserve(cacheState.commandsSize);
|
||||||
|
_commandOffsets.reserve(cacheState.offsetsSize);
|
||||||
|
_params.reserve(cacheState.paramsSize);
|
||||||
|
_data.reserve(cacheState.dataSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
Batch::CacheState Batch::getCacheState() {
|
||||||
|
return CacheState(_commands.size(), _commandOffsets.size(), _params.size(), _data.size(),
|
||||||
|
_buffers.size(), _textures.size(), _streamFormats.size(), _transforms.size(), _pipelines.size(),
|
||||||
|
_framebuffers.size(), _queries.size());
|
||||||
|
}
|
||||||
|
|
||||||
Batch::~Batch() {
|
Batch::~Batch() {
|
||||||
|
//qDebug() << "Batch::~Batch()... " << getCacheState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::clear() {
|
void Batch::clear() {
|
||||||
|
@ -358,3 +373,14 @@ void Batch::preExecute() {
|
||||||
}
|
}
|
||||||
_namedData.clear();
|
_namedData.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QDebug& operator<<(QDebug& debug, const Batch::CacheState& cacheState) {
|
||||||
|
debug << "Batch::CacheState[ "
|
||||||
|
<< "commandsSize:" << cacheState.commandsSize
|
||||||
|
<< "offsetsSize:" << cacheState.offsetsSize
|
||||||
|
<< "paramsSize:" << cacheState.paramsSize
|
||||||
|
<< "dataSize:" << cacheState.dataSize
|
||||||
|
<< "]";
|
||||||
|
|
||||||
|
return debug;
|
||||||
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "Texture.h"
|
#include "Texture.h"
|
||||||
#include "Transform.h"
|
#include "Transform.h"
|
||||||
|
|
||||||
|
|
||||||
#if defined(NSIGHT_FOUND)
|
#if defined(NSIGHT_FOUND)
|
||||||
class ProfileRange {
|
class ProfileRange {
|
||||||
public:
|
public:
|
||||||
|
@ -33,6 +34,8 @@
|
||||||
#define PROFILE_RANGE(name)
|
#define PROFILE_RANGE(name)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
class QDebug;
|
||||||
|
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
|
|
||||||
enum ReservedSlot {
|
enum ReservedSlot {
|
||||||
|
@ -70,7 +73,34 @@ public:
|
||||||
|
|
||||||
using NamedBatchDataMap = std::map<std::string, NamedBatchData>;
|
using NamedBatchDataMap = std::map<std::string, NamedBatchData>;
|
||||||
|
|
||||||
|
class CacheState {
|
||||||
|
public:
|
||||||
|
size_t commandsSize;
|
||||||
|
size_t offsetsSize;
|
||||||
|
size_t paramsSize;
|
||||||
|
size_t dataSize;
|
||||||
|
|
||||||
|
size_t buffersSize;
|
||||||
|
size_t texturesSize;
|
||||||
|
size_t streamFormatsSize;
|
||||||
|
size_t transformsSize;
|
||||||
|
size_t pipelinesSize;
|
||||||
|
size_t framebuffersSize;
|
||||||
|
size_t queriesSize;
|
||||||
|
|
||||||
|
CacheState() : commandsSize(0), offsetsSize(0), paramsSize(0), dataSize(0), buffersSize(0), texturesSize(0),
|
||||||
|
streamFormatsSize(0), transformsSize(0), pipelinesSize(0), framebuffersSize(0), queriesSize(0) { }
|
||||||
|
|
||||||
|
CacheState(size_t commandsSize, size_t offsetsSize, size_t paramsSize, size_t dataSize, size_t buffersSize,
|
||||||
|
size_t texturesSize, size_t streamFormatsSize, size_t transformsSize, size_t pipelinesSize,
|
||||||
|
size_t framebuffersSize, size_t queriesSize) :
|
||||||
|
commandsSize(commandsSize), offsetsSize(offsetsSize), paramsSize(paramsSize), dataSize(dataSize),
|
||||||
|
buffersSize(buffersSize), texturesSize(texturesSize), streamFormatsSize(streamFormatsSize),
|
||||||
|
transformsSize(transformsSize), pipelinesSize(pipelinesSize), framebuffersSize(framebuffersSize), queriesSize(queriesSize) { }
|
||||||
|
};
|
||||||
|
|
||||||
Batch();
|
Batch();
|
||||||
|
Batch(const CacheState& cacheState);
|
||||||
explicit Batch(const Batch& batch);
|
explicit Batch(const Batch& batch);
|
||||||
~Batch();
|
~Batch();
|
||||||
|
|
||||||
|
@ -78,6 +108,9 @@ public:
|
||||||
|
|
||||||
void preExecute();
|
void preExecute();
|
||||||
|
|
||||||
|
CacheState getCacheState();
|
||||||
|
|
||||||
|
|
||||||
// Batches may need to override the context level stereo settings
|
// Batches may need to override the context level stereo settings
|
||||||
// if they're performing framebuffer copy operations, like the
|
// if they're performing framebuffer copy operations, like the
|
||||||
// deferred lighting resolution mechanism
|
// deferred lighting resolution mechanism
|
||||||
|
@ -307,6 +340,7 @@ public:
|
||||||
public:
|
public:
|
||||||
std::vector< Cache<T> > _items;
|
std::vector< Cache<T> > _items;
|
||||||
|
|
||||||
|
size_t size() const { return _items.size(); }
|
||||||
uint32 cache(const Data& data) {
|
uint32 cache(const Data& data) {
|
||||||
uint32 offset = _items.size();
|
uint32 offset = _items.size();
|
||||||
_items.push_back(Cache<T>(data));
|
_items.push_back(Cache<T>(data));
|
||||||
|
@ -373,4 +407,6 @@ protected:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QDebug& operator<<(QDebug& debug, const gpu::Batch::CacheState& cacheState);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -217,4 +217,13 @@ typedef std::shared_ptr<Context> ContextPointer;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
void doInBatch(std::shared_ptr<gpu::Context> context, F f) {
|
||||||
|
static gpu::Batch::CacheState cacheState;
|
||||||
|
gpu::Batch batch(cacheState);
|
||||||
|
f(batch);
|
||||||
|
context->render(batch);
|
||||||
|
cacheState = batch.getCacheState();
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -173,23 +173,22 @@ void ViveControllerManager::updateRendering(RenderArgs* args, render::ScenePoint
|
||||||
UserInputMapper::PoseValue leftHand = _poseStateMap[makeInput(JointChannel::LEFT_HAND).getChannel()];
|
UserInputMapper::PoseValue leftHand = _poseStateMap[makeInput(JointChannel::LEFT_HAND).getChannel()];
|
||||||
UserInputMapper::PoseValue rightHand = _poseStateMap[makeInput(JointChannel::RIGHT_HAND).getChannel()];
|
UserInputMapper::PoseValue rightHand = _poseStateMap[makeInput(JointChannel::RIGHT_HAND).getChannel()];
|
||||||
|
|
||||||
gpu::Batch batch;
|
doInBatch(args->_context, [=](gpu::Batch& batch) {
|
||||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||||
geometryCache->useSimpleDrawPipeline(batch);
|
geometryCache->useSimpleDrawPipeline(batch);
|
||||||
DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(batch, true);
|
DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(batch, true);
|
||||||
|
|
||||||
auto mesh = _modelGeometry.getMesh();
|
auto mesh = _modelGeometry.getMesh();
|
||||||
batch.setInputFormat(mesh->getVertexFormat());
|
batch.setInputFormat(mesh->getVertexFormat());
|
||||||
//batch._glBindTexture(GL_TEXTURE_2D, _uexture);
|
//batch._glBindTexture(GL_TEXTURE_2D, _uexture);
|
||||||
|
|
||||||
if (leftHand.isValid()) {
|
if (leftHand.isValid()) {
|
||||||
renderHand(leftHand, batch, LEFT_HAND);
|
renderHand(leftHand, batch, LEFT_HAND);
|
||||||
}
|
}
|
||||||
if (rightHand.isValid()) {
|
if (rightHand.isValid()) {
|
||||||
renderHand(rightHand, batch, RIGHT_HAND);
|
renderHand(rightHand, batch, RIGHT_HAND);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
args->_context->render(batch);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -178,112 +178,109 @@ void AmbientOcclusion::run(const render::SceneContextPointer& sceneContext, cons
|
||||||
assert(renderContext->args);
|
assert(renderContext->args);
|
||||||
assert(renderContext->args->_viewFrustum);
|
assert(renderContext->args->_viewFrustum);
|
||||||
|
|
||||||
gpu::Batch batch;
|
|
||||||
RenderArgs* args = renderContext->args;
|
RenderArgs* args = renderContext->args;
|
||||||
|
doInBatch(args->_context, [=](gpu::Batch& batch) {
|
||||||
auto framebufferCache = DependencyManager::get<FramebufferCache>();
|
auto framebufferCache = DependencyManager::get<FramebufferCache>();
|
||||||
QSize framebufferSize = framebufferCache->getFrameBufferSize();
|
QSize framebufferSize = framebufferCache->getFrameBufferSize();
|
||||||
float fbWidth = framebufferSize.width();
|
float fbWidth = framebufferSize.width();
|
||||||
float fbHeight = framebufferSize.height();
|
float fbHeight = framebufferSize.height();
|
||||||
float sMin = args->_viewport.x / fbWidth;
|
float sMin = args->_viewport.x / fbWidth;
|
||||||
float sWidth = args->_viewport.z / fbWidth;
|
float sWidth = args->_viewport.z / fbWidth;
|
||||||
float tMin = args->_viewport.y / fbHeight;
|
float tMin = args->_viewport.y / fbHeight;
|
||||||
float tHeight = args->_viewport.w / fbHeight;
|
float tHeight = args->_viewport.w / fbHeight;
|
||||||
|
|
||||||
|
|
||||||
glm::mat4 projMat;
|
glm::mat4 projMat;
|
||||||
Transform viewMat;
|
Transform viewMat;
|
||||||
args->_viewFrustum->evalProjectionMatrix(projMat);
|
args->_viewFrustum->evalProjectionMatrix(projMat);
|
||||||
args->_viewFrustum->evalViewTransform(viewMat);
|
args->_viewFrustum->evalViewTransform(viewMat);
|
||||||
batch.setProjectionTransform(projMat);
|
batch.setProjectionTransform(projMat);
|
||||||
batch.setViewTransform(viewMat);
|
batch.setViewTransform(viewMat);
|
||||||
batch.setModelTransform(Transform());
|
batch.setModelTransform(Transform());
|
||||||
|
|
||||||
// Occlusion step
|
// Occlusion step
|
||||||
getOcclusionPipeline();
|
getOcclusionPipeline();
|
||||||
batch.setResourceTexture(0, framebufferCache->getPrimaryDepthTexture());
|
batch.setResourceTexture(0, framebufferCache->getPrimaryDepthTexture());
|
||||||
batch.setResourceTexture(1, framebufferCache->getPrimaryNormalTexture());
|
batch.setResourceTexture(1, framebufferCache->getPrimaryNormalTexture());
|
||||||
_occlusionBuffer->setRenderBuffer(0, _occlusionTexture);
|
_occlusionBuffer->setRenderBuffer(0, _occlusionTexture);
|
||||||
batch.setFramebuffer(_occlusionBuffer);
|
batch.setFramebuffer(_occlusionBuffer);
|
||||||
|
|
||||||
// Occlusion uniforms
|
// Occlusion uniforms
|
||||||
g_scale = 1.0f;
|
g_scale = 1.0f;
|
||||||
g_bias = 1.0f;
|
g_bias = 1.0f;
|
||||||
g_sample_rad = 1.0f;
|
g_sample_rad = 1.0f;
|
||||||
g_intensity = 1.0f;
|
g_intensity = 1.0f;
|
||||||
|
|
||||||
// Bind the first gpu::Pipeline we need - for calculating occlusion buffer
|
// Bind the first gpu::Pipeline we need - for calculating occlusion buffer
|
||||||
batch.setPipeline(getOcclusionPipeline());
|
batch.setPipeline(getOcclusionPipeline());
|
||||||
batch._glUniform1f(_gScaleLoc, g_scale);
|
batch._glUniform1f(_gScaleLoc, g_scale);
|
||||||
batch._glUniform1f(_gBiasLoc, g_bias);
|
batch._glUniform1f(_gBiasLoc, g_bias);
|
||||||
batch._glUniform1f(_gSampleRadiusLoc, g_sample_rad);
|
batch._glUniform1f(_gSampleRadiusLoc, g_sample_rad);
|
||||||
batch._glUniform1f(_gIntensityLoc, g_intensity);
|
batch._glUniform1f(_gIntensityLoc, g_intensity);
|
||||||
|
|
||||||
// setup uniforms for unpacking a view-space position from the depth buffer
|
// setup uniforms for unpacking a view-space position from the depth buffer
|
||||||
// This is code taken from DeferredLightEffect.render() method in DeferredLightingEffect.cpp.
|
// This is code taken from DeferredLightEffect.render() method in DeferredLightingEffect.cpp.
|
||||||
// DeferredBuffer.slh shows how the unpacking is done and what variables are needed.
|
// DeferredBuffer.slh shows how the unpacking is done and what variables are needed.
|
||||||
|
|
||||||
// initialize the view-space unpacking uniforms using frustum data
|
// initialize the view-space unpacking uniforms using frustum data
|
||||||
float left, right, bottom, top, nearVal, farVal;
|
float left, right, bottom, top, nearVal, farVal;
|
||||||
glm::vec4 nearClipPlane, farClipPlane;
|
glm::vec4 nearClipPlane, farClipPlane;
|
||||||
|
|
||||||
args->_viewFrustum->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
|
args->_viewFrustum->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
|
||||||
|
|
||||||
float depthScale = (farVal - nearVal) / farVal;
|
float depthScale = (farVal - nearVal) / farVal;
|
||||||
float nearScale = -1.0f / nearVal;
|
float nearScale = -1.0f / nearVal;
|
||||||
float depthTexCoordScaleS = (right - left) * nearScale / sWidth;
|
float depthTexCoordScaleS = (right - left) * nearScale / sWidth;
|
||||||
float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight;
|
float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight;
|
||||||
float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS;
|
float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS;
|
||||||
float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT;
|
float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT;
|
||||||
|
|
||||||
// now set the position-unpacking unforms
|
// now set the position-unpacking unforms
|
||||||
batch._glUniform1f(_nearLoc, nearVal);
|
batch._glUniform1f(_nearLoc, nearVal);
|
||||||
batch._glUniform1f(_depthScaleLoc, depthScale);
|
batch._glUniform1f(_depthScaleLoc, depthScale);
|
||||||
batch._glUniform2f(_depthTexCoordOffsetLoc, depthTexCoordOffsetS, depthTexCoordOffsetT);
|
batch._glUniform2f(_depthTexCoordOffsetLoc, depthTexCoordOffsetS, depthTexCoordOffsetT);
|
||||||
batch._glUniform2f(_depthTexCoordScaleLoc, depthTexCoordScaleS, depthTexCoordScaleT);
|
batch._glUniform2f(_depthTexCoordScaleLoc, depthTexCoordScaleS, depthTexCoordScaleT);
|
||||||
|
|
||||||
batch._glUniform2f(_renderTargetResLoc, fbWidth, fbHeight);
|
batch._glUniform2f(_renderTargetResLoc, fbWidth, fbHeight);
|
||||||
batch._glUniform2f(_renderTargetResInvLoc, 1.0f / fbWidth, 1.0f / fbHeight);
|
batch._glUniform2f(_renderTargetResInvLoc, 1.0f / fbWidth, 1.0f / fbHeight);
|
||||||
|
|
||||||
glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f);
|
glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
glm::vec2 bottomLeft(-1.0f, -1.0f);
|
glm::vec2 bottomLeft(-1.0f, -1.0f);
|
||||||
glm::vec2 topRight(1.0f, 1.0f);
|
glm::vec2 topRight(1.0f, 1.0f);
|
||||||
glm::vec2 texCoordTopLeft(0.0f, 0.0f);
|
glm::vec2 texCoordTopLeft(0.0f, 0.0f);
|
||||||
glm::vec2 texCoordBottomRight(1.0f, 1.0f);
|
glm::vec2 texCoordBottomRight(1.0f, 1.0f);
|
||||||
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
|
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
|
||||||
|
|
||||||
// Vertical blur step
|
// Vertical blur step
|
||||||
getVBlurPipeline();
|
getVBlurPipeline();
|
||||||
batch.setResourceTexture(0, _occlusionTexture);
|
batch.setResourceTexture(0, _occlusionTexture);
|
||||||
_vBlurBuffer->setRenderBuffer(0, _vBlurTexture);
|
_vBlurBuffer->setRenderBuffer(0, _vBlurTexture);
|
||||||
batch.setFramebuffer(_vBlurBuffer);
|
batch.setFramebuffer(_vBlurBuffer);
|
||||||
|
|
||||||
// Bind the second gpu::Pipeline we need - for calculating blur buffer
|
// Bind the second gpu::Pipeline we need - for calculating blur buffer
|
||||||
batch.setPipeline(getVBlurPipeline());
|
batch.setPipeline(getVBlurPipeline());
|
||||||
|
|
||||||
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
|
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
|
||||||
|
|
||||||
// Horizontal blur step
|
// Horizontal blur step
|
||||||
getHBlurPipeline();
|
getHBlurPipeline();
|
||||||
batch.setResourceTexture(0, _vBlurTexture);
|
batch.setResourceTexture(0, _vBlurTexture);
|
||||||
_hBlurBuffer->setRenderBuffer(0, _hBlurTexture);
|
_hBlurBuffer->setRenderBuffer(0, _hBlurTexture);
|
||||||
batch.setFramebuffer(_hBlurBuffer);
|
batch.setFramebuffer(_hBlurBuffer);
|
||||||
|
|
||||||
// Bind the third gpu::Pipeline we need - for calculating blur buffer
|
// Bind the third gpu::Pipeline we need - for calculating blur buffer
|
||||||
batch.setPipeline(getHBlurPipeline());
|
batch.setPipeline(getHBlurPipeline());
|
||||||
|
|
||||||
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
|
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
|
||||||
|
|
||||||
// Blend step
|
// Blend step
|
||||||
getBlendPipeline();
|
getBlendPipeline();
|
||||||
batch.setResourceTexture(0, _hBlurTexture);
|
batch.setResourceTexture(0, _hBlurTexture);
|
||||||
batch.setFramebuffer(framebufferCache->getPrimaryFramebuffer());
|
batch.setFramebuffer(framebufferCache->getPrimaryFramebuffer());
|
||||||
|
|
||||||
// Bind the fourth gpu::Pipeline we need - for blending the primary color buffer with blurred occlusion texture
|
// Bind the fourth gpu::Pipeline we need - for blending the primary color buffer with blurred occlusion texture
|
||||||
batch.setPipeline(getBlendPipeline());
|
batch.setPipeline(getBlendPipeline());
|
||||||
|
|
||||||
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
|
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
|
||||||
|
});
|
||||||
// Ready to render
|
|
||||||
args->_context->render((batch));
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,66 +100,62 @@ void Antialiasing::run(const render::SceneContextPointer& sceneContext, const re
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gpu::Batch batch;
|
|
||||||
|
|
||||||
batch.enableStereo(false);
|
|
||||||
|
|
||||||
RenderArgs* args = renderContext->args;
|
RenderArgs* args = renderContext->args;
|
||||||
|
doInBatch(args->_context, [=](gpu::Batch& batch) {
|
||||||
|
batch.enableStereo(false);
|
||||||
|
|
||||||
auto framebufferCache = DependencyManager::get<FramebufferCache>();
|
auto framebufferCache = DependencyManager::get<FramebufferCache>();
|
||||||
QSize framebufferSize = framebufferCache->getFrameBufferSize();
|
QSize framebufferSize = framebufferCache->getFrameBufferSize();
|
||||||
float fbWidth = framebufferSize.width();
|
float fbWidth = framebufferSize.width();
|
||||||
float fbHeight = framebufferSize.height();
|
float fbHeight = framebufferSize.height();
|
||||||
// float sMin = args->_viewport.x / fbWidth;
|
// float sMin = args->_viewport.x / fbWidth;
|
||||||
// float sWidth = args->_viewport.z / fbWidth;
|
// float sWidth = args->_viewport.z / fbWidth;
|
||||||
// float tMin = args->_viewport.y / fbHeight;
|
// float tMin = args->_viewport.y / fbHeight;
|
||||||
// float tHeight = args->_viewport.w / fbHeight;
|
// float tHeight = args->_viewport.w / fbHeight;
|
||||||
|
|
||||||
glm::mat4 projMat;
|
glm::mat4 projMat;
|
||||||
Transform viewMat;
|
Transform viewMat;
|
||||||
args->_viewFrustum->evalProjectionMatrix(projMat);
|
args->_viewFrustum->evalProjectionMatrix(projMat);
|
||||||
args->_viewFrustum->evalViewTransform(viewMat);
|
args->_viewFrustum->evalViewTransform(viewMat);
|
||||||
batch.setProjectionTransform(projMat);
|
batch.setProjectionTransform(projMat);
|
||||||
batch.setViewTransform(viewMat);
|
batch.setViewTransform(viewMat);
|
||||||
batch.setModelTransform(Transform());
|
batch.setModelTransform(Transform());
|
||||||
|
|
||||||
// FXAA step
|
// FXAA step
|
||||||
getAntialiasingPipeline();
|
getAntialiasingPipeline();
|
||||||
batch.setResourceTexture(0, framebufferCache->getPrimaryColorTexture());
|
batch.setResourceTexture(0, framebufferCache->getPrimaryColorTexture());
|
||||||
_antialiasingBuffer->setRenderBuffer(0, _antialiasingTexture);
|
_antialiasingBuffer->setRenderBuffer(0, _antialiasingTexture);
|
||||||
batch.setFramebuffer(_antialiasingBuffer);
|
batch.setFramebuffer(_antialiasingBuffer);
|
||||||
batch.setPipeline(getAntialiasingPipeline());
|
batch.setPipeline(getAntialiasingPipeline());
|
||||||
|
|
||||||
// initialize the view-space unpacking uniforms using frustum data
|
// initialize the view-space unpacking uniforms using frustum data
|
||||||
float left, right, bottom, top, nearVal, farVal;
|
float left, right, bottom, top, nearVal, farVal;
|
||||||
glm::vec4 nearClipPlane, farClipPlane;
|
glm::vec4 nearClipPlane, farClipPlane;
|
||||||
|
|
||||||
args->_viewFrustum->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
|
args->_viewFrustum->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
|
||||||
|
|
||||||
// float depthScale = (farVal - nearVal) / farVal;
|
// float depthScale = (farVal - nearVal) / farVal;
|
||||||
// float nearScale = -1.0f / nearVal;
|
// float nearScale = -1.0f / nearVal;
|
||||||
// float depthTexCoordScaleS = (right - left) * nearScale / sWidth;
|
// float depthTexCoordScaleS = (right - left) * nearScale / sWidth;
|
||||||
// float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight;
|
// float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight;
|
||||||
// float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS;
|
// float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS;
|
||||||
// float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT;
|
// float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT;
|
||||||
|
|
||||||
batch._glUniform2f(_texcoordOffsetLoc, 1.0f / fbWidth, 1.0f / fbHeight);
|
batch._glUniform2f(_texcoordOffsetLoc, 1.0f / fbWidth, 1.0f / fbHeight);
|
||||||
|
|
||||||
glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f);
|
glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
glm::vec2 bottomLeft(-1.0f, -1.0f);
|
glm::vec2 bottomLeft(-1.0f, -1.0f);
|
||||||
glm::vec2 topRight(1.0f, 1.0f);
|
glm::vec2 topRight(1.0f, 1.0f);
|
||||||
glm::vec2 texCoordTopLeft(0.0f, 0.0f);
|
glm::vec2 texCoordTopLeft(0.0f, 0.0f);
|
||||||
glm::vec2 texCoordBottomRight(1.0f, 1.0f);
|
glm::vec2 texCoordBottomRight(1.0f, 1.0f);
|
||||||
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
|
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
|
||||||
|
|
||||||
// Blend step
|
// Blend step
|
||||||
getBlendPipeline();
|
getBlendPipeline();
|
||||||
batch.setResourceTexture(0, _antialiasingTexture);
|
batch.setResourceTexture(0, _antialiasingTexture);
|
||||||
batch.setFramebuffer(framebufferCache->getPrimaryFramebuffer());
|
batch.setFramebuffer(framebufferCache->getPrimaryFramebuffer());
|
||||||
batch.setPipeline(getBlendPipeline());
|
batch.setPipeline(getBlendPipeline());
|
||||||
|
|
||||||
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
|
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
|
||||||
|
});
|
||||||
// Ready to render
|
|
||||||
args->_context->render((batch));
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -340,341 +340,338 @@ void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radiu
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeferredLightingEffect::prepare(RenderArgs* args) {
|
void DeferredLightingEffect::prepare(RenderArgs* args) {
|
||||||
gpu::Batch batch;
|
doInBatch(args->_context, [=](gpu::Batch& batch) {
|
||||||
batch.enableStereo(false);
|
batch.enableStereo(false);
|
||||||
|
batch.setStateScissorRect(args->_viewport);
|
||||||
|
|
||||||
batch.setStateScissorRect(args->_viewport);
|
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebuffer();
|
||||||
|
|
||||||
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebuffer();
|
batch.setFramebuffer(primaryFbo);
|
||||||
|
// clear the normal and specular buffers
|
||||||
batch.setFramebuffer(primaryFbo);
|
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR1, glm::vec4(0.0f, 0.0f, 0.0f, 0.0f), true);
|
||||||
// clear the normal and specular buffers
|
const float MAX_SPECULAR_EXPONENT = 128.0f;
|
||||||
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR1, glm::vec4(0.0f, 0.0f, 0.0f, 0.0f), true);
|
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR2, glm::vec4(0.0f, 0.0f, 0.0f, 1.0f / MAX_SPECULAR_EXPONENT), true);
|
||||||
const float MAX_SPECULAR_EXPONENT = 128.0f;
|
});
|
||||||
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR2, glm::vec4(0.0f, 0.0f, 0.0f, 1.0f / MAX_SPECULAR_EXPONENT), true);
|
|
||||||
|
|
||||||
args->_context->render(batch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gpu::FramebufferPointer _copyFBO;
|
gpu::FramebufferPointer _copyFBO;
|
||||||
|
|
||||||
void DeferredLightingEffect::render(RenderArgs* args) {
|
void DeferredLightingEffect::render(RenderArgs* args) {
|
||||||
gpu::Batch batch;
|
doInBatch(args->_context, [=](gpu::Batch& batch) {
|
||||||
|
|
||||||
// Allocate the parameters buffer used by all the deferred shaders
|
|
||||||
if (!_deferredTransformBuffer[0]._buffer) {
|
|
||||||
DeferredTransform parameters;
|
|
||||||
_deferredTransformBuffer[0] = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(DeferredTransform), (const gpu::Byte*) ¶meters));
|
|
||||||
_deferredTransformBuffer[1] = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(DeferredTransform), (const gpu::Byte*) ¶meters));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Framebuffer copy operations cannot function as multipass stereo operations.
|
|
||||||
batch.enableStereo(false);
|
|
||||||
|
|
||||||
// perform deferred lighting, rendering to free fbo
|
|
||||||
auto framebufferCache = DependencyManager::get<FramebufferCache>();
|
|
||||||
|
|
||||||
QSize framebufferSize = framebufferCache->getFrameBufferSize();
|
|
||||||
|
|
||||||
// binding the first framebuffer
|
|
||||||
_copyFBO = framebufferCache->getFramebuffer();
|
|
||||||
batch.setFramebuffer(_copyFBO);
|
|
||||||
|
|
||||||
// Clearing it
|
|
||||||
batch.setViewportTransform(args->_viewport);
|
|
||||||
batch.setStateScissorRect(args->_viewport);
|
|
||||||
batch.clearColorFramebuffer(_copyFBO->getBufferMask(), glm::vec4(0.0f, 0.0f, 0.0f, 0.0f), true);
|
|
||||||
|
|
||||||
// BInd the G-Buffer surfaces
|
|
||||||
batch.setResourceTexture(0, framebufferCache->getPrimaryColorTexture());
|
|
||||||
batch.setResourceTexture(1, framebufferCache->getPrimaryNormalTexture());
|
|
||||||
batch.setResourceTexture(2, framebufferCache->getPrimarySpecularTexture());
|
|
||||||
batch.setResourceTexture(3, framebufferCache->getPrimaryDepthTexture());
|
|
||||||
|
|
||||||
// THe main viewport is assumed to be the mono viewport (or the 2 stereo faces side by side within that viewport)
|
|
||||||
auto monoViewport = args->_viewport;
|
|
||||||
float sMin = args->_viewport.x / (float)framebufferSize.width();
|
|
||||||
float sWidth = args->_viewport.z / (float)framebufferSize.width();
|
|
||||||
float tMin = args->_viewport.y / (float)framebufferSize.height();
|
|
||||||
float tHeight = args->_viewport.w / (float)framebufferSize.height();
|
|
||||||
|
|
||||||
// The view frustum is the mono frustum base
|
|
||||||
auto viewFrustum = args->_viewFrustum;
|
|
||||||
|
|
||||||
// Eval the mono projection
|
|
||||||
mat4 monoProjMat;
|
|
||||||
viewFrustum->evalProjectionMatrix(monoProjMat);
|
|
||||||
|
|
||||||
// The mono view transform
|
|
||||||
Transform monoViewTransform;
|
|
||||||
viewFrustum->evalViewTransform(monoViewTransform);
|
|
||||||
|
|
||||||
// THe mono view matrix coming from the mono view transform
|
|
||||||
glm::mat4 monoViewMat;
|
|
||||||
monoViewTransform.getMatrix(monoViewMat);
|
|
||||||
|
|
||||||
// Running in stero ?
|
|
||||||
bool isStereo = args->_context->isStereo();
|
|
||||||
int numPasses = 1;
|
|
||||||
|
|
||||||
mat4 projMats[2];
|
|
||||||
Transform viewTransforms[2];
|
|
||||||
ivec4 viewports[2];
|
|
||||||
vec4 clipQuad[2];
|
|
||||||
vec2 screenBottomLeftCorners[2];
|
|
||||||
vec2 screenTopRightCorners[2];
|
|
||||||
vec4 fetchTexcoordRects[2];
|
|
||||||
|
|
||||||
DeferredTransform deferredTransforms[2];
|
|
||||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
|
||||||
|
|
||||||
if (isStereo) {
|
|
||||||
numPasses = 2;
|
|
||||||
|
|
||||||
mat4 eyeViews[2];
|
|
||||||
args->_context->getStereoProjections(projMats);
|
|
||||||
args->_context->getStereoViews(eyeViews);
|
|
||||||
|
|
||||||
float halfWidth = 0.5f * sWidth;
|
|
||||||
|
|
||||||
for (int i = 0; i < numPasses; i++) {
|
|
||||||
// In stereo, the 2 sides are layout side by side in the mono viewport and their width is half
|
|
||||||
int sideWidth = monoViewport.z >> 1;
|
|
||||||
viewports[i] = ivec4(monoViewport.x + (i * sideWidth), monoViewport.y, sideWidth, monoViewport.w);
|
|
||||||
|
|
||||||
deferredTransforms[i].projection = projMats[i];
|
|
||||||
|
|
||||||
auto sideViewMat = eyeViews[i] * monoViewMat;
|
|
||||||
viewTransforms[i].evalFromRawMatrix(sideViewMat);
|
|
||||||
deferredTransforms[i].viewInverse = sideViewMat;
|
|
||||||
|
|
||||||
deferredTransforms[i].stereoSide = (i == 0 ? -1.0f : 1.0f);
|
|
||||||
|
|
||||||
clipQuad[i] = glm::vec4(sMin + i * halfWidth, tMin, halfWidth, tHeight);
|
|
||||||
screenBottomLeftCorners[i] = glm::vec2(-1.0f + i * 1.0f, -1.0f);
|
|
||||||
screenTopRightCorners[i] = glm::vec2(i * 1.0f, 1.0f);
|
|
||||||
|
|
||||||
fetchTexcoordRects[i] = glm::vec4(sMin + i * halfWidth, tMin, halfWidth, tHeight);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
|
|
||||||
viewports[0] = monoViewport;
|
|
||||||
projMats[0] = monoProjMat;
|
|
||||||
|
|
||||||
deferredTransforms[0].projection = monoProjMat;
|
|
||||||
|
|
||||||
deferredTransforms[0].viewInverse = monoViewMat;
|
|
||||||
viewTransforms[0] = monoViewTransform;
|
|
||||||
|
|
||||||
deferredTransforms[0].stereoSide = 0.0f;
|
|
||||||
|
|
||||||
clipQuad[0] = glm::vec4(sMin, tMin, sWidth, tHeight);
|
|
||||||
screenBottomLeftCorners[0] = glm::vec2(-1.0f, -1.0f);
|
|
||||||
screenTopRightCorners[0] = glm::vec2(1.0f, 1.0f);
|
|
||||||
|
|
||||||
fetchTexcoordRects[0] = glm::vec4(sMin, tMin, sWidth, tHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto eyePoint = viewFrustum->getPosition();
|
|
||||||
float nearRadius = glm::distance(eyePoint, viewFrustum->getNearTopLeft());
|
|
||||||
|
|
||||||
|
|
||||||
for (int side = 0; side < numPasses; side++) {
|
|
||||||
// Render in this side's viewport
|
|
||||||
batch.setViewportTransform(viewports[side]);
|
|
||||||
batch.setStateScissorRect(viewports[side]);
|
|
||||||
|
|
||||||
// Sync and Bind the correct DeferredTransform ubo
|
|
||||||
_deferredTransformBuffer[side]._buffer->setSubData(0, sizeof(DeferredTransform), (const gpu::Byte*) &deferredTransforms[side]);
|
|
||||||
batch.setUniformBuffer(_directionalLightLocations->deferredTransformBuffer, _deferredTransformBuffer[side]);
|
|
||||||
|
|
||||||
glm::vec2 topLeft(-1.0f, -1.0f);
|
|
||||||
glm::vec2 bottomRight(1.0f, 1.0f);
|
|
||||||
glm::vec2 texCoordTopLeft(clipQuad[side].x, clipQuad[side].y);
|
|
||||||
glm::vec2 texCoordBottomRight(clipQuad[side].x + clipQuad[side].z, clipQuad[side].y + clipQuad[side].w);
|
|
||||||
|
|
||||||
// First Global directional light and ambient pass
|
|
||||||
{
|
|
||||||
bool useSkyboxCubemap = (_skybox) && (_skybox->getCubemap());
|
|
||||||
|
|
||||||
auto& program = _directionalLight;
|
|
||||||
LightLocationsPtr locations = _directionalLightLocations;
|
|
||||||
|
|
||||||
// TODO: At some point bring back the shadows...
|
|
||||||
// Setup the global directional pass pipeline
|
|
||||||
{
|
|
||||||
if (useSkyboxCubemap) {
|
|
||||||
program = _directionalSkyboxLight;
|
|
||||||
locations = _directionalSkyboxLightLocations;
|
|
||||||
} else if (_ambientLightMode > -1) {
|
|
||||||
program = _directionalAmbientSphereLight;
|
|
||||||
locations = _directionalAmbientSphereLightLocations;
|
|
||||||
}
|
|
||||||
batch.setPipeline(program);
|
|
||||||
}
|
|
||||||
|
|
||||||
{ // Setup the global lighting
|
|
||||||
auto globalLight = _allocatedLights[_globalLights.front()];
|
|
||||||
|
|
||||||
if (locations->ambientSphere >= 0) {
|
|
||||||
gpu::SphericalHarmonics sh = globalLight->getAmbientSphere();
|
|
||||||
if (useSkyboxCubemap && _skybox->getCubemap()->getIrradiance()) {
|
|
||||||
sh = (*_skybox->getCubemap()->getIrradiance());
|
|
||||||
}
|
|
||||||
for (int i =0; i <gpu::SphericalHarmonics::NUM_COEFFICIENTS; i++) {
|
|
||||||
batch._glUniform4fv(locations->ambientSphere + i, 1, (const float*) (&sh) + i * 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (useSkyboxCubemap) {
|
|
||||||
batch.setResourceTexture(5, _skybox->getCubemap());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (locations->lightBufferUnit >= 0) {
|
|
||||||
batch.setUniformBuffer(locations->lightBufferUnit, globalLight->getSchemaBuffer());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_atmosphere && (locations->atmosphereBufferUnit >= 0)) {
|
// Allocate the parameters buffer used by all the deferred shaders
|
||||||
batch.setUniformBuffer(locations->atmosphereBufferUnit, _atmosphere->getDataBuffer());
|
if (!_deferredTransformBuffer[0]._buffer) {
|
||||||
}
|
DeferredTransform parameters;
|
||||||
}
|
_deferredTransformBuffer[0] = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(DeferredTransform), (const gpu::Byte*) ¶meters));
|
||||||
|
_deferredTransformBuffer[1] = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(DeferredTransform), (const gpu::Byte*) ¶meters));
|
||||||
{
|
|
||||||
batch.setModelTransform(Transform());
|
|
||||||
batch.setProjectionTransform(glm::mat4());
|
|
||||||
batch.setViewTransform(Transform());
|
|
||||||
|
|
||||||
glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f);
|
|
||||||
geometryCache->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (useSkyboxCubemap) {
|
|
||||||
batch.setResourceTexture(5, nullptr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto texcoordMat = glm::mat4();
|
// Framebuffer copy operations cannot function as multipass stereo operations.
|
||||||
/* texcoordMat[0] = glm::vec4(sWidth / 2.0f, 0.0f, 0.0f, sMin + sWidth / 2.0f);
|
batch.enableStereo(false);
|
||||||
texcoordMat[1] = glm::vec4(0.0f, tHeight / 2.0f, 0.0f, tMin + tHeight / 2.0f);
|
|
||||||
*/ texcoordMat[0] = glm::vec4(fetchTexcoordRects[side].z / 2.0f, 0.0f, 0.0f, fetchTexcoordRects[side].x + fetchTexcoordRects[side].z / 2.0f);
|
|
||||||
texcoordMat[1] = glm::vec4(0.0f, fetchTexcoordRects[side].w / 2.0f, 0.0f, fetchTexcoordRects[side].y + fetchTexcoordRects[side].w / 2.0f);
|
|
||||||
texcoordMat[2] = glm::vec4(0.0f, 0.0f, 1.0f, 0.0f);
|
|
||||||
texcoordMat[3] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
|
|
||||||
|
|
||||||
// enlarge the scales slightly to account for tesselation
|
// perform deferred lighting, rendering to free fbo
|
||||||
const float SCALE_EXPANSION = 0.05f;
|
auto framebufferCache = DependencyManager::get<FramebufferCache>();
|
||||||
|
|
||||||
|
|
||||||
batch.setProjectionTransform(projMats[side]);
|
|
||||||
batch.setViewTransform(viewTransforms[side]);
|
|
||||||
|
|
||||||
// Splat Point lights
|
|
||||||
if (!_pointLights.empty()) {
|
|
||||||
batch.setPipeline(_pointLight);
|
|
||||||
|
|
||||||
batch._glUniformMatrix4fv(_pointLightLocations->texcoordMat, 1, false, reinterpret_cast< const float* >(&texcoordMat));
|
|
||||||
|
|
||||||
for (auto lightID : _pointLights) {
|
|
||||||
auto& light = _allocatedLights[lightID];
|
|
||||||
// IN DEBUG: light->setShowContour(true);
|
|
||||||
if (_pointLightLocations->lightBufferUnit >= 0) {
|
|
||||||
batch.setUniformBuffer(_pointLightLocations->lightBufferUnit, light->getSchemaBuffer());
|
|
||||||
}
|
|
||||||
|
|
||||||
float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION);
|
|
||||||
// TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume,
|
|
||||||
// we should be able to draw thre same geometry use DepthClamp but for unknown reason it's s not working...
|
|
||||||
if (glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius) {
|
|
||||||
Transform model;
|
|
||||||
model.setTranslation(glm::vec3(0.0f, 0.0f, -1.0f));
|
|
||||||
batch.setModelTransform(model);
|
|
||||||
batch.setViewTransform(Transform());
|
|
||||||
batch.setProjectionTransform(glm::mat4());
|
|
||||||
|
|
||||||
glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f);
|
|
||||||
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color);
|
|
||||||
|
|
||||||
batch.setProjectionTransform(projMats[side]);
|
|
||||||
batch.setViewTransform(viewTransforms[side]);
|
|
||||||
} else {
|
|
||||||
Transform model;
|
|
||||||
model.setTranslation(glm::vec3(light->getPosition().x, light->getPosition().y, light->getPosition().z));
|
|
||||||
batch.setModelTransform(model.postScale(expandedRadius));
|
|
||||||
batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
|
||||||
geometryCache->renderSphere(batch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Splat spot lights
|
QSize framebufferSize = framebufferCache->getFrameBufferSize();
|
||||||
if (!_spotLights.empty()) {
|
|
||||||
batch.setPipeline(_spotLight);
|
// binding the first framebuffer
|
||||||
|
_copyFBO = framebufferCache->getFramebuffer();
|
||||||
|
batch.setFramebuffer(_copyFBO);
|
||||||
|
|
||||||
batch._glUniformMatrix4fv(_spotLightLocations->texcoordMat, 1, false, reinterpret_cast< const float* >(&texcoordMat));
|
// Clearing it
|
||||||
|
batch.setViewportTransform(args->_viewport);
|
||||||
|
batch.setStateScissorRect(args->_viewport);
|
||||||
|
batch.clearColorFramebuffer(_copyFBO->getBufferMask(), glm::vec4(0.0f, 0.0f, 0.0f, 0.0f), true);
|
||||||
|
|
||||||
for (auto lightID : _spotLights) {
|
// BInd the G-Buffer surfaces
|
||||||
auto light = _allocatedLights[lightID];
|
batch.setResourceTexture(0, framebufferCache->getPrimaryColorTexture());
|
||||||
// IN DEBUG: light->setShowContour(true);
|
batch.setResourceTexture(1, framebufferCache->getPrimaryNormalTexture());
|
||||||
|
batch.setResourceTexture(2, framebufferCache->getPrimarySpecularTexture());
|
||||||
|
batch.setResourceTexture(3, framebufferCache->getPrimaryDepthTexture());
|
||||||
|
|
||||||
batch.setUniformBuffer(_spotLightLocations->lightBufferUnit, light->getSchemaBuffer());
|
// THe main viewport is assumed to be the mono viewport (or the 2 stereo faces side by side within that viewport)
|
||||||
|
auto monoViewport = args->_viewport;
|
||||||
|
float sMin = args->_viewport.x / (float)framebufferSize.width();
|
||||||
|
float sWidth = args->_viewport.z / (float)framebufferSize.width();
|
||||||
|
float tMin = args->_viewport.y / (float)framebufferSize.height();
|
||||||
|
float tHeight = args->_viewport.w / (float)framebufferSize.height();
|
||||||
|
|
||||||
auto eyeLightPos = eyePoint - light->getPosition();
|
// The view frustum is the mono frustum base
|
||||||
auto eyeHalfPlaneDistance = glm::dot(eyeLightPos, light->getDirection());
|
auto viewFrustum = args->_viewFrustum;
|
||||||
|
|
||||||
const float TANGENT_LENGTH_SCALE = 0.666f;
|
// Eval the mono projection
|
||||||
glm::vec4 coneParam(light->getSpotAngleCosSin(), TANGENT_LENGTH_SCALE * tanf(0.5f * light->getSpotAngle()), 1.0f);
|
mat4 monoProjMat;
|
||||||
|
viewFrustum->evalProjectionMatrix(monoProjMat);
|
||||||
|
|
||||||
float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION);
|
// The mono view transform
|
||||||
// TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume,
|
Transform monoViewTransform;
|
||||||
// we should be able to draw thre same geometry use DepthClamp but for unknown reason it's s not working...
|
viewFrustum->evalViewTransform(monoViewTransform);
|
||||||
if ((eyeHalfPlaneDistance > -nearRadius) &&
|
|
||||||
(glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius)) {
|
|
||||||
coneParam.w = 0.0f;
|
|
||||||
batch._glUniform4fv(_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam));
|
|
||||||
|
|
||||||
Transform model;
|
// THe mono view matrix coming from the mono view transform
|
||||||
model.setTranslation(glm::vec3(0.0f, 0.0f, -1.0f));
|
glm::mat4 monoViewMat;
|
||||||
batch.setModelTransform(model);
|
monoViewTransform.getMatrix(monoViewMat);
|
||||||
batch.setViewTransform(Transform());
|
|
||||||
|
// Running in stero ?
|
||||||
|
bool isStereo = args->_context->isStereo();
|
||||||
|
int numPasses = 1;
|
||||||
|
|
||||||
|
mat4 projMats[2];
|
||||||
|
Transform viewTransforms[2];
|
||||||
|
ivec4 viewports[2];
|
||||||
|
vec4 clipQuad[2];
|
||||||
|
vec2 screenBottomLeftCorners[2];
|
||||||
|
vec2 screenTopRightCorners[2];
|
||||||
|
vec4 fetchTexcoordRects[2];
|
||||||
|
|
||||||
|
DeferredTransform deferredTransforms[2];
|
||||||
|
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||||
|
|
||||||
|
if (isStereo) {
|
||||||
|
numPasses = 2;
|
||||||
|
|
||||||
|
mat4 eyeViews[2];
|
||||||
|
args->_context->getStereoProjections(projMats);
|
||||||
|
args->_context->getStereoViews(eyeViews);
|
||||||
|
|
||||||
|
float halfWidth = 0.5f * sWidth;
|
||||||
|
|
||||||
|
for (int i = 0; i < numPasses; i++) {
|
||||||
|
// In stereo, the 2 sides are layout side by side in the mono viewport and their width is half
|
||||||
|
int sideWidth = monoViewport.z >> 1;
|
||||||
|
viewports[i] = ivec4(monoViewport.x + (i * sideWidth), monoViewport.y, sideWidth, monoViewport.w);
|
||||||
|
|
||||||
|
deferredTransforms[i].projection = projMats[i];
|
||||||
|
|
||||||
|
auto sideViewMat = eyeViews[i] * monoViewMat;
|
||||||
|
viewTransforms[i].evalFromRawMatrix(sideViewMat);
|
||||||
|
deferredTransforms[i].viewInverse = sideViewMat;
|
||||||
|
|
||||||
|
deferredTransforms[i].stereoSide = (i == 0 ? -1.0f : 1.0f);
|
||||||
|
|
||||||
|
clipQuad[i] = glm::vec4(sMin + i * halfWidth, tMin, halfWidth, tHeight);
|
||||||
|
screenBottomLeftCorners[i] = glm::vec2(-1.0f + i * 1.0f, -1.0f);
|
||||||
|
screenTopRightCorners[i] = glm::vec2(i * 1.0f, 1.0f);
|
||||||
|
|
||||||
|
fetchTexcoordRects[i] = glm::vec4(sMin + i * halfWidth, tMin, halfWidth, tHeight);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
viewports[0] = monoViewport;
|
||||||
|
projMats[0] = monoProjMat;
|
||||||
|
|
||||||
|
deferredTransforms[0].projection = monoProjMat;
|
||||||
|
|
||||||
|
deferredTransforms[0].viewInverse = monoViewMat;
|
||||||
|
viewTransforms[0] = monoViewTransform;
|
||||||
|
|
||||||
|
deferredTransforms[0].stereoSide = 0.0f;
|
||||||
|
|
||||||
|
clipQuad[0] = glm::vec4(sMin, tMin, sWidth, tHeight);
|
||||||
|
screenBottomLeftCorners[0] = glm::vec2(-1.0f, -1.0f);
|
||||||
|
screenTopRightCorners[0] = glm::vec2(1.0f, 1.0f);
|
||||||
|
|
||||||
|
fetchTexcoordRects[0] = glm::vec4(sMin, tMin, sWidth, tHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto eyePoint = viewFrustum->getPosition();
|
||||||
|
float nearRadius = glm::distance(eyePoint, viewFrustum->getNearTopLeft());
|
||||||
|
|
||||||
|
|
||||||
|
for (int side = 0; side < numPasses; side++) {
|
||||||
|
// Render in this side's viewport
|
||||||
|
batch.setViewportTransform(viewports[side]);
|
||||||
|
batch.setStateScissorRect(viewports[side]);
|
||||||
|
|
||||||
|
// Sync and Bind the correct DeferredTransform ubo
|
||||||
|
_deferredTransformBuffer[side]._buffer->setSubData(0, sizeof(DeferredTransform), (const gpu::Byte*) &deferredTransforms[side]);
|
||||||
|
batch.setUniformBuffer(_directionalLightLocations->deferredTransformBuffer, _deferredTransformBuffer[side]);
|
||||||
|
|
||||||
|
glm::vec2 topLeft(-1.0f, -1.0f);
|
||||||
|
glm::vec2 bottomRight(1.0f, 1.0f);
|
||||||
|
glm::vec2 texCoordTopLeft(clipQuad[side].x, clipQuad[side].y);
|
||||||
|
glm::vec2 texCoordBottomRight(clipQuad[side].x + clipQuad[side].z, clipQuad[side].y + clipQuad[side].w);
|
||||||
|
|
||||||
|
// First Global directional light and ambient pass
|
||||||
|
{
|
||||||
|
bool useSkyboxCubemap = (_skybox) && (_skybox->getCubemap());
|
||||||
|
|
||||||
|
auto& program = _directionalLight;
|
||||||
|
LightLocationsPtr locations = _directionalLightLocations;
|
||||||
|
|
||||||
|
// TODO: At some point bring back the shadows...
|
||||||
|
// Setup the global directional pass pipeline
|
||||||
|
{
|
||||||
|
if (useSkyboxCubemap) {
|
||||||
|
program = _directionalSkyboxLight;
|
||||||
|
locations = _directionalSkyboxLightLocations;
|
||||||
|
} else if (_ambientLightMode > -1) {
|
||||||
|
program = _directionalAmbientSphereLight;
|
||||||
|
locations = _directionalAmbientSphereLightLocations;
|
||||||
|
}
|
||||||
|
batch.setPipeline(program);
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // Setup the global lighting
|
||||||
|
auto globalLight = _allocatedLights[_globalLights.front()];
|
||||||
|
|
||||||
|
if (locations->ambientSphere >= 0) {
|
||||||
|
gpu::SphericalHarmonics sh = globalLight->getAmbientSphere();
|
||||||
|
if (useSkyboxCubemap && _skybox->getCubemap()->getIrradiance()) {
|
||||||
|
sh = (*_skybox->getCubemap()->getIrradiance());
|
||||||
|
}
|
||||||
|
for (int i =0; i <gpu::SphericalHarmonics::NUM_COEFFICIENTS; i++) {
|
||||||
|
batch._glUniform4fv(locations->ambientSphere + i, 1, (const float*) (&sh) + i * 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useSkyboxCubemap) {
|
||||||
|
batch.setResourceTexture(5, _skybox->getCubemap());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (locations->lightBufferUnit >= 0) {
|
||||||
|
batch.setUniformBuffer(locations->lightBufferUnit, globalLight->getSchemaBuffer());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_atmosphere && (locations->atmosphereBufferUnit >= 0)) {
|
||||||
|
batch.setUniformBuffer(locations->atmosphereBufferUnit, _atmosphere->getDataBuffer());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
batch.setModelTransform(Transform());
|
||||||
batch.setProjectionTransform(glm::mat4());
|
batch.setProjectionTransform(glm::mat4());
|
||||||
|
batch.setViewTransform(Transform());
|
||||||
|
|
||||||
glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f);
|
glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color);
|
geometryCache->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useSkyboxCubemap) {
|
||||||
|
batch.setResourceTexture(5, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto texcoordMat = glm::mat4();
|
||||||
|
/* texcoordMat[0] = glm::vec4(sWidth / 2.0f, 0.0f, 0.0f, sMin + sWidth / 2.0f);
|
||||||
|
texcoordMat[1] = glm::vec4(0.0f, tHeight / 2.0f, 0.0f, tMin + tHeight / 2.0f);
|
||||||
|
*/ texcoordMat[0] = glm::vec4(fetchTexcoordRects[side].z / 2.0f, 0.0f, 0.0f, fetchTexcoordRects[side].x + fetchTexcoordRects[side].z / 2.0f);
|
||||||
|
texcoordMat[1] = glm::vec4(0.0f, fetchTexcoordRects[side].w / 2.0f, 0.0f, fetchTexcoordRects[side].y + fetchTexcoordRects[side].w / 2.0f);
|
||||||
|
texcoordMat[2] = glm::vec4(0.0f, 0.0f, 1.0f, 0.0f);
|
||||||
|
texcoordMat[3] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
// enlarge the scales slightly to account for tesselation
|
||||||
|
const float SCALE_EXPANSION = 0.05f;
|
||||||
|
|
||||||
|
|
||||||
|
batch.setProjectionTransform(projMats[side]);
|
||||||
|
batch.setViewTransform(viewTransforms[side]);
|
||||||
|
|
||||||
|
// Splat Point lights
|
||||||
|
if (!_pointLights.empty()) {
|
||||||
|
batch.setPipeline(_pointLight);
|
||||||
|
|
||||||
|
batch._glUniformMatrix4fv(_pointLightLocations->texcoordMat, 1, false, reinterpret_cast< const float* >(&texcoordMat));
|
||||||
|
|
||||||
|
for (auto lightID : _pointLights) {
|
||||||
|
auto& light = _allocatedLights[lightID];
|
||||||
|
// IN DEBUG: light->setShowContour(true);
|
||||||
|
if (_pointLightLocations->lightBufferUnit >= 0) {
|
||||||
|
batch.setUniformBuffer(_pointLightLocations->lightBufferUnit, light->getSchemaBuffer());
|
||||||
|
}
|
||||||
|
|
||||||
|
float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION);
|
||||||
|
// TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume,
|
||||||
|
// we should be able to draw thre same geometry use DepthClamp but for unknown reason it's s not working...
|
||||||
|
if (glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius) {
|
||||||
|
Transform model;
|
||||||
|
model.setTranslation(glm::vec3(0.0f, 0.0f, -1.0f));
|
||||||
|
batch.setModelTransform(model);
|
||||||
|
batch.setViewTransform(Transform());
|
||||||
|
batch.setProjectionTransform(glm::mat4());
|
||||||
|
|
||||||
|
glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color);
|
||||||
|
|
||||||
batch.setProjectionTransform( projMats[side]);
|
batch.setProjectionTransform(projMats[side]);
|
||||||
batch.setViewTransform(viewTransforms[side]);
|
batch.setViewTransform(viewTransforms[side]);
|
||||||
} else {
|
} else {
|
||||||
coneParam.w = 1.0f;
|
Transform model;
|
||||||
batch._glUniform4fv(_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam));
|
model.setTranslation(glm::vec3(light->getPosition().x, light->getPosition().y, light->getPosition().z));
|
||||||
|
batch.setModelTransform(model.postScale(expandedRadius));
|
||||||
|
batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
geometryCache->renderSphere(batch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Splat spot lights
|
||||||
|
if (!_spotLights.empty()) {
|
||||||
|
batch.setPipeline(_spotLight);
|
||||||
|
|
||||||
Transform model;
|
batch._glUniformMatrix4fv(_spotLightLocations->texcoordMat, 1, false, reinterpret_cast< const float* >(&texcoordMat));
|
||||||
model.setTranslation(light->getPosition());
|
|
||||||
model.postRotate(light->getOrientation());
|
|
||||||
model.postScale(glm::vec3(expandedRadius, expandedRadius, expandedRadius));
|
|
||||||
|
|
||||||
batch.setModelTransform(model);
|
for (auto lightID : _spotLights) {
|
||||||
auto mesh = getSpotLightMesh();
|
auto light = _allocatedLights[lightID];
|
||||||
|
// IN DEBUG: light->setShowContour(true);
|
||||||
|
|
||||||
batch.setIndexBuffer(mesh->getIndexBuffer());
|
batch.setUniformBuffer(_spotLightLocations->lightBufferUnit, light->getSchemaBuffer());
|
||||||
batch.setInputBuffer(0, mesh->getVertexBuffer());
|
|
||||||
batch.setInputFormat(mesh->getVertexFormat());
|
|
||||||
|
|
||||||
auto& part = mesh->getPartBuffer().get<model::Mesh::Part>();
|
auto eyeLightPos = eyePoint - light->getPosition();
|
||||||
|
auto eyeHalfPlaneDistance = glm::dot(eyeLightPos, light->getDirection());
|
||||||
|
|
||||||
batch.drawIndexed(model::Mesh::topologyToPrimitive(part._topology), part._numIndices, part._startIndex);
|
const float TANGENT_LENGTH_SCALE = 0.666f;
|
||||||
|
glm::vec4 coneParam(light->getSpotAngleCosSin(), TANGENT_LENGTH_SCALE * tanf(0.5f * light->getSpotAngle()), 1.0f);
|
||||||
|
|
||||||
|
float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION);
|
||||||
|
// TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume,
|
||||||
|
// we should be able to draw thre same geometry use DepthClamp but for unknown reason it's s not working...
|
||||||
|
if ((eyeHalfPlaneDistance > -nearRadius) &&
|
||||||
|
(glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius)) {
|
||||||
|
coneParam.w = 0.0f;
|
||||||
|
batch._glUniform4fv(_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam));
|
||||||
|
|
||||||
|
Transform model;
|
||||||
|
model.setTranslation(glm::vec3(0.0f, 0.0f, -1.0f));
|
||||||
|
batch.setModelTransform(model);
|
||||||
|
batch.setViewTransform(Transform());
|
||||||
|
batch.setProjectionTransform(glm::mat4());
|
||||||
|
|
||||||
|
glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color);
|
||||||
|
|
||||||
|
batch.setProjectionTransform( projMats[side]);
|
||||||
|
batch.setViewTransform(viewTransforms[side]);
|
||||||
|
} else {
|
||||||
|
coneParam.w = 1.0f;
|
||||||
|
batch._glUniform4fv(_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam));
|
||||||
|
|
||||||
|
Transform model;
|
||||||
|
model.setTranslation(light->getPosition());
|
||||||
|
model.postRotate(light->getOrientation());
|
||||||
|
model.postScale(glm::vec3(expandedRadius, expandedRadius, expandedRadius));
|
||||||
|
|
||||||
|
batch.setModelTransform(model);
|
||||||
|
auto mesh = getSpotLightMesh();
|
||||||
|
|
||||||
|
batch.setIndexBuffer(mesh->getIndexBuffer());
|
||||||
|
batch.setInputBuffer(0, mesh->getVertexBuffer());
|
||||||
|
batch.setInputFormat(mesh->getVertexFormat());
|
||||||
|
|
||||||
|
auto& part = mesh->getPartBuffer().get<model::Mesh::Part>();
|
||||||
|
|
||||||
|
batch.drawIndexed(model::Mesh::topologyToPrimitive(part._topology), part._numIndices, part._startIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Probably not necessary in the long run because the gpu layer would unbound this texture if used as render target
|
// Probably not necessary in the long run because the gpu layer would unbound this texture if used as render target
|
||||||
batch.setResourceTexture(0, nullptr);
|
batch.setResourceTexture(0, nullptr);
|
||||||
batch.setResourceTexture(1, nullptr);
|
batch.setResourceTexture(1, nullptr);
|
||||||
batch.setResourceTexture(2, nullptr);
|
batch.setResourceTexture(2, nullptr);
|
||||||
batch.setResourceTexture(3, nullptr);
|
batch.setResourceTexture(3, nullptr);
|
||||||
batch.setUniformBuffer(_directionalLightLocations->deferredTransformBuffer, nullptr);
|
batch.setUniformBuffer(_directionalLightLocations->deferredTransformBuffer, nullptr);
|
||||||
|
});
|
||||||
args->_context->render(batch);
|
|
||||||
|
|
||||||
// End of the Lighting pass
|
// End of the Lighting pass
|
||||||
if (!_pointLights.empty()) {
|
if (!_pointLights.empty()) {
|
||||||
|
@ -687,36 +684,37 @@ void DeferredLightingEffect::render(RenderArgs* args) {
|
||||||
|
|
||||||
|
|
||||||
void DeferredLightingEffect::copyBack(RenderArgs* args) {
|
void DeferredLightingEffect::copyBack(RenderArgs* args) {
|
||||||
gpu::Batch batch;
|
|
||||||
batch.enableStereo(false);
|
|
||||||
auto framebufferCache = DependencyManager::get<FramebufferCache>();
|
auto framebufferCache = DependencyManager::get<FramebufferCache>();
|
||||||
QSize framebufferSize = framebufferCache->getFrameBufferSize();
|
doInBatch(args->_context, [=](gpu::Batch& batch) {
|
||||||
|
batch.enableStereo(false);
|
||||||
|
QSize framebufferSize = framebufferCache->getFrameBufferSize();
|
||||||
|
|
||||||
// TODO why doesn't this blit work? It only seems to affect a small area below the rear view mirror.
|
// TODO why doesn't this blit work? It only seems to affect a small area below the rear view mirror.
|
||||||
// auto destFbo = framebufferCache->getPrimaryFramebuffer();
|
// auto destFbo = framebufferCache->getPrimaryFramebuffer();
|
||||||
auto destFbo = framebufferCache->getPrimaryFramebufferDepthColor();
|
auto destFbo = framebufferCache->getPrimaryFramebufferDepthColor();
|
||||||
// gpu::Vec4i vp = args->_viewport;
|
// gpu::Vec4i vp = args->_viewport;
|
||||||
// batch.blit(_copyFBO, vp, framebufferCache->getPrimaryFramebuffer(), vp);
|
// batch.blit(_copyFBO, vp, framebufferCache->getPrimaryFramebuffer(), vp);
|
||||||
batch.setFramebuffer(destFbo);
|
batch.setFramebuffer(destFbo);
|
||||||
batch.setViewportTransform(args->_viewport);
|
batch.setViewportTransform(args->_viewport);
|
||||||
batch.setProjectionTransform(glm::mat4());
|
batch.setProjectionTransform(glm::mat4());
|
||||||
batch.setViewTransform(Transform());
|
batch.setViewTransform(Transform());
|
||||||
{
|
{
|
||||||
float sMin = args->_viewport.x / (float)framebufferSize.width();
|
float sMin = args->_viewport.x / (float)framebufferSize.width();
|
||||||
float sWidth = args->_viewport.z / (float)framebufferSize.width();
|
float sWidth = args->_viewport.z / (float)framebufferSize.width();
|
||||||
float tMin = args->_viewport.y / (float)framebufferSize.height();
|
float tMin = args->_viewport.y / (float)framebufferSize.height();
|
||||||
float tHeight = args->_viewport.w / (float)framebufferSize.height();
|
float tHeight = args->_viewport.w / (float)framebufferSize.height();
|
||||||
Transform model;
|
Transform model;
|
||||||
batch.setPipeline(_blitLightBuffer);
|
batch.setPipeline(_blitLightBuffer);
|
||||||
model.setTranslation(glm::vec3(sMin, tMin, 0.0));
|
model.setTranslation(glm::vec3(sMin, tMin, 0.0));
|
||||||
model.setScale(glm::vec3(sWidth, tHeight, 1.0));
|
model.setScale(glm::vec3(sWidth, tHeight, 1.0));
|
||||||
batch.setModelTransform(model);
|
batch.setModelTransform(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
batch.setResourceTexture(0, _copyFBO->getRenderBuffer(0));
|
batch.setResourceTexture(0, _copyFBO->getRenderBuffer(0));
|
||||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||||
|
|
||||||
args->_context->render(batch);
|
args->_context->render(batch);
|
||||||
|
});
|
||||||
framebufferCache->releaseFramebuffer(_copyFBO);
|
framebufferCache->releaseFramebuffer(_copyFBO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,23 +63,22 @@ void HitEffect::run(const render::SceneContextPointer& sceneContext, const rende
|
||||||
assert(renderContext->args);
|
assert(renderContext->args);
|
||||||
assert(renderContext->args->_viewFrustum);
|
assert(renderContext->args->_viewFrustum);
|
||||||
RenderArgs* args = renderContext->args;
|
RenderArgs* args = renderContext->args;
|
||||||
gpu::Batch batch;
|
doInBatch(args->_context, [=](gpu::Batch& batch) {
|
||||||
|
|
||||||
glm::mat4 projMat;
|
glm::mat4 projMat;
|
||||||
Transform viewMat;
|
Transform viewMat;
|
||||||
args->_viewFrustum->evalProjectionMatrix(projMat);
|
args->_viewFrustum->evalProjectionMatrix(projMat);
|
||||||
args->_viewFrustum->evalViewTransform(viewMat);
|
args->_viewFrustum->evalViewTransform(viewMat);
|
||||||
batch.setProjectionTransform(projMat);
|
batch.setProjectionTransform(projMat);
|
||||||
batch.setViewTransform(viewMat);
|
batch.setViewTransform(viewMat);
|
||||||
batch.setModelTransform(Transform());
|
batch.setModelTransform(Transform());
|
||||||
|
|
||||||
batch.setPipeline(getHitEffectPipeline());
|
batch.setPipeline(getHitEffectPipeline());
|
||||||
|
|
||||||
glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f);
|
glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
glm::vec2 bottomLeft(-1.0f, -1.0f);
|
glm::vec2 bottomLeft(-1.0f, -1.0f);
|
||||||
glm::vec2 topRight(1.0f, 1.0f);
|
glm::vec2 topRight(1.0f, 1.0f);
|
||||||
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, color);
|
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, color);
|
||||||
args->_context->render((batch));
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,23 +32,22 @@ using namespace render;
|
||||||
|
|
||||||
void SetupDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
void SetupDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||||
RenderArgs* args = renderContext->args;
|
RenderArgs* args = renderContext->args;
|
||||||
|
doInBatch(args->_context, [=](gpu::Batch& batch) {
|
||||||
|
|
||||||
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebufferDepthColor();
|
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebufferDepthColor();
|
||||||
|
|
||||||
gpu::Batch batch;
|
batch.enableStereo(false);
|
||||||
batch.enableStereo(false);
|
batch.setFramebuffer(nullptr);
|
||||||
batch.setFramebuffer(nullptr);
|
batch.setFramebuffer(primaryFbo);
|
||||||
batch.setFramebuffer(primaryFbo);
|
|
||||||
|
|
||||||
batch.setViewportTransform(args->_viewport);
|
batch.setViewportTransform(args->_viewport);
|
||||||
batch.setStateScissorRect(args->_viewport);
|
batch.setStateScissorRect(args->_viewport);
|
||||||
|
|
||||||
batch.clearFramebuffer(
|
batch.clearFramebuffer(
|
||||||
gpu::Framebuffer::BUFFER_COLOR0 |
|
gpu::Framebuffer::BUFFER_COLOR0 |
|
||||||
gpu::Framebuffer::BUFFER_DEPTH,
|
gpu::Framebuffer::BUFFER_DEPTH,
|
||||||
vec4(vec3(0), 1), 1.0, 0.0, true);
|
vec4(vec3(0), 1), 1.0, 0.0, true);
|
||||||
|
});
|
||||||
args->_context->render(batch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrepareDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
void PrepareDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||||
|
@ -167,30 +166,28 @@ void DrawOpaqueDeferred::run(const SceneContextPointer& sceneContext, const Rend
|
||||||
assert(renderContext->args->_viewFrustum);
|
assert(renderContext->args->_viewFrustum);
|
||||||
|
|
||||||
RenderArgs* args = renderContext->args;
|
RenderArgs* args = renderContext->args;
|
||||||
gpu::Batch batch;
|
doInBatch(args->_context, [=](gpu::Batch& batch) {
|
||||||
batch.setViewportTransform(args->_viewport);
|
batch.setViewportTransform(args->_viewport);
|
||||||
batch.setStateScissorRect(args->_viewport);
|
batch.setStateScissorRect(args->_viewport);
|
||||||
args->_batch = &batch;
|
args->_batch = &batch;
|
||||||
|
|
||||||
renderContext->_numDrawnOpaqueItems = inItems.size();
|
renderContext->_numDrawnOpaqueItems = inItems.size();
|
||||||
|
|
||||||
glm::mat4 projMat;
|
glm::mat4 projMat;
|
||||||
Transform viewMat;
|
Transform viewMat;
|
||||||
args->_viewFrustum->evalProjectionMatrix(projMat);
|
args->_viewFrustum->evalProjectionMatrix(projMat);
|
||||||
args->_viewFrustum->evalViewTransform(viewMat);
|
args->_viewFrustum->evalViewTransform(viewMat);
|
||||||
|
|
||||||
batch.setProjectionTransform(projMat);
|
batch.setProjectionTransform(projMat);
|
||||||
batch.setViewTransform(viewMat);
|
batch.setViewTransform(viewMat);
|
||||||
|
|
||||||
{
|
{
|
||||||
const float OPAQUE_ALPHA_THRESHOLD = 0.5f;
|
const float OPAQUE_ALPHA_THRESHOLD = 0.5f;
|
||||||
args->_alphaThreshold = OPAQUE_ALPHA_THRESHOLD;
|
args->_alphaThreshold = OPAQUE_ALPHA_THRESHOLD;
|
||||||
}
|
}
|
||||||
|
renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnOpaqueItems);
|
||||||
renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnOpaqueItems);
|
args->_batch = nullptr;
|
||||||
|
});
|
||||||
args->_context->render((*args->_batch));
|
|
||||||
args->_batch = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawTransparentDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems) {
|
void DrawTransparentDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems) {
|
||||||
|
@ -198,31 +195,27 @@ void DrawTransparentDeferred::run(const SceneContextPointer& sceneContext, const
|
||||||
assert(renderContext->args->_viewFrustum);
|
assert(renderContext->args->_viewFrustum);
|
||||||
|
|
||||||
RenderArgs* args = renderContext->args;
|
RenderArgs* args = renderContext->args;
|
||||||
gpu::Batch batch;
|
doInBatch(args->_context, [=](gpu::Batch& batch) {
|
||||||
batch.setViewportTransform(args->_viewport);
|
batch.setViewportTransform(args->_viewport);
|
||||||
batch.setStateScissorRect(args->_viewport);
|
batch.setStateScissorRect(args->_viewport);
|
||||||
args->_batch = &batch;
|
args->_batch = &batch;
|
||||||
|
|
||||||
renderContext->_numDrawnTransparentItems = inItems.size();
|
renderContext->_numDrawnTransparentItems = inItems.size();
|
||||||
|
|
||||||
glm::mat4 projMat;
|
glm::mat4 projMat;
|
||||||
Transform viewMat;
|
Transform viewMat;
|
||||||
args->_viewFrustum->evalProjectionMatrix(projMat);
|
args->_viewFrustum->evalProjectionMatrix(projMat);
|
||||||
args->_viewFrustum->evalViewTransform(viewMat);
|
args->_viewFrustum->evalViewTransform(viewMat);
|
||||||
|
|
||||||
batch.setProjectionTransform(projMat);
|
batch.setProjectionTransform(projMat);
|
||||||
batch.setViewTransform(viewMat);
|
batch.setViewTransform(viewMat);
|
||||||
|
|
||||||
{
|
|
||||||
const float TRANSPARENT_ALPHA_THRESHOLD = 0.0f;
|
const float TRANSPARENT_ALPHA_THRESHOLD = 0.0f;
|
||||||
args->_alphaThreshold = TRANSPARENT_ALPHA_THRESHOLD;
|
args->_alphaThreshold = TRANSPARENT_ALPHA_THRESHOLD;
|
||||||
}
|
|
||||||
|
|
||||||
|
renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnTransparentItems);
|
||||||
renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnTransparentItems);
|
args->_batch = nullptr;
|
||||||
|
});
|
||||||
args->_context->render((*args->_batch));
|
|
||||||
args->_batch = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gpu::PipelinePointer DrawOverlay3D::_opaquePipeline;
|
gpu::PipelinePointer DrawOverlay3D::_opaquePipeline;
|
||||||
|
@ -274,8 +267,7 @@ void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderCon
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render the items
|
// Render the items
|
||||||
{
|
doInBatch(args->_context, [=](gpu::Batch& batch) {
|
||||||
gpu::Batch batch;
|
|
||||||
args->_batch = &batch;
|
args->_batch = &batch;
|
||||||
args->_whiteTexture = DependencyManager::get<TextureCache>()->getWhiteTexture();
|
args->_whiteTexture = DependencyManager::get<TextureCache>()->getWhiteTexture();
|
||||||
|
|
||||||
|
@ -292,10 +284,8 @@ void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderCon
|
||||||
batch.setPipeline(getOpaquePipeline());
|
batch.setPipeline(getOpaquePipeline());
|
||||||
batch.setResourceTexture(0, args->_whiteTexture);
|
batch.setResourceTexture(0, args->_whiteTexture);
|
||||||
renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnOverlay3DItems);
|
renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnOverlay3DItems);
|
||||||
|
});
|
||||||
args->_context->render((*args->_batch));
|
args->_batch = nullptr;
|
||||||
args->_batch = nullptr;
|
args->_whiteTexture.reset();
|
||||||
args->_whiteTexture.reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,40 +126,38 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allright, something to render let's do it
|
// Allright, something to render let's do it
|
||||||
gpu::Batch batch;
|
doInBatch(args->_context, [=](gpu::Batch& batch) {
|
||||||
|
glm::mat4 projMat;
|
||||||
|
Transform viewMat;
|
||||||
|
args->_viewFrustum->evalProjectionMatrix(projMat);
|
||||||
|
args->_viewFrustum->evalViewTransform(viewMat);
|
||||||
|
|
||||||
glm::mat4 projMat;
|
batch.setProjectionTransform(projMat);
|
||||||
Transform viewMat;
|
batch.setViewTransform(viewMat);
|
||||||
args->_viewFrustum->evalProjectionMatrix(projMat);
|
batch.setModelTransform(Transform());
|
||||||
args->_viewFrustum->evalViewTransform(viewMat);
|
|
||||||
|
|
||||||
batch.setProjectionTransform(projMat);
|
// bind the one gpu::Pipeline we need
|
||||||
batch.setViewTransform(viewMat);
|
batch.setPipeline(getDrawItemBoundsPipeline());
|
||||||
batch.setModelTransform(Transform());
|
|
||||||
|
|
||||||
// bind the one gpu::Pipeline we need
|
AABox* itemAABox = reinterpret_cast<AABox*> (_itemBounds->editData());
|
||||||
batch.setPipeline(getDrawItemBoundsPipeline());
|
glm::ivec4* itemStatus = reinterpret_cast<glm::ivec4*> (_itemStatus->editData());
|
||||||
|
|
||||||
AABox* itemAABox = reinterpret_cast<AABox*> (_itemBounds->editData());
|
const unsigned int VEC3_ADRESS_OFFSET = 3;
|
||||||
glm::ivec4* itemStatus = reinterpret_cast<glm::ivec4*> (_itemStatus->editData());
|
|
||||||
|
|
||||||
const unsigned int VEC3_ADRESS_OFFSET = 3;
|
for (int i = 0; i < nbItems; i++) {
|
||||||
|
batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*) (itemAABox + i));
|
||||||
|
batch._glUniform3fv(_drawItemBoundDimLoc, 1, ((const float*) (itemAABox + i)) + VEC3_ADRESS_OFFSET);
|
||||||
|
|
||||||
for (int i = 0; i < nbItems; i++) {
|
batch.draw(gpu::LINES, 24, 0);
|
||||||
batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*) (itemAABox + i));
|
}
|
||||||
batch._glUniform3fv(_drawItemBoundDimLoc, 1, ((const float*) (itemAABox + i)) + VEC3_ADRESS_OFFSET);
|
|
||||||
|
|
||||||
batch.draw(gpu::LINES, 24, 0);
|
batch.setPipeline(getDrawItemStatusPipeline());
|
||||||
}
|
for (int i = 0; i < nbItems; i++) {
|
||||||
|
batch._glUniform3fv(_drawItemStatusPosLoc, 1, (const float*) (itemAABox + i));
|
||||||
|
batch._glUniform3fv(_drawItemStatusDimLoc, 1, ((const float*) (itemAABox + i)) + VEC3_ADRESS_OFFSET);
|
||||||
|
batch._glUniform4iv(_drawItemStatusValueLoc, 1, (const int*) (itemStatus + i));
|
||||||
|
|
||||||
batch.setPipeline(getDrawItemStatusPipeline());
|
batch.draw(gpu::TRIANGLES, 24, 0);
|
||||||
for (int i = 0; i < nbItems; i++) {
|
}
|
||||||
batch._glUniform3fv(_drawItemStatusPosLoc, 1, (const float*) (itemAABox + i));
|
});
|
||||||
batch._glUniform3fv(_drawItemStatusDimLoc, 1, ((const float*) (itemAABox + i)) + VEC3_ADRESS_OFFSET);
|
|
||||||
batch._glUniform4iv(_drawItemStatusValueLoc, 1, (const int*) (itemStatus + i));
|
|
||||||
|
|
||||||
batch.draw(gpu::TRIANGLES, 24, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
args->_context->render(batch);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <ViewFrustum.h>
|
#include <ViewFrustum.h>
|
||||||
#include <gpu/Context.h>
|
#include <gpu/Context.h>
|
||||||
|
|
||||||
|
|
||||||
using namespace render;
|
using namespace render;
|
||||||
|
|
||||||
DrawSceneTask::DrawSceneTask() : Task() {
|
DrawSceneTask::DrawSceneTask() : Task() {
|
||||||
|
@ -235,10 +236,10 @@ void DrawLight::run(const SceneContextPointer& sceneContext, const RenderContext
|
||||||
cullItems(sceneContext, renderContext, inItems, culledItems);
|
cullItems(sceneContext, renderContext, inItems, culledItems);
|
||||||
|
|
||||||
RenderArgs* args = renderContext->args;
|
RenderArgs* args = renderContext->args;
|
||||||
gpu::Batch theBatch;
|
doInBatch(args->_context, [=](gpu::Batch& batch) {
|
||||||
args->_batch = &theBatch;
|
args->_batch = &batch;
|
||||||
renderItems(sceneContext, renderContext, culledItems);
|
renderItems(sceneContext, renderContext, culledItems);
|
||||||
args->_context->render((*args->_batch));
|
});
|
||||||
args->_batch = nullptr;
|
args->_batch = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,22 +258,22 @@ void DrawBackground::run(const SceneContextPointer& sceneContext, const RenderCo
|
||||||
inItems.emplace_back(id);
|
inItems.emplace_back(id);
|
||||||
}
|
}
|
||||||
RenderArgs* args = renderContext->args;
|
RenderArgs* args = renderContext->args;
|
||||||
gpu::Batch batch;
|
doInBatch(args->_context, [=](gpu::Batch& batch) {
|
||||||
batch.enableSkybox(true);
|
args->_batch = &batch;
|
||||||
batch.setViewportTransform(args->_viewport);
|
batch.enableSkybox(true);
|
||||||
batch.setStateScissorRect(args->_viewport);
|
batch.setViewportTransform(args->_viewport);
|
||||||
args->_batch = &batch;
|
batch.setStateScissorRect(args->_viewport);
|
||||||
|
|
||||||
glm::mat4 projMat;
|
glm::mat4 projMat;
|
||||||
Transform viewMat;
|
Transform viewMat;
|
||||||
args->_viewFrustum->evalProjectionMatrix(projMat);
|
args->_viewFrustum->evalProjectionMatrix(projMat);
|
||||||
args->_viewFrustum->evalViewTransform(viewMat);
|
args->_viewFrustum->evalViewTransform(viewMat);
|
||||||
|
|
||||||
batch.setProjectionTransform(projMat);
|
batch.setProjectionTransform(projMat);
|
||||||
batch.setViewTransform(viewMat);
|
batch.setViewTransform(viewMat);
|
||||||
|
|
||||||
renderItems(sceneContext, renderContext, inItems);
|
renderItems(sceneContext, renderContext, inItems);
|
||||||
args->_context->render((*args->_batch));
|
});
|
||||||
args->_batch = nullptr;
|
args->_batch = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue